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

Contents of /navit/navit/navigation.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 50 - (hide annotations) (download)
Wed Jun 22 07:33:35 2016 UTC (7 years, 9 months ago) by zoff99
File MIME type: text/plain
File size: 200917 byte(s)
v2.0.51
1 zoff99 2 /**
2 zoff99 27 * ZANavi, Zoff Android Navigation system.
3 zoff99 41 * Copyright (C) 2011-2015 Zoff <zoff@zoff.cc>
4 zoff99 27 *
5     * This program is free software; you can redistribute it and/or
6     * modify it under the terms of the GNU General Public License
7     * version 2 as published by the Free Software Foundation.
8     *
9     * This program is distributed in the hope that it will be useful,
10     * but WITHOUT ANY WARRANTY; without even the implied warranty of
11     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12     * GNU General Public License for more details.
13     *
14     * You should have received a copy of the GNU General Public License
15     * along with this program; if not, write to the
16     * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17     * Boston, MA 02110-1301, USA.
18     */
19    
20     /**
21 zoff99 2 * Navit, a modular navigation system.
22     * Copyright (C) 2005-2008 Navit Team
23     *
24     * This program is free software; you can redistribute it and/or
25     * modify it under the terms of the GNU General Public License
26     * version 2 as published by the Free Software Foundation.
27     *
28     * This program is distributed in the hope that it will be useful,
29     * but WITHOUT ANY WARRANTY; without even the implied warranty of
30     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31     * GNU General Public License for more details.
32     *
33     * You should have received a copy of the GNU General Public License
34     * along with this program; if not, write to the
35     * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
36     * Boston, MA 02110-1301, USA.
37     */
38    
39     #include <stdio.h>
40     #include <stdlib.h>
41     #include <string.h>
42     #include <math.h>
43     #include <ctype.h>
44     #include <glib.h>
45     #include "debug.h"
46     #include "profile.h"
47     #include "navigation.h"
48     #include "coord.h"
49 zoff99 48
50 zoff99 2 #include "route.h"
51     #include "transform.h"
52     #include "mapset.h"
53     #include "projection.h"
54     #include "map.h"
55     #include "navit.h"
56     #include "callback.h"
57     #include "speech.h"
58     #include "vehicleprofile.h"
59     #include "plugin.h"
60     #include "navit_nls.h"
61    
62     /* #define DEBUG */
63    
64 zoff99 40
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    
96 zoff99 27 static int roundabout_extra_length = 50;
97 zoff99 2
98 zoff99 27 struct suffix
99     {
100 zoff99 2 char *fullname;
101     char *abbrev;
102     int sex;
103 zoff99 30 } suffixes[] = { { "weg", NULL, 1 }, { "platz", "pl.", 1 }, { "ring", NULL, 1 }, { "allee", NULL, 2 }, { "gasse", NULL, 2 }, { "straße", "str.", 2 }, { "strasse", NULL, 2 }, };
104 zoff99 2
105    
106 zoff99 30 int distances[] = { 1, 2, 3, 4, 5, 10, 25, 50, 75, 100, 150, 200, 250, 300, 400, 500, 750, -1 };
107 zoff99 2
108 zoff99 40
109    
110    
111    
112    
113     // -- NEW 002 --
114     /* Allowed values for navigation_maneuver.merge_or_exit
115     * The numeric values are chosen in such a way that they can be interpreted as flags:
116     * 1=merge, 2=exit, 4=interchange, 8=right, 16=left
117     * Identifiers were chosen over flags to enforce certain rules
118     * (merge/exit/interchange and left/right are mutually exclusive, left/right requires merge or exit). */
119     //FIXME: should we make this an enum?
120    
121     /** Not merging into or exiting from a motorway_like road */
122     #define mex_none 0
123    
124     /** Merging into a motorway-like road, direction undefined */
125     //FIXME: do we need this constant?
126     #define mex_merge 1
127    
128     /** Exiting from a motorway-like road, direction undefined.
129     * This should only be used for ramps leading to a non-motorway road.
130     * For interchanges, use {@code mex_interchange} instead. */
131     //FIXME: do we need this constant?
132     #define mex_exit 2
133    
134     /** Motorway-like road splits in two.
135     * This should be used for all cases in which ramps lead to another motorway-like road. */
136     #define mex_interchange 4
137    
138     /** Merging into a motorway-like road to the right (coming from the left) */
139     #define mex_merge_right 9
140    
141     /** Exiting from a motorway-like road to the right.
142     * See {@code mex_exit} for usage. */
143     #define mex_exit_right 10
144    
145     /** Merging into a motorway-like road to the left (coming from the right) */
146     #define mex_merge_left 17
147    
148     /** Exiting from a motorway-like road to the left.
149     * See {@code mex_exit} for usage. */
150     #define mex_exit_left 18
151    
152     /**
153     * @brief Holds information about a navigation maneuver.
154     *
155     * This structure is populated when a navigation maneuver is first analyzed. Its members contain all information
156     * needed to decide whether or not to announce the maneuver, what type of maneuver it is and the information that
157     * was used to determine the former two.
158     */
159     struct navigation_maneuver {
160     enum item_type type; /**< The type of maneuver to perform. Any {@code nav_*} item is permitted here, with one exception:
161     merge or exit maneuvers are indicated by the {@code merge_or_exit} member. The {@code item_type}
162     for such maneuvers should be a turn instruction in cases where the maneuver is ambiguous, or
163     {@code nav_none} for cases in which we would expect the driver to perform this maneuver even
164     without being instructed to do so. **/
165     int delta; /**< Bearing difference (the angle the driver has to steer) for the maneuver */
166     int merge_or_exit; /**< Whether we are merging into or exiting from a motorway_like road or we are at an interchange */
167     int is_complex_t_junction; /**< Whether we are coming from the "stem" of a T junction whose "bar" is a dual-carriageway road and
168     crossing the opposite lane of the "bar" first (i.e. turning left in countries that drive on the
169     right, or turning right in countries that drive on the left). For these maneuvers
170     {@code num_options} is 1 (which means we normally wouldn't announce the maneuver) but drivers
171     would expect an announcement in such cases. */
172     int num_options; /**< Number of permitted candidate ways, i.e. ways which we may enter (based on access flags of the
173     way but without considering turn restrictions). Permitted candidate ways include the route. */
174     int num_new_motorways; /**< Number of permitted candidate ways that are motorway-like */
175     int num_other_ways; /**< Number of permitted candidate ways that are neither ramps nor motorway-like */
176     int old_cat; /**< Maneuver category of the way leading to the maneuver */
177     int new_cat; /**< Maneuver category of the selected way after the maneuver */
178     int max_cat; /**< Highest maneuver category of any permitted candidate way other than the route */
179     int num_similar_ways; /**< Number of candidate ways (including the route) that have a {@code maneuver_category()} similar
180     to {@code old_cat}. See {@code maneuver_required2()} for definition of "similar". */
181     int left; /**< Minimum bearing delta of any candidate way left of the route, -180 for none */
182     int right; /**< Minimum bearing delta of any candidate way right of the route, 180 for none */
183     int is_unambiguous; /**< Whether the maneuver is unambiguous. A maneuver is unambiguous if, despite
184     multiple candidate way being available, we can reasonable expect the driver to
185     continue on the route without being told to do so. This is typically the case when
186     the route stays on the main road and goes straight, while all other candidate ways
187     are minor roads and involve a significant turn. */
188     int is_same_street; /**< Whether the street keeps its name after the maneuver. */
189     };
190     // -- NEW 002 --
191    
192    
193    
194    
195    
196 zoff99 27 struct navigation_command
197     {
198 zoff99 2 struct navigation_itm *itm;
199     struct navigation_command *next;
200     struct navigation_command *prev;
201     int delta;
202 zoff99 41 int delta_real;
203 zoff99 2 int roundabout_delta;
204     int length;
205 zoff99 40 // -- NEW 002 --
206     struct navigation_maneuver *maneuver; /**< Details on the maneuver to perform */
207     // -- NEW 002 --
208 zoff99 2 };
209    
210 zoff99 40
211    
212    
213    
214    
215    
216     // -- NEW 002 --
217     /*@brief A linked list conataining the destination of the road
218     *
219     *
220     * Holds the destination info from the road, that is the place
221     * you drive to if you keep following the road as found on
222     * traffic sign's (ex. Paris, Senlis ...)
223     *
224     *
225     */
226     struct street_destination
227     {
228     struct street_destination *next;
229     char *destination;
230     };
231     // -- NEW 002 --
232    
233    
234    
235    
236    
237 zoff99 2 static void navigation_flush(struct navigation *this_);
238    
239     /**
240     * @brief Calculates the delta between two angles
241     * @param angle1 The first angle
242     * @param angle2 The second angle
243     * @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
244 zoff99 27 */
245 zoff99 2
246 zoff99 27 static int angle_delta(int angle1, int angle2)
247 zoff99 2 {
248 zoff99 27 int delta = angle2 - angle1;
249 zoff99 40
250 zoff99 2 if (delta <= -180)
251 zoff99 27 delta += 360;
252 zoff99 40
253 zoff99 2 if (delta > 180)
254 zoff99 27 delta -= 360;
255 zoff99 40
256 zoff99 2 return delta;
257     }
258    
259 zoff99 27 static int angle_median(int angle1, int angle2)
260 zoff99 2 {
261 zoff99 27 int delta = angle_delta(angle1, angle2);
262     int ret = angle1 + delta / 2;
263 zoff99 40
264 zoff99 2 if (ret < 0)
265 zoff99 27 ret += 360;
266 zoff99 40
267 zoff99 2 if (ret > 360)
268 zoff99 27 ret -= 360;
269 zoff99 40
270 zoff99 2 return ret;
271     }
272    
273 zoff99 27 static int angle_opposite(int angle)
274 zoff99 2 {
275 zoff99 27 return ((angle + 180) % 360);
276 zoff99 2 }
277    
278 zoff99 30 int navigation_get_attr(struct navigation *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
279 zoff99 2 {
280     struct map_rect *mr;
281     struct item *item;
282 zoff99 40 // dbg(1, "enter %s\n", attr_to_name(type));
283 zoff99 27 switch (type)
284     {
285     case attr_map:
286     attr->u.map = this_->map;
287     break;
288     case attr_item_type:
289     case attr_length:
290     case attr_navigation_speech:
291     mr = map_rect_new(this_->map, NULL);
292     while ((item = map_rect_get_item(mr)))
293     {
294 zoff99 30 if (item->type != type_nav_none && item->type != type_nav_position)
295 zoff99 27 {
296     if (type == attr_item_type)
297     attr->u.item_type = item->type;
298     else
299     {
300     if (!item_attr_get(item, type, attr))
301     item = NULL;
302     }
303     break;
304 zoff99 2 }
305     }
306 zoff99 27 map_rect_destroy(mr);
307     if (!item)
308     return 0;
309     break;
310     default:
311 zoff99 2 return 0;
312     }
313 zoff99 27 attr->type = type;
314 zoff99 2 return 1;
315     }
316    
317 zoff99 27 int navigation_set_attr(struct navigation *this_, struct attr *attr)
318 zoff99 2 {
319 zoff99 27 switch (attr->type)
320     {
321     case attr_speech:
322     this_->speech = attr->u.speech;
323     return 1;
324     default:
325     return 0;
326 zoff99 2 }
327     }
328    
329     struct navigation *
330     navigation_new(struct attr *parent, struct attr **attrs)
331     {
332 zoff99 27 int i, j;
333 zoff99 2 struct attr * attr;
334     struct navigation *ret=g_new0(struct navigation, 1);
335 zoff99 27 ret->hash = item_hash_new();
336 zoff99 40 ret->callback = callback_list_new("navigation_new:ret->callback");
337     ret->callback_speech = callback_list_new("navigation_new:ret->callback_speech");
338 zoff99 27 ret->level_last = -2;
339     ret->distance_turn = 50;
340 zoff99 41 ret->turn_around_limit = 2; // at first occurence of "turn around" -> say so!
341 zoff99 27 ret->navit = parent->u.navit;
342     ret->tell_street_name = 1;
343 zoff99 40 ret->previous = NULL;
344     ret->cmd_previous = NULL;
345 zoff99 2
346 zoff99 27 for (j = 0; j <= route_item_last - route_item_first; j++)
347     {
348     for (i = 0; i < 3; i++)
349     {
350     ret->announce[j][i] = -1;
351 zoff99 2 }
352     }
353    
354 zoff99 27 if ((attr = attr_search(attrs, NULL, attr_tell_street_name)))
355     {
356 zoff99 2 ret->tell_street_name = attr->u.num;
357     }
358 zoff99 27 if ((attr = attr_search(attrs, NULL, attr_delay)))
359     {
360 zoff99 2 ret->delay = attr->u.num;
361     }
362    
363 zoff99 27 return ret;
364 zoff99 2 }
365    
366 zoff99 30 int navigation_set_announce(struct navigation *this_, enum item_type type, int *level)
367 zoff99 2 {
368     int i;
369 zoff99 27 if (type < route_item_first || type > route_item_last)
370     {
371 zoff99 30 dbg(0, "street type %d out of range [%d,%d]", type, route_item_first, route_item_last);
372 zoff99 2 return 0;
373     }
374 zoff99 40
375 zoff99 27 for (i = 0; i < 3; i++)
376 zoff99 40 {
377     // dbg(0, "announce=%d type=%s\n", level[i], item_to_name(type));
378 zoff99 27 this_->announce[type - route_item_first][i] = level[i];
379 zoff99 40 }
380    
381 zoff99 2 return 1;
382     }
383    
384 zoff99 40 // global var ------------
385     static int level_static_for_bicycle[3];
386     // global var ------------
387    
388    
389    
390     // ------------------------------------
391     // returns: "0", "1", "2" or "3"
392     // ------------------------------------
393 zoff99 41 static int navigation_get_announce_level(struct navigation *this_, enum item_type type, int dist, float speed_in_ms)
394 zoff99 2 {
395 zoff99 41 int i = 3;
396 zoff99 2
397     if (type < route_item_first || type > route_item_last)
398 zoff99 40 {
399 zoff99 2 return -1;
400 zoff99 40 }
401    
402     if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
403 zoff99 27 {
404 zoff99 41 #if 0
405 zoff99 40 for (i = 0; i < 3; i++)
406     {
407     // 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);
408     if (dist <= level_static_for_bicycle[i])
409     {
410     //dbg(0, "ret(1a)=%d\n", i);
411     return i;
412     }
413 zoff99 41 }
414     #endif
415    
416     for (i = 0; i < 3; i++)
417     {
418     if (speed_in_ms > 19.444f) // > 70 km/h
419     {
420    
421     if (i == 0)
422     {
423     if (dist <= (int)(global_b_level0_announcement * global_b_levelx_announcement_factor * speed_in_ms) )
424     {
425     return i;
426     }
427     }
428     else if (i == 1)
429     {
430     if (dist <= (int)(global_b_level1_announcement * global_b_levelx_announcement_factor * speed_in_ms) )
431     {
432     return i;
433     }
434     }
435     else
436     {
437     if (dist <= (int)(global_b_level2_announcement * global_b_levelx_announcement_factor * speed_in_ms) )
438     {
439     return i;
440     }
441     }
442     }
443     else if (speed_in_ms > 0.9f)
444     {
445     if (i == 0)
446     {
447     // always have at least 12 meters to turn for level 0 announcement
448     if (dist <= 12)
449     {
450     return i;
451     }
452    
453     if (dist <= (int)(global_b_level0_announcement * speed_in_ms) )
454     {
455     dbg(0, "NCC_:0:%d %f\n", (int)(global_b_level0_announcement * speed_in_ms), speed_in_ms);
456     return i;
457     }
458     }
459     else if (i == 1)
460     {
461     if (dist <= (int)(global_b_level1_announcement * speed_in_ms) )
462     {
463     dbg(0, "NCC_:1:%d %f\n", (int)(global_b_level1_announcement * speed_in_ms), speed_in_ms);
464     return i;
465     }
466     }
467     else
468     {
469     if (dist <= (int)(global_b_level2_announcement * speed_in_ms) )
470     {
471     dbg(0, "NCC_:2:%d %f\n", (int)(global_b_level2_announcement * speed_in_ms), speed_in_ms);
472     return i;
473     }
474     }
475     }
476     else
477     {
478     if (dist <= level_static_for_bicycle[i])
479     {
480     //dbg(0, "ret(1a)=%d\n", i);
481     return i;
482     }
483     }
484    
485     }
486    
487 zoff99 2 }
488 zoff99 40 else
489     {
490 zoff99 41
491 zoff99 40 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 zoff99 41
495    
496     if (speed_in_ms > 19.444f) // > 70 km/h
497 zoff99 40 {
498 zoff99 41 if (i == 0)
499     {
500     if (dist <= (int)(global_level0_announcement * global_levelx_announcement_factor * speed_in_ms) )
501     {
502     return i;
503     }
504     }
505     else if (i == 1)
506     {
507     if (dist <= (int)(global_level1_announcement * global_levelx_announcement_factor * speed_in_ms) )
508     {
509     return i;
510     }
511     }
512     else
513     {
514     if (dist <= (int)(global_level2_announcement * global_levelx_announcement_factor * speed_in_ms) )
515     {
516     return i;
517     }
518     }
519 zoff99 40 }
520 zoff99 41 else if (speed_in_ms > 0.9f)
521     {
522     if (i == 0)
523     {
524     // always have at least 12 meters to turn for level 0 announcement
525     if (dist <= 12)
526     {
527     return i;
528     }
529    
530     if (dist <= (int)(global_level0_announcement * speed_in_ms) )
531     {
532     dbg(0, "NCC_:0:%d %f\n", (int)(global_level0_announcement * speed_in_ms), speed_in_ms);
533     return i;
534     }
535     }
536     else if (i == 1)
537     {
538     if (dist <= (int)(global_level1_announcement * speed_in_ms) )
539     {
540     dbg(0, "NCC_:1:%d %f\n", (int)(global_level1_announcement * speed_in_ms), speed_in_ms);
541     return i;
542     }
543     }
544     else
545     {
546     if (dist <= (int)(global_level2_announcement * speed_in_ms) )
547     {
548     dbg(0, "NCC_:2:%d %f\n", (int)(global_level2_announcement * speed_in_ms), speed_in_ms);
549     return i;
550     }
551     }
552     }
553     else
554     {
555     if (dist <= this_->announce[type - route_item_first][i])
556     {
557     //dbg(0, "ret(1b)=%d\n", i);
558     return i;
559     }
560     }
561 zoff99 40 }
562     }
563 zoff99 41
564    
565 zoff99 40 //dbg(0, "ret(2)=%d\n", i);
566 zoff99 41
567 zoff99 2 return i;
568     }
569    
570    
571 zoff99 41 static int navigation_get_announce_dist_for_level_on_item_bicycle(struct navigation *this_, enum item_type type, int level, float speed_in_ms)
572     {
573    
574     if (speed_in_ms > 19.444f) // > 70 km/h
575     {
576     if (level == 0)
577     {
578     return (int)(global_b_level0_announcement * global_b_levelx_announcement_factor * speed_in_ms);
579     }
580     else if (level == 1)
581     {
582     return (int)(global_b_level1_announcement * global_b_levelx_announcement_factor * speed_in_ms);
583     }
584     else
585     {
586     return (int)(global_b_level2_announcement * global_b_levelx_announcement_factor * speed_in_ms);
587     }
588     }
589     else if (speed_in_ms > 0.9f)
590     {
591     if (level == 0)
592     {
593     // always have at least 12 meters to turn for level 0 announcement
594     if ( (int)(global_b_level0_announcement * speed_in_ms) < 12)
595     {
596     return 12;
597     }
598     else
599     {
600     return (int)(global_b_level0_announcement * speed_in_ms);
601     }
602     }
603     else if (level == 1)
604     {
605     return (int)(global_b_level1_announcement * speed_in_ms);
606     }
607     else
608     {
609     return (int)(global_b_level2_announcement * speed_in_ms);
610     }
611     }
612     else
613     {
614     return level_static_for_bicycle[level];
615     }
616     }
617    
618    
619     static int navigation_get_announce_dist_for_level_on_item(struct navigation *this_, enum item_type type, int level, float speed_in_ms)
620     {
621    
622     if (speed_in_ms > 19.444f) // > 70 km/h
623     {
624     if (level == 0)
625     {
626     return (int)(global_level0_announcement * global_levelx_announcement_factor * speed_in_ms);
627     }
628     else if (level == 1)
629     {
630     return (int)(global_level1_announcement * global_levelx_announcement_factor * speed_in_ms);
631     }
632     else
633     {
634     return (int)(global_level2_announcement * global_levelx_announcement_factor * speed_in_ms);
635     }
636     }
637     else if (speed_in_ms > 0.9f)
638     {
639     if (level == 0)
640     {
641     // always have at least 12 meters to turn for level 0 announcement
642     if ( (int)(global_level0_announcement * speed_in_ms) < 12)
643     {
644     return 12;
645     }
646     else
647     {
648     return (int)(global_level0_announcement * speed_in_ms);
649     }
650     }
651     else if (level == 1)
652     {
653     return (int)(global_level1_announcement * speed_in_ms);
654     }
655     else
656     {
657     return (int)(global_level2_announcement * speed_in_ms);
658     }
659     }
660     else
661     {
662     return this_->announce[type - route_item_first][level];
663     }
664     }
665    
666 zoff99 30 static int is_way_allowed(struct navigation *nav, struct navigation_way *way, int mode);
667 zoff99 2
668 zoff99 41 static int navigation_get_announce_level_cmd(struct navigation *this_, struct navigation_itm *itm, struct navigation_command *cmd, int distance, float speed_in_ms)
669 zoff99 2 {
670 zoff99 40
671 zoff99 41 int level2, level = navigation_get_announce_level(this_, itm->way.item.type, distance, speed_in_ms);
672    
673 zoff99 27 if (this_->cmd_first->itm->prev)
674     {
675 zoff99 41 level2 = navigation_get_announce_level(this_, cmd->itm->prev->way.item.type, distance, speed_in_ms);
676 zoff99 2 if (level2 > level)
677 zoff99 40 {
678 zoff99 27 level = level2;
679 zoff99 40 }
680 zoff99 2 }
681 zoff99 40
682 zoff99 2 return level;
683     }
684    
685     /* 0=N,90=E */
686 zoff99 41 static int road_angle_accurate(struct coord *c1, struct coord *c2, int dir)
687     {
688     // COST: 006 acc
689     // dbg(0, "COST:006acc\n");
690    
691     int ret = transform_get_angle_delta_accurate(c1, c2, dir);
692     return ret;
693     }
694    
695    
696 zoff99 27 static int road_angle(struct coord *c1, struct coord *c2, int dir)
697 zoff99 2 {
698 zoff99 40 // COST: 006
699 zoff99 41 // dbg(0, "COST:006\n");
700 zoff99 40
701 zoff99 27 int ret = transform_get_angle_delta(c1, c2, dir);
702     // dbg(1, "road_angle(0x%x,0x%x - 0x%x,0x%x)=%d\n", c1->x, c1->y, c2->x, c2->y, ret);
703 zoff99 2 return ret;
704     }
705    
706 zoff99 27 static char *get_count_str(int n)
707 zoff99 2 {
708 zoff99 27 switch (n)
709     {
710     case 0:
711     #ifdef HAVE_API_ANDROID
712 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
713 zoff99 46 android_send_generic_text(1,"+*#O:first\n");
714 zoff99 27 #endif
715 zoff99 28 #endif
716 zoff99 46 // TRANSLATORS: the following counts refer to streets (example: turn right after the first street)
717     return _("first"); // Not sure if this exists, neither if it will ever be needed
718 zoff99 27 case 1:
719     #ifdef HAVE_API_ANDROID
720 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
721 zoff99 27 android_send_generic_text(1,"+*#O:first\n");
722     #endif
723 zoff99 28 #endif
724 zoff99 27 // TRANSLATORS: the following counts refer to streets (example: turn right after the first street)
725     return _("first");
726     case 2:
727     #ifdef HAVE_API_ANDROID
728 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
729 zoff99 27 android_send_generic_text(1,"+*#O:second\n");
730     #endif
731 zoff99 28 #endif
732 zoff99 27 // TRANSLATORS: the following counts refer to streets (example: turn right after the second street)
733     return _("second");
734     case 3:
735     #ifdef HAVE_API_ANDROID
736 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
737 zoff99 27 android_send_generic_text(1,"+*#O:third\n");
738     #endif
739 zoff99 28 #endif
740 zoff99 27 // TRANSLATORS: the following counts refer to streets (example: turn right after the third street)
741     return _("third");
742     case 4:
743     #ifdef HAVE_API_ANDROID
744 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
745 zoff99 27 android_send_generic_text(1,"+*#O:fourth\n");
746     #endif
747 zoff99 28 #endif
748 zoff99 27 // TRANSLATORS: the following counts refer to streets (example: turn right after the fourth street)
749     return _("fourth");
750     case 5:
751     #ifdef HAVE_API_ANDROID
752 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
753 zoff99 27 android_send_generic_text(1,"+*#O:fifth\n");
754     #endif
755 zoff99 28 #endif
756 zoff99 27 // TRANSLATORS: the following counts refer to streets (example: turn right after the fifth street)
757     return _("fifth");
758     case 6:
759     #ifdef HAVE_API_ANDROID
760 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
761 zoff99 27 android_send_generic_text(1,"+*#O:sixth\n");
762     #endif
763 zoff99 28 #endif
764 zoff99 27 // TRANSLATORS: the following counts refer to streets (example: turn right after the sixth street)
765     return _("sixth");
766     case 7:
767     #ifdef HAVE_API_ANDROID
768 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
769 zoff99 27 android_send_generic_text(1,"+*#O:seventh\n");
770     #endif
771 zoff99 28 #endif
772 zoff99 27 // TRANSLATORS: the following counts refer to streets (example: turn right after the seventh street)
773     return _("seventh");
774     case 8:
775     #ifdef HAVE_API_ANDROID
776 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
777 zoff99 27 android_send_generic_text(1,"+*#O:eighth\n");
778     #endif
779 zoff99 28 #endif
780 zoff99 27 // TRANSLATORS: the following counts refer to streets (example: turn right after the eighth street)
781     return _("eighth");
782     case 9:
783     #ifdef HAVE_API_ANDROID
784 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
785 zoff99 27 android_send_generic_text(1,"+*#O:ninth\n");
786     #endif
787 zoff99 28 #endif
788 zoff99 27 // TRANSLATORS: the following counts refer to streets (example: turn right after the ninth street)
789     return _("ninth");
790     default:
791     return NULL;
792 zoff99 2 }
793     }
794    
795 zoff99 27 static char *get_exit_count_str(int n)
796 zoff99 2 {
797 zoff99 27 switch (n)
798     {
799     case 0:
800     #ifdef HAVE_API_ANDROID
801 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
802 zoff99 46 android_send_generic_text(1,"+*#O:first exit\n");
803 zoff99 27 #endif
804 zoff99 28 #endif
805 zoff99 46 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the first exit)
806     return _("first exit"); // Not sure if this exists, neither if it will ever be needed
807 zoff99 27 case 1:
808     #ifdef HAVE_API_ANDROID
809 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
810 zoff99 27 android_send_generic_text(1,"+*#O:first exit\n");
811     #endif
812 zoff99 28 #endif
813 zoff99 27 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the first exit)
814     return _("first exit");
815     case 2:
816     #ifdef HAVE_API_ANDROID
817 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
818 zoff99 27 android_send_generic_text(1,"+*#O:second exit\n");
819     #endif
820 zoff99 28 #endif
821 zoff99 27 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the second exit)
822     return _("second exit");
823     case 3:
824     #ifdef HAVE_API_ANDROID
825 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
826 zoff99 27 android_send_generic_text(1,"+*#O:third exit\n");
827     #endif
828 zoff99 28 #endif
829 zoff99 27 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the third exit)
830     return _("third exit");
831     case 4:
832     #ifdef HAVE_API_ANDROID
833 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
834 zoff99 27 android_send_generic_text(1,"+*#O:fourth exit\n");
835     #endif
836 zoff99 28 #endif
837 zoff99 27 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the fourth exit)
838     return _("fourth exit");
839     case 5:
840     #ifdef HAVE_API_ANDROID
841 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
842 zoff99 27 android_send_generic_text(1,"+*#O:fifth exit\n");
843     #endif
844 zoff99 28 #endif
845 zoff99 27 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the fifth exit)
846     return _("fifth exit");
847     case 6:
848     #ifdef HAVE_API_ANDROID
849 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
850 zoff99 27 android_send_generic_text(1,"+*#O:sixth exit\n");
851     #endif
852 zoff99 28 #endif
853 zoff99 27 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the sixth exit)
854     return _("sixth exit");
855     case 7:
856     #ifdef HAVE_API_ANDROID
857 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
858 zoff99 27 android_send_generic_text(1,"+*#O:seventh exit\n");
859     #endif
860 zoff99 28 #endif
861 zoff99 27 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the seventh exit)
862     return _("seventh exit");
863     case 8:
864     #ifdef HAVE_API_ANDROID
865 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
866 zoff99 27 android_send_generic_text(1,"+*#O:eighth exit\n");
867     #endif
868 zoff99 28 #endif
869 zoff99 27 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the eighth exit)
870     return _("eighth exit");
871     case 9:
872     #ifdef HAVE_API_ANDROID
873 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
874 zoff99 27 android_send_generic_text(1,"+*#O:ninth exit\n");
875     #endif
876 zoff99 28 #endif
877 zoff99 27 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the ninth exit)
878     return _("ninth exit");
879     default:
880     return NULL;
881 zoff99 2 }
882     }
883 zoff99 40
884 zoff99 27 static int round_distance(int dist)
885 zoff99 2 {
886 zoff99 27 if (dist < 100)
887     {
888     dist = (dist + 5) / 10;
889     return dist * 10;
890 zoff99 2 }
891 zoff99 27 if (dist < 250)
892     {
893     dist = (dist + 13) / 25;
894     return dist * 25;
895 zoff99 2 }
896 zoff99 27 if (dist < 500)
897     {
898     dist = (dist + 25) / 50;
899     return dist * 50;
900 zoff99 2 }
901 zoff99 27 if (dist < 1000)
902     {
903     dist = (dist + 50) / 100;
904     return dist * 100;
905 zoff99 2 }
906 zoff99 27 if (dist < 5000)
907     {
908     dist = (dist + 50) / 100;
909     return dist * 100;
910 zoff99 2 }
911 zoff99 27 if (dist < 100000)
912     {
913     dist = (dist + 500) / 1000;
914     return dist * 1000;
915 zoff99 2 }
916 zoff99 27 dist = (dist + 5000) / 10000;
917     return dist * 10000;
918 zoff99 2 }
919    
920 zoff99 27 static int round_for_vocabulary(int vocabulary, int dist, int factor)
921 zoff99 2 {
922 zoff99 40
923     //dbg(0, "DIST_FEET:rfv:001:d=%d f=%d\n", dist, factor);
924    
925     //if (!(vocabulary & 256))
926     //{
927 zoff99 27 if (factor != 1)
928 zoff99 40 {
929 zoff99 27 dist = (dist + factor / 2) / factor;
930 zoff99 40 //dbg(0, "DIST_FEET:rfv:002:d=%d\n", dist);
931     }
932     //}
933     //else
934     //{
935     // factor = 1;
936     //}
937    
938 zoff99 27 if (!(vocabulary & 255))
939     {
940     int i = 0, d = 0, m = 0;
941     while (distances[i] > 0)
942     {
943     if (!i || abs(distances[i] - dist) <= d)
944     {
945     d = abs(distances[i] - dist);
946 zoff99 40 //dbg(0, "DIST_FEET:rfv:003:d=%d\n", dist);
947 zoff99 27 m = i;
948 zoff99 2 }
949 zoff99 40
950 zoff99 2 if (distances[i] > dist)
951 zoff99 40 {
952 zoff99 2 break;
953 zoff99 40 }
954 zoff99 2 i++;
955     }
956 zoff99 27 // dbg(0, "converted %d to %d with factor %d\n", dist, distances[m], factor);
957     dist = distances[m];
958 zoff99 2 }
959 zoff99 40
960     //dbg(0, "DIST_FEET:rfv:002:d=%d f=%d res=%d\n", dist, factor, dist * factor);
961    
962 zoff99 27 return dist * factor;
963 zoff99 2 }
964    
965 zoff99 27 static int vocabulary_last(int vocabulary)
966 zoff99 2 {
967 zoff99 27 int i = 0;
968 zoff99 40
969 zoff99 2 if (vocabulary == 65535)
970 zoff99 40 {
971 zoff99 2 return 1000;
972 zoff99 40 }
973    
974 zoff99 27 while (distances[i] > 0)
975 zoff99 40 {
976 zoff99 2 i++;
977 zoff99 40 }
978    
979 zoff99 27 return distances[i - 1];
980 zoff99 2 }
981    
982 zoff99 41 char *
983 zoff99 30 get_distance(struct navigation *nav, int dist, enum attr_type type, int is_length)
984 zoff99 2 {
985 zoff99 40 int imperial = 0;
986     int vocabulary = 65535;
987 zoff99 2 struct attr attr;
988 zoff99 27
989     if (type == attr_navigation_long)
990     {
991 zoff99 2 if (is_length)
992 zoff99 27 {
993     #ifdef HAVE_API_ANDROID
994 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
995 zoff99 27 android_send_generic_text(1,"+*#O:%d m\n");
996     #endif
997 zoff99 28 #endif
998 zoff99 2 return g_strdup_printf(_("%d m"), dist);
999 zoff99 27 }
1000 zoff99 2 else
1001 zoff99 27 {
1002     #ifdef HAVE_API_ANDROID
1003 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
1004 zoff99 27 android_send_generic_text(1,"+*#O:in %d m\n");
1005     #endif
1006 zoff99 28 #endif
1007 zoff99 2 return g_strdup_printf(_("in %d m"), dist);
1008 zoff99 27 }
1009 zoff99 2 }
1010 zoff99 40
1011 zoff99 2 if (navit_get_attr(nav->navit, attr_imperial, &attr, NULL))
1012 zoff99 40 {
1013 zoff99 27 imperial = attr.u.num;
1014 zoff99 40 }
1015    
1016 zoff99 30 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_distances, &attr, NULL))
1017 zoff99 40 {
1018 zoff99 27 vocabulary = attr.u.num;
1019 zoff99 40 }
1020    
1021 zoff99 27 if (imperial)
1022     {
1023 zoff99 40 //dbg(0, "DIST_FEET:001:d=%d\n", dist);
1024    
1025     // if (dist * FEET_PER_METER < vocabulary_last(vocabulary))
1026     if (dist * FEET_PER_METER < 5300) // fix for "0"-miles later!!
1027 zoff99 27 {
1028 zoff99 40 if (( dist * FEET_PER_METER ) > 1900)
1029     {
1030     //dbg(0, "DIST_FEET:002a:d=%d m=%d\n", dist, (int)(dist * FEET_PER_METER));
1031     dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER, 500);
1032     }
1033     else if (( dist * FEET_PER_METER ) > 290)
1034     {
1035     //dbg(0, "DIST_FEET:002a:d=%d m=%d\n", dist, (int)(dist * FEET_PER_METER));
1036     dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER, 100);
1037     }
1038     else if (( dist * FEET_PER_METER ) > 25)
1039     {
1040     //dbg(0, "DIST_FEET:002a:d=%d m=%d\n", dist, (int)(dist * FEET_PER_METER));
1041     dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER, 20);
1042     }
1043     else
1044     {
1045     //dbg(0, "DIST_FEET:002b:d=%d m=%d\n", dist, dist * FEET_PER_METER);
1046     dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER, 1);
1047     }
1048    
1049     //dbg(0, "DIST_FEET:002:d=%d v=%d\n", dist, vocabulary);
1050    
1051 zoff99 2 if (is_length)
1052 zoff99 27 {
1053     #ifdef HAVE_API_ANDROID
1054 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
1055 zoff99 27 android_send_generic_text(1,"+*#O:%d feet\n");
1056     #endif
1057 zoff99 28 #endif
1058 zoff99 2 return g_strdup_printf(_("%d feet"), dist);
1059 zoff99 27 }
1060 zoff99 2 else
1061 zoff99 27 {
1062     #ifdef HAVE_API_ANDROID
1063 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
1064 zoff99 27 android_send_generic_text(1,"+*#O:in %d feet\n");
1065     #endif
1066 zoff99 28 #endif
1067 zoff99 2 return g_strdup_printf(_("in %d feet"), dist);
1068 zoff99 27 }
1069 zoff99 2 }
1070 zoff99 27 }
1071     else
1072     {
1073     if (dist < vocabulary_last(vocabulary))
1074     {
1075     dist = round_for_vocabulary(vocabulary, dist, 1);
1076 zoff99 2 if (is_length)
1077 zoff99 27 {
1078     #ifdef HAVE_API_ANDROID
1079 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
1080 zoff99 27 android_send_generic_text(1,"+*#O:%d meters\n");
1081     gchar* xy=g_strdup_printf("+*#1:%d\n", dist);
1082     android_send_generic_text(1,xy);
1083     g_free(xy);
1084     #endif
1085 zoff99 28 #endif
1086 zoff99 2 return g_strdup_printf(_("%d meters"), dist);
1087 zoff99 27 }
1088 zoff99 2 else
1089 zoff99 27 {
1090     #ifdef HAVE_API_ANDROID
1091 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
1092 zoff99 27 android_send_generic_text(1,"+*#O:in %d meters\n");
1093     gchar* xy=g_strdup_printf("+*#1:%d\n", dist);
1094     android_send_generic_text(1,xy);
1095     g_free(xy);
1096     #endif
1097 zoff99 28 #endif
1098 zoff99 2 return g_strdup_printf(_("in %d meters"), dist);
1099 zoff99 27 }
1100 zoff99 2 }
1101     }
1102 zoff99 40
1103 zoff99 2 if (imperial)
1104 zoff99 27 {
1105 zoff99 40 //dbg(0, "DIST_FEET:003:d=%d v=%d\n", dist, vocabulary);
1106 zoff99 30 dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER * 1000 / FEET_PER_MILE, 1000);
1107 zoff99 40 //dbg(0, "DIST_FEET:004:d=%d v=%d\n", dist, vocabulary);
1108 zoff99 27 }
1109 zoff99 2 else
1110 zoff99 27 {
1111     dist = round_for_vocabulary(vocabulary, dist, 1000);
1112     }
1113    
1114     if (dist < 5000)
1115     {
1116     int rem = (dist / 100) % 10;
1117     if (rem)
1118     {
1119     if (imperial)
1120     {
1121 zoff99 2 if (is_length)
1122 zoff99 27 {
1123     #ifdef HAVE_API_ANDROID
1124 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
1125 zoff99 27 android_send_generic_text(1,"+*#O:%d.%d miles\n");
1126     #endif
1127 zoff99 28 #endif
1128 zoff99 27 return g_strdup_printf(_("%d.%d miles"), dist / 1000, rem);
1129     }
1130 zoff99 2 else
1131 zoff99 27 {
1132     #ifdef HAVE_API_ANDROID
1133 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
1134 zoff99 27 android_send_generic_text(1,"+*#O:in %d.%d miles\n");
1135     #endif
1136 zoff99 28 #endif
1137 zoff99 40 //dbg(0, "DIST_FEET:005:d/1000=%d rem=%d\n", dist / 1000, rem);
1138    
1139 zoff99 30 return g_strdup_printf(_("in %d.%d miles"), dist / 1000, rem);
1140 zoff99 27 }
1141     }
1142     else
1143     {
1144 zoff99 2 if (is_length)
1145 zoff99 27 {
1146     #ifdef HAVE_API_ANDROID
1147 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
1148 zoff99 27 android_send_generic_text(1,"+*#O:%d.%d kilometers\n");
1149     #endif
1150 zoff99 28 #endif
1151 zoff99 30 return g_strdup_printf(_("%d.%d kilometers"), dist / 1000, rem);
1152 zoff99 27 }
1153 zoff99 2 else
1154 zoff99 27 {
1155     #ifdef HAVE_API_ANDROID
1156 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
1157 zoff99 27 android_send_generic_text(1,"+*#O:in %d.%d kilometers\n");
1158     #endif
1159 zoff99 28 #endif
1160 zoff99 30 return g_strdup_printf(_("in %d.%d kilometers"), dist / 1000, rem);
1161 zoff99 27 }
1162 zoff99 2 }
1163     }
1164     }
1165 zoff99 40
1166 zoff99 27 if (imperial)
1167     {
1168     if (is_length)
1169 zoff99 40 {
1170 zoff99 30 return g_strdup_printf(ngettext("one mile", "%d miles", dist / 1000), dist / 1000);
1171 zoff99 40 }
1172 zoff99 2 else
1173 zoff99 40 {
1174     //dbg(0, "DIST_FEET:006:d/1000=%d\n", dist / 1000);
1175    
1176 zoff99 30 return g_strdup_printf(ngettext("in one mile", "in %d miles", dist / 1000), dist / 1000);
1177 zoff99 40 }
1178 zoff99 27 }
1179     else
1180     {
1181     if (is_length)
1182     {
1183     #ifdef HAVE_API_ANDROID
1184 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
1185 zoff99 27 android_send_generic_text(1,"+*#O:one kilometer|%d kilometers\n");
1186     #endif
1187 zoff99 28 #endif
1188 zoff99 30 return g_strdup_printf(ngettext("one kilometer", "%d kilometers", dist / 1000), dist / 1000);
1189 zoff99 27 }
1190 zoff99 2 else
1191 zoff99 27 {
1192     #ifdef HAVE_API_ANDROID
1193 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
1194 zoff99 27 android_send_generic_text(1,"+*#O:in one kilometer|in %d kilometers\n");
1195     #endif
1196 zoff99 28 #endif
1197 zoff99 30 return g_strdup_printf(ngettext("in one kilometer", "in %d kilometers", dist / 1000), dist / 1000);
1198 zoff99 27 }
1199 zoff99 2 }
1200     }
1201    
1202 zoff99 40 static int navigation_get_real_item_first_coord(struct navigation_way *w, struct coord *c)
1203     {
1204     struct item *ritem = NULL; // the "real" item
1205     struct map_rect *mr;
1206     struct attr attr;
1207     struct coord c2[5];
1208    
1209    
1210     #if 1
1211     if (!w)
1212     {
1213     return 0;
1214     }
1215    
1216     if (!w->item.map)
1217     {
1218     return 0;
1219     }
1220    
1221     if ((!w->item.id_hi) && (w->item.id_lo))
1222     {
1223     return 0;
1224     }
1225    
1226     mr = map_rect_new(w->item.map, NULL);
1227    
1228     if (!mr)
1229     {
1230     return 0;
1231     }
1232    
1233     // COST: 001
1234     dbg(0, "COST:001\n");
1235     ritem = map_rect_get_item_byid(mr, w->item.id_hi, w->item.id_lo);
1236    
1237     if (!ritem)
1238     {
1239     map_rect_destroy(mr);
1240     return 0;
1241     }
1242    
1243     if (item_coord_get(ritem, c2, 2) == 2)
1244     {
1245     c[0].x = c2[0].x;
1246     c[0].y = c2[0].y;
1247     c[1].x = c2[1].x;
1248     c[1].y = c2[1].y;
1249    
1250     map_rect_destroy(mr);
1251     return 1;
1252     }
1253    
1254     map_rect_destroy(mr);
1255     return 0;
1256    
1257     #endif
1258     }
1259    
1260     long long navigation_item_get_wayid(struct navigation_way *w)
1261     {
1262     struct item *ritem; // the "real" item
1263     struct map_rect *mr;
1264     struct attr attr;
1265     long long ret = 0;
1266    
1267     if (!w)
1268     {
1269     return ret;
1270     }
1271    
1272     if (!w->item.map)
1273     {
1274     return ret;
1275     }
1276    
1277     if ((!w->item.id_hi) && (w->item.id_lo))
1278     {
1279     return ret;
1280     }
1281    
1282     mr = map_rect_new(w->item.map, NULL);
1283    
1284     if (!mr)
1285     {
1286     return ret;
1287     }
1288    
1289     // COST: 002
1290     dbg(0, "COST:002\n");
1291     ritem = map_rect_get_item_byid(mr, w->item.id_hi, w->item.id_lo);
1292    
1293     if (!ritem)
1294     {
1295     map_rect_destroy(mr);
1296     return ret;
1297     }
1298    
1299     if (item_attr_get(ritem, attr_osm_wayid, &attr))
1300     {
1301     // dbg(0, "START:attr.u.num64=%x attr.u.num64=%lld\n", attr.u.num64, attr.u.num64);
1302     if (attr.u.num64)
1303     {
1304     ret = *attr.u.num64;
1305     }
1306     // dbg(0, "END:attr.u.num64\n");
1307     }
1308    
1309     map_rect_destroy(mr);
1310    
1311     // dbg(0, "return 099\n");
1312    
1313     return ret;
1314     }
1315    
1316     int navigation_item_get_flags(struct navigation_way *w)
1317     {
1318     struct item *ritem; // the "real" item
1319     struct map_rect *mr;
1320     struct attr attr;
1321     long long ret = 0;
1322    
1323     if (!w)
1324     {
1325     return ret;
1326     }
1327    
1328    
1329     // -----------------------------------------
1330     // -----------------------------------------
1331     // flags should be there already!?
1332     if (w->flags != 0)
1333     {
1334     // we already have flags set!
1335     return w->flags;
1336     }
1337     // -----------------------------------------
1338     // -----------------------------------------
1339    
1340    
1341     if (!w->item.map)
1342     {
1343     return ret;
1344     }
1345    
1346     if ((!w->item.id_hi) && (w->item.id_lo))
1347     {
1348     return ret;
1349     }
1350    
1351     mr = map_rect_new(w->item.map, NULL);
1352    
1353     if (!mr)
1354     {
1355     return ret;
1356     }
1357    
1358     // COST: 003
1359     dbg(0, "COST:003\n");
1360     ritem = map_rect_get_item_byid(mr, w->item.id_hi, w->item.id_lo);
1361    
1362     if (!ritem)
1363     {
1364     map_rect_destroy(mr);
1365     return ret;
1366     }
1367    
1368     if (item_attr_get(ritem, attr_flags, &attr))
1369     {
1370     ret = attr.u.num;
1371     // also set the flags here!!
1372     w->flags = ret;
1373     }
1374     else
1375     {
1376     w->flags = 0;
1377     }
1378    
1379     map_rect_destroy(mr);
1380    
1381     // dbg(0, "return 099\n");
1382    
1383     return ret;
1384     }
1385    
1386    
1387 zoff99 2 /**
1388     * @brief This calculates the angle with which an item starts or ends
1389     *
1390     * This function can be used to get the angle an item (from a route graph map)
1391     * starts or ends with. Note that the angle will point towards the inner of
1392     * the item.
1393     *
1394     * This is meant to be used with items from a route graph map
1395     * With other items this will probably not be optimal...
1396     *
1397     * @param w The way which should be calculated
1398 zoff99 27 */
1399     static void calculate_angle(struct navigation_way *w)
1400 zoff99 2 {
1401     struct coord cbuf[2];
1402     struct item *ritem; // the "real" item
1403     struct coord c;
1404     struct map_rect *mr;
1405     struct attr attr;
1406    
1407 zoff99 27 w->angle2 = 361;
1408 zoff99 2 mr = map_rect_new(w->item.map, NULL);
1409 zoff99 40
1410 zoff99 2 if (!mr)
1411 zoff99 40 {
1412 zoff99 2 return;
1413 zoff99 40 }
1414 zoff99 2
1415 zoff99 40 // COST: 004
1416     dbg(0, "COST:004\n");
1417 zoff99 2 ritem = map_rect_get_item_byid(mr, w->item.id_hi, w->item.id_lo);
1418 zoff99 40
1419 zoff99 27 if (!ritem)
1420     {
1421 zoff99 40 // dbg(1, "Item from segment not found on map!\n");
1422 zoff99 2 map_rect_destroy(mr);
1423     return;
1424     }
1425    
1426 zoff99 27 if (ritem->type < type_line || ritem->type >= type_area)
1427     {
1428 zoff99 2 map_rect_destroy(mr);
1429     return;
1430     }
1431 zoff99 40
1432    
1433 zoff99 2 if (item_attr_get(ritem, attr_flags, &attr))
1434 zoff99 40 {
1435 zoff99 27 w->flags = attr.u.num;
1436 zoff99 40 }
1437 zoff99 2 else
1438 zoff99 40 {
1439 zoff99 27 w->flags = 0;
1440 zoff99 40 }
1441     // dbg(0, "w->flags=%x\n", w->flags);
1442    
1443    
1444 zoff99 2 if (item_attr_get(ritem, attr_street_name, &attr))
1445 zoff99 40 {
1446 zoff99 27 w->name1 = map_convert_string(ritem->map, attr.u.str);
1447 zoff99 40 }
1448 zoff99 2 else
1449 zoff99 40 {
1450 zoff99 27 w->name1 = NULL;
1451 zoff99 40 }
1452    
1453    
1454 zoff99 2 if (item_attr_get(ritem, attr_street_name_systematic, &attr))
1455 zoff99 40 {
1456 zoff99 27 w->name2 = map_convert_string(ritem->map, attr.u.str);
1457 zoff99 40 }
1458 zoff99 2 else
1459 zoff99 40 {
1460 zoff99 27 w->name2 = NULL;
1461 zoff99 40 }
1462 zoff99 27
1463 zoff99 40
1464 zoff99 27 if (w->dir < 0)
1465     {
1466     if (item_coord_get(ritem, cbuf, 2) != 2)
1467     {
1468 zoff99 40 // dbg(1, "Using calculate_angle() with a less-than-two-coords-item?\n");
1469 zoff99 2 map_rect_destroy(mr);
1470     return;
1471     }
1472 zoff99 27
1473     while (item_coord_get(ritem, &c, 1))
1474     {
1475 zoff99 2 cbuf[0] = cbuf[1];
1476     cbuf[1] = c;
1477     }
1478 zoff99 27
1479     }
1480     else
1481     {
1482     if (item_coord_get(ritem, cbuf, 2) != 2)
1483     {
1484 zoff99 40 // dbg(1, "Using calculate_angle() with a less-than-two-coords-item?\n");
1485 zoff99 2 map_rect_destroy(mr);
1486     return;
1487     }
1488 zoff99 40
1489 zoff99 2 c = cbuf[0];
1490     cbuf[0] = cbuf[1];
1491     cbuf[1] = c;
1492     }
1493    
1494     map_rect_destroy(mr);
1495    
1496 zoff99 41 // w->angle2 = road_angle_accurate(&cbuf[1], &cbuf[0], 0);
1497 zoff99 27 w->angle2 = road_angle(&cbuf[1], &cbuf[0], 0);
1498 zoff99 2 }
1499    
1500     /**
1501     * @brief Returns the time (in seconds) one will drive between two navigation items
1502     *
1503     * This function returns the time needed to drive between two items, including both of them,
1504     * in seconds.
1505     *
1506     * @param from The first item
1507     * @param to The last item
1508     * @return The travel time in seconds, or -1 on error
1509     */
1510 zoff99 30 static int navigation_time(struct navigation_itm *from, struct navigation_itm *to)
1511 zoff99 2 {
1512     struct navigation_itm *cur;
1513     int time;
1514    
1515     time = 0;
1516     cur = from;
1517 zoff99 27 while (cur)
1518     {
1519 zoff99 2 time += cur->time;
1520    
1521 zoff99 27 if (cur == to)
1522     {
1523 zoff99 2 break;
1524     }
1525     cur = cur->next;
1526     }
1527    
1528 zoff99 27 if (!cur)
1529     {
1530 zoff99 2 return -1;
1531     }
1532    
1533     return time;
1534     }
1535    
1536 zoff99 40
1537    
1538 zoff99 41 static int navigation_time_real_speed(struct navigation_itm *from, struct navigation_itm *to, int speed_in_kmh)
1539     {
1540     struct navigation_itm *cur;
1541     int time;
1542     int first = 1;
1543     float speed_in_ms = (float) ((float)speed_in_kmh / 3.6f);
1544    
1545     time = 0;
1546     cur = from;
1547    
1548     while (cur)
1549     {
1550    
1551     if (first == 1)
1552     {
1553     first = 0;
1554     if (speed_in_kmh < 1)
1555     {
1556     time += cur->time;
1557     }
1558     else
1559     {
1560     time = time + (int)( ((float)cur->length / speed_in_ms ) * 10.0f );
1561     }
1562     }
1563     else
1564     {
1565     time += cur->time;
1566     }
1567    
1568     if (cur == to)
1569     {
1570     break;
1571     }
1572     cur = cur->next;
1573     }
1574    
1575     if (!cur)
1576     {
1577     return -1;
1578     }
1579    
1580     return time;
1581     }
1582    
1583    
1584    
1585    
1586 zoff99 40 // -- NEW 002 --
1587     static void navigation_free_list(struct street_destination *list)
1588     {
1589     if (list)
1590     {
1591     struct street_destination *clist = NULL;
1592     while (list)
1593     {
1594     clist = list->next;
1595     if (list->destination)
1596     {
1597     g_free(list->destination);
1598     }
1599    
1600     g_free(list);
1601     list = clist;
1602     }
1603     list = NULL;
1604     }
1605     }
1606     // -- NEW 002 --
1607    
1608    
1609    
1610    
1611    
1612 zoff99 2 /**
1613     * @brief Clears the ways one can drive from itm
1614     *
1615     * @param itm The item that should have its ways cleared
1616     */
1617 zoff99 27 static void navigation_itm_ways_clear(struct navigation_itm *itm)
1618 zoff99 2 {
1619 zoff99 27 struct navigation_way *c, *n;
1620 zoff99 2
1621     c = itm->way.next;
1622 zoff99 27 while (c)
1623     {
1624 zoff99 2 n = c->next;
1625     map_convert_free(c->name1);
1626     map_convert_free(c->name2);
1627 zoff99 40
1628     if (c->exit_ref)
1629     {
1630     g_free(c->exit_ref);
1631     c->exit_ref = NULL;
1632     }
1633    
1634     if (c->exit_label)
1635     {
1636     g_free(c->exit_label);
1637     c->exit_label = NULL;
1638     }
1639    
1640     if (c->street_dest_text)
1641     {
1642     g_free(c->street_dest_text);
1643     c->street_dest_text = NULL;
1644     }
1645    
1646     if (c->s_destination)
1647     {
1648     navigation_free_list(c->s_destination);
1649     }
1650    
1651 zoff99 2 g_free(c);
1652 zoff99 40 c = NULL;
1653    
1654 zoff99 2 c = n;
1655     }
1656    
1657     itm->way.next = NULL;
1658     }
1659    
1660     /**
1661     * @brief Updates the ways one can drive from itm
1662     *
1663     * This updates the list of possible ways to drive to from itm. The item "itm" is on
1664     * and the next navigation item are excluded.
1665     *
1666     * @param itm The item that should be updated
1667     * @param graph_map The route graph's map that these items are on
1668     */
1669 zoff99 30 static void navigation_itm_ways_update(struct navigation_itm *itm, struct map *graph_map)
1670 zoff99 2 {
1671     struct map_selection coord_sel;
1672     struct map_rect *g_rect; // Contains a map rectangle from the route graph's map
1673 zoff99 27 struct item *i, *sitem;
1674     struct attr sitem_attr, direction_attr;
1675 zoff99 40 // struct attr flags_attr;
1676 zoff99 27 struct navigation_way *w, *l;
1677 zoff99 2
1678     navigation_itm_ways_clear(itm);
1679    
1680     // These values cause the code in route.c to get us only the route graph point and connected segments
1681     coord_sel.next = NULL;
1682     coord_sel.u.c_rect.lu = itm->start;
1683     coord_sel.u.c_rect.rl = itm->start;
1684     // the selection's order is ignored
1685 zoff99 27
1686 zoff99 2 g_rect = map_rect_new(graph_map, &coord_sel);
1687 zoff99 27
1688 zoff99 2 i = map_rect_get_item(g_rect);
1689 zoff99 40
1690 zoff99 27 if (!i || i->type != type_rg_point)
1691     { // probably offroad?
1692     return;
1693 zoff99 2 }
1694    
1695     w = NULL;
1696 zoff99 27
1697     while (1)
1698     {
1699 zoff99 2 i = map_rect_get_item(g_rect);
1700    
1701 zoff99 27 if (!i)
1702     {
1703 zoff99 2 break;
1704     }
1705 zoff99 27
1706     if (i->type != type_rg_segment)
1707     {
1708 zoff99 2 continue;
1709     }
1710 zoff99 27
1711     if (!item_attr_get(i, attr_street_item, &sitem_attr))
1712     {
1713 zoff99 40 // dbg(1, "Got no street item for route graph item in entering_straight()\n");
1714 zoff99 2 continue;
1715 zoff99 27 }
1716 zoff99 2
1717 zoff99 27 if (!item_attr_get(i, attr_direction, &direction_attr))
1718     {
1719 zoff99 2 continue;
1720     }
1721    
1722     sitem = sitem_attr.u.item;
1723 zoff99 40
1724 zoff99 30 if (sitem->type == type_street_turn_restriction_no || sitem->type == type_street_turn_restriction_only)
1725 zoff99 40 {
1726 zoff99 2 continue;
1727 zoff99 40 }
1728 zoff99 2
1729 zoff99 30 if (item_is_equal(itm->way.item, *sitem) || ((itm->prev) && item_is_equal(itm->prev->way.item, *sitem)))
1730 zoff99 27 {
1731 zoff99 2 continue;
1732     }
1733    
1734 zoff99 40 //if (!item_attr_get(i, attr_flags, &flags_attr))
1735     //{
1736     // flags_attr.u.num = 0;
1737     //}
1738     //dbg(0, "w2->flags=%x\n", flags_attr.u.num);
1739    
1740 zoff99 2 l = w;
1741 zoff99 40 w = g_new0(struct navigation_way, 1);
1742 zoff99 2 w->dir = direction_attr.u.num;
1743     w->item = *sitem;
1744     w->next = l;
1745 zoff99 40 // w->flags = flags_attr.u.num;
1746    
1747 zoff99 2 calculate_angle(w);
1748     }
1749    
1750     map_rect_destroy(g_rect);
1751 zoff99 27
1752 zoff99 2 itm->way.next = w;
1753     }
1754    
1755 zoff99 30 static void navigation_destroy_itms_cmds(struct navigation *this_, struct navigation_itm *end)
1756 zoff99 2 {
1757     struct navigation_itm *itm;
1758     struct navigation_command *cmd;
1759 zoff99 40
1760 zoff99 27 // dbg(2, "enter this_=%p this_->first=%p this_->cmd_first=%p end=%p\n", this_, this_->first, this_->cmd_first, end);
1761 zoff99 40
1762 zoff99 2 if (this_->cmd_first)
1763 zoff99 27 {
1764     // dbg(2, "this_->cmd_first->itm=%p\n", this_->cmd_first->itm);
1765     }
1766 zoff99 40
1767 zoff99 27 while (this_->first && this_->first != end)
1768     {
1769     itm = this_->first;
1770     // dbg(3, "destroying %p\n", itm);
1771 zoff99 2 item_hash_remove(this_->hash, &itm->way.item);
1772 zoff99 27 this_->first = itm->next;
1773 zoff99 40
1774 zoff99 2 if (this_->first)
1775 zoff99 40 {
1776 zoff99 27 this_->first->prev = NULL;
1777 zoff99 40 }
1778    
1779 zoff99 27 if (this_->cmd_first && this_->cmd_first->itm == itm->next)
1780     {
1781     cmd = this_->cmd_first;
1782     this_->cmd_first = cmd->next;
1783     if (cmd->next)
1784     {
1785 zoff99 2 cmd->next->prev = NULL;
1786     }
1787     g_free(cmd);
1788 zoff99 41 // FF: ??
1789     // cmd = NULL;
1790 zoff99 2 }
1791 zoff99 40
1792 zoff99 2 map_convert_free(itm->way.name1);
1793     map_convert_free(itm->way.name2);
1794 zoff99 40
1795     if (itm->way.s_destination)
1796     {
1797     navigation_free_list(itm->way.s_destination);
1798     }
1799    
1800     if (itm->way.exit_ref)
1801     {
1802     g_free(itm->way.exit_ref);
1803     itm->way.exit_ref = NULL;
1804     }
1805    
1806     if (itm->way.exit_label)
1807     {
1808     g_free(itm->way.exit_label);
1809     itm->way.exit_label = NULL;
1810     }
1811    
1812     if (itm->way.street_dest_text)
1813     {
1814     g_free(itm->way.street_dest_text);
1815     itm->way.street_dest_text = NULL;
1816     }
1817    
1818 zoff99 2 navigation_itm_ways_clear(itm);
1819 zoff99 40
1820 zoff99 2 g_free(itm);
1821 zoff99 40 itm = NULL;
1822 zoff99 2 }
1823 zoff99 40
1824 zoff99 27 if (!this_->first)
1825 zoff99 40 {
1826 zoff99 27 this_->last = NULL;
1827 zoff99 40 }
1828    
1829 zoff99 27 if (!this_->first && end)
1830     {
1831     // dbg(0, "end wrong\n");
1832     }
1833 zoff99 2 }
1834    
1835 zoff99 30 static void navigation_itm_update(struct navigation_itm *itm, struct item *ritem)
1836 zoff99 2 {
1837     struct attr length, time, speed;
1838    
1839 zoff99 27 if (!item_attr_get(ritem, attr_length, &length))
1840     {
1841     // dbg(0, "no length\n");
1842 zoff99 2 return;
1843     }
1844 zoff99 40
1845 zoff99 27 if (!item_attr_get(ritem, attr_time, &time))
1846     {
1847     // dbg(0, "no time\n");
1848 zoff99 2 return;
1849     }
1850 zoff99 40
1851 zoff99 27 if (!item_attr_get(ritem, attr_speed, &speed))
1852     {
1853 zoff99 40 // dbg(0, "no speed\n");
1854 zoff99 2 return;
1855     }
1856    
1857 zoff99 27 // dbg(1, "length=%d time=%d speed=%d\n", length.u.num, time.u.num, speed.u.num);
1858     itm->length = length.u.num;
1859     itm->time = time.u.num;
1860     itm->speed = speed.u.num;
1861 zoff99 2 }
1862    
1863     /**
1864     * @brief This check if an item is part of a roundabout
1865     *
1866     * @param itm The item to be checked
1867     * @return True if the item is part of a roundabout
1868 zoff99 27 */
1869     static int check_roundabout(struct navigation_itm *itm, struct map *graph_map)
1870 zoff99 2 {
1871     struct map_selection coord_sel;
1872     struct map_rect *g_rect; // Contains a map rectangle from the route graph's map
1873 zoff99 27 struct item *i, *sitem;
1874     struct attr sitem_attr, flags_attr;
1875 zoff99 2
1876     // These values cause the code in route.c to get us only the route graph point and connected segments
1877     coord_sel.next = NULL;
1878     coord_sel.u.c_rect.lu = itm->start;
1879     coord_sel.u.c_rect.rl = itm->start;
1880     // the selection's order is ignored
1881 zoff99 27
1882 zoff99 2 g_rect = map_rect_new(graph_map, &coord_sel);
1883 zoff99 27
1884 zoff99 2 i = map_rect_get_item(g_rect);
1885 zoff99 40
1886 zoff99 27 if (!i || i->type != type_rg_point)
1887 zoff99 40 {
1888     // probably offroad?
1889 zoff99 2 map_rect_destroy(g_rect);
1890     return 0;
1891     }
1892    
1893 zoff99 27 while (1)
1894     {
1895 zoff99 2 i = map_rect_get_item(g_rect);
1896    
1897 zoff99 27 if (!i)
1898     {
1899 zoff99 2 break;
1900     }
1901 zoff99 27
1902     if (i->type != type_rg_segment)
1903     {
1904 zoff99 2 continue;
1905     }
1906 zoff99 27
1907     if (!item_attr_get(i, attr_street_item, &sitem_attr))
1908     {
1909 zoff99 2 continue;
1910 zoff99 27 }
1911 zoff99 2
1912     sitem = sitem_attr.u.item;
1913 zoff99 27 if (item_is_equal(itm->way.item, *sitem))
1914     {
1915 zoff99 34 if (item_attr_get(i, attr_flags, &flags_attr) && (flags_attr.u.num & NAVIT_AF_ROUNDABOUT))
1916 zoff99 27 {
1917 zoff99 2 map_rect_destroy(g_rect);
1918     return 1;
1919     }
1920     }
1921     }
1922    
1923     map_rect_destroy(g_rect);
1924     return 0;
1925     }
1926    
1927 zoff99 40
1928    
1929     // -- NEW 002 --
1930     static int navigation_split_string_to_list(struct navigation_way *way, char* raw_string, char sep)
1931     {
1932     struct street_destination *new_street_destination = NULL;
1933     struct street_destination *next_street_destination_remember = NULL;
1934     char *pos1 = raw_string;
1935     char *pos2 = NULL;
1936     int count = 0;
1937    
1938     navigation_free_list(way->s_destination); /*in case this is a retry with a different separator.*/
1939    
1940     //dbg(0,"raw_string=%s split with %c\n",raw_string, sep);
1941     if (strlen(raw_string) > 0)
1942     {
1943     count = 1;
1944     while (pos1)
1945     {
1946     new_street_destination = g_new0(struct street_destination, 1);
1947     new_street_destination->next = next_street_destination_remember;
1948     next_street_destination_remember = new_street_destination;
1949     if ((pos2 = strrchr(pos1, sep)) != NULL)
1950     {
1951     new_street_destination->destination = g_strdup(pos2 + 1);
1952     *pos2 = '\0' ;
1953     //dbg(0,"splitted_off_string=%s\n", new_street_destination->destination);
1954     count++;
1955     }
1956     else
1957     {
1958     new_street_destination->destination = g_strdup(pos1);
1959     pos1 = NULL;
1960     //dbg(0,"head_of_string=%s\n", new_street_destination->destination);
1961     }
1962     way->s_destination = next_street_destination_remember;
1963     }
1964     }
1965     return count;
1966     }
1967    
1968     static int navigation_split_string_to_list_2(struct navigation_way *way, char* raw_string, char sep, char sep2)
1969     {
1970     struct street_destination *new_street_destination = NULL;
1971     struct street_destination *next_street_destination_remember = NULL;
1972     char *pos1 = raw_string;
1973     char *pos2 = NULL;
1974     char *pos2a = NULL;
1975     char *pos2b = NULL;
1976     int count = 0;
1977    
1978     navigation_free_list(way->s_destination); /*in case this is a retry with a different separator.*/
1979    
1980     //dbg(0,"raw_string=%s split with %c\n",raw_string, sep);
1981     if (strlen(raw_string) > 0)
1982     {
1983     count = 1;
1984     while (pos1)
1985     {
1986     new_street_destination = g_new0(struct street_destination, 1);
1987     new_street_destination->next = next_street_destination_remember;
1988     next_street_destination_remember = new_street_destination;
1989    
1990     pos2a = strrchr(pos1, sep);
1991     pos2b = strrchr(pos1, sep2);
1992    
1993     if (pos2a == NULL)
1994     {
1995     if (pos2b != NULL)
1996     {
1997     pos2 = pos2b;
1998     }
1999     else
2000     {
2001     pos2 = NULL;
2002     }
2003     }
2004     else if (pos2b == NULL)
2005     {
2006     if (pos2a != NULL)
2007     {
2008     pos2 = pos2a;
2009     }
2010     else
2011     {
2012     pos2 = NULL;
2013     }
2014     }
2015     else // both NOT NULL
2016     {
2017     if (pos2a > pos2b)
2018     {
2019     pos2 = pos2b;
2020     }
2021     else
2022     {
2023     pos2 = pos2a;
2024     }
2025     }
2026    
2027     if (pos2 != NULL)
2028     {
2029     new_street_destination->destination = g_strdup(pos2 + 1);
2030     *pos2 = '\0' ;
2031     //dbg(0,"splitted_off_string=%s\n", new_street_destination->destination);
2032     count++;
2033     }
2034     else
2035     {
2036     new_street_destination->destination = g_strdup(pos1);
2037     pos1 = NULL;
2038     //dbg(0,"head_of_string=%s\n", new_street_destination->destination);
2039     }
2040     way->s_destination = next_street_destination_remember;
2041     }
2042     }
2043     return count;
2044     }
2045    
2046     // -- NEW 002 --
2047    
2048    
2049    
2050    
2051    
2052    
2053    
2054    
2055     // -- NEW 002 --
2056     /** @brief Selects the destination-names for the next announcement from the
2057     * destination-names that are registered in the following command items.
2058     *
2059     * The aim of this function is to find the destination-name entry that has the most hits in the following
2060     * command items so that the destination name has a relevance over several announcements. If there is no 'winner'
2061     * the entry is selected that is at top of the destination.
2062 zoff99 46 *
2063     * thanks to jandegr
2064 zoff99 40 */
2065     static navigation_select_announced_destinations(struct navigation_command *current_command)
2066     {
2067     struct street_destination *current_destination = NULL; /* the list pointer of the destination_names of the current command. */
2068     struct street_destination *search_destination = NULL; /* the list pointer of the destination_names of the respective search_command. */
2069    
2070     struct navigation_command *search_command = NULL; /* loop through every navigation command up to the end. */
2071    
2072     /* limits the number of entries of a destination sign as well as the number of command items to investigate */
2073     #define DEST_MAX_LOOPS_SIGN_TEXTS 10
2074     #define DEST_MAX_LOOPS_NAV_ITEMS 3
2075    
2076     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 */
2077     /* investigated command items - a 'high score' of destination names */
2078    
2079     int destination_index = 0;
2080     int search_command_counter = 0;
2081     int i;
2082     int max_hits;
2083     int max_hit_index;
2084     struct navigation_way *current_nav_way = NULL;
2085    
2086     // put text into way struct later -----------------
2087     current_nav_way = &(current_command->itm->way);
2088     if ((current_nav_way) && (current_nav_way->street_dest_text))
2089     {
2090     // already have set a destination --> return
2091     return;
2092     }
2093     current_nav_way->street_dest_text = NULL; // set default to "no value"
2094     // put text into way struct later -----------------
2095    
2096    
2097     /* search over every following command for seeking identical destination_names */
2098     if (current_command->itm->way.s_destination)
2099     {
2100     /* can we investigate over the following commands? */
2101    
2102     if (current_command->next)
2103     {
2104     /* loop over every destination sign of the current command, as far as there are not more than 10 entries. */
2105     destination_index = 0; /* Do only the first DEST_MAX_LOOPS_SIGN_TEXTS destination_signs */
2106     current_destination = current_command->itm->way.s_destination;
2107    
2108     while (current_destination && (destination_index < DEST_MAX_LOOPS_SIGN_TEXTS))
2109     { /* initialize the search command */
2110    
2111     search_command = current_command->next;
2112     search_command_counter = 0; // Do only the first DEST_MAX_LOOPS_NAV_ITEMS commands.
2113    
2114     while (search_command && (search_command_counter < DEST_MAX_LOOPS_NAV_ITEMS))
2115     {
2116     if (search_command->itm)
2117     { /* has the search command any destination_signs? */
2118    
2119     if (search_command->itm->way.s_destination)
2120     {
2121     search_destination = search_command->itm->way.s_destination;
2122    
2123     while (search_destination)
2124     { /* Search this name in the destination list of the current command. */
2125    
2126     if (0 == strcmp(current_destination->destination, search_destination->destination))
2127     { /* enter the destination_name in the investigation list*/
2128    
2129     destination_count[destination_index]++;
2130     //search_destination = NULL; /* break condition */
2131     break;
2132     }
2133     else
2134     {
2135     search_destination = search_destination->next;
2136     }
2137     }
2138     }
2139     }
2140     search_command_counter++;
2141     search_command = search_command->next;
2142     }
2143    
2144     destination_index++;
2145     current_destination = current_destination->next;
2146     }
2147    
2148     /* search for the best candidate */
2149     max_hits = 0;
2150     max_hit_index = 0;
2151     for (i = 0; i < destination_index; i++)
2152     {
2153     if (destination_count[i] > max_hits)
2154     {
2155     max_hits = destination_count[i];
2156     max_hit_index = i;
2157     }
2158     }
2159     /* jump to the corresponding destination_name */
2160     current_destination = current_command->itm->way.s_destination;
2161     for (i = 0; i < max_hit_index; i++)
2162     {
2163     current_destination = current_destination->next;
2164     }
2165     }
2166     else if (current_command->itm->way.exit_label)
2167     {
2168     if ((current_nav_way) && (current_nav_way->street_dest_text))
2169     {
2170     g_free(current_nav_way->street_dest_text);
2171     }
2172    
2173     current_nav_way->street_dest_text = g_strdup(current_command->itm->way.exit_label);
2174     #ifdef NAVIT_ROUTING_DEBUG_PRINT
2175     dbg(0, "put exit_label into nav way (C) %s\n", current_command->itm->way.exit_label);
2176     #endif
2177    
2178     return;
2179     }
2180     }
2181     else if (current_command->itm->way.exit_label)
2182     {
2183     if ((current_nav_way) && (current_nav_way->street_dest_text))
2184     {
2185     g_free(current_nav_way->street_dest_text);
2186     }
2187    
2188     current_nav_way->street_dest_text = g_strdup(current_command->itm->way.exit_label);
2189     #ifdef NAVIT_ROUTING_DEBUG_PRINT
2190     dbg(0, "put exit_label into nav way (A) %s\n", current_command->itm->way.exit_label);
2191     #endif
2192    
2193     return;
2194     }
2195    
2196    
2197    
2198    
2199    
2200     /* return the best candidate, if there is any.*/
2201     if ((current_nav_way) && (current_nav_way->street_dest_text))
2202     {
2203     g_free(current_nav_way->street_dest_text);
2204     current_nav_way->street_dest_text = NULL;
2205     }
2206    
2207     if ((current_destination) && (current_destination->destination))
2208     {
2209     current_nav_way->street_dest_text = g_strdup(current_destination->destination);
2210     #ifdef NAVIT_ROUTING_DEBUG_PRINT
2211     dbg(0, "put destination into nav way (B) %s\n", current_nav_way->street_dest_text);
2212     #endif
2213     }
2214     else
2215     {
2216     // stay NULL
2217     //current_nav_way->street_dest_text = NULL;
2218     //dbg(0, "put destination into nav way NULL (C)\n");
2219     }
2220     }
2221     // -- NEW 002 --
2222    
2223    
2224    
2225    
2226 zoff99 2 static struct navigation_itm *
2227     navigation_itm_new(struct navigation *this_, struct item *ritem)
2228     {
2229     struct navigation_itm *ret=g_new0(struct navigation_itm, 1);
2230 zoff99 27 int i = 0;
2231 zoff99 2 struct item *sitem;
2232     struct map *graph_map = NULL;
2233 zoff99 27 struct attr street_item, direction, route_attr;
2234 zoff99 2 struct map_rect *mr;
2235     struct attr attr;
2236     struct coord c[5];
2237    
2238 zoff99 27 if (ritem)
2239     {
2240     ret->streetname_told = 0;
2241 zoff99 41
2242     if (ritem->type == type_street_route_waypoint)
2243     {
2244     dbg(0, "NAVR:XX:0:make street item\n");
2245    
2246     while (item_coord_get(ritem, &c[i], 1))
2247     {
2248     if (i < 4)
2249     {
2250     i++;
2251     }
2252     else
2253     {
2254     c[2] = c[3];
2255     c[3] = c[4];
2256     }
2257     }
2258    
2259     i--;
2260     ret->start = c[0];
2261     ret->end = c[i];
2262    
2263     if (item_attr_get(ritem, attr_direction, &direction))
2264     {
2265     if (direction.u.num < 0)
2266     {
2267     ret->way.dir = -99; // mark waypoint type
2268     }
2269     else
2270     {
2271     ret->way.dir = 99; // mark waypoint type
2272     }
2273     }
2274     else
2275     {
2276     ret->way.dir = 99; // mark waypoint type
2277     }
2278    
2279     navigation_itm_update(ret, ritem);
2280     ret->length = 1;
2281     ret->time = 1;
2282     ret->speed = 30;
2283    
2284     if (!this_->first)
2285     {
2286     this_->first = ret;
2287     }
2288    
2289     if (this_->last)
2290     {
2291     this_->last->next = ret;
2292     ret->prev = this_->last;
2293     //if (graph_map)
2294     //{
2295     // navigation_itm_ways_update(ret, graph_map);
2296     //}
2297     }
2298     this_->last = ret;
2299    
2300     return ret;
2301     }
2302    
2303 zoff99 27 if (!item_attr_get(ritem, attr_street_item, &street_item))
2304     {
2305 zoff99 41 dbg(0, "NAVR:XX:1:no street item\n");
2306 zoff99 2 g_free(ret);
2307     ret = NULL;
2308     return ret;
2309     }
2310 zoff99 40
2311 zoff99 2 if (item_attr_get(ritem, attr_direction, &direction))
2312 zoff99 40 {
2313 zoff99 27 ret->way.dir = direction.u.num;
2314 zoff99 40 }
2315 zoff99 2 else
2316 zoff99 40 {
2317 zoff99 27 ret->way.dir = 0;
2318 zoff99 40 }
2319 zoff99 2
2320 zoff99 27 sitem = street_item.u.item;
2321     ret->way.item = *sitem;
2322 zoff99 2 item_hash_insert(this_->hash, sitem, ret);
2323 zoff99 27 mr = map_rect_new(sitem->map, NULL);
2324 zoff99 40
2325     // -- NEW 002 --
2326     struct map *tmap = sitem->map; /*find better name for backup pointer to map*/
2327     // -- NEW 002 --
2328    
2329     // COST: 005
2330     dbg(0, "COST:005\n");
2331 zoff99 27 if (!(sitem = map_rect_get_item_byid(mr, sitem->id_hi, sitem->id_lo)))
2332 zoff99 40 {
2333     // -- NEW 002 --
2334     if (mr)
2335     {
2336     map_rect_destroy(mr);
2337     }
2338     g_free(ret);
2339     ret = NULL;
2340     // -- NEW 002 --
2341    
2342 zoff99 2 return NULL;
2343 zoff99 40 }
2344    
2345     // -- NEW 002 --
2346     if (item_attr_get(sitem, attr_flags, &attr))
2347     {
2348     ret->way.flags=attr.u.num;
2349     }
2350     // -- NEW 002 --
2351    
2352 zoff99 2 if (item_attr_get(sitem, attr_street_name, &attr))
2353 zoff99 40 {
2354 zoff99 27 ret->way.name1 = map_convert_string(sitem->map, attr.u.str);
2355 zoff99 40 }
2356    
2357 zoff99 2 if (item_attr_get(sitem, attr_street_name_systematic, &attr))
2358 zoff99 40 {
2359 zoff99 27 ret->way.name2 = map_convert_string(sitem->map, attr.u.str);
2360 zoff99 40 }
2361    
2362 zoff99 2 navigation_itm_update(ret, ritem);
2363    
2364 zoff99 27 while (item_coord_get(ritem, &c[i], 1))
2365     {
2366     if (i < 4)
2367 zoff99 40 {
2368 zoff99 2 i++;
2369 zoff99 40 }
2370 zoff99 27 else
2371     {
2372     c[2] = c[3];
2373     c[3] = c[4];
2374 zoff99 2 }
2375     }
2376 zoff99 40
2377 zoff99 2 i--;
2378    
2379    
2380 zoff99 40
2381     // -- NEW 002 --
2382     if (item_attr_get(sitem, attr_street_destination, &attr))
2383     {
2384     char *destination_raw;
2385     destination_raw = map_convert_string(sitem->map,attr.u.str);
2386     #ifdef NAVIT_ROUTING_DEBUG_PRINT
2387     dbg(0, "DEST::destination_raw=%s\n", destination_raw);
2388     #endif
2389    
2390     #ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
2391     char *tt = g_strdup_printf("D:%s", attr.u.str);
2392     route_add_to_freetext_list(&c[0], tt);
2393     g_free(tt);
2394     #endif
2395    
2396     // also save full text into "exit_label" --------------
2397     if (ret->way.exit_label)
2398     {
2399     g_free(ret->way.exit_label);
2400     }
2401     ret->way.exit_label = map_convert_string(sitem->map, destination_raw);
2402     // also save full text into "exit_label" --------------
2403    
2404     navigation_split_string_to_list(&(ret->way), destination_raw, ';');
2405     g_free(destination_raw);
2406     }
2407     else if (item_attr_get(sitem, attr_street_destination_lanes, &attr))
2408     {
2409     char *destination_raw;
2410     destination_raw = map_convert_string(sitem->map,attr.u.str);
2411     #ifdef NAVIT_ROUTING_DEBUG_PRINT
2412     dbg(0, "DEST::destination_lanes_raw=%s\n", destination_raw);
2413     #endif
2414    
2415     #ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
2416     char *tt = g_strdup_printf("d_l:%s", attr.u.str);
2417     route_add_to_freetext_list(&c[0], tt);
2418     g_free(tt);
2419     #endif
2420    
2421     // also save full text into "exit_label" --------------
2422     if (ret->way.exit_label)
2423     {
2424     g_free(ret->way.exit_label);
2425     }
2426     ret->way.exit_label = map_convert_string(sitem->map, destination_raw);
2427     // also save full text into "exit_label" --------------
2428    
2429     navigation_split_string_to_list_2(&(ret->way), destination_raw, ';', '|');
2430     g_free(destination_raw);
2431     }
2432     // -- NEW 002 --
2433    
2434    
2435 zoff99 41 // ret->way.angle2 = road_angle_accurate(&c[0], &c[1], 0); // angle at start of way
2436     // ret->angle_end = road_angle_accurate(&c[i - 1], &c[i], 0); // angle at end of way
2437 zoff99 40 ret->way.angle2 = road_angle(&c[0], &c[1], 0); // angle at start of way
2438     ret->angle_end = road_angle(&c[i - 1], &c[i], 0); // angle at end of way
2439    
2440 zoff99 27 ret->start = c[0];
2441     ret->end = c[i];
2442 zoff99 2
2443 zoff99 40 // -- NEW 002 --
2444     /* If we have a ramp check the map for higway_exit info,
2445     * but only on the first node of the ramp.
2446     * Ramps with nodes in reverse order and oneway=-1 are not
2447     * specifically handled, but no occurence known so far either.
2448     * If present, obtain exit_ref, exit_label and exit_to
2449     * from the map.
2450     * exit_to holds info similar to attr_street_destination, and
2451     * we place it in way.s_destination as well, unless the street_destination info
2452     * is already present. In the future it will have to be skipped if destiantion:lanes
2453     * info exists as well.
2454     *
2455     * Now it still holds a bug, if a ramp splits in 2, the exit_to info can end up on
2456     * both continuations of the ramp. Maybe this can be solved by passing the struct
2457     * navigation_maneuver up to here to help decide on exit_to.
2458     *
2459     */
2460    
2461 zoff99 41 if (item_is_ramp(*sitem)) /* hier motorway_link en trunk_link toevoegen */
2462 zoff99 40 {
2463     struct map_selection mselexit;
2464     struct item *rampitem;
2465     struct map_rect *mr2;
2466     struct coord exitcoord;
2467    
2468     mselexit.next = NULL;
2469     mselexit.u.c_rect.lu = c[0];
2470     mselexit.u.c_rect.rl = c[0];
2471     mselexit.range = item_range_all;
2472     mselexit.order = 18;
2473    
2474     mr2 = map_rect_new(tmap, &mselexit);
2475    
2476     while ((rampitem = map_rect_get_item(mr2)))
2477     {
2478     if (rampitem->type == type_highway_exit && item_coord_get(rampitem, &exitcoord, 1)
2479     && exitcoord.x == c[0].x && exitcoord.y == c[0].y)
2480     {
2481     while (item_attr_get(rampitem, attr_any, &attr))
2482     {
2483     if (attr.type && attr.type == attr_label)
2484     {
2485     #ifdef NAVIT_ROUTING_DEBUG_PRINT
2486     dbg(0,"DEST::exit_label=%s\n",attr.u.str);
2487     #endif
2488     if (ret->way.exit_label)
2489     {
2490     g_free(ret->way.exit_label);
2491     }
2492     ret->way.exit_label = map_convert_string(sitem->map,attr.u.str);
2493    
2494     #ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
2495     char *tt = g_strdup_printf("exit_label:%s", attr.u.str);
2496     route_add_to_freetext_list(&c[0], tt);
2497     g_free(tt);
2498     #endif
2499    
2500     }
2501    
2502     if (attr.type == attr_ref)
2503     {
2504     #ifdef NAVIT_ROUTING_DEBUG_PRINT
2505     dbg(0,"DEST::exit_ref=%s\n",attr.u.str);
2506     #endif
2507     if (ret->way.exit_ref)
2508     {
2509     g_free(ret->way.exit_ref);
2510     }
2511     ret->way.exit_ref = map_convert_string(sitem->map,attr.u.str);
2512    
2513     #ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
2514     char *tt = g_strdup_printf("exit_ref:%s", attr.u.str);
2515     route_add_to_freetext_list(&c[0], tt);
2516     g_free(tt);
2517     #endif
2518    
2519     }
2520    
2521     if (attr.type == attr_exit_to)
2522     {
2523     if (attr.u.str && !ret->way.s_destination)
2524     {
2525     char *destination_raw;
2526     destination_raw = map_convert_string(sitem->map,attr.u.str);
2527     #ifdef NAVIT_ROUTING_DEBUG_PRINT
2528     dbg(0,"DEST::destination_raw from exit_to =%s\n",destination_raw);
2529     #endif
2530    
2531     // also save full text into "exit_label" --------------
2532     if (ret->way.exit_label)
2533     {
2534     g_free(ret->way.exit_label);
2535     }
2536     ret->way.exit_label = map_convert_string(sitem->map, destination_raw);
2537     // also save full text into "exit_label" --------------
2538    
2539     #ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
2540     char *tt = g_strdup_printf("exit_to:%s", destination_raw);
2541     route_add_to_freetext_list(&c[0], tt);
2542     g_free(tt);
2543     #endif
2544    
2545     if ((navigation_split_string_to_list(&(ret->way),destination_raw, ';')) < 2)
2546     {
2547     /*
2548     * if a first try did not result in an actual splitting
2549     * retry with ',' as a separator
2550     *
2551     * */
2552     navigation_split_string_to_list(&(ret->way),destination_raw, ',');
2553     }
2554     g_free(destination_raw);
2555     }
2556     }
2557     }
2558     }
2559     }
2560    
2561     if (mr2)
2562     {
2563     map_rect_destroy(mr2);
2564     }
2565     }
2566     // -- NEW 002 --
2567    
2568    
2569    
2570    
2571    
2572    
2573    
2574    
2575    
2576    
2577    
2578    
2579 zoff99 2 item_attr_get(ritem, attr_route, &route_attr);
2580     graph_map = route_get_graph_map(route_attr.u.route);
2581 zoff99 27 if (check_roundabout(ret, graph_map))
2582     {
2583 zoff99 34 ret->way.flags |= NAVIT_AF_ROUNDABOUT;
2584 zoff99 2 }
2585    
2586 zoff99 27 // dbg(1, "i=%d start %d end %d '%s' '%s'\n", i, ret->way.angle2, ret->angle_end, ret->way.name1, ret->way.name2);
2587 zoff99 2 map_rect_destroy(mr);
2588 zoff99 27 }
2589     else
2590     {
2591 zoff99 2 if (this_->last)
2592 zoff99 40 {
2593 zoff99 27 ret->start = ret->end = this_->last->end;
2594 zoff99 40 }
2595 zoff99 2 }
2596 zoff99 40
2597 zoff99 27 if (!this_->first)
2598 zoff99 40 {
2599 zoff99 27 this_->first = ret;
2600 zoff99 40 }
2601    
2602 zoff99 27 if (this_->last)
2603     {
2604     this_->last->next = ret;
2605     ret->prev = this_->last;
2606     if (graph_map)
2607     {
2608     navigation_itm_ways_update(ret, graph_map);
2609 zoff99 2 }
2610     }
2611 zoff99 27 //dbg(1, "ret=%p\n", ret);
2612     this_->last = ret;
2613 zoff99 2 return ret;
2614     }
2615    
2616     /**
2617     * @brief Counts how many times a driver could turn right/left
2618     *
2619     * This function counts how many times the driver theoretically could
2620     * turn right/left between two navigation items, not counting the final
2621     * turn itself.
2622     *
2623     * @param from The navigation item which should form the start
2624     * @param to The navigation item which should form the end
2625     * @param direction Set to < 0 to count turns to the left >= 0 for turns to the right
2626     * @return The number of possibilities to turn or -1 on error
2627     */
2628 zoff99 30 static int count_possible_turns(struct navigation *nav, struct navigation_itm *from, struct navigation_itm *to, int direction)
2629 zoff99 2 {
2630     int count;
2631     struct navigation_itm *curr;
2632     struct navigation_way *w;
2633    
2634 zoff99 40 if (direction == 0)
2635     {
2636     // we are going straight!!
2637     return -1;
2638     }
2639    
2640 zoff99 2 count = 0;
2641     curr = from->next;
2642 zoff99 40
2643     int cur_next_is_lower_level_street = navigation_is_low_level_street(to->way.item.type);
2644    
2645 zoff99 27 while (curr && (curr != to))
2646     {
2647 zoff99 2 w = curr->way.next;
2648    
2649 zoff99 27 while (w)
2650     {
2651     if (is_way_allowed(nav, w, 4))
2652     {
2653 zoff99 40
2654     // dont count lower level streets, if next turn is NOT also a lower level street
2655     if ((cur_next_is_lower_level_street == 1) || (navigation_is_low_level_street(w->item.type) == 0))
2656 zoff99 27 {
2657 zoff99 40 if (direction < 0)
2658 zoff99 27 {
2659 zoff99 40 if (angle_delta(curr->prev->angle_end, w->angle2) < 0)
2660     {
2661     count++;
2662 zoff99 48
2663     #ifdef NAVIT_DEBUG_COORD_DIE2TE_LIST
2664     // ------- DEBUG ---------
2665     // ------- DEBUG ---------
2666     // ------- DEBUG ---------
2667     if ((global_debug_coord_list_items + 2) > MAX_DEBUG_COORDS)
2668     {
2669     global_debug_coord_list_items = 0;
2670     }
2671    
2672     struct coord c2[5];
2673    
2674     if (navigation_get_real_item_first_coord(w, c2))
2675     {
2676     global_debug_coord_list[global_debug_coord_list_items].x = c2[0].x;
2677     global_debug_coord_list[global_debug_coord_list_items].y = c2[0].y;
2678     global_debug_coord_list_items++;
2679     global_debug_coord_list[global_debug_coord_list_items].x = c2[1].x;
2680     global_debug_coord_list[global_debug_coord_list_items].y = c2[1].y;
2681     global_debug_coord_list_items++;
2682     }
2683     // ------- DEBUG ---------
2684     // ------- DEBUG ---------
2685     // ------- DEBUG ---------
2686     #endif
2687    
2688    
2689 zoff99 40 break;
2690     }
2691 zoff99 2 }
2692 zoff99 40 else if (direction > 0)
2693 zoff99 27 {
2694 zoff99 40 if (angle_delta(curr->prev->angle_end, w->angle2) > 0)
2695     {
2696     count++;
2697 zoff99 48 #ifdef NAVIT_DEBUG_COORD_DIE2TE_LIST
2698     // ------- DEBUG ---------
2699     // ------- DEBUG ---------
2700     // ------- DEBUG ---------
2701     if ((global_debug_coord_list_items + 2) > MAX_DEBUG_COORDS)
2702     {
2703     global_debug_coord_list_items = 0;
2704     }
2705    
2706     struct coord c2[5];
2707    
2708     if (navigation_get_real_item_first_coord(w, c2))
2709     {
2710     global_debug_coord_list[global_debug_coord_list_items].x = c2[0].x;
2711     global_debug_coord_list[global_debug_coord_list_items].y = c2[0].y;
2712     global_debug_coord_list_items++;
2713     global_debug_coord_list[global_debug_coord_list_items].x = c2[1].x;
2714     global_debug_coord_list[global_debug_coord_list_items].y = c2[1].y;
2715     global_debug_coord_list_items++;
2716     }
2717     // ------- DEBUG ---------
2718     // ------- DEBUG ---------
2719     // ------- DEBUG ---------
2720     #endif
2721    
2722 zoff99 40 break;
2723     }
2724 zoff99 27 }
2725 zoff99 2 }
2726     }
2727     w = w->next;
2728     }
2729     curr = curr->next;
2730     }
2731    
2732 zoff99 27 if (!curr)
2733 zoff99 40 {
2734     // from does not lead to to?
2735 zoff99 2 return -1;
2736     }
2737    
2738     return count;
2739     }
2740    
2741     /**
2742     * @brief Calculates distance and time to the destination
2743     *
2744     * This function calculates the distance and the time to the destination of a
2745     * navigation. If incr is set, this is only calculated for the first navigation
2746     * item, which is a lot faster than re-calculation the whole destination, but works
2747     * only if the rest of the navigation already has been calculated.
2748     *
2749     * @param this_ The navigation whose destination / time should be calculated
2750     * @param incr Set this to true to only calculate the first item. See description.
2751     */
2752 zoff99 27 static void calculate_dest_distance(struct navigation *this_, int incr)
2753 zoff99 2 {
2754 zoff99 27 int len = 0, time = 0, count = 0;
2755 zoff99 41 struct navigation_itm *next = NULL;
2756     struct navigation_itm *itm = this_->last;
2757    
2758 zoff99 27 //dbg(1, "enter this_=%p, incr=%d\n", this_, incr);
2759 zoff99 41
2760 zoff99 27 if (incr)
2761     {
2762     if (itm)
2763     {
2764     //dbg(2, "old values: (%p) time=%d lenght=%d\n", itm,
2765     // itm->dest_length, itm->dest_time);
2766 zoff99 2 }
2767 zoff99 27 else
2768     {
2769     //dbg(2, "old values: itm is null\n");
2770     }
2771     itm = this_->first;
2772     next = itm->next;
2773     //dbg(2, "itm values: time=%d lenght=%d\n", itm->length, itm->time);
2774     //dbg(2, "next values: (%p) time=%d lenght=%d\n", next, next->dest_length, next->dest_time);
2775     itm->dest_length = next->dest_length + itm->length;
2776     itm->dest_count = next->dest_count + 1;
2777     itm->dest_time = next->dest_time + itm->time;
2778     //dbg(2, "new values: time=%d lenght=%d\n", itm->dest_length, itm->dest_time);
2779 zoff99 2 return;
2780     }
2781 zoff99 40
2782 zoff99 27 while (itm)
2783     {
2784     len += itm->length;
2785     time += itm->time;
2786     itm->dest_length = len;
2787     itm->dest_time = time;
2788     itm->dest_count = count++;
2789     itm = itm->prev;
2790 zoff99 2 }
2791 zoff99 27 //dbg(1, "len %d time %d\n", len, time);
2792 zoff99 2 }
2793    
2794     /**
2795 zoff99 41 *
2796     * check it w1 is the same as w2 (duplicate way)
2797     *
2798     * @param w1 The first way to be checked
2799     * @param w2 The second way to be checked
2800     * @return 0 -> no, 1 -> yes:it's the same way
2801     *
2802     */
2803     static int is_maybe_same_item(struct navigation_way *w1, struct navigation_way *w2, int reverse_match)
2804     {
2805    
2806     dbg(0, "======================================\n");
2807    
2808     dbg(0, "w1=%p w2=%p\n", w1, w2);
2809    
2810     dbg(0, "w1 type=%s w2 type=%s\n", item_to_name(w1->item.type), item_to_name(w2->item.type));
2811     dbg(0, "w1 dir=%d w2 dir=%d\n", w1->dir, w2->dir);
2812     dbg(0, "w1 angle2=%d w2 angle2=%d\n", w1->angle2, w2->angle2);
2813     dbg(0, "w1 n1=%s w2 n1=%s\n", w1->name1, w2->name1);
2814     dbg(0, "w1 n2=%s w2 n2=%s\n", w1->name2, w2->name2);
2815    
2816     #ifdef NAVIT_NAVIGATION_REMOVE_DUPL_WAYS
2817    
2818     int dir_reverse = 0;
2819    
2820     if (w1->item.type != w2->item.type)
2821     {
2822     dbg(0, "x:w1 type=%s w2 type=%s\n", item_to_name(w1->item.type), item_to_name(w2->item.type));
2823     return 0;
2824     }
2825    
2826     #if 0
2827     if (w1->dir != w2->dir)
2828     {
2829     dir_reverse = 1;
2830     }
2831     #endif
2832    
2833     if (reverse_match != 0)
2834     {
2835     dir_reverse = 1 - dir_reverse; // toggle "dir_reverse"
2836     }
2837    
2838     if (dir_reverse == 0)
2839     {
2840     if ((abs(w1->angle2 - w2->angle2) != 0) && (abs(w1->angle2 - w2->angle2) != 360))
2841     {
2842     dbg(0, "x:000:w1 angle2=%d w2 angle2=%d\n", w1->angle2, w2->angle2);
2843     return 0;
2844     }
2845     }
2846     else
2847     {
2848     if (abs(w1->angle2 - w2->angle2) != 180)
2849     {
2850     dbg(0, "x:180:w1 angle2=%d w2 angle2=%d\n", w1->angle2, w2->angle2);
2851     return 0;
2852     }
2853     }
2854    
2855    
2856     if ((w1->name1 == NULL) && (w2->name1 == NULL))
2857     {
2858     }
2859     else
2860     {
2861     if ((w1->name1 == NULL) || (w2->name1 == NULL))
2862     {
2863     return 0;
2864     }
2865     else if (strcmp(w1->name1, w2->name1) != 0)
2866     {
2867     dbg(0, "x:w1 n1=%s w2 n1=%s\n", w1->name1, w2->name1);
2868     return 0;
2869     }
2870     }
2871    
2872     if ((w1->name2 == NULL) && (w2->name2 == NULL))
2873     {
2874     }
2875     else
2876     {
2877     if ((w1->name2 == NULL) || (w2->name2 == NULL))
2878     {
2879     return 0;
2880     }
2881     else if (strcmp(w1->name2, w2->name2) != 0)
2882     {
2883     dbg(0, "x:w1 n2=%s w2 n2=%s\n", w1->name2, w2->name2);
2884     return 0;
2885     }
2886     }
2887    
2888     return 1;
2889    
2890     #else
2891    
2892     return 0;
2893    
2894     #endif
2895    
2896     }
2897    
2898     /**
2899 zoff99 2 * @brief Checks if two navigation items are on the same street
2900     *
2901     * This function checks if two navigation items are on the same street. It returns
2902     * true if either their name or their "systematic name" (e.g. "A6" or "B256") are the
2903     * same.
2904     *
2905     * @param old The first item to be checked
2906     * @param new The second item to be checked
2907     * @return True if both old and new are on the same street
2908     */
2909 zoff99 30 static int is_same_street2(char *old_name1, char *old_name2, char *new_name1, char *new_name2)
2910 zoff99 2 {
2911 zoff99 40 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
2912     {
2913     // always return false when in bicycle mode
2914     return 0;
2915     }
2916    
2917 zoff99 27 if (old_name1 && new_name1 && !strcmp(old_name1, new_name1))
2918     {
2919     // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' yes (1.)\n", old_name2, new_name2, old_name1, new_name1);
2920 zoff99 2 return 1;
2921     }
2922 zoff99 40
2923 zoff99 27 if (old_name2 && new_name2 && !strcmp(old_name2, new_name2))
2924     {
2925     // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' yes (2.)\n", old_name2, new_name2, old_name1, new_name1);
2926 zoff99 2 return 1;
2927     }
2928 zoff99 40
2929 zoff99 27 // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' no\n", old_name2, new_name2, old_name1, new_name1);
2930 zoff99 2 return 0;
2931     }
2932    
2933     #if 0
2934     /**
2935     * @brief Checks if two navigation items are on the same street
2936     *
2937     * This function checks if two navigation items are on the same street. It returns
2938     * true if the first part of their "systematic name" is equal. If the "systematic name" is
2939     * for example "A352/E3" (a german highway which at the same time is part of the international
2940     * E-road network), it would only search for "A352" in the second item's systematic name.
2941     *
2942     * @param old The first item to be checked
2943     * @param new The second item to be checked
2944     * @return True if the "systematic name" of both items matches. See description.
2945     */
2946     static int
2947     is_same_street_systematic(struct navigation_itm *old, struct navigation_itm *new)
2948     {
2949     int slashold,slashnew;
2950     if (!old->name2 || !new->name2)
2951 zoff99 27 return 1;
2952 zoff99 2 slashold=strcspn(old->name2, "/");
2953     slashnew=strcspn(new->name2, "/");
2954     if (slashold != slashnew || strncmp(old->name2, new->name2, slashold))
2955 zoff99 27 return 0;
2956 zoff99 2 return 1;
2957     }
2958    
2959     /**
2960     * @brief Check if there are multiple possibilities to drive from old
2961     *
2962     * This function checks, if there are multiple streets connected to the exit of "old".
2963     * Sometimes it happens that an item on a map is just segmented, without any other streets
2964     * being connected there, and it is not useful if navit creates a maneuver there.
2965     *
2966     * @param new The navigation item we're driving to
2967     * @return True if there are multiple streets
2968     */
2969 zoff99 27 static int
2970 zoff99 2 maneuver_multiple_streets(struct navigation_itm *new)
2971     {
2972 zoff99 27 if (new->way.next)
2973     {
2974 zoff99 2 return 1;
2975 zoff99 27 }
2976     else
2977     {
2978 zoff99 2 return 0;
2979     }
2980     }
2981    
2982     /**
2983     * @brief Check if the new item is entered "straight"
2984     *
2985     * This function checks if the new item is entered "straight" from the old item, i.e. if there
2986     * is no other street one could take from the old item on with less steering.
2987     *
2988     * @param new The navigation item we're driving to
2989     * @param diff The absolute angle one needs to steer to drive to this item
2990     * @return True if the new item is entered "straight"
2991     */
2992 zoff99 27 static int
2993 zoff99 2 maneuver_straight(struct navigation_itm *new, int diff)
2994     {
2995     int curr_diff;
2996     struct navigation_way *w;
2997    
2998     w = new->way.next;
2999     dbg(1,"diff=%d\n", diff);
3000 zoff99 27 while (w)
3001     {
3002 zoff99 2 curr_diff=abs(angle_delta(new->prev->angle_end, w->angle2));
3003     dbg(1,"curr_diff=%d\n", curr_diff);
3004 zoff99 27 if (curr_diff < diff)
3005     {
3006 zoff99 2 return 0;
3007     }
3008     w = w->next;
3009     }
3010     return 1;
3011     }
3012     #endif
3013    
3014     static int maneuver_category(enum item_type type)
3015     {
3016 zoff99 40 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
3017 zoff99 27 {
3018 zoff99 40 switch (type)
3019     {
3020     case type_cycleway:
3021     return 1;
3022     case type_footway:
3023     return 1;
3024     case type_street_service:
3025     return 1;
3026     case type_street_parking_lane:
3027     return 1;
3028     case type_living_street:
3029     return 1;
3030     case type_street_0:
3031     return 1;
3032     case type_street_1_city:
3033     return 2;
3034     case type_street_2_city:
3035 zoff99 41 case type_ramp_street_2_city:
3036 zoff99 40 return 3;
3037     case type_street_3_city:
3038 zoff99 41 case type_ramp_street_3_city:
3039 zoff99 40 return 4;
3040     case type_street_4_city:
3041 zoff99 41 case type_ramp_street_4_city:
3042 zoff99 40 return 5;
3043     case type_highway_city:
3044     return 7;
3045     case type_street_1_land:
3046     return 2;
3047     case type_street_2_land:
3048     return 3;
3049     case type_street_3_land:
3050     return 4;
3051     case type_street_4_land:
3052     return 5;
3053     case type_street_n_lanes:
3054     return 6;
3055 zoff99 46 case type_ramp_highway_land:
3056     return 6;
3057 zoff99 40 case type_highway_land:
3058     return 7;
3059 zoff99 41 //case type_ramp:
3060     // return 0;
3061 zoff99 40 case type_roundabout:
3062     return 0;
3063     case type_ferry:
3064     return 0;
3065     default:
3066     return 0;
3067     }
3068 zoff99 2 }
3069 zoff99 46 else // car mode ---------------
3070 zoff99 40 {
3071     switch (type)
3072     {
3073     case type_street_0:
3074     return 1;
3075     case type_street_1_city:
3076     return 2;
3077     case type_street_2_city:
3078 zoff99 41 case type_ramp_street_2_city:
3079 zoff99 40 return 3;
3080     case type_street_3_city:
3081 zoff99 41 case type_ramp_street_3_city:
3082 zoff99 40 return 4;
3083     case type_street_4_city:
3084 zoff99 41 case type_ramp_street_4_city:
3085 zoff99 40 return 5;
3086     case type_highway_city:
3087     return 7;
3088     case type_street_1_land:
3089     return 2;
3090     case type_street_2_land:
3091     return 3;
3092     case type_street_3_land:
3093     return 4;
3094     case type_street_4_land:
3095     return 5;
3096     case type_street_n_lanes:
3097     return 6;
3098 zoff99 46 case type_ramp_highway_land:
3099     return 6;
3100 zoff99 40 case type_highway_land:
3101     return 7;
3102 zoff99 41 //case type_ramp:
3103     // return 0;
3104     case type_roundabout:
3105 zoff99 40 return 0;
3106 zoff99 41 case type_ferry:
3107     return 0;
3108     default:
3109     return 0;
3110     }
3111     }
3112     }
3113    
3114    
3115    
3116    
3117    
3118     static int maneuver_category_calc2(enum item_type type)
3119     {
3120     if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
3121     {
3122     switch (type)
3123     {
3124     case type_cycleway:
3125     return 1;
3126     case type_footway:
3127     return 1;
3128     case type_street_service:
3129     return 1;
3130     case type_street_parking_lane:
3131     return 1;
3132     case type_living_street:
3133     return 1;
3134     case type_street_0:
3135     return 1;
3136     case type_street_1_city:
3137     return 2;
3138     case type_street_2_city:
3139     case type_ramp_street_2_city:
3140     return 3;
3141     case type_street_3_city:
3142     case type_ramp_street_3_city:
3143     return 4;
3144     case type_street_4_city:
3145     case type_ramp_street_4_city:
3146     return 5;
3147     case type_highway_city:
3148     return 7;
3149     case type_street_1_land:
3150     return 2;
3151     case type_street_2_land:
3152     return 3;
3153     case type_street_3_land:
3154     return 4;
3155     case type_street_4_land:
3156     return 5;
3157     case type_street_n_lanes:
3158     return 6;
3159 zoff99 46 case type_ramp_highway_land:
3160     return 6;
3161 zoff99 41 case type_highway_land:
3162     return 7;
3163     //case type_ramp:
3164     // return 0;
3165 zoff99 40 case type_roundabout:
3166     return 0;
3167     case type_ferry:
3168     return 0;
3169     default:
3170     return 0;
3171     }
3172     }
3173 zoff99 41 else
3174     {
3175     switch (type)
3176     {
3177     case type_street_0:
3178     return 1;
3179     case type_street_1_city:
3180     return 1;
3181     case type_street_2_city:
3182     case type_ramp_street_2_city:
3183     return 4;
3184     case type_street_3_city:
3185     case type_ramp_street_3_city:
3186     return 4;
3187     case type_street_4_city:
3188     case type_ramp_street_4_city:
3189     return 4;
3190     case type_highway_city:
3191     return 7;
3192     case type_street_1_land:
3193     return 1;
3194     case type_street_2_land:
3195     return 4;
3196     case type_street_3_land:
3197     return 4;
3198     case type_street_4_land:
3199     return 4;
3200     case type_street_n_lanes:
3201     return 6;
3202 zoff99 46 case type_ramp_highway_land:
3203     return 6;
3204 zoff99 41 case type_highway_land:
3205     return 7;
3206     //case type_ramp: // ramp need to be high enough
3207     // return 4;
3208     case type_roundabout:
3209     return 0;
3210     case type_ferry:
3211     return 0;
3212     default:
3213     return 0;
3214     }
3215     }
3216 zoff99 2 }
3217    
3218 zoff99 41
3219    
3220    
3221    
3222    
3223    
3224    
3225    
3226    
3227 zoff99 30 static int is_way_allowed(struct navigation *nav, struct navigation_way *way, int mode)
3228 zoff99 2 {
3229     if (!nav->vehicleprofile)
3230 zoff99 27 {
3231 zoff99 2 return 1;
3232 zoff99 27 }
3233 zoff99 40
3234     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);
3235 zoff99 2 }
3236    
3237     /**
3238 zoff99 40 * @brief Checks if navit has to create a maneuver to drive from old to new (run only once!!)
3239 zoff99 2 *
3240     * This function checks if it has to create a "maneuver" - i.e. guide the user - to drive
3241     * from "old" to "new".
3242     *
3243     * @param old The old navigation item, where we're coming from
3244     * @param new The new navigation item, where we're going to
3245     * @param delta The angle the user has to steer to navigate from old to new
3246     * @param reason A text string explaining how the return value resulted
3247     * @return True if navit should guide the user, false otherwise
3248     */
3249 zoff99 41 static int maneuver_required2(struct navigation *nav, struct navigation_itm *old, struct navigation_itm *new, int *delta, int *delta_real, char **reason)
3250 zoff99 2 {
3251 zoff99 27 int ret = 0, d, dw, dlim;
3252     char *r = NULL;
3253 zoff99 41 struct navigation_way *w = NULL;
3254 zoff99 30 int cat, ncat, wcat, maxcat, left = -180, right = 180, is_unambigous = 0, is_same_street;
3255 zoff99 41 int cat_2 = 0;
3256     int ncat_2 = 0;
3257     int highest_other_cat = 0;
3258     int original_d = 0;
3259 zoff99 2
3260 zoff99 41 dbg(0, "STRAI:000:\n");
3261     dbg(0, "STRAI:000:======================================\n");
3262    
3263     // ---------------------------
3264     //
3265     // HINT: angle < 0 --> left
3266     // > 0 --> right
3267     // = 0 --> straight
3268     //
3269     // ---------------------------
3270    
3271 zoff99 27 d = angle_delta(old->angle_end, new->way.angle2);
3272 zoff99 41 original_d = d;
3273 zoff99 40
3274     //long long wayid_old = navigation_item_get_wayid(&(old->way));
3275     //long long wayid_new = navigation_item_get_wayid(&(new->way));
3276     //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);
3277    
3278 zoff99 41 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)) // bicycle mode
3279 zoff99 27 {
3280 zoff99 40 int flags_old = navigation_item_get_flags(&(old->way));
3281     int flags_new = navigation_item_get_flags(&(new->way));
3282    
3283     //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);
3284     //dbg(0, "(b2)old flags=%x new flags=%x\n", (flags_old & NAVIT_AF_ONEWAY), (flags_new & NAVIT_AF_ONEWAY));
3285     //dbg(0, "(b3)old flags=%x new flags=%x\n", (flags_old & NAVIT_AF_ONEWAYREV), (flags_new & NAVIT_AF_ONEWAYREV));
3286    
3287     if ((old->way.dir == 1) && ((new->way.dir == -1) && (new->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)))
3288     {
3289     r = "yes: bicycle starts going against oneway here (1)";
3290     ret = 1;
3291     //dbg(0, "%s\n", r);
3292     }
3293     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)))
3294     {
3295     r = "yes: bicycle starts going against oneway here (2)";
3296     ret = 1;
3297     //dbg(0, "%s\n", r);
3298     }
3299 zoff99 27 }
3300 zoff99 40
3301    
3302    
3303    
3304     // z2z2
3305     int have_more_than_one_way_to_turn = 0;
3306 zoff99 41 int have_more_than_one_way_to_turn_cycleways = 0;
3307 zoff99 40 struct navigation_way *w22;
3308     w22 = new->way.next;
3309     int new_angle_abs = 999;
3310     int new_angle_abs_min = 999;
3311 zoff99 41 int new_angle_abs_min_allowed = 999;
3312     int new_angle_real = 999;
3313     int new_angle_min_allowed = 999;
3314     int new_angle_abs_min_ramp_allowed = 999;
3315 zoff99 40 int old_angle_abs = abs(d);
3316 zoff99 41 int new_angle_closest_to_cur = 999;
3317 zoff99 46 int no_correction = 0;
3318 zoff99 40
3319 zoff99 46 dbg(0, "STRAI:001:d=%d original_d=%d\n", old_angle_abs, original_d);
3320 zoff99 40
3321     while (w22)
3322 zoff99 27 {
3323 zoff99 40
3324     dbg(0, "STRAI:002\n");
3325    
3326     //if ((w22->dir == -1) && (w22->flags & NAVIT_AF_ONEWAY))
3327     //{
3328     // // against oneway not allowed
3329     //}
3330 zoff99 41 if (((global_vehicle_profile != 1) && (global_vehicle_profile != 2)) // NOT bicycle mode
3331 zoff99 40 && (navigation_is_low_level_street(old->way.item.type) == 0)
3332     && (navigation_is_low_level_street(new->way.item.type) == 0)
3333     && (navigation_is_low_level_street(w22->item.type) == 1))
3334     {
3335     // dont count "lower" streets when not on "lower" street now or next
3336     }
3337     else
3338     {
3339 zoff99 41
3340     if ( (is_maybe_same_item(&(new->way), w22, 0) == 0) && (is_maybe_same_item(&(old->way), w22, 1) == 0) )
3341 zoff99 40 {
3342    
3343 zoff99 41 new_angle_real = angle_delta(old->angle_end, w22->angle2);
3344     new_angle_abs = abs(new_angle_real);
3345     if (new_angle_abs < new_angle_abs_min)
3346     {
3347     new_angle_abs_min = new_angle_abs;
3348     }
3349 zoff99 40
3350 zoff99 41 if (is_way_allowed(nav, w22, 1))
3351     {
3352     have_more_than_one_way_to_turn = 1;
3353 zoff99 40
3354 zoff99 41 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)) // bicycle mode
3355     {
3356     if (w22->item.type == type_cycleway)
3357     {
3358     have_more_than_one_way_to_turn_cycleways = 1;
3359     }
3360     }
3361    
3362     if (maneuver_category_calc2(w22->item.type) > highest_other_cat)
3363     {
3364     highest_other_cat = maneuver_category_calc2(w22->item.type);
3365     }
3366    
3367     if (item_is_ramp(w22->item))
3368     {
3369     if (new_angle_abs < new_angle_abs_min_ramp_allowed)
3370     {
3371     new_angle_abs_min_ramp_allowed = new_angle_abs;
3372     }
3373     }
3374    
3375     if (abs(new_angle_real - d) < abs(new_angle_closest_to_cur))
3376     {
3377     new_angle_closest_to_cur = new_angle_real;
3378     }
3379    
3380     if (new_angle_abs < new_angle_abs_min_allowed)
3381     {
3382     new_angle_abs_min_allowed = new_angle_abs;
3383     new_angle_min_allowed = new_angle_real;
3384     }
3385     }
3386    
3387     dbg(0, "STRAI:003:new angle abs=%d min_allowed=%d have_more_than_one_way_to_turn=%d new_angle_closest_to_cur=%d d=%d\n", new_angle_abs, new_angle_abs_min_allowed, have_more_than_one_way_to_turn, new_angle_closest_to_cur, d);
3388    
3389 zoff99 40 }
3390     }
3391     w22 = w22->next;
3392 zoff99 2 }
3393 zoff99 40
3394 zoff99 41 dbg(0, "STRAI:004 new_angle_abs_min=%d new_angle_abs_min_allowed=%d\n", new_angle_abs_min, new_angle_abs_min_allowed);
3395 zoff99 40
3396 zoff99 41 if ((new_angle_abs_min_allowed > ROAD_ANGLE_IS_STRAIGHT_ABS) && (old_angle_abs <= ROAD_ANGLE_IS_STRAIGHT_ABS))
3397 zoff99 40 {
3398 zoff99 41 dbg(0, "STRAI:005 new_abs=%d old_abs=%d\n", new_angle_abs_min_allowed, old_angle_abs);
3399 zoff99 40
3400     // we want to drive almost straight, set angle to "0"
3401     d = 0;
3402     }
3403    
3404     dbg(0, "STRAI:005a:d=%d\n", d);
3405    
3406 zoff99 27 if (!r)
3407     {
3408 zoff99 40 if (have_more_than_one_way_to_turn == 1) // more than 1 possibility
3409     {
3410     if (new->way.exit_label)
3411     {
3412 zoff99 41 // highway to highway, nearest ramp is more than 15° angle turn
3413 zoff99 46 if ( (cat > 6) && (ncat > 6) && (highest_other_cat <= 6) && (abs(d) < 12) && (new_angle_abs_min_ramp_allowed > 15) )
3414 zoff99 41 {
3415     dbg(0, "STRAI:005a:d=%d\n", d);
3416     r = "no: driving almost straight on highway and no other highway possibilities (1)";
3417     }
3418     else
3419     {
3420 zoff99 46 // r = "yes: we have an exit-sign to tell the user";
3421     // ret = 1;
3422 zoff99 41 }
3423 zoff99 40 }
3424     else if (new->way.s_destination)
3425     {
3426 zoff99 46 if ( (cat > 6) && (ncat > 6) && (highest_other_cat <= 6) && (abs(d) < 12) && (new_angle_abs_min_ramp_allowed > 15) )
3427 zoff99 41 {
3428     dbg(0, "STRAI:005a:d=%d\n", d);
3429     r = "no: driving almost straight on highway and no other highway possibilities (2)";
3430     }
3431     else
3432     {
3433 zoff99 46 // r = "yes: we have a road-sign to tell the user";
3434     // ret = 1;
3435 zoff99 41 }
3436 zoff99 40 }
3437 zoff99 41 else if (item_is_ramp(old->way.item))
3438 zoff99 40 {
3439     r = "yes: we are currently on a ramp and have more than 1 road to take";
3440     ret = 1;
3441     }
3442     }
3443     }
3444    
3445    
3446     if ((global_vehicle_profile != 1) && (global_vehicle_profile != 2))
3447     {
3448     if (!new->way.next)
3449     {
3450     /* No announcement necessary */
3451     r = "no: Only one possibility";
3452     }
3453 zoff99 41 else if (!new->way.next->next && item_is_ramp(new->way.next->item) && !is_way_allowed(nav, new->way.next, 1))
3454 zoff99 40 {
3455     /* If the other way is only a ramp and it is one-way in the wrong direction, no announcement necessary */
3456     r = "no: Only ramp";
3457     }
3458     }
3459 zoff99 41 else // bicycle mode --------------------
3460 zoff99 40 {
3461     if (!r)
3462     {
3463     #if 0
3464     if ((!new->way.next) && (abs(d) < 20))
3465     {
3466     /* No announcement necessary */
3467     r = "no: Only one possibility and less than 20° turn";
3468     dbg(0, "%s\n", r);
3469     }
3470     else
3471     {
3472     if (abs(d) > 2)
3473     {
3474     r = "yes: bicycle mode";
3475     dbg(0, "%s\n", r);
3476     ret = 1;
3477     }
3478     else
3479     {
3480     r = "no: less than 3° turn";
3481     dbg(0, "%s\n", r);
3482     }
3483     }
3484     #endif
3485    
3486     #if 0
3487     if (!new->way.next)
3488     {
3489     /* No announcement necessary */
3490     r = "no: Only one possibility";
3491     }
3492     #endif
3493    
3494     #if 1
3495 zoff99 41
3496     if ((old->way.item.type == type_cycleway) && (new->way.item.type == type_cycleway))
3497 zoff99 40 {
3498 zoff99 41 if (have_more_than_one_way_to_turn_cycleways == 0)
3499 zoff99 40 {
3500 zoff99 41 if (abs(d) > ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE_CYC_2_CYC)
3501     {
3502     r = "yes: delta over ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE_CYC_2_CYC in bicycle mode (Only one possibility cyc-2-cyc)";
3503     //dbg(0, "%s\n", r);
3504     ret = 1;
3505     }
3506     else
3507     {
3508     r = "no: delta less than ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE_CYC_2_CYC in bicycle mode (Only one possibility cyc-2-cyc)";
3509     //dbg(0, "%s\n", r);
3510     ret = 0;
3511     }
3512 zoff99 40 }
3513     else
3514     {
3515 zoff99 41 if (abs(d) > ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE_CYC_2_CYC__2)
3516     {
3517     r = "yes: delta over ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE_CYC_2_CYC__2 in bicycle mode (cyc-2cyc)";
3518     //dbg(0, "%s\n", r);
3519     ret = 1;
3520     }
3521     else
3522     {
3523     r = "no: delta less than ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE_CYC_2_CYC__2 in bicycle mode (cyc-2cyc)";
3524     //dbg(0, "%s\n", r);
3525     ret = 0;
3526     }
3527 zoff99 40 }
3528     }
3529     else
3530     {
3531 zoff99 41
3532     if (!new->way.next)
3533 zoff99 40 {
3534 zoff99 41 if (abs(d) > ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE)
3535     {
3536     r = "yes: delta over ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE in bicycle mode (Only one possibility)";
3537     //dbg(0, "%s\n", r);
3538     ret = 1;
3539     }
3540     else
3541     {
3542     r = "no: delta less than ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE in bicycle mode (Only one possibility)";
3543     //dbg(0, "%s\n", r);
3544     ret = 0;
3545     }
3546 zoff99 40 }
3547     else
3548     {
3549 zoff99 41 if (abs(d) > ROAD_ANGLE_MIN__FOR_TURN_BICYCLEMODE_ONLY_1_POSSIBILITY)
3550     {
3551     r = "yes: delta over ROAD_ANGLE_MIN__FOR_TURN_BICYCLEMODE_ONLY_1_POSSIBILITY in bicycle mode";
3552     //dbg(0, "%s\n", r);
3553     ret = 1;
3554     }
3555     else
3556     {
3557     r = "no: delta less than ROAD_ANGLE_MIN__FOR_TURN_BICYCLEMODE_ONLY_1_POSSIBILITY in bicycle mode";
3558     //dbg(0, "%s\n", r);
3559     ret = 0;
3560     }
3561 zoff99 40 }
3562 zoff99 41
3563 zoff99 40 }
3564     #endif
3565    
3566     }
3567     }
3568    
3569     if (!r)
3570     {
3571 zoff99 34 if ((old->way.flags & NAVIT_AF_ROUNDABOUT) && !(new->way.flags & NAVIT_AF_ROUNDABOUT))
3572 zoff99 27 {
3573     r = "yes: leaving roundabout";
3574     ret = 1;
3575     }
3576 zoff99 34 else if (!(old->way.flags & NAVIT_AF_ROUNDABOUT) && (new->way.flags & NAVIT_AF_ROUNDABOUT))
3577 zoff99 27 {
3578     r = "no: entering roundabout";
3579     }
3580 zoff99 34 else if ((old->way.flags & NAVIT_AF_ROUNDABOUT) && (new->way.flags & NAVIT_AF_ROUNDABOUT))
3581 zoff99 40 {
3582 zoff99 27 r = "no: staying in roundabout";
3583 zoff99 40 }
3584 zoff99 2 }
3585 zoff99 40
3586     if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
3587 zoff99 27 {
3588 zoff99 40 if (!r && abs(d) > ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE)
3589     {
3590     /* always make an announcement if you have to make a turn */
3591     r = "yes: delta over ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE in bicycle mode";
3592     //dbg(0, "%s\n", r);
3593     ret = 1;
3594     }
3595 zoff99 2 }
3596 zoff99 41 else // car mode ---------------------
3597 zoff99 40 {
3598     if (!r && abs(d) > 75)
3599     {
3600     /* always make an announcement if you have to make a sharp turn */
3601     r = "yes: delta over 75";
3602     ret = 1;
3603     }
3604     }
3605    
3606 zoff99 27 cat = maneuver_category(old->way.item.type);
3607     ncat = maneuver_category(new->way.item.type);
3608 zoff99 40
3609 zoff99 41 cat_2 = maneuver_category_calc2(old->way.item.type);
3610     ncat_2 = maneuver_category_calc2(new->way.item.type);
3611    
3612    
3613 zoff99 27 if (!r)
3614     {
3615 zoff99 2 /* Check whether the street keeps its name */
3616 zoff99 30 is_same_street = is_same_street2(old->way.name1, old->way.name2, new->way.name1, new->way.name2);
3617 zoff99 40
3618     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);
3619    
3620 zoff99 2 w = new->way.next;
3621 zoff99 27 maxcat = -1;
3622     while (w)
3623     {
3624 zoff99 41 if ( (is_maybe_same_item(&(new->way), w, 0) == 0) && (is_maybe_same_item(&(old->way), w, 1) == 0) )
3625     {
3626     dw = angle_delta(old->angle_end, w->angle2);
3627     dbg(0, "STRAI:011.02 dw=%d l=%d r=%d\n", dw, left, right);
3628 zoff99 40
3629 zoff99 41 if (dw < 0)
3630 zoff99 40 {
3631 zoff99 41 if (dw > left)
3632     {
3633     left = dw;
3634     }
3635 zoff99 40 }
3636 zoff99 41 else
3637 zoff99 40 {
3638 zoff99 41 if (dw < right)
3639     {
3640     right = dw;
3641     }
3642 zoff99 40 }
3643    
3644 zoff99 41 wcat = maneuver_category(w->item.type);
3645     dbg(0, "STRAI:011.03 wcat=%d\n", wcat);
3646 zoff99 40
3647 zoff99 41 /* If any other street has the same name [ removed:"but isn't a highway (a highway might split up temporarily)" ], then
3648     we can't use the same name criterium */
3649     // 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))
3650     if (is_same_street && is_same_street2(old->way.name1, old->way.name2, w->name1, w->name2) && is_way_allowed(nav, w, 2))
3651     {
3652     is_same_street = 0;
3653     dbg(0, "STRAI:011.04 is_same_street=%d\n", is_same_street);
3654     }
3655 zoff99 40
3656 zoff99 41 /* Mark if the street has a higher or the same category */
3657     if (wcat > maxcat)
3658     {
3659     maxcat = wcat;
3660     dbg(0, "STRAI:011.06 maxcat=%d wcat=%d\n", maxcat, wcat);
3661     }
3662    
3663 zoff99 40 }
3664    
3665 zoff99 2 w = w->next;
3666     }
3667 zoff99 40
3668     if (have_more_than_one_way_to_turn == 1) // more than 1 possibility
3669     {
3670     /* Even if the ramp has the same name, announce it */
3671 zoff99 41 if (item_is_ramp(new->way.item) && !item_is_ramp(old->way.item))
3672 zoff99 40 {
3673     is_same_street = 0;
3674     dbg(0, "STRAI:011.05.xx is_same_street=%d\n", is_same_street);
3675     }
3676     }
3677    
3678 zoff99 2 /* get the delta limit for checking for other streets. It is lower if the street has no other
3679 zoff99 27 streets of the same or higher category */
3680 zoff99 2 if (ncat < cat)
3681 zoff99 40 {
3682 zoff99 27 dlim = 80;
3683 zoff99 40 }
3684 zoff99 2 else
3685 zoff99 40 {
3686 zoff99 27 dlim = 120;
3687 zoff99 40 }
3688    
3689 zoff99 2 /* if the street is really straight, the others might be closer to straight */
3690     if (abs(d) < 20)
3691 zoff99 40 {
3692 zoff99 27 dlim /= 2;
3693 zoff99 40 }
3694    
3695 zoff99 27 if ((maxcat == ncat && maxcat == cat) || (ncat == 0 && cat == 0))
3696 zoff99 40 {
3697 zoff99 41 dlim = abs(d) * (620 / 256); // abs(d) * 2.4
3698 zoff99 40 }
3699 zoff99 2 else if (maxcat < ncat && maxcat < cat)
3700 zoff99 40 {
3701 zoff99 41 dlim = abs(d) * (128 / 256); // abs(d) * 0.5
3702 zoff99 40 }
3703    
3704 zoff99 41 if (left < -dlim && right > dlim) // no other road is between -dlim : dlim angle (no other road is "dlim" close to straight)
3705 zoff99 40 {
3706 zoff99 27 is_unambigous = 1;
3707 zoff99 40 }
3708    
3709 zoff99 27 if (!is_same_street && is_unambigous < 1)
3710     {
3711     ret = 1;
3712 zoff99 46 r = "yes: (not same street) or (ambigous [nicht eindeutig])";
3713 zoff99 27 }
3714     else
3715 zoff99 40 {
3716 zoff99 46 r = "no: (same street) and (unambigous [eindeutig])";
3717 zoff99 40 }
3718    
3719 zoff99 41 if (ret == 0)
3720     {
3721     // add a new check here:
3722     if (have_more_than_one_way_to_turn == 1)
3723     {
3724    
3725 zoff99 46 dbg(0, "STRAI:11.07:4.0: cat=%d, ncat=%d, highest_other_cat=%d, d=%d, abs(d)=%d new_angle_closest_to_cur=%d original_d=%d\n", cat, ncat, highest_other_cat, d, abs(d), new_angle_closest_to_cur, original_d);
3726    
3727     if ( (cat > 6) && (ncat > 6) && (highest_other_cat <= 6) && (abs(d) < 70) )
3728 zoff99 41 {
3729     r = "no: from highway to highway (no other highway possibilities)";
3730     dbg(0, "STRAI:011.07:4 abs(d)=%d cat=%d ncat=%d highest_other_cat=%d\n", abs(d), cat, ncat, highest_other_cat);
3731     }
3732     else
3733     {
3734 zoff99 46
3735     if ((ncat == 6) && (highest_other_cat == 6) && (abs(d) < 50) && (abs(new_angle_closest_to_cur - original_d) < 65))
3736     {
3737     ret = 1;
3738     r = "yes: we are driving onto a ramp and there a other ramps near (<50 degrees) to it";
3739     dbg(0, "STRAI:011.07:3.001 ncat=%d highest_other_cat=%d d=%d (new_angle_closest_to_cur=%d - original_d=%d)\n", ncat, highest_other_cat, d, new_angle_closest_to_cur, original_d);
3740     }
3741    
3742    
3743 zoff99 41 if ((d == 0) && (new_angle_abs_min_allowed >= 25))
3744     {
3745     r = "no: driving almost straight, and other ways not very close to straight";
3746     dbg(0, "STRAI:011.07:3 abs(d)=%d new_angle_abs_min_allowed=%d\n", abs(d), new_angle_abs_min_allowed);
3747     }
3748     else
3749     {
3750    
3751     if ( (d == 0) && (abs(new_angle_closest_to_cur - original_d) < 16) )
3752     {
3753     ret = 1;
3754     r = "yes: we are going straight and some other way is very close to it";
3755     dbg(0, "STRAI:011.07:0 abs(d)=%d new_angle_abs_min_allowed=%d\n", abs(d), new_angle_abs_min_allowed);
3756     }
3757     else if ( (ncat_2 <= highest_other_cat) && (d == 0) && (abs(new_angle_closest_to_cur - original_d) < 30) )
3758     {
3759     ret = 1;
3760     r = "yes: we are going straight and some other way is very close to it (same or higher cat)";
3761     dbg(0, "STRAI:011.07:7 abs(d)=%d new_angle_abs_min_allowed=%d\n", abs(d), new_angle_abs_min_allowed);
3762     }
3763     else if ((abs(d) > 0) && (new_angle_abs_min_allowed < abs(d)))
3764     {
3765     ret = 1;
3766     r = "yes: some other way is going more straight";
3767     dbg(0, "STRAI:011.07:0 abs(d)=%d new_angle_abs_min_allowed=%d\n", abs(d), new_angle_abs_min_allowed);
3768 zoff99 46
3769    
3770     if (abs(d) < 10)
3771     {
3772    
3773     // ----------########### more way left/right of way ? ###########----------
3774     int more_ways_to_left_ = 0;
3775     int more_ways_to_right_ = 0;
3776     w = new->way.next;
3777     while (w)
3778     {
3779     if (is_way_allowed(nav, w, 1))
3780     {
3781     if ( (is_maybe_same_item(&(new->way), w, 0) == 0) && (is_maybe_same_item(&(old->way), w, 1) == 0) )
3782     {
3783     dbg(0, "STRAI:108.02a delta=%d\n", angle_delta(old->angle_end, w->angle2));
3784    
3785     if (is_way_allowed(nav, w, 1))
3786     {
3787     if (angle_delta(old->angle_end, w->angle2) < d) // other ways are going more to the left?
3788     {
3789     more_ways_to_left_++;
3790     }
3791     else if (angle_delta(old->angle_end, w->angle2) > d) // other ways are going more to the right?
3792     {
3793     more_ways_to_right_++;
3794     }
3795     }
3796     }
3797     }
3798     w = w->next;
3799     }
3800    
3801     dbg(0, "STRAI:108.02 %d %d\n", more_ways_to_left_, more_ways_to_right_);
3802    
3803    
3804     if ((d < 0) && (more_ways_to_left_ == 0)) // && (more_ways_to_right_ > 0))
3805     {
3806    
3807     dbg(0, "STRAI:108.03:left\n");
3808     *delta_real = 0;
3809     d = -8;
3810     no_correction = 1;
3811     }
3812     else if ((d > 0) && (more_ways_to_left_ > 0)) // && (more_ways_to_right_ == 0))
3813     {
3814     dbg(0, "STRAI:108.04:right\n");
3815     *delta_real = 0;
3816     d = 8;
3817     no_correction = 1;
3818     }
3819    
3820    
3821    
3822     // ----------########### more way left/right of way ? ###########----------
3823    
3824     }
3825    
3826    
3827 zoff99 41 }
3828     else if ((abs(d) > 0) && (new_angle_abs_min_allowed < 39) && (is_same_street))
3829     {
3830     if ( (cat == ncat) && (ncat_2 > highest_other_cat) )
3831     {
3832     r = "no: we need to make a turn, but other possibilites are much lower cat roads";
3833     dbg(0, "STRAI:011.07:5iss cat=%d ncat=%d cat_2=%d ncat_2=%d highest_other_cat=%d\n", cat, ncat, cat_2, ncat_2, highest_other_cat);
3834     }
3835     else
3836     {
3837     ret = 1;
3838     r = "yes: we need to make a turn";
3839     dbg(0, "STRAI:011.07:1iss abs(d)=%d new_angle_abs_min_allowed=%d\n", abs(d), new_angle_abs_min_allowed);
3840     }
3841     }
3842     else if ((abs(d) > 0) && (new_angle_abs_min_allowed < 52) && (!is_same_street))
3843     {
3844     if ( (cat == ncat) && (ncat_2 > highest_other_cat) )
3845     {
3846     r = "no: we need to make a turn, but other possibilites are much lower cat roads";
3847     dbg(0, "STRAI:011.07:5nss cat=%d ncat=%d cat_2=%d ncat_2=%d highest_other_cat=%d\n", cat, ncat, cat_2, ncat_2, highest_other_cat);
3848     }
3849     else
3850     {
3851     ret = 1;
3852     r = "yes: we need to make a turn";
3853     dbg(0, "STRAI:011.07:1nss abs(d)=%d new_angle_abs_min_allowed=%d\n", abs(d), new_angle_abs_min_allowed);
3854     }
3855     }
3856     else
3857     {
3858     dbg(0, "STRAI:011.07:6 abs(d)=%d new_angle_abs_min_allowed=%d cat=%d ncat=%d cat_2=%d ncat_2=%d highest_other_cat=%d new_angle_closest_to_cur=%d original_d=%d\n", abs(d), new_angle_abs_min_allowed, cat, ncat, cat_2, ncat_2, highest_other_cat, new_angle_closest_to_cur, original_d);
3859     }
3860     }
3861     }
3862     }
3863     }
3864    
3865 zoff99 46 dbg(0, "STRAI:011.07 is_unambigous[eindeutig]=%d ret=%d r=%s\n", is_unambigous, ret, r);
3866 zoff99 40
3867 zoff99 2 #ifdef DEBUG
3868 zoff99 27 // 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);
3869 zoff99 2 #endif
3870     }
3871 zoff99 40
3872 zoff99 41
3873    
3874    
3875    
3876    
3877     dbg(0, "STRAI:007.00aa:d=%d ******************++++++++++++\n", d);
3878    
3879    
3880    
3881    
3882    
3883 zoff99 40 // correct "delta" (turn angle) here !! ---------------------------
3884     // correct "delta" (turn angle) here !! ---------------------------
3885    
3886 zoff99 46 if (no_correction == 0)
3887     {
3888     *delta_real = d;
3889     }
3890 zoff99 41
3891 zoff99 46 if ((ret == 1) && (have_more_than_one_way_to_turn == 1) && (no_correction == 0))
3892 zoff99 27 {
3893 zoff99 40 w = new->way.next;
3894     //int d2 = angle_delta(old->angle_end, new->way.angle2);
3895     int d2 = d;
3896     //if (d == 0)
3897     //{
3898     // d2 = 0;
3899     //}
3900 zoff99 2
3901 zoff99 40 int correct_direction = 1;
3902    
3903 zoff99 41 dbg(0, "STRAI:007.01:d=%d d2=%d\n", d, d2);
3904 zoff99 40
3905     if (d2 < 0) // left
3906 zoff99 27 {
3907 zoff99 40 while (w)
3908 zoff99 27 {
3909 zoff99 41 if (is_way_allowed(nav, w, 1))
3910 zoff99 40 {
3911 zoff99 41 if ( (is_maybe_same_item(&(new->way), w, 0) == 0) && (is_maybe_same_item(&(old->way), w, 1) == 0) )
3912     {
3913     if (angle_delta(old->angle_end, w->angle2) > d2) // other ways are going more to the right?
3914     {
3915     correct_direction = 0;
3916     break;
3917     }
3918     }
3919 zoff99 40 }
3920     w = w->next;
3921 zoff99 2 }
3922    
3923 zoff99 40 if (correct_direction == 1)
3924 zoff99 27 {
3925 zoff99 40 #ifdef NAVIT_ROUTING_DEBUG_PRINT
3926     dbg(0, "MAV:001:correct to right\n");
3927     #endif
3928     d = 8; // set to "slight right"
3929     }
3930     }
3931     else if (d2 > 0) // right
3932     {
3933     while (w)
3934     {
3935 zoff99 41 if (is_way_allowed(nav, w, 1))
3936 zoff99 27 {
3937 zoff99 41 if ( (is_maybe_same_item(&(new->way), w, 0) == 0) && (is_maybe_same_item(&(old->way), w, 1) == 0) )
3938     {
3939     if (angle_delta(old->angle_end, w->angle2) < d2) // other ways are going more to the left?
3940     {
3941     correct_direction = 0;
3942     break;
3943     }
3944     }
3945 zoff99 2 }
3946 zoff99 40 w = w->next;
3947 zoff99 27 }
3948 zoff99 40
3949     if (correct_direction == 1)
3950 zoff99 27 {
3951 zoff99 40 #ifdef NAVIT_ROUTING_DEBUG_PRINT
3952     dbg(0, "MAV:002:correct to left\n");
3953     #endif
3954     d = -8; // set to "slight left"
3955 zoff99 2 }
3956     }
3957 zoff99 40 else // (d2 == 0) // straight
3958     {
3959    
3960 zoff99 41 dbg(0, "STRAI:008.01:%d (%d < %d) new_angle_abs_min_allowed=%d\n", d2, new_angle_abs_min, ROAD_ANGLE_DISTANCE_FOR_STRAIGHT, new_angle_abs_min_allowed);
3961 zoff99 40
3962     int more_ways_to_left = 0;
3963     int more_ways_to_right = 0;
3964    
3965 zoff99 41 if (new_angle_abs_min_allowed < ROAD_ANGLE_DISTANCE_FOR_STRAIGHT) // if other angles are far different from straight, than let it still be straight! otherwise correct direction
3966 zoff99 40 {
3967     dbg(0, "STRAI:008.02\n");
3968    
3969 zoff99 46
3970     if ((abs(new_angle_closest_to_cur - original_d) <= 25) || (abs(original_d) >= 10))
3971     // if (1 == 1)
3972 zoff99 40 {
3973 zoff99 46
3974     while (w)
3975 zoff99 41 {
3976 zoff99 46 if (is_way_allowed(nav, w, 1))
3977 zoff99 41 {
3978 zoff99 46 if ( (is_maybe_same_item(&(new->way), w, 0) == 0) && (is_maybe_same_item(&(old->way), w, 1) == 0) )
3979     {
3980     dbg(0, "STRAI:008.02a delta=%d\n", angle_delta(old->angle_end, w->angle2));
3981 zoff99 40
3982 zoff99 46 if (is_way_allowed(nav, w, 1))
3983 zoff99 41 {
3984 zoff99 46 if (angle_delta(old->angle_end, w->angle2) < d2) // other ways are going more to the left?
3985     {
3986     more_ways_to_left++;
3987     }
3988     else if (angle_delta(old->angle_end, w->angle2) > d2) // other ways are going more to the right?
3989     {
3990     more_ways_to_right++;
3991     }
3992 zoff99 41 }
3993     }
3994     }
3995 zoff99 46 w = w->next;
3996 zoff99 40 }
3997    
3998 zoff99 46 dbg(0, "STRAI:008.02 %d %d\n", more_ways_to_left, more_ways_to_right);
3999 zoff99 40
4000 zoff99 46 if ((more_ways_to_left == 0) && (more_ways_to_right > 0))
4001     {
4002 zoff99 40
4003 zoff99 46 dbg(0, "STRAI:008.03:left\n");
4004 zoff99 40
4005     #ifdef NAVIT_ROUTING_DEBUG_PRINT
4006 zoff99 46 dbg(0, "MAV:003:correct to left\n");
4007 zoff99 2 #endif
4008 zoff99 46 d = -8;
4009     }
4010     else if ((more_ways_to_left > 0) && (more_ways_to_right == 0))
4011     {
4012     dbg(0, "STRAI:008.04:right\n");
4013 zoff99 40
4014     #ifdef NAVIT_ROUTING_DEBUG_PRINT
4015 zoff99 46 dbg(0, "MAV:003:correct to right\n");
4016 zoff99 2 #endif
4017 zoff99 46 d = 8;
4018     }
4019    
4020 zoff99 40 }
4021 zoff99 46 else
4022     {
4023     dbg(0, "STRAI:008.02f street almost straight and nearest other street at least 25 away: closest=%d orig_d=%d\n", new_angle_closest_to_cur, original_d);
4024     }
4025    
4026 zoff99 40 }
4027    
4028 zoff99 2 }
4029    
4030     }
4031    
4032 zoff99 40 // correct "delta" (turn angle) here !! ---------------------------
4033     // correct "delta" (turn angle) here !! ---------------------------
4034    
4035    
4036 zoff99 41
4037    
4038    
4039    
4040    
4041    
4042     dbg(0, "STRAI:099:ret=%d r=%s d=%d d_real=%d\n", ret, r, d, *delta_real);
4043     dbg(0, "STRAI:099:======================================\n");
4044    
4045 zoff99 40 *delta = d;
4046     if (reason)
4047 zoff99 27 {
4048 zoff99 40 *reason = r;
4049 zoff99 2 }
4050    
4051 zoff99 40 return ret;
4052 zoff99 2 }
4053    
4054 zoff99 41 static struct navigation_command *command_new(struct navigation *this_, struct navigation_itm *itm, int delta, int delta_real)
4055 zoff99 2 {
4056     struct navigation_command *ret=g_new0(struct navigation_command, 1);
4057 zoff99 40
4058 zoff99 27 //dbg(1, "enter this_=%p itm=%p delta=%d\n", this_, itm, delta);
4059     ret->delta = delta;
4060 zoff99 41 ret->delta_real = delta_real;
4061 zoff99 27 ret->itm = itm;
4062 zoff99 40
4063 zoff99 34 if (itm && itm->prev && itm->way.next && itm->prev->way.next && !(itm->way.flags & NAVIT_AF_ROUNDABOUT) && (itm->prev->way.flags & NAVIT_AF_ROUNDABOUT))
4064 zoff99 27 {
4065     int len = 0;
4066     int angle = 0;
4067 zoff99 2 int entry_angle;
4068 zoff99 27 struct navigation_itm *itm2 = itm->prev;
4069 zoff99 30 int exit_angle = angle_median(itm->prev->angle_end, itm->way.next->angle2);
4070 zoff99 27 //dbg(1, "exit %d median from %d,%d\n", exit_angle, itm->prev->angle_end, itm->way.next->angle2);
4071 zoff99 40
4072 zoff99 34 while (itm2 && (itm2->way.flags & NAVIT_AF_ROUNDABOUT))
4073 zoff99 27 {
4074     len += itm2->length;
4075     angle = itm2->angle_end;
4076     itm2 = itm2->prev;
4077 zoff99 2 }
4078 zoff99 40
4079 zoff99 27 if (itm2 && itm2->next && itm2->next->way.next)
4080     {
4081     itm2 = itm2->next;
4082 zoff99 30 entry_angle = angle_median(angle_opposite(itm2->way.angle2), itm2->way.next->angle2);
4083 zoff99 27 // dbg(1, "entry %d median from %d(%d),%d\n", entry_angle, angle_opposite(itm2->way.angle2), itm2->way.angle2, itm2->way.next->angle2);
4084 zoff99 2 }
4085 zoff99 27 else
4086     {
4087     entry_angle = angle_opposite(angle);
4088     }
4089     //dbg(0, "entry %d exit %d\n", entry_angle, exit_angle);
4090     ret->roundabout_delta = angle_delta(entry_angle, exit_angle);
4091     ret->length = len + roundabout_extra_length;
4092 zoff99 2 }
4093 zoff99 40
4094 zoff99 27 if (this_->cmd_last)
4095     {
4096     this_->cmd_last->next = ret;
4097 zoff99 2 ret->prev = this_->cmd_last;
4098     }
4099 zoff99 40
4100 zoff99 27 this_->cmd_last = ret;
4101 zoff99 2
4102     if (!this_->cmd_first)
4103 zoff99 40 {
4104 zoff99 27 this_->cmd_first = ret;
4105 zoff99 40 }
4106    
4107 zoff99 2 return ret;
4108     }
4109    
4110 zoff99 40
4111    
4112     // ----------- main place where maneuvers generated (run only once) ------------
4113     // ----------- main place where maneuvers generated (run only once) ------------
4114     // ----------- main place where maneuvers generated (run only once) ------------
4115 zoff99 27 static void make_maneuvers(struct navigation *this_, struct route *route)
4116 zoff99 2 {
4117 zoff99 40 __F_START__
4118    
4119 zoff99 27 struct navigation_itm *itm, *last = NULL, *last_itm = NULL;
4120 zoff99 2 int delta;
4121 zoff99 41 int delta_real;
4122 zoff99 27 itm = this_->first;
4123     this_->cmd_last = NULL;
4124     this_->cmd_first = NULL;
4125     while (itm)
4126     {
4127     if (last)
4128     {
4129 zoff99 41 if (maneuver_required2(this_, last_itm, itm, &delta, &delta_real, NULL))
4130 zoff99 27 {
4131 zoff99 40 //dbg(0, "maneuver_required2 = true\n");
4132 zoff99 41 command_new(this_, itm, delta, delta_real);
4133 zoff99 2 }
4134 zoff99 27 }
4135     else
4136 zoff99 40 {
4137 zoff99 27 last = itm;
4138 zoff99 40 }
4139 zoff99 27 last_itm = itm;
4140     itm = itm->next;
4141 zoff99 2 }
4142 zoff99 41 command_new(this_, last_itm, 0, 0);
4143 zoff99 40
4144     __F_END__
4145 zoff99 2 }
4146 zoff99 40 // ----------- main place where maneuvers generated ------------
4147     // ----------- main place where maneuvers generated ------------
4148     // ----------- main place where maneuvers generated ------------
4149 zoff99 2
4150 zoff99 40
4151    
4152 zoff99 27 static int contains_suffix(char *name, char *suffix)
4153 zoff99 2 {
4154     if (!suffix)
4155 zoff99 41 {
4156 zoff99 2 return 0;
4157 zoff99 41 }
4158    
4159 zoff99 2 if (strlen(name) < strlen(suffix))
4160 zoff99 41 {
4161 zoff99 2 return 0;
4162 zoff99 41 }
4163    
4164 zoff99 27 return !g_strcasecmp(name + strlen(name) - strlen(suffix), suffix);
4165 zoff99 2 }
4166    
4167     static char *
4168     replace_suffix(char *name, char *search, char *replace)
4169     {
4170 zoff99 27 int len = strlen(name) - strlen(search);
4171     char *ret = g_malloc(len + strlen(replace) + 1);
4172 zoff99 41
4173 zoff99 2 strncpy(ret, name, len);
4174 zoff99 27 strcpy(ret + len, replace);
4175 zoff99 41
4176 zoff99 27 if (isupper(name[len]))
4177     {
4178     ret[len] = toupper(ret[len]);
4179 zoff99 2 }
4180    
4181     return ret;
4182     }
4183    
4184     static char *
4185 zoff99 30 navigation_item_destination(struct navigation *nav, struct navigation_itm *itm, struct navigation_itm *next, char *prefix)
4186 zoff99 2 {
4187 zoff99 27 char *ret = NULL, *name1, *sep, *name2;
4188     char *n1, *n2;
4189     int i, sex;
4190     int vocabulary1 = 65535;
4191     int vocabulary2 = 65535;
4192 zoff99 2 struct attr attr;
4193    
4194 zoff99 27 if (!prefix)
4195 zoff99 41 {
4196 zoff99 27 prefix = "";
4197 zoff99 41 }
4198 zoff99 40
4199 zoff99 30 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name, &attr, NULL))
4200 zoff99 41 {
4201 zoff99 27 vocabulary1 = attr.u.num;
4202 zoff99 41 }
4203 zoff99 40
4204 zoff99 30 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name_systematic, &attr, NULL))
4205 zoff99 41 {
4206 zoff99 27 vocabulary2 = attr.u.num;
4207 zoff99 41 }
4208 zoff99 40
4209 zoff99 27 n1 = itm->way.name1;
4210     n2 = itm->way.name2;
4211 zoff99 40
4212 zoff99 2 if (!vocabulary1)
4213 zoff99 27 n1 = NULL;
4214 zoff99 40
4215 zoff99 2 if (!vocabulary2)
4216 zoff99 27 n2 = NULL;
4217 zoff99 40
4218 zoff99 41 if (!n1 && !n2 && (item_is_ramp(itm->way.item)) && vocabulary2)
4219 zoff99 27 {
4220     //dbg(1,">> Next is ramp %lx current is %lx \n", itm->way.item.type, next->way.item.type);
4221    
4222 zoff99 40
4223     // disabled for now !!!!!!!! -------------------------
4224     #if 0
4225 zoff99 27 if (next->way.item.type == type_ramp)
4226 zoff99 40 {
4227 zoff99 2 return NULL;
4228 zoff99 40 }
4229     #endif
4230     // disabled for now !!!!!!!! -------------------------
4231    
4232    
4233     //else
4234     //{
4235     // return g_strdup_printf("%s%s",prefix,_("into the ramp"));
4236     //}
4237    
4238     #if 0
4239 zoff99 30 if (itm->way.item.type == type_highway_city || itm->way.item.type == type_highway_land)
4240 zoff99 27 {
4241     #ifdef HAVE_API_ANDROID
4242 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4243 zoff99 27 android_send_generic_text(1,"+*#O:exit\n");
4244     gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
4245     android_send_generic_text(1,xy);
4246     g_free(xy);
4247     #endif
4248 zoff99 28 #endif
4249 zoff99 27 return g_strdup_printf("%s%s", prefix, _("exit")); /* %FIXME Can this even be reached? and "exit" is the wrong text anyway ! */
4250     }
4251 zoff99 2 else
4252 zoff99 40 #endif
4253 zoff99 27 {
4254 zoff99 40 if (itm->way.street_dest_text)
4255     {
4256 zoff99 27 #ifdef HAVE_API_ANDROID
4257 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4258 zoff99 40 gchar* xy=g_strdup_printf("+*#0:%s\n", itm->way.street_dest_text);
4259     android_send_generic_text(1,xy);
4260     g_free(xy);
4261     gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
4262     android_send_generic_text(1,xy);
4263     g_free(xy);
4264 zoff99 27 #endif
4265 zoff99 28 #endif
4266 zoff99 40
4267     // say the name on the exit sign/destinaion sign
4268     return g_strdup_printf("%s%s", prefix, itm->way.street_dest_text);
4269     }
4270     else
4271     {
4272     #ifdef HAVE_API_ANDROID
4273     #ifdef NAVIT_SAY_DEBUG_PRINT
4274     android_send_generic_text(1,"+*#O:into the ramp\n");
4275     gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
4276     android_send_generic_text(1,xy);
4277     g_free(xy);
4278     #endif
4279     #endif
4280    
4281     return g_strdup_printf("%s%s", prefix, _("into the ramp"));
4282     }
4283 zoff99 27 }
4284    
4285 zoff99 2 }
4286 zoff99 27
4287 zoff99 40 if (!n1 && !n2 && !itm->way.street_dest_text)
4288 zoff99 27 {
4289 zoff99 2 return NULL;
4290 zoff99 27 }
4291    
4292 zoff99 40 if (itm->way.street_dest_text)
4293 zoff99 27 {
4294 zoff99 40 #ifdef HAVE_API_ANDROID
4295     #ifdef NAVIT_SAY_DEBUG_PRINT
4296     gchar* xy=g_strdup_printf("+*#0:%s\n", itm->way.street_dest_text);
4297     android_send_generic_text(1,xy);
4298     g_free(xy);
4299     gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
4300     android_send_generic_text(1,xy);
4301     g_free(xy);
4302     #endif
4303     #endif
4304     // say the name on the exit sign/destinaion sign
4305     return g_strdup_printf("%s%s", prefix, itm->way.street_dest_text);
4306     }
4307     else if (n1)
4308     {
4309 zoff99 27 sex = -1;
4310     name1 = NULL;
4311     for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++)
4312     {
4313     if (contains_suffix(n1, suffixes[i].fullname))
4314     {
4315     sex = suffixes[i].sex;
4316     name1 = g_strdup(n1);
4317 zoff99 2 break;
4318     }
4319 zoff99 27 if (contains_suffix(n1, suffixes[i].abbrev))
4320     {
4321     sex = suffixes[i].sex;
4322 zoff99 41
4323     // TODO: replacing strings here maybe not so good?!?
4324 zoff99 30 name1 = replace_suffix(n1, suffixes[i].abbrev, suffixes[i].fullname);
4325 zoff99 2 break;
4326     }
4327     }
4328 zoff99 27
4329     if (n2)
4330     {
4331     name2 = n2;
4332     sep = " ";
4333 zoff99 2 }
4334 zoff99 27 else
4335     {
4336     name2 = "";
4337     sep = "";
4338 zoff99 2 }
4339 zoff99 27
4340     gchar* xy;
4341     switch (sex)
4342     {
4343     case -1:
4344     #ifdef HAVE_API_ANDROID
4345 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4346 zoff99 27 android_send_generic_text(1,"+*#O:%sinto the street %s%s%s\n");
4347     xy=g_strdup_printf("+*#1:%s\n", prefix);
4348     android_send_generic_text(1,xy);
4349     g_free(xy);
4350     xy=g_strdup_printf("+*#1:%s\n", n1);
4351     android_send_generic_text(1,xy);
4352     g_free(xy);
4353     xy=g_strdup_printf("+*#1:%s\n", sep);
4354     android_send_generic_text(1,xy);
4355     g_free(xy);
4356     xy=g_strdup_printf("+*#1:%s\n", name2);
4357     android_send_generic_text(1,xy);
4358     g_free(xy);
4359     #endif
4360 zoff99 28 #endif
4361 zoff99 27 // TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name
4362 zoff99 30 ret = g_strdup_printf(_("%sinto the street %s%s%s"), prefix, n1, sep, name2);
4363 zoff99 27 break;
4364     case 1:
4365     #ifdef HAVE_API_ANDROID
4366 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4367 zoff99 27 android_send_generic_text(1,"+*#O:%sinto the %s%s%s|male form\n");
4368     xy=g_strdup_printf("+*#1:%s\n", prefix);
4369     android_send_generic_text(1,xy);
4370     g_free(xy);
4371     xy=g_strdup_printf("+*#1:%s\n", name1);
4372     android_send_generic_text(1,xy);
4373     g_free(xy);
4374     xy=g_strdup_printf("+*#1:%s\n", sep);
4375     android_send_generic_text(1,xy);
4376     g_free(xy);
4377     xy=g_strdup_printf("+*#1:%s\n", name2);
4378     android_send_generic_text(1,xy);
4379     g_free(xy);
4380     #endif
4381 zoff99 28 #endif
4382 zoff99 27 // TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name. Male form. The stuff after | doesn't have to be included
4383 zoff99 30 ret = g_strdup_printf(_("%sinto the %s%s%s|male form"), prefix, name1, sep, name2);
4384 zoff99 27 break;
4385     case 2:
4386     #ifdef HAVE_API_ANDROID
4387 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4388 zoff99 27 android_send_generic_text(1,"+*#O:%sinto the %s%s%s|female form\n");
4389     xy=g_strdup_printf("+*#1:%s\n", prefix);
4390     android_send_generic_text(1,xy);
4391     g_free(xy);
4392     xy=g_strdup_printf("+*#1:%s\n", name1);
4393     android_send_generic_text(1,xy);
4394     g_free(xy);
4395     xy=g_strdup_printf("+*#1:%s\n", sep);
4396     android_send_generic_text(1,xy);
4397     g_free(xy);
4398     xy=g_strdup_printf("+*#1:%s\n", name2);
4399     android_send_generic_text(1,xy);
4400     g_free(xy);
4401     #endif
4402 zoff99 28 #endif
4403 zoff99 27 // TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name. Female form. The stuff after | doesn't have to be included
4404 zoff99 30 ret = g_strdup_printf(_("%sinto the %s%s%s|female form"), prefix, name1, sep, name2);
4405 zoff99 27 break;
4406     case 3:
4407     #ifdef HAVE_API_ANDROID
4408 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4409 zoff99 27 android_send_generic_text(1,"+*#O:%sinto the %s%s%s|neutral form\n");
4410     xy=g_strdup_printf("+*#1:%s\n", prefix);
4411     android_send_generic_text(1,xy);
4412     g_free(xy);
4413     xy=g_strdup_printf("+*#1:%s\n", name1);
4414     android_send_generic_text(1,xy);
4415     g_free(xy);
4416     xy=g_strdup_printf("+*#1:%s\n", sep);
4417     android_send_generic_text(1,xy);
4418     g_free(xy);
4419     xy=g_strdup_printf("+*#1:%s\n", name2);
4420     android_send_generic_text(1,xy);
4421     g_free(xy);
4422     #endif
4423 zoff99 28 #endif
4424 zoff99 27 // TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name. Neutral form. The stuff after | doesn't have to be included
4425 zoff99 30 ret = g_strdup_printf(_("%sinto the %s%s%s|neutral form"), prefix, name1, sep, name2);
4426 zoff99 27 break;
4427     }
4428 zoff99 2 g_free(name1);
4429 zoff99 27
4430     }
4431     else
4432     {
4433     #ifdef HAVE_API_ANDROID
4434 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4435 zoff99 27 android_send_generic_text(1,"+*#O:sinto the %s\n");
4436     gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
4437     android_send_generic_text(1,xy);
4438     g_free(xy);
4439     xy=g_strdup_printf("+*#1:%s\n", n2);
4440     android_send_generic_text(1,xy);
4441     g_free(xy);
4442     #endif
4443 zoff99 28 #endif
4444 zoff99 27 // TRANSLATORS: gives the name of the next road to turn into (into the E17)
4445     ret = g_strdup_printf(_("%sinto the %s"), prefix, n2);
4446     }
4447    
4448     name1 = ret;
4449    
4450     while (name1 && *name1)
4451     {
4452     switch (*name1)
4453     {
4454     case '|':
4455     *name1 = '\0';
4456     break;
4457     case '/':
4458     *name1++ = ' ';
4459     break;
4460     default:
4461     name1++;
4462 zoff99 2 }
4463     }
4464 zoff99 27
4465 zoff99 2 return ret;
4466     }
4467    
4468 zoff99 41
4469    
4470    
4471     #define DONT_KNOW_LEVEL -997
4472    
4473    
4474 zoff99 2 static char *
4475 zoff99 41 show_maneuver_bicycle(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type, int connect, int want_this_level)
4476 zoff99 40 {
4477     __F_START__
4478    
4479     // TRANSLATORS: right, as in 'Turn right'
4480     char *dir = _("right");
4481     char *strength = "";
4482     int distance = itm->dest_length - cmd->itm->dest_length;
4483     char *d, *ret = NULL;
4484     int delta = cmd->delta;
4485 zoff99 41 int delta_real = cmd->delta_real;
4486 zoff99 40 int level;
4487     int level_now = 99;
4488 zoff99 41 int level3;
4489 zoff99 40 int strength_needed;
4490     int skip_roads;
4491     int count_roundabout;
4492     struct navigation_itm *cur;
4493     struct navigation_way *w;
4494     int against_oneway = 0;
4495 zoff99 41 int keep_dir = 0;
4496     int old_dir = 0;
4497 zoff99 40
4498 zoff99 41 if (want_this_level == DONT_KNOW_LEVEL)
4499     {
4500     level3 = 1;
4501     }
4502     else
4503     {
4504     level3 = want_this_level;
4505     }
4506    
4507    
4508     int cur_vehicle_speed = 0;
4509     if ((global_navit) && (global_navit->vehicle))
4510     {
4511     cur_vehicle_speed = global_navit->vehicle->speed; // in km/h
4512     }
4513    
4514 zoff99 40 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
4515     {
4516     //dbg(0, "itm->way.flags=%x\n", itm->way.flags);
4517     //dbg(0, "itm->next->way.flags=%x\n", itm->next->way.flags);
4518     //dbg(0, "itm->way.dir=%d itm->next->way.dir=%d\n", itm->way.dir, itm->next->way.dir);
4519    
4520     //dbg(0, "2 itm->way.flags=%x\n", cmd->itm->way.flags);
4521     //dbg(0, "2 itm->next->way.flags=%x\n", cmd->itm->next->way.flags);
4522     //dbg(0, "2 itm->way.dir=%d itm->next->way.dir=%d\n", cmd->itm->way.dir, cmd->itm->next->way.dir);
4523    
4524     int flags_old = navigation_item_get_flags(&itm->way);
4525     int flags_new = 0;
4526     if (itm->next)
4527     {
4528     flags_new = navigation_item_get_flags(&itm->next->way);
4529     }
4530     //dbg(0, "(2211)old flags=%x new flags=%x\n", flags_old, flags_new);
4531    
4532     // long long wayid_old = navigation_item_get_wayid(&(itm->way));
4533     // long long wayid_new = navigation_item_get_wayid(&(itm->next->way));
4534     // dbg(0, "WID old_way_id=%lld new_way_id=%lld\n", wayid_old, wayid_new);
4535    
4536    
4537     if ( (itm->way.dir == 1) && ((itm->next->way.dir == -1) && (itm->next->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)) )
4538     {
4539     against_oneway = 1;
4540     //dbg(0, "SPEAK: (1)going against oneway street!\n");
4541     }
4542     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)) )
4543     {
4544     against_oneway = 1;
4545     //dbg(0, "SPEAK: (2)going against oneway street!\n");
4546     }
4547     }
4548    
4549     //dbg(0, "d=%d d3=%d\n", distance, (distance - cmd->length));
4550 zoff99 41 level_now = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length, 0);
4551 zoff99 40 //dbg(0, "level_now=%d\n", level_now);
4552    
4553     w = itm->next->way.next;
4554     strength_needed = 0;
4555    
4556 zoff99 41 if (angle_delta(itm->next->way.angle2, itm->angle_end) < 0) // left
4557 zoff99 40 {
4558     while (w)
4559     {
4560 zoff99 41 if (angle_delta(w->angle2, itm->angle_end) < 0) // other ways are going left
4561 zoff99 40 {
4562     strength_needed = 1;
4563     break;
4564     }
4565     w = w->next;
4566     }
4567     }
4568 zoff99 41 else // right
4569 zoff99 40 {
4570     while (w)
4571     {
4572 zoff99 41 if (angle_delta(w->angle2, itm->angle_end) > 0) // other ways are going right
4573 zoff99 40 {
4574     strength_needed = 1;
4575     break;
4576     }
4577     w = w->next;
4578     }
4579     }
4580    
4581    
4582 zoff99 41 if ((strength_needed == 0) && (delta < 9)) // for corrected turn (delta will be 8), use strength ("slight")
4583     {
4584     strength_needed = 1;
4585     }
4586    
4587 zoff99 40 //dbg(0, "cmd->delta=%d\n", delta);
4588    
4589     if (delta < 0)
4590     {
4591     // TRANSLATORS: left, as in 'Turn left'
4592     dir = _("left");
4593     delta = -delta;
4594 zoff99 41
4595     old_dir = -1; // left
4596 zoff99 40 }
4597 zoff99 41 else if (delta > 0)
4598     {
4599 zoff99 40
4600 zoff99 41 old_dir = 1; // right
4601    
4602     // dir = right
4603     }
4604     else // delta == 0 // go straight
4605     {
4606     dir = _("straight");
4607     strength_needed = 0;
4608     }
4609    
4610    
4611     keep_dir = 0;
4612    
4613 zoff99 40 if (strength_needed)
4614     {
4615     if (delta < 45)
4616     {
4617     // TRANSLATORS: Don't forget the ending space
4618     // TRANSLATORS: EXAMPLE: turn slight right
4619 zoff99 41 strength = _("slighty ");
4620     // TRANSLATORS: Don't forget the ending space
4621     // TRANSLATORS: EXAMPLE: turn slight right
4622 zoff99 40 strength = _("slight ");
4623 zoff99 41
4624     if (delta_real == 0) // keep left/right
4625     {
4626     if (old_dir == -1)
4627     {
4628     keep_dir = -1;
4629     }
4630     else
4631     {
4632     keep_dir = 1;
4633     }
4634     }
4635 zoff99 40 }
4636     else if (delta < 105)
4637     {
4638     strength = "";
4639     }
4640     else if (delta < 165)
4641     {
4642     // TRANSLATORS: Don't forget the ending space
4643     // TRANSLATORS: EXAMPLE: turn hard right
4644     strength = _("hard ");
4645     }
4646     else if (delta < 180)
4647     {
4648     // TRANSLATORS: Don't forget the ending space
4649     // TRANSLATORS: EXAMPLE: turn really hard right
4650     strength = _("really hard ");
4651     }
4652     else
4653     {
4654     // TRANSLATORS: Don't forget the ending space
4655     strength = "";
4656     }
4657     }
4658    
4659    
4660     if (type != attr_navigation_long_exact)
4661     {
4662     //dbg(0, "round distance d=%d dr=%d\n", distance, round_distance(distance));
4663     distance = round_distance(distance);
4664     }
4665    
4666    
4667    
4668    
4669     if (type == attr_navigation_speech)
4670     {
4671 zoff99 41 dbg(0, "NAV_TURNAROUND:003 ta=%d talimit=%d\n", nav->turn_around, nav->turn_around_limit);
4672    
4673 zoff99 40 if (nav->turn_around && nav->turn_around == nav->turn_around_limit)
4674     {
4675 zoff99 41 dbg(0, "NAV_TURNAROUND:004\n");
4676    
4677 zoff99 40 return2 g_strdup(_("When possible, please turn around"));
4678     }
4679 zoff99 41
4680     if (!connect)
4681     {
4682     if (want_this_level == DONT_KNOW_LEVEL)
4683     {
4684     level3 = navigation_get_announce_level_cmd(nav, itm, cmd, distance - cmd->length, ((float)cur_vehicle_speed / 3.6f) );
4685     }
4686     else
4687     {
4688     level3 = want_this_level;
4689     }
4690     }
4691    
4692     if (want_this_level == DONT_KNOW_LEVEL)
4693     {
4694     level_now = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length, ((float)cur_vehicle_speed / 3.6f) );
4695     }
4696     else
4697     {
4698     level_now = want_this_level;
4699     }
4700 zoff99 40 }
4701    
4702    
4703    
4704     switch (level3)
4705     {
4706     case 3:
4707     if (distance > 500)
4708     {
4709     d = get_distance(nav, distance, type, 1);
4710     ret = g_strdup_printf(_("Follow the road for the next %s"), d);
4711     g_free(d);
4712     }
4713     else
4714     {
4715     ret = g_strdup("");
4716     }
4717     return2 ret;
4718     // break;
4719     case 2:
4720     d = g_strdup(_("soon"));
4721     break;
4722     case 1:
4723     d = get_distance(nav, distance, attr_navigation_short, 0);
4724     break;
4725     case 0:
4726     // d = g_strdup(_("now"));
4727     d = g_strdup("");
4728     break;
4729     }
4730    
4731    
4732     // are there more commands left?
4733     if (cmd->itm->next)
4734     {
4735     int tellstreetname = 0;
4736     char *destination = NULL;
4737    
4738     if (type == attr_navigation_speech)
4739     {
4740     if (level3 == 1)
4741     {
4742     tellstreetname = 1; // Ok so we tell the name of the street
4743     }
4744     else // if (level3 == 0)
4745     {
4746     tellstreetname = 0;
4747     }
4748     }
4749     else
4750     {
4751     tellstreetname = 1;
4752     }
4753    
4754     if (global_speak_streetnames == 0)
4755     {
4756     // never speak streetnames (user config option)
4757     tellstreetname = 0;
4758     }
4759    
4760     if (nav->tell_street_name && tellstreetname)
4761     {
4762     destination = navigation_item_destination(nav, cmd->itm, itm, " ");
4763     }
4764    
4765    
4766     if (connect == 0)
4767     {
4768     //dbg(0, "level3=%5$d str=%1$s%2$s %3$s%4$s\n", strength, dir, d, destination ? destination : "", level3);
4769    
4770     if (level3 == 0)
4771     {
4772     if (against_oneway == 1)
4773     {
4774 zoff99 41 #if 1
4775 zoff99 40 if (delta < 10)
4776     {
4777     ret = g_strdup_printf("%s", _("oncoming traffic!")); // just say "attention oneway street!"
4778     }
4779     else
4780     {
4781     ret = g_strdup_printf("%s, %s", dir, _("oncoming traffic!")); // just say "left" or "right" at the turn + "attention oneway street!"
4782     }
4783 zoff99 41 #endif
4784    
4785 zoff99 40 }
4786     else
4787     {
4788 zoff99 41 #if 1
4789 zoff99 40 if (delta >= 10)
4790     {
4791     ret = g_strdup(dir); // just say "left" or "right" at the turn
4792     }
4793     else
4794     {
4795     ret = g_strdup("");
4796     }
4797 zoff99 41 #endif
4798    
4799     #if 0
4800     if (delta == 0)
4801     {
4802     ret = g_strdup(dir); // just say "left" or "right" or "straight" at the turn
4803     }
4804     else
4805     {
4806     if (keep_dir != 0)
4807     {
4808     if (keep_dir == -1)
4809     {
4810     // TRANSLATORS: The argument is the distance. Example: 'keep left in 100 meters'
4811     ret = g_strdup_printf(_("keep left %s"), "");
4812     }
4813     else
4814     {
4815     // TRANSLATORS: The argument is the distance. Example: 'keep right in 100 meters'
4816     ret = g_strdup_printf(_("keep right %s"), "");
4817     }
4818     }
4819     else
4820     {
4821     if (delta >= 10)
4822     {
4823     ret = g_strdup(dir); // just say "left" or "right" at the turn
4824     }
4825     else
4826     {
4827     ret = g_strdup("");
4828     }
4829     }
4830     }
4831     #endif
4832    
4833 zoff99 40 }
4834     }
4835     else // if (level3 == 1)
4836     {
4837     if ((against_oneway == 1) && (delta < 10))
4838     {
4839     ret = g_strdup(""); // probably just going against a oneway street, but travelling straight on. dont say anything now
4840     }
4841     else
4842     {
4843     if (delta >= 10)
4844     {
4845     // 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'
4846     ret = g_strdup_printf_4_str(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
4847     }
4848     else
4849     {
4850     ret = g_strdup("");
4851     }
4852     }
4853     }
4854    
4855     }
4856     else // (connect == 1)
4857     {
4858     if (level3 == 0)
4859     {
4860     if (against_oneway == 1)
4861     {
4862     if (delta < 10)
4863     {
4864     ret = g_strdup_printf("%s %s", _("then"), _("oncoming traffic!"));
4865     }
4866     else
4867     {
4868     ret = g_strdup_printf("%s %s %s", _("then"), dir, _("oncoming traffic!"));
4869     }
4870     }
4871     else
4872     {
4873     if (delta >= 10)
4874     {
4875     ret = g_strdup_printf("%s %s", _("then"), dir);
4876     }
4877     else
4878     {
4879     ret = g_strdup("");
4880     }
4881     }
4882     }
4883     else // if (level3 == 1)
4884     {
4885     if (against_oneway == 1)
4886     {
4887     if (delta < 10)
4888     {
4889     // nothing
4890     ret = g_strdup("");
4891     }
4892     else
4893     {
4894 zoff99 50 // TRANSLATORS: First argument is strength, second direction, third distance, fourth destination
4895 zoff99 40 ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
4896     }
4897     }
4898     else
4899     {
4900     if (delta >= 10)
4901     {
4902 zoff99 50 // TRANSLATORS: First argument is strength, second direction, third distance, fourth destination
4903 zoff99 40 ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
4904     }
4905     else
4906     {
4907     ret = g_strdup("");
4908     }
4909     }
4910     }
4911     }
4912    
4913    
4914     if (destination)
4915     {
4916     g_free(destination);
4917     destination = NULL;
4918     }
4919     }
4920     // no more commands left, must be at destination
4921     else
4922     {
4923     if (!connect)
4924     {
4925     d = get_distance(nav, distance, type, 1);
4926    
4927     // TRANSLATORS: EXAMPLE: You have reached your destination in 300 meters
4928     ret = g_strdup_printf(_("You have reached your destination %s"), d);
4929    
4930     g_free(d);
4931     }
4932     else
4933     {
4934     ret = g_strdup(_("then you have reached your destination."));
4935     }
4936     }
4937    
4938     return2 ret;
4939    
4940     __F_END__
4941     }
4942    
4943     int navigation_is_low_level_street(enum item_type t)
4944     {
4945     if (global_vehicle_profile == 0) // only in car profile!
4946     {
4947     if (t == type_street_service)
4948     {
4949     return 1;
4950     }
4951     else if (t == type_street_parking_lane)
4952     {
4953     return 1;
4954     }
4955     else if (t == type_track_ground)
4956     {
4957     return 1;
4958     }
4959     else if (t == type_track_grass)
4960     {
4961     return 1;
4962     }
4963     else if (t == type_track_gravelled)
4964     {
4965     return 1;
4966     }
4967     else if (t == type_track_unpaved)
4968     {
4969     return 1;
4970     }
4971     else if (t == type_track_paved)
4972     {
4973     return 1;
4974     }
4975     }
4976    
4977     return 0;
4978     }
4979    
4980 zoff99 41
4981    
4982 zoff99 40 static char *
4983 zoff99 41 show_maneuver_at_level(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type, int connect, int want_this_level, int override_tellstreetname)
4984 zoff99 2 {
4985 zoff99 40 __F_START__
4986    
4987 zoff99 27 // TRANSLATORS: right, as in 'Turn right'
4988     char *dir = _("right");
4989     char *strength = "";
4990     int distance = itm->dest_length - cmd->itm->dest_length;
4991     char *d, *ret = NULL;
4992     int delta = cmd->delta;
4993 zoff99 41 int delta_real = cmd->delta_real;
4994 zoff99 2 int level;
4995 zoff99 40 int level_now = 99;
4996 zoff99 2 int strength_needed;
4997     int skip_roads;
4998 zoff99 46 int count_roundabout; // car mode ----
4999 zoff99 2 struct navigation_itm *cur;
5000     struct navigation_way *w;
5001 zoff99 40 int against_oneway = 0;
5002 zoff99 46 int keep_dir = 0; // car mode ----
5003 zoff99 41 int old_dir = 0;
5004 zoff99 27
5005     if (connect)
5006     {
5007 zoff99 2 level = -2; // level = -2 means "connect to another maneuver via 'then ...'"
5008     }
5009 zoff99 27 else
5010     {
5011 zoff99 41 if (want_this_level == DONT_KNOW_LEVEL)
5012     {
5013     level = 1;
5014     }
5015     else
5016     {
5017     level = want_this_level;
5018     }
5019 zoff99 27 }
5020 zoff99 2
5021 zoff99 41 int cur_vehicle_speed = 0;
5022     if ((global_navit) && (global_navit->vehicle))
5023     {
5024     cur_vehicle_speed = global_navit->vehicle->speed; // in km/h
5025     }
5026    
5027    
5028 zoff99 40 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
5029     {
5030     //dbg(0, "itm->way.flags=%x\n", itm->way.flags);
5031     //dbg(0, "itm->next->way.flags=%x\n", itm->next->way.flags);
5032    
5033     // int flags_old = navigation_item_get_flags(&itm->way);
5034     // int flags_new = navigation_item_get_flags(&itm->next->way);
5035     // dbg(0, "old flags=%x new flags=%x\n", flags_old, flags_new);
5036    
5037     if ( (itm->way.dir == 1) && ((itm->next->way.dir == -1) && (itm->next->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)) )
5038     {
5039     against_oneway = 1;
5040     //dbg(0, "SPEAK: (1)going against oneway street!\n");
5041     }
5042     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)) )
5043     {
5044     against_oneway = 1;
5045     //dbg(0, "SPEAK: (2)going against oneway street!\n");
5046     }
5047     }
5048    
5049 zoff99 2 w = itm->next->way.next;
5050     strength_needed = 0;
5051 zoff99 27
5052 zoff99 40 //dbg(0, "STRENGTH:001:strength_needed = %d delta = %d\n", strength_needed, delta);
5053    
5054     if (angle_delta(itm->next->way.angle2, itm->angle_end) < 0) // left
5055 zoff99 27 {
5056     while (w)
5057     {
5058 zoff99 40 if (angle_delta(w->angle2, itm->angle_end) < 0) // other ways are going left
5059 zoff99 27 {
5060 zoff99 2 strength_needed = 1;
5061 zoff99 40 // dbg(0, "STRENGTH:002:strength_needed = %d\n", strength_needed);
5062 zoff99 2 break;
5063     }
5064     w = w->next;
5065     }
5066 zoff99 27 }
5067 zoff99 40 else // right
5068 zoff99 27 {
5069     while (w)
5070     {
5071 zoff99 40 if (angle_delta(w->angle2, itm->angle_end) > 0) // other ways are going right
5072 zoff99 27 {
5073 zoff99 2 strength_needed = 1;
5074 zoff99 40 // dbg(0, "STRENGTH:003:strength_needed = %d\n", strength_needed);
5075 zoff99 2 break;
5076     }
5077     w = w->next;
5078     }
5079     }
5080    
5081 zoff99 46 if ((strength_needed == 0) && (delta < 9)) // for corrected turn (delta will be 8), use strength ("slight")
5082 zoff99 40 {
5083     strength_needed = 1;
5084     }
5085    
5086 zoff99 46 // dbg(0, "STRAI:K001:strength_needed=%d delta=%d delta_real=%d\n", strength_needed, delta, delta_real);
5087    
5088 zoff99 40 //dbg(0, "cmd->delta=%d\n", delta);
5089    
5090 zoff99 27 if (delta < 0)
5091     {
5092     #ifdef HAVE_API_ANDROID
5093 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5094 zoff99 27 android_send_generic_text(1,"+*#O:left\n");
5095     #endif
5096 zoff99 28 #endif
5097 zoff99 27 // TRANSLATORS: left, as in 'Turn left'
5098     dir = _("left");
5099     delta = -delta;
5100 zoff99 41
5101     old_dir = -1; // left
5102    
5103 zoff99 2 }
5104 zoff99 40 else if (delta > 0)
5105 zoff99 27 {
5106 zoff99 41
5107     old_dir = 1; // right
5108    
5109 zoff99 27 // dir = right
5110     #ifdef HAVE_API_ANDROID
5111 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5112 zoff99 27 android_send_generic_text(1,"+*#O:right\n");
5113     #endif
5114 zoff99 28 #endif
5115 zoff99 27 }
5116 zoff99 40 else // delta == 0 // go straight
5117     {
5118     dir = _("straight");
5119     strength_needed = 0;
5120     // dbg(0, "STRENGTH:004:strength_needed = %d\n", strength_needed);
5121     }
5122 zoff99 2
5123 zoff99 46 dbg(0, "STRAI:K002:*:strength_needed=%d delta=%d delta_real=%d\n", strength_needed, delta, delta_real);
5124 zoff99 40
5125 zoff99 46
5126 zoff99 41 keep_dir = 0;
5127    
5128 zoff99 27 if (strength_needed)
5129     {
5130 zoff99 40 // dbg(0, "STRENGTH:005:\n");
5131    
5132    
5133 zoff99 27 if (delta < 45)
5134     {
5135     #ifdef HAVE_API_ANDROID
5136 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5137 zoff99 27 android_send_generic_text(1,"+*#O:slight \n");
5138     #endif
5139 zoff99 28 #endif
5140 zoff99 27 // TRANSLATORS: Don't forget the ending space
5141     // TRANSLATORS: EXAMPLE: turn slight right
5142 zoff99 41 strength = _("slighty ");
5143     // TRANSLATORS: Don't forget the ending space
5144     // TRANSLATORS: EXAMPLE: turn slight right
5145 zoff99 27 strength = _("slight ");
5146 zoff99 40
5147 zoff99 41 if (delta_real == 0) // keep left/right
5148     {
5149     if (old_dir == -1)
5150     {
5151     keep_dir = -1;
5152     }
5153     else
5154     {
5155     keep_dir = 1;
5156     }
5157     }
5158    
5159 zoff99 46 dbg(0, "STRENGTH:006:strength_needed = %s\n", strength);
5160 zoff99 40
5161 zoff99 2 }
5162 zoff99 27 else if (delta < 105)
5163     {
5164     strength = "";
5165     }
5166     else if (delta < 165)
5167     {
5168     #ifdef HAVE_API_ANDROID
5169 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5170 zoff99 27 android_send_generic_text(1,"+*#O:hard \n");
5171     #endif
5172 zoff99 28 #endif
5173 zoff99 27 // TRANSLATORS: Don't forget the ending space
5174     // TRANSLATORS: EXAMPLE: turn hard right
5175     strength = _("hard ");
5176     }
5177     else if (delta < 180)
5178     {
5179     #ifdef HAVE_API_ANDROID
5180 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5181 zoff99 27 android_send_generic_text(1,"+*#O:really hard \n");
5182     #endif
5183 zoff99 28 #endif
5184 zoff99 27 // TRANSLATORS: Don't forget the ending space
5185     // TRANSLATORS: EXAMPLE: turn really hard right
5186     strength = _("really hard ");
5187     }
5188     else
5189     {
5190     // dbg(1,"delta=%d\n", delta);
5191     strength = "";
5192     }
5193 zoff99 2 }
5194 zoff99 27
5195 zoff99 40 // dbg(0, "STRENGTH:010:strength_needed = %s\n", strength);
5196    
5197    
5198 zoff99 27 if (type != attr_navigation_long_exact)
5199     {
5200     distance = round_distance(distance);
5201     }
5202    
5203     if (type == attr_navigation_speech)
5204     {
5205 zoff99 41 dbg(0, "NAV_TURNAROUND:001 ta=%d talimit=%d\n", nav->turn_around, nav->turn_around_limit);
5206    
5207 zoff99 27 if (nav->turn_around && nav->turn_around == nav->turn_around_limit)
5208     {
5209 zoff99 41
5210     dbg(0, "NAV_TURNAROUND:002:*******\n");
5211    
5212 zoff99 27 #ifdef HAVE_API_ANDROID
5213 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5214 zoff99 27 android_send_generic_text(1,"+*#O:When possible, please turn around\n");
5215     #endif
5216 zoff99 28 #endif
5217 zoff99 40 return2 g_strdup(_("When possible, please turn around"));
5218 zoff99 2 }
5219 zoff99 27
5220     if (!connect)
5221     {
5222 zoff99 41 if (want_this_level == DONT_KNOW_LEVEL)
5223     {
5224     level = navigation_get_announce_level_cmd(nav, itm, cmd, distance - cmd->length, ((float)cur_vehicle_speed / 3.6f) );
5225     }
5226     else
5227     {
5228     level = want_this_level;
5229     }
5230 zoff99 27 }
5231 zoff99 40
5232 zoff99 41 if (want_this_level == DONT_KNOW_LEVEL)
5233     {
5234     level_now = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length, ((float)cur_vehicle_speed / 3.6f) );
5235     }
5236     else
5237     {
5238     level_now = want_this_level;
5239     }
5240    
5241 zoff99 2 }
5242    
5243 zoff99 41 #ifdef NAVIT_DEBUG_COORD_LIST
5244 zoff99 40 int need_clear = 1;
5245     #endif
5246    
5247    
5248 zoff99 46 #if 1
5249     // ------------------- jandegr -------------------
5250    
5251     struct navigation_way *candidate_way;
5252    
5253 zoff99 34 if (cmd->itm->prev->way.flags & NAVIT_AF_ROUNDABOUT)
5254 zoff99 27 {
5255 zoff99 2 cur = cmd->itm->prev;
5256     count_roundabout = 0;
5257 zoff99 40
5258 zoff99 46 // ----- fix -----
5259 zoff99 40 struct navigation_itm *cur_orig = cur->next;
5260    
5261     enum item_type cur_street_type = 0;
5262     int exit_is_lover_street_type = 0;
5263     cur_street_type = cur_orig->way.item.type;
5264     // dbg(0, "curr item type=%s\n", item_to_name(cur_orig->way.item.type));
5265     exit_is_lover_street_type = navigation_is_low_level_street(cur_street_type);
5266    
5267     int next_exit_is_lower_street_type = 0;
5268 zoff99 46 // ----- fix -----
5269 zoff99 40
5270 zoff99 46
5271     dbg(0, "ROUNDABT:001:enter\n");
5272    
5273 zoff99 34 while (cur && (cur->way.flags & NAVIT_AF_ROUNDABOUT))
5274 zoff99 27 {
5275 zoff99 46
5276     // dbg(0, "ROUNDABT:002:loop-1:w\n");
5277    
5278     candidate_way=cur->next->way.next;
5279     while (candidate_way)
5280     {
5281    
5282     dbg(0, "ROUNDABT:002:loop-2:w2 type=%s\n", item_to_name(candidate_way->item.type));
5283    
5284     // If the next segment has no exit or the exit isn't allowed, don't count it
5285     if (candidate_way && is_way_allowed(nav, candidate_way, 3))
5286     {
5287    
5288     dbg(0, "ROUNDABT:003:is_allowed type=%s\n", item_to_name(candidate_way->item.type));
5289    
5290     // only count street_service (and lesser streets) if we also exit on street_service (or any lesser street)
5291     if (cur->next)
5292     {
5293     next_exit_is_lower_street_type = navigation_is_low_level_street(candidate_way->item.type);
5294    
5295     dbg(0, "ROUNDABT:004:next_exit_is_lower_street_type=%d type=%s\n", next_exit_is_lower_street_type, item_to_name(candidate_way->item.type));
5296     }
5297    
5298     if ((exit_is_lover_street_type == 1) || (next_exit_is_lower_street_type == 0))
5299     {
5300     count_roundabout++;
5301    
5302     dbg(0, "ROUNDABT:005:found:count_roundabout=%d\n", count_roundabout);
5303    
5304     /* As soon as we have an allowed one on this node,
5305     * stop further counting for this node.
5306     */
5307     candidate_way = candidate_way->next;
5308     break;
5309     }
5310     }
5311     candidate_way=candidate_way->next;
5312     }
5313     cur = cur->prev;
5314     }
5315    
5316     /*try to figure out if the entry node has a usable exit as well
5317     *
5318     * this will fail for left-hand driving areas
5319     */
5320     if (cur && cur->next)
5321     {
5322     dbg(0, "ROUNDABT:007:entry-check\n");
5323    
5324     candidate_way = cur->next->way.next;
5325     while (candidate_way)
5326     {
5327     dbg(0, "ROUNDABT:008:loop-3:w3 type=%s\n", item_to_name(candidate_way->item.type));
5328    
5329     if (candidate_way && is_way_allowed(nav,candidate_way,3)
5330     && (cur->angle_end < candidate_way->angle2) && ( candidate_way->angle2 > cur->next->way.angle2 ))
5331     /*for the entry node only count exits to the right ?*/
5332     {
5333     count_roundabout++;
5334    
5335     dbg(0, "ROUNDABT:009:entry:found:count_roundabout=%d\n", count_roundabout);
5336     /* As soon as we have an allowed one on this node,
5337     * stop further counting for this node.
5338     */
5339     break;
5340     }
5341     candidate_way = candidate_way->next;
5342     }
5343     }
5344    
5345     switch (level)
5346     {
5347     #if 0
5348     case 3:
5349     d=get_distance(nav, distance, type, 1);
5350     return g_strdup_printf(_("Follow the road for the next %s"), d);
5351     #endif
5352     case 2:
5353     return2 g_strdup(_("Enter the roundabout soon"));
5354     case 1:
5355     // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit
5356     return2 g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
5357     case -2:
5358     // TRANSLATORS: EXAMPLE: ... then leave the roundabout at the second exit
5359     return2 g_strdup_printf(_("then leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
5360     case 0:
5361     // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit
5362     return2 g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
5363     }
5364     }
5365    
5366    
5367     // ------------------- jandegr -------------------
5368     #endif
5369    
5370    
5371    
5372    
5373    
5374    
5375    
5376     #if 0
5377     // ------------------- zoff -------------------
5378    
5379     if (cmd->itm->prev->way.flags & NAVIT_AF_ROUNDABOUT)
5380     {
5381     cur = cmd->itm->prev;
5382     count_roundabout = 0;
5383    
5384     struct navigation_itm *cur_orig = cur->next;
5385    
5386     enum item_type cur_street_type = 0;
5387     int exit_is_lover_street_type = 0;
5388     cur_street_type = cur_orig->way.item.type;
5389     // dbg(0, "curr item type=%s\n", item_to_name(cur_orig->way.item.type));
5390     exit_is_lover_street_type = navigation_is_low_level_street(cur_street_type);
5391    
5392     int next_exit_is_lower_street_type = 0;
5393    
5394     while (cur && (cur->way.flags & NAVIT_AF_ROUNDABOUT))
5395     {
5396 zoff99 27 // If the next segment has no exit or the exit isn't allowed, don't count it
5397 zoff99 30 if (cur->next->way.next && is_way_allowed(nav, cur->next->way.next, 3))
5398 zoff99 27 {
5399 zoff99 40
5400     // only count street_service (and lesser streets) if we also exit on street_service (or any lesser street)
5401     if (cur->next)
5402     {
5403     next_exit_is_lower_street_type = navigation_is_low_level_street(cur->next->way.next->item.type);
5404     }
5405    
5406     if ((exit_is_lover_street_type == 1) || (next_exit_is_lower_street_type == 0))
5407     {
5408     count_roundabout++;
5409    
5410 zoff99 41 #ifdef NAVIT_DEBUG_COORD_LIST
5411 zoff99 40 if (need_clear == 1)
5412     {
5413     need_clear = 0;
5414     global_debug_coord_list_items = 0;
5415    
5416     struct coord c2[5];
5417    
5418     if (navigation_get_real_item_first_coord(&(cur_orig->way), c2))
5419     {
5420     global_debug_coord_list[global_debug_coord_list_items].x = c2[0].x;
5421     global_debug_coord_list[global_debug_coord_list_items].y = c2[0].y;
5422     global_debug_coord_list_items++;
5423     global_debug_coord_list[global_debug_coord_list_items].x = c2[1].x;
5424     global_debug_coord_list[global_debug_coord_list_items].y = c2[1].y;
5425     global_debug_coord_list_items++;
5426     }
5427    
5428     }
5429    
5430     struct coord c1[5];
5431     if (navigation_get_real_item_first_coord(cur->next->way.next, c1))
5432     {
5433     if ((global_debug_coord_list_items + 2) > MAX_DEBUG_COORDS)
5434     {
5435     global_debug_coord_list_items = 0;
5436     }
5437    
5438     global_debug_coord_list[global_debug_coord_list_items].x = c1[0].x;
5439     global_debug_coord_list[global_debug_coord_list_items].y = c1[0].y;
5440     global_debug_coord_list_items++;
5441     global_debug_coord_list[global_debug_coord_list_items].x = c1[1].x;
5442     global_debug_coord_list[global_debug_coord_list_items].y = c1[1].y;
5443     global_debug_coord_list_items++;
5444     }
5445     #endif
5446    
5447     }
5448 zoff99 2 }
5449     cur = cur->prev;
5450     }
5451 zoff99 27
5452     gchar* xy;
5453    
5454     switch (level)
5455     {
5456     case 2:
5457     #ifdef HAVE_API_ANDROID
5458 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5459 zoff99 27 android_send_generic_text(1,"+*#O:Enter the roundabout soon\n");
5460     #endif
5461 zoff99 28 #endif
5462 zoff99 40 return2 g_strdup(_("Enter the roundabout soon"));
5463    
5464    
5465    
5466    
5467 zoff99 27 case 1:
5468 zoff99 40
5469    
5470     #ifdef HAVE_API_ANDROID
5471     #ifdef NAVIT_SAY_DEBUG_PRINT
5472     android_send_generic_text(1,"+*#O:Leave the roundabout at the %s\n");
5473     xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
5474     android_send_generic_text(1,xy);
5475     g_free(xy);
5476     #endif
5477     #endif
5478     // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit
5479     return2 g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
5480    
5481    
5482     // ---- DISABLED ----
5483     #if 0
5484 zoff99 27 d = get_distance(nav, distance, type, 1);
5485    
5486     #ifdef HAVE_API_ANDROID
5487 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5488 zoff99 27 android_send_generic_text(1,"+*#O:In %s, enter the roundabout\n");
5489     xy=g_strdup_printf("+*#1:%s\n", d);
5490     android_send_generic_text(1,xy);
5491     g_free(xy);
5492     #endif
5493 zoff99 28 #endif
5494 zoff99 27 // TRANSLATORS: %s is the distance to the roundabout
5495     // TRANSLATORS: EXAMPLE: In 300m, enter the roundabout
5496     ret = g_strdup_printf(_("In %s, enter the roundabout"), d);
5497     g_free(d);
5498 zoff99 40 return2 ret;
5499     #endif
5500     // ---- DISABLED ----
5501    
5502    
5503    
5504 zoff99 27 case -2:
5505     #ifdef HAVE_API_ANDROID
5506 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5507 zoff99 27 android_send_generic_text(1,"+*#O:then leave the roundabout at the %s\n");
5508     xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
5509     android_send_generic_text(1,xy);
5510     g_free(xy);
5511     #endif
5512 zoff99 28 #endif
5513 zoff99 27 // TRANSLATORS: EXAMPLE: ... then leave the roundabout at the second exit
5514 zoff99 40 return2 g_strdup_printf(_("then leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
5515    
5516    
5517 zoff99 27 case 0:
5518     #ifdef HAVE_API_ANDROID
5519 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5520 zoff99 27 android_send_generic_text(1,"+*#O:Leave the roundabout at the %s\n");
5521     xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
5522     android_send_generic_text(1,xy);
5523     g_free(xy);
5524     #endif
5525 zoff99 28 #endif
5526 zoff99 27 // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit
5527 zoff99 40 return2 g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
5528 zoff99 27 }
5529     }
5530    
5531 zoff99 46 // ------------------- zoff -------------------
5532     #endif
5533    
5534    
5535    
5536    
5537    
5538    
5539    
5540    
5541    
5542 zoff99 40 // -- NEW 002 --
5543     if (cmd->itm)
5544     {
5545     // put correct destination into struct (to later show in GUI)
5546     navigation_select_announced_destinations(cmd);
5547     // string is in cmd->itm->way.street_dest_text
5548     }
5549     // -- NEW 002 --
5550    
5551    
5552    
5553 zoff99 27 switch (level)
5554     {
5555     case 3:
5556 zoff99 40 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
5557     {
5558     if (distance > 500)
5559     {
5560     d = get_distance(nav, distance, type, 1);
5561 zoff99 27
5562     #ifdef HAVE_API_ANDROID
5563 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5564 zoff99 40 android_send_generic_text(1,"+*#O:Follow the road for the next %s\n");
5565     gchar* xy=g_strdup_printf("+*#1:%s\n", d);
5566     android_send_generic_text(1,xy);
5567     g_free(xy);
5568 zoff99 27 #endif
5569 zoff99 28 #endif
5570 zoff99 40
5571     ret = g_strdup_printf(_("Follow the road for the next %s"), d);
5572     g_free(d);
5573     }
5574     else
5575     {
5576     ret = g_strdup("");
5577     }
5578     }
5579     else
5580     {
5581     d = get_distance(nav, distance, type, 1);
5582    
5583     #ifdef HAVE_API_ANDROID
5584     #ifdef NAVIT_SAY_DEBUG_PRINT
5585     android_send_generic_text(1,"+*#O:Follow the road for the next %s\n");
5586     gchar* xy=g_strdup_printf("+*#1:%s\n", d);
5587     android_send_generic_text(1,xy);
5588     g_free(xy);
5589     #endif
5590     #endif
5591     // TRANSLATORS: EXAMPLE: Follow the road for the next 300 meters
5592     ret = g_strdup_printf(_("Follow the road for the next %s"), d);
5593     g_free(d);
5594     }
5595     return2 ret;
5596 zoff99 2 case 2:
5597 zoff99 27 #ifdef HAVE_API_ANDROID
5598 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5599 zoff99 27 android_send_generic_text(1,"+*#O:soon\n");
5600     #endif
5601 zoff99 28 #endif
5602 zoff99 40
5603     // dbg(0, "SPK:*soon*\n");
5604    
5605    
5606 zoff99 27 d = g_strdup(_("soon"));
5607     break;
5608 zoff99 2 case 1:
5609 zoff99 27 d = get_distance(nav, distance, attr_navigation_short, 0);
5610     break;
5611     case 0:
5612 zoff99 50 // DISABLE S_R // skip_roads = count_possible_turns(nav, cmd->prev ? cmd->prev->itm : nav->first, cmd->itm, cmd->delta);
5613     skip_roads = 0;
5614 zoff99 48
5615     dbg(0, "count_possible_turns:1:%d", skip_roads);
5616    
5617 zoff99 40 if ((skip_roads > 0) && ((global_vehicle_profile != 1) && (global_vehicle_profile != 2)))
5618 zoff99 27 {
5619     if (get_count_str(skip_roads + 1))
5620     {
5621 zoff99 48
5622     // marker -1- //
5623    
5624 zoff99 27 #ifdef HAVE_API_ANDROID
5625 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5626 zoff99 27 android_send_generic_text(1,"+*#O:Take the %1$s road to the %2$s\n");
5627     gchar* xy=g_strdup_printf("+*#1:%s\n", get_count_str(skip_roads + 1));
5628     android_send_generic_text(1,xy);
5629     g_free(xy);
5630     xy=g_strdup_printf("+*#1:%s\n", dir);
5631     android_send_generic_text(1,xy);
5632     g_free(xy);
5633     #endif
5634 zoff99 28 #endif
5635 zoff99 27 // TRANSLATORS: First argument is the how manieth street to take, second the direction
5636 zoff99 40 ret = g_strdup_printf_2_str(_("Take the %1$s road to the %2$s"), get_count_str(skip_roads + 1), dir);
5637     return2 ret;
5638 zoff99 27 }
5639     else
5640     {
5641     #ifdef HAVE_API_ANDROID
5642 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5643 zoff99 27 android_send_generic_text(1,"+*#O:after %i roads\n");
5644     gchar* xy=g_strdup_printf("+*#1:%i\n", skip_roads);
5645     android_send_generic_text(1,xy);
5646     g_free(xy);
5647     #endif
5648 zoff99 28 #endif
5649 zoff99 27 d = g_strdup_printf(_("after %i roads"), skip_roads);
5650     }
5651     }
5652     else
5653     {
5654     #ifdef HAVE_API_ANDROID
5655 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5656 zoff99 27 android_send_generic_text(1,"+*#O:now\n");
5657     #endif
5658 zoff99 28 #endif
5659 zoff99 27 d = g_strdup(_("now"));
5660     }
5661 zoff99 40
5662 zoff99 27 break;
5663 zoff99 40
5664 zoff99 2 case -2:
5665 zoff99 50 // DISABLE S_R // skip_roads = count_possible_turns(nav, cmd->prev->itm, cmd->itm, cmd->delta);
5666     skip_roads = 0;
5667 zoff99 48
5668     dbg(0, "count_possible_turns:2:%d", skip_roads);
5669    
5670 zoff99 40 if ((skip_roads > 0) && ((global_vehicle_profile != 1) && (global_vehicle_profile != 2)))
5671 zoff99 27 {
5672     // TRANSLATORS: First argument is the how manieth street to take, second the direction
5673     // TRANSLATORS: EXAMPLE: ... then take the second road to the right
5674     if (get_count_str(skip_roads + 1))
5675     {
5676 zoff99 48
5677     // marker -2- //
5678    
5679 zoff99 27 #ifdef HAVE_API_ANDROID
5680 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5681 zoff99 27 android_send_generic_text(1,"+*#O:then take the %1$s road to the %2$s\n");
5682     gchar* xy=g_strdup_printf("+*#1:%s\n", get_count_str(skip_roads + 1));
5683     android_send_generic_text(1,xy);
5684     g_free(xy);
5685     xy=g_strdup_printf("+*#1:%s\n", dir);
5686     android_send_generic_text(1,xy);
5687     g_free(xy);
5688     #endif
5689 zoff99 28 #endif
5690 zoff99 40 ret = g_strdup_printf_2_str(_("then take the %1$s road to the %2$s"), get_count_str(skip_roads + 1), dir);
5691     return2 ret;
5692 zoff99 27 }
5693     else
5694     {
5695     #ifdef HAVE_API_ANDROID
5696 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5697 zoff99 27 android_send_generic_text(1,"+*#O:after %i roads\n");
5698     gchar* xy=g_strdup_printf("+*#1:%i\n", skip_roads);
5699     android_send_generic_text(1,xy);
5700     g_free(xy);
5701     #endif
5702 zoff99 28 #endif
5703 zoff99 27 d = g_strdup_printf(_("after %i roads"), skip_roads);
5704     }
5705 zoff99 2
5706     }
5707 zoff99 27 else
5708     {
5709     d = g_strdup("");
5710 zoff99 2 }
5711 zoff99 27 break;
5712     default:
5713     #ifdef HAVE_API_ANDROID
5714 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5715 zoff99 27 android_send_generic_text(1,"+*#O:error\n");
5716     #endif
5717 zoff99 28 #endif
5718 zoff99 27 d = g_strdup(_("error"));
5719     }
5720 zoff99 2
5721 zoff99 41
5722    
5723 zoff99 27 if (cmd->itm->next)
5724     {
5725 zoff99 40 // dbg(0, "SPK:000a\n");
5726    
5727 zoff99 2 int tellstreetname = 0;
5728     char *destination = NULL;
5729 zoff99 27
5730     if (type == attr_navigation_speech)
5731 zoff99 41 {
5732 zoff99 27 if (level == 1)
5733 zoff99 41 {
5734     cmd->itm->streetname_told = 1;
5735 zoff99 2 tellstreetname = 1; // Ok so we tell the name of the street
5736     }
5737    
5738 zoff99 27 if (level == 0)
5739     {
5740     if (cmd->itm->streetname_told == 0) // we are right at the intersection
5741     {
5742     tellstreetname = 1;
5743     }
5744 zoff99 2 else
5745 zoff99 27 {
5746     cmd->itm->streetname_told = 0; // reset just in case we come to the same street again
5747     }
5748 zoff99 2 }
5749    
5750     }
5751     else
5752 zoff99 27 {
5753     tellstreetname = 1;
5754     }
5755 zoff99 2
5756 zoff99 27 if (global_speak_streetnames == 0)
5757     {
5758     // never speak streetnames (user config option)
5759     tellstreetname = 0;
5760     }
5761 zoff99 2
5762 zoff99 41
5763    
5764     if (override_tellstreetname != -1)
5765     {
5766    
5767 zoff99 40 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5768 zoff99 41 dbg(0, "SPK:level=%d street_dest_text=%p tellstreetname=%d\n", level, cmd->itm->way.street_dest_text, tellstreetname);
5769 zoff99 40 #endif
5770 zoff99 41 if (nav->tell_street_name && tellstreetname)
5771     {
5772     destination = navigation_item_destination(nav, cmd->itm, itm, " ");
5773 zoff99 40 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5774 zoff99 41 dbg(0, "SPK:levelX=%d dest=%s\n", level, destination);
5775 zoff99 40 #endif
5776 zoff99 41 }
5777     else if ((global_speak_streetnames == 1) && (cmd->itm->way.street_dest_text))
5778     {
5779     destination = navigation_item_destination(nav, cmd->itm, itm, " ");
5780 zoff99 40 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5781 zoff99 41 dbg(0, "SPK:levely=%d dest=%s d=%s\n", level, destination, cmd->itm->way.street_dest_text);
5782 zoff99 40 #endif
5783 zoff99 27
5784 zoff99 41 cmd->itm->streetname_told = 0;
5785     }
5786 zoff99 40 }
5787    
5788 zoff99 41
5789 zoff99 40 // dbg(0, "SPK:001\n");
5790    
5791 zoff99 27 if (level != -2)
5792     {
5793 zoff99 40
5794     //dbg(0, "SPK:002\n");
5795    
5796 zoff99 27 #ifdef HAVE_API_ANDROID
5797 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5798 zoff99 27 android_send_generic_text(1,"+*#O:Turn %1$s%2$s %3$s%4$s\n");
5799     gchar* xy=g_strdup_printf("+*#1:%s\n", strength);
5800     android_send_generic_text(1,xy);
5801     g_free(xy);
5802     xy=g_strdup_printf("+*#1:%s\n", dir);
5803     android_send_generic_text(1,xy);
5804     g_free(xy);
5805     xy=g_strdup_printf("+*#1:%s\n", d);
5806     android_send_generic_text(1,xy);
5807     g_free(xy);
5808     xy=g_strdup_printf("+*#1:%s\n", destination ? destination : "");
5809     android_send_generic_text(1,xy);
5810     g_free(xy);
5811     #endif
5812 zoff99 28 #endif
5813 zoff99 40
5814 zoff99 41 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)) // bicycle mode
5815 zoff99 40 {
5816     //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);
5817    
5818     if (level_now == 0)
5819     {
5820     if (against_oneway == 1)
5821     {
5822     if (delta < 8)
5823     {
5824     ret = g_strdup_printf("%s", _("oncoming traffic!")); // just say "attention oneway street!"
5825     }
5826     else
5827     {
5828     ret = g_strdup_printf("%s, %s", dir, _("oncoming traffic!")); // just say "left" or "right" at the turn + "attention oneway street!"
5829     }
5830     }
5831     else
5832     {
5833     ret = g_strdup(dir); // just say "left" or "right" at the turn
5834     }
5835     }
5836     else
5837     {
5838     if ((against_oneway == 1) && (delta < 8))
5839     {
5840     ret = g_strdup(""); // probably just going against a oneway street, but travelling straight on. dont say anything now
5841     }
5842     else
5843     {
5844     if (delta == 0)
5845     {
5846     // 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'
5847     ret = g_strdup_printf_4_str(_("%1$s%2$s %3$s%4$s"), "", dir, d, destination ? destination : "");
5848     }
5849     else
5850     {
5851     // 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'
5852     ret = g_strdup_printf_4_str(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
5853     }
5854     }
5855     }
5856     }
5857 zoff99 41 else // car mode
5858 zoff99 40 {
5859     if (delta == 0)
5860     {
5861     // 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'
5862     ret = g_strdup_printf_4_str(_("%1$s%2$s %3$s%4$s"), "", dir, d, destination ? destination : "");
5863     }
5864     else
5865     {
5866 zoff99 41 if (keep_dir != 0)
5867     {
5868     if (keep_dir == -1)
5869     {
5870     // TRANSLATORS: The argument is the distance. Example: 'keep left in 100 meters'
5871     ret = g_strdup_printf(_("keep left %s"), d);
5872 zoff99 46
5873     // dirty hack, so we don't need new translations
5874     char *ret2 = g_strdup_printf("%s%s", ret, destination ? destination : "");
5875     g_free(ret);
5876     ret = ret2;
5877     // ret2 = NULL;
5878 zoff99 41 }
5879     else
5880     {
5881     // TRANSLATORS: The argument is the distance. Example: 'keep right in 100 meters'
5882     ret = g_strdup_printf(_("keep right %s"), d);
5883 zoff99 46
5884     // dirty hack, so we don't need new translations
5885     char *ret2 = g_strdup_printf("%s%s", ret, destination ? destination : "");
5886     g_free(ret);
5887     ret = ret2;
5888     // ret2 = NULL;
5889 zoff99 41 }
5890     }
5891     else
5892     {
5893     // 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'
5894     ret = g_strdup_printf_4_str(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
5895     }
5896 zoff99 40 }
5897     }
5898 zoff99 27 }
5899 zoff99 41 else // (level == -2)
5900 zoff99 27 {
5901 zoff99 40
5902     //dbg(0, "SPK:007\n");
5903    
5904    
5905 zoff99 27 #ifdef HAVE_API_ANDROID
5906 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5907 zoff99 27 android_send_generic_text(1,"+*#O:then turn %1$s%2$s %3$s%4$s\n");
5908     gchar* xy=g_strdup_printf("+*#1:%s\n", strength);
5909     android_send_generic_text(1,xy);
5910     g_free(xy);
5911     xy=g_strdup_printf("+*#1:%s\n", dir);
5912     android_send_generic_text(1,xy);
5913     g_free(xy);
5914     xy=g_strdup_printf("+*#1:%s\n", d);
5915     android_send_generic_text(1,xy);
5916     g_free(xy);
5917     xy=g_strdup_printf("+*#1:%s\n", destination ? destination : "");
5918     android_send_generic_text(1,xy);
5919     g_free(xy);
5920     #endif
5921 zoff99 28 #endif
5922 zoff99 41 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)) // bicycle mode
5923 zoff99 40 {
5924     if ((against_oneway == 1) && (delta < 8))
5925     {
5926     ret = g_strdup(""); // probably just going against a oneway street, but travelling straight on. dont say anything now
5927     }
5928     else
5929     {
5930     if (delta == 0)
5931     {
5932     // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
5933     ret = g_strdup_printf_4_str(_("then %1$s%2$s %3$s%4$s"), "", dir, d, destination ? destination : "");
5934     }
5935     else
5936     {
5937     // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
5938     ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
5939     }
5940     }
5941     }
5942 zoff99 41 else // car mode
5943 zoff99 40 {
5944     if (delta == 0)
5945     {
5946     // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
5947     ret = g_strdup_printf_4_str(_("then %1$s%2$s %3$s%4$s"), "", dir, d, destination ? destination : "");
5948     }
5949     else
5950     {
5951 zoff99 41 if (keep_dir != 0)
5952     {
5953     if (keep_dir == -1)
5954     {
5955     ret = g_strdup_printf("%s", _("then keep left"));
5956     }
5957     else
5958     {
5959     ret = g_strdup_printf("%s", _("then keep right"));
5960     }
5961     }
5962     else
5963     {
5964     // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
5965     ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, ""); // dont speak destination when maneuvers are connected!
5966     // ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
5967     }
5968 zoff99 40 }
5969     }
5970 zoff99 27 }
5971 zoff99 2 g_free(destination);
5972 zoff99 27 }
5973     else
5974     {
5975     if (!connect)
5976     {
5977     #ifdef HAVE_API_ANDROID
5978 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5979 zoff99 27 android_send_generic_text(1,"+*#O:You have reached your destination %s\n");
5980     gchar* xy=g_strdup_printf("+*#1:%s\n", d);
5981     android_send_generic_text(1,xy);
5982     g_free(xy);
5983     #endif
5984 zoff99 28 #endif
5985 zoff99 27 // TRANSLATORS: EXAMPLE: You have reached your destination in 300 meters
5986     ret = g_strdup_printf(_("You have reached your destination %s"), d);
5987 zoff99 2 }
5988 zoff99 27 else
5989     {
5990     #ifdef HAVE_API_ANDROID
5991 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5992 zoff99 27 android_send_generic_text(1,"+*#O:then you have reached your destination.\n");
5993     #endif
5994 zoff99 28 #endif
5995 zoff99 40 ret = g_strdup(_("then you have reached your destination."));
5996 zoff99 27 }
5997 zoff99 2 }
5998     g_free(d);
5999 zoff99 40
6000     return2 ret;
6001    
6002     __F_END__
6003 zoff99 2 }
6004    
6005 zoff99 41
6006    
6007     static char *
6008     show_maneuver(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type, int connect)
6009     {
6010     return show_maneuver_at_level(nav, itm, cmd, type, connect, DONT_KNOW_LEVEL, 0);
6011     }
6012    
6013    
6014    
6015    
6016 zoff99 2 /**
6017     * @brief Creates announcements for maneuvers, plus maneuvers immediately following the next maneuver
6018     *
6019     * This function does create an announcement for the current maneuver and for maneuvers
6020     * immediately following that maneuver, if these are too close and we're in speech navigation.
6021     *
6022     * @return An announcement that should be made
6023     */
6024 zoff99 40 // central entry point for TTS maneuvers --------------
6025     // central entry point for TTS maneuvers --------------
6026     // central entry point for TTS maneuvers --------------
6027 zoff99 2 static char *
6028 zoff99 30 show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type)
6029 zoff99 2 {
6030 zoff99 40 __F_START__
6031    
6032 zoff99 27 struct navigation_command *cur, *prev;
6033     int distance = itm->dest_length - cmd->itm->dest_length;
6034 zoff99 40 int level, dist, i, time, level2;
6035 zoff99 27 int speech_time, time2nav;
6036     char *ret, *old, *buf, *next;
6037 zoff99 41 char *ret22;
6038 zoff99 2
6039 zoff99 40 char *temp_txt = NULL;
6040    
6041    
6042     //dbg(0, "Enter\n");
6043    
6044 zoff99 27 if (type != attr_navigation_speech)
6045     {
6046 zoff99 41 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6047     {
6048     return2 show_maneuver_bicycle(nav, itm, cmd, type, 0, DONT_KNOW_LEVEL); // not for speech, so just return the real values
6049     }
6050     else
6051     {
6052     return2 show_maneuver(nav, itm, cmd, type, 0); // not for speech, so just return the real values
6053     }
6054 zoff99 2 }
6055    
6056    
6057 zoff99 41 int cur_vehicle_speed = 0;
6058     if ((global_navit) && (global_navit->vehicle))
6059     {
6060     cur_vehicle_speed = global_navit->vehicle->speed; // in km/h
6061     }
6062    
6063    
6064     dbg(0, "SPEECH:[-0v-] current speed=%d\n", cur_vehicle_speed);
6065    
6066    
6067     // -- bicycle mode START -------------------------------------
6068     // -- bicycle mode START -------------------------------------
6069     // -- bicycle mode START -------------------------------------
6070 zoff99 40 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6071 zoff99 27 {
6072 zoff99 41 level = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length, 0);
6073 zoff99 2
6074 zoff99 40 //dbg(0, "level = %d\n", level);
6075     //dbg(0, "(nn)itm->way.flags=%x\n", itm->way.flags);
6076     //dbg(0, "(nn)itm->next->way.flags=%x\n", itm->next->way.flags);
6077     //dbg(0, "(nn)distance=%d cmd->length=%d (minus)=%d\n", distance, cmd->length, (distance - cmd->length));
6078 zoff99 2
6079 zoff99 40 // in bike mode level should only be "0" or "1" or "3" !
6080 zoff99 2
6081 zoff99 40 if (level > 2)
6082     {
6083     //dbg(0, "just say the current command\n");
6084     return2 show_maneuver_bicycle(nav, itm, cmd, type, 0, level); // just say the current command
6085 zoff99 2 }
6086 zoff99 27
6087 zoff99 40 if (cmd->itm->told)
6088 zoff99 27 {
6089 zoff99 40 // current command should not be spoken again!
6090     //dbg(0, "current command should not be spoken again\n");
6091     return2 g_strdup("");
6092 zoff99 27 }
6093 zoff99 40
6094    
6095     //dbg(0, "xx 017a fsp, itm->told=%d l=%d\n", cmd->itm->told, level);
6096     if (level == 0)
6097 zoff99 27 {
6098 zoff99 40 // this command is spoken (now)
6099     //dbg(0, "this command is spoken (now)\n");
6100     cmd->itm->told = 1;
6101 zoff99 27 }
6102 zoff99 40 //dbg(0, "xx 017b fsp, itm->told=%d\n", cmd->itm->told);
6103 zoff99 2
6104 zoff99 40
6105     // current maneuver -------
6106     ret = show_maneuver_bicycle(nav, itm, cmd, type, 0, level); // generate TTS text for current command
6107     //dbg(0, "ret cmd=%s\n", ret);
6108     time2nav = navigation_time(itm, cmd->itm->prev);
6109     //dbg(0, "time2nav = %d\n", time2nav);
6110     old = NULL;
6111     // current maneuver -------
6112    
6113     cur = cmd->next;
6114     prev = cmd;
6115    
6116     if (cur && cur->itm) // we have a next command
6117     {
6118     dist = prev->itm->dest_length - cur->itm->dest_length;
6119 zoff99 41 level2 = navigation_get_announce_level(nav, itm->next->way.item.type, dist, 0);
6120 zoff99 40 //dbg(0, "(next)level2 = %d\n", level2);
6121     //dbg(0, "(next)dist=%d\n", dist);
6122    
6123     if ((level2 < 2) && (dist < (2 * level_static_for_bicycle[0])))
6124     {
6125     //dbg(0, "link next command, and dont say it again!\n");
6126     old = ret;
6127     buf = show_maneuver_bicycle(nav, prev->itm, cur, type, 1, 0); // generate TTS text for next command, and dont say the next command again!
6128     //dbg(0, "next cmd=%s\n", next);
6129     ret = g_strdup_printf("%s, %s", old, buf);
6130     //dbg(0, "next cmd concat=%s\n", ret);
6131     g_free(buf);
6132     g_free(old);
6133     if (level == 0)
6134     {
6135     // dont say this next command again!
6136     cur->itm->told = 1;
6137     }
6138     }
6139 zoff99 2 }
6140 zoff99 40 }
6141 zoff99 41 // -- bicycle mode END -------------------------------------
6142     // -- bicycle mode END -------------------------------------
6143     // -- bicycle mode END -------------------------------------
6144 zoff99 40 else
6145     {
6146 zoff99 2
6147    
6148 zoff99 40
6149     // -------------------------------------------------
6150     // -------------------------------------------------
6151     // -- ******************************************* --
6152 zoff99 41 // CAR MODE
6153 zoff99 40 // -- ******************************************* --
6154     // -------------------------------------------------
6155     // -------------------------------------------------
6156    
6157 zoff99 41 level = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length, ((float)cur_vehicle_speed / 3.6f));
6158 zoff99 40 //dbg(0, "level = %d\n", level);
6159     //dbg(0, "(nn)itm->way.flags=%x\n", itm->way.flags);
6160     //dbg(0, "(nn)itm->next->way.flags=%x\n", itm->next->way.flags);
6161    
6162     long temp_ts = -1;
6163     debug_get_timestamp_millis(&temp_ts);
6164     if (global_last_spoken == -1)
6165     {
6166     temp_ts = 99999999;
6167 zoff99 2 }
6168    
6169 zoff99 41 int time2nav_2 = navigation_time_real_speed(itm, cmd->itm->prev, cur_vehicle_speed);
6170 zoff99 27
6171 zoff99 40 dbg(0, "SPEECH:[-00-] last spoken ago=%f\n", (float)((temp_ts - global_last_spoken) / 1000.0f));
6172     dbg(0, "SPEECH:[-01-] meters to next maneuver=%d\n", (distance - cmd->length));
6173     dbg(0, "SPEECH:[-02-] level=%d\n", level);
6174    
6175     #ifdef HAVE_API_ANDROID
6176     temp_txt = g_strdup_printf("SPEECH:[-00-] last spoken ago=%f\n", (float)((temp_ts - global_last_spoken) / 1000.0f));
6177     android_send_generic_text(20, temp_txt);
6178     g_free(temp_txt);
6179    
6180     temp_txt = g_strdup_printf("SPEECH:[-01-] meters to next maneuver=%d\n", (distance - cmd->length));
6181     android_send_generic_text(20, temp_txt);
6182     g_free(temp_txt);
6183    
6184     temp_txt = g_strdup_printf("SPEECH:[-02-] level=%d\n", level);
6185     android_send_generic_text(20, temp_txt);
6186     g_free(temp_txt);
6187     #endif
6188    
6189     dbg(0, "SPEECH:[-03-] time2nav secs=%f\n", ((float)time2nav_2 / 10.0f));
6190 zoff99 41
6191     int dist_to_next_spoken_command = -1;
6192     float secs_to_next_spoken_command = -1;
6193     if (level > 0)
6194     {
6195     dist_to_next_spoken_command = (distance - cmd->length) - (navigation_get_announce_dist_for_level_on_item(nav, itm->way.item.type, (level - 1), ((float)cur_vehicle_speed / 3.6f) ) );
6196    
6197     if (cur_vehicle_speed > 0)
6198     {
6199     secs_to_next_spoken_command = ((float)dist_to_next_spoken_command / ((float)cur_vehicle_speed / 3.6f));
6200     }
6201     else
6202     {
6203     secs_to_next_spoken_command = ((float)dist_to_next_spoken_command / ((float)itm->speed / 3.6f));
6204     }
6205     }
6206    
6207    
6208     // current maneuver -------
6209     ret22 = show_maneuver_at_level(nav, itm, cmd, type, 0, level, 0);
6210     // current maneuver -------
6211    
6212     if (nav->speech)
6213     {
6214     speech_time = speech_estimate_duration(nav->speech, ret22);
6215     dbg(0, "SPEECH:[-CUR-] secs=%f text=%s\n", ((float)speech_time)/10.0f, ret22);
6216     }
6217     else
6218     {
6219     speech_time = -1;
6220     dbg(0, "SPEECH:[-CUR-] secs=-1 text=%s\n", ret22);
6221     }
6222    
6223    
6224     dbg(0, "SPEECH:[-03-] meters to next announcement=%d secs to next announcement=%f\n", dist_to_next_spoken_command, secs_to_next_spoken_command);
6225    
6226     if (level == 3)
6227     {
6228 zoff99 47
6229     // ===========----------- LEVEL 3 -----------===========
6230    
6231 zoff99 41 #if 0
6232     if (((float)((temp_ts - global_last_spoken) / 1000.0f)) < 3.0f)
6233     {
6234     dbg(0, "SPEECH:[-NOOP-] 004: already spoken in the last 3 secs.\n");
6235     return2 g_strdup(""); // dont speak this command now!
6236     }
6237     #endif
6238    
6239 zoff99 47 if (secs_to_next_spoken_command < 7 )
6240 zoff99 41 {
6241     if (ret22)
6242     {
6243     g_free(ret22);
6244     ret22 = NULL;
6245     }
6246 zoff99 47
6247     #ifdef _DEBUG_BUILD_
6248     // speak debug ----
6249     navit_say(global_navit, "level 3a wieder in 7 sekunden");
6250     // speak debug ----
6251     #endif
6252    
6253     dbg(0, "SPEECH:[-NOOP-] 006b: want to speak again in less than %d secs. level=%d\n", 7, level);
6254 zoff99 41 return2 g_strdup(""); // dont speak this command now!
6255     }
6256    
6257     if (secs_to_next_spoken_command < (((float)speech_time/10.0f) + 3) )
6258     {
6259     if (ret22)
6260     {
6261     g_free(ret22);
6262     ret22 = NULL;
6263     }
6264 zoff99 47
6265     #ifdef _DEBUG_BUILD_
6266     // speak debug ----
6267     temp_txt = g_strdup_printf("level 3b wieder in %d sekunden", (int)(((float)speech_time/10.0f) + 3));
6268     navit_say(global_navit, temp_txt);
6269     g_free(temp_txt);
6270     // speak debug ----
6271     #endif
6272    
6273 zoff99 41 dbg(0, "SPEECH:[-NOOP-] 006: want to speak again in less than %d secs. level=%d\n", (((float)speech_time/10.0f) + 3), level );
6274     return2 g_strdup(""); // dont speak this command now!
6275     }
6276 zoff99 47 // ===========----------- LEVEL 3 -----------===========
6277    
6278    
6279 zoff99 41 }
6280     else if (level == 2)
6281     {
6282 zoff99 47
6283     // ===========----------- LEVEL 2 -----------===========
6284    
6285    
6286     #if 0
6287     if (secs_to_next_spoken_command < 3 )
6288 zoff99 41 {
6289     if (ret22)
6290     {
6291     g_free(ret22);
6292     ret22 = NULL;
6293     }
6294 zoff99 47
6295     #ifdef _DEBUG_BUILD_
6296     // speak debug ----
6297     navit_say(global_navit, "level 2a wieder in 3 sekunden");
6298     // speak debug ----
6299     #endif
6300    
6301     dbg(0, "SPEECH:[-NOOP-] 007b: want to speak again in less than %d secs. level=%d\n", 3, level);
6302 zoff99 41 return2 g_strdup(""); // dont speak this command now!
6303     }
6304 zoff99 47 #endif
6305 zoff99 41
6306     #if 1
6307     if (secs_to_next_spoken_command < (((float)speech_time/10.0f) + 1) )
6308     {
6309     if (ret22)
6310     {
6311     g_free(ret22);
6312     ret22 = NULL;
6313     }
6314 zoff99 47
6315     #ifdef _DEBUG_BUILD_
6316     // speak debug ----
6317     temp_txt = g_strdup_printf("level 2b wieder in %d sekunden", (int)(((float)speech_time/10.0f) + 1));
6318     navit_say(global_navit, temp_txt);
6319     // speak debug ----
6320     #endif
6321    
6322     dbg(0, "SPEECH:[-NOOP-] 007: want to speak again in less than %d secs. level=%d\n", (int)(((float)speech_time/10.0f) + 1), level);
6323 zoff99 41 return2 g_strdup(""); // dont speak this command now!
6324     }
6325     #endif
6326    
6327 zoff99 47 #if 0
6328 zoff99 41 if (((float)((temp_ts - global_last_spoken) / 1000.0f)) < 5.0f)
6329     {
6330     if (ret22)
6331     {
6332     g_free(ret22);
6333     ret22 = NULL;
6334     }
6335    
6336 zoff99 47 #ifdef _DEBUG_BUILD_
6337     // speak debug ----
6338     navit_say(global_navit, "level 2c schon vor 5 sekunden");
6339     // speak debug ----
6340     #endif
6341    
6342 zoff99 41 dbg(0, "SPEECH:[-NOOP-] 005: already spoken in the last 5 secs. level=%d\n", level);
6343     return2 g_strdup(""); // dont speak this command now!
6344     }
6345 zoff99 47 #endif
6346    
6347     // ===========----------- LEVEL 2 -----------===========
6348    
6349    
6350 zoff99 41 }
6351     else if (level == 1)
6352     {
6353 zoff99 47
6354     // ===========----------- LEVEL 1 -----------===========
6355    
6356    
6357 zoff99 41 #if 0
6358     if (((float)time2nav_2 / 10.0f) < 5.0f)
6359     {
6360     dbg(0, "SPEECH:[-NOOP-] 001: less than 5 secs. to maneuver\n");
6361     return2 g_strdup(""); // dont speak this command now!
6362     }
6363     #endif
6364    
6365     #if 0
6366     if ((distance - cmd->length) < 50)
6367     {
6368     dbg(0, "SPEECH:[-NOOP-] 003: less than 50 meters to maneuver\n");
6369     return2 g_strdup(""); // dont speak this command now!
6370     }
6371     #endif
6372    
6373    
6374     if (dist_to_next_spoken_command < 18)
6375     {
6376     if (ret22)
6377     {
6378     g_free(ret22);
6379     ret22 = NULL;
6380     }
6381    
6382 zoff99 47 #ifdef _DEBUG_BUILD_
6383     // speak debug ----
6384     temp_txt = g_strdup_printf("level 1a wieder in %d sekunden", 18);
6385     navit_say(global_navit, temp_txt);
6386     g_free(temp_txt);
6387     // speak debug ----
6388     #endif
6389    
6390    
6391 zoff99 41 dbg(0, "SPEECH:[-NOOP-] 011: less than 18 meters to next announcement\n");
6392     return2 g_strdup(""); // dont speak this command now!
6393     }
6394    
6395 zoff99 47 #if 0
6396 zoff99 41 if (((float)((temp_ts - global_last_spoken) / 1000.0f)) < 4.0f)
6397     {
6398     if (ret22)
6399     {
6400     g_free(ret22);
6401     ret22 = NULL;
6402     }
6403    
6404     dbg(0, "SPEECH:[-NOOP-] 002: already spoken in the last 4 secs. level=%d\n", level);
6405     return2 g_strdup(""); // dont speak this command now!
6406     }
6407 zoff99 47 #endif
6408 zoff99 41
6409     if (secs_to_next_spoken_command < (((float)speech_time/10.0f) + 1) )
6410     {
6411     if (secs_to_next_spoken_command < 3.0f)
6412     {
6413     if (ret22)
6414     {
6415     g_free(ret22);
6416     ret22 = NULL;
6417     }
6418    
6419 zoff99 47 #ifdef _DEBUG_BUILD_
6420     // speak debug ----
6421     temp_txt = g_strdup_printf("level 1b wieder in %d sekunden", 3);
6422     navit_say(global_navit, temp_txt);
6423     g_free(temp_txt);
6424     // speak debug ----
6425     #endif
6426    
6427    
6428 zoff99 41 dbg(0, "SPEECH:[-NOOP-] 008: want to speak again in less than %d secs. level=%d\n", (((float)speech_time/10.0f) + 1), level);
6429     return2 g_strdup(""); // dont speak this command now!
6430     }
6431     else
6432     {
6433     // if we have at least 3 seconds left, still say level 1 announcement (without the streetname/destination name)
6434     dbg(0, "SPEECH:[-NOOP-] 008lo: use level=%d announcement without destination name\n", level);
6435     if (ret22)
6436     {
6437     g_free(ret22);
6438     ret22 = NULL;
6439     }
6440     ret22 = show_maneuver_at_level(nav, itm, cmd, type, 0, level, -1);
6441     if (nav->speech)
6442     {
6443     speech_time = speech_estimate_duration(nav->speech, ret22);
6444     dbg(0, "SPEECH:[-CUR-] :lo: secs=%f text=%s\n", ((float)speech_time)/10.0f, ret22);
6445     }
6446     else
6447     {
6448     speech_time = -1;
6449     dbg(0, "SPEECH:[-CUR-] :lo: secs=-1 text=%s\n", next);
6450     }
6451    
6452     if (secs_to_next_spoken_command < (((float)speech_time/10.0f) + 0) )
6453     {
6454     if (ret22)
6455     {
6456     g_free(ret22);
6457     ret22 = NULL;
6458     }
6459    
6460 zoff99 47 #ifdef _DEBUG_BUILD_
6461     // speak debug ----
6462     temp_txt = g_strdup_printf("level 1c wieder in %d sekunden", (int)(((float)speech_time/10.0f) + 0));
6463     navit_say(global_navit, temp_txt);
6464     g_free(temp_txt);
6465     // speak debug ----
6466     #endif
6467    
6468    
6469 zoff99 41 dbg(0, "SPEECH:[-NOOP-] 008loEE: giving up on this announcement\n");
6470     return2 g_strdup(""); // dont speak this command now!
6471     }
6472     }
6473     }
6474 zoff99 47
6475     // ===========----------- LEVEL 1 -----------===========
6476    
6477 zoff99 41 }
6478    
6479    
6480    
6481 zoff99 47
6482    
6483    
6484 zoff99 40 #ifdef HAVE_API_ANDROID
6485     temp_txt = g_strdup_printf("SPEECH:[-03-] time2nav secs=%f\n", ((float)time2nav_2 / 10.0f));
6486     android_send_generic_text(20, temp_txt);
6487     g_free(temp_txt);
6488     #endif
6489    
6490     if (level > 1)
6491 zoff99 27 {
6492 zoff99 40 dbg(0, "SPEECH:[-R1-]\n");
6493 zoff99 47 return2 ret22; // We accumulate maneuvers only if they are close (level-0 and level-1)
6494 zoff99 27 }
6495 zoff99 40
6496     if (cmd->itm->told)
6497 zoff99 27 {
6498 zoff99 40 #ifdef HAVE_API_ANDROID
6499     #ifdef NAVIT_SAY_DEBUG_PRINT
6500     android_send_generic_text(1,"+*#C1:*CANCEL*\n");
6501     #endif
6502     #endif
6503     dbg(0, "SPEECH:[-R2-]\n");
6504     #ifdef HAVE_API_ANDROID
6505     temp_txt = g_strdup("SPEECH:[-R2-]\n");
6506     android_send_generic_text(20, temp_txt);
6507     g_free(temp_txt);
6508     #endif
6509 zoff99 41 if (ret22)
6510     {
6511     g_free(ret22);
6512     ret22 = NULL;
6513     }
6514 zoff99 40
6515 zoff99 41
6516 zoff99 40 return2 g_strdup("");
6517 zoff99 2 }
6518    
6519 zoff99 41
6520 zoff99 40 // current maneuver -------
6521 zoff99 41 ret = ret22;
6522     time2nav = navigation_time_real_speed(itm, cmd->itm->prev, cur_vehicle_speed);
6523     // current maneuver -------
6524    
6525    
6526     #if 0
6527     if (nav->speech)
6528     {
6529     speech_time = speech_estimate_duration(nav->speech, ret);
6530     dbg(0, "SPEECH:[-CUR-] secs=%f text=%s\n", ((float)speech_time)/10.0f, ret);
6531     }
6532     else
6533     {
6534     speech_time = -1;
6535     dbg(0, "SPEECH:[-CUR-] secs=-1 text=%s\n", next);
6536     }
6537     #endif
6538    
6539    
6540 zoff99 40 old = NULL;
6541    
6542     dbg(0, "SPEECH:[-04-] time2nav secs=%f\n", ((float)time2nav / 10.0f));
6543     #ifdef HAVE_API_ANDROID
6544     temp_txt = g_strdup_printf("SPEECH:[-04-] time2nav secs=%f\n", ((float)time2nav / 10.0f));
6545     android_send_generic_text(20, temp_txt);
6546     g_free(temp_txt);
6547     #endif
6548    
6549    
6550 zoff99 41
6551    
6552     // next maneuver -------
6553 zoff99 40 cur = cmd->next;
6554     prev = cmd;
6555 zoff99 41 // next maneuver -------
6556 zoff99 40
6557 zoff99 41
6558 zoff99 40 i = 0;
6559     int max_announcements = 3;
6560     if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6561 zoff99 27 {
6562 zoff99 40 max_announcements = 2;
6563     }
6564    
6565 zoff99 41 while (cur && cur->itm) // only accumulate at "level 0" or "level 1"
6566 zoff99 40 {
6567     // We don't merge more than "max_announcements" announcements...
6568     if (i > (max_announcements - 2))
6569     {
6570     break;
6571     }
6572    
6573 zoff99 41 dist = prev->itm->dest_length - cur->itm->dest_length; // distance between next 2 maneuvers in meters
6574    
6575     if (dist > 420) // too far apart, bail out
6576     {
6577     break;
6578     }
6579    
6580 zoff99 40 next = show_maneuver(nav, prev->itm, cur, type, 0);
6581     if (nav->speech)
6582     {
6583     speech_time = speech_estimate_duration(nav->speech, next);
6584 zoff99 41 dbg(0, "SPEECH:[-NXT-] secs=%f text=%s\n", ((float)speech_time)/10.0f, next);
6585 zoff99 40 }
6586     else
6587     {
6588     speech_time = -1;
6589 zoff99 41 dbg(0, "SPEECH:[-NXT-] secs=-1 text=%s\n", next);
6590 zoff99 40 }
6591     g_free(next);
6592    
6593     if (speech_time == -1)
6594     {
6595     // user didn't set cps
6596 zoff99 41 speech_time = 25; // assume 2.5 seconds
6597     dbg(0, "SPEECH:[-NXT-](2) secs=%f\n", ((float)speech_time)/10.0f);
6598 zoff99 40 }
6599    
6600 zoff99 41 //if (cur_vehicle_speed > 0)
6601     //{
6602     // time = ((float)dist / ((float)cur_vehicle_speed / 3.6f)) * 10;
6603     //}
6604     //else
6605     //{
6606     // time = navigation_time_real_speed(prev->itm, cur->itm->prev, cur_vehicle_speed);
6607 zoff99 40 time = navigation_time(prev->itm, cur->itm->prev);
6608 zoff99 41 //}
6609    
6610     dbg(0, "SPEECH:[-NXT-][-05-] dist meters=%d time secs=%f speech_time=%f\n", dist, ((float)time)/10.0f, ((float)speech_time)/10.0f);
6611 zoff99 27 #ifdef HAVE_API_ANDROID
6612 zoff99 40 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);
6613     android_send_generic_text(20, temp_txt);
6614     g_free(temp_txt);
6615     #endif
6616    
6617    
6618     if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6619     {
6620 zoff99 41 // !! should never get here !!
6621 zoff99 40 }
6622     else
6623     {
6624 zoff99 41 dbg(0, "SPEECH: time secs=%f speech_time secs=%f [if (time >= (speech_time + 35))]\n", ((float)time)/10.0f, ((float)speech_time)/10.0f);
6625    
6626     if (i == 0)
6627     {
6628     if (dist < 170) // distance between maneuvers less than 170m --> always merge maneuvers
6629     {
6630     }
6631     else
6632     {
6633     // **OLD** // if (time >= (speech_time + 35)) // (time to turn) >= (time to speak command + 3.5 secs.)
6634 zoff99 47 if (time > ((global_level1_announcement * 10.0f) - 3) ) // more than "global_level1_announcement" seconds to next maneuver -> don't merge it
6635 zoff99 41 {
6636     dbg(0, "SPEECH:*break first*\n");
6637     break;
6638     }
6639     }
6640 zoff99 40 }
6641 zoff99 41 else
6642     {
6643 zoff99 47 if (time > (global_level0_announcement * 10.0f)) // more than "global_level0_announcement" seconds to next maneuver -> don't merge it
6644 zoff99 41 {
6645     dbg(0, "SPEECH:*break next*\n");
6646     break;
6647     }
6648     }
6649 zoff99 40 }
6650    
6651     old = ret;
6652     buf = show_maneuver(nav, prev->itm, cur, type, 1);
6653     ret = g_strdup_printf("%s, %s", old, buf);
6654     g_free(buf);
6655    
6656     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);
6657 zoff99 41 // if (nav->speech && speech_estimate_duration(nav->speech, ret) > time2nav)
6658     // {
6659     // g_free(ret);
6660     // ret = old;
6661     // i = (max_announcements - 1); // This will terminate the loop
6662     // dbg(0, "SPEECH:*terminate loop*\n");
6663     // }
6664     // else
6665     // {
6666 zoff99 40 g_free(old);
6667 zoff99 41 // }
6668 zoff99 40
6669    
6670     if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6671     {
6672 zoff99 41 // !! should never get here !!
6673 zoff99 40 }
6674     else
6675     {
6676 zoff99 41 #if 0
6677 zoff99 40 dbg(0, "SPEECH: time secs=%f speech_time secs=%f [if (time <= speech_time)]\n", ((float)time)/10.0f, ((float)speech_time)/10.0f);
6678     // If the two maneuvers are *really* close, we shouldn't tell the second one again, because TTS won't be fast enough
6679     if (time <= speech_time)
6680     {
6681     #ifdef HAVE_API_ANDROID
6682 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
6683 zoff99 40 android_send_generic_text(1,"+*#C2:*CANCEL*\n");
6684 zoff99 27 #endif
6685 zoff99 28 #endif
6686 zoff99 40 //dbg(0, "cancel speak:%s\n", ret);
6687     cur->itm->told = 1;
6688     }
6689 zoff99 41 #endif
6690 zoff99 40 }
6691    
6692     prev = cur;
6693     cur = cur->next;
6694     i++;
6695 zoff99 2 }
6696    
6697 zoff99 40 // -------------------------------------------------
6698     // -------------------------------------------------
6699     // -- ******************************************* --
6700 zoff99 41 // CAR MODE
6701 zoff99 40 // -- ******************************************* --
6702     // -------------------------------------------------
6703     // -------------------------------------------------
6704    
6705 zoff99 2 }
6706    
6707 zoff99 40 dbg(0, "SPEECH:[-Re-]\n");
6708     #ifdef HAVE_API_ANDROID
6709     temp_txt = g_strdup("SPEECH:[-Re-]\n");
6710     android_send_generic_text(20, temp_txt);
6711     g_free(temp_txt);
6712     #endif
6713    
6714     return2 ret;
6715    
6716     __F_END__
6717 zoff99 2 }
6718 zoff99 40 // central entry point for TTS maneuvers --------------
6719     // central entry point for TTS maneuvers --------------
6720     // central entry point for TTS maneuvers --------------
6721 zoff99 2
6722 zoff99 40
6723    
6724     // ----- global var, BAD!! -------
6725     int global_spoke_last_position_update = 0;
6726 zoff99 41 int previous_dest_length = -1;
6727     int previous_dest_length_save = -1;
6728     struct navigation_command *last_first_cmd_save = NULL;
6729     int global_turn_around_spoken = 0;
6730 zoff99 40 // ----- global var, BAD!! -------
6731    
6732 zoff99 30 static void navigation_call_callbacks(struct navigation *this_, int force_speech)
6733 zoff99 2 {
6734 zoff99 40 __F_START__
6735    
6736 zoff99 2 int distance, level = 0;
6737 zoff99 40 int level_cur;
6738     int distance_orig;
6739 zoff99 27 void *p = this_;
6740 zoff99 41 int dont_speak_yet = 0;
6741     int level_last_save = 99;
6742 zoff99 30
6743 zoff99 2 if (!this_->cmd_first)
6744 zoff99 30 {
6745 zoff99 40 //dbg(0, "ret 0001\n");
6746     global_spoke_last_position_update = 0;
6747     return2;
6748 zoff99 30 }
6749    
6750 zoff99 41 // EMPTY: calls nothing!!
6751     // ****** // callback_list_call(this_->callback, 1, &p);
6752 zoff99 40
6753     //if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6754     //{
6755     // force_speech = 7;
6756     //}
6757    
6758     //dbg(0, "force_speech=%d turn_around=%d turn_around_limit=%d\n", force_speech, this_->turn_around, this_->turn_around_limit);
6759    
6760     distance = this_->first->dest_length - this_->cmd_first->itm->dest_length;
6761     //dbg(0, "fdl=%d cmdidl=%d\n", this_->first->dest_length, this_->cmd_first->itm->dest_length);
6762     distance_orig = distance;
6763     distance = round_distance(distance);
6764 zoff99 41
6765     int cur_vehicle_speed = 0;
6766     if ((global_navit) && (global_navit->vehicle))
6767     {
6768     cur_vehicle_speed = global_navit->vehicle->speed;
6769     }
6770    
6771     dbg(0, "NCC_:distance_orig=%d distance=%d curr vehicle speed=%d force_speech=%d\n", distance_orig, distance, global_navit->vehicle->speed, force_speech);
6772    
6773    
6774 zoff99 30 if (this_->turn_around_limit && this_->turn_around == this_->turn_around_limit)
6775 zoff99 27 {
6776 zoff99 41
6777     dbg(0, "NAV_TURNAROUND:005 ta=%d talimit=%d\n", this_->turn_around, this_->turn_around_limit);
6778    
6779 zoff99 40 //dbg(0, "xx 001 d=%d rd=%d dt=%d\n", distance_orig, distance_orig, this_->distance_turn);
6780 zoff99 41 #if 0
6781 zoff99 27 while (distance > this_->distance_turn)
6782     {
6783     this_->level_last = 4;
6784     level = 4;
6785     force_speech = 2;
6786 zoff99 40
6787 zoff99 2 if (this_->distance_turn >= 500)
6788 zoff99 40 {
6789 zoff99 27 this_->distance_turn *= 2;
6790 zoff99 40 }
6791 zoff99 2 else
6792 zoff99 40 {
6793 zoff99 27 this_->distance_turn = 500;
6794 zoff99 40 }
6795 zoff99 41 #endif
6796 zoff99 40
6797 zoff99 41 // we need to force a maneuver for "turn around" ------------------
6798     this_->level_last = 4;
6799     level = 4;
6800     force_speech = 2;
6801     // this_->distance_turn *= 100;
6802    
6803     #if 1
6804     global_driven_away_from_route = 0;
6805     global_spoke_last_position_update = 0;
6806     global_last_spoken = -1;
6807     previous_dest_length = -1;
6808     previous_dest_length_save = -1;
6809     last_first_cmd_save = NULL;
6810     #endif
6811    
6812     this_->level_last = 99;
6813    
6814    
6815     this_->level_last = level;
6816     this_->curr_delay = 0;
6817    
6818     dbg(0, "NCC_:force_speech=%d distance=%d level=%d global_spoke_last_position_update=%d\n", force_speech, distance, level, global_spoke_last_position_update);
6819     dbg(0, "NCC_:========= END ==========\n");
6820    
6821     global_spoke_last_position_update = 1;
6822    
6823     // ----------------------------------
6824     // ----------------------------------
6825     // calls -> calls navit_speak
6826     //
6827     callback_list_call(this_->callback_speech, 1, &p);
6828     // ----------------------------------
6829     // ----------------------------------
6830    
6831    
6832     return2;
6833    
6834     // we need to force a maneuver for "turn around" ------------------
6835    
6836     #if 0
6837     dbg(0, "NCC_:loop 001 d=%d dt=%d force_speech=%d\n", distance, this_->distance_turn, force_speech);
6838 zoff99 2 }
6839 zoff99 41 #endif
6840    
6841 zoff99 27 }
6842 zoff99 41 else if (!this_->turn_around_limit || this_->turn_around != this_->turn_around_limit)
6843 zoff99 27 {
6844     this_->distance_turn = 50;
6845 zoff99 40
6846 zoff99 41 global_turn_around_spoken = 0; // reset turn around speak flag
6847    
6848 zoff99 40 //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);
6849     //dbg(0, "xx 002a d=%d d2=%d diff=%d\n", distance, (distance - this_->cmd_first->length), (this_->cmd_first->itm->length - distance_orig));
6850    
6851     //dbg(0, "xx 002a ll001=%d\n", (this_->cmd_first->itm->prev->dest_length - this_->cmd_first->itm->dest_length));
6852    
6853 zoff99 27 distance -= this_->cmd_first->length;
6854 zoff99 40
6855 zoff99 41
6856     level = navigation_get_announce_level_cmd(this_, this_->first, this_->cmd_first, distance_orig, ((float)cur_vehicle_speed / 3.6f) );
6857     level_cur = navigation_get_announce_level(this_, this_->first->way.item.type, distance_orig, ((float)cur_vehicle_speed / 3.6f));
6858    
6859    
6860    
6861     if (last_first_cmd_save != this_->cmd_first)
6862     {
6863     last_first_cmd_save = this_->cmd_first;
6864     previous_dest_length = previous_dest_length_save;
6865     }
6866     previous_dest_length_save = this_->cmd_first->itm->dest_length;
6867     // level_last_save = this_->level_last;
6868    
6869     //dbg(0, "NCC_:\n");
6870     //dbg(0, "NCC_:0---passed item?---\n");
6871     // dbg(0, "NCC_:level=%d level_cur=%d this_->level_last=%d distance_orig=%d distance=%d\n", level, level_cur, this_->level_last, distance_orig, distance);
6872    
6873     #if 1
6874     if (previous_dest_length == -1)
6875     {
6876     dbg(0, "NCC_:no prev nav command\n");
6877     }
6878     else
6879     {
6880     if (distance_orig > 40)
6881     {
6882     if ((distance_orig + 25) >= (previous_dest_length - this_->cmd_first->itm->dest_length))
6883     {
6884     // we are still within 25 meters of the previous navigation command item
6885     dont_speak_yet = 1;
6886     dbg(0, "NCC_:too close to last command, speak later level=%d level_cur=%d back-distance=%d\n", level, level_cur, (previous_dest_length - this_->cmd_first->itm->dest_length));
6887     }
6888     }
6889     #if 1
6890     else if (distance_orig > 20)
6891     {
6892     if ((distance_orig) > (previous_dest_length - this_->cmd_first->itm->dest_length))
6893     {
6894     // we are still at the position of the previous navigation command item
6895     dont_speak_yet = 1;
6896     dbg(0, "NCC_:too close to last command, speak later level=%d level_cur=%d back-distance=%d\n", level, level_cur, (previous_dest_length - this_->cmd_first->itm->dest_length));
6897     }
6898     }
6899     #endif
6900     }
6901     #endif
6902    
6903     //dbg(0, "NCC_:1---passed item?---\n");
6904     //dbg(0, "NCC_:\n");
6905    
6906    
6907    
6908    
6909 zoff99 40 //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);
6910    
6911 zoff99 27 if (level < this_->level_last)
6912     {
6913 zoff99 2 /* only tell if the level is valid for more than 3 seconds */
6914 zoff99 27 int speed_distance = this_->first->speed * 30 / 36;
6915 zoff99 40
6916 zoff99 41 dbg(0, "NCC_:speed_distance=%d\n", speed_distance);
6917    
6918    
6919 zoff99 40 //dbg(0, "xx 003 speed_distance=%d this_->first->speed=%d globalslp=%d\n", speed_distance, this_->first->speed, global_spoke_last_position_update);
6920    
6921     if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6922 zoff99 27 {
6923 zoff99 40
6924     level = level_cur;
6925    
6926     if ((level_cur > 0) && (global_spoke_last_position_update > 0))
6927     {
6928     // skip this time, speak command on the next update
6929 zoff99 41 dbg(0, "NCC_:SKIP[1] this update, speak next update (%d)! level=%d level_cur=%d\n", global_spoke_last_position_update, level, level_cur);
6930 zoff99 40 }
6931     else
6932     {
6933     this_->level_last = level_cur;
6934     force_speech = 3;
6935 zoff99 41 dbg(0, "NCC_:force_speech(2)=%d\n", force_speech);
6936 zoff99 40 }
6937 zoff99 2 }
6938 zoff99 40 else
6939     {
6940 zoff99 41 if (distance < speed_distance || navigation_get_announce_level_cmd(this_, this_->first, this_->cmd_first, distance - speed_distance, ((float)cur_vehicle_speed / 3.6f) ) == level)
6941 zoff99 40 {
6942     //dbg(0, "distance %d speed_distance %d\n", distance, speed_distance);
6943     //dbg(0, "level %d < %d\n", level, this_->level_last);
6944     this_->level_last = level;
6945     force_speech = 3;
6946 zoff99 41 dbg(0, "NCC_:force_speech(3)=%d\n", force_speech);
6947 zoff99 40 //dbg(0, "xx 004\n");
6948     }
6949     }
6950 zoff99 2 }
6951 zoff99 27
6952 zoff99 40
6953 zoff99 27 if (!item_is_equal(this_->cmd_first->itm->way.item, this_->item_last))
6954     {
6955 zoff99 40 //dbg(0, "xx 005\n");
6956    
6957 zoff99 27 this_->item_last = this_->cmd_first->itm->way.item;
6958 zoff99 40 this_->level_last = 99; // new item, reset command level
6959    
6960 zoff99 41 dbg(0, "NCC_:Ni---new navigation command item!!---\n");
6961    
6962 zoff99 2 if (this_->delay)
6963 zoff99 40 {
6964 zoff99 27 this_->curr_delay = this_->delay;
6965 zoff99 40 }
6966 zoff99 2 else
6967 zoff99 40 {
6968 zoff99 41 // if ((level_cur > 0) && (global_spoke_last_position_update > 0) && (distance_orig > 50))
6969     // {
6970     // // skip this time, speak command on the next update
6971     // dbg(0, "NCC_:SKIP[2] speech this update, speak at next update (%d)!\n", global_spoke_last_position_update);
6972     // }
6973     // else
6974     // {
6975 zoff99 40 force_speech = 5;
6976 zoff99 41 dbg(0, "NCC_:force_speech(4)=%d\n", force_speech);
6977     // }
6978 zoff99 40 }
6979 zoff99 27 }
6980     else
6981     {
6982 zoff99 40 //dbg(0, "xx 006\n");
6983    
6984 zoff99 27 if (this_->curr_delay)
6985     {
6986 zoff99 2 this_->curr_delay--;
6987 zoff99 40
6988 zoff99 2 if (!this_->curr_delay)
6989 zoff99 40 {
6990 zoff99 27 force_speech = 4;
6991 zoff99 41 dbg(0, "NCC_:force_speech(5)=%d\n", force_speech);
6992 zoff99 40 }
6993 zoff99 2 }
6994     }
6995     }
6996 zoff99 27
6997 zoff99 40 if (global_spoke_last_position_update > 0)
6998     {
6999     //dbg(0,"globalslp(1)=%d\n", global_spoke_last_position_update);
7000     global_spoke_last_position_update--;
7001     //dbg(0,"globalslp(2)=%d\n", global_spoke_last_position_update);
7002     }
7003    
7004 zoff99 41
7005     #if 0
7006 zoff99 40 //dbg(0,"XA 000\n");
7007 zoff99 41 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)) // bicycle mode
7008 zoff99 40 {
7009     if ((this_->previous) && (!item_is_equal(this_->cmd_first->itm->way.item, this_->previous->way.item)))
7010     {
7011     // item has changed, check if we missed a spoken level 0 command
7012     if (this_->previous->told == 0)
7013     {
7014 zoff99 41 dbg(0, "NCC_:MISSED a level 0 spoken command!\n");
7015 zoff99 40
7016     char *dir2 = _("right");
7017     int delta2 = this_->cmd_previous->delta;
7018 zoff99 41 dbg(0, "NCC_:missed delta = %d\n", delta2);
7019 zoff99 40 if (delta2 < 0)
7020     {
7021     // TRANSLATORS: left, as in 'Turn left'
7022     dir2 = _("left");
7023     delta2 = -delta2;
7024     }
7025    
7026     if (delta2 > 20)
7027     {
7028 zoff99 41 dbg(0,"NCC_:XA 002a\n");
7029 zoff99 40 navit_say(this_->navit, dir2);
7030     this_->previous->told = 1;
7031     }
7032     }
7033     }
7034     }
7035 zoff99 41 #endif
7036 zoff99 40
7037 zoff99 41
7038 zoff99 40 this_->previous = this_->cmd_first->itm;
7039     this_->cmd_previous = this_->cmd_first;
7040    
7041 zoff99 41 #if 1
7042     if ((dont_speak_yet == 1) && (force_speech))
7043 zoff99 27 {
7044 zoff99 41 dbg(0,"NCC_:this_->level_last = 99\n");
7045     this_->level_last = 99;
7046     }
7047     #endif
7048 zoff99 40
7049 zoff99 41 if (global_driven_away_from_route == 1)
7050     {
7051     dbg(0,"NCC_:** NEW PATH **\n");
7052     global_driven_away_from_route = 0;
7053     global_spoke_last_position_update = 0;
7054     global_last_spoken = -1;
7055     previous_dest_length = -1;
7056     previous_dest_length_save = -1;
7057     last_first_cmd_save = NULL;
7058    
7059     this_->level_last = 99;
7060 zoff99 2 }
7061 zoff99 40
7062 zoff99 41 if ( (dont_speak_yet == 0) || ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)) )
7063     {
7064     if (force_speech)
7065     {
7066     this_->level_last = level;
7067     this_->curr_delay = 0;
7068    
7069     dbg(0, "NCC_:force_speech=%d distance=%d level=%d global_spoke_last_position_update=%d\n", force_speech, distance, level, global_spoke_last_position_update);
7070     dbg(0, "NCC_:========= END ==========\n");
7071    
7072     global_spoke_last_position_update = 1;
7073    
7074     // ----------------------------------
7075     // ----------------------------------
7076     // calls -> calls navit_speak
7077     //
7078     callback_list_call(this_->callback_speech, 1, &p);
7079     // ----------------------------------
7080     // ----------------------------------
7081     }
7082     }
7083    
7084 zoff99 40 __F_END__
7085 zoff99 2 }
7086    
7087 zoff99 40
7088     // ----------- main place where navigation commands are generated ------------
7089     // ----------- main place where navigation commands are generated ------------
7090     // ----------- main place where navigation commands are generated ------------
7091 zoff99 30 static void navigation_update(struct navigation *this_, struct route *route, struct attr *attr)
7092 zoff99 2 {
7093 zoff99 40 __F_START__
7094    
7095 zoff99 2 struct map *map;
7096     struct map_rect *mr;
7097 zoff99 27 struct item *ritem; /* Holds an item from the route map */
7098     struct item *sitem; /* Holds the corresponding item from the actual map */
7099     struct attr street_item, street_direction;
7100 zoff99 2 struct navigation_itm *itm;
7101     struct attr vehicleprofile;
7102 zoff99 27 int mode = 0, incr = 0, first = 1;
7103 zoff99 40
7104     //dbg(0, "Enter\n");
7105    
7106 zoff99 2 if (attr->type != attr_route_status)
7107 zoff99 40 {
7108     //dbg(0, "return 001\n");
7109     return2;
7110     }
7111 zoff99 2
7112 zoff99 40 #ifdef NAVIT_ROUTING_DEBUG_PRINT
7113     dbg(0, "RS:001:route_status=%s\n", route_status_to_name(attr->u.num));
7114     #endif
7115    
7116 zoff99 41
7117     dbg(0, "NCC_:NU:RRRRSSSSSS::route_status=%s\n", route_status_to_name(attr->u.num));
7118    
7119     if (attr->u.num == route_status_path_done_new)
7120     {
7121     // route calculated new, you drove a different path?
7122     global_driven_away_from_route = 1;
7123     }
7124    
7125    
7126 zoff99 40 //dbg(1, "enter %d\n", mode);
7127 zoff99 30 if (attr->u.num == route_status_no_destination || attr->u.num == route_status_not_found || attr->u.num == route_status_path_done_new)
7128 zoff99 40 {
7129 zoff99 41 dbg(0, "NCC_:NU:navigation_flush\n");
7130 zoff99 2 navigation_flush(this_);
7131 zoff99 40 }
7132    
7133 zoff99 30 if (attr->u.num != route_status_path_done_new && attr->u.num != route_status_path_done_incremental)
7134 zoff99 40 {
7135     //dbg(0, "return 002\n");
7136 zoff99 41 dbg(0, "NCC_:NU:ret 001\n");
7137    
7138 zoff99 40 return2;
7139     }
7140 zoff99 27
7141     if (!this_->route)
7142 zoff99 40 {
7143     //dbg(0, "return 003\n");
7144 zoff99 41 dbg(0, "NCC_:NU:ret 002\n");
7145    
7146 zoff99 40 return2;
7147     }
7148    
7149 zoff99 27 map = route_get_map(this_->route);
7150     if (!map)
7151 zoff99 40 {
7152     //dbg(0, "return 004\n");
7153     return2;
7154     }
7155    
7156 zoff99 27 mr = map_rect_new(map, NULL);
7157 zoff99 40
7158 zoff99 27 if (!mr)
7159 zoff99 40 {
7160     //dbg(0, "return 005\n");
7161     return2;
7162     }
7163    
7164 zoff99 2 if (route_get_attr(route, attr_vehicleprofile, &vehicleprofile, NULL))
7165 zoff99 40 {
7166 zoff99 27 this_->vehicleprofile = vehicleprofile.u.vehicleprofile;
7167 zoff99 40 }
7168 zoff99 2 else
7169 zoff99 40 {
7170 zoff99 27 this_->vehicleprofile = NULL;
7171 zoff99 40 }
7172    
7173 zoff99 27 //dbg(1,"enter\n");
7174    
7175 zoff99 41 dbg(0, "NCC_:NU:------ LOOP START ------\n");
7176    
7177     int first_item = 1;
7178     this_->turn_around = 0;
7179    
7180 zoff99 27 while ((ritem = map_rect_get_item(mr)))
7181     {
7182 zoff99 41
7183     dbg(0, "NAVR:001:%s\n", item_to_name(ritem->type));
7184    
7185     #if 0
7186 zoff99 30 if (ritem->type == type_route_start && this_->turn_around > -this_->turn_around_limit + 1)
7187 zoff99 40 {
7188 zoff99 2 this_->turn_around--;
7189 zoff99 40 }
7190    
7191 zoff99 30 if (ritem->type == type_route_start_reverse && this_->turn_around < this_->turn_around_limit)
7192 zoff99 40 {
7193 zoff99 2 this_->turn_around++;
7194 zoff99 41 dbg(0, "NAVR:001.1:** TURN AROUND **\n");
7195 zoff99 40 }
7196 zoff99 41 #endif
7197 zoff99 40
7198 zoff99 41 #if 1
7199     if (first_item == 1)
7200 zoff99 40 {
7201 zoff99 41 first_item = 0;
7202     if (ritem->type == type_route_start_reverse)
7203     {
7204     this_->turn_around = this_->turn_around_limit;
7205    
7206     dbg(0, "NAV_TURNAROUND:006 ta=%d talimit=%d\n", this_->turn_around, this_->turn_around_limit);
7207    
7208     dbg(0, "NAVR:001.1:T_A:** TURN AROUND **:%s\n", item_to_name(ritem->type));
7209     }
7210     else
7211     {
7212     dbg(0, "NAVR:001.1:T_A:first item=%s\n", item_to_name(ritem->type));
7213     }
7214     }
7215     #endif
7216    
7217    
7218     dbg(0, "NAVR:001:X1:%s\n", item_to_name(ritem->type));
7219     if ((ritem->type != type_street_route) && (ritem->type != type_street_route_waypoint))
7220     {
7221     dbg(0, "NAVR:001:X2R:%s\n", item_to_name(ritem->type));
7222 zoff99 2 continue;
7223 zoff99 40 }
7224 zoff99 41 dbg(0, "NAVR:001:X3:%s\n", item_to_name(ritem->type));
7225 zoff99 27
7226     if (first && item_attr_get(ritem, attr_street_item, &street_item))
7227     {
7228     first = 0;
7229 zoff99 2 if (!item_attr_get(ritem, attr_direction, &street_direction))
7230 zoff99 40 {
7231 zoff99 27 street_direction.u.num = 0;
7232 zoff99 40 }
7233    
7234 zoff99 27 sitem = street_item.u.item;
7235     //dbg(1,"sitem=%p\n", sitem);
7236     itm = item_hash_lookup(this_->hash, sitem);
7237     //dbg(2,"itm for item with id (0x%x,0x%x) is %p\n", sitem->id_hi, sitem->id_lo, itm);
7238    
7239     if (itm && itm->way.dir != street_direction.u.num)
7240     {
7241     //dbg(2,"wrong direction\n");
7242 zoff99 41 dbg(0, "NAVR:001.2:*+ WRONG DIRECTION +*\n");
7243 zoff99 27 itm = NULL;
7244 zoff99 2 }
7245 zoff99 40
7246 zoff99 41 dbg(0, "NCC_:NU:navigation_destroy_itms_cmds\n");
7247 zoff99 2 navigation_destroy_itms_cmds(this_, itm);
7248 zoff99 40
7249 zoff99 27 if (itm)
7250     {
7251 zoff99 41 dbg(0, "NCC_:NU:navigation_itm_update\n");
7252    
7253 zoff99 2 navigation_itm_update(itm, ritem);
7254     break;
7255     }
7256 zoff99 27 //dbg(1,"not on track\n");
7257 zoff99 2 }
7258 zoff99 41
7259     dbg(0, "NAVR:001:X4:%s\n", item_to_name(ritem->type));
7260     dbg(0, "NCC_:NU:navigation_itm_new\n");
7261 zoff99 2 navigation_itm_new(this_, ritem);
7262 zoff99 41 dbg(0, "NAVR:001:X5:%s\n", item_to_name(ritem->type));
7263    
7264 zoff99 2 }
7265 zoff99 40
7266 zoff99 41
7267     dbg(0, "NCC_:NU:------ LOOP END ------\n");
7268    
7269    
7270 zoff99 40 //dbg(2, "turn_around=%d\n", this_->turn_around);
7271    
7272 zoff99 27 if (first)
7273 zoff99 40 {
7274    
7275     #ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
7276     dbg(0, "DEST::route_clear_freetext_list\n");
7277     route_clear_freetext_list();
7278     #endif
7279    
7280 zoff99 41 dbg(0, "NCC_:NU:navigation_destroy_itms_cmds[first]\n");
7281    
7282 zoff99 2 navigation_destroy_itms_cmds(this_, NULL);
7283 zoff99 40 }
7284 zoff99 27 else
7285     {
7286     if (!ritem)
7287     {
7288 zoff99 41 dbg(0, "NCC_:NU:navigation_itm_new[!ritem]\n");
7289 zoff99 2 navigation_itm_new(this_, NULL);
7290 zoff99 40 //dbg(0, "Enter: make_maneuvers\n");
7291 zoff99 41 dbg(0, "NAVR:001.2:*= MAKE MANEUVERS =*\n");
7292     dbg(0, "NCC_:NU:make_maneuvers[!ritem]\n");
7293 zoff99 27 make_maneuvers(this_, this_->route);
7294 zoff99 40 //dbg(0, "end : make_maneuvers\n");
7295 zoff99 2 }
7296 zoff99 41
7297     dbg(0, "NCC_:NU:calculate_dest_distance\n");
7298 zoff99 2 calculate_dest_distance(this_, incr);
7299 zoff99 40
7300     // calls navit_speak later !! ----------
7301 zoff99 2 navigation_call_callbacks(this_, FALSE);
7302 zoff99 40 // calls navit_speak later !! ----------
7303 zoff99 2 }
7304     map_rect_destroy(mr);
7305 zoff99 40
7306     __F_END__
7307 zoff99 2 }
7308 zoff99 40 // ----------- main place where navigation commands are generated ------------
7309     // ----------- main place where navigation commands are generated ------------
7310     // ----------- main place where navigation commands are generated ------------
7311 zoff99 2
7312 zoff99 40
7313 zoff99 27 static void navigation_flush(struct navigation *this_)
7314 zoff99 2 {
7315 zoff99 40 __F_START__
7316 zoff99 2 navigation_destroy_itms_cmds(this_, NULL);
7317 zoff99 40 __F_END__
7318 zoff99 2 }
7319    
7320 zoff99 27 void navigation_destroy(struct navigation *this_)
7321 zoff99 2 {
7322     navigation_flush(this_);
7323     item_hash_destroy(this_->hash);
7324     callback_list_destroy(this_->callback);
7325     callback_list_destroy(this_->callback_speech);
7326     g_free(this_);
7327     }
7328    
7329 zoff99 30 int navigation_register_callback(struct navigation *this_, enum attr_type type, struct callback *cb)
7330 zoff99 2 {
7331 zoff99 40 __F_START__
7332    
7333 zoff99 2 if (type == attr_navigation_speech)
7334 zoff99 40 {
7335 zoff99 2 callback_list_add(this_->callback_speech, cb);
7336 zoff99 40 }
7337 zoff99 2 else
7338 zoff99 40 {
7339 zoff99 2 callback_list_add(this_->callback, cb);
7340 zoff99 40 }
7341    
7342     return2 1;
7343    
7344     __F_END__
7345 zoff99 2 }
7346    
7347 zoff99 30 void navigation_unregister_callback(struct navigation *this_, enum attr_type type, struct callback *cb)
7348 zoff99 2 {
7349 zoff99 40 __F_START__
7350    
7351 zoff99 2 if (type == attr_navigation_speech)
7352 zoff99 40 {
7353 zoff99 2 callback_list_remove_destroy(this_->callback_speech, cb);
7354 zoff99 40 }
7355 zoff99 2 else
7356 zoff99 40 {
7357 zoff99 2 callback_list_remove_destroy(this_->callback, cb);
7358 zoff99 40 }
7359    
7360     __F_END__
7361 zoff99 2 }
7362    
7363     struct map *
7364     navigation_get_map(struct navigation *this_)
7365     {
7366     struct attr *attrs[5];
7367 zoff99 27 struct attr type, navigation, data, description;
7368     type.type = attr_type;
7369     type.u.str = "navigation";
7370     navigation.type = attr_navigation;
7371     navigation.u.navigation = this_;
7372     data.type = attr_data;
7373     data.u.str = "";
7374     description.type = attr_description;
7375     description.u.str = "Navigation";
7376    
7377     attrs[0] = &type;
7378     attrs[1] = &navigation;
7379     attrs[2] = &data;
7380     attrs[3] = &description;
7381     attrs[4] = NULL;
7382 zoff99 41
7383 zoff99 27 if (!this_->map)
7384 zoff99 41 {
7385 zoff99 27 this_->map = map_new(NULL, attrs);
7386 zoff99 41 }
7387    
7388 zoff99 27 return this_->map;
7389 zoff99 2 }
7390    
7391 zoff99 27 struct map_priv
7392     {
7393 zoff99 2 struct navigation *navigation;
7394     };
7395    
7396 zoff99 27 struct map_rect_priv
7397     {
7398 zoff99 2 struct navigation *nav;
7399     struct navigation_command *cmd;
7400     struct navigation_command *cmd_next;
7401     struct navigation_itm *itm;
7402     struct navigation_itm *itm_next;
7403     struct navigation_itm *cmd_itm;
7404     struct navigation_itm *cmd_itm_next;
7405     struct item item;
7406     enum attr_type attr_next;
7407     int ccount;
7408     int debug_idx;
7409     struct navigation_way *ways;
7410     int show_all;
7411     char *str;
7412     };
7413    
7414 zoff99 30 static int navigation_map_item_coord_get(void *priv_data, struct coord *c, int count)
7415 zoff99 2 {
7416 zoff99 27 struct map_rect_priv *this = priv_data;
7417 zoff99 40
7418 zoff99 27 if (this->ccount || !count)
7419 zoff99 41 {
7420     // dbg(0, "NAVICG:return 001 %d %d\n", this->ccount, count);
7421 zoff99 2 return 0;
7422 zoff99 41 }
7423 zoff99 40
7424 zoff99 41 if (this->item.type == type_nav_waypoint)
7425     {
7426     if (this->itm->way.dir == 99)
7427     {
7428     dbg(0, "NAVICG:waypoint:END of seg\n");
7429     *c = this->itm->end;
7430     }
7431     else
7432     {
7433     dbg(0, "NAVICG:waypoint:start of seg\n");
7434     *c = this->itm->start;
7435     }
7436     }
7437     else
7438     {
7439     // dbg(0, "NAVICG:normal type=%s cc=%d\n", item_to_name(this->item.type), this->ccount);
7440     *c = this->itm->start;
7441     }
7442    
7443 zoff99 27 this->ccount = 1;
7444 zoff99 40
7445 zoff99 2 return 1;
7446     }
7447    
7448 zoff99 30 static int navigation_map_item_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
7449 zoff99 2 {
7450 zoff99 27 struct map_rect_priv *this_ = priv_data;
7451     struct navigation_command *cmd = this_->cmd;
7452     struct navigation_itm *itm = this_->itm;
7453     struct navigation_itm *prev = itm->prev;
7454     attr->type = attr_type;
7455 zoff99 2
7456 zoff99 27 if (this_->str)
7457     {
7458 zoff99 2 g_free(this_->str);
7459 zoff99 27 this_->str = NULL;
7460 zoff99 2 }
7461    
7462 zoff99 27 if (cmd)
7463     {
7464 zoff99 2 if (cmd->itm != itm)
7465 zoff99 40 {
7466 zoff99 27 cmd = NULL;
7467 zoff99 40 }
7468 zoff99 2 }
7469 zoff99 40
7470 zoff99 27 switch (attr_type)
7471     {
7472     case attr_navigation_short:
7473     this_->attr_next = attr_navigation_long;
7474     if (cmd)
7475     {
7476 zoff99 40 //dbg(0, "attr_navigation_short\n");
7477 zoff99 30 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type);
7478 zoff99 2 return 1;
7479     }
7480 zoff99 27 return 0;
7481     case attr_navigation_long:
7482     this_->attr_next = attr_navigation_long_exact;
7483     if (cmd)
7484     {
7485 zoff99 40 //dbg(0, "attr_navigation_long\n");
7486 zoff99 30 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type);
7487 zoff99 2 return 1;
7488     }
7489 zoff99 27 return 0;
7490     case attr_navigation_long_exact:
7491     this_->attr_next = attr_navigation_speech;
7492     if (cmd)
7493     {
7494 zoff99 40 //dbg(0, "attr_navigation_long_exact\n");
7495 zoff99 30 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type);
7496 zoff99 2 return 1;
7497     }
7498 zoff99 27 return 0;
7499     case attr_navigation_speech:
7500     this_->attr_next = attr_length;
7501     if (cmd)
7502     {
7503 zoff99 40 //dbg(0, "attr_navigation_speech\n");
7504     //dbg(0, "Enter: attr_navigation_speech\n");
7505 zoff99 30 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, this_->cmd, attr_type);
7506 zoff99 40 //dbg(0, "back : attr_navigation_speech\n");
7507 zoff99 2 return 1;
7508     }
7509 zoff99 41 else if (this_->nav->turn_around_limit && this_->nav->turn_around == this_->nav->turn_around_limit)
7510     {
7511     if (global_turn_around_spoken == 0)
7512     {
7513     this_->str = attr->u.str = g_strdup(_("When possible, please turn around"));
7514     global_turn_around_spoken = 1;
7515     return 1;
7516     }
7517     else
7518     {
7519     return 0;
7520     }
7521     }
7522 zoff99 27 return 0;
7523     case attr_length:
7524     this_->attr_next = attr_time;
7525     if (cmd)
7526     {
7527 zoff99 30 attr->u.num = this_->cmd_itm->dest_length - cmd->itm->dest_length;
7528 zoff99 2 return 1;
7529     }
7530 zoff99 27 return 0;
7531     case attr_time:
7532     this_->attr_next = attr_destination_length;
7533     if (cmd)
7534     {
7535     attr->u.num = this_->cmd_itm->dest_time - cmd->itm->dest_time;
7536 zoff99 2 return 1;
7537     }
7538 zoff99 27 return 0;
7539 zoff99 40
7540 zoff99 27 case attr_destination_length:
7541     attr->u.num = itm->dest_length;
7542     this_->attr_next = attr_destination_time;
7543     return 1;
7544 zoff99 40
7545 zoff99 27 case attr_destination_time:
7546     attr->u.num = itm->dest_time;
7547     this_->attr_next = attr_street_name;
7548     return 1;
7549 zoff99 40
7550 zoff99 27 case attr_street_name:
7551     attr->u.str = itm->way.name1;
7552     this_->attr_next = attr_street_name_systematic;
7553     if (attr->u.str)
7554 zoff99 2 return 1;
7555 zoff99 27 return 0;
7556 zoff99 40
7557 zoff99 27 case attr_street_name_systematic:
7558     attr->u.str = itm->way.name2;
7559 zoff99 40 this_->attr_next = attr_street_destination;
7560     if (attr->u.str)
7561     return 1;
7562     return 0;
7563    
7564     case attr_street_destination:
7565     attr->u.str = itm->way.street_dest_text;
7566 zoff99 27 this_->attr_next = attr_debug;
7567     if (attr->u.str)
7568 zoff99 40 {
7569 zoff99 27 return 1;
7570 zoff99 40 }
7571 zoff99 27 return 0;
7572 zoff99 40
7573 zoff99 27 case attr_debug:
7574     switch (this_->debug_idx)
7575     {
7576     case 0:
7577     this_->debug_idx++;
7578 zoff99 30 this_->str = attr->u.str = g_strdup_printf("angle:%d (- %d)", itm->way.angle2, itm->angle_end);
7579 zoff99 27 return 1;
7580     case 1:
7581     this_->debug_idx++;
7582 zoff99 30 this_->str = attr->u.str = g_strdup_printf("item type:%s", item_to_name(itm->way.item.type));
7583 zoff99 27 return 1;
7584     case 2:
7585     this_->debug_idx++;
7586     if (cmd)
7587     {
7588 zoff99 30 this_->str = attr->u.str = g_strdup_printf("delta:%d", cmd->delta);
7589 zoff99 27 return 1;
7590     }
7591     case 3:
7592     this_->debug_idx++;
7593     if (prev)
7594     {
7595 zoff99 30 this_->str = attr->u.str = g_strdup_printf("prev street_name:%s", prev->way.name1);
7596 zoff99 27 return 1;
7597     }
7598     case 4:
7599     this_->debug_idx++;
7600     if (prev)
7601     {
7602 zoff99 30 this_->str = attr->u.str = g_strdup_printf("prev street_name_systematic:%s", prev->way.name2);
7603 zoff99 27 return 1;
7604     }
7605     case 5:
7606     this_->debug_idx++;
7607     if (prev)
7608     {
7609 zoff99 30 this_->str = attr->u.str = g_strdup_printf("prev angle:(%d -) %d", prev->way.angle2, prev->angle_end);
7610 zoff99 27 return 1;
7611     }
7612     case 6:
7613     this_->debug_idx++;
7614     this_->ways = itm->way.next;
7615     if (prev)
7616     {
7617 zoff99 30 this_->str = attr->u.str = g_strdup_printf("prev item type:%s", item_to_name(prev->way.item.type));
7618 zoff99 27 return 1;
7619     }
7620     case 7:
7621     if (this_->ways && prev)
7622     {
7623 zoff99 30 this_->str = attr->u.str = g_strdup_printf("other item angle:%d delta:%d flags:%d dir:%d type:%s id:(0x%x,0x%x)", this_->ways->angle2, angle_delta(prev->angle_end, this_->ways->angle2), this_->ways->flags, this_->ways->dir, item_to_name(this_->ways->item.type), this_->ways->item.id_hi, this_->ways->item.id_lo);
7624 zoff99 27 this_->ways = this_->ways->next;
7625     return 1;
7626     }
7627     this_->debug_idx++;
7628     case 8:
7629     this_->debug_idx++;
7630     if (prev)
7631     {
7632     int delta = 0;
7633 zoff99 41 int delta_real = 0;
7634 zoff99 27 char *reason = NULL;
7635 zoff99 41 maneuver_required2(this_->nav, prev, itm, &delta, &delta_real, &reason);
7636 zoff99 30 this_->str = attr->u.str = g_strdup_printf("reason:%s", reason);
7637 zoff99 27 return 1;
7638     }
7639    
7640     default:
7641     this_->attr_next = attr_none;
7642     return 0;
7643 zoff99 2 }
7644 zoff99 40
7645 zoff99 27 case attr_any:
7646     while (this_->attr_next != attr_none)
7647     {
7648 zoff99 30 if (navigation_map_item_attr_get(priv_data, this_->attr_next, attr))
7649 zoff99 27 return 1;
7650     }
7651     return 0;
7652 zoff99 40
7653 zoff99 2 default:
7654 zoff99 27 attr->type = attr_none;
7655 zoff99 2 return 0;
7656     }
7657     }
7658    
7659 zoff99 30 static struct item_methods navigation_map_item_methods = { NULL, navigation_map_item_coord_get, NULL, navigation_map_item_attr_get, };
7660 zoff99 2
7661 zoff99 27 static void navigation_map_destroy(struct map_priv *priv)
7662 zoff99 2 {
7663     g_free(priv);
7664     }
7665    
7666 zoff99 27 static void navigation_map_rect_init(struct map_rect_priv *priv)
7667 zoff99 2 {
7668 zoff99 27 priv->cmd_next = priv->nav->cmd_first;
7669     priv->cmd_itm_next = priv->itm_next = priv->nav->first;
7670 zoff99 2 }
7671    
7672     static struct map_rect_priv *
7673     navigation_map_rect_new(struct map_priv *priv, struct map_selection *sel)
7674     {
7675 zoff99 27 struct navigation *nav = priv->navigation;
7676 zoff99 2 struct map_rect_priv *ret=g_new0(struct map_rect_priv, 1);
7677 zoff99 27 ret->nav = nav;
7678 zoff99 40
7679 zoff99 2 navigation_map_rect_init(ret);
7680 zoff99 40
7681 zoff99 27 ret->item.meth = &navigation_map_item_methods;
7682     ret->item.priv_data = ret;
7683 zoff99 40
7684 zoff99 2 #ifdef DEBUG
7685     ret->show_all=1;
7686     #endif
7687 zoff99 40
7688 zoff99 2 return ret;
7689     }
7690    
7691 zoff99 27 static void navigation_map_rect_destroy(struct map_rect_priv *priv)
7692 zoff99 2 {
7693     g_free(priv);
7694     }
7695    
7696 zoff99 41
7697    
7698     void navigation_dump_items(struct navigation *this_)
7699     {
7700     if (this_->first)
7701     {
7702     dbg(0, "NAVR:dump:=================++++++++++++================\n");
7703     struct navigation_itm *i;
7704     int count = 0;
7705    
7706     i = this_->first;
7707     while (i)
7708     {
7709     count++;
7710     i = i->next;
7711     }
7712    
7713     i = this_->first;
7714     while (i)
7715     {
7716     count--;
7717     dbg(0, "NAVR:dump:count=%d %p %d\n", count, i, i->way.dir);
7718     i = i->next;
7719     }
7720     dbg(0, "NAVR:dump:=================++++++++++++================\n");
7721     }
7722     }
7723    
7724    
7725     // -----------------------------------
7726     static int save_last_dest_count = -1;
7727     // -----------------------------------
7728    
7729 zoff99 2 static struct item *
7730     navigation_map_get_item(struct map_rect_priv *priv)
7731     {
7732 zoff99 27 struct item *ret = &priv->item;
7733 zoff99 2 int delta;
7734 zoff99 40
7735 zoff99 41 int fake_dir1;
7736     int fake_dir2;
7737    
7738     dbg(0, "NAVR:ROUTE:Enter:\n");
7739     dbg(0, "NAVR:ROUTE:Enter:------------------------\n");
7740    
7741 zoff99 2 if (!priv->itm_next)
7742 zoff99 40 {
7743 zoff99 41 dbg(0, "NAVR:ROUTE:006:0000\n");
7744 zoff99 2 return NULL;
7745 zoff99 40 }
7746    
7747 zoff99 41 int stepped_to_waypoint = 0;
7748    
7749     // now check if we missed a waypoint, if so -> move back to waypoint -------------------------
7750     if (priv->itm)
7751     {
7752     if (save_last_dest_count != -1)
7753     {
7754     int count_back = (save_last_dest_count - priv->itm->dest_count - 1);
7755     int count_forw = count_back;
7756     dbg(0, "NAVR:ROUTE:006:cback:%d = (%d - %d - 1)\n", count_back, save_last_dest_count, priv->itm->dest_count);
7757    
7758     struct navigation_itm *i = priv->itm;
7759    
7760     // go to first item to check
7761     while (count_back > 0)
7762     {
7763     count_back--;
7764     if (i->prev)
7765     {
7766     i = i->prev;
7767     dbg(0, "NAVR:ROUTE:006:cback:stepping back to item #%d dir=%d\n", i->dest_count, i->way.dir);
7768     }
7769     }
7770    
7771     // now step forward until waypoint found, or just skip the whole thing if we dont find any waypoint
7772     while (count_forw > 0)
7773     {
7774     if (i)
7775     {
7776     dbg(0, "NAVR:ROUTE:006:cback:stepping forw to item #%d dir=%d\n", i->dest_count, i->way.dir);
7777    
7778     if ((i->way.dir == 99) || (i->way.dir == -99))
7779     {
7780     // found a waypoint
7781     priv->itm = i;
7782     stepped_to_waypoint = 1;
7783    
7784     dbg(0, "NAVR:ROUTE:006:cback:stepping found waypoint item #%d dir=%d itm=%p\n", priv->itm->dest_count, priv->itm->way.dir, priv->itm);
7785    
7786     break;
7787     }
7788    
7789     count_forw--;
7790     if (i->next)
7791     {
7792     i = i->next;
7793     }
7794     }
7795     }
7796    
7797     }
7798     }
7799     // now check if we missed a waypoint, if so -> move back to waypoint -------------------------
7800    
7801    
7802     if (priv->itm)
7803     {
7804     dbg(0, "NAVR:ROUTE:006:8888:1: %p dir=%d DST_COUNT(1)=%d\n", priv->itm, priv->itm->way.dir, priv->itm->dest_count);
7805     fake_dir1 = priv->itm->way.dir;
7806     save_last_dest_count = priv->itm->dest_count;
7807     }
7808     else
7809     {
7810     dbg(0, "NAVR:ROUTE:006:8888:1: NULL\n");
7811     fake_dir1 = 0;
7812     save_last_dest_count = -1;
7813     }
7814    
7815     if (stepped_to_waypoint != 1)
7816     {
7817     priv->itm = priv->itm_next;
7818     }
7819    
7820    
7821     fake_dir2 = priv->itm->way.dir;
7822     dbg(0, "NAVR:ROUTE:006:8888:2: %p dir=%d DST_COUNT(2)=%d\n", priv->itm, priv->itm->way.dir, priv->itm->dest_count);
7823 zoff99 27 priv->cmd = priv->cmd_next;
7824     priv->cmd_itm = priv->cmd_itm_next;
7825 zoff99 40
7826 zoff99 41 if ((priv->itm->way.dir == 99) || (priv->itm->way.dir == -99))
7827     {
7828     // return fake waypoint item!! ---------
7829     ret->type = type_nav_waypoint;
7830     ret->id_lo = priv->itm->dest_count;
7831     priv->ccount = 0;
7832    
7833     priv->itm_next = priv->itm->next;
7834    
7835     dbg(0, "NAVR:ROUTE:006:fake:%s dir=%d ,,,,,\n", item_to_name(ret->type), priv->itm->way.dir);
7836    
7837     return ret;
7838     }
7839    
7840    
7841    
7842     // navigation_dump_items(priv->nav);
7843    
7844 zoff99 2 if (!priv->cmd)
7845 zoff99 40 {
7846 zoff99 41 dbg(0, "NAVR:ROUTE:006:1111\n");
7847 zoff99 2 return NULL;
7848 zoff99 40 }
7849    
7850 zoff99 41
7851 zoff99 27 if (!priv->show_all && priv->itm->prev != NULL)
7852 zoff99 40 {
7853 zoff99 41 dbg(0, "NAVR:ROUTE:006:112a\n");
7854 zoff99 27 priv->itm = priv->cmd->itm;
7855 zoff99 40 }
7856    
7857 zoff99 27 priv->itm_next = priv->itm->next;
7858 zoff99 40
7859 zoff99 2 if (priv->itm->prev)
7860 zoff99 40 {
7861 zoff99 27 ret->type = type_nav_none;
7862 zoff99 40 }
7863 zoff99 2 else
7864 zoff99 40 {
7865 zoff99 27 ret->type = type_nav_position;
7866 zoff99 40 }
7867    
7868 zoff99 41 dbg(0, "NAVR:ROUTE:006:2222 %p dir=%d\n", priv->itm, priv->itm->way.dir);
7869    
7870 zoff99 27 if (priv->cmd->itm == priv->itm)
7871     {
7872 zoff99 41
7873     dbg(0, "NAVR:ROUTE:006:3333 %p dir=%d %p\n", priv->itm, priv->itm->way.dir, route_get_map(global_navit->route));
7874     // item_dump_coords(priv->itm, route_get_map(global_navit->route));
7875    
7876 zoff99 27 priv->cmd_itm_next = priv->cmd->itm;
7877     priv->cmd_next = priv->cmd->next;
7878 zoff99 40
7879 zoff99 2 if (priv->cmd_itm_next && !priv->cmd_itm_next->next)
7880 zoff99 40 {
7881 zoff99 27 ret->type = type_nav_destination;
7882 zoff99 40 }
7883 zoff99 27 else
7884     {
7885 zoff99 34 if (priv->itm && priv->itm->prev && !(priv->itm->way.flags & NAVIT_AF_ROUNDABOUT) && (priv->itm->prev->way.flags & NAVIT_AF_ROUNDABOUT))
7886 zoff99 27 {
7887     enum item_type r = type_none, l = type_none;
7888     switch (((180 + 22) - priv->cmd->roundabout_delta) / 45)
7889     {
7890     case 0:
7891     case 1:
7892     r = type_nav_roundabout_r1;
7893     l = type_nav_roundabout_l7;
7894     break;
7895     case 2:
7896     r = type_nav_roundabout_r2;
7897     l = type_nav_roundabout_l6;
7898     break;
7899     case 3:
7900     r = type_nav_roundabout_r3;
7901     l = type_nav_roundabout_l5;
7902     break;
7903     case 4:
7904     r = type_nav_roundabout_r4;
7905     l = type_nav_roundabout_l4;
7906     break;
7907     case 5:
7908     r = type_nav_roundabout_r5;
7909     l = type_nav_roundabout_l3;
7910     break;
7911     case 6:
7912     r = type_nav_roundabout_r6;
7913     l = type_nav_roundabout_l2;
7914     break;
7915     case 7:
7916     r = type_nav_roundabout_r7;
7917     l = type_nav_roundabout_l1;
7918     break;
7919     case 8:
7920     r = type_nav_roundabout_r8;
7921     l = type_nav_roundabout_l8;
7922     break;
7923 zoff99 2 }
7924 zoff99 40 // dbg(0, "delta %d\n", priv->cmd->delta);
7925    
7926 zoff99 2 if (priv->cmd->delta < 0)
7927 zoff99 40 {
7928 zoff99 27 ret->type = l;
7929 zoff99 40 }
7930 zoff99 2 else
7931 zoff99 40 {
7932 zoff99 27 ret->type = r;
7933 zoff99 40 }
7934 zoff99 27 }
7935     else
7936     {
7937     delta = priv->cmd->delta;
7938     if (delta < 0)
7939     {
7940     delta = -delta;
7941 zoff99 2 if (delta < 45)
7942 zoff99 27 ret->type = type_nav_left_1;
7943 zoff99 2 else if (delta < 105)
7944 zoff99 27 ret->type = type_nav_left_2;
7945     else if (delta < 165)
7946     ret->type = type_nav_left_3;
7947 zoff99 2 else
7948 zoff99 27 ret->type = type_none;
7949     }
7950 zoff99 40 else if (delta > 0)
7951 zoff99 27 {
7952 zoff99 2 if (delta < 45)
7953 zoff99 27 ret->type = type_nav_right_1;
7954 zoff99 2 else if (delta < 105)
7955 zoff99 27 ret->type = type_nav_right_2;
7956     else if (delta < 165)
7957     ret->type = type_nav_right_3;
7958 zoff99 2 else
7959 zoff99 27 ret->type = type_none;
7960 zoff99 2 }
7961 zoff99 40 else // delta == 0
7962     {
7963     ret->type = type_nav_straight;
7964     }
7965 zoff99 2 }
7966     }
7967     }
7968 zoff99 40
7969 zoff99 27 priv->ccount = 0;
7970     priv->debug_idx = 0;
7971     priv->attr_next = attr_navigation_short;
7972 zoff99 2
7973 zoff99 27 ret->id_lo = priv->itm->dest_count;
7974 zoff99 40
7975 zoff99 46 // dbg(0, "NAVR:ROUTE:006:%s ,,,,, ta=%d talim=%d\n", item_to_name(ret->type), priv->nav->turn_around, priv->nav->turn_around_limit);
7976 zoff99 41
7977    
7978     // check for "turn around" and return "type_nav_turnaround" !! ---------------
7979     if ((priv->nav->turn_around && priv->nav->turn_around == priv->nav->turn_around_limit) && (ret->type == type_nav_position))
7980     {
7981 zoff99 46 // dbg(0, "priv->itm->dest_count=%d\n", priv->itm->dest_count);
7982 zoff99 41 ret->type = type_nav_turnaround_right;
7983     }
7984     // check for "turn around" and return "type_nav_turnaround" !! ---------------
7985    
7986 zoff99 46 // dbg(0, "NAVR:ROUTE:007a:%s ,,,,, priv->itm->dest_count=%d\n", item_to_name(ret->type), priv->itm->dest_count);
7987 zoff99 41
7988 zoff99 2 return ret;
7989     }
7990    
7991     static struct item *
7992     navigation_map_get_item_byid(struct map_rect_priv *priv, int id_hi, int id_lo)
7993     {
7994     struct item *ret;
7995     navigation_map_rect_init(priv);
7996 zoff99 27 while ((ret = navigation_map_get_item(priv)))
7997     {
7998     if (ret->id_hi == id_hi && ret->id_lo == id_lo)
7999 zoff99 2 return ret;
8000     }
8001     return NULL;
8002     }
8003    
8004 zoff99 30 static 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, };
8005 zoff99 2
8006 zoff99 40 struct map_priv *
8007 zoff99 30 navigation_map_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl)
8008 zoff99 2 {
8009     struct map_priv *ret;
8010     struct attr *navigation_attr;
8011    
8012 zoff99 27 navigation_attr = attr_search(attrs, NULL, attr_navigation);
8013 zoff99 40
8014 zoff99 27 if (!navigation_attr)
8015 zoff99 40 {
8016 zoff99 34 return NULL;
8017 zoff99 40 }
8018    
8019 zoff99 34 ret=g_new0(struct map_priv, 1);
8020 zoff99 27 *meth = navigation_map_meth;
8021     ret->navigation = navigation_attr->u.navigation;
8022 zoff99 2
8023 zoff99 41 level_static_for_bicycle[0] = 22; // in meters
8024 zoff99 40 level_static_for_bicycle[1] = 100; // in meters
8025     level_static_for_bicycle[2] = -1; // dont announce
8026    
8027 zoff99 2 return ret;
8028     }
8029    
8030 zoff99 27 void navigation_set_route(struct navigation *this_, struct route *route)
8031 zoff99 2 {
8032 zoff99 40 __F_START__
8033    
8034 zoff99 2 struct attr callback;
8035 zoff99 27 this_->route = route;
8036 zoff99 30 this_->route_cb = callback_new_attr_1(callback_cast(navigation_update), attr_route_status, this_);
8037     callback_add_names(this_->route_cb, "navigation_set_route", "navigation_update");
8038 zoff99 27 callback.type = attr_callback;
8039     callback.u.callback = this_->route_cb;
8040 zoff99 2 route_add_attr(route, &callback);
8041 zoff99 40
8042     __F_END__
8043 zoff99 2 }
8044    
8045 zoff99 27 void navigation_init(void)
8046 zoff99 2 {
8047 zoff99 40 #ifdef PLUGSSS
8048 zoff99 2 plugin_register_map_type("navigation", navigation_map_new);
8049 zoff99 40 #endif
8050 zoff99 2 }
8051 zoff99 40
8052    

   
Visit the ZANavi Wiki