/[zanavi_public1]/navit/navit/navigation.c
ZANavi

Diff of /navit/navit/navigation.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 34 Revision 40
59#include "plugin.h" 59#include "plugin.h"
60#include "navit_nls.h" 60#include "navit_nls.h"
61 61
62/* #define DEBUG */ 62/* #define DEBUG */
63 63
64
65
66
67
68
69// #define NAVIT_FUNC_CALLS_DEBUG_PRINT 1
70
71
72// --------------- debug function calls ------------------
73// --------------- debug function calls ------------------
74#ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
75 #undef return2
76 #define return2 dbg_func(0, global_func_indent_counter, "return(%d)\n", __LINE__);global_func_indent_counter--;return
77
78 #define __F_START__ global_func_indent_counter++;dbg_func(0, global_func_indent_counter, "enter\n");
79 #define __F_END__ dbg_func(0, global_func_indent_counter, "leave\n");global_func_indent_counter--;
80#else
81 #undef return2
82 #define return2 return
83
84 #define __F_START__
85 #define __F_END__
86#endif
87// --------------- debug function calls ------------------
88// --------------- debug function calls ------------------
89
90
91
92
93
94
95
64static int roundabout_extra_length = 50; 96static int roundabout_extra_length = 50;
65 97
66struct suffix 98struct suffix
67{ 99{
68 char *fullname; 100 char *fullname;
92 struct callback *route_cb; 124 struct callback *route_cb;
93 int announce[route_item_last - route_item_first + 1][3]; 125 int announce[route_item_last - route_item_first + 1][3];
94 int tell_street_name; 126 int tell_street_name;
95 int delay; 127 int delay;
96 int curr_delay; 128 int curr_delay;
129 struct navigation_itm *previous;
130 struct navigation_command *cmd_previous;
97}; 131};
98 132
99int distances[] = { 1, 2, 3, 4, 5, 10, 25, 50, 75, 100, 150, 200, 250, 300, 400, 500, 750, -1 }; 133int distances[] = { 1, 2, 3, 4, 5, 10, 25, 50, 75, 100, 150, 200, 250, 300, 400, 500, 750, -1 };
134
135
136
137
138
139
140// -- NEW 002 --
141/* Allowed values for navigation_maneuver.merge_or_exit
142 * The numeric values are chosen in such a way that they can be interpreted as flags:
143 * 1=merge, 2=exit, 4=interchange, 8=right, 16=left
144 * Identifiers were chosen over flags to enforce certain rules
145 * (merge/exit/interchange and left/right are mutually exclusive, left/right requires merge or exit). */
146//FIXME: should we make this an enum?
147
148/** Not merging into or exiting from a motorway_like road */
149#define mex_none 0
150
151/** Merging into a motorway-like road, direction undefined */
152//FIXME: do we need this constant?
153#define mex_merge 1
154
155/** Exiting from a motorway-like road, direction undefined.
156 * This should only be used for ramps leading to a non-motorway road.
157 * For interchanges, use {@code mex_interchange} instead. */
158//FIXME: do we need this constant?
159#define mex_exit 2
160
161/** Motorway-like road splits in two.
162 * This should be used for all cases in which ramps lead to another motorway-like road. */
163#define mex_interchange 4
164
165/** Merging into a motorway-like road to the right (coming from the left) */
166#define mex_merge_right 9
167
168/** Exiting from a motorway-like road to the right.
169 * See {@code mex_exit} for usage. */
170#define mex_exit_right 10
171
172/** Merging into a motorway-like road to the left (coming from the right) */
173#define mex_merge_left 17
174
175/** Exiting from a motorway-like road to the left.
176 * See {@code mex_exit} for usage. */
177#define mex_exit_left 18
178
179/**
180 * @brief Holds information about a navigation maneuver.
181 *
182 * This structure is populated when a navigation maneuver is first analyzed. Its members contain all information
183 * needed to decide whether or not to announce the maneuver, what type of maneuver it is and the information that
184 * was used to determine the former two.
185 */
186struct navigation_maneuver {
187 enum item_type type; /**< The type of maneuver to perform. Any {@code nav_*} item is permitted here, with one exception:
188 merge or exit maneuvers are indicated by the {@code merge_or_exit} member. The {@code item_type}
189 for such maneuvers should be a turn instruction in cases where the maneuver is ambiguous, or
190 {@code nav_none} for cases in which we would expect the driver to perform this maneuver even
191 without being instructed to do so. **/
192 int delta; /**< Bearing difference (the angle the driver has to steer) for the maneuver */
193 int merge_or_exit; /**< Whether we are merging into or exiting from a motorway_like road or we are at an interchange */
194 int is_complex_t_junction; /**< Whether we are coming from the "stem" of a T junction whose "bar" is a dual-carriageway road and
195 crossing the opposite lane of the "bar" first (i.e. turning left in countries that drive on the
196 right, or turning right in countries that drive on the left). For these maneuvers
197 {@code num_options} is 1 (which means we normally wouldn't announce the maneuver) but drivers
198 would expect an announcement in such cases. */
199 int num_options; /**< Number of permitted candidate ways, i.e. ways which we may enter (based on access flags of the
200 way but without considering turn restrictions). Permitted candidate ways include the route. */
201 int num_new_motorways; /**< Number of permitted candidate ways that are motorway-like */
202 int num_other_ways; /**< Number of permitted candidate ways that are neither ramps nor motorway-like */
203 int old_cat; /**< Maneuver category of the way leading to the maneuver */
204 int new_cat; /**< Maneuver category of the selected way after the maneuver */
205 int max_cat; /**< Highest maneuver category of any permitted candidate way other than the route */
206 int num_similar_ways; /**< Number of candidate ways (including the route) that have a {@code maneuver_category()} similar
207 to {@code old_cat}. See {@code maneuver_required2()} for definition of "similar". */
208 int left; /**< Minimum bearing delta of any candidate way left of the route, -180 for none */
209 int right; /**< Minimum bearing delta of any candidate way right of the route, 180 for none */
210 int is_unambiguous; /**< Whether the maneuver is unambiguous. A maneuver is unambiguous if, despite
211 multiple candidate way being available, we can reasonable expect the driver to
212 continue on the route without being told to do so. This is typically the case when
213 the route stays on the main road and goes straight, while all other candidate ways
214 are minor roads and involve a significant turn. */
215 int is_same_street; /**< Whether the street keeps its name after the maneuver. */
216};
217// -- NEW 002 --
218
219
220
221
100 222
101struct navigation_command 223struct navigation_command
102{ 224{
103 struct navigation_itm *itm; 225 struct navigation_itm *itm;
104 struct navigation_command *next; 226 struct navigation_command *next;
105 struct navigation_command *prev; 227 struct navigation_command *prev;
106 int delta; 228 int delta;
107 int roundabout_delta; 229 int roundabout_delta;
108 int length; 230 int length;
231// -- NEW 002 --
232 struct navigation_maneuver *maneuver; /**< Details on the maneuver to perform */
233// -- NEW 002 --
109}; 234};
110 235
111static void navigation_flush(struct navigation *this_);
112 236
113/** 237
114 * @brief Calculates the delta between two angles 238
115 * @param angle1 The first angle 239
116 * @param angle2 The second angle 240
117 * @return The difference between the angles: -179..-1=angle2 is left of angle1,0=same,1..179=angle2 is right of angle1,180=angle1 is opposite of angle2 241
242// -- NEW 002 --
243/*@brief A linked list conataining the destination of the road
244 *
245 *
246 * Holds the destination info from the road, that is the place
247 * you drive to if you keep following the road as found on
248 * traffic sign's (ex. Paris, Senlis ...)
249 *
250 *
118 */ 251 */
119 252struct street_destination
120static int angle_delta(int angle1, int angle2)
121{ 253{
122 int delta = angle2 - angle1; 254 struct street_destination *next;
123 if (delta <= -180) 255 char *destination;
124 delta += 360; 256};
125 if (delta > 180) 257// -- NEW 002 --
126 delta -= 360;
127 return delta;
128}
129 258
130static int angle_median(int angle1, int angle2)
131{
132 int delta = angle_delta(angle1, angle2);
133 int ret = angle1 + delta / 2;
134 if (ret < 0)
135 ret += 360;
136 if (ret > 360)
137 ret -= 360;
138 return ret;
139}
140
141static int angle_opposite(int angle)
142{
143 return ((angle + 180) % 360);
144}
145
146int navigation_get_attr(struct navigation *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
147{
148 struct map_rect *mr;
149 struct item *item;
150 dbg(1, "enter %s\n", attr_to_name(type));
151 switch (type)
152 {
153 case attr_map:
154 attr->u.map = this_->map;
155 break;
156 case attr_item_type:
157 case attr_length:
158 case attr_navigation_speech:
159 mr = map_rect_new(this_->map, NULL);
160 while ((item = map_rect_get_item(mr)))
161 {
162 if (item->type != type_nav_none && item->type != type_nav_position)
163 {
164 if (type == attr_item_type)
165 attr->u.item_type = item->type;
166 else
167 {
168 if (!item_attr_get(item, type, attr))
169 item = NULL;
170 }
171 break;
172 }
173 }
174 map_rect_destroy(mr);
175 if (!item)
176 return 0;
177 break;
178 default:
179 return 0;
180 }
181 attr->type = type;
182 return 1;
183}
184
185int navigation_set_attr(struct navigation *this_, struct attr *attr)
186{
187 switch (attr->type)
188 {
189 case attr_speech:
190 this_->speech = attr->u.speech;
191 return 1;
192 default:
193 return 0;
194 }
195}
196
197struct navigation *
198navigation_new(struct attr *parent, struct attr **attrs)
199{
200 int i, j;
201 struct attr * attr;
202 struct navigation *ret=g_new0(struct navigation, 1);
203 ret->hash = item_hash_new();
204 ret->callback = callback_list_new();
205 ret->callback_speech = callback_list_new();
206 ret->level_last = -2;
207 ret->distance_turn = 50;
208 ret->turn_around_limit = 3;
209 ret->navit = parent->u.navit;
210 ret->tell_street_name = 1;
211
212 for (j = 0; j <= route_item_last - route_item_first; j++)
213 {
214 for (i = 0; i < 3; i++)
215 {
216 ret->announce[j][i] = -1;
217 }
218 }
219
220 if ((attr = attr_search(attrs, NULL, attr_tell_street_name)))
221 {
222 ret->tell_street_name = attr->u.num;
223 }
224 if ((attr = attr_search(attrs, NULL, attr_delay)))
225 {
226 ret->delay = attr->u.num;
227 }
228
229 return ret;
230}
231
232int navigation_set_announce(struct navigation *this_, enum item_type type, int *level)
233{
234 int i;
235 if (type < route_item_first || type > route_item_last)
236 {
237 dbg(0, "street type %d out of range [%d,%d]", type, route_item_first, route_item_last);
238 return 0;
239 }
240 for (i = 0; i < 3; i++)
241 this_->announce[type - route_item_first][i] = level[i];
242 return 1;
243}
244
245static int navigation_get_announce_level(struct navigation *this_, enum item_type type, int dist)
246{
247 int i;
248
249 if (type < route_item_first || type > route_item_last)
250 return -1;
251 for (i = 0; i < 3; i++)
252 {
253 if (dist <= this_->announce[type - route_item_first][i])
254 return i;
255 }
256 return i;
257}
258 259
259/** 260/**
260 * @brief Holds a way that one could possibly drive from a navigation item 261 * @brief Holds a way that one could possibly drive from a navigation item
261 */ 262 */
262struct navigation_way 263struct navigation_way
264 struct navigation_way *next; /**< Pointer to a linked-list of all navigation_ways from this navigation item */ 265 struct navigation_way *next; /**< Pointer to a linked-list of all navigation_ways from this navigation item */
265 short dir; /**< The direction -1 or 1 of the way */ 266 short dir; /**< The direction -1 or 1 of the way */
266 short angle2; /**< The angle one has to steer to drive from the old item to this street */ 267 short angle2; /**< The angle one has to steer to drive from the old item to this street */
267 int flags; /**< The flags of the way */ 268 int flags; /**< The flags of the way */
268 struct item item; /**< The item of the way */ 269 struct item item; /**< The item of the way */
269 char *name1; 270 char *name1; // = streetname
270 char *name2; 271 char *name2; // = streetname systematic (road number e.g.: E51)
272
273// -- NEW 002 --
274// char *name_systematic; /**< The road number ({@code street_name_systematic} attribute, OSM: {@code ref}) */
275 char *exit_ref; /**< Exit_ref if found on the first node of the way*/
276 char *exit_label; /**< Exit_label if found on the first node of the way*/
277 struct street_destination *s_destination; /**< The destination this way leads to (OSM: {@code destination}) */
278 char *street_dest_text; /* selected destination to display in GUI */
279// -- NEW 002 --
280
271}; 281};
272 282
273struct navigation_itm 283struct navigation_itm
274{ 284{
275 struct navigation_way way; 285 struct navigation_way way;
285 int dest_count; 295 int dest_count;
286 struct navigation_itm *next; 296 struct navigation_itm *next;
287 struct navigation_itm *prev; 297 struct navigation_itm *prev;
288}; 298};
289 299
300
301
302
303
304
305
306
307
308
309
310
311
312static void navigation_flush(struct navigation *this_);
313
314/**
315 * @brief Calculates the delta between two angles
316 * @param angle1 The first angle
317 * @param angle2 The second angle
318 * @return The difference between the angles: -179..-1=angle2 is left of angle1,0=same,1..179=angle2 is right of angle1,180=angle1 is opposite of angle2
319 */
320
321static int angle_delta(int angle1, int angle2)
322{
323 int delta = angle2 - angle1;
324
325 if (delta <= -180)
326 delta += 360;
327
328 if (delta > 180)
329 delta -= 360;
330
331 return delta;
332}
333
334static int angle_median(int angle1, int angle2)
335{
336 int delta = angle_delta(angle1, angle2);
337 int ret = angle1 + delta / 2;
338
339 if (ret < 0)
340 ret += 360;
341
342 if (ret > 360)
343 ret -= 360;
344
345 return ret;
346}
347
348static int angle_opposite(int angle)
349{
350 return ((angle + 180) % 360);
351}
352
353int navigation_get_attr(struct navigation *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
354{
355 struct map_rect *mr;
356 struct item *item;
357 // dbg(1, "enter %s\n", attr_to_name(type));
358 switch (type)
359 {
360 case attr_map:
361 attr->u.map = this_->map;
362 break;
363 case attr_item_type:
364 case attr_length:
365 case attr_navigation_speech:
366 mr = map_rect_new(this_->map, NULL);
367 while ((item = map_rect_get_item(mr)))
368 {
369 if (item->type != type_nav_none && item->type != type_nav_position)
370 {
371 if (type == attr_item_type)
372 attr->u.item_type = item->type;
373 else
374 {
375 if (!item_attr_get(item, type, attr))
376 item = NULL;
377 }
378 break;
379 }
380 }
381 map_rect_destroy(mr);
382 if (!item)
383 return 0;
384 break;
385 default:
386 return 0;
387 }
388 attr->type = type;
389 return 1;
390}
391
392int navigation_set_attr(struct navigation *this_, struct attr *attr)
393{
394 switch (attr->type)
395 {
396 case attr_speech:
397 this_->speech = attr->u.speech;
398 return 1;
399 default:
400 return 0;
401 }
402}
403
404struct navigation *
405navigation_new(struct attr *parent, struct attr **attrs)
406{
407 int i, j;
408 struct attr * attr;
409 struct navigation *ret=g_new0(struct navigation, 1);
410 ret->hash = item_hash_new();
411 ret->callback = callback_list_new("navigation_new:ret->callback");
412 ret->callback_speech = callback_list_new("navigation_new:ret->callback_speech");
413 ret->level_last = -2;
414 ret->distance_turn = 50;
415 ret->turn_around_limit = 3;
416 ret->navit = parent->u.navit;
417 ret->tell_street_name = 1;
418 ret->previous = NULL;
419 ret->cmd_previous = NULL;
420
421 for (j = 0; j <= route_item_last - route_item_first; j++)
422 {
423 for (i = 0; i < 3; i++)
424 {
425 ret->announce[j][i] = -1;
426 }
427 }
428
429 if ((attr = attr_search(attrs, NULL, attr_tell_street_name)))
430 {
431 ret->tell_street_name = attr->u.num;
432 }
433 if ((attr = attr_search(attrs, NULL, attr_delay)))
434 {
435 ret->delay = attr->u.num;
436 }
437
438 return ret;
439}
440
441int navigation_set_announce(struct navigation *this_, enum item_type type, int *level)
442{
443 int i;
444 if (type < route_item_first || type > route_item_last)
445 {
446 dbg(0, "street type %d out of range [%d,%d]", type, route_item_first, route_item_last);
447 return 0;
448 }
449
450 for (i = 0; i < 3; i++)
451 {
452 // dbg(0, "announce=%d type=%s\n", level[i], item_to_name(type));
453 this_->announce[type - route_item_first][i] = level[i];
454 }
455
456 return 1;
457}
458
459// global var ------------
460static int level_static_for_bicycle[3];
461// global var ------------
462
463
464
465// ------------------------------------
466// returns: "0", "1", "2" or "3"
467// ------------------------------------
468static int navigation_get_announce_level(struct navigation *this_, enum item_type type, int dist)
469{
470 int i;
471
472 if (type < route_item_first || type > route_item_last)
473 {
474 return -1;
475 }
476
477 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
478 {
479 for (i = 0; i < 3; i++)
480 {
481 // dbg(0, "loop(a) i=%d type=%s, route_item_first=%x, announce=%d, dist=%d\n", i, item_to_name(type), route_item_first, level_static_for_bicycle[i], dist);
482 if (dist <= level_static_for_bicycle[i])
483 {
484 //dbg(0, "ret(1a)=%d\n", i);
485 return i;
486 }
487 }
488 }
489 else
490 {
491 for (i = 0; i < 3; i++)
492 {
493 //dbg(0, "loop(b) i=%d type=%s, route_item_first=%x, announce=%d, dist=%d\n", i, item_to_name(type), route_item_first, (this_->announce[type - route_item_first][i]), dist);
494 if (dist <= this_->announce[type - route_item_first][i])
495 {
496 //dbg(0, "ret(1b)=%d\n", i);
497 return i;
498 }
499 }
500 }
501 //dbg(0, "ret(2)=%d\n", i);
502 return i;
503}
504
505
290static int is_way_allowed(struct navigation *nav, struct navigation_way *way, int mode); 506static int is_way_allowed(struct navigation *nav, struct navigation_way *way, int mode);
291 507
292static int navigation_get_announce_level_cmd(struct navigation *this_, struct navigation_itm *itm, struct navigation_command *cmd, int distance) 508static int navigation_get_announce_level_cmd(struct navigation *this_, struct navigation_itm *itm, struct navigation_command *cmd, int distance)
293{ 509{
294 int level2, level = navigation_get_announce_level(this_, itm->way.item.type, distance); 510 int level2, level = navigation_get_announce_level(this_, itm->way.item.type, distance);
511
295 if (this_->cmd_first->itm->prev) 512 if (this_->cmd_first->itm->prev)
296 { 513 {
297 level2 = navigation_get_announce_level(this_, cmd->itm->prev->way.item.type, distance); 514 level2 = navigation_get_announce_level(this_, cmd->itm->prev->way.item.type, distance);
298 if (level2 > level) 515 if (level2 > level)
516 {
299 level = level2; 517 level = level2;
300 } 518 }
519 }
520
301 return level; 521 return level;
302} 522}
303 523
304/* 0=N,90=E */ 524/* 0=N,90=E */
305static int road_angle(struct coord *c1, struct coord *c2, int dir) 525static int road_angle(struct coord *c1, struct coord *c2, int dir)
306{ 526{
527 // COST: 006
528 dbg(0, "COST:006\n");
529
307 int ret = transform_get_angle_delta(c1, c2, dir); 530 int ret = transform_get_angle_delta(c1, c2, dir);
308 // dbg(1, "road_angle(0x%x,0x%x - 0x%x,0x%x)=%d\n", c1->x, c1->y, c2->x, c2->y, ret); 531 // dbg(1, "road_angle(0x%x,0x%x - 0x%x,0x%x)=%d\n", c1->x, c1->y, c2->x, c2->y, ret);
309 return ret; 532 return ret;
310} 533}
311 534
484 return _("ninth exit"); 707 return _("ninth exit");
485 default: 708 default:
486 return NULL; 709 return NULL;
487 } 710 }
488} 711}
712
489static int round_distance(int dist) 713static int round_distance(int dist)
490{ 714{
491 if (dist < 100) 715 if (dist < 100)
492 { 716 {
493 dist = (dist + 5) / 10; 717 dist = (dist + 5) / 10;
522 return dist * 10000; 746 return dist * 10000;
523} 747}
524 748
525static int round_for_vocabulary(int vocabulary, int dist, int factor) 749static int round_for_vocabulary(int vocabulary, int dist, int factor)
526{ 750{
751
752 //dbg(0, "DIST_FEET:rfv:001:d=%d f=%d\n", dist, factor);
753
527 if (!(vocabulary & 256)) 754 //if (!(vocabulary & 256))
528 { 755 //{
529 if (factor != 1) 756 if (factor != 1)
757 {
530 dist = (dist + factor / 2) / factor; 758 dist = (dist + factor / 2) / factor;
759 //dbg(0, "DIST_FEET:rfv:002:d=%d\n", dist);
531 } 760 }
761 //}
532 else 762 //else
763 //{
533 factor = 1; 764 // factor = 1;
765 //}
766
534 if (!(vocabulary & 255)) 767 if (!(vocabulary & 255))
535 { 768 {
536 int i = 0, d = 0, m = 0; 769 int i = 0, d = 0, m = 0;
537 while (distances[i] > 0) 770 while (distances[i] > 0)
538 { 771 {
539 if (!i || abs(distances[i] - dist) <= d) 772 if (!i || abs(distances[i] - dist) <= d)
540 { 773 {
541 d = abs(distances[i] - dist); 774 d = abs(distances[i] - dist);
775 //dbg(0, "DIST_FEET:rfv:003:d=%d\n", dist);
542 m = i; 776 m = i;
543 } 777 }
778
544 if (distances[i] > dist) 779 if (distances[i] > dist)
780 {
545 break; 781 break;
782 }
546 i++; 783 i++;
547 } 784 }
548 // dbg(0, "converted %d to %d with factor %d\n", dist, distances[m], factor); 785 // dbg(0, "converted %d to %d with factor %d\n", dist, distances[m], factor);
549 dist = distances[m]; 786 dist = distances[m];
550 } 787 }
788
789 //dbg(0, "DIST_FEET:rfv:002:d=%d f=%d res=%d\n", dist, factor, dist * factor);
790
551 return dist * factor; 791 return dist * factor;
552} 792}
553 793
554static int vocabulary_last(int vocabulary) 794static int vocabulary_last(int vocabulary)
555{ 795{
556 int i = 0; 796 int i = 0;
797
557 if (vocabulary == 65535) 798 if (vocabulary == 65535)
799 {
558 return 1000; 800 return 1000;
801 }
802
559 while (distances[i] > 0) 803 while (distances[i] > 0)
804 {
560 i++; 805 i++;
806 }
807
561 return distances[i - 1]; 808 return distances[i - 1];
562} 809}
563 810
564static char * 811static char *
565get_distance(struct navigation *nav, int dist, enum attr_type type, int is_length) 812get_distance(struct navigation *nav, int dist, enum attr_type type, int is_length)
566{ 813{
814 int imperial = 0;
567 int imperial = 0, vocabulary = 65535; 815 int vocabulary = 65535;
568 struct attr attr; 816 struct attr attr;
569 817
570 if (type == attr_navigation_long) 818 if (type == attr_navigation_long)
571 { 819 {
572 if (is_length) 820 if (is_length)
586#endif 834#endif
587#endif 835#endif
588 return g_strdup_printf(_("in %d m"), dist); 836 return g_strdup_printf(_("in %d m"), dist);
589 } 837 }
590 } 838 }
839
591 if (navit_get_attr(nav->navit, attr_imperial, &attr, NULL)) 840 if (navit_get_attr(nav->navit, attr_imperial, &attr, NULL))
841 {
592 imperial = attr.u.num; 842 imperial = attr.u.num;
843 }
844
593 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_distances, &attr, NULL)) 845 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_distances, &attr, NULL))
846 {
594 vocabulary = attr.u.num; 847 vocabulary = attr.u.num;
848 }
849
595 if (imperial) 850 if (imperial)
596 { 851 {
852 //dbg(0, "DIST_FEET:001:d=%d\n", dist);
853
597 if (dist * FEET_PER_METER < vocabulary_last(vocabulary)) 854 // if (dist * FEET_PER_METER < vocabulary_last(vocabulary))
855 if (dist * FEET_PER_METER < 5300) // fix for "0"-miles later!!
856 {
857 if (( dist * FEET_PER_METER ) > 1900)
598 { 858 {
859 //dbg(0, "DIST_FEET:002a:d=%d m=%d\n", dist, (int)(dist * FEET_PER_METER));
860 dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER, 500);
861 }
862 else if (( dist * FEET_PER_METER ) > 290)
863 {
864 //dbg(0, "DIST_FEET:002a:d=%d m=%d\n", dist, (int)(dist * FEET_PER_METER));
865 dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER, 100);
866 }
867 else if (( dist * FEET_PER_METER ) > 25)
868 {
869 //dbg(0, "DIST_FEET:002a:d=%d m=%d\n", dist, (int)(dist * FEET_PER_METER));
870 dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER, 20);
871 }
872 else
873 {
874 //dbg(0, "DIST_FEET:002b:d=%d m=%d\n", dist, dist * FEET_PER_METER);
599 dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER, 1); 875 dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER, 1);
876 }
877
878 //dbg(0, "DIST_FEET:002:d=%d v=%d\n", dist, vocabulary);
879
600 if (is_length) 880 if (is_length)
601 { 881 {
602#ifdef HAVE_API_ANDROID 882#ifdef HAVE_API_ANDROID
603#ifdef NAVIT_SAY_DEBUG_PRINT 883#ifdef NAVIT_SAY_DEBUG_PRINT
604 android_send_generic_text(1,"+*#O:%d feet\n"); 884 android_send_generic_text(1,"+*#O:%d feet\n");
646#endif 926#endif
647 return g_strdup_printf(_("in %d meters"), dist); 927 return g_strdup_printf(_("in %d meters"), dist);
648 } 928 }
649 } 929 }
650 } 930 }
931
651 if (imperial) 932 if (imperial)
652 { 933 {
934 //dbg(0, "DIST_FEET:003:d=%d v=%d\n", dist, vocabulary);
653 dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER * 1000 / FEET_PER_MILE, 1000); 935 dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER * 1000 / FEET_PER_MILE, 1000);
936 //dbg(0, "DIST_FEET:004:d=%d v=%d\n", dist, vocabulary);
654 } 937 }
655 else 938 else
656 { 939 {
657 dist = round_for_vocabulary(vocabulary, dist, 1000); 940 dist = round_for_vocabulary(vocabulary, dist, 1000);
658 } 941 }
678#ifdef HAVE_API_ANDROID 961#ifdef HAVE_API_ANDROID
679#ifdef NAVIT_SAY_DEBUG_PRINT 962#ifdef NAVIT_SAY_DEBUG_PRINT
680 android_send_generic_text(1,"+*#O:in %d.%d miles\n"); 963 android_send_generic_text(1,"+*#O:in %d.%d miles\n");
681#endif 964#endif
682#endif 965#endif
966 //dbg(0, "DIST_FEET:005:d/1000=%d rem=%d\n", dist / 1000, rem);
967
683 return g_strdup_printf(_("in %d.%d miles"), dist / 1000, rem); 968 return g_strdup_printf(_("in %d.%d miles"), dist / 1000, rem);
684 } 969 }
685 } 970 }
686 else 971 else
687 { 972 {
704 return g_strdup_printf(_("in %d.%d kilometers"), dist / 1000, rem); 989 return g_strdup_printf(_("in %d.%d kilometers"), dist / 1000, rem);
705 } 990 }
706 } 991 }
707 } 992 }
708 } 993 }
994
709 if (imperial) 995 if (imperial)
710 { 996 {
711 if (is_length) 997 if (is_length)
998 {
712 return g_strdup_printf(ngettext("one mile", "%d miles", dist / 1000), dist / 1000); 999 return g_strdup_printf(ngettext("one mile", "%d miles", dist / 1000), dist / 1000);
1000 }
713 else 1001 else
1002 {
1003 //dbg(0, "DIST_FEET:006:d/1000=%d\n", dist / 1000);
1004
714 return g_strdup_printf(ngettext("in one mile", "in %d miles", dist / 1000), dist / 1000); 1005 return g_strdup_printf(ngettext("in one mile", "in %d miles", dist / 1000), dist / 1000);
1006 }
715 } 1007 }
716 else 1008 else
717 { 1009 {
718 if (is_length) 1010 if (is_length)
719 { 1011 {
733#endif 1025#endif
734 return g_strdup_printf(ngettext("in one kilometer", "in %d kilometers", dist / 1000), dist / 1000); 1026 return g_strdup_printf(ngettext("in one kilometer", "in %d kilometers", dist / 1000), dist / 1000);
735 } 1027 }
736 } 1028 }
737} 1029}
1030
1031static int navigation_get_real_item_first_coord(struct navigation_way *w, struct coord *c)
1032{
1033 struct item *ritem = NULL; // the "real" item
1034 struct map_rect *mr;
1035 struct attr attr;
1036 struct coord c2[5];
1037
1038
1039#if 1
1040 if (!w)
1041 {
1042 return 0;
1043 }
1044
1045 if (!w->item.map)
1046 {
1047 return 0;
1048 }
1049
1050 if ((!w->item.id_hi) && (w->item.id_lo))
1051 {
1052 return 0;
1053 }
1054
1055 mr = map_rect_new(w->item.map, NULL);
1056
1057 if (!mr)
1058 {
1059 return 0;
1060 }
1061
1062 // COST: 001
1063 dbg(0, "COST:001\n");
1064 ritem = map_rect_get_item_byid(mr, w->item.id_hi, w->item.id_lo);
1065
1066 if (!ritem)
1067 {
1068 map_rect_destroy(mr);
1069 return 0;
1070 }
1071
1072 if (item_coord_get(ritem, c2, 2) == 2)
1073 {
1074 c[0].x = c2[0].x;
1075 c[0].y = c2[0].y;
1076 c[1].x = c2[1].x;
1077 c[1].y = c2[1].y;
1078
1079 map_rect_destroy(mr);
1080 return 1;
1081 }
1082
1083 map_rect_destroy(mr);
1084 return 0;
1085
1086#endif
1087}
1088
1089long long navigation_item_get_wayid(struct navigation_way *w)
1090{
1091 struct item *ritem; // the "real" item
1092 struct map_rect *mr;
1093 struct attr attr;
1094 long long ret = 0;
1095
1096 if (!w)
1097 {
1098 return ret;
1099 }
1100
1101 if (!w->item.map)
1102 {
1103 return ret;
1104 }
1105
1106 if ((!w->item.id_hi) && (w->item.id_lo))
1107 {
1108 return ret;
1109 }
1110
1111 mr = map_rect_new(w->item.map, NULL);
1112
1113 if (!mr)
1114 {
1115 return ret;
1116 }
1117
1118 // COST: 002
1119 dbg(0, "COST:002\n");
1120 ritem = map_rect_get_item_byid(mr, w->item.id_hi, w->item.id_lo);
1121
1122 if (!ritem)
1123 {
1124 map_rect_destroy(mr);
1125 return ret;
1126 }
1127
1128 if (item_attr_get(ritem, attr_osm_wayid, &attr))
1129 {
1130 // dbg(0, "START:attr.u.num64=%x attr.u.num64=%lld\n", attr.u.num64, attr.u.num64);
1131 if (attr.u.num64)
1132 {
1133 ret = *attr.u.num64;
1134 }
1135 // dbg(0, "END:attr.u.num64\n");
1136 }
1137
1138 map_rect_destroy(mr);
1139
1140 // dbg(0, "return 099\n");
1141
1142 return ret;
1143}
1144
1145int navigation_item_get_flags(struct navigation_way *w)
1146{
1147 struct item *ritem; // the "real" item
1148 struct map_rect *mr;
1149 struct attr attr;
1150 long long ret = 0;
1151
1152 if (!w)
1153 {
1154 return ret;
1155 }
1156
1157
1158 // -----------------------------------------
1159 // -----------------------------------------
1160 // flags should be there already!?
1161 if (w->flags != 0)
1162 {
1163 // we already have flags set!
1164 return w->flags;
1165 }
1166 // -----------------------------------------
1167 // -----------------------------------------
1168
1169
1170 if (!w->item.map)
1171 {
1172 return ret;
1173 }
1174
1175 if ((!w->item.id_hi) && (w->item.id_lo))
1176 {
1177 return ret;
1178 }
1179
1180 mr = map_rect_new(w->item.map, NULL);
1181
1182 if (!mr)
1183 {
1184 return ret;
1185 }
1186
1187 // COST: 003
1188 dbg(0, "COST:003\n");
1189 ritem = map_rect_get_item_byid(mr, w->item.id_hi, w->item.id_lo);
1190
1191 if (!ritem)
1192 {
1193 map_rect_destroy(mr);
1194 return ret;
1195 }
1196
1197 if (item_attr_get(ritem, attr_flags, &attr))
1198 {
1199 ret = attr.u.num;
1200 // also set the flags here!!
1201 w->flags = ret;
1202 }
1203 else
1204 {
1205 w->flags = 0;
1206 }
1207
1208 map_rect_destroy(mr);
1209
1210 // dbg(0, "return 099\n");
1211
1212 return ret;
1213}
1214
738 1215
739/** 1216/**
740 * @brief This calculates the angle with which an item starts or ends 1217 * @brief This calculates the angle with which an item starts or ends
741 * 1218 *
742 * This function can be used to get the angle an item (from a route graph map) 1219 * This function can be used to get the angle an item (from a route graph map)
756 struct map_rect *mr; 1233 struct map_rect *mr;
757 struct attr attr; 1234 struct attr attr;
758 1235
759 w->angle2 = 361; 1236 w->angle2 = 361;
760 mr = map_rect_new(w->item.map, NULL); 1237 mr = map_rect_new(w->item.map, NULL);
1238
761 if (!mr) 1239 if (!mr)
1240 {
762 return; 1241 return;
1242 }
763 1243
1244 // COST: 004
1245 dbg(0, "COST:004\n");
764 ritem = map_rect_get_item_byid(mr, w->item.id_hi, w->item.id_lo); 1246 ritem = map_rect_get_item_byid(mr, w->item.id_hi, w->item.id_lo);
1247
765 if (!ritem) 1248 if (!ritem)
766 { 1249 {
767 dbg(1, "Item from segment not found on map!\n"); 1250 // dbg(1, "Item from segment not found on map!\n");
768 map_rect_destroy(mr); 1251 map_rect_destroy(mr);
769 return; 1252 return;
770 } 1253 }
771 1254
772 if (ritem->type < type_line || ritem->type >= type_area) 1255 if (ritem->type < type_line || ritem->type >= type_area)
773 { 1256 {
774 map_rect_destroy(mr); 1257 map_rect_destroy(mr);
775 return; 1258 return;
776 } 1259 }
1260
1261
777 if (item_attr_get(ritem, attr_flags, &attr)) 1262 if (item_attr_get(ritem, attr_flags, &attr))
1263 {
778 w->flags = attr.u.num; 1264 w->flags = attr.u.num;
1265 }
779 else 1266 else
1267 {
780 w->flags = 0; 1268 w->flags = 0;
1269 }
1270 // dbg(0, "w->flags=%x\n", w->flags);
1271
1272
781 if (item_attr_get(ritem, attr_street_name, &attr)) 1273 if (item_attr_get(ritem, attr_street_name, &attr))
1274 {
782 w->name1 = map_convert_string(ritem->map, attr.u.str); 1275 w->name1 = map_convert_string(ritem->map, attr.u.str);
1276 }
783 else 1277 else
1278 {
784 w->name1 = NULL; 1279 w->name1 = NULL;
1280 }
1281
1282
785 if (item_attr_get(ritem, attr_street_name_systematic, &attr)) 1283 if (item_attr_get(ritem, attr_street_name_systematic, &attr))
1284 {
786 w->name2 = map_convert_string(ritem->map, attr.u.str); 1285 w->name2 = map_convert_string(ritem->map, attr.u.str);
1286 }
787 else 1287 else
1288 {
788 w->name2 = NULL; 1289 w->name2 = NULL;
1290 }
1291
789 1292
790 if (w->dir < 0) 1293 if (w->dir < 0)
791 { 1294 {
792 if (item_coord_get(ritem, cbuf, 2) != 2) 1295 if (item_coord_get(ritem, cbuf, 2) != 2)
793 { 1296 {
794 dbg(1, "Using calculate_angle() with a less-than-two-coords-item?\n"); 1297 // dbg(1, "Using calculate_angle() with a less-than-two-coords-item?\n");
795 map_rect_destroy(mr); 1298 map_rect_destroy(mr);
796 return; 1299 return;
797 } 1300 }
798 1301
799 while (item_coord_get(ritem, &c, 1)) 1302 while (item_coord_get(ritem, &c, 1))
805 } 1308 }
806 else 1309 else
807 { 1310 {
808 if (item_coord_get(ritem, cbuf, 2) != 2) 1311 if (item_coord_get(ritem, cbuf, 2) != 2)
809 { 1312 {
810 dbg(1, "Using calculate_angle() with a less-than-two-coords-item?\n"); 1313 // dbg(1, "Using calculate_angle() with a less-than-two-coords-item?\n");
811 map_rect_destroy(mr); 1314 map_rect_destroy(mr);
812 return; 1315 return;
813 } 1316 }
1317
814 c = cbuf[0]; 1318 c = cbuf[0];
815 cbuf[0] = cbuf[1]; 1319 cbuf[0] = cbuf[1];
816 cbuf[1] = c; 1320 cbuf[1] = c;
817 } 1321 }
818 1322
855 } 1359 }
856 1360
857 return time; 1361 return time;
858} 1362}
859 1363
1364
1365
1366// -- NEW 002 --
1367static void navigation_free_list(struct street_destination *list)
1368{
1369 if (list)
1370 {
1371 struct street_destination *clist = NULL;
1372 while (list)
1373 {
1374 clist = list->next;
1375 if (list->destination)
1376 {
1377 g_free(list->destination);
1378 }
1379
1380 g_free(list);
1381 list = clist;
1382 }
1383 list = NULL;
1384 }
1385}
1386// -- NEW 002 --
1387
1388
1389
1390
1391
860/** 1392/**
861 * @brief Clears the ways one can drive from itm 1393 * @brief Clears the ways one can drive from itm
862 * 1394 *
863 * @param itm The item that should have its ways cleared 1395 * @param itm The item that should have its ways cleared
864 */ 1396 */
870 while (c) 1402 while (c)
871 { 1403 {
872 n = c->next; 1404 n = c->next;
873 map_convert_free(c->name1); 1405 map_convert_free(c->name1);
874 map_convert_free(c->name2); 1406 map_convert_free(c->name2);
1407
1408 if (c->exit_ref)
1409 {
1410 g_free(c->exit_ref);
1411 c->exit_ref = NULL;
1412 }
1413
1414 if (c->exit_label)
1415 {
1416 g_free(c->exit_label);
1417 c->exit_label = NULL;
1418 }
1419
1420 if (c->street_dest_text)
1421 {
1422 g_free(c->street_dest_text);
1423 c->street_dest_text = NULL;
1424 }
1425
1426 if (c->s_destination)
1427 {
1428 navigation_free_list(c->s_destination);
1429 }
1430
875 g_free(c); 1431 g_free(c);
1432 c = NULL;
1433
876 c = n; 1434 c = n;
877 } 1435 }
878 1436
879 itm->way.next = NULL; 1437 itm->way.next = NULL;
880} 1438}
892{ 1450{
893 struct map_selection coord_sel; 1451 struct map_selection coord_sel;
894 struct map_rect *g_rect; // Contains a map rectangle from the route graph's map 1452 struct map_rect *g_rect; // Contains a map rectangle from the route graph's map
895 struct item *i, *sitem; 1453 struct item *i, *sitem;
896 struct attr sitem_attr, direction_attr; 1454 struct attr sitem_attr, direction_attr;
1455 // struct attr flags_attr;
897 struct navigation_way *w, *l; 1456 struct navigation_way *w, *l;
898 1457
899 navigation_itm_ways_clear(itm); 1458 navigation_itm_ways_clear(itm);
900 1459
901 // These values cause the code in route.c to get us only the route graph point and connected segments 1460 // These values cause the code in route.c to get us only the route graph point and connected segments
905 // the selection's order is ignored 1464 // the selection's order is ignored
906 1465
907 g_rect = map_rect_new(graph_map, &coord_sel); 1466 g_rect = map_rect_new(graph_map, &coord_sel);
908 1467
909 i = map_rect_get_item(g_rect); 1468 i = map_rect_get_item(g_rect);
1469
910 if (!i || i->type != type_rg_point) 1470 if (!i || i->type != type_rg_point)
911 { // probably offroad? 1471 { // probably offroad?
912 return; 1472 return;
913 } 1473 }
914 1474
928 continue; 1488 continue;
929 } 1489 }
930 1490
931 if (!item_attr_get(i, attr_street_item, &sitem_attr)) 1491 if (!item_attr_get(i, attr_street_item, &sitem_attr))
932 { 1492 {
933 dbg(1, "Got no street item for route graph item in entering_straight()\n"); 1493 // dbg(1, "Got no street item for route graph item in entering_straight()\n");
934 continue; 1494 continue;
935 } 1495 }
936 1496
937 if (!item_attr_get(i, attr_direction, &direction_attr)) 1497 if (!item_attr_get(i, attr_direction, &direction_attr))
938 { 1498 {
939 continue; 1499 continue;
940 } 1500 }
941 1501
942 sitem = sitem_attr.u.item; 1502 sitem = sitem_attr.u.item;
1503
943 if (sitem->type == type_street_turn_restriction_no || sitem->type == type_street_turn_restriction_only) 1504 if (sitem->type == type_street_turn_restriction_no || sitem->type == type_street_turn_restriction_only)
1505 {
944 continue; 1506 continue;
1507 }
945 1508
946 if (item_is_equal(itm->way.item, *sitem) || ((itm->prev) && item_is_equal(itm->prev->way.item, *sitem))) 1509 if (item_is_equal(itm->way.item, *sitem) || ((itm->prev) && item_is_equal(itm->prev->way.item, *sitem)))
947 { 1510 {
948 continue; 1511 continue;
949 } 1512 }
950 1513
1514 //if (!item_attr_get(i, attr_flags, &flags_attr))
1515 //{
1516 // flags_attr.u.num = 0;
1517 //}
1518 //dbg(0, "w2->flags=%x\n", flags_attr.u.num);
1519
951 l = w; 1520 l = w;
952 w = g_new(struct navigation_way, 1); 1521 w = g_new0(struct navigation_way, 1);
953 w->dir = direction_attr.u.num; 1522 w->dir = direction_attr.u.num;
954 w->item = *sitem; 1523 w->item = *sitem;
955 w->next = l; 1524 w->next = l;
1525 // w->flags = flags_attr.u.num;
1526
956 calculate_angle(w); 1527 calculate_angle(w);
957 } 1528 }
958 1529
959 map_rect_destroy(g_rect); 1530 map_rect_destroy(g_rect);
960 1531
963 1534
964static void navigation_destroy_itms_cmds(struct navigation *this_, struct navigation_itm *end) 1535static void navigation_destroy_itms_cmds(struct navigation *this_, struct navigation_itm *end)
965{ 1536{
966 struct navigation_itm *itm; 1537 struct navigation_itm *itm;
967 struct navigation_command *cmd; 1538 struct navigation_command *cmd;
1539
968 // dbg(2, "enter this_=%p this_->first=%p this_->cmd_first=%p end=%p\n", this_, this_->first, this_->cmd_first, end); 1540 // dbg(2, "enter this_=%p this_->first=%p this_->cmd_first=%p end=%p\n", this_, this_->first, this_->cmd_first, end);
1541
969 if (this_->cmd_first) 1542 if (this_->cmd_first)
970 { 1543 {
971 // dbg(2, "this_->cmd_first->itm=%p\n", this_->cmd_first->itm); 1544 // dbg(2, "this_->cmd_first->itm=%p\n", this_->cmd_first->itm);
972 } 1545 }
1546
973 while (this_->first && this_->first != end) 1547 while (this_->first && this_->first != end)
974 { 1548 {
975 itm = this_->first; 1549 itm = this_->first;
976 // dbg(3, "destroying %p\n", itm); 1550 // dbg(3, "destroying %p\n", itm);
977 item_hash_remove(this_->hash, &itm->way.item); 1551 item_hash_remove(this_->hash, &itm->way.item);
978 this_->first = itm->next; 1552 this_->first = itm->next;
1553
979 if (this_->first) 1554 if (this_->first)
1555 {
980 this_->first->prev = NULL; 1556 this_->first->prev = NULL;
1557 }
1558
981 if (this_->cmd_first && this_->cmd_first->itm == itm->next) 1559 if (this_->cmd_first && this_->cmd_first->itm == itm->next)
982 { 1560 {
983 cmd = this_->cmd_first; 1561 cmd = this_->cmd_first;
984 this_->cmd_first = cmd->next; 1562 this_->cmd_first = cmd->next;
985 if (cmd->next) 1563 if (cmd->next)
986 { 1564 {
987 cmd->next->prev = NULL; 1565 cmd->next->prev = NULL;
988 } 1566 }
989 g_free(cmd); 1567 g_free(cmd);
990 } 1568 }
1569
991 map_convert_free(itm->way.name1); 1570 map_convert_free(itm->way.name1);
992 map_convert_free(itm->way.name2); 1571 map_convert_free(itm->way.name2);
1572
1573 if (itm->way.s_destination)
1574 {
1575 navigation_free_list(itm->way.s_destination);
1576 }
1577
1578 if (itm->way.exit_ref)
1579 {
1580 g_free(itm->way.exit_ref);
1581 itm->way.exit_ref = NULL;
1582 }
1583
1584 if (itm->way.exit_label)
1585 {
1586 g_free(itm->way.exit_label);
1587 itm->way.exit_label = NULL;
1588 }
1589
1590 if (itm->way.street_dest_text)
1591 {
1592 g_free(itm->way.street_dest_text);
1593 itm->way.street_dest_text = NULL;
1594 }
1595
993 navigation_itm_ways_clear(itm); 1596 navigation_itm_ways_clear(itm);
1597
994 g_free(itm); 1598 g_free(itm);
1599 itm = NULL;
995 } 1600 }
1601
996 if (!this_->first) 1602 if (!this_->first)
1603 {
997 this_->last = NULL; 1604 this_->last = NULL;
1605 }
1606
998 if (!this_->first && end) 1607 if (!this_->first && end)
999 { 1608 {
1000 // dbg(0, "end wrong\n"); 1609 // dbg(0, "end wrong\n");
1001 } 1610 }
1002 // dbg(2, "ret this_->first=%p this_->cmd_first=%p\n", this_->first, this_->cmd_first);
1003} 1611}
1004 1612
1005static void navigation_itm_update(struct navigation_itm *itm, struct item *ritem) 1613static void navigation_itm_update(struct navigation_itm *itm, struct item *ritem)
1006{ 1614{
1007 struct attr length, time, speed; 1615 struct attr length, time, speed;
1009 if (!item_attr_get(ritem, attr_length, &length)) 1617 if (!item_attr_get(ritem, attr_length, &length))
1010 { 1618 {
1011 // dbg(0, "no length\n"); 1619 // dbg(0, "no length\n");
1012 return; 1620 return;
1013 } 1621 }
1622
1014 if (!item_attr_get(ritem, attr_time, &time)) 1623 if (!item_attr_get(ritem, attr_time, &time))
1015 { 1624 {
1016 // dbg(0, "no time\n"); 1625 // dbg(0, "no time\n");
1017 return; 1626 return;
1018 } 1627 }
1628
1019 if (!item_attr_get(ritem, attr_speed, &speed)) 1629 if (!item_attr_get(ritem, attr_speed, &speed))
1020 { 1630 {
1021 // dbg(0, "no time\n"); 1631 // dbg(0, "no speed\n");
1022 return; 1632 return;
1023 } 1633 }
1024 1634
1025 // dbg(1, "length=%d time=%d speed=%d\n", length.u.num, time.u.num, speed.u.num); 1635 // dbg(1, "length=%d time=%d speed=%d\n", length.u.num, time.u.num, speed.u.num);
1026 itm->length = length.u.num; 1636 itm->length = length.u.num;
1048 // the selection's order is ignored 1658 // the selection's order is ignored
1049 1659
1050 g_rect = map_rect_new(graph_map, &coord_sel); 1660 g_rect = map_rect_new(graph_map, &coord_sel);
1051 1661
1052 i = map_rect_get_item(g_rect); 1662 i = map_rect_get_item(g_rect);
1663
1053 if (!i || i->type != type_rg_point) 1664 if (!i || i->type != type_rg_point)
1665 {
1054 { // probably offroad? 1666 // probably offroad?
1055 map_rect_destroy(g_rect); 1667 map_rect_destroy(g_rect);
1056 return 0; 1668 return 0;
1057 } 1669 }
1058 1670
1059 while (1) 1671 while (1)
1087 } 1699 }
1088 1700
1089 map_rect_destroy(g_rect); 1701 map_rect_destroy(g_rect);
1090 return 0; 1702 return 0;
1091} 1703}
1704
1705
1706
1707// -- NEW 002 --
1708static int navigation_split_string_to_list(struct navigation_way *way, char* raw_string, char sep)
1709{
1710 struct street_destination *new_street_destination = NULL;
1711 struct street_destination *next_street_destination_remember = NULL;
1712 char *pos1 = raw_string;
1713 char *pos2 = NULL;
1714 int count = 0;
1715
1716 navigation_free_list(way->s_destination); /*in case this is a retry with a different separator.*/
1717
1718 //dbg(0,"raw_string=%s split with %c\n",raw_string, sep);
1719 if (strlen(raw_string) > 0)
1720 {
1721 count = 1;
1722 while (pos1)
1723 {
1724 new_street_destination = g_new0(struct street_destination, 1);
1725 new_street_destination->next = next_street_destination_remember;
1726 next_street_destination_remember = new_street_destination;
1727 if ((pos2 = strrchr(pos1, sep)) != NULL)
1728 {
1729 new_street_destination->destination = g_strdup(pos2 + 1);
1730 *pos2 = '\0' ;
1731 //dbg(0,"splitted_off_string=%s\n", new_street_destination->destination);
1732 count++;
1733 }
1734 else
1735 {
1736 new_street_destination->destination = g_strdup(pos1);
1737 pos1 = NULL;
1738 //dbg(0,"head_of_string=%s\n", new_street_destination->destination);
1739 }
1740 way->s_destination = next_street_destination_remember;
1741 }
1742 }
1743 return count;
1744}
1745
1746static int navigation_split_string_to_list_2(struct navigation_way *way, char* raw_string, char sep, char sep2)
1747{
1748 struct street_destination *new_street_destination = NULL;
1749 struct street_destination *next_street_destination_remember = NULL;
1750 char *pos1 = raw_string;
1751 char *pos2 = NULL;
1752 char *pos2a = NULL;
1753 char *pos2b = NULL;
1754 int count = 0;
1755
1756 navigation_free_list(way->s_destination); /*in case this is a retry with a different separator.*/
1757
1758 //dbg(0,"raw_string=%s split with %c\n",raw_string, sep);
1759 if (strlen(raw_string) > 0)
1760 {
1761 count = 1;
1762 while (pos1)
1763 {
1764 new_street_destination = g_new0(struct street_destination, 1);
1765 new_street_destination->next = next_street_destination_remember;
1766 next_street_destination_remember = new_street_destination;
1767
1768 pos2a = strrchr(pos1, sep);
1769 pos2b = strrchr(pos1, sep2);
1770
1771 if (pos2a == NULL)
1772 {
1773 if (pos2b != NULL)
1774 {
1775 pos2 = pos2b;
1776 }
1777 else
1778 {
1779 pos2 = NULL;
1780 }
1781 }
1782 else if (pos2b == NULL)
1783 {
1784 if (pos2a != NULL)
1785 {
1786 pos2 = pos2a;
1787 }
1788 else
1789 {
1790 pos2 = NULL;
1791 }
1792 }
1793 else // both NOT NULL
1794 {
1795 if (pos2a > pos2b)
1796 {
1797 pos2 = pos2b;
1798 }
1799 else
1800 {
1801 pos2 = pos2a;
1802 }
1803 }
1804
1805 if (pos2 != NULL)
1806 {
1807 new_street_destination->destination = g_strdup(pos2 + 1);
1808 *pos2 = '\0' ;
1809 //dbg(0,"splitted_off_string=%s\n", new_street_destination->destination);
1810 count++;
1811 }
1812 else
1813 {
1814 new_street_destination->destination = g_strdup(pos1);
1815 pos1 = NULL;
1816 //dbg(0,"head_of_string=%s\n", new_street_destination->destination);
1817 }
1818 way->s_destination = next_street_destination_remember;
1819 }
1820 }
1821 return count;
1822}
1823
1824// -- NEW 002 --
1825
1826
1827
1828
1829
1830
1831
1832
1833// -- NEW 002 --
1834/** @brief Selects the destination-names for the next announcement from the
1835 * destination-names that are registered in the following command items.
1836 *
1837 * The aim of this function is to find the destination-name entry that has the most hits in the following
1838 * command items so that the destination name has a relevance over several announcements. If there is no 'winner'
1839 * the entry is selected that is at top of the destination.
1840 */
1841static navigation_select_announced_destinations(struct navigation_command *current_command)
1842{
1843 struct street_destination *current_destination = NULL; /* the list pointer of the destination_names of the current command. */
1844 struct street_destination *search_destination = NULL; /* the list pointer of the destination_names of the respective search_command. */
1845
1846 struct navigation_command *search_command = NULL; /* loop through every navigation command up to the end. */
1847
1848 /* limits the number of entries of a destination sign as well as the number of command items to investigate */
1849 #define DEST_MAX_LOOPS_SIGN_TEXTS 10
1850 #define DEST_MAX_LOOPS_NAV_ITEMS 3
1851
1852 int destination_count[DEST_MAX_LOOPS_SIGN_TEXTS] = {0,0,0,0,0,0,0,0,0,0}; /* countains the hits of identical destination signs over all */
1853 /* investigated command items - a 'high score' of destination names */
1854
1855 int destination_index = 0;
1856 int search_command_counter = 0;
1857 int i;
1858 int max_hits;
1859 int max_hit_index;
1860 struct navigation_way *current_nav_way = NULL;
1861
1862 // put text into way struct later -----------------
1863 current_nav_way = &(current_command->itm->way);
1864 if ((current_nav_way) && (current_nav_way->street_dest_text))
1865 {
1866 // already have set a destination --> return
1867 return;
1868 }
1869 current_nav_way->street_dest_text = NULL; // set default to "no value"
1870 // put text into way struct later -----------------
1871
1872
1873 /* search over every following command for seeking identical destination_names */
1874 if (current_command->itm->way.s_destination)
1875 {
1876 /* can we investigate over the following commands? */
1877
1878 if (current_command->next)
1879 {
1880 /* loop over every destination sign of the current command, as far as there are not more than 10 entries. */
1881 destination_index = 0; /* Do only the first DEST_MAX_LOOPS_SIGN_TEXTS destination_signs */
1882 current_destination = current_command->itm->way.s_destination;
1883
1884 while (current_destination && (destination_index < DEST_MAX_LOOPS_SIGN_TEXTS))
1885 { /* initialize the search command */
1886
1887 search_command = current_command->next;
1888 search_command_counter = 0; // Do only the first DEST_MAX_LOOPS_NAV_ITEMS commands.
1889
1890 while (search_command && (search_command_counter < DEST_MAX_LOOPS_NAV_ITEMS))
1891 {
1892 if (search_command->itm)
1893 { /* has the search command any destination_signs? */
1894
1895 if (search_command->itm->way.s_destination)
1896 {
1897 search_destination = search_command->itm->way.s_destination;
1898
1899 while (search_destination)
1900 { /* Search this name in the destination list of the current command. */
1901
1902 if (0 == strcmp(current_destination->destination, search_destination->destination))
1903 { /* enter the destination_name in the investigation list*/
1904
1905 destination_count[destination_index]++;
1906 //search_destination = NULL; /* break condition */
1907 break;
1908 }
1909 else
1910 {
1911 search_destination = search_destination->next;
1912 }
1913 }
1914 }
1915 }
1916 search_command_counter++;
1917 search_command = search_command->next;
1918 }
1919
1920 destination_index++;
1921 current_destination = current_destination->next;
1922 }
1923
1924 /* search for the best candidate */
1925 max_hits = 0;
1926 max_hit_index = 0;
1927 for (i = 0; i < destination_index; i++)
1928 {
1929 if (destination_count[i] > max_hits)
1930 {
1931 max_hits = destination_count[i];
1932 max_hit_index = i;
1933 }
1934 }
1935 /* jump to the corresponding destination_name */
1936 current_destination = current_command->itm->way.s_destination;
1937 for (i = 0; i < max_hit_index; i++)
1938 {
1939 current_destination = current_destination->next;
1940 }
1941 }
1942 else if (current_command->itm->way.exit_label)
1943 {
1944 if ((current_nav_way) && (current_nav_way->street_dest_text))
1945 {
1946 g_free(current_nav_way->street_dest_text);
1947 }
1948
1949 current_nav_way->street_dest_text = g_strdup(current_command->itm->way.exit_label);
1950#ifdef NAVIT_ROUTING_DEBUG_PRINT
1951 dbg(0, "put exit_label into nav way (C) %s\n", current_command->itm->way.exit_label);
1952#endif
1953
1954 return;
1955 }
1956 }
1957 else if (current_command->itm->way.exit_label)
1958 {
1959 if ((current_nav_way) && (current_nav_way->street_dest_text))
1960 {
1961 g_free(current_nav_way->street_dest_text);
1962 }
1963
1964 current_nav_way->street_dest_text = g_strdup(current_command->itm->way.exit_label);
1965#ifdef NAVIT_ROUTING_DEBUG_PRINT
1966 dbg(0, "put exit_label into nav way (A) %s\n", current_command->itm->way.exit_label);
1967#endif
1968
1969 return;
1970 }
1971
1972
1973
1974
1975
1976 /* return the best candidate, if there is any.*/
1977 if ((current_nav_way) && (current_nav_way->street_dest_text))
1978 {
1979 g_free(current_nav_way->street_dest_text);
1980 current_nav_way->street_dest_text = NULL;
1981 }
1982
1983 if ((current_destination) && (current_destination->destination))
1984 {
1985 current_nav_way->street_dest_text = g_strdup(current_destination->destination);
1986#ifdef NAVIT_ROUTING_DEBUG_PRINT
1987 dbg(0, "put destination into nav way (B) %s\n", current_nav_way->street_dest_text);
1988#endif
1989 }
1990 else
1991 {
1992 // stay NULL
1993 //current_nav_way->street_dest_text = NULL;
1994 //dbg(0, "put destination into nav way NULL (C)\n");
1995 }
1996}
1997// -- NEW 002 --
1998
1999
2000
1092 2001
1093static struct navigation_itm * 2002static struct navigation_itm *
1094navigation_itm_new(struct navigation *this_, struct item *ritem) 2003navigation_itm_new(struct navigation *this_, struct item *ritem)
1095{ 2004{
1096 struct navigation_itm *ret=g_new0(struct navigation_itm, 1); 2005 struct navigation_itm *ret=g_new0(struct navigation_itm, 1);
1110 //dbg(1, "no street item\n"); 2019 //dbg(1, "no street item\n");
1111 g_free(ret); 2020 g_free(ret);
1112 ret = NULL; 2021 ret = NULL;
1113 return ret; 2022 return ret;
1114 } 2023 }
2024
1115 if (item_attr_get(ritem, attr_direction, &direction)) 2025 if (item_attr_get(ritem, attr_direction, &direction))
2026 {
1116 ret->way.dir = direction.u.num; 2027 ret->way.dir = direction.u.num;
2028 }
1117 else 2029 else
2030 {
1118 ret->way.dir = 0; 2031 ret->way.dir = 0;
2032 }
1119 2033
1120 sitem = street_item.u.item; 2034 sitem = street_item.u.item;
1121 ret->way.item = *sitem; 2035 ret->way.item = *sitem;
1122 item_hash_insert(this_->hash, sitem, ret); 2036 item_hash_insert(this_->hash, sitem, ret);
1123 mr = map_rect_new(sitem->map, NULL); 2037 mr = map_rect_new(sitem->map, NULL);
2038
2039 // -- NEW 002 --
2040 struct map *tmap = sitem->map; /*find better name for backup pointer to map*/
2041 // -- NEW 002 --
2042
2043 // COST: 005
2044 dbg(0, "COST:005\n");
1124 if (!(sitem = map_rect_get_item_byid(mr, sitem->id_hi, sitem->id_lo))) 2045 if (!(sitem = map_rect_get_item_byid(mr, sitem->id_hi, sitem->id_lo)))
2046 {
2047 // -- NEW 002 --
2048 if (mr)
2049 {
2050 map_rect_destroy(mr);
2051 }
2052 g_free(ret);
2053 ret = NULL;
2054 // -- NEW 002 --
2055
1125 return NULL; 2056 return NULL;
2057 }
2058
2059 // -- NEW 002 --
2060 if (item_attr_get(sitem, attr_flags, &attr))
2061 {
2062 ret->way.flags=attr.u.num;
2063 }
2064 // -- NEW 002 --
2065
1126 if (item_attr_get(sitem, attr_street_name, &attr)) 2066 if (item_attr_get(sitem, attr_street_name, &attr))
2067 {
1127 ret->way.name1 = map_convert_string(sitem->map, attr.u.str); 2068 ret->way.name1 = map_convert_string(sitem->map, attr.u.str);
2069 }
2070
1128 if (item_attr_get(sitem, attr_street_name_systematic, &attr)) 2071 if (item_attr_get(sitem, attr_street_name_systematic, &attr))
2072 {
1129 ret->way.name2 = map_convert_string(sitem->map, attr.u.str); 2073 ret->way.name2 = map_convert_string(sitem->map, attr.u.str);
2074 }
2075
1130 navigation_itm_update(ret, ritem); 2076 navigation_itm_update(ret, ritem);
1131 2077
1132 while (item_coord_get(ritem, &c[i], 1)) 2078 while (item_coord_get(ritem, &c[i], 1))
1133 { 2079 {
1134 //dbg(1, "coord %d 0x%x 0x%x\n", i, c[i].x, c[i].y);
1135
1136 if (i < 4) 2080 if (i < 4)
2081 {
1137 i++; 2082 i++;
2083 }
1138 else 2084 else
1139 { 2085 {
1140 c[2] = c[3]; 2086 c[2] = c[3];
1141 c[3] = c[4]; 2087 c[3] = c[4];
1142 } 2088 }
1143 } 2089 }
1144 //dbg(1, "count=%d\n", i); 2090
1145 i--; 2091 i--;
1146 2092
2093
2094
2095 // -- NEW 002 --
2096 if (item_attr_get(sitem, attr_street_destination, &attr))
2097 {
2098 char *destination_raw;
2099 destination_raw = map_convert_string(sitem->map,attr.u.str);
2100#ifdef NAVIT_ROUTING_DEBUG_PRINT
2101 dbg(0, "DEST::destination_raw=%s\n", destination_raw);
2102#endif
2103
2104#ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
2105 char *tt = g_strdup_printf("D:%s", attr.u.str);
2106 route_add_to_freetext_list(&c[0], tt);
2107 g_free(tt);
2108#endif
2109
2110 // also save full text into "exit_label" --------------
2111 if (ret->way.exit_label)
2112 {
2113 g_free(ret->way.exit_label);
2114 }
2115 ret->way.exit_label = map_convert_string(sitem->map, destination_raw);
2116 // also save full text into "exit_label" --------------
2117
2118 navigation_split_string_to_list(&(ret->way), destination_raw, ';');
2119 g_free(destination_raw);
2120 }
2121 else if (item_attr_get(sitem, attr_street_destination_lanes, &attr))
2122 {
2123 char *destination_raw;
2124 destination_raw = map_convert_string(sitem->map,attr.u.str);
2125#ifdef NAVIT_ROUTING_DEBUG_PRINT
2126 dbg(0, "DEST::destination_lanes_raw=%s\n", destination_raw);
2127#endif
2128
2129#ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
2130 char *tt = g_strdup_printf("d_l:%s", attr.u.str);
2131 route_add_to_freetext_list(&c[0], tt);
2132 g_free(tt);
2133#endif
2134
2135 // also save full text into "exit_label" --------------
2136 if (ret->way.exit_label)
2137 {
2138 g_free(ret->way.exit_label);
2139 }
2140 ret->way.exit_label = map_convert_string(sitem->map, destination_raw);
2141 // also save full text into "exit_label" --------------
2142
2143 navigation_split_string_to_list_2(&(ret->way), destination_raw, ';', '|');
2144 g_free(destination_raw);
2145 }
2146 // -- NEW 002 --
2147
2148
1147 ret->way.angle2 = road_angle(&c[0], &c[1], 0); 2149 ret->way.angle2 = road_angle(&c[0], &c[1], 0); // angle at start of way
1148 ret->angle_end = road_angle(&c[i - 1], &c[i], 0); 2150 ret->angle_end = road_angle(&c[i - 1], &c[i], 0); // angle at end of way
1149 2151
1150 ret->start = c[0]; 2152 ret->start = c[0];
1151 ret->end = c[i]; 2153 ret->end = c[i];
2154
2155 // -- NEW 002 --
2156 /* If we have a ramp check the map for higway_exit info,
2157 * but only on the first node of the ramp.
2158 * Ramps with nodes in reverse order and oneway=-1 are not
2159 * specifically handled, but no occurence known so far either.
2160 * If present, obtain exit_ref, exit_label and exit_to
2161 * from the map.
2162 * exit_to holds info similar to attr_street_destination, and
2163 * we place it in way.s_destination as well, unless the street_destination info
2164 * is already present. In the future it will have to be skipped if destiantion:lanes
2165 * info exists as well.
2166 *
2167 * Now it still holds a bug, if a ramp splits in 2, the exit_to info can end up on
2168 * both continuations of the ramp. Maybe this can be solved by passing the struct
2169 * navigation_maneuver up to here to help decide on exit_to.
2170 *
2171 */
2172
2173 if (sitem->type == type_ramp) /* hier motorway_link en trunk_link toevoegen */
2174 {
2175 struct map_selection mselexit;
2176 struct item *rampitem;
2177 struct map_rect *mr2;
2178 struct coord exitcoord;
2179
2180 mselexit.next = NULL;
2181 mselexit.u.c_rect.lu = c[0];
2182 mselexit.u.c_rect.rl = c[0];
2183 mselexit.range = item_range_all;
2184 mselexit.order = 18;
2185
2186 mr2 = map_rect_new(tmap, &mselexit);
2187
2188 while ((rampitem = map_rect_get_item(mr2)))
2189 {
2190 if (rampitem->type == type_highway_exit && item_coord_get(rampitem, &exitcoord, 1)
2191 && exitcoord.x == c[0].x && exitcoord.y == c[0].y)
2192 {
2193 while (item_attr_get(rampitem, attr_any, &attr))
2194 {
2195 if (attr.type && attr.type == attr_label)
2196 {
2197#ifdef NAVIT_ROUTING_DEBUG_PRINT
2198 dbg(0,"DEST::exit_label=%s\n",attr.u.str);
2199#endif
2200 if (ret->way.exit_label)
2201 {
2202 g_free(ret->way.exit_label);
2203 }
2204 ret->way.exit_label = map_convert_string(sitem->map,attr.u.str);
2205
2206#ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
2207 char *tt = g_strdup_printf("exit_label:%s", attr.u.str);
2208 route_add_to_freetext_list(&c[0], tt);
2209 g_free(tt);
2210#endif
2211
2212 }
2213
2214 if (attr.type == attr_ref)
2215 {
2216#ifdef NAVIT_ROUTING_DEBUG_PRINT
2217 dbg(0,"DEST::exit_ref=%s\n",attr.u.str);
2218#endif
2219 if (ret->way.exit_ref)
2220 {
2221 g_free(ret->way.exit_ref);
2222 }
2223 ret->way.exit_ref = map_convert_string(sitem->map,attr.u.str);
2224
2225#ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
2226 char *tt = g_strdup_printf("exit_ref:%s", attr.u.str);
2227 route_add_to_freetext_list(&c[0], tt);
2228 g_free(tt);
2229#endif
2230
2231 }
2232
2233 if (attr.type == attr_exit_to)
2234 {
2235 if (attr.u.str && !ret->way.s_destination)
2236 {
2237 char *destination_raw;
2238 destination_raw = map_convert_string(sitem->map,attr.u.str);
2239#ifdef NAVIT_ROUTING_DEBUG_PRINT
2240 dbg(0,"DEST::destination_raw from exit_to =%s\n",destination_raw);
2241#endif
2242
2243 // also save full text into "exit_label" --------------
2244 if (ret->way.exit_label)
2245 {
2246 g_free(ret->way.exit_label);
2247 }
2248 ret->way.exit_label = map_convert_string(sitem->map, destination_raw);
2249 // also save full text into "exit_label" --------------
2250
2251#ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
2252 char *tt = g_strdup_printf("exit_to:%s", destination_raw);
2253 route_add_to_freetext_list(&c[0], tt);
2254 g_free(tt);
2255#endif
2256
2257 if ((navigation_split_string_to_list(&(ret->way),destination_raw, ';')) < 2)
2258 {
2259 /*
2260 * if a first try did not result in an actual splitting
2261 * retry with ',' as a separator
2262 *
2263 * */
2264 navigation_split_string_to_list(&(ret->way),destination_raw, ',');
2265 }
2266 g_free(destination_raw);
2267 }
2268 }
2269 }
2270 }
2271 }
2272
2273 if (mr2)
2274 {
2275 map_rect_destroy(mr2);
2276 }
2277 }
2278 // -- NEW 002 --
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
1152 2290
1153 item_attr_get(ritem, attr_route, &route_attr); 2291 item_attr_get(ritem, attr_route, &route_attr);
1154 graph_map = route_get_graph_map(route_attr.u.route); 2292 graph_map = route_get_graph_map(route_attr.u.route);
1155 if (check_roundabout(ret, graph_map)) 2293 if (check_roundabout(ret, graph_map))
1156 { 2294 {
1161 map_rect_destroy(mr); 2299 map_rect_destroy(mr);
1162 } 2300 }
1163 else 2301 else
1164 { 2302 {
1165 if (this_->last) 2303 if (this_->last)
2304 {
1166 ret->start = ret->end = this_->last->end; 2305 ret->start = ret->end = this_->last->end;
1167 } 2306 }
2307 }
2308
1168 if (!this_->first) 2309 if (!this_->first)
2310 {
1169 this_->first = ret; 2311 this_->first = ret;
2312 }
2313
1170 if (this_->last) 2314 if (this_->last)
1171 { 2315 {
1172 this_->last->next = ret; 2316 this_->last->next = ret;
1173 ret->prev = this_->last; 2317 ret->prev = this_->last;
1174 if (graph_map) 2318 if (graph_map)
1197{ 2341{
1198 int count; 2342 int count;
1199 struct navigation_itm *curr; 2343 struct navigation_itm *curr;
1200 struct navigation_way *w; 2344 struct navigation_way *w;
1201 2345
2346 if (direction == 0)
2347 {
2348 // we are going straight!!
2349 return -1;
2350 }
2351
1202 count = 0; 2352 count = 0;
1203 curr = from->next; 2353 curr = from->next;
2354
2355 int cur_next_is_lower_level_street = navigation_is_low_level_street(to->way.item.type);
2356
1204 while (curr && (curr != to)) 2357 while (curr && (curr != to))
1205 { 2358 {
1206 w = curr->way.next; 2359 w = curr->way.next;
1207 2360
1208 while (w) 2361 while (w)
1209 { 2362 {
1210 if (is_way_allowed(nav, w, 4)) 2363 if (is_way_allowed(nav, w, 4))
1211 { 2364 {
2365
2366 // dont count lower level streets, if next turn is NOT also a lower level street
2367 if ((cur_next_is_lower_level_street == 1) || (navigation_is_low_level_street(w->item.type) == 0))
2368 {
1212 if (direction < 0) 2369 if (direction < 0)
1213 {
1214 if (angle_delta(curr->prev->angle_end, w->angle2) < 0)
1215 { 2370 {
2371 if (angle_delta(curr->prev->angle_end, w->angle2) < 0)
2372 {
1216 count++; 2373 count++;
1217 break; 2374 break;
2375 }
1218 } 2376 }
1219 } 2377 else if (direction > 0)
1220 else
1221 {
1222 if (angle_delta(curr->prev->angle_end, w->angle2) > 0)
1223 { 2378 {
2379 if (angle_delta(curr->prev->angle_end, w->angle2) > 0)
2380 {
1224 count++; 2381 count++;
1225 break; 2382 break;
2383 }
1226 } 2384 }
1227 } 2385 }
1228 } 2386 }
1229 w = w->next; 2387 w = w->next;
1230 } 2388 }
1231 curr = curr->next; 2389 curr = curr->next;
1232 } 2390 }
1233 2391
1234 if (!curr) 2392 if (!curr)
2393 {
1235 { // from does not lead to to? 2394 // from does not lead to to?
1236 return -1; 2395 return -1;
1237 } 2396 }
1238 2397
1239 return count; 2398 return count;
1240} 2399}
1274 itm->dest_count = next->dest_count + 1; 2433 itm->dest_count = next->dest_count + 1;
1275 itm->dest_time = next->dest_time + itm->time; 2434 itm->dest_time = next->dest_time + itm->time;
1276 //dbg(2, "new values: time=%d lenght=%d\n", itm->dest_length, itm->dest_time); 2435 //dbg(2, "new values: time=%d lenght=%d\n", itm->dest_length, itm->dest_time);
1277 return; 2436 return;
1278 } 2437 }
2438
1279 while (itm) 2439 while (itm)
1280 { 2440 {
1281 len += itm->length; 2441 len += itm->length;
1282 time += itm->time; 2442 time += itm->time;
1283 itm->dest_length = len; 2443 itm->dest_length = len;
1299 * @param new The second item to be checked 2459 * @param new The second item to be checked
1300 * @return True if both old and new are on the same street 2460 * @return True if both old and new are on the same street
1301 */ 2461 */
1302static int is_same_street2(char *old_name1, char *old_name2, char *new_name1, char *new_name2) 2462static int is_same_street2(char *old_name1, char *old_name2, char *new_name1, char *new_name2)
1303{ 2463{
2464 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
2465 {
2466 // always return false when in bicycle mode
2467 return 0;
2468 }
2469
1304 if (old_name1 && new_name1 && !strcmp(old_name1, new_name1)) 2470 if (old_name1 && new_name1 && !strcmp(old_name1, new_name1))
1305 { 2471 {
1306 // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' yes (1.)\n", old_name2, new_name2, old_name1, new_name1); 2472 // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' yes (1.)\n", old_name2, new_name2, old_name1, new_name1);
1307 return 1; 2473 return 1;
1308 } 2474 }
2475
1309 if (old_name2 && new_name2 && !strcmp(old_name2, new_name2)) 2476 if (old_name2 && new_name2 && !strcmp(old_name2, new_name2))
1310 { 2477 {
1311 // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' yes (2.)\n", old_name2, new_name2, old_name1, new_name1); 2478 // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' yes (2.)\n", old_name2, new_name2, old_name1, new_name1);
1312 return 1; 2479 return 1;
1313 } 2480 }
2481
1314 // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' no\n", old_name2, new_name2, old_name1, new_name1); 2482 // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' no\n", old_name2, new_name2, old_name1, new_name1);
1315 return 0; 2483 return 0;
1316} 2484}
1317 2485
1318#if 0 2486#if 0
1396} 2564}
1397#endif 2565#endif
1398 2566
1399static int maneuver_category(enum item_type type) 2567static int maneuver_category(enum item_type type)
1400{ 2568{
2569 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
2570 {
1401 switch (type) 2571 switch (type)
1402 { 2572 {
2573 case type_cycleway:
2574 return 1;
2575 case type_footway:
2576 return 1;
2577 case type_street_service:
2578 return 1;
2579 case type_street_parking_lane:
2580 return 1;
2581 case type_living_street:
2582 return 1;
1403 case type_street_0: 2583 case type_street_0:
1404 return 1; 2584 return 1;
1405 case type_street_1_city: 2585 case type_street_1_city:
1406 return 2; 2586 return 2;
1407 case type_street_2_city: 2587 case type_street_2_city:
1408 return 3; 2588 return 3;
1409 case type_street_3_city: 2589 case type_street_3_city:
1410 return 4; 2590 return 4;
1411 case type_street_4_city: 2591 case type_street_4_city:
1412 return 5; 2592 return 5;
1413 case type_highway_city: 2593 case type_highway_city:
1414 return 7; 2594 return 7;
1415 case type_street_1_land: 2595 case type_street_1_land:
1416 return 2; 2596 return 2;
1417 case type_street_2_land: 2597 case type_street_2_land:
1418 return 3; 2598 return 3;
1419 case type_street_3_land: 2599 case type_street_3_land:
1420 return 4; 2600 return 4;
1421 case type_street_4_land: 2601 case type_street_4_land:
1422 return 5; 2602 return 5;
1423 case type_street_n_lanes: 2603 case type_street_n_lanes:
1424 return 6; 2604 return 6;
1425 case type_highway_land: 2605 case type_highway_land:
1426 return 7; 2606 return 7;
1427 case type_ramp: 2607 case type_ramp:
1428 return 0; 2608 return 0;
1429 case type_roundabout: 2609 case type_roundabout:
1430 return 0; 2610 return 0;
1431 case type_ferry: 2611 case type_ferry:
1432 return 0; 2612 return 0;
1433 default: 2613 default:
1434 return 0; 2614 return 0;
1435 } 2615 }
1436 2616 }
2617 else
2618 {
2619 switch (type)
2620 {
2621 case type_street_0:
2622 return 1;
2623 case type_street_1_city:
2624 return 2;
2625 case type_street_2_city:
2626 return 3;
2627 case type_street_3_city:
2628 return 4;
2629 case type_street_4_city:
2630 return 5;
2631 case type_highway_city:
2632 return 7;
2633 case type_street_1_land:
2634 return 2;
2635 case type_street_2_land:
2636 return 3;
2637 case type_street_3_land:
2638 return 4;
2639 case type_street_4_land:
2640 return 5;
2641 case type_street_n_lanes:
2642 return 6;
2643 case type_highway_land:
2644 return 7;
2645 case type_ramp:
2646 return 0;
2647 case type_roundabout:
2648 return 0;
2649 case type_ferry:
2650 return 0;
2651 default:
2652 return 0;
2653 }
2654 }
1437} 2655}
1438 2656
1439static int is_way_allowed(struct navigation *nav, struct navigation_way *way, int mode) 2657static int is_way_allowed(struct navigation *nav, struct navigation_way *way, int mode)
1440{ 2658{
1441 if (!nav->vehicleprofile) 2659 if (!nav->vehicleprofile)
1442 { 2660 {
1443 return 1; 2661 return 1;
1444 } 2662 }
2663
1445 return !way->flags || ((way->flags & (way->dir >= 0 ? nav->vehicleprofile->flags_forward_mask : nav->vehicleprofile->flags_reverse_mask)) == nav->vehicleprofile->flags); 2664 return !way->flags || ((way->flags & (way->dir >= 0 ? route_get_real_oneway_mask(way->flags, nav->vehicleprofile->flags_forward_mask) : route_get_real_oneway_mask(way->flags, nav->vehicleprofile->flags_reverse_mask))) == nav->vehicleprofile->flags);
1446} 2665}
1447 2666
1448/** 2667/**
1449 * @brief Checks if navit has to create a maneuver to drive from old to new 2668 * @brief Checks if navit has to create a maneuver to drive from old to new (run only once!!)
1450 * 2669 *
1451 * This function checks if it has to create a "maneuver" - i.e. guide the user - to drive 2670 * This function checks if it has to create a "maneuver" - i.e. guide the user - to drive
1452 * from "old" to "new". 2671 * from "old" to "new".
1453 * 2672 *
1454 * @param old The old navigation item, where we're coming from 2673 * @param old The old navigation item, where we're coming from
1462 int ret = 0, d, dw, dlim; 2681 int ret = 0, d, dw, dlim;
1463 char *r = NULL; 2682 char *r = NULL;
1464 struct navigation_way *w; 2683 struct navigation_way *w;
1465 int cat, ncat, wcat, maxcat, left = -180, right = 180, is_unambigous = 0, is_same_street; 2684 int cat, ncat, wcat, maxcat, left = -180, right = 180, is_unambigous = 0, is_same_street;
1466 2685
1467 //dbg(1, "enter %p %p %p\n", old, new, delta);
1468 d = angle_delta(old->angle_end, new->way.angle2); 2686 d = angle_delta(old->angle_end, new->way.angle2);
2687
2688 //long long wayid_old = navigation_item_get_wayid(&(old->way));
2689 //long long wayid_new = navigation_item_get_wayid(&(new->way));
2690 //dbg(0, "Enter d=%d old->angle_end=%d new->way.angle2=%d old_way_id=%lld new_way_id=%lld\n", d, old->angle_end, new->way.angle2, wayid_old, wayid_new);
2691
2692 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
2693 {
2694 int flags_old = navigation_item_get_flags(&(old->way));
2695 int flags_new = navigation_item_get_flags(&(new->way));
2696
2697 //dbg(0, "(b1)old flags=%x new flags=%x old dir=%d new dir=%d\n", old->way.flags, new->way.flags, old->way.dir, new->way.dir);
2698 //dbg(0, "(b2)old flags=%x new flags=%x\n", (flags_old & NAVIT_AF_ONEWAY), (flags_new & NAVIT_AF_ONEWAY));
2699 //dbg(0, "(b3)old flags=%x new flags=%x\n", (flags_old & NAVIT_AF_ONEWAYREV), (flags_new & NAVIT_AF_ONEWAYREV));
2700
2701 if ((old->way.dir == 1) && ((new->way.dir == -1) && (new->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)))
2702 {
2703 r = "yes: bicycle starts going against oneway here (1)";
2704 ret = 1;
2705 //dbg(0, "%s\n", r);
2706 }
2707 else if ( ((old->way.dir == -1) && (!(old->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)) ) && ((new->way.dir == -1) && (new->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)))
2708 {
2709 r = "yes: bicycle starts going against oneway here (2)";
2710 ret = 1;
2711 //dbg(0, "%s\n", r);
2712 }
2713 }
2714
2715
2716
2717
2718 // z2z2
2719 int have_more_than_one_way_to_turn = 0;
2720 struct navigation_way *w22;
2721 w22 = new->way.next;
2722 int new_angle_abs = 999;
2723 int new_angle_abs_min = 999;
2724 int old_angle_abs = abs(d);
2725
2726 dbg(0, "STRAI:001:%d\n", old_angle_abs);
2727
2728 while (w22)
2729 {
2730
2731 dbg(0, "STRAI:002\n");
2732
2733 //if ((w22->dir == -1) && (w22->flags & NAVIT_AF_ONEWAY))
2734 //{
2735 // // against oneway not allowed
2736 //}
2737 if (((global_vehicle_profile != 1) && (global_vehicle_profile != 2))
2738 && (navigation_is_low_level_street(old->way.item.type) == 0)
2739 && (navigation_is_low_level_street(new->way.item.type) == 0)
2740 && (navigation_is_low_level_street(w22->item.type) == 1))
2741 {
2742 // dont count "lower" streets when not on "lower" street now or next
2743 }
2744 else
2745 {
2746 if (is_way_allowed(nav, w22, 1))
2747 {
2748 have_more_than_one_way_to_turn = 1;
2749 }
2750
2751 new_angle_abs = abs(angle_delta(old->angle_end, w22->angle2));
2752
2753 dbg(0, "STRAI:003:%d have_more_than_one_way_to_turn=%d\n", new_angle_abs, have_more_than_one_way_to_turn);
2754
2755 if (new_angle_abs < new_angle_abs_min)
2756 {
2757 new_angle_abs_min = new_angle_abs;
2758 }
2759
2760 }
2761 w22 = w22->next;
2762 }
2763
2764 dbg(0, "STRAI:004\n");
2765
2766 if ((new_angle_abs_min > ROAD_ANGLE_IS_STRAIGHT_ABS) && (old_angle_abs <= ROAD_ANGLE_IS_STRAIGHT_ABS))
2767 {
2768 dbg(0, "STRAI:005 new_abs=%d old_abs=%d\n", new_angle_abs_min, old_angle_abs);
2769
2770 // we want to drive almost straight, set angle to "0"
2771 d = 0;
2772 }
2773
2774 dbg(0, "STRAI:005a:d=%d\n", d);
2775
2776 if (!r)
2777 {
2778 if (have_more_than_one_way_to_turn == 1) // more than 1 possibility
2779 {
2780 if (new->way.exit_label)
2781 {
2782 r = "yes: we have a exit-sign to tell the user";
2783 ret = 1;
2784 }
2785 else if (new->way.s_destination)
2786 {
2787 r = "yes: we have a road-sign to tell the user";
2788 ret = 1;
2789 }
2790 else if (old->way.item.type == type_ramp)
2791 {
2792 r = "yes: we are currently on a ramp and have more than 1 road to take";
2793 ret = 1;
2794 }
2795 }
2796 }
2797
2798
2799 if ((global_vehicle_profile != 1) && (global_vehicle_profile != 2))
2800 {
1469 if (!new->way.next) 2801 if (!new->way.next)
1470 { 2802 {
1471 /* No announcement necessary */ 2803 /* No announcement necessary */
1472 r = "no: Only one possibility"; 2804 r = "no: Only one possibility";
1473 } 2805 }
1474 else if (!new->way.next->next && new->way.next->item.type == type_ramp && !is_way_allowed(nav, new->way.next, 1)) 2806 else if (!new->way.next->next && new->way.next->item.type == type_ramp && !is_way_allowed(nav, new->way.next, 1))
1475 { 2807 {
1476 /* If the other way is only a ramp and it is one-way in the wrong direction, no announcement necessary */ 2808 /* If the other way is only a ramp and it is one-way in the wrong direction, no announcement necessary */
1477 r = "no: Only ramp"; 2809 r = "no: Only ramp";
1478 } 2810 }
2811 }
2812 else
2813 {
2814 if (!r)
2815 {
2816#if 0
2817 if ((!new->way.next) && (abs(d) < 20))
2818 {
2819 /* No announcement necessary */
2820 r = "no: Only one possibility and less than 20° turn";
2821 dbg(0, "%s\n", r);
2822 }
2823 else
2824 {
2825 if (abs(d) > 2)
2826 {
2827 r = "yes: bicycle mode";
2828 dbg(0, "%s\n", r);
2829 ret = 1;
2830 }
2831 else
2832 {
2833 r = "no: less than 3° turn";
2834 dbg(0, "%s\n", r);
2835 }
2836 }
2837#endif
2838
2839#if 0
2840 if (!new->way.next)
2841 {
2842 /* No announcement necessary */
2843 r = "no: Only one possibility";
2844 }
2845#endif
2846
2847#if 1
2848 if (!new->way.next)
2849 {
2850 if (abs(d) > ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE)
2851 {
2852 r = "yes: delta over ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE in bicycle mode (Only one possibility)";
2853 //dbg(0, "%s\n", r);
2854 ret = 1;
2855 }
2856 else
2857 {
2858 r = "no: delta less than ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE in bicycle mode (Only one possibility)";
2859 //dbg(0, "%s\n", r);
2860 ret = 0;
2861 }
2862 }
2863 else
2864 {
2865 if (abs(d) > ROAD_ANGLE_MIN__FOR_TURN_BICYCLEMODE_ONLY_1_POSSIBILITY)
2866 {
2867 r = "yes: delta over ROAD_ANGLE_MIN__FOR_TURN_BICYCLEMODE_ONLY_1_POSSIBILITY in bicycle mode";
2868 //dbg(0, "%s\n", r);
2869 ret = 1;
2870 }
2871 else
2872 {
2873 r = "no: delta less than ROAD_ANGLE_MIN__FOR_TURN_BICYCLEMODE_ONLY_1_POSSIBILITY in bicycle mode";
2874 //dbg(0, "%s\n", r);
2875 ret = 0;
2876 }
2877 }
2878#endif
2879
2880 }
2881 }
2882
1479 if (!r) 2883 if (!r)
1480 { 2884 {
1481 if ((old->way.flags & NAVIT_AF_ROUNDABOUT) && !(new->way.flags & NAVIT_AF_ROUNDABOUT)) 2885 if ((old->way.flags & NAVIT_AF_ROUNDABOUT) && !(new->way.flags & NAVIT_AF_ROUNDABOUT))
1482 { 2886 {
1483 r = "yes: leaving roundabout"; 2887 r = "yes: leaving roundabout";
1486 else if (!(old->way.flags & NAVIT_AF_ROUNDABOUT) && (new->way.flags & NAVIT_AF_ROUNDABOUT)) 2890 else if (!(old->way.flags & NAVIT_AF_ROUNDABOUT) && (new->way.flags & NAVIT_AF_ROUNDABOUT))
1487 { 2891 {
1488 r = "no: entering roundabout"; 2892 r = "no: entering roundabout";
1489 } 2893 }
1490 else if ((old->way.flags & NAVIT_AF_ROUNDABOUT) && (new->way.flags & NAVIT_AF_ROUNDABOUT)) 2894 else if ((old->way.flags & NAVIT_AF_ROUNDABOUT) && (new->way.flags & NAVIT_AF_ROUNDABOUT))
2895 {
1491 r = "no: staying in roundabout"; 2896 r = "no: staying in roundabout";
1492 } 2897 }
2898 }
2899
2900 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
2901 {
2902 if (!r && abs(d) > ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE)
2903 {
2904 /* always make an announcement if you have to make a turn */
2905 r = "yes: delta over ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE in bicycle mode";
2906 //dbg(0, "%s\n", r);
2907 ret = 1;
2908 }
2909 }
2910 else
2911 {
1493 if (!r && abs(d) > 75) 2912 if (!r && abs(d) > 75)
1494 { 2913 {
1495 /* always make an announcement if you have to make a sharp turn */ 2914 /* always make an announcement if you have to make a sharp turn */
1496 r = "yes: delta over 75"; 2915 r = "yes: delta over 75";
1497 ret = 1; 2916 ret = 1;
1498 } 2917 }
2918 }
2919
1499 cat = maneuver_category(old->way.item.type); 2920 cat = maneuver_category(old->way.item.type);
1500 ncat = maneuver_category(new->way.item.type); 2921 ncat = maneuver_category(new->way.item.type);
2922
1501 if (!r) 2923 if (!r)
1502 { 2924 {
1503 /* Check whether the street keeps its name */ 2925 /* Check whether the street keeps its name */
1504 is_same_street = is_same_street2(old->way.name1, old->way.name2, new->way.name1, new->way.name2); 2926 is_same_street = is_same_street2(old->way.name1, old->way.name2, new->way.name1, new->way.name2);
2927
2928 dbg(0, "STRAI:011.01 is_same_street=%d old->way.name1=%s old->way.name2=%s new->way.name1=%s new->way.name2=%s\n", is_same_street, old->way.name1, old->way.name2, new->way.name1, new->way.name2);
2929
1505 w = new->way.next; 2930 w = new->way.next;
1506 maxcat = -1; 2931 maxcat = -1;
1507 while (w) 2932 while (w)
1508 { 2933 {
1509 dw = angle_delta(old->angle_end, w->angle2); 2934 dw = angle_delta(old->angle_end, w->angle2);
2935 dbg(0, "STRAI:011.02 dw=%d l=%d r=%d\n", dw, left, right);
2936
1510 if (dw < 0) 2937 if (dw < 0)
1511 { 2938 {
1512 if (dw > left) 2939 if (dw > left)
2940 {
1513 left = dw; 2941 left = dw;
2942 }
1514 } 2943 }
1515 else 2944 else
1516 { 2945 {
1517 if (dw < right) 2946 if (dw < right)
2947 {
1518 right = dw; 2948 right = dw;
1519 } 2949 }
2950 }
2951
1520 wcat = maneuver_category(w->item.type); 2952 wcat = maneuver_category(w->item.type);
2953 dbg(0, "STRAI:011.03 wcat=%d\n", wcat);
2954
1521 /* If any other street has the same name but isn't a highway (a highway might split up temporarily), then 2955 /* If any other street has the same name [ removed:"but isn't a highway (a highway might split up temporarily)" ], then
1522 we can't use the same name criterium */ 2956 we can't use the same name criterium */
1523 if (is_same_street && is_same_street2(old->way.name1, old->way.name2, w->name1, w->name2) && (cat != 7 || wcat != 7) && is_way_allowed(nav, w, 2)) 2957 // if (is_same_street && is_same_street2(old->way.name1, old->way.name2, w->name1, w->name2) && (cat != 7 || wcat != 7) && is_way_allowed(nav, w, 2))
2958 if (is_same_street && is_same_street2(old->way.name1, old->way.name2, w->name1, w->name2) && is_way_allowed(nav, w, 2))
2959 {
1524 is_same_street = 0; 2960 is_same_street = 0;
2961 dbg(0, "STRAI:011.04 is_same_street=%d\n", is_same_street);
2962 }
2963
2964 /* Mark if the street has a higher or the same category */
2965 if (wcat > maxcat)
2966 {
2967 maxcat = wcat;
2968 dbg(0, "STRAI:011.06 maxcat=%d wcat=%d\n", maxcat, wcat);
2969 }
2970
2971 w = w->next;
2972 }
2973
2974 if (have_more_than_one_way_to_turn == 1) // more than 1 possibility
2975 {
1525 /* Even if the ramp has the same name, announce it */ 2976 /* Even if the ramp has the same name, announce it */
1526 if (new->way.item.type == type_ramp && old->way.item.type != type_ramp) 2977 if (new->way.item.type == type_ramp && old->way.item.type != type_ramp)
2978 {
1527 is_same_street = 0; 2979 is_same_street = 0;
1528 /* Mark if the street has a higher or the same category */ 2980 dbg(0, "STRAI:011.05.xx is_same_street=%d\n", is_same_street);
1529 if (wcat > maxcat)
1530 maxcat = wcat;
1531 w = w->next;
1532 } 2981 }
2982 }
2983
1533 /* get the delta limit for checking for other streets. It is lower if the street has no other 2984 /* get the delta limit for checking for other streets. It is lower if the street has no other
1534 streets of the same or higher category */ 2985 streets of the same or higher category */
1535 if (ncat < cat) 2986 if (ncat < cat)
2987 {
1536 dlim = 80; 2988 dlim = 80;
2989 }
1537 else 2990 else
2991 {
1538 dlim = 120; 2992 dlim = 120;
2993 }
2994
1539 /* if the street is really straight, the others might be closer to straight */ 2995 /* if the street is really straight, the others might be closer to straight */
1540 if (abs(d) < 20) 2996 if (abs(d) < 20)
2997 {
1541 dlim /= 2; 2998 dlim /= 2;
2999 }
3000
1542 if ((maxcat == ncat && maxcat == cat) || (ncat == 0 && cat == 0)) 3001 if ((maxcat == ncat && maxcat == cat) || (ncat == 0 && cat == 0))
3002 {
1543 dlim = abs(d) * 620 / 256; 3003 dlim = abs(d) * 620 / 256;
3004 }
1544 else if (maxcat < ncat && maxcat < cat) 3005 else if (maxcat < ncat && maxcat < cat)
3006 {
1545 dlim = abs(d) * 128 / 256; 3007 dlim = abs(d) * 128 / 256;
3008 }
3009
1546 if (left < -dlim && right > dlim) 3010 if (left < -dlim && right > dlim)
3011 {
1547 is_unambigous = 1; 3012 is_unambigous = 1;
3013 }
3014
1548 if (!is_same_street && is_unambigous < 1) 3015 if (!is_same_street && is_unambigous < 1)
1549 { 3016 {
1550 ret = 1; 3017 ret = 1;
1551 r = "yes: not same street or ambigous"; 3018 r = "yes: not same street or ambigous";
1552 } 3019 }
1553 else 3020 else
3021 {
1554 r = "no: same street and unambigous"; 3022 r = "no: same street and unambigous";
3023 }
3024
3025 dbg(0, "STRAI:011.07 is_unambigous=%d ret=%d r=%s\n", is_unambigous, ret, r);
3026
1555#ifdef DEBUG 3027#ifdef DEBUG
1556 // r=g_strdup_printf("yes: d %d left %d right %d dlim=%d cat old:%d new:%d max:%d unambigous=%d same_street=%d", d, left, right, dlim, cat, ncat, maxcat, is_unambigous, is_same_street); 3028 // r=g_strdup_printf("yes: d %d left %d right %d dlim=%d cat old:%d new:%d max:%d unambigous=%d same_street=%d", d, left, right, dlim, cat, ncat, maxcat, is_unambigous, is_same_street);
1557#endif 3029#endif
1558 } 3030 }
3031
3032 // correct "delta" (turn angle) here !! ---------------------------
3033 // correct "delta" (turn angle) here !! ---------------------------
3034
3035 if (ret == 1)
3036 {
3037 w = new->way.next;
3038 //int d2 = angle_delta(old->angle_end, new->way.angle2);
3039 int d2 = d;
3040 //if (d == 0)
3041 //{
3042 // d2 = 0;
3043 //}
3044
3045 int correct_direction = 1;
3046
3047 dbg(0, "STRAI:007.01:%d\n", d);
3048
3049 if (d2 < 0) // left
3050 {
3051 while (w)
3052 {
3053 if (angle_delta(old->angle_end, w->angle2) > d2) // other ways are going more to the right?
3054 {
3055 correct_direction = 0;
3056 break;
3057 }
3058 w = w->next;
3059 }
3060
3061 if (correct_direction == 1)
3062 {
3063#ifdef NAVIT_ROUTING_DEBUG_PRINT
3064 dbg(0, "MAV:001:correct to right\n");
3065#endif
3066 d = 8; // set to "slight right"
3067 }
3068 }
3069 else if (d2 > 0) // right
3070 {
3071 while (w)
3072 {
3073 if (angle_delta(old->angle_end, w->angle2) < d2) // other ways are going more to the left?
3074 {
3075 correct_direction = 0;
3076 break;
3077 }
3078 w = w->next;
3079 }
3080
3081 if (correct_direction == 1)
3082 {
3083#ifdef NAVIT_ROUTING_DEBUG_PRINT
3084 dbg(0, "MAV:002:correct to left\n");
3085#endif
3086 d = -8; // set to "slight left"
3087 }
3088 }
3089 else // (d2 == 0) // straight
3090 {
3091
3092 dbg(0, "STRAI:008.01:%d (%d < %d)\n", d2, new_angle_abs_min, ROAD_ANGLE_DISTANCE_FOR_STRAIGHT);
3093
3094 int more_ways_to_left = 0;
3095 int more_ways_to_right = 0;
3096
3097 if (new_angle_abs_min < ROAD_ANGLE_DISTANCE_FOR_STRAIGHT) // if other angles are far different from straight, than let it still be straight! otherwise correct direction
3098 {
3099 dbg(0, "STRAI:008.02\n");
3100
3101 while (w)
3102 {
3103 dbg(0, "STRAI:008.02a delta=%d\n", angle_delta(old->angle_end, w->angle2));
3104
3105 if (angle_delta(old->angle_end, w->angle2) < d2) // other ways are going more to the left?
3106 {
3107 more_ways_to_left++;
3108 }
3109 else if (angle_delta(old->angle_end, w->angle2) > d2) // other ways are going more to the right?
3110 {
3111 more_ways_to_right++;
3112 }
3113 w = w->next;
3114 }
3115
3116 dbg(0, "STRAI:008.02 %d %d\n", more_ways_to_left, more_ways_to_right);
3117
3118 if ((more_ways_to_left == 0) && (more_ways_to_right > 0))
3119 {
3120
3121 dbg(0, "STRAI:008.03:left\n");
3122
3123#ifdef NAVIT_ROUTING_DEBUG_PRINT
3124 dbg(0, "MAV:003:correct to left\n");
3125#endif
3126 d = -8;
3127 }
3128 else if ((more_ways_to_left > 0) && (more_ways_to_right == 0))
3129 {
3130 dbg(0, "STRAI:008.04:right\n");
3131
3132#ifdef NAVIT_ROUTING_DEBUG_PRINT
3133 dbg(0, "MAV:003:correct to right\n");
3134#endif
3135 d = 8;
3136 }
3137 }
3138
3139 }
3140
3141 }
3142
3143 // correct "delta" (turn angle) here !! ---------------------------
3144 // correct "delta" (turn angle) here !! ---------------------------
3145
3146 dbg(0, "STRAI:099:ret=%d r=%s d=%d\n", ret, r, d);
3147
1559 *delta = d; 3148 *delta = d;
1560 if (reason) 3149 if (reason)
1561 { 3150 {
1562 *reason = r; 3151 *reason = r;
1563 } 3152 }
3153
1564 return ret; 3154 return ret;
1565
1566#if 0
1567 if (new->item.type == old->item.type || (new->item.type != type_ramp && old->item.type != type_ramp))
1568 {
1569 if (is_same_street2(old, new))
1570 {
1571 if (! entering_straight(new, abs(*delta)))
1572 {
1573 dbg(1, "maneuver_required: Not driving straight: yes\n");
1574 if (reason)
1575 *reason="yes: Not driving straight";
1576 return 1;
1577 }
1578
1579 if (check_multiple_streets(new))
1580 {
1581 if (entering_straight(new,abs(*delta)*2))
1582 {
1583 if (reason)
1584 *reason="no: delta < ext_limit for same name";
1585 return 0;
1586 }
1587 if (reason)
1588 *reason="yes: delta > ext_limit for same name";
1589 return 1;
1590 }
1591 else
1592 {
1593 dbg(1, "maneuver_required: Staying on the same street: no\n");
1594 if (reason)
1595 *reason="no: Staying on same street";
1596 return 0;
1597 }
1598 }
1599 }
1600 else
1601 dbg(1, "maneuver_required: old or new is ramp\n");
1602#if 0
1603 if (old->item.type == type_ramp && (new->item.type == type_highway_city || new->item.type == type_highway_land))
1604 {
1605 dbg(1, "no_maneuver_required: old is ramp new is highway\n");
1606 if (reason)
1607 *reason="no: old is ramp new is highway";
1608 return 0;
1609 }
1610#endif
1611#if 0
1612 if (old->crossings_end == 2)
1613 {
1614 dbg(1, "maneuver_required: only 2 connections: no\n");
1615 return 0;
1616 }
1617#endif
1618 dbg(1,"delta=%d-%d=%d\n", new->way.angle2, old->angle_end, *delta);
1619 if ((new->item.type == type_highway_land || new->item.type == type_highway_city || old->item.type == type_highway_land || old->item.type == type_highway_city) && (!is_same_street_systematic(old, new) || (old->name2 != NULL && new->name2 == NULL)))
1620 {
1621 dbg(1, "maneuver_required: highway changed name\n");
1622 if (reason)
1623 *reason="yes: highway changed name";
1624 return 1;
1625 }
1626 if (abs(*delta) < straight_limit)
1627 {
1628 if (! entering_straight(new,abs(*delta)))
1629 {
1630 if (reason)
1631 *reason="yes: not straight";
1632 dbg(1, "maneuver_required: not driving straight: yes\n");
1633 return 1;
1634 }
1635
1636 dbg(1, "maneuver_required: delta(%d) < %d: no\n", *delta, straight_limit);
1637 if (reason)
1638 *reason="no: delta < limit";
1639 return 0;
1640 }
1641 if (abs(*delta) < ext_straight_limit)
1642 {
1643 if (entering_straight(new,abs(*delta)*2))
1644 {
1645 if (reason)
1646 *reason="no: delta < ext_limit";
1647 return 0;
1648 }
1649 }
1650
1651 if (! check_multiple_streets(new))
1652 {
1653 dbg(1, "maneuver_required: only one possibility: no\n");
1654 if (reason)
1655 *reason="no: only one possibility";
1656 return 0;
1657 }
1658
1659 dbg(1, "maneuver_required: delta=%d: yes\n", *delta);
1660 if (reason)
1661 *reason="yes: delta >= limit";
1662 return 1;
1663#endif
1664} 3155}
1665 3156
1666static struct navigation_command *
1667command_new(struct navigation *this_, struct navigation_itm *itm, int delta) 3157static struct navigation_command *command_new(struct navigation *this_, struct navigation_itm *itm, int delta)
1668{ 3158{
1669 struct navigation_command *ret=g_new0(struct navigation_command, 1); 3159 struct navigation_command *ret=g_new0(struct navigation_command, 1);
3160
1670 //dbg(1, "enter this_=%p itm=%p delta=%d\n", this_, itm, delta); 3161 //dbg(1, "enter this_=%p itm=%p delta=%d\n", this_, itm, delta);
1671 ret->delta = delta; 3162 ret->delta = delta;
1672 ret->itm = itm; 3163 ret->itm = itm;
3164
1673 if (itm && itm->prev && itm->way.next && itm->prev->way.next && !(itm->way.flags & NAVIT_AF_ROUNDABOUT) && (itm->prev->way.flags & NAVIT_AF_ROUNDABOUT)) 3165 if (itm && itm->prev && itm->way.next && itm->prev->way.next && !(itm->way.flags & NAVIT_AF_ROUNDABOUT) && (itm->prev->way.flags & NAVIT_AF_ROUNDABOUT))
1674 { 3166 {
1675 int len = 0; 3167 int len = 0;
1676 int angle = 0; 3168 int angle = 0;
1677 int entry_angle; 3169 int entry_angle;
1678 struct navigation_itm *itm2 = itm->prev; 3170 struct navigation_itm *itm2 = itm->prev;
1679 int exit_angle = angle_median(itm->prev->angle_end, itm->way.next->angle2); 3171 int exit_angle = angle_median(itm->prev->angle_end, itm->way.next->angle2);
1680 //dbg(1, "exit %d median from %d,%d\n", exit_angle, itm->prev->angle_end, itm->way.next->angle2); 3172 //dbg(1, "exit %d median from %d,%d\n", exit_angle, itm->prev->angle_end, itm->way.next->angle2);
3173
1681 while (itm2 && (itm2->way.flags & NAVIT_AF_ROUNDABOUT)) 3174 while (itm2 && (itm2->way.flags & NAVIT_AF_ROUNDABOUT))
1682 { 3175 {
1683 len += itm2->length; 3176 len += itm2->length;
1684 angle = itm2->angle_end; 3177 angle = itm2->angle_end;
1685 itm2 = itm2->prev; 3178 itm2 = itm2->prev;
1686 } 3179 }
3180
1687 if (itm2 && itm2->next && itm2->next->way.next) 3181 if (itm2 && itm2->next && itm2->next->way.next)
1688 { 3182 {
1689 itm2 = itm2->next; 3183 itm2 = itm2->next;
1690 entry_angle = angle_median(angle_opposite(itm2->way.angle2), itm2->way.next->angle2); 3184 entry_angle = angle_median(angle_opposite(itm2->way.angle2), itm2->way.next->angle2);
1691 // dbg(1, "entry %d median from %d(%d),%d\n", entry_angle, angle_opposite(itm2->way.angle2), itm2->way.angle2, itm2->way.next->angle2); 3185 // dbg(1, "entry %d median from %d(%d),%d\n", entry_angle, angle_opposite(itm2->way.angle2), itm2->way.angle2, itm2->way.next->angle2);
1696 } 3190 }
1697 //dbg(0, "entry %d exit %d\n", entry_angle, exit_angle); 3191 //dbg(0, "entry %d exit %d\n", entry_angle, exit_angle);
1698 ret->roundabout_delta = angle_delta(entry_angle, exit_angle); 3192 ret->roundabout_delta = angle_delta(entry_angle, exit_angle);
1699 ret->length = len + roundabout_extra_length; 3193 ret->length = len + roundabout_extra_length;
1700 } 3194 }
3195
1701 if (this_->cmd_last) 3196 if (this_->cmd_last)
1702 { 3197 {
1703 this_->cmd_last->next = ret; 3198 this_->cmd_last->next = ret;
1704 ret->prev = this_->cmd_last; 3199 ret->prev = this_->cmd_last;
1705 } 3200 }
3201
1706 this_->cmd_last = ret; 3202 this_->cmd_last = ret;
1707 3203
1708 if (!this_->cmd_first) 3204 if (!this_->cmd_first)
3205 {
1709 this_->cmd_first = ret; 3206 this_->cmd_first = ret;
3207 }
3208
1710 return ret; 3209 return ret;
1711} 3210}
1712 3211
3212
3213
3214// ----------- main place where maneuvers generated (run only once) ------------
3215// ----------- main place where maneuvers generated (run only once) ------------
3216// ----------- main place where maneuvers generated (run only once) ------------
1713static void make_maneuvers(struct navigation *this_, struct route *route) 3217static void make_maneuvers(struct navigation *this_, struct route *route)
1714{ 3218{
3219__F_START__
3220
1715 struct navigation_itm *itm, *last = NULL, *last_itm = NULL; 3221 struct navigation_itm *itm, *last = NULL, *last_itm = NULL;
1716 int delta; 3222 int delta;
1717 itm = this_->first; 3223 itm = this_->first;
1718 this_->cmd_last = NULL; 3224 this_->cmd_last = NULL;
1719 this_->cmd_first = NULL; 3225 this_->cmd_first = NULL;
1721 { 3227 {
1722 if (last) 3228 if (last)
1723 { 3229 {
1724 if (maneuver_required2(this_, last_itm, itm, &delta, NULL)) 3230 if (maneuver_required2(this_, last_itm, itm, &delta, NULL))
1725 { 3231 {
3232 //dbg(0, "maneuver_required2 = true\n");
1726 command_new(this_, itm, delta); 3233 command_new(this_, itm, delta);
1727 } 3234 }
1728 } 3235 }
1729 else 3236 else
3237 {
1730 last = itm; 3238 last = itm;
3239 }
1731 last_itm = itm; 3240 last_itm = itm;
1732 itm = itm->next; 3241 itm = itm->next;
1733 } 3242 }
1734 command_new(this_, last_itm, 0); 3243 command_new(this_, last_itm, 0);
3244
3245__F_END__
1735} 3246}
3247// ----------- main place where maneuvers generated ------------
3248// ----------- main place where maneuvers generated ------------
3249// ----------- main place where maneuvers generated ------------
3250
3251
1736 3252
1737static int contains_suffix(char *name, char *suffix) 3253static int contains_suffix(char *name, char *suffix)
1738{ 3254{
1739 if (!suffix) 3255 if (!suffix)
1740 return 0; 3256 return 0;
1768 int vocabulary2 = 65535; 3284 int vocabulary2 = 65535;
1769 struct attr attr; 3285 struct attr attr;
1770 3286
1771 if (!prefix) 3287 if (!prefix)
1772 prefix = ""; 3288 prefix = "";
3289
1773 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name, &attr, NULL)) 3290 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name, &attr, NULL))
1774 vocabulary1 = attr.u.num; 3291 vocabulary1 = attr.u.num;
3292
1775 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name_systematic, &attr, NULL)) 3293 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name_systematic, &attr, NULL))
1776 vocabulary2 = attr.u.num; 3294 vocabulary2 = attr.u.num;
3295
1777 n1 = itm->way.name1; 3296 n1 = itm->way.name1;
1778 n2 = itm->way.name2; 3297 n2 = itm->way.name2;
3298
1779 if (!vocabulary1) 3299 if (!vocabulary1)
1780 n1 = NULL; 3300 n1 = NULL;
3301
1781 if (!vocabulary2) 3302 if (!vocabulary2)
1782 n2 = NULL; 3303 n2 = NULL;
3304
1783 if (!n1 && !n2 && itm->way.item.type == type_ramp && vocabulary2) 3305 if (!n1 && !n2 && (itm->way.item.type == type_ramp) && vocabulary2)
1784 { 3306 {
1785 //dbg(1,">> Next is ramp %lx current is %lx \n", itm->way.item.type, next->way.item.type); 3307 //dbg(1,">> Next is ramp %lx current is %lx \n", itm->way.item.type, next->way.item.type);
1786 3308
3309
3310// disabled for now !!!!!!!! -------------------------
3311#if 0
1787 if (next->way.item.type == type_ramp) 3312 if (next->way.item.type == type_ramp)
3313 {
1788 return NULL; 3314 return NULL;
3315 }
3316#endif
3317// disabled for now !!!!!!!! -------------------------
3318
3319
3320 //else
3321 //{
3322 // return g_strdup_printf("%s%s",prefix,_("into the ramp"));
3323 //}
3324
3325#if 0
1789 if (itm->way.item.type == type_highway_city || itm->way.item.type == type_highway_land) 3326 if (itm->way.item.type == type_highway_city || itm->way.item.type == type_highway_land)
1790 { 3327 {
1791#ifdef HAVE_API_ANDROID 3328#ifdef HAVE_API_ANDROID
1792#ifdef NAVIT_SAY_DEBUG_PRINT 3329#ifdef NAVIT_SAY_DEBUG_PRINT
1793 android_send_generic_text(1,"+*#O:exit\n"); 3330 android_send_generic_text(1,"+*#O:exit\n");
1797#endif 3334#endif
1798#endif 3335#endif
1799 return g_strdup_printf("%s%s", prefix, _("exit")); /* %FIXME Can this even be reached? and "exit" is the wrong text anyway ! */ 3336 return g_strdup_printf("%s%s", prefix, _("exit")); /* %FIXME Can this even be reached? and "exit" is the wrong text anyway ! */
1800 } 3337 }
1801 else 3338 else
3339#endif
3340 {
3341 if (itm->way.street_dest_text)
1802 { 3342 {
1803#ifdef HAVE_API_ANDROID 3343#ifdef HAVE_API_ANDROID
1804#ifdef NAVIT_SAY_DEBUG_PRINT 3344#ifdef NAVIT_SAY_DEBUG_PRINT
3345 gchar* xy=g_strdup_printf("+*#0:%s\n", itm->way.street_dest_text);
3346 android_send_generic_text(1,xy);
3347 g_free(xy);
3348 gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
3349 android_send_generic_text(1,xy);
3350 g_free(xy);
3351#endif
3352#endif
3353
3354 // say the name on the exit sign/destinaion sign
3355 return g_strdup_printf("%s%s", prefix, itm->way.street_dest_text);
3356 }
3357 else
3358 {
3359#ifdef HAVE_API_ANDROID
3360#ifdef NAVIT_SAY_DEBUG_PRINT
1805 android_send_generic_text(1,"+*#O:into the ramp\n"); 3361 android_send_generic_text(1,"+*#O:into the ramp\n");
1806 gchar* xy=g_strdup_printf("+*#1:%s\n", prefix); 3362 gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
1807 android_send_generic_text(1,xy); 3363 android_send_generic_text(1,xy);
1808 g_free(xy); 3364 g_free(xy);
1809#endif 3365#endif
1810#endif 3366#endif
3367
1811 return g_strdup_printf("%s%s", prefix, _("into the ramp")); 3368 return g_strdup_printf("%s%s", prefix, _("into the ramp"));
1812 } 3369 }
1813
1814 } 3370 }
1815 3371
1816 if (!n1 && !n2) 3372 }
3373
3374 if (!n1 && !n2 && !itm->way.street_dest_text)
1817 { 3375 {
1818 return NULL; 3376 return NULL;
1819 } 3377 }
1820 3378
3379 if (itm->way.street_dest_text)
3380 {
3381#ifdef HAVE_API_ANDROID
3382#ifdef NAVIT_SAY_DEBUG_PRINT
3383 gchar* xy=g_strdup_printf("+*#0:%s\n", itm->way.street_dest_text);
3384 android_send_generic_text(1,xy);
3385 g_free(xy);
3386 gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
3387 android_send_generic_text(1,xy);
3388 g_free(xy);
3389#endif
3390#endif
3391 // say the name on the exit sign/destinaion sign
3392 return g_strdup_printf("%s%s", prefix, itm->way.street_dest_text);
3393 }
1821 if (n1) 3394 else if (n1)
1822 { 3395 {
1823 sex = -1; 3396 sex = -1;
1824 name1 = NULL; 3397 name1 = NULL;
1825 for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++) 3398 for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++)
1826 { 3399 {
1976 3549
1977 return ret; 3550 return ret;
1978} 3551}
1979 3552
1980static char * 3553static char *
1981show_maneuver(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type, int connect) 3554show_maneuver_bicycle(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type, int connect, int level3)
1982{ 3555{
3556__F_START__
3557
1983 // TRANSLATORS: right, as in 'Turn right' 3558 // TRANSLATORS: right, as in 'Turn right'
1984 char *dir = _("right"); 3559 char *dir = _("right");
1985 char *strength = ""; 3560 char *strength = "";
1986 int distance = itm->dest_length - cmd->itm->dest_length; 3561 int distance = itm->dest_length - cmd->itm->dest_length;
1987 char *d, *ret = NULL; 3562 char *d, *ret = NULL;
1988 int delta = cmd->delta; 3563 int delta = cmd->delta;
1989 int level; 3564 int level;
3565 int level_now = 99;
1990 int strength_needed; 3566 int strength_needed;
1991 int skip_roads; 3567 int skip_roads;
1992 int count_roundabout; 3568 int count_roundabout;
1993 struct navigation_itm *cur; 3569 struct navigation_itm *cur;
1994 struct navigation_way *w; 3570 struct navigation_way *w;
3571 int against_oneway = 0;
1995 3572
1996 if (connect) 3573 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
3574 {
3575 //dbg(0, "itm->way.flags=%x\n", itm->way.flags);
3576 //dbg(0, "itm->next->way.flags=%x\n", itm->next->way.flags);
3577 //dbg(0, "itm->way.dir=%d itm->next->way.dir=%d\n", itm->way.dir, itm->next->way.dir);
3578
3579 //dbg(0, "2 itm->way.flags=%x\n", cmd->itm->way.flags);
3580 //dbg(0, "2 itm->next->way.flags=%x\n", cmd->itm->next->way.flags);
3581 //dbg(0, "2 itm->way.dir=%d itm->next->way.dir=%d\n", cmd->itm->way.dir, cmd->itm->next->way.dir);
3582
3583 int flags_old = navigation_item_get_flags(&itm->way);
3584 int flags_new = 0;
3585 if (itm->next)
1997 { 3586 {
1998 level = -2; // level = -2 means "connect to another maneuver via 'then ...'" 3587 flags_new = navigation_item_get_flags(&itm->next->way);
1999 } 3588 }
2000 else 3589 //dbg(0, "(2211)old flags=%x new flags=%x\n", flags_old, flags_new);
3590
3591 // long long wayid_old = navigation_item_get_wayid(&(itm->way));
3592 // long long wayid_new = navigation_item_get_wayid(&(itm->next->way));
3593 // dbg(0, "WID old_way_id=%lld new_way_id=%lld\n", wayid_old, wayid_new);
3594
3595
3596 if ( (itm->way.dir == 1) && ((itm->next->way.dir == -1) && (itm->next->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)) )
2001 { 3597 {
2002 level = 1; 3598 against_oneway = 1;
3599 //dbg(0, "SPEAK: (1)going against oneway street!\n");
2003 } 3600 }
3601 else if ( ((itm->way.dir == -1) && (!(itm->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO))) && ((itm->next->way.dir == -1) && (itm->next->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)) )
3602 {
3603 against_oneway = 1;
3604 //dbg(0, "SPEAK: (2)going against oneway street!\n");
3605 }
3606 }
3607
3608 //dbg(0, "d=%d d3=%d\n", distance, (distance - cmd->length));
3609 level_now = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length);
3610 //dbg(0, "level_now=%d\n", level_now);
2004 3611
2005 w = itm->next->way.next; 3612 w = itm->next->way.next;
2006 strength_needed = 0; 3613 strength_needed = 0;
2007 3614
2008 if (angle_delta(itm->next->way.angle2, itm->angle_end) < 0) 3615 if (angle_delta(itm->next->way.angle2, itm->angle_end) < 0)
2028 } 3635 }
2029 w = w->next; 3636 w = w->next;
2030 } 3637 }
2031 } 3638 }
2032 3639
3640
3641 //dbg(0, "cmd->delta=%d\n", delta);
3642
2033 if (delta < 0) 3643 if (delta < 0)
2034 { 3644 {
2035#ifdef HAVE_API_ANDROID
2036#ifdef NAVIT_SAY_DEBUG_PRINT
2037 android_send_generic_text(1,"+*#O:left\n");
2038#endif
2039#endif
2040 // TRANSLATORS: left, as in 'Turn left' 3645 // TRANSLATORS: left, as in 'Turn left'
2041 dir = _("left"); 3646 dir = _("left");
2042 delta = -delta; 3647 delta = -delta;
2043 } 3648 }
2044 else
2045 {
2046 // dir = right
2047#ifdef HAVE_API_ANDROID
2048#ifdef NAVIT_SAY_DEBUG_PRINT
2049 android_send_generic_text(1,"+*#O:right\n");
2050#endif
2051#endif
2052 }
2053 3649
2054 if (strength_needed) 3650 if (strength_needed)
2055 { 3651 {
2056 if (delta < 45) 3652 if (delta < 45)
2057 { 3653 {
2058#ifdef HAVE_API_ANDROID
2059#ifdef NAVIT_SAY_DEBUG_PRINT
2060 android_send_generic_text(1,"+*#O:slight \n");
2061#endif
2062#endif
2063 // TRANSLATORS: Don't forget the ending space 3654 // TRANSLATORS: Don't forget the ending space
2064 // TRANSLATORS: EXAMPLE: turn slight right 3655 // TRANSLATORS: EXAMPLE: turn slight right
2065 strength = _("slight "); 3656 strength = _("slight ");
2066 } 3657 }
2067 else if (delta < 105) 3658 else if (delta < 105)
2068 { 3659 {
2069 strength = ""; 3660 strength = "";
2070 } 3661 }
2071 else if (delta < 165) 3662 else if (delta < 165)
2072 { 3663 {
2073#ifdef HAVE_API_ANDROID
2074#ifdef NAVIT_SAY_DEBUG_PRINT
2075 android_send_generic_text(1,"+*#O:hard \n");
2076#endif
2077#endif
2078 // TRANSLATORS: Don't forget the ending space 3664 // TRANSLATORS: Don't forget the ending space
2079 // TRANSLATORS: EXAMPLE: turn hard right 3665 // TRANSLATORS: EXAMPLE: turn hard right
2080 strength = _("hard "); 3666 strength = _("hard ");
2081 } 3667 }
2082 else if (delta < 180) 3668 else if (delta < 180)
2083 { 3669 {
2084#ifdef HAVE_API_ANDROID
2085#ifdef NAVIT_SAY_DEBUG_PRINT
2086 android_send_generic_text(1,"+*#O:really hard \n");
2087#endif
2088#endif
2089 // TRANSLATORS: Don't forget the ending space 3670 // TRANSLATORS: Don't forget the ending space
2090 // TRANSLATORS: EXAMPLE: turn really hard right 3671 // TRANSLATORS: EXAMPLE: turn really hard right
2091 strength = _("really hard "); 3672 strength = _("really hard ");
2092 } 3673 }
2093 else 3674 else
2094 { 3675 {
2095 // dbg(1,"delta=%d\n", delta);
2096 // TRANSLATORS: Don't forget the ending space 3676 // TRANSLATORS: Don't forget the ending space
2097 //strength=_("unknown ");
2098 strength = ""; 3677 strength = "";
2099 } 3678 }
2100 } 3679 }
2101 3680
3681
2102 if (type != attr_navigation_long_exact) 3682 if (type != attr_navigation_long_exact)
2103 { 3683 {
3684 //dbg(0, "round distance d=%d dr=%d\n", distance, round_distance(distance));
2104 distance = round_distance(distance); 3685 distance = round_distance(distance);
2105 } 3686 }
2106 3687
3688
3689
3690
2107 if (type == attr_navigation_speech) 3691 if (type == attr_navigation_speech)
2108 { 3692 {
2109 if (nav->turn_around && nav->turn_around == nav->turn_around_limit) 3693 if (nav->turn_around && nav->turn_around == nav->turn_around_limit)
2110 { 3694 {
2111#ifdef HAVE_API_ANDROID
2112#ifdef NAVIT_SAY_DEBUG_PRINT
2113 android_send_generic_text(1,"+*#O:When possible, please turn around\n");
2114#endif
2115#endif
2116 return g_strdup(_("When possible, please turn around")); 3695 return2 g_strdup(_("When possible, please turn around"));
2117 }
2118
2119 if (!connect)
2120 {
2121 level = navigation_get_announce_level_cmd(nav, itm, cmd, distance - cmd->length);
2122 }
2123 // dbg(1,"distance=%d level=%d type=0x%x\n", distance, level, itm->way.item.type);
2124 }
2125
2126 if (cmd->itm->prev->way.flags & NAVIT_AF_ROUNDABOUT)
2127 {
2128 cur = cmd->itm->prev;
2129 count_roundabout = 0;
2130 while (cur && (cur->way.flags & NAVIT_AF_ROUNDABOUT))
2131 {
2132 // If the next segment has no exit or the exit isn't allowed, don't count it
2133 if (cur->next->way.next && is_way_allowed(nav, cur->next->way.next, 3))
2134 {
2135 count_roundabout++;
2136 } 3696 }
2137 cur = cur->prev;
2138 } 3697 }
2139 3698
2140 gchar* xy;
2141 3699
3700
2142 switch (level) 3701 switch (level3)
3702 {
3703 case 3:
3704 if (distance > 500)
2143 { 3705 {
2144 case 2:
2145#ifdef HAVE_API_ANDROID
2146#ifdef NAVIT_SAY_DEBUG_PRINT
2147 android_send_generic_text(1,"+*#O:Enter the roundabout soon\n");
2148#endif
2149#endif
2150 return g_strdup(_("Enter the roundabout soon"));
2151 case 1:
2152 d = get_distance(nav, distance, type, 1); 3706 d = get_distance(nav, distance, type, 1);
2153 3707 ret = g_strdup_printf(_("Follow the road for the next %s"), d);
2154#ifdef HAVE_API_ANDROID
2155#ifdef NAVIT_SAY_DEBUG_PRINT
2156 android_send_generic_text(1,"+*#O:In %s, enter the roundabout\n");
2157 xy=g_strdup_printf("+*#1:%s\n", d);
2158 android_send_generic_text(1,xy);
2159 g_free(xy);
2160#endif
2161#endif
2162 // TRANSLATORS: %s is the distance to the roundabout
2163 // TRANSLATORS: EXAMPLE: In 300m, enter the roundabout
2164 ret = g_strdup_printf(_("In %s, enter the roundabout"), d);
2165 g_free(d); 3708 g_free(d);
2166 return ret;
2167 case -2:
2168#ifdef HAVE_API_ANDROID
2169#ifdef NAVIT_SAY_DEBUG_PRINT
2170 android_send_generic_text(1,"+*#O:then leave the roundabout at the %s\n");
2171 xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
2172 android_send_generic_text(1,xy);
2173 g_free(xy);
2174#endif
2175#endif
2176 // TRANSLATORS: EXAMPLE: ... then leave the roundabout at the second exit
2177 return g_strdup_printf(_("then leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
2178 case 0:
2179#ifdef HAVE_API_ANDROID
2180#ifdef NAVIT_SAY_DEBUG_PRINT
2181 android_send_generic_text(1,"+*#O:Leave the roundabout at the %s\n");
2182 xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
2183 android_send_generic_text(1,xy);
2184 g_free(xy);
2185#endif
2186#endif
2187 // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit
2188 return g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
2189 } 3709 }
2190 } 3710 else
2191 3711 {
2192 switch (level) 3712 ret = g_strdup("");
2193 { 3713 }
2194 case 3:
2195 d = get_distance(nav, distance, type, 1);
2196
2197#ifdef HAVE_API_ANDROID
2198#ifdef NAVIT_SAY_DEBUG_PRINT
2199 android_send_generic_text(1,"+*#O:Follow the road for the next %s\n");
2200 gchar* xy=g_strdup_printf("+*#1:%s\n", d);
2201 android_send_generic_text(1,xy);
2202 g_free(xy);
2203#endif
2204#endif
2205 // TRANSLATORS: EXAMPLE: Follow the road for the next 300 meters
2206 ret = g_strdup_printf(_("Follow the road for the next %s"), d);
2207 g_free(d);
2208 return ret; 3714 return2 ret;
3715 // break;
2209 case 2: 3716 case 2:
2210#ifdef HAVE_API_ANDROID
2211#ifdef NAVIT_SAY_DEBUG_PRINT
2212 android_send_generic_text(1,"+*#O:soon\n");
2213#endif
2214#endif
2215 d = g_strdup(_("soon")); 3717 d = g_strdup(_("soon"));
2216 break; 3718 break;
2217 case 1: 3719 case 1:
2218 d = get_distance(nav, distance, attr_navigation_short, 0); 3720 d = get_distance(nav, distance, attr_navigation_short, 0);
2219 break; 3721 break;
2220 case 0: 3722 case 0:
3723 // d = g_strdup(_("now"));
3724 d = g_strdup("");
3725 break;
3726 }
3727
3728
3729 // are there more commands left?
3730 if (cmd->itm->next)
3731 {
3732 int tellstreetname = 0;
3733 char *destination = NULL;
3734
3735 if (type == attr_navigation_speech)
3736 {
3737 if (level3 == 1)
3738 {
3739 tellstreetname = 1; // Ok so we tell the name of the street
3740 }
3741 else // if (level3 == 0)
3742 {
3743 tellstreetname = 0;
3744 }
3745 }
3746 else
3747 {
3748 tellstreetname = 1;
3749 }
3750
3751 if (global_speak_streetnames == 0)
3752 {
3753 // never speak streetnames (user config option)
3754 tellstreetname = 0;
3755 }
3756
3757 if (nav->tell_street_name && tellstreetname)
3758 {
3759 destination = navigation_item_destination(nav, cmd->itm, itm, " ");
3760 }
3761
3762
3763 if (connect == 0)
3764 {
3765 //dbg(0, "level3=%5$d str=%1$s%2$s %3$s%4$s\n", strength, dir, d, destination ? destination : "", level3);
3766
3767 if (level3 == 0)
3768 {
3769 if (against_oneway == 1)
3770 {
3771 if (delta < 10)
3772 {
3773 ret = g_strdup_printf("%s", _("oncoming traffic!")); // just say "attention oneway street!"
3774 }
3775 else
3776 {
3777 ret = g_strdup_printf("%s, %s", dir, _("oncoming traffic!")); // just say "left" or "right" at the turn + "attention oneway street!"
3778 }
3779 }
3780 else
3781 {
3782 if (delta >= 10)
3783 {
3784 ret = g_strdup(dir); // just say "left" or "right" at the turn
3785 }
3786 else
3787 {
3788 ret = g_strdup("");
3789 }
3790 }
3791 }
3792 else // if (level3 == 1)
3793 {
3794 if ((against_oneway == 1) && (delta < 10))
3795 {
3796 ret = g_strdup(""); // probably just going against a oneway street, but travelling straight on. dont say anything now
3797 }
3798 else
3799 {
3800 if (delta >= 10)
3801 {
3802 // TRANSLATORS: The first argument is strength, the second direction, the third distance and the fourth destination Example: 'Turn 'slightly' 'left' in '100 m' 'onto baker street'
3803 ret = g_strdup_printf_4_str(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
3804 }
3805 else
3806 {
3807 ret = g_strdup("");
3808 }
3809 }
3810 }
3811
3812 }
3813 else // (connect == 1)
3814 {
3815 if (level3 == 0)
3816 {
3817 if (against_oneway == 1)
3818 {
3819 if (delta < 10)
3820 {
3821 ret = g_strdup_printf("%s %s", _("then"), _("oncoming traffic!"));
3822 }
3823 else
3824 {
3825 ret = g_strdup_printf("%s %s %s", _("then"), dir, _("oncoming traffic!"));
3826 }
3827 }
3828 else
3829 {
3830 if (delta >= 10)
3831 {
3832 ret = g_strdup_printf("%s %s", _("then"), dir);
3833 }
3834 else
3835 {
3836 ret = g_strdup("");
3837 }
3838 }
3839 }
3840 else // if (level3 == 1)
3841 {
3842 if (against_oneway == 1)
3843 {
3844 if (delta < 10)
3845 {
3846 // nothing
3847 ret = g_strdup("");
3848 }
3849 else
3850 {
3851 // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
3852 ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
3853 }
3854 }
3855 else
3856 {
3857 if (delta >= 10)
3858 {
3859 // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
3860 ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
3861 }
3862 else
3863 {
3864 ret = g_strdup("");
3865 }
3866 }
3867 }
3868 }
3869
3870
3871 if (destination)
3872 {
3873 g_free(destination);
3874 destination = NULL;
3875 }
3876 }
3877 // no more commands left, must be at destination
3878 else
3879 {
3880 if (!connect)
3881 {
3882 d = get_distance(nav, distance, type, 1);
3883
3884 // TRANSLATORS: EXAMPLE: You have reached your destination in 300 meters
3885 ret = g_strdup_printf(_("You have reached your destination %s"), d);
3886
3887 g_free(d);
3888 }
3889 else
3890 {
3891 ret = g_strdup(_("then you have reached your destination."));
3892 }
3893 }
3894
3895 return2 ret;
3896
3897__F_END__
3898}
3899
3900int navigation_is_low_level_street(enum item_type t)
3901{
3902 if (global_vehicle_profile == 0) // only in car profile!
3903 {
3904 if (t == type_street_service)
3905 {
3906 return 1;
3907 }
3908 else if (t == type_street_parking_lane)
3909 {
3910 return 1;
3911 }
3912 else if (t == type_track_ground)
3913 {
3914 return 1;
3915 }
3916 else if (t == type_track_grass)
3917 {
3918 return 1;
3919 }
3920 else if (t == type_track_gravelled)
3921 {
3922 return 1;
3923 }
3924 else if (t == type_track_unpaved)
3925 {
3926 return 1;
3927 }
3928 else if (t == type_track_paved)
3929 {
3930 return 1;
3931 }
3932 }
3933
3934 return 0;
3935}
3936
3937static char *
3938show_maneuver(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type, int connect)
3939{
3940__F_START__
3941
3942 // TRANSLATORS: right, as in 'Turn right'
3943 char *dir = _("right");
3944 char *strength = "";
3945 int distance = itm->dest_length - cmd->itm->dest_length;
3946 char *d, *ret = NULL;
3947 int delta = cmd->delta;
3948 int level;
3949 int level_now = 99;
3950 int strength_needed;
3951 int skip_roads;
3952 int count_roundabout;
3953 struct navigation_itm *cur;
3954 struct navigation_way *w;
3955 int against_oneway = 0;
3956
3957 if (connect)
3958 {
3959 level = -2; // level = -2 means "connect to another maneuver via 'then ...'"
3960 }
3961 else
3962 {
3963 level = 1;
3964 }
3965
3966 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
3967 {
3968 //dbg(0, "itm->way.flags=%x\n", itm->way.flags);
3969 //dbg(0, "itm->next->way.flags=%x\n", itm->next->way.flags);
3970
3971 // int flags_old = navigation_item_get_flags(&itm->way);
3972 // int flags_new = navigation_item_get_flags(&itm->next->way);
3973 // dbg(0, "old flags=%x new flags=%x\n", flags_old, flags_new);
3974
3975 if ( (itm->way.dir == 1) && ((itm->next->way.dir == -1) && (itm->next->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)) )
3976 {
3977 against_oneway = 1;
3978 //dbg(0, "SPEAK: (1)going against oneway street!\n");
3979 }
3980 else if ( ((itm->way.dir == -1) && (!(itm->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO))) && ((itm->next->way.dir == -1) && (itm->next->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)) )
3981 {
3982 against_oneway = 1;
3983 //dbg(0, "SPEAK: (2)going against oneway street!\n");
3984 }
3985 }
3986
3987 w = itm->next->way.next;
3988 strength_needed = 0;
3989
3990 //dbg(0, "STRENGTH:001:strength_needed = %d delta = %d\n", strength_needed, delta);
3991
3992 if (angle_delta(itm->next->way.angle2, itm->angle_end) < 0) // left
3993 {
3994 while (w)
3995 {
3996 if (angle_delta(w->angle2, itm->angle_end) < 0) // other ways are going left
3997 {
3998 strength_needed = 1;
3999 // dbg(0, "STRENGTH:002:strength_needed = %d\n", strength_needed);
4000 break;
4001 }
4002 w = w->next;
4003 }
4004 }
4005 else // right
4006 {
4007 while (w)
4008 {
4009 if (angle_delta(w->angle2, itm->angle_end) > 0) // other ways are going right
4010 {
4011 strength_needed = 1;
4012 // dbg(0, "STRENGTH:003:strength_needed = %d\n", strength_needed);
4013 break;
4014 }
4015 w = w->next;
4016 }
4017 }
4018
4019 if ((strength_needed == 0) && (delta < 9)) // for corrected turn (delta will be 8), use strenght ("slight")
4020 {
4021 strength_needed = 1;
4022 }
4023
4024 //dbg(0, "cmd->delta=%d\n", delta);
4025
4026 if (delta < 0)
4027 {
4028#ifdef HAVE_API_ANDROID
4029#ifdef NAVIT_SAY_DEBUG_PRINT
4030 android_send_generic_text(1,"+*#O:left\n");
4031#endif
4032#endif
4033 // TRANSLATORS: left, as in 'Turn left'
4034 dir = _("left");
4035 delta = -delta;
4036 }
4037 else if (delta > 0)
4038 {
4039 // dir = right
4040#ifdef HAVE_API_ANDROID
4041#ifdef NAVIT_SAY_DEBUG_PRINT
4042 android_send_generic_text(1,"+*#O:right\n");
4043#endif
4044#endif
4045 }
4046 else // delta == 0 // go straight
4047 {
4048 dir = _("straight");
4049 strength_needed = 0;
4050 // dbg(0, "STRENGTH:004:strength_needed = %d\n", strength_needed);
4051 }
4052
4053
4054 if (strength_needed)
4055 {
4056 // dbg(0, "STRENGTH:005:\n");
4057
4058
4059 if (delta < 45)
4060 {
4061#ifdef HAVE_API_ANDROID
4062#ifdef NAVIT_SAY_DEBUG_PRINT
4063 android_send_generic_text(1,"+*#O:slight \n");
4064#endif
4065#endif
4066 // TRANSLATORS: Don't forget the ending space
4067 // TRANSLATORS: EXAMPLE: turn slight right
4068 strength = _("slight ");
4069
4070 // dbg(0, "STRENGTH:006:strength_needed = %s\n", strength);
4071
4072 }
4073 else if (delta < 105)
4074 {
4075 strength = "";
4076 }
4077 else if (delta < 165)
4078 {
4079#ifdef HAVE_API_ANDROID
4080#ifdef NAVIT_SAY_DEBUG_PRINT
4081 android_send_generic_text(1,"+*#O:hard \n");
4082#endif
4083#endif
4084 // TRANSLATORS: Don't forget the ending space
4085 // TRANSLATORS: EXAMPLE: turn hard right
4086 strength = _("hard ");
4087 }
4088 else if (delta < 180)
4089 {
4090#ifdef HAVE_API_ANDROID
4091#ifdef NAVIT_SAY_DEBUG_PRINT
4092 android_send_generic_text(1,"+*#O:really hard \n");
4093#endif
4094#endif
4095 // TRANSLATORS: Don't forget the ending space
4096 // TRANSLATORS: EXAMPLE: turn really hard right
4097 strength = _("really hard ");
4098 }
4099 else
4100 {
4101 // dbg(1,"delta=%d\n", delta);
4102 strength = "";
4103 }
4104 }
4105
4106 // dbg(0, "STRENGTH:010:strength_needed = %s\n", strength);
4107
4108
4109 if (type != attr_navigation_long_exact)
4110 {
4111 distance = round_distance(distance);
4112 }
4113
4114 if (type == attr_navigation_speech)
4115 {
4116 if (nav->turn_around && nav->turn_around == nav->turn_around_limit)
4117 {
4118#ifdef HAVE_API_ANDROID
4119#ifdef NAVIT_SAY_DEBUG_PRINT
4120 android_send_generic_text(1,"+*#O:When possible, please turn around\n");
4121#endif
4122#endif
4123 return2 g_strdup(_("When possible, please turn around"));
4124 }
4125
4126 if (!connect)
4127 {
4128 level = navigation_get_announce_level_cmd(nav, itm, cmd, distance - cmd->length);
4129 //dbg(0, "distance=%d level=%d type=%s\n", distance, level, item_to_name(itm->way.item.type));
4130 }
4131
4132 level_now = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length);
4133 }
4134
4135#if 0
4136 int need_clear = 1;
4137#endif
4138
4139
4140 if (cmd->itm->prev->way.flags & NAVIT_AF_ROUNDABOUT)
4141 {
4142 cur = cmd->itm->prev;
4143 count_roundabout = 0;
4144
4145 struct navigation_itm *cur_orig = cur->next;
4146
4147 enum item_type cur_street_type = 0;
4148 int exit_is_lover_street_type = 0;
4149 cur_street_type = cur_orig->way.item.type;
4150 // dbg(0, "curr item type=%s\n", item_to_name(cur_orig->way.item.type));
4151 exit_is_lover_street_type = navigation_is_low_level_street(cur_street_type);
4152
4153 int next_exit_is_lower_street_type = 0;
4154
4155 while (cur && (cur->way.flags & NAVIT_AF_ROUNDABOUT))
4156 {
4157 // If the next segment has no exit or the exit isn't allowed, don't count it
4158 if (cur->next->way.next && is_way_allowed(nav, cur->next->way.next, 3))
4159 {
4160
4161 // only count street_service (and lesser streets) if we also exit on street_service (or any lesser street)
4162 if (cur->next)
4163 {
4164 next_exit_is_lower_street_type = navigation_is_low_level_street(cur->next->way.next->item.type);
4165 }
4166
4167 if ((exit_is_lover_street_type == 1) || (next_exit_is_lower_street_type == 0))
4168 {
4169 count_roundabout++;
4170
4171#if 0
4172 if (need_clear == 1)
4173 {
4174 need_clear = 0;
4175 global_debug_coord_list_items = 0;
4176
4177 struct coord c2[5];
4178
4179 if (navigation_get_real_item_first_coord(&(cur_orig->way), c2))
4180 {
4181 global_debug_coord_list[global_debug_coord_list_items].x = c2[0].x;
4182 global_debug_coord_list[global_debug_coord_list_items].y = c2[0].y;
4183 global_debug_coord_list_items++;
4184 global_debug_coord_list[global_debug_coord_list_items].x = c2[1].x;
4185 global_debug_coord_list[global_debug_coord_list_items].y = c2[1].y;
4186 global_debug_coord_list_items++;
4187 }
4188
4189 }
4190
4191 struct coord c1[5];
4192 if (navigation_get_real_item_first_coord(cur->next->way.next, c1))
4193 {
4194 if ((global_debug_coord_list_items + 2) > MAX_DEBUG_COORDS)
4195 {
4196 global_debug_coord_list_items = 0;
4197 }
4198
4199 global_debug_coord_list[global_debug_coord_list_items].x = c1[0].x;
4200 global_debug_coord_list[global_debug_coord_list_items].y = c1[0].y;
4201 global_debug_coord_list_items++;
4202 global_debug_coord_list[global_debug_coord_list_items].x = c1[1].x;
4203 global_debug_coord_list[global_debug_coord_list_items].y = c1[1].y;
4204 global_debug_coord_list_items++;
4205 }
4206#endif
4207
4208 }
4209 }
4210 cur = cur->prev;
4211 }
4212
4213 gchar* xy;
4214
4215 switch (level)
4216 {
4217 case 2:
4218#ifdef HAVE_API_ANDROID
4219#ifdef NAVIT_SAY_DEBUG_PRINT
4220 android_send_generic_text(1,"+*#O:Enter the roundabout soon\n");
4221#endif
4222#endif
4223 return2 g_strdup(_("Enter the roundabout soon"));
4224
4225
4226
4227
4228 case 1:
4229
4230
4231#ifdef HAVE_API_ANDROID
4232#ifdef NAVIT_SAY_DEBUG_PRINT
4233 android_send_generic_text(1,"+*#O:Leave the roundabout at the %s\n");
4234 xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
4235 android_send_generic_text(1,xy);
4236 g_free(xy);
4237#endif
4238#endif
4239 // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit
4240 return2 g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
4241
4242
4243// ---- DISABLED ----
4244#if 0
4245 d = get_distance(nav, distance, type, 1);
4246
4247#ifdef HAVE_API_ANDROID
4248#ifdef NAVIT_SAY_DEBUG_PRINT
4249 android_send_generic_text(1,"+*#O:In %s, enter the roundabout\n");
4250 xy=g_strdup_printf("+*#1:%s\n", d);
4251 android_send_generic_text(1,xy);
4252 g_free(xy);
4253#endif
4254#endif
4255 // TRANSLATORS: %s is the distance to the roundabout
4256 // TRANSLATORS: EXAMPLE: In 300m, enter the roundabout
4257 ret = g_strdup_printf(_("In %s, enter the roundabout"), d);
4258 g_free(d);
4259 return2 ret;
4260#endif
4261// ---- DISABLED ----
4262
4263
4264
4265 case -2:
4266#ifdef HAVE_API_ANDROID
4267#ifdef NAVIT_SAY_DEBUG_PRINT
4268 android_send_generic_text(1,"+*#O:then leave the roundabout at the %s\n");
4269 xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
4270 android_send_generic_text(1,xy);
4271 g_free(xy);
4272#endif
4273#endif
4274 // TRANSLATORS: EXAMPLE: ... then leave the roundabout at the second exit
4275 return2 g_strdup_printf(_("then leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
4276
4277
4278 case 0:
4279#ifdef HAVE_API_ANDROID
4280#ifdef NAVIT_SAY_DEBUG_PRINT
4281 android_send_generic_text(1,"+*#O:Leave the roundabout at the %s\n");
4282 xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
4283 android_send_generic_text(1,xy);
4284 g_free(xy);
4285#endif
4286#endif
4287 // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit
4288 return2 g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
4289 }
4290 }
4291
4292 // -- NEW 002 --
4293 if (cmd->itm)
4294 {
4295 // put correct destination into struct (to later show in GUI)
4296 navigation_select_announced_destinations(cmd);
4297 // string is in cmd->itm->way.street_dest_text
4298 }
4299 // -- NEW 002 --
4300
4301
4302
4303
4304 switch (level)
4305 {
4306 case 3:
4307 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
4308 {
4309 if (distance > 500)
4310 {
4311 d = get_distance(nav, distance, type, 1);
4312
4313#ifdef HAVE_API_ANDROID
4314#ifdef NAVIT_SAY_DEBUG_PRINT
4315 android_send_generic_text(1,"+*#O:Follow the road for the next %s\n");
4316 gchar* xy=g_strdup_printf("+*#1:%s\n", d);
4317 android_send_generic_text(1,xy);
4318 g_free(xy);
4319#endif
4320#endif
4321
4322 ret = g_strdup_printf(_("Follow the road for the next %s"), d);
4323 g_free(d);
4324 }
4325 else
4326 {
4327 ret = g_strdup("");
4328 }
4329 }
4330 else
4331 {
4332 d = get_distance(nav, distance, type, 1);
4333
4334#ifdef HAVE_API_ANDROID
4335#ifdef NAVIT_SAY_DEBUG_PRINT
4336 android_send_generic_text(1,"+*#O:Follow the road for the next %s\n");
4337 gchar* xy=g_strdup_printf("+*#1:%s\n", d);
4338 android_send_generic_text(1,xy);
4339 g_free(xy);
4340#endif
4341#endif
4342 // TRANSLATORS: EXAMPLE: Follow the road for the next 300 meters
4343 ret = g_strdup_printf(_("Follow the road for the next %s"), d);
4344 g_free(d);
4345 }
4346 return2 ret;
4347 case 2:
4348#ifdef HAVE_API_ANDROID
4349#ifdef NAVIT_SAY_DEBUG_PRINT
4350 android_send_generic_text(1,"+*#O:soon\n");
4351#endif
4352#endif
4353
4354 // dbg(0, "SPK:*soon*\n");
4355
4356
4357 d = g_strdup(_("soon"));
4358 break;
4359 case 1:
4360 d = get_distance(nav, distance, attr_navigation_short, 0);
4361 break;
4362 case 0:
4363 // zz33
2221 skip_roads = count_possible_turns(nav, cmd->prev ? cmd->prev->itm : nav->first, cmd->itm, cmd->delta); 4364 skip_roads = count_possible_turns(nav, cmd->prev ? cmd->prev->itm : nav->first, cmd->itm, cmd->delta);
2222 if (skip_roads > 0) 4365 if ((skip_roads > 0) && ((global_vehicle_profile != 1) && (global_vehicle_profile != 2)))
2223 { 4366 {
2224 if (get_count_str(skip_roads + 1)) 4367 if (get_count_str(skip_roads + 1))
2225 { 4368 {
2226#ifdef HAVE_API_ANDROID 4369#ifdef HAVE_API_ANDROID
2227#ifdef NAVIT_SAY_DEBUG_PRINT 4370#ifdef NAVIT_SAY_DEBUG_PRINT
2233 android_send_generic_text(1,xy); 4376 android_send_generic_text(1,xy);
2234 g_free(xy); 4377 g_free(xy);
2235#endif 4378#endif
2236#endif 4379#endif
2237 // TRANSLATORS: First argument is the how manieth street to take, second the direction 4380 // TRANSLATORS: First argument is the how manieth street to take, second the direction
2238 ret = g_strdup_printf(_("Take the %1$s road to the %2$s"), get_count_str(skip_roads + 1), dir); 4381 ret = g_strdup_printf_2_str(_("Take the %1$s road to the %2$s"), get_count_str(skip_roads + 1), dir);
2239 return ret; 4382 return2 ret;
2240 } 4383 }
2241 else 4384 else
2242 { 4385 {
2243#ifdef HAVE_API_ANDROID 4386#ifdef HAVE_API_ANDROID
2244#ifdef NAVIT_SAY_DEBUG_PRINT 4387#ifdef NAVIT_SAY_DEBUG_PRINT
2258 android_send_generic_text(1,"+*#O:now\n"); 4401 android_send_generic_text(1,"+*#O:now\n");
2259#endif 4402#endif
2260#endif 4403#endif
2261 d = g_strdup(_("now")); 4404 d = g_strdup(_("now"));
2262 } 4405 }
4406
2263 break; 4407 break;
4408
2264 case -2: 4409 case -2:
2265 skip_roads = count_possible_turns(nav, cmd->prev->itm, cmd->itm, cmd->delta); 4410 skip_roads = count_possible_turns(nav, cmd->prev->itm, cmd->itm, cmd->delta);
2266 if (skip_roads > 0) 4411 if ((skip_roads > 0) && ((global_vehicle_profile != 1) && (global_vehicle_profile != 2)))
2267 { 4412 {
2268 // TRANSLATORS: First argument is the how manieth street to take, second the direction 4413 // TRANSLATORS: First argument is the how manieth street to take, second the direction
2269 // TRANSLATORS: EXAMPLE: ... then take the second road to the right 4414 // TRANSLATORS: EXAMPLE: ... then take the second road to the right
2270 if (get_count_str(skip_roads + 1)) 4415 if (get_count_str(skip_roads + 1))
2271 { 4416 {
2278 xy=g_strdup_printf("+*#1:%s\n", dir); 4423 xy=g_strdup_printf("+*#1:%s\n", dir);
2279 android_send_generic_text(1,xy); 4424 android_send_generic_text(1,xy);
2280 g_free(xy); 4425 g_free(xy);
2281#endif 4426#endif
2282#endif 4427#endif
2283 ret = g_strdup_printf(_("then take the %1$s road to the %2$s"), get_count_str(skip_roads + 1), dir); 4428 ret = g_strdup_printf_2_str(_("then take the %1$s road to the %2$s"), get_count_str(skip_roads + 1), dir);
2284 return ret; 4429 return2 ret;
2285 } 4430 }
2286 else 4431 else
2287 { 4432 {
2288#ifdef HAVE_API_ANDROID 4433#ifdef HAVE_API_ANDROID
2289#ifdef NAVIT_SAY_DEBUG_PRINT 4434#ifdef NAVIT_SAY_DEBUG_PRINT
2311 d = g_strdup(_("error")); 4456 d = g_strdup(_("error"));
2312 } 4457 }
2313 4458
2314 if (cmd->itm->next) 4459 if (cmd->itm->next)
2315 { 4460 {
4461 // dbg(0, "SPK:000a\n");
4462
2316 int tellstreetname = 0; 4463 int tellstreetname = 0;
2317 char *destination = NULL; 4464 char *destination = NULL;
2318 4465
2319 if (type == attr_navigation_speech) 4466 if (type == attr_navigation_speech)
2320 { // In voice mode 4467 { // In voice mode
2321 // In Voice Mode only tell the street name in level 1 or in level 0 if level 1 4468 // In Voice Mode only tell the street name in level 1 or in level 0 if level 1
2322 // was skipped 4469 // was skipped
2323 4470
2324 if (level == 1) 4471 if (level == 1)
2325 { // we are close to the intersection 4472 { // we are close to the intersection
2326 cmd->itm->streetname_told = 1; // remeber to be checked when we turn 4473 cmd->itm->streetname_told = 1; // remember to be checked when we turn
2327 tellstreetname = 1; // Ok so we tell the name of the street 4474 tellstreetname = 1; // Ok so we tell the name of the street
2328 } 4475 }
2329 4476
2330 if (level == 0) 4477 if (level == 0)
2331 { 4478 {
2349 { 4496 {
2350 // never speak streetnames (user config option) 4497 // never speak streetnames (user config option)
2351 tellstreetname = 0; 4498 tellstreetname = 0;
2352 } 4499 }
2353 4500
4501#ifdef NAVIT_ROUTING_DEBUG_PRINT
4502 dbg(0, "SPK:level=%d street_dest_text=%p tellstreetname=%d\n", level, cmd->itm->way.street_dest_text, tellstreetname);
4503#endif
2354 if (nav->tell_street_name && tellstreetname) 4504 if (nav->tell_street_name && tellstreetname)
2355 { 4505 {
2356 destination = navigation_item_destination(nav, cmd->itm, itm, " "); 4506 destination = navigation_item_destination(nav, cmd->itm, itm, " ");
4507#ifdef NAVIT_ROUTING_DEBUG_PRINT
4508 dbg(0, "SPK:levelX=%d dest=%s\n", level, destination);
4509#endif
2357 } 4510 }
4511 else if ((global_speak_streetnames == 1) && (cmd->itm->way.street_dest_text))
4512 {
4513 destination = navigation_item_destination(nav, cmd->itm, itm, " ");
4514#ifdef NAVIT_ROUTING_DEBUG_PRINT
4515 dbg(0, "SPK:levely=%d dest=%s d=%s\n", level, destination, cmd->itm->way.street_dest_text);
4516#endif
4517
4518 cmd->itm->streetname_told = 0;
4519 }
4520
4521 // dbg(0, "SPK:001\n");
2358 4522
2359 if (level != -2) 4523 if (level != -2)
2360 { 4524 {
4525
4526 //dbg(0, "SPK:002\n");
4527
2361#ifdef HAVE_API_ANDROID 4528#ifdef HAVE_API_ANDROID
2362#ifdef NAVIT_SAY_DEBUG_PRINT 4529#ifdef NAVIT_SAY_DEBUG_PRINT
2363 android_send_generic_text(1,"+*#O:Turn %1$s%2$s %3$s%4$s\n"); 4530 android_send_generic_text(1,"+*#O:Turn %1$s%2$s %3$s%4$s\n");
2364 gchar* xy=g_strdup_printf("+*#1:%s\n", strength); 4531 gchar* xy=g_strdup_printf("+*#1:%s\n", strength);
2365 android_send_generic_text(1,xy); 4532 android_send_generic_text(1,xy);
2373 xy=g_strdup_printf("+*#1:%s\n", destination ? destination : ""); 4540 xy=g_strdup_printf("+*#1:%s\n", destination ? destination : "");
2374 android_send_generic_text(1,xy); 4541 android_send_generic_text(1,xy);
2375 g_free(xy); 4542 g_free(xy);
2376#endif 4543#endif
2377#endif 4544#endif
4545
4546 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
4547 {
4548 //dbg(0, "level=%5$d level_now=%6$d str=%1$s%2$s %3$s%4$s\n", strength, dir, d, destination ? destination : "", level, level_now);
4549
4550 if (level_now == 0)
4551 {
4552 if (against_oneway == 1)
4553 {
4554 if (delta < 8)
4555 {
4556 ret = g_strdup_printf("%s", _("oncoming traffic!")); // just say "attention oneway street!"
4557 }
4558 else
4559 {
4560 ret = g_strdup_printf("%s, %s", dir, _("oncoming traffic!")); // just say "left" or "right" at the turn + "attention oneway street!"
4561 }
4562 }
4563 else
4564 {
4565 ret = g_strdup(dir); // just say "left" or "right" at the turn
4566 }
4567 }
4568 else
4569 {
4570 if ((against_oneway == 1) && (delta < 8))
4571 {
4572 ret = g_strdup(""); // probably just going against a oneway street, but travelling straight on. dont say anything now
4573 }
4574 else
4575 {
4576 if (delta == 0)
4577 {
4578 // TRANSLATORS: The first argument is strength, the second direction, the third distance and the fourth destination Example: 'Turn 'slightly' 'left' in '100 m' 'onto baker street'
4579 ret = g_strdup_printf_4_str(_("%1$s%2$s %3$s%4$s"), "", dir, d, destination ? destination : "");
4580 }
4581 else
4582 {
4583 // TRANSLATORS: The first argument is strength, the second direction, the third distance and the fourth destination Example: 'Turn 'slightly' 'left' in '100 m' 'onto baker street'
4584 ret = g_strdup_printf_4_str(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
4585 }
4586 }
4587 }
4588 }
4589 else
4590 {
4591 if (delta == 0)
4592 {
2378 // TRANSLATORS: The first argument is strength, the second direction, the third distance and the fourth destination Example: 'Turn 'slightly' 'left' in '100 m' 'onto baker street' 4593 // TRANSLATORS: The first argument is strength, the second direction, the third distance and the fourth destination Example: 'Turn 'slightly' 'left' in '100 m' 'onto baker street'
4594 ret = g_strdup_printf_4_str(_("%1$s%2$s %3$s%4$s"), "", dir, d, destination ? destination : "");
4595 }
4596 else
4597 {
4598 // TRANSLATORS: The first argument is strength, the second direction, the third distance and the fourth destination Example: 'Turn 'slightly' 'left' in '100 m' 'onto baker street'
2379 ret = g_strdup_printf(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : ""); 4599 ret = g_strdup_printf_4_str(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
4600 }
2380 } 4601 }
2381 else 4602 }
4603 else // (level == 2)
2382 { 4604 {
4605
4606 //dbg(0, "SPK:007\n");
4607
4608
2383#ifdef HAVE_API_ANDROID 4609#ifdef HAVE_API_ANDROID
2384#ifdef NAVIT_SAY_DEBUG_PRINT 4610#ifdef NAVIT_SAY_DEBUG_PRINT
2385 android_send_generic_text(1,"+*#O:then turn %1$s%2$s %3$s%4$s\n"); 4611 android_send_generic_text(1,"+*#O:then turn %1$s%2$s %3$s%4$s\n");
2386 gchar* xy=g_strdup_printf("+*#1:%s\n", strength); 4612 gchar* xy=g_strdup_printf("+*#1:%s\n", strength);
2387 android_send_generic_text(1,xy); 4613 android_send_generic_text(1,xy);
2395 xy=g_strdup_printf("+*#1:%s\n", destination ? destination : ""); 4621 xy=g_strdup_printf("+*#1:%s\n", destination ? destination : "");
2396 android_send_generic_text(1,xy); 4622 android_send_generic_text(1,xy);
2397 g_free(xy); 4623 g_free(xy);
2398#endif 4624#endif
2399#endif 4625#endif
4626 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
4627 {
4628 if ((against_oneway == 1) && (delta < 8))
4629 {
4630 ret = g_strdup(""); // probably just going against a oneway street, but travelling straight on. dont say anything now
4631 }
4632 else
4633 {
4634 if (delta == 0)
4635 {
4636 // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
4637 ret = g_strdup_printf_4_str(_("then %1$s%2$s %3$s%4$s"), "", dir, d, destination ? destination : "");
4638 }
4639 else
4640 {
4641 // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
4642 ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
4643 }
4644 }
4645 }
4646 else
4647 {
4648 if (delta == 0)
4649 {
2400 // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination 4650 // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
4651 ret = g_strdup_printf_4_str(_("then %1$s%2$s %3$s%4$s"), "", dir, d, destination ? destination : "");
4652 }
4653 else
4654 {
4655 // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
2401 ret = g_strdup_printf(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : ""); 4656 ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
4657 }
4658 }
2402 } 4659 }
2403 g_free(destination); 4660 g_free(destination);
2404 } 4661 }
2405 else 4662 else
2406 { 4663 {
2422#ifdef HAVE_API_ANDROID 4679#ifdef HAVE_API_ANDROID
2423#ifdef NAVIT_SAY_DEBUG_PRINT 4680#ifdef NAVIT_SAY_DEBUG_PRINT
2424 android_send_generic_text(1,"+*#O:then you have reached your destination.\n"); 4681 android_send_generic_text(1,"+*#O:then you have reached your destination.\n");
2425#endif 4682#endif
2426#endif 4683#endif
2427 ret = g_strdup_printf(_("then you have reached your destination.")); 4684 ret = g_strdup(_("then you have reached your destination."));
2428 } 4685 }
2429 } 4686 }
2430 g_free(d); 4687 g_free(d);
4688
2431 return ret; 4689 return2 ret;
4690
4691__F_END__
2432} 4692}
2433 4693
2434/** 4694/**
2435 * @brief Creates announcements for maneuvers, plus maneuvers immediately following the next maneuver 4695 * @brief Creates announcements for maneuvers, plus maneuvers immediately following the next maneuver
2436 * 4696 *
2437 * This function does create an announcement for the current maneuver and for maneuvers 4697 * This function does create an announcement for the current maneuver and for maneuvers
2438 * immediately following that maneuver, if these are too close and we're in speech navigation. 4698 * immediately following that maneuver, if these are too close and we're in speech navigation.
2439 * 4699 *
2440 * @return An announcement that should be made 4700 * @return An announcement that should be made
2441 */ 4701 */
4702// central entry point for TTS maneuvers --------------
4703// central entry point for TTS maneuvers --------------
4704// central entry point for TTS maneuvers --------------
2442static char * 4705static char *
2443show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type) 4706show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type)
2444{ 4707{
4708__F_START__
4709
2445 struct navigation_command *cur, *prev; 4710 struct navigation_command *cur, *prev;
2446 int distance = itm->dest_length - cmd->itm->dest_length; 4711 int distance = itm->dest_length - cmd->itm->dest_length;
2447 int level, dist, i, time; 4712 int level, dist, i, time, level2;
2448 int speech_time, time2nav; 4713 int speech_time, time2nav;
2449 char *ret, *old, *buf, *next; 4714 char *ret, *old, *buf, *next;
2450 4715
4716 char *temp_txt = NULL;
4717
4718
4719 //dbg(0, "Enter\n");
4720
2451 if (type != attr_navigation_speech) 4721 if (type != attr_navigation_speech)
2452 { 4722 {
2453 return show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only in speech navigation 4723 return2 show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only in speech navigation
2454 } 4724 }
2455 4725
4726
4727 // -- bicycle mode START --
4728 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
4729 {
2456 level = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length); 4730 level = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length);
2457 4731
4732 //dbg(0, "level = %d\n", level);
4733 //dbg(0, "(nn)itm->way.flags=%x\n", itm->way.flags);
4734 //dbg(0, "(nn)itm->next->way.flags=%x\n", itm->next->way.flags);
4735 //dbg(0, "(nn)distance=%d cmd->length=%d (minus)=%d\n", distance, cmd->length, (distance - cmd->length));
4736
4737 // in bike mode level should only be "0" or "1" or "3" !
4738
4739 if (level > 2)
4740 {
4741 //dbg(0, "just say the current command\n");
4742 return2 show_maneuver_bicycle(nav, itm, cmd, type, 0, level); // just say the current command
4743 }
4744
4745 if (cmd->itm->told)
4746 {
4747 // current command should not be spoken again!
4748 //dbg(0, "current command should not be spoken again\n");
4749 return2 g_strdup("");
4750 }
4751
4752
4753 //dbg(0, "xx 017a fsp, itm->told=%d l=%d\n", cmd->itm->told, level);
4754 if (level == 0)
4755 {
4756 // this command is spoken (now)
4757 //dbg(0, "this command is spoken (now)\n");
4758 cmd->itm->told = 1;
4759 }
4760 //dbg(0, "xx 017b fsp, itm->told=%d\n", cmd->itm->told);
4761
4762
4763 // current maneuver -------
4764 ret = show_maneuver_bicycle(nav, itm, cmd, type, 0, level); // generate TTS text for current command
4765 //dbg(0, "ret cmd=%s\n", ret);
4766 time2nav = navigation_time(itm, cmd->itm->prev);
4767 //dbg(0, "time2nav = %d\n", time2nav);
4768 old = NULL;
4769 // current maneuver -------
4770
4771 cur = cmd->next;
4772 prev = cmd;
4773
4774 if (cur && cur->itm) // we have a next command
4775 {
4776 dist = prev->itm->dest_length - cur->itm->dest_length;
4777 level2 = navigation_get_announce_level(nav, itm->next->way.item.type, dist);
4778 //dbg(0, "(next)level2 = %d\n", level2);
4779 //dbg(0, "(next)dist=%d\n", dist);
4780
4781 if ((level2 < 2) && (dist < (2 * level_static_for_bicycle[0])))
4782 {
4783 //dbg(0, "link next command, and dont say it again!\n");
4784 old = ret;
4785 buf = show_maneuver_bicycle(nav, prev->itm, cur, type, 1, 0); // generate TTS text for next command, and dont say the next command again!
4786 //dbg(0, "next cmd=%s\n", next);
4787 ret = g_strdup_printf("%s, %s", old, buf);
4788 //dbg(0, "next cmd concat=%s\n", ret);
4789 g_free(buf);
4790 g_free(old);
4791 if (level == 0)
4792 {
4793 // dont say this next command again!
4794 cur->itm->told = 1;
4795 }
4796 }
4797 }
4798 }
4799 // -- bicycle mode END --
4800 else
4801 {
4802
4803
4804
4805 // -------------------------------------------------
4806 // -------------------------------------------------
4807 // -- ******************************************* --
4808 // -- ******************************************* --
4809 // -------------------------------------------------
4810 // -------------------------------------------------
4811
4812 level = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length);
4813 //dbg(0, "level = %d\n", level);
4814 //dbg(0, "(nn)itm->way.flags=%x\n", itm->way.flags);
4815 //dbg(0, "(nn)itm->next->way.flags=%x\n", itm->next->way.flags);
4816
4817 long temp_ts = -1;
4818 debug_get_timestamp_millis(&temp_ts);
4819 if (global_last_spoken == -1)
4820 {
4821 temp_ts = 99999999;
4822 }
4823
4824 int time2nav_2 = navigation_time(itm, cmd->itm->prev);
4825
4826 dbg(0, "SPEECH:[-00-] last spoken ago=%f\n", (float)((temp_ts - global_last_spoken) / 1000.0f));
4827 dbg(0, "SPEECH:[-01-] meters to next maneuver=%d\n", (distance - cmd->length));
4828 dbg(0, "SPEECH:[-02-] level=%d\n", level);
4829
4830#ifdef HAVE_API_ANDROID
4831 temp_txt = g_strdup_printf("SPEECH:[-00-] last spoken ago=%f\n", (float)((temp_ts - global_last_spoken) / 1000.0f));
4832 android_send_generic_text(20, temp_txt);
4833 g_free(temp_txt);
4834
4835 temp_txt = g_strdup_printf("SPEECH:[-01-] meters to next maneuver=%d\n", (distance - cmd->length));
4836 android_send_generic_text(20, temp_txt);
4837 g_free(temp_txt);
4838
4839 temp_txt = g_strdup_printf("SPEECH:[-02-] level=%d\n", level);
4840 android_send_generic_text(20, temp_txt);
4841 g_free(temp_txt);
4842#endif
4843
4844 dbg(0, "SPEECH:[-03-] time2nav secs=%f\n", ((float)time2nav_2 / 10.0f));
4845#ifdef HAVE_API_ANDROID
4846 temp_txt = g_strdup_printf("SPEECH:[-03-] time2nav secs=%f\n", ((float)time2nav_2 / 10.0f));
4847 android_send_generic_text(20, temp_txt);
4848 g_free(temp_txt);
4849#endif
4850
2458 if (level > 1) 4851 if (level > 1)
2459 { 4852 {
4853 dbg(0, "SPEECH:[-R1-]\n");
2460 return show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only if they are close 4854 return2 show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only if they are close
2461 } 4855 }
2462 4856
2463 if (cmd->itm->told) 4857 if (cmd->itm->told)
2464 { 4858 {
2465#ifdef HAVE_API_ANDROID 4859#ifdef HAVE_API_ANDROID
2466#ifdef NAVIT_SAY_DEBUG_PRINT 4860#ifdef NAVIT_SAY_DEBUG_PRINT
2467 android_send_generic_text(1,"+*#C1:*CANCEL*\n"); 4861 android_send_generic_text(1,"+*#C1:*CANCEL*\n");
2468#endif 4862#endif
2469#endif 4863#endif
4864 dbg(0, "SPEECH:[-R2-]\n");
4865#ifdef HAVE_API_ANDROID
4866 temp_txt = g_strdup("SPEECH:[-R2-]\n");
4867 android_send_generic_text(20, temp_txt);
4868 g_free(temp_txt);
4869#endif
4870
2470 return g_strdup(""); 4871 return2 g_strdup("");
2471 } 4872 }
2472 4873
4874 // current maneuver -------
2473 ret = show_maneuver(nav, itm, cmd, type, 0); 4875 ret = show_maneuver(nav, itm, cmd, type, 0);
2474 time2nav = navigation_time(itm, cmd->itm->prev); 4876 time2nav = navigation_time(itm, cmd->itm->prev);
2475 old = NULL; 4877 old = NULL;
2476 4878
4879 dbg(0, "SPEECH:[-04-] time2nav secs=%f\n", ((float)time2nav / 10.0f));
4880#ifdef HAVE_API_ANDROID
4881 temp_txt = g_strdup_printf("SPEECH:[-04-] time2nav secs=%f\n", ((float)time2nav / 10.0f));
4882 android_send_generic_text(20, temp_txt);
4883 g_free(temp_txt);
4884#endif
4885
4886 // current maneuver -------
4887
2477 cur = cmd->next; 4888 cur = cmd->next;
2478 prev = cmd; 4889 prev = cmd;
4890
2479 i = 0; 4891 i = 0;
4892 int max_announcements = 3;
4893 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
4894 {
4895 max_announcements = 2;
4896 }
4897
2480 while (cur && cur->itm) 4898 while (cur && cur->itm)
2481 { 4899 {
2482 // We don't merge more than 3 announcements... 4900 // We don't merge more than "max_announcements" announcements...
2483 if (i > 1) 4901 if (i > (max_announcements - 2))
2484 { // if you change this, please also change the value below, that is used to terminate the loop 4902 {
2485 break; 4903 break;
2486 } 4904 }
2487 4905
2488 next = show_maneuver(nav, prev->itm, cur, type, 0); 4906 next = show_maneuver(nav, prev->itm, cur, type, 0);
2489 if (nav->speech) 4907 if (nav->speech)
2490 { 4908 {
2491 speech_time = speech_estimate_duration(nav->speech, next); 4909 speech_time = speech_estimate_duration(nav->speech, next);
4910 dbg(0, "SPEECH: secs=%f text=%s\n", ((float)speech_time)/10.0f, next);
2492 } 4911 }
2493 else 4912 else
2494 { 4913 {
2495 speech_time = -1; 4914 speech_time = -1;
4915 dbg(0, "SPEECH: secs=-1 text=%s\n", next);
2496 } 4916 }
2497 g_free(next); 4917 g_free(next);
2498 4918
2499 if (speech_time == -1) 4919 if (speech_time == -1)
4920 {
2500 { // user didn't set cps 4921 // user didn't set cps
2501 speech_time = 30; // assume 3 seconds 4922 speech_time = 20; // assume 2 seconds
4923 dbg(0, "SPEECH:(2) secs=%f\n", ((float)speech_time)/10.0f);
2502 } 4924 }
2503 4925
2504 dist = prev->itm->dest_length - cur->itm->dest_length; 4926 dist = prev->itm->dest_length - cur->itm->dest_length;
2505 time = navigation_time(prev->itm, cur->itm->prev); 4927 time = navigation_time(prev->itm, cur->itm->prev);
4928 dbg(0, "SPEECH:[-05-] dist meters=%d time secs=%f speech_time=%f\n", dist, ((float)time)/10.0f, ((float)speech_time)/10.0f);
4929#ifdef HAVE_API_ANDROID
4930 temp_txt = g_strdup_printf("SPEECH:[-05-] dist meters=%d time secs=%f speech_time=%f\n", dist, ((float)time)/10.0f, ((float)speech_time)/10.0f);
4931 android_send_generic_text(20, temp_txt);
4932 g_free(temp_txt);
4933#endif
2506 4934
2507 if (time >= (speech_time + 30)) 4935
4936 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
4937 {
4938 }
4939 else
4940 {
4941 dbg(0, "SPEECH: time secs=%f speech_time secs=%f [if (time >= (speech_time + 30))]\n", ((float)time)/10.0f, ((float)speech_time)/10.0f);
4942 if (time >= (speech_time + 30)) // in 1/10th of seconds
2508 { // 3 seconds for understanding what has been said 4943 { // 0 seconds for understanding what has been said
2509 break; 4944 break;
4945 }
2510 } 4946 }
2511 4947
2512 old = ret; 4948 old = ret;
2513 buf = show_maneuver(nav, prev->itm, cur, type, 1); 4949 buf = show_maneuver(nav, prev->itm, cur, type, 1);
2514 ret = g_strdup_printf("%s, %s", old, buf); 4950 ret = g_strdup_printf("%s, %s", old, buf);
2515 g_free(buf); 4951 g_free(buf);
2516 4952
4953 dbg(0, "SPEECH: speech_est_dur secs=%f time2nav secs=%f\n", (float)(speech_estimate_duration(nav->speech, ret))/10.0f, (float)time2nav/10.0f);
2517 if (nav->speech && speech_estimate_duration(nav->speech, ret) > time2nav) 4954 if (nav->speech && speech_estimate_duration(nav->speech, ret) > time2nav)
2518 { 4955 {
2519 g_free(ret); 4956 g_free(ret);
2520 ret = old; 4957 ret = old;
2521 i = 2; // This will terminate the loop 4958 i = (max_announcements - 1); // This will terminate the loop
2522 } 4959 }
2523 else 4960 else
2524 { 4961 {
2525 g_free(old); 4962 g_free(old);
2526 } 4963 }
2527 4964
4965
4966 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
4967 {
4968 }
4969 else
4970 {
4971 dbg(0, "SPEECH: time secs=%f speech_time secs=%f [if (time <= speech_time)]\n", ((float)time)/10.0f, ((float)speech_time)/10.0f);
2528 // If the two maneuvers are *really* close, we shouldn't tell the second one again, because TTS won't be fast enough 4972 // If the two maneuvers are *really* close, we shouldn't tell the second one again, because TTS won't be fast enough
2529 if (time <= speech_time) 4973 if (time <= speech_time)
2530 { 4974 {
2531#ifdef HAVE_API_ANDROID 4975#ifdef HAVE_API_ANDROID
2532#ifdef NAVIT_SAY_DEBUG_PRINT 4976#ifdef NAVIT_SAY_DEBUG_PRINT
2533 android_send_generic_text(1,"+*#C2:*CANCEL*\n"); 4977 android_send_generic_text(1,"+*#C2:*CANCEL*\n");
2534#endif 4978#endif
2535#endif 4979#endif
4980 //dbg(0, "cancel speak:%s\n", ret);
2536 cur->itm->told = 1; 4981 cur->itm->told = 1;
4982 }
2537 } 4983 }
2538 4984
2539 prev = cur; 4985 prev = cur;
2540 cur = cur->next; 4986 cur = cur->next;
2541 i++; 4987 i++;
2542 } 4988 }
2543 4989
4990 // -------------------------------------------------
4991 // -------------------------------------------------
4992 // -- ******************************************* --
4993 // -- ******************************************* --
4994 // -------------------------------------------------
4995 // -------------------------------------------------
4996
4997
4998
4999
5000
5001 }
5002
5003 dbg(0, "SPEECH:[-Re-]\n");
5004#ifdef HAVE_API_ANDROID
5005 temp_txt = g_strdup("SPEECH:[-Re-]\n");
5006 android_send_generic_text(20, temp_txt);
5007 g_free(temp_txt);
5008#endif
5009
2544 return ret; 5010 return2 ret;
5011
5012__F_END__
2545} 5013}
5014// central entry point for TTS maneuvers --------------
5015// central entry point for TTS maneuvers --------------
5016// central entry point for TTS maneuvers --------------
5017
5018
5019
5020// ----- global var, BAD!! -------
5021int global_spoke_last_position_update = 0;
5022// ----- global var, BAD!! -------
2546 5023
2547static void navigation_call_callbacks(struct navigation *this_, int force_speech) 5024static void navigation_call_callbacks(struct navigation *this_, int force_speech)
2548{ 5025{
5026__F_START__
5027
2549 int distance, level = 0; 5028 int distance, level = 0;
5029 int level_cur;
5030 int distance_orig;
2550 void *p = this_; 5031 void *p = this_;
2551 5032
2552 if (!this_->cmd_first) 5033 if (!this_->cmd_first)
2553 { 5034 {
5035 //dbg(0, "ret 0001\n");
5036 global_spoke_last_position_update = 0;
2554 return; 5037 return2;
2555 } 5038 }
2556 5039
2557 callback_list_call(this_->callback, 1, &p); 5040 callback_list_call(this_->callback, 1, &p);
5041
5042 //if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
5043 //{
5044 // force_speech = 7;
5045 //}
5046
2558 //dbg(1,"force_speech=%d turn_around=%d turn_around_limit=%d\n", force_speech, this_->turn_around, this_->turn_around_limit); 5047 //dbg(0, "force_speech=%d turn_around=%d turn_around_limit=%d\n", force_speech, this_->turn_around, this_->turn_around_limit);
5048
2559 distance = round_distance(this_->first->dest_length - this_->cmd_first->itm->dest_length); 5049 distance = this_->first->dest_length - this_->cmd_first->itm->dest_length;
5050 //dbg(0, "fdl=%d cmdidl=%d\n", this_->first->dest_length, this_->cmd_first->itm->dest_length);
5051 distance_orig = distance;
5052 distance = round_distance(distance);
2560 if (this_->turn_around_limit && this_->turn_around == this_->turn_around_limit) 5053 if (this_->turn_around_limit && this_->turn_around == this_->turn_around_limit)
2561 { 5054 {
2562 //dbg(1,"distance=%d distance_turn=%d\n", distance, this_->distance_turn); 5055 //dbg(0, "xx 001 d=%d rd=%d dt=%d\n", distance_orig, distance_orig, this_->distance_turn);
2563 while (distance > this_->distance_turn) 5056 while (distance > this_->distance_turn)
2564 { 5057 {
2565 this_->level_last = 4; 5058 this_->level_last = 4;
2566 level = 4; 5059 level = 4;
2567 force_speech = 2; 5060 force_speech = 2;
5061
2568 if (this_->distance_turn >= 500) 5062 if (this_->distance_turn >= 500)
5063 {
2569 this_->distance_turn *= 2; 5064 this_->distance_turn *= 2;
5065 }
2570 else 5066 else
5067 {
2571 this_->distance_turn = 500; 5068 this_->distance_turn = 500;
5069 }
5070
5071 //dbg(0, "xx loop 001 d=%d dt=%d\n", distance, this_->distance_turn);
2572 } 5072 }
2573 } 5073 }
2574 else if (!this_->turn_around_limit || this_->turn_around == -this_->turn_around_limit + 1) 5074 else if (!this_->turn_around_limit || this_->turn_around == -this_->turn_around_limit + 1)
2575 { 5075 {
2576 this_->distance_turn = 50; 5076 this_->distance_turn = 50;
5077
5078 //dbg(0, "lcur=%d lprev=%d lnext=%d\n", this_->cmd_first->itm->length, this_->cmd_first->itm->prev->length, this_->cmd_first->itm->next->length);
5079 //dbg(0, "xx 002a d=%d d2=%d diff=%d\n", distance, (distance - this_->cmd_first->length), (this_->cmd_first->itm->length - distance_orig));
5080
5081 //dbg(0, "xx 002a ll001=%d\n", (this_->cmd_first->itm->prev->dest_length - this_->cmd_first->itm->dest_length));
5082
2577 distance -= this_->cmd_first->length; 5083 distance -= this_->cmd_first->length;
2578 level = navigation_get_announce_level_cmd(this_, this_->first, this_->cmd_first, distance); 5084 level = navigation_get_announce_level_cmd(this_, this_->first, this_->cmd_first, distance_orig);
5085 level_cur = navigation_get_announce_level(this_, this_->first->way.item.type, distance_orig);
5086
5087 //dbg(0, "xx 002 d=%d rd=%d dt=%d l=%d lcur=%d ll=%d\n", distance_orig, distance, this_->distance_turn, level, level_cur, this_->level_last);
5088
2579 if (level < this_->level_last) 5089 if (level < this_->level_last)
2580 { 5090 {
2581 /* only tell if the level is valid for more than 3 seconds */ 5091 /* only tell if the level is valid for more than 3 seconds */
2582 int speed_distance = this_->first->speed * 30 / 36; 5092 int speed_distance = this_->first->speed * 30 / 36;
5093
5094 //dbg(0, "xx 003 speed_distance=%d this_->first->speed=%d globalslp=%d\n", speed_distance, this_->first->speed, global_spoke_last_position_update);
5095
5096 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
5097 {
5098
5099 level = level_cur;
5100
5101 if ((level_cur > 0) && (global_spoke_last_position_update > 0))
5102 {
5103 // skip this time, speak command on the next update
5104 //dbg(0, "SKIP[1] this update, speak next update (%d)!\n", global_spoke_last_position_update);
5105 }
5106 else
5107 {
5108 this_->level_last = level_cur;
5109 force_speech = 3;
5110 }
5111 }
5112 else
5113 {
2583 if (distance < speed_distance || navigation_get_announce_level_cmd(this_, this_->first, this_->cmd_first, distance - speed_distance) == level) 5114 if (distance < speed_distance || navigation_get_announce_level_cmd(this_, this_->first, this_->cmd_first, distance - speed_distance) == level)
2584 { 5115 {
2585 dbg(1, "distance %d speed_distance %d\n", distance, speed_distance); 5116 //dbg(0, "distance %d speed_distance %d\n", distance, speed_distance);
2586 dbg(1, "level %d < %d\n", level, this_->level_last); 5117 //dbg(0, "level %d < %d\n", level, this_->level_last);
2587 this_->level_last = level; 5118 this_->level_last = level;
2588 force_speech = 3; 5119 force_speech = 3;
5120 //dbg(0, "xx 004\n");
2589 } 5121 }
2590 } 5122 }
5123 }
5124
2591 5125
2592 if (!item_is_equal(this_->cmd_first->itm->way.item, this_->item_last)) 5126 if (!item_is_equal(this_->cmd_first->itm->way.item, this_->item_last))
2593 { 5127 {
5128 //dbg(0, "xx 005\n");
5129
2594 this_->item_last = this_->cmd_first->itm->way.item; 5130 this_->item_last = this_->cmd_first->itm->way.item;
5131 this_->level_last = 99; // new item, reset command level
5132
2595 if (this_->delay) 5133 if (this_->delay)
5134 {
2596 this_->curr_delay = this_->delay; 5135 this_->curr_delay = this_->delay;
5136 }
2597 else 5137 else
5138 {
5139 if ((level_cur > 0) && (global_spoke_last_position_update > 0) && (distance_orig > 50))
5140 {
5141 // skip this time, speak command on the next update
5142 //dbg(0, "SKIP[2] speech this update, speak at next update (%d)!\n", global_spoke_last_position_update);
5143 }
5144 else
5145 {
2598 force_speech = 5; 5146 force_speech = 5;
5147 }
5148 }
2599 } 5149 }
2600 else 5150 else
2601 { 5151 {
5152 //dbg(0, "xx 006\n");
5153
2602 if (this_->curr_delay) 5154 if (this_->curr_delay)
2603 { 5155 {
2604 this_->curr_delay--; 5156 this_->curr_delay--;
5157
2605 if (!this_->curr_delay) 5158 if (!this_->curr_delay)
5159 {
2606 force_speech = 4; 5160 force_speech = 4;
2607 } 5161 }
2608 } 5162 }
2609 } 5163 }
5164 }
5165
5166 if (global_spoke_last_position_update > 0)
5167 {
5168 //dbg(0,"globalslp(1)=%d\n", global_spoke_last_position_update);
5169 global_spoke_last_position_update--;
5170 //dbg(0,"globalslp(2)=%d\n", global_spoke_last_position_update);
5171 }
5172
5173 //dbg(0,"XA 000\n");
5174 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
5175 {
5176 if ((this_->previous) && (!item_is_equal(this_->cmd_first->itm->way.item, this_->previous->way.item)))
5177 {
5178 // item has changed, check if we missed a spoken level 0 command
5179 if (this_->previous->told == 0)
5180 {
5181 dbg(0, "MISSED a level 0 spoken command!\n");
5182
5183 char *dir2 = _("right");
5184 int delta2 = this_->cmd_previous->delta;
5185 dbg(0, "missed delta = %d\n", delta2);
5186 if (delta2 < 0)
5187 {
5188 // TRANSLATORS: left, as in 'Turn left'
5189 dir2 = _("left");
5190 delta2 = -delta2;
5191 }
5192
5193 if (delta2 > 20)
5194 {
5195 dbg(0,"XA 002a\n");
5196 navit_say(this_->navit, dir2);
5197 this_->previous->told = 1;
5198 }
5199 }
5200 }
5201 }
5202
5203 this_->previous = this_->cmd_first->itm;
5204 this_->cmd_previous = this_->cmd_first;
2610 5205
2611 if (force_speech) 5206 if (force_speech)
2612 { 5207 {
2613 this_->level_last = level; 5208 this_->level_last = level;
2614 this_->curr_delay = 0; 5209 this_->curr_delay = 0;
5210 global_spoke_last_position_update = 1;
5211 //dbg(0, "xx 017 force_speech! globalslp(f1)=%d\n", global_spoke_last_position_update);
5212
2615 dbg(1, "force_speech=%d distance=%d level=%d type=0x%x\n", force_speech, distance, level, this_->first->way.item.type); 5213 //dbg(0, "force_speech=%d distance=%d level=%d\n", force_speech, distance, level);
2616 callback_list_call(this_->callback_speech, 1, &p); 5214 callback_list_call(this_->callback_speech, 1, &p);
2617 } 5215 }
2618}
2619 5216
5217__F_END__
5218}
5219
5220
5221// ----------- main place where navigation commands are generated ------------
5222// ----------- main place where navigation commands are generated ------------
5223// ----------- main place where navigation commands are generated ------------
2620static void navigation_update(struct navigation *this_, struct route *route, struct attr *attr) 5224static void navigation_update(struct navigation *this_, struct route *route, struct attr *attr)
2621{ 5225{
5226__F_START__
5227
2622 struct map *map; 5228 struct map *map;
2623 struct map_rect *mr; 5229 struct map_rect *mr;
2624 struct item *ritem; /* Holds an item from the route map */ 5230 struct item *ritem; /* Holds an item from the route map */
2625 struct item *sitem; /* Holds the corresponding item from the actual map */ 5231 struct item *sitem; /* Holds the corresponding item from the actual map */
2626 struct attr street_item, street_direction; 5232 struct attr street_item, street_direction;
2627 struct navigation_itm *itm; 5233 struct navigation_itm *itm;
2628 struct attr vehicleprofile; 5234 struct attr vehicleprofile;
2629 int mode = 0, incr = 0, first = 1; 5235 int mode = 0, incr = 0, first = 1;
5236
5237 //dbg(0, "Enter\n");
5238
2630 if (attr->type != attr_route_status) 5239 if (attr->type != attr_route_status)
5240 {
5241 //dbg(0, "return 001\n");
2631 return; 5242 return2;
5243 }
2632 5244
5245#ifdef NAVIT_ROUTING_DEBUG_PRINT
5246 dbg(0, "RS:001:route_status=%s\n", route_status_to_name(attr->u.num));
5247#endif
5248
2633 dbg(1, "enter %d\n", mode); 5249 //dbg(1, "enter %d\n", mode);
2634 if (attr->u.num == route_status_no_destination || attr->u.num == route_status_not_found || attr->u.num == route_status_path_done_new) 5250 if (attr->u.num == route_status_no_destination || attr->u.num == route_status_not_found || attr->u.num == route_status_path_done_new)
5251 {
2635 navigation_flush(this_); 5252 navigation_flush(this_);
5253 }
5254
2636 if (attr->u.num != route_status_path_done_new && attr->u.num != route_status_path_done_incremental) 5255 if (attr->u.num != route_status_path_done_new && attr->u.num != route_status_path_done_incremental)
5256 {
5257 //dbg(0, "return 002\n");
2637 return; 5258 return2;
5259 }
2638 5260
2639 if (!this_->route) 5261 if (!this_->route)
5262 {
5263 //dbg(0, "return 003\n");
2640 return; 5264 return2;
5265 }
5266
2641 map = route_get_map(this_->route); 5267 map = route_get_map(this_->route);
2642 if (!map) 5268 if (!map)
5269 {
5270 //dbg(0, "return 004\n");
2643 return; 5271 return2;
5272 }
5273
2644 mr = map_rect_new(map, NULL); 5274 mr = map_rect_new(map, NULL);
5275
2645 if (!mr) 5276 if (!mr)
5277 {
5278 //dbg(0, "return 005\n");
2646 return; 5279 return2;
5280 }
5281
2647 if (route_get_attr(route, attr_vehicleprofile, &vehicleprofile, NULL)) 5282 if (route_get_attr(route, attr_vehicleprofile, &vehicleprofile, NULL))
5283 {
2648 this_->vehicleprofile = vehicleprofile.u.vehicleprofile; 5284 this_->vehicleprofile = vehicleprofile.u.vehicleprofile;
5285 }
2649 else 5286 else
5287 {
2650 this_->vehicleprofile = NULL; 5288 this_->vehicleprofile = NULL;
5289 }
5290
2651 //dbg(1,"enter\n"); 5291 //dbg(1,"enter\n");
2652 5292
2653 while ((ritem = map_rect_get_item(mr))) 5293 while ((ritem = map_rect_get_item(mr)))
2654 { 5294 {
2655 if (ritem->type == type_route_start && this_->turn_around > -this_->turn_around_limit + 1) 5295 if (ritem->type == type_route_start && this_->turn_around > -this_->turn_around_limit + 1)
5296 {
2656 this_->turn_around--; 5297 this_->turn_around--;
5298 }
5299
2657 if (ritem->type == type_route_start_reverse && this_->turn_around < this_->turn_around_limit) 5300 if (ritem->type == type_route_start_reverse && this_->turn_around < this_->turn_around_limit)
5301 {
2658 this_->turn_around++; 5302 this_->turn_around++;
5303 }
5304
2659 if (ritem->type != type_street_route) 5305 if (ritem->type != type_street_route)
5306 {
2660 continue; 5307 continue;
5308 }
2661 5309
2662 if (first && item_attr_get(ritem, attr_street_item, &street_item)) 5310 if (first && item_attr_get(ritem, attr_street_item, &street_item))
2663 { 5311 {
2664 first = 0; 5312 first = 0;
2665 if (!item_attr_get(ritem, attr_direction, &street_direction)) 5313 if (!item_attr_get(ritem, attr_direction, &street_direction))
5314 {
2666 street_direction.u.num = 0; 5315 street_direction.u.num = 0;
5316 }
5317
2667 sitem = street_item.u.item; 5318 sitem = street_item.u.item;
2668 //dbg(1,"sitem=%p\n", sitem); 5319 //dbg(1,"sitem=%p\n", sitem);
2669 itm = item_hash_lookup(this_->hash, sitem); 5320 itm = item_hash_lookup(this_->hash, sitem);
2670 //dbg(2,"itm for item with id (0x%x,0x%x) is %p\n", sitem->id_hi, sitem->id_lo, itm); 5321 //dbg(2,"itm for item with id (0x%x,0x%x) is %p\n", sitem->id_hi, sitem->id_lo, itm);
2671 5322
2672 if (itm && itm->way.dir != street_direction.u.num) 5323 if (itm && itm->way.dir != street_direction.u.num)
2673 { 5324 {
2674 //dbg(2,"wrong direction\n"); 5325 //dbg(2,"wrong direction\n");
2675 itm = NULL; 5326 itm = NULL;
2676 } 5327 }
5328
2677 navigation_destroy_itms_cmds(this_, itm); 5329 navigation_destroy_itms_cmds(this_, itm);
5330
2678 if (itm) 5331 if (itm)
2679 { 5332 {
2680 navigation_itm_update(itm, ritem); 5333 navigation_itm_update(itm, ritem);
2681 break; 5334 break;
2682 } 5335 }
2683 //dbg(1,"not on track\n"); 5336 //dbg(1,"not on track\n");
2684 } 5337 }
2685 navigation_itm_new(this_, ritem); 5338 navigation_itm_new(this_, ritem);
2686 } 5339 }
5340
2687 dbg(2, "turn_around=%d\n", this_->turn_around); 5341 //dbg(2, "turn_around=%d\n", this_->turn_around);
5342
2688 if (first) 5343 if (first)
5344 {
5345
5346#ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
5347 dbg(0, "DEST::route_clear_freetext_list\n");
5348 route_clear_freetext_list();
5349#endif
5350
2689 navigation_destroy_itms_cmds(this_, NULL); 5351 navigation_destroy_itms_cmds(this_, NULL);
5352 }
2690 else 5353 else
2691 { 5354 {
2692 if (!ritem) 5355 if (!ritem)
2693 { 5356 {
2694 navigation_itm_new(this_, NULL); 5357 navigation_itm_new(this_, NULL);
5358 //dbg(0, "Enter: make_maneuvers\n");
2695 make_maneuvers(this_, this_->route); 5359 make_maneuvers(this_, this_->route);
5360 //dbg(0, "end : make_maneuvers\n");
2696 } 5361 }
2697 calculate_dest_distance(this_, incr); 5362 calculate_dest_distance(this_, incr);
2698 //profile(0,"end"); 5363
5364 // calls navit_speak later !! ----------
2699 navigation_call_callbacks(this_, FALSE); 5365 navigation_call_callbacks(this_, FALSE);
5366 // calls navit_speak later !! ----------
2700 } 5367 }
2701 map_rect_destroy(mr); 5368 map_rect_destroy(mr);
5369
5370__F_END__
2702} 5371}
5372// ----------- main place where navigation commands are generated ------------
5373// ----------- main place where navigation commands are generated ------------
5374// ----------- main place where navigation commands are generated ------------
5375
2703 5376
2704static void navigation_flush(struct navigation *this_) 5377static void navigation_flush(struct navigation *this_)
2705{ 5378{
5379__F_START__
2706 navigation_destroy_itms_cmds(this_, NULL); 5380 navigation_destroy_itms_cmds(this_, NULL);
5381__F_END__
2707} 5382}
2708 5383
2709void navigation_destroy(struct navigation *this_) 5384void navigation_destroy(struct navigation *this_)
2710{ 5385{
2711 navigation_flush(this_); 5386 navigation_flush(this_);
2715 g_free(this_); 5390 g_free(this_);
2716} 5391}
2717 5392
2718int navigation_register_callback(struct navigation *this_, enum attr_type type, struct callback *cb) 5393int navigation_register_callback(struct navigation *this_, enum attr_type type, struct callback *cb)
2719{ 5394{
5395__F_START__
5396
2720 if (type == attr_navigation_speech) 5397 if (type == attr_navigation_speech)
5398 {
2721 callback_list_add(this_->callback_speech, cb); 5399 callback_list_add(this_->callback_speech, cb);
5400 }
2722 else 5401 else
5402 {
2723 callback_list_add(this_->callback, cb); 5403 callback_list_add(this_->callback, cb);
5404 }
5405
2724 return 1; 5406 return2 1;
5407
5408__F_END__
2725} 5409}
2726 5410
2727void navigation_unregister_callback(struct navigation *this_, enum attr_type type, struct callback *cb) 5411void navigation_unregister_callback(struct navigation *this_, enum attr_type type, struct callback *cb)
2728{ 5412{
5413__F_START__
5414
2729 if (type == attr_navigation_speech) 5415 if (type == attr_navigation_speech)
5416 {
2730 callback_list_remove_destroy(this_->callback_speech, cb); 5417 callback_list_remove_destroy(this_->callback_speech, cb);
5418 }
2731 else 5419 else
5420 {
2732 callback_list_remove_destroy(this_->callback, cb); 5421 callback_list_remove_destroy(this_->callback, cb);
5422 }
5423
5424__F_END__
2733} 5425}
2734 5426
2735struct map * 5427struct map *
2736navigation_get_map(struct navigation *this_) 5428navigation_get_map(struct navigation *this_)
2737{ 5429{
2780}; 5472};
2781 5473
2782static int navigation_map_item_coord_get(void *priv_data, struct coord *c, int count) 5474static int navigation_map_item_coord_get(void *priv_data, struct coord *c, int count)
2783{ 5475{
2784 struct map_rect_priv *this = priv_data; 5476 struct map_rect_priv *this = priv_data;
5477
2785 if (this->ccount || !count) 5478 if (this->ccount || !count)
2786 return 0; 5479 return 0;
5480
2787 *c = this->itm->start; 5481 *c = this->itm->start;
2788 this->ccount = 1; 5482 this->ccount = 1;
5483
2789 return 1; 5484 return 1;
2790} 5485}
2791 5486
2792static int navigation_map_item_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) 5487static int navigation_map_item_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
2793{ 5488{
2804 } 5499 }
2805 5500
2806 if (cmd) 5501 if (cmd)
2807 { 5502 {
2808 if (cmd->itm != itm) 5503 if (cmd->itm != itm)
5504 {
2809 cmd = NULL; 5505 cmd = NULL;
2810 } 5506 }
5507 }
5508
2811 switch (attr_type) 5509 switch (attr_type)
2812 { 5510 {
2813 case attr_navigation_short: 5511 case attr_navigation_short:
2814 this_->attr_next = attr_navigation_long; 5512 this_->attr_next = attr_navigation_long;
2815 if (cmd) 5513 if (cmd)
2816 { 5514 {
5515 //dbg(0, "attr_navigation_short\n");
2817 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type); 5516 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type);
2818 return 1; 5517 return 1;
2819 } 5518 }
2820 return 0; 5519 return 0;
2821 case attr_navigation_long: 5520 case attr_navigation_long:
2822 this_->attr_next = attr_navigation_long_exact; 5521 this_->attr_next = attr_navigation_long_exact;
2823 if (cmd) 5522 if (cmd)
2824 { 5523 {
5524 //dbg(0, "attr_navigation_long\n");
2825 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type); 5525 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type);
2826 return 1; 5526 return 1;
2827 } 5527 }
2828 return 0; 5528 return 0;
2829 case attr_navigation_long_exact: 5529 case attr_navigation_long_exact:
2830 this_->attr_next = attr_navigation_speech; 5530 this_->attr_next = attr_navigation_speech;
2831 if (cmd) 5531 if (cmd)
2832 { 5532 {
5533 //dbg(0, "attr_navigation_long_exact\n");
2833 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type); 5534 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type);
2834 return 1; 5535 return 1;
2835 } 5536 }
2836 return 0; 5537 return 0;
2837 case attr_navigation_speech: 5538 case attr_navigation_speech:
2838 this_->attr_next = attr_length; 5539 this_->attr_next = attr_length;
2839 if (cmd) 5540 if (cmd)
2840 { 5541 {
5542 //dbg(0, "attr_navigation_speech\n");
5543 //dbg(0, "Enter: attr_navigation_speech\n");
2841 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, this_->cmd, attr_type); 5544 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, this_->cmd, attr_type);
5545 //dbg(0, "back : attr_navigation_speech\n");
2842 return 1; 5546 return 1;
2843 } 5547 }
2844 return 0; 5548 return 0;
2845 case attr_length: 5549 case attr_length:
2846 this_->attr_next = attr_time; 5550 this_->attr_next = attr_time;
2856 { 5560 {
2857 attr->u.num = this_->cmd_itm->dest_time - cmd->itm->dest_time; 5561 attr->u.num = this_->cmd_itm->dest_time - cmd->itm->dest_time;
2858 return 1; 5562 return 1;
2859 } 5563 }
2860 return 0; 5564 return 0;
5565
2861 case attr_destination_length: 5566 case attr_destination_length:
2862 attr->u.num = itm->dest_length; 5567 attr->u.num = itm->dest_length;
2863 this_->attr_next = attr_destination_time; 5568 this_->attr_next = attr_destination_time;
2864 return 1; 5569 return 1;
5570
2865 case attr_destination_time: 5571 case attr_destination_time:
2866 attr->u.num = itm->dest_time; 5572 attr->u.num = itm->dest_time;
2867 this_->attr_next = attr_street_name; 5573 this_->attr_next = attr_street_name;
2868 return 1; 5574 return 1;
5575
2869 case attr_street_name: 5576 case attr_street_name:
2870 attr->u.str = itm->way.name1; 5577 attr->u.str = itm->way.name1;
2871 this_->attr_next = attr_street_name_systematic; 5578 this_->attr_next = attr_street_name_systematic;
2872 if (attr->u.str) 5579 if (attr->u.str)
2873 return 1; 5580 return 1;
2874 return 0; 5581 return 0;
5582
2875 case attr_street_name_systematic: 5583 case attr_street_name_systematic:
2876 attr->u.str = itm->way.name2; 5584 attr->u.str = itm->way.name2;
2877 this_->attr_next = attr_debug; 5585 this_->attr_next = attr_street_destination;
2878 if (attr->u.str) 5586 if (attr->u.str)
2879 return 1; 5587 return 1;
2880 return 0; 5588 return 0;
5589
5590 case attr_street_destination:
5591 attr->u.str = itm->way.street_dest_text;
5592 this_->attr_next = attr_debug;
5593 if (attr->u.str)
5594 {
5595 return 1;
5596 }
5597 return 0;
5598
2881 case attr_debug: 5599 case attr_debug:
2882 switch (this_->debug_idx) 5600 switch (this_->debug_idx)
2883 { 5601 {
2884 case 0: 5602 case 0:
2885 this_->debug_idx++; 5603 this_->debug_idx++;
2946 5664
2947 default: 5665 default:
2948 this_->attr_next = attr_none; 5666 this_->attr_next = attr_none;
2949 return 0; 5667 return 0;
2950 } 5668 }
5669
2951 case attr_any: 5670 case attr_any:
2952 while (this_->attr_next != attr_none) 5671 while (this_->attr_next != attr_none)
2953 { 5672 {
2954 if (navigation_map_item_attr_get(priv_data, this_->attr_next, attr)) 5673 if (navigation_map_item_attr_get(priv_data, this_->attr_next, attr))
2955 return 1; 5674 return 1;
2956 } 5675 }
2957 return 0; 5676 return 0;
5677
2958 default: 5678 default:
2959 attr->type = attr_none; 5679 attr->type = attr_none;
2960 return 0; 5680 return 0;
2961 } 5681 }
2962} 5682}
2978navigation_map_rect_new(struct map_priv *priv, struct map_selection *sel) 5698navigation_map_rect_new(struct map_priv *priv, struct map_selection *sel)
2979{ 5699{
2980 struct navigation *nav = priv->navigation; 5700 struct navigation *nav = priv->navigation;
2981 struct map_rect_priv *ret=g_new0(struct map_rect_priv, 1); 5701 struct map_rect_priv *ret=g_new0(struct map_rect_priv, 1);
2982 ret->nav = nav; 5702 ret->nav = nav;
5703
2983 navigation_map_rect_init(ret); 5704 navigation_map_rect_init(ret);
5705
2984 ret->item.meth = &navigation_map_item_methods; 5706 ret->item.meth = &navigation_map_item_methods;
2985 ret->item.priv_data = ret; 5707 ret->item.priv_data = ret;
5708
2986#ifdef DEBUG 5709#ifdef DEBUG
2987 ret->show_all=1; 5710 ret->show_all=1;
2988#endif 5711#endif
5712
2989 return ret; 5713 return ret;
2990} 5714}
2991 5715
2992static void navigation_map_rect_destroy(struct map_rect_priv *priv) 5716static void navigation_map_rect_destroy(struct map_rect_priv *priv)
2993{ 5717{
2997static struct item * 5721static struct item *
2998navigation_map_get_item(struct map_rect_priv *priv) 5722navigation_map_get_item(struct map_rect_priv *priv)
2999{ 5723{
3000 struct item *ret = &priv->item; 5724 struct item *ret = &priv->item;
3001 int delta; 5725 int delta;
5726
3002 if (!priv->itm_next) 5727 if (!priv->itm_next)
5728 {
3003 return NULL; 5729 return NULL;
5730 }
5731
3004 priv->itm = priv->itm_next; 5732 priv->itm = priv->itm_next;
3005 priv->cmd = priv->cmd_next; 5733 priv->cmd = priv->cmd_next;
3006 priv->cmd_itm = priv->cmd_itm_next; 5734 priv->cmd_itm = priv->cmd_itm_next;
5735
3007 if (!priv->cmd) 5736 if (!priv->cmd)
5737 {
3008 return NULL; 5738 return NULL;
5739 }
5740
3009 if (!priv->show_all && priv->itm->prev != NULL) 5741 if (!priv->show_all && priv->itm->prev != NULL)
5742 {
3010 priv->itm = priv->cmd->itm; 5743 priv->itm = priv->cmd->itm;
5744 }
5745
3011 priv->itm_next = priv->itm->next; 5746 priv->itm_next = priv->itm->next;
5747
3012 if (priv->itm->prev) 5748 if (priv->itm->prev)
5749 {
3013 ret->type = type_nav_none; 5750 ret->type = type_nav_none;
5751 }
3014 else 5752 else
5753 {
3015 ret->type = type_nav_position; 5754 ret->type = type_nav_position;
5755 }
5756
3016 if (priv->cmd->itm == priv->itm) 5757 if (priv->cmd->itm == priv->itm)
3017 { 5758 {
3018 priv->cmd_itm_next = priv->cmd->itm; 5759 priv->cmd_itm_next = priv->cmd->itm;
3019 priv->cmd_next = priv->cmd->next; 5760 priv->cmd_next = priv->cmd->next;
5761
3020 if (priv->cmd_itm_next && !priv->cmd_itm_next->next) 5762 if (priv->cmd_itm_next && !priv->cmd_itm_next->next)
5763 {
3021 ret->type = type_nav_destination; 5764 ret->type = type_nav_destination;
5765 }
3022 else 5766 else
3023 { 5767 {
3024 if (priv->itm && priv->itm->prev && !(priv->itm->way.flags & NAVIT_AF_ROUNDABOUT) && (priv->itm->prev->way.flags & NAVIT_AF_ROUNDABOUT)) 5768 if (priv->itm && priv->itm->prev && !(priv->itm->way.flags & NAVIT_AF_ROUNDABOUT) && (priv->itm->prev->way.flags & NAVIT_AF_ROUNDABOUT))
3025 { 5769 {
3026 enum item_type r = type_none, l = type_none; 5770 enum item_type r = type_none, l = type_none;
3058 case 8: 5802 case 8:
3059 r = type_nav_roundabout_r8; 5803 r = type_nav_roundabout_r8;
3060 l = type_nav_roundabout_l8; 5804 l = type_nav_roundabout_l8;
3061 break; 5805 break;
3062 } 5806 }
3063 dbg(1, "delta %d\n", priv->cmd->delta); 5807 // dbg(0, "delta %d\n", priv->cmd->delta);
5808
3064 if (priv->cmd->delta < 0) 5809 if (priv->cmd->delta < 0)
5810 {
3065 ret->type = l; 5811 ret->type = l;
5812 }
3066 else 5813 else
5814 {
3067 ret->type = r; 5815 ret->type = r;
5816 }
3068 } 5817 }
3069 else 5818 else
3070 { 5819 {
3071 delta = priv->cmd->delta; 5820 delta = priv->cmd->delta;
3072 if (delta < 0) 5821 if (delta < 0)
3079 else if (delta < 165) 5828 else if (delta < 165)
3080 ret->type = type_nav_left_3; 5829 ret->type = type_nav_left_3;
3081 else 5830 else
3082 ret->type = type_none; 5831 ret->type = type_none;
3083 } 5832 }
3084 else 5833 else if (delta > 0)
3085 { 5834 {
3086 if (delta < 45) 5835 if (delta < 45)
3087 ret->type = type_nav_right_1; 5836 ret->type = type_nav_right_1;
3088 else if (delta < 105) 5837 else if (delta < 105)
3089 ret->type = type_nav_right_2; 5838 ret->type = type_nav_right_2;
3090 else if (delta < 165) 5839 else if (delta < 165)
3091 ret->type = type_nav_right_3; 5840 ret->type = type_nav_right_3;
3092 else 5841 else
3093 ret->type = type_none; 5842 ret->type = type_none;
3094 } 5843 }
5844 else // delta == 0
5845 {
5846 ret->type = type_nav_straight;
3095 } 5847 }
3096 } 5848 }
3097 } 5849 }
5850 }
5851
3098 priv->ccount = 0; 5852 priv->ccount = 0;
3099 priv->debug_idx = 0; 5853 priv->debug_idx = 0;
3100 priv->attr_next = attr_navigation_short; 5854 priv->attr_next = attr_navigation_short;
3101 5855
3102 ret->id_lo = priv->itm->dest_count; 5856 ret->id_lo = priv->itm->dest_count;
3103 dbg(1, "type=%d\n", ret->type); 5857
3104 return ret; 5858 return ret;
3105} 5859}
3106 5860
3107static struct item * 5861static struct item *
3108navigation_map_get_item_byid(struct map_rect_priv *priv, int id_hi, int id_lo) 5862navigation_map_get_item_byid(struct map_rect_priv *priv, int id_hi, int id_lo)
3117 return NULL; 5871 return NULL;
3118} 5872}
3119 5873
3120static struct map_methods navigation_map_meth = { projection_mg, "utf-8", navigation_map_destroy, navigation_map_rect_new, navigation_map_rect_destroy, navigation_map_get_item, navigation_map_get_item_byid, NULL, NULL, NULL, }; 5874static struct map_methods navigation_map_meth = { projection_mg, "utf-8", navigation_map_destroy, navigation_map_rect_new, navigation_map_rect_destroy, navigation_map_get_item, navigation_map_get_item_byid, NULL, NULL, NULL, };
3121 5875
3122static struct map_priv * 5876struct map_priv *
3123navigation_map_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) 5877navigation_map_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl)
3124{ 5878{
3125 struct map_priv *ret; 5879 struct map_priv *ret;
3126 struct attr *navigation_attr; 5880 struct attr *navigation_attr;
3127 5881
3128 navigation_attr = attr_search(attrs, NULL, attr_navigation); 5882 navigation_attr = attr_search(attrs, NULL, attr_navigation);
5883
3129 if (!navigation_attr) 5884 if (!navigation_attr)
5885 {
3130 return NULL; 5886 return NULL;
5887 }
5888
3131 ret=g_new0(struct map_priv, 1); 5889 ret=g_new0(struct map_priv, 1);
3132 *meth = navigation_map_meth; 5890 *meth = navigation_map_meth;
3133 ret->navigation = navigation_attr->u.navigation; 5891 ret->navigation = navigation_attr->u.navigation;
3134 5892
5893 level_static_for_bicycle[0] = 18; // in meters
5894 level_static_for_bicycle[1] = 100; // in meters
5895 level_static_for_bicycle[2] = -1; // dont announce
5896
3135 return ret; 5897 return ret;
3136} 5898}
3137 5899
3138void navigation_set_route(struct navigation *this_, struct route *route) 5900void navigation_set_route(struct navigation *this_, struct route *route)
3139{ 5901{
5902__F_START__
5903
3140 struct attr callback; 5904 struct attr callback;
3141 this_->route = route; 5905 this_->route = route;
3142 this_->route_cb = callback_new_attr_1(callback_cast(navigation_update), attr_route_status, this_); 5906 this_->route_cb = callback_new_attr_1(callback_cast(navigation_update), attr_route_status, this_);
3143 callback_add_names(this_->route_cb, "navigation_set_route", "navigation_update"); 5907 callback_add_names(this_->route_cb, "navigation_set_route", "navigation_update");
3144 callback.type = attr_callback; 5908 callback.type = attr_callback;
3145 callback.u.callback = this_->route_cb; 5909 callback.u.callback = this_->route_cb;
3146 route_add_attr(route, &callback); 5910 route_add_attr(route, &callback);
5911
5912__F_END__
3147} 5913}
3148 5914
3149void navigation_init(void) 5915void navigation_init(void)
3150{ 5916{
5917#ifdef PLUGSSS
3151 plugin_register_map_type("navigation", navigation_map_new); 5918 plugin_register_map_type("navigation", navigation_map_new);
5919#endif
3152} 5920}
5921
5922

Legend:
Removed from v.34  
changed lines
  Added in v.40

   
Visit the ZANavi Wiki