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

Contents of /navit/navit/navigation.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 56 - (hide annotations) (download)
Sun Mar 19 08:44:36 2017 UTC (7 years, 1 month ago) by zoff99
File MIME type: text/plain
File size: 205756 byte(s)
updates
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 zoff99 56 return NULL;
2092 zoff99 40 }
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 zoff99 56 return NULL;
2179 zoff99 40 }
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 zoff99 56 return NULL;
2194 zoff99 40 }
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 54
3250     //UNIT_TESTS_001_PATTERN_START
3251 zoff99 41 static int maneuver_required2(struct navigation *nav, struct navigation_itm *old, struct navigation_itm *new, int *delta, int *delta_real, char **reason)
3252 zoff99 2 {
3253 zoff99 54
3254 zoff99 27 int ret = 0, d, dw, dlim;
3255     char *r = NULL;
3256 zoff99 41 struct navigation_way *w = NULL;
3257 zoff99 30 int cat, ncat, wcat, maxcat, left = -180, right = 180, is_unambigous = 0, is_same_street;
3258 zoff99 41 int cat_2 = 0;
3259     int ncat_2 = 0;
3260     int highest_other_cat = 0;
3261     int original_d = 0;
3262 zoff99 2
3263 zoff99 41 dbg(0, "STRAI:000:\n");
3264     dbg(0, "STRAI:000:======================================\n");
3265    
3266 zoff99 51 tests_dbg(0, "\n=== maneuver_required2 [ENTER] ===");
3267    
3268 zoff99 41 // ---------------------------
3269     //
3270     // HINT: angle < 0 --> left
3271     // > 0 --> right
3272     // = 0 --> straight
3273     //
3274     // ---------------------------
3275    
3276 zoff99 27 d = angle_delta(old->angle_end, new->way.angle2);
3277 zoff99 41 original_d = d;
3278 zoff99 40
3279 zoff99 51
3280     #ifdef _CIDEBUG_BUILD_
3281     tests_dbg(0, "angle<0 : left");
3282     struct coord_geo g22;
3283     transform_to_geo(projection_mg, &old->end, &g22);
3284     tests_dbg(0, "http://www.openstreetmap.org/search?query=%f %f#map=19/%f/%f", g22.lat, g22.lng, g22.lat, g22.lng);
3285    
3286     tests_dbg(0, "delta=%d delta_real=%d d=%d", *delta, *delta_real, d);
3287     tests_dbg(0, "old->angle_end=%d new->way.angle2=%d", old->angle_end, new->way.angle2);
3288     tests_dbg(0, "from type=%s", item_to_name(old->way.item.type));
3289     tests_dbg(0, "to type=%s", item_to_name(new->way.item.type));
3290     #endif
3291    
3292    
3293 zoff99 40 //long long wayid_old = navigation_item_get_wayid(&(old->way));
3294     //long long wayid_new = navigation_item_get_wayid(&(new->way));
3295     //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);
3296    
3297 zoff99 41 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)) // bicycle mode
3298 zoff99 27 {
3299 zoff99 40 int flags_old = navigation_item_get_flags(&(old->way));
3300     int flags_new = navigation_item_get_flags(&(new->way));
3301    
3302     //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);
3303     //dbg(0, "(b2)old flags=%x new flags=%x\n", (flags_old & NAVIT_AF_ONEWAY), (flags_new & NAVIT_AF_ONEWAY));
3304     //dbg(0, "(b3)old flags=%x new flags=%x\n", (flags_old & NAVIT_AF_ONEWAYREV), (flags_new & NAVIT_AF_ONEWAYREV));
3305    
3306     if ((old->way.dir == 1) && ((new->way.dir == -1) && (new->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)))
3307     {
3308     r = "yes: bicycle starts going against oneway here (1)";
3309 zoff99 51 tests_dbg(0, "yes: bicycle starts going against oneway here (1)");
3310 zoff99 40 ret = 1;
3311     //dbg(0, "%s\n", r);
3312     }
3313     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)))
3314     {
3315     r = "yes: bicycle starts going against oneway here (2)";
3316     ret = 1;
3317     //dbg(0, "%s\n", r);
3318     }
3319 zoff99 27 }
3320 zoff99 40
3321    
3322    
3323    
3324     // z2z2
3325     int have_more_than_one_way_to_turn = 0;
3326 zoff99 41 int have_more_than_one_way_to_turn_cycleways = 0;
3327 zoff99 40 struct navigation_way *w22;
3328     w22 = new->way.next;
3329     int new_angle_abs = 999;
3330     int new_angle_abs_min = 999;
3331 zoff99 41 int new_angle_abs_min_allowed = 999;
3332     int new_angle_real = 999;
3333     int new_angle_min_allowed = 999;
3334     int new_angle_abs_min_ramp_allowed = 999;
3335 zoff99 40 int old_angle_abs = abs(d);
3336 zoff99 41 int new_angle_closest_to_cur = 999;
3337 zoff99 46 int no_correction = 0;
3338 zoff99 40
3339 zoff99 46 dbg(0, "STRAI:001:d=%d original_d=%d\n", old_angle_abs, original_d);
3340 zoff99 51 tests_dbg(0, "STRAI:001:d=%d original_d=%d", old_angle_abs, original_d);
3341 zoff99 40
3342 zoff99 51 tests_dbg(0, "\n-- other ways START --");
3343    
3344 zoff99 40 while (w22)
3345 zoff99 27 {
3346 zoff99 40
3347     dbg(0, "STRAI:002\n");
3348    
3349     //if ((w22->dir == -1) && (w22->flags & NAVIT_AF_ONEWAY))
3350     //{
3351     // // against oneway not allowed
3352     //}
3353 zoff99 41 if (((global_vehicle_profile != 1) && (global_vehicle_profile != 2)) // NOT bicycle mode
3354 zoff99 40 && (navigation_is_low_level_street(old->way.item.type) == 0)
3355     && (navigation_is_low_level_street(new->way.item.type) == 0)
3356     && (navigation_is_low_level_street(w22->item.type) == 1))
3357     {
3358     // dont count "lower" streets when not on "lower" street now or next
3359     }
3360     else
3361     {
3362 zoff99 41
3363     if ( (is_maybe_same_item(&(new->way), w22, 0) == 0) && (is_maybe_same_item(&(old->way), w22, 1) == 0) )
3364 zoff99 40 {
3365    
3366 zoff99 41 new_angle_real = angle_delta(old->angle_end, w22->angle2);
3367     new_angle_abs = abs(new_angle_real);
3368     if (new_angle_abs < new_angle_abs_min)
3369     {
3370     new_angle_abs_min = new_angle_abs;
3371     }
3372 zoff99 40
3373 zoff99 51 tests_dbg(0, "new_angle_real=%d new_angle_abs=%d is allowed=%d", new_angle_real, new_angle_abs, is_way_allowed(nav, w22, 1));
3374     tests_dbg(0, "old->angle_end=%d w22->angle2=%d", old->angle_end, w22->angle2);
3375     tests_dbg(0, "new_angle_abs_min=%d", new_angle_abs_min);
3376     tests_dbg(0, "other type=%s is_ramp=%d", item_to_name(w22->item.type), item_is_ramp(w22->item));
3377    
3378 zoff99 41 if (is_way_allowed(nav, w22, 1))
3379     {
3380     have_more_than_one_way_to_turn = 1;
3381 zoff99 40
3382 zoff99 41 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)) // bicycle mode
3383     {
3384     if (w22->item.type == type_cycleway)
3385     {
3386     have_more_than_one_way_to_turn_cycleways = 1;
3387     }
3388     }
3389    
3390     if (maneuver_category_calc2(w22->item.type) > highest_other_cat)
3391     {
3392     highest_other_cat = maneuver_category_calc2(w22->item.type);
3393     }
3394    
3395     if (item_is_ramp(w22->item))
3396     {
3397     if (new_angle_abs < new_angle_abs_min_ramp_allowed)
3398     {
3399     new_angle_abs_min_ramp_allowed = new_angle_abs;
3400     }
3401     }
3402    
3403     if (abs(new_angle_real - d) < abs(new_angle_closest_to_cur))
3404     {
3405     new_angle_closest_to_cur = new_angle_real;
3406     }
3407    
3408     if (new_angle_abs < new_angle_abs_min_allowed)
3409     {
3410     new_angle_abs_min_allowed = new_angle_abs;
3411     new_angle_min_allowed = new_angle_real;
3412     }
3413     }
3414    
3415     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);
3416    
3417 zoff99 51 tests_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", new_angle_abs, new_angle_abs_min_allowed, have_more_than_one_way_to_turn, new_angle_closest_to_cur, d);
3418    
3419    
3420 zoff99 40 }
3421     }
3422     w22 = w22->next;
3423 zoff99 2 }
3424 zoff99 40
3425 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);
3426 zoff99 51 tests_dbg(0, "STRAI:004 new_angle_abs_min=%d new_angle_abs_min_allowed=%d", new_angle_abs_min, new_angle_abs_min_allowed);
3427 zoff99 40
3428 zoff99 51 tests_dbg(0, "-- other ways END --\n");
3429    
3430    
3431 zoff99 41 if ((new_angle_abs_min_allowed > ROAD_ANGLE_IS_STRAIGHT_ABS) && (old_angle_abs <= ROAD_ANGLE_IS_STRAIGHT_ABS))
3432 zoff99 40 {
3433 zoff99 41 dbg(0, "STRAI:005 new_abs=%d old_abs=%d\n", new_angle_abs_min_allowed, old_angle_abs);
3434 zoff99 51 tests_dbg(0, "we want to drive almost straight, set angle to 0");
3435 zoff99 40 // we want to drive almost straight, set angle to "0"
3436     d = 0;
3437     }
3438    
3439     dbg(0, "STRAI:005a:d=%d\n", d);
3440 zoff99 51 tests_dbg(0, "STRAI:005a:d=%d", d);
3441 zoff99 40
3442 zoff99 27 if (!r)
3443     {
3444 zoff99 40 if (have_more_than_one_way_to_turn == 1) // more than 1 possibility
3445     {
3446     if (new->way.exit_label)
3447     {
3448 zoff99 41 // highway to highway, nearest ramp is more than 15° angle turn
3449 zoff99 46 if ( (cat > 6) && (ncat > 6) && (highest_other_cat <= 6) && (abs(d) < 12) && (new_angle_abs_min_ramp_allowed > 15) )
3450 zoff99 41 {
3451     dbg(0, "STRAI:005a:d=%d\n", d);
3452     r = "no: driving almost straight on highway and no other highway possibilities (1)";
3453 zoff99 53 tests_dbg(0, "no: STRAI:005a: driving almost straight on highway and no other highway possibilities (1)");
3454 zoff99 41 }
3455     else
3456     {
3457 zoff99 46 // r = "yes: we have an exit-sign to tell the user";
3458     // ret = 1;
3459 zoff99 41 }
3460 zoff99 40 }
3461     else if (new->way.s_destination)
3462     {
3463 zoff99 46 if ( (cat > 6) && (ncat > 6) && (highest_other_cat <= 6) && (abs(d) < 12) && (new_angle_abs_min_ramp_allowed > 15) )
3464 zoff99 41 {
3465     dbg(0, "STRAI:005a:d=%d\n", d);
3466     r = "no: driving almost straight on highway and no other highway possibilities (2)";
3467 zoff99 53 tests_dbg(0, "no: STRAI:005a: driving almost straight on highway and no other highway possibilities (2)");
3468 zoff99 41 }
3469     else
3470     {
3471 zoff99 46 // r = "yes: we have a road-sign to tell the user";
3472     // ret = 1;
3473 zoff99 41 }
3474 zoff99 40 }
3475 zoff99 41 else if (item_is_ramp(old->way.item))
3476 zoff99 40 {
3477     r = "yes: we are currently on a ramp and have more than 1 road to take";
3478 zoff99 53 tests_dbg(0, "yes: 001: we are currently on a ramp and have more than 1 road to take");
3479 zoff99 40 ret = 1;
3480     }
3481     }
3482     }
3483    
3484    
3485     if ((global_vehicle_profile != 1) && (global_vehicle_profile != 2))
3486     {
3487     if (!new->way.next)
3488     {
3489     /* No announcement necessary */
3490     r = "no: Only one possibility";
3491 zoff99 53 tests_dbg(0, "no: 002: Only one possibility");
3492 zoff99 40 }
3493 zoff99 41 else if (!new->way.next->next && item_is_ramp(new->way.next->item) && !is_way_allowed(nav, new->way.next, 1))
3494 zoff99 40 {
3495     /* If the other way is only a ramp and it is one-way in the wrong direction, no announcement necessary */
3496     r = "no: Only ramp";
3497 zoff99 53 tests_dbg(0, "no: 003: Only ramp");
3498 zoff99 40 }
3499     }
3500 zoff99 41 else // bicycle mode --------------------
3501 zoff99 40 {
3502     if (!r)
3503     {
3504     #if 0
3505     if ((!new->way.next) && (abs(d) < 20))
3506     {
3507     /* No announcement necessary */
3508     r = "no: Only one possibility and less than 20° turn";
3509 zoff99 53 tests_dbg(0, "no: 004: Only one possibility and less than 20° turn");
3510 zoff99 40 dbg(0, "%s\n", r);
3511     }
3512     else
3513     {
3514     if (abs(d) > 2)
3515     {
3516     r = "yes: bicycle mode";
3517     dbg(0, "%s\n", r);
3518     ret = 1;
3519     }
3520     else
3521     {
3522     r = "no: less than 3° turn";
3523     dbg(0, "%s\n", r);
3524     }
3525     }
3526     #endif
3527    
3528     #if 0
3529     if (!new->way.next)
3530     {
3531     /* No announcement necessary */
3532     r = "no: Only one possibility";
3533     }
3534     #endif
3535    
3536     #if 1
3537 zoff99 41
3538     if ((old->way.item.type == type_cycleway) && (new->way.item.type == type_cycleway))
3539 zoff99 40 {
3540 zoff99 41 if (have_more_than_one_way_to_turn_cycleways == 0)
3541 zoff99 40 {
3542 zoff99 41 if (abs(d) > ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE_CYC_2_CYC)
3543     {
3544     r = "yes: delta over ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE_CYC_2_CYC in bicycle mode (Only one possibility cyc-2-cyc)";
3545     //dbg(0, "%s\n", r);
3546     ret = 1;
3547     }
3548     else
3549     {
3550     r = "no: delta less than ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE_CYC_2_CYC in bicycle mode (Only one possibility cyc-2-cyc)";
3551     //dbg(0, "%s\n", r);
3552     ret = 0;
3553     }
3554 zoff99 40 }
3555     else
3556     {
3557 zoff99 41 if (abs(d) > ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE_CYC_2_CYC__2)
3558     {
3559     r = "yes: delta over ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE_CYC_2_CYC__2 in bicycle mode (cyc-2cyc)";
3560     //dbg(0, "%s\n", r);
3561     ret = 1;
3562     }
3563     else
3564     {
3565     r = "no: delta less than ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE_CYC_2_CYC__2 in bicycle mode (cyc-2cyc)";
3566     //dbg(0, "%s\n", r);
3567     ret = 0;
3568     }
3569 zoff99 40 }
3570     }
3571     else
3572     {
3573 zoff99 41
3574     if (!new->way.next)
3575 zoff99 40 {
3576 zoff99 41 if (abs(d) > ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE)
3577     {
3578     r = "yes: delta over ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE in bicycle mode (Only one possibility)";
3579     //dbg(0, "%s\n", r);
3580     ret = 1;
3581     }
3582     else
3583     {
3584     r = "no: delta less than ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE in bicycle mode (Only one possibility)";
3585     //dbg(0, "%s\n", r);
3586     ret = 0;
3587     }
3588 zoff99 40 }
3589     else
3590     {
3591 zoff99 41 if (abs(d) > ROAD_ANGLE_MIN__FOR_TURN_BICYCLEMODE_ONLY_1_POSSIBILITY)
3592     {
3593     r = "yes: delta over ROAD_ANGLE_MIN__FOR_TURN_BICYCLEMODE_ONLY_1_POSSIBILITY in bicycle mode";
3594     //dbg(0, "%s\n", r);
3595     ret = 1;
3596     }
3597     else
3598     {
3599     r = "no: delta less than ROAD_ANGLE_MIN__FOR_TURN_BICYCLEMODE_ONLY_1_POSSIBILITY in bicycle mode";
3600     //dbg(0, "%s\n", r);
3601     ret = 0;
3602     }
3603 zoff99 40 }
3604 zoff99 41
3605 zoff99 40 }
3606     #endif
3607    
3608     }
3609     }
3610    
3611     if (!r)
3612     {
3613 zoff99 34 if ((old->way.flags & NAVIT_AF_ROUNDABOUT) && !(new->way.flags & NAVIT_AF_ROUNDABOUT))
3614 zoff99 27 {
3615     r = "yes: leaving roundabout";
3616 zoff99 53 tests_dbg(0, "yes: 005: leaving roundabout");
3617 zoff99 27 ret = 1;
3618     }
3619 zoff99 34 else if (!(old->way.flags & NAVIT_AF_ROUNDABOUT) && (new->way.flags & NAVIT_AF_ROUNDABOUT))
3620 zoff99 27 {
3621     r = "no: entering roundabout";
3622 zoff99 53 tests_dbg(0, "no: 006: entering roundabout");
3623 zoff99 27 }
3624 zoff99 34 else if ((old->way.flags & NAVIT_AF_ROUNDABOUT) && (new->way.flags & NAVIT_AF_ROUNDABOUT))
3625 zoff99 40 {
3626 zoff99 27 r = "no: staying in roundabout";
3627 zoff99 53 tests_dbg(0, "no: 007: staying in roundabout");
3628 zoff99 40 }
3629 zoff99 2 }
3630 zoff99 40
3631     if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
3632 zoff99 27 {
3633 zoff99 40 if (!r && abs(d) > ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE)
3634     {
3635     /* always make an announcement if you have to make a turn */
3636     r = "yes: delta over ROAD_ANGLE_MIN_FOR_TURN_BICYCLEMODE in bicycle mode";
3637     //dbg(0, "%s\n", r);
3638     ret = 1;
3639     }
3640 zoff99 2 }
3641 zoff99 41 else // car mode ---------------------
3642 zoff99 40 {
3643     if (!r && abs(d) > 75)
3644     {
3645     /* always make an announcement if you have to make a sharp turn */
3646     r = "yes: delta over 75";
3647 zoff99 53 tests_dbg(0, "yes: 008: delta over 75");
3648 zoff99 40 ret = 1;
3649     }
3650     }
3651    
3652 zoff99 27 cat = maneuver_category(old->way.item.type);
3653     ncat = maneuver_category(new->way.item.type);
3654 zoff99 40
3655 zoff99 41 cat_2 = maneuver_category_calc2(old->way.item.type);
3656     ncat_2 = maneuver_category_calc2(new->way.item.type);
3657    
3658    
3659 zoff99 27 if (!r)
3660     {
3661 zoff99 2 /* Check whether the street keeps its name */
3662 zoff99 30 is_same_street = is_same_street2(old->way.name1, old->way.name2, new->way.name1, new->way.name2);
3663 zoff99 40
3664     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);
3665    
3666 zoff99 2 w = new->way.next;
3667 zoff99 27 maxcat = -1;
3668     while (w)
3669     {
3670 zoff99 41 if ( (is_maybe_same_item(&(new->way), w, 0) == 0) && (is_maybe_same_item(&(old->way), w, 1) == 0) )
3671     {
3672     dw = angle_delta(old->angle_end, w->angle2);
3673     dbg(0, "STRAI:011.02 dw=%d l=%d r=%d\n", dw, left, right);
3674 zoff99 40
3675 zoff99 41 if (dw < 0)
3676 zoff99 40 {
3677 zoff99 41 if (dw > left)
3678     {
3679     left = dw;
3680     }
3681 zoff99 40 }
3682 zoff99 41 else
3683 zoff99 40 {
3684 zoff99 41 if (dw < right)
3685     {
3686     right = dw;
3687     }
3688 zoff99 40 }
3689    
3690 zoff99 41 wcat = maneuver_category(w->item.type);
3691     dbg(0, "STRAI:011.03 wcat=%d\n", wcat);
3692 zoff99 40
3693 zoff99 41 /* If any other street has the same name [ removed:"but isn't a highway (a highway might split up temporarily)" ], then
3694     we can't use the same name criterium */
3695     // 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))
3696     if (is_same_street && is_same_street2(old->way.name1, old->way.name2, w->name1, w->name2) && is_way_allowed(nav, w, 2))
3697     {
3698     is_same_street = 0;
3699     dbg(0, "STRAI:011.04 is_same_street=%d\n", is_same_street);
3700     }
3701 zoff99 40
3702 zoff99 41 /* Mark if the street has a higher or the same category */
3703     if (wcat > maxcat)
3704     {
3705     maxcat = wcat;
3706     dbg(0, "STRAI:011.06 maxcat=%d wcat=%d\n", maxcat, wcat);
3707     }
3708    
3709 zoff99 40 }
3710    
3711 zoff99 2 w = w->next;
3712     }
3713 zoff99 40
3714     if (have_more_than_one_way_to_turn == 1) // more than 1 possibility
3715     {
3716     /* Even if the ramp has the same name, announce it */
3717 zoff99 41 if (item_is_ramp(new->way.item) && !item_is_ramp(old->way.item))
3718 zoff99 40 {
3719     is_same_street = 0;
3720     dbg(0, "STRAI:011.05.xx is_same_street=%d\n", is_same_street);
3721     }
3722     }
3723    
3724 zoff99 2 /* get the delta limit for checking for other streets. It is lower if the street has no other
3725 zoff99 27 streets of the same or higher category */
3726 zoff99 2 if (ncat < cat)
3727 zoff99 40 {
3728 zoff99 27 dlim = 80;
3729 zoff99 40 }
3730 zoff99 2 else
3731 zoff99 40 {
3732 zoff99 27 dlim = 120;
3733 zoff99 40 }
3734    
3735 zoff99 2 /* if the street is really straight, the others might be closer to straight */
3736     if (abs(d) < 20)
3737 zoff99 40 {
3738 zoff99 27 dlim /= 2;
3739 zoff99 40 }
3740    
3741 zoff99 27 if ((maxcat == ncat && maxcat == cat) || (ncat == 0 && cat == 0))
3742 zoff99 40 {
3743 zoff99 41 dlim = abs(d) * (620 / 256); // abs(d) * 2.4
3744 zoff99 40 }
3745 zoff99 2 else if (maxcat < ncat && maxcat < cat)
3746 zoff99 40 {
3747 zoff99 41 dlim = abs(d) * (128 / 256); // abs(d) * 0.5
3748 zoff99 40 }
3749    
3750 zoff99 41 if (left < -dlim && right > dlim) // no other road is between -dlim : dlim angle (no other road is "dlim" close to straight)
3751 zoff99 40 {
3752 zoff99 27 is_unambigous = 1;
3753 zoff99 40 }
3754    
3755 zoff99 27 if (!is_same_street && is_unambigous < 1)
3756     {
3757     ret = 1;
3758 zoff99 46 r = "yes: (not same street) or (ambigous [nicht eindeutig])";
3759 zoff99 53 tests_dbg(0, "yes: 009: (not same street) or (ambigous [nicht eindeutig])");
3760 zoff99 27 }
3761     else
3762 zoff99 40 {
3763 zoff99 46 r = "no: (same street) and (unambigous [eindeutig])";
3764 zoff99 53 tests_dbg(0, "no: 010: (same street) and (unambigous [eindeutig])");
3765 zoff99 40 }
3766    
3767 zoff99 41 if (ret == 0)
3768     {
3769 zoff99 53 tests_dbg(0, "enter: ret==0");
3770    
3771 zoff99 41 // add a new check here:
3772     if (have_more_than_one_way_to_turn == 1)
3773     {
3774 zoff99 53 tests_dbg(0, "have_more_than_one_way_to_turn == 1");
3775 zoff99 41
3776 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);
3777    
3778     if ( (cat > 6) && (ncat > 6) && (highest_other_cat <= 6) && (abs(d) < 70) )
3779 zoff99 41 {
3780     r = "no: from highway to highway (no other highway possibilities)";
3781 zoff99 53 tests_dbg(0, "no: 011: from highway to highway (no other highway possibilities)");
3782 zoff99 41 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);
3783     }
3784     else
3785     {
3786 zoff99 46
3787     if ((ncat == 6) && (highest_other_cat == 6) && (abs(d) < 50) && (abs(new_angle_closest_to_cur - original_d) < 65))
3788     {
3789     ret = 1;
3790     r = "yes: we are driving onto a ramp and there a other ramps near (<50 degrees) to it";
3791 zoff99 53 tests_dbg(0, "yes: 012: we are driving onto a ramp and there a other ramps near (<50 degrees) to it");
3792 zoff99 46 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);
3793     }
3794    
3795    
3796 zoff99 41 if ((d == 0) && (new_angle_abs_min_allowed >= 25))
3797     {
3798     r = "no: driving almost straight, and other ways not very close to straight";
3799 zoff99 53 tests_dbg(0, "no: 013: driving almost straight, and other ways not very close to straight");
3800 zoff99 41 dbg(0, "STRAI:011.07:3 abs(d)=%d new_angle_abs_min_allowed=%d\n", abs(d), new_angle_abs_min_allowed);
3801     }
3802     else
3803     {
3804    
3805     if ( (d == 0) && (abs(new_angle_closest_to_cur - original_d) < 16) )
3806     {
3807     ret = 1;
3808     r = "yes: we are going straight and some other way is very close to it";
3809 zoff99 53 tests_dbg(0, "yes: 014: we are going straight and some other way is very close to it");
3810 zoff99 41 dbg(0, "STRAI:011.07:0 abs(d)=%d new_angle_abs_min_allowed=%d\n", abs(d), new_angle_abs_min_allowed);
3811     }
3812     else if ( (ncat_2 <= highest_other_cat) && (d == 0) && (abs(new_angle_closest_to_cur - original_d) < 30) )
3813     {
3814     ret = 1;
3815     r = "yes: we are going straight and some other way is very close to it (same or higher cat)";
3816 zoff99 53 tests_dbg(0, "yes: 015: we are going straight and some other way is very close to it (same or higher cat)");
3817 zoff99 41 dbg(0, "STRAI:011.07:7 abs(d)=%d new_angle_abs_min_allowed=%d\n", abs(d), new_angle_abs_min_allowed);
3818     }
3819     else if ((abs(d) > 0) && (new_angle_abs_min_allowed < abs(d)))
3820     {
3821     ret = 1;
3822     r = "yes: some other way is going more straight";
3823 zoff99 53 tests_dbg(0, "yes: 016: some other way is going more straight");
3824 zoff99 41 dbg(0, "STRAI:011.07:0 abs(d)=%d new_angle_abs_min_allowed=%d\n", abs(d), new_angle_abs_min_allowed);
3825 zoff99 46
3826    
3827     if (abs(d) < 10)
3828     {
3829    
3830 zoff99 53 tests_dbg(0, "enter: (abs(d) < 10)");
3831    
3832     // ----------########### more ways left/right of way ? ###########----------
3833 zoff99 46 int more_ways_to_left_ = 0;
3834     int more_ways_to_right_ = 0;
3835     w = new->way.next;
3836     while (w)
3837     {
3838     if (is_way_allowed(nav, w, 1))
3839     {
3840     if ( (is_maybe_same_item(&(new->way), w, 0) == 0) && (is_maybe_same_item(&(old->way), w, 1) == 0) )
3841     {
3842     dbg(0, "STRAI:108.02a delta=%d\n", angle_delta(old->angle_end, w->angle2));
3843    
3844     if (is_way_allowed(nav, w, 1))
3845     {
3846     if (angle_delta(old->angle_end, w->angle2) < d) // other ways are going more to the left?
3847     {
3848     more_ways_to_left_++;
3849     }
3850     else if (angle_delta(old->angle_end, w->angle2) > d) // other ways are going more to the right?
3851     {
3852     more_ways_to_right_++;
3853     }
3854     }
3855     }
3856     }
3857     w = w->next;
3858     }
3859    
3860 zoff99 53 tests_dbg(0, "STRAI:108.02 %d %d\n", more_ways_to_left_, more_ways_to_right_);
3861 zoff99 46 dbg(0, "STRAI:108.02 %d %d\n", more_ways_to_left_, more_ways_to_right_);
3862    
3863    
3864     if ((d < 0) && (more_ways_to_left_ == 0)) // && (more_ways_to_right_ > 0))
3865     {
3866    
3867     dbg(0, "STRAI:108.03:left\n");
3868 zoff99 53 tests_dbg(0, "STRAI:108.03:left\n");
3869 zoff99 46 *delta_real = 0;
3870     d = -8;
3871     no_correction = 1;
3872     }
3873     else if ((d > 0) && (more_ways_to_left_ > 0)) // && (more_ways_to_right_ == 0))
3874     {
3875     dbg(0, "STRAI:108.04:right\n");
3876 zoff99 53 tests_dbg(0, "STRAI:108.04:right\n");
3877 zoff99 46 *delta_real = 0;
3878     d = 8;
3879     no_correction = 1;
3880     }
3881    
3882    
3883    
3884 zoff99 53 // ----------########### more ways left/right of way ? ###########----------
3885 zoff99 46
3886     }
3887    
3888    
3889 zoff99 41 }
3890     else if ((abs(d) > 0) && (new_angle_abs_min_allowed < 39) && (is_same_street))
3891     {
3892     if ( (cat == ncat) && (ncat_2 > highest_other_cat) )
3893     {
3894     r = "no: we need to make a turn, but other possibilites are much lower cat roads";
3895 zoff99 53 tests_dbg(0, "no: 017: we need to make a turn, but other possibilites are much lower cat roads");
3896 zoff99 41 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);
3897     }
3898     else
3899     {
3900     ret = 1;
3901     r = "yes: we need to make a turn";
3902 zoff99 53 tests_dbg(0, "yes: 018: we need to make a turn");
3903 zoff99 41 dbg(0, "STRAI:011.07:1iss abs(d)=%d new_angle_abs_min_allowed=%d\n", abs(d), new_angle_abs_min_allowed);
3904     }
3905     }
3906     else if ((abs(d) > 0) && (new_angle_abs_min_allowed < 52) && (!is_same_street))
3907     {
3908     if ( (cat == ncat) && (ncat_2 > highest_other_cat) )
3909     {
3910     r = "no: we need to make a turn, but other possibilites are much lower cat roads";
3911 zoff99 53 tests_dbg(0, "no: 019: we need to make a turn, but other possibilites are much lower cat roads");
3912 zoff99 41 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);
3913     }
3914     else
3915     {
3916     ret = 1;
3917     r = "yes: we need to make a turn";
3918 zoff99 53 tests_dbg(0, "yes: 020: we need to make a turn");
3919 zoff99 41 dbg(0, "STRAI:011.07:1nss abs(d)=%d new_angle_abs_min_allowed=%d\n", abs(d), new_angle_abs_min_allowed);
3920     }
3921     }
3922     else
3923     {
3924     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);
3925     }
3926     }
3927     }
3928     }
3929     }
3930    
3931 zoff99 46 dbg(0, "STRAI:011.07 is_unambigous[eindeutig]=%d ret=%d r=%s\n", is_unambigous, ret, r);
3932 zoff99 51 tests_dbg(0, "STRAI:011.07 is_unambigous[eindeutig]=%d ret=%d r=%s", is_unambigous, ret, r);
3933 zoff99 40
3934 zoff99 2 #ifdef DEBUG
3935 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);
3936 zoff99 2 #endif
3937     }
3938 zoff99 40
3939 zoff99 41
3940    
3941    
3942    
3943    
3944     dbg(0, "STRAI:007.00aa:d=%d ******************++++++++++++\n", d);
3945    
3946    
3947    
3948    
3949    
3950 zoff99 40 // correct "delta" (turn angle) here !! ---------------------------
3951     // correct "delta" (turn angle) here !! ---------------------------
3952    
3953 zoff99 46 if (no_correction == 0)
3954     {
3955 zoff99 53 tests_dbg(0, "enter: no_correction == 0");
3956 zoff99 46 *delta_real = d;
3957     }
3958 zoff99 41
3959 zoff99 46 if ((ret == 1) && (have_more_than_one_way_to_turn == 1) && (no_correction == 0))
3960 zoff99 27 {
3961 zoff99 40 w = new->way.next;
3962     //int d2 = angle_delta(old->angle_end, new->way.angle2);
3963     int d2 = d;
3964     //if (d == 0)
3965     //{
3966     // d2 = 0;
3967     //}
3968 zoff99 2
3969 zoff99 40 int correct_direction = 1;
3970    
3971 zoff99 41 dbg(0, "STRAI:007.01:d=%d d2=%d\n", d, d2);
3972 zoff99 53 tests_dbg(0, "STRAI:007.01:d=%d d2=%d\n", d, d2);
3973 zoff99 40
3974     if (d2 < 0) // left
3975 zoff99 27 {
3976 zoff99 40 while (w)
3977 zoff99 27 {
3978 zoff99 41 if (is_way_allowed(nav, w, 1))
3979 zoff99 40 {
3980 zoff99 41 if ( (is_maybe_same_item(&(new->way), w, 0) == 0) && (is_maybe_same_item(&(old->way), w, 1) == 0) )
3981     {
3982     if (angle_delta(old->angle_end, w->angle2) > d2) // other ways are going more to the right?
3983     {
3984     correct_direction = 0;
3985     break;
3986     }
3987     }
3988 zoff99 40 }
3989     w = w->next;
3990 zoff99 2 }
3991    
3992 zoff99 40 if (correct_direction == 1)
3993 zoff99 27 {
3994 zoff99 53 tests_dbg(0, "MAV:001:correct to right\n");
3995 zoff99 40 #ifdef NAVIT_ROUTING_DEBUG_PRINT
3996     dbg(0, "MAV:001:correct to right\n");
3997     #endif
3998     d = 8; // set to "slight right"
3999     }
4000     }
4001     else if (d2 > 0) // right
4002     {
4003     while (w)
4004     {
4005 zoff99 41 if (is_way_allowed(nav, w, 1))
4006 zoff99 27 {
4007 zoff99 41 if ( (is_maybe_same_item(&(new->way), w, 0) == 0) && (is_maybe_same_item(&(old->way), w, 1) == 0) )
4008     {
4009     if (angle_delta(old->angle_end, w->angle2) < d2) // other ways are going more to the left?
4010     {
4011     correct_direction = 0;
4012     break;
4013     }
4014     }
4015 zoff99 2 }
4016 zoff99 40 w = w->next;
4017 zoff99 27 }
4018 zoff99 40
4019     if (correct_direction == 1)
4020 zoff99 27 {
4021 zoff99 53 tests_dbg(0, "MAV:002:correct to left\n");
4022 zoff99 40 #ifdef NAVIT_ROUTING_DEBUG_PRINT
4023     dbg(0, "MAV:002:correct to left\n");
4024     #endif
4025     d = -8; // set to "slight left"
4026 zoff99 2 }
4027     }
4028 zoff99 40 else // (d2 == 0) // straight
4029     {
4030    
4031 zoff99 53 tests_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);
4032 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);
4033 zoff99 40
4034     int more_ways_to_left = 0;
4035     int more_ways_to_right = 0;
4036    
4037 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
4038 zoff99 40 {
4039 zoff99 53 tests_dbg(0, "STRAI:008.02\n");
4040 zoff99 40 dbg(0, "STRAI:008.02\n");
4041    
4042 zoff99 46
4043     if ((abs(new_angle_closest_to_cur - original_d) <= 25) || (abs(original_d) >= 10))
4044     // if (1 == 1)
4045 zoff99 40 {
4046 zoff99 46
4047     while (w)
4048 zoff99 41 {
4049 zoff99 46 if (is_way_allowed(nav, w, 1))
4050 zoff99 41 {
4051 zoff99 46 if ( (is_maybe_same_item(&(new->way), w, 0) == 0) && (is_maybe_same_item(&(old->way), w, 1) == 0) )
4052     {
4053 zoff99 53 tests_dbg(0, "STRAI:008.02a delta=%d\n", angle_delta(old->angle_end, w->angle2));
4054 zoff99 46 dbg(0, "STRAI:008.02a delta=%d\n", angle_delta(old->angle_end, w->angle2));
4055 zoff99 40
4056 zoff99 46 if (is_way_allowed(nav, w, 1))
4057 zoff99 41 {
4058 zoff99 46 if (angle_delta(old->angle_end, w->angle2) < d2) // other ways are going more to the left?
4059     {
4060     more_ways_to_left++;
4061     }
4062     else if (angle_delta(old->angle_end, w->angle2) > d2) // other ways are going more to the right?
4063     {
4064     more_ways_to_right++;
4065     }
4066 zoff99 41 }
4067     }
4068     }
4069 zoff99 46 w = w->next;
4070 zoff99 40 }
4071    
4072 zoff99 53 tests_dbg(0, "STRAI:008.02 %d %d\n", more_ways_to_left, more_ways_to_right);
4073 zoff99 46 dbg(0, "STRAI:008.02 %d %d\n", more_ways_to_left, more_ways_to_right);
4074 zoff99 40
4075 zoff99 46 if ((more_ways_to_left == 0) && (more_ways_to_right > 0))
4076     {
4077 zoff99 40
4078 zoff99 53 tests_dbg(0, "STRAI:008.03:left\n");
4079 zoff99 46 dbg(0, "STRAI:008.03:left\n");
4080 zoff99 40
4081     #ifdef NAVIT_ROUTING_DEBUG_PRINT
4082 zoff99 46 dbg(0, "MAV:003:correct to left\n");
4083 zoff99 2 #endif
4084 zoff99 46 d = -8;
4085     }
4086     else if ((more_ways_to_left > 0) && (more_ways_to_right == 0))
4087     {
4088 zoff99 53 tests_dbg(0, "STRAI:008.04:right\n");
4089 zoff99 46 dbg(0, "STRAI:008.04:right\n");
4090 zoff99 40
4091     #ifdef NAVIT_ROUTING_DEBUG_PRINT
4092 zoff99 46 dbg(0, "MAV:003:correct to right\n");
4093 zoff99 2 #endif
4094 zoff99 46 d = 8;
4095     }
4096    
4097 zoff99 40 }
4098 zoff99 46 else
4099     {
4100 zoff99 53 tests_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);
4101 zoff99 46 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);
4102     }
4103    
4104 zoff99 40 }
4105    
4106 zoff99 2 }
4107    
4108     }
4109    
4110 zoff99 40 // correct "delta" (turn angle) here !! ---------------------------
4111     // correct "delta" (turn angle) here !! ---------------------------
4112    
4113    
4114 zoff99 41
4115    
4116    
4117    
4118    
4119    
4120 zoff99 53 tests_dbg(0, "STRAI:099:ret=%d r=%s d=%d d_real=%d\n", ret, r, d, *delta_real);
4121 zoff99 41 dbg(0, "STRAI:099:ret=%d r=%s d=%d d_real=%d\n", ret, r, d, *delta_real);
4122     dbg(0, "STRAI:099:======================================\n");
4123    
4124 zoff99 40 *delta = d;
4125     if (reason)
4126 zoff99 27 {
4127 zoff99 40 *reason = r;
4128 zoff99 2 }
4129    
4130 zoff99 51 tests_dbg(0, "=== maneuver_required2 [Exit] ===");
4131    
4132 zoff99 54
4133 zoff99 40 return ret;
4134 zoff99 2 }
4135 zoff99 54 //UNIT_TESTS_001_PATTERN_END
4136 zoff99 2
4137 zoff99 54
4138 zoff99 41 static struct navigation_command *command_new(struct navigation *this_, struct navigation_itm *itm, int delta, int delta_real)
4139 zoff99 2 {
4140     struct navigation_command *ret=g_new0(struct navigation_command, 1);
4141 zoff99 40
4142 zoff99 27 //dbg(1, "enter this_=%p itm=%p delta=%d\n", this_, itm, delta);
4143     ret->delta = delta;
4144 zoff99 41 ret->delta_real = delta_real;
4145 zoff99 27 ret->itm = itm;
4146 zoff99 40
4147 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))
4148 zoff99 27 {
4149     int len = 0;
4150     int angle = 0;
4151 zoff99 2 int entry_angle;
4152 zoff99 27 struct navigation_itm *itm2 = itm->prev;
4153 zoff99 30 int exit_angle = angle_median(itm->prev->angle_end, itm->way.next->angle2);
4154 zoff99 27 //dbg(1, "exit %d median from %d,%d\n", exit_angle, itm->prev->angle_end, itm->way.next->angle2);
4155 zoff99 40
4156 zoff99 34 while (itm2 && (itm2->way.flags & NAVIT_AF_ROUNDABOUT))
4157 zoff99 27 {
4158     len += itm2->length;
4159     angle = itm2->angle_end;
4160     itm2 = itm2->prev;
4161 zoff99 2 }
4162 zoff99 40
4163 zoff99 27 if (itm2 && itm2->next && itm2->next->way.next)
4164     {
4165     itm2 = itm2->next;
4166 zoff99 30 entry_angle = angle_median(angle_opposite(itm2->way.angle2), itm2->way.next->angle2);
4167 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);
4168 zoff99 2 }
4169 zoff99 27 else
4170     {
4171     entry_angle = angle_opposite(angle);
4172     }
4173     //dbg(0, "entry %d exit %d\n", entry_angle, exit_angle);
4174     ret->roundabout_delta = angle_delta(entry_angle, exit_angle);
4175     ret->length = len + roundabout_extra_length;
4176 zoff99 2 }
4177 zoff99 40
4178 zoff99 27 if (this_->cmd_last)
4179     {
4180     this_->cmd_last->next = ret;
4181 zoff99 2 ret->prev = this_->cmd_last;
4182     }
4183 zoff99 40
4184 zoff99 27 this_->cmd_last = ret;
4185 zoff99 2
4186     if (!this_->cmd_first)
4187 zoff99 40 {
4188 zoff99 27 this_->cmd_first = ret;
4189 zoff99 40 }
4190    
4191 zoff99 2 return ret;
4192     }
4193    
4194 zoff99 40
4195    
4196     // ----------- main place where maneuvers generated (run only once) ------------
4197     // ----------- main place where maneuvers generated (run only once) ------------
4198     // ----------- main place where maneuvers generated (run only once) ------------
4199 zoff99 27 static void make_maneuvers(struct navigation *this_, struct route *route)
4200 zoff99 2 {
4201 zoff99 40 __F_START__
4202    
4203 zoff99 27 struct navigation_itm *itm, *last = NULL, *last_itm = NULL;
4204 zoff99 2 int delta;
4205 zoff99 41 int delta_real;
4206 zoff99 27 itm = this_->first;
4207     this_->cmd_last = NULL;
4208     this_->cmd_first = NULL;
4209     while (itm)
4210     {
4211     if (last)
4212     {
4213 zoff99 41 if (maneuver_required2(this_, last_itm, itm, &delta, &delta_real, NULL))
4214 zoff99 27 {
4215 zoff99 40 //dbg(0, "maneuver_required2 = true\n");
4216 zoff99 41 command_new(this_, itm, delta, delta_real);
4217 zoff99 2 }
4218 zoff99 27 }
4219     else
4220 zoff99 40 {
4221 zoff99 27 last = itm;
4222 zoff99 40 }
4223 zoff99 27 last_itm = itm;
4224     itm = itm->next;
4225 zoff99 2 }
4226 zoff99 41 command_new(this_, last_itm, 0, 0);
4227 zoff99 40
4228     __F_END__
4229 zoff99 2 }
4230 zoff99 40 // ----------- main place where maneuvers generated ------------
4231     // ----------- main place where maneuvers generated ------------
4232     // ----------- main place where maneuvers generated ------------
4233 zoff99 2
4234 zoff99 40
4235    
4236 zoff99 27 static int contains_suffix(char *name, char *suffix)
4237 zoff99 2 {
4238     if (!suffix)
4239 zoff99 41 {
4240 zoff99 2 return 0;
4241 zoff99 41 }
4242    
4243 zoff99 2 if (strlen(name) < strlen(suffix))
4244 zoff99 41 {
4245 zoff99 2 return 0;
4246 zoff99 41 }
4247    
4248 zoff99 27 return !g_strcasecmp(name + strlen(name) - strlen(suffix), suffix);
4249 zoff99 2 }
4250    
4251     static char *
4252     replace_suffix(char *name, char *search, char *replace)
4253     {
4254 zoff99 27 int len = strlen(name) - strlen(search);
4255     char *ret = g_malloc(len + strlen(replace) + 1);
4256 zoff99 41
4257 zoff99 2 strncpy(ret, name, len);
4258 zoff99 27 strcpy(ret + len, replace);
4259 zoff99 41
4260 zoff99 27 if (isupper(name[len]))
4261     {
4262     ret[len] = toupper(ret[len]);
4263 zoff99 2 }
4264    
4265     return ret;
4266     }
4267    
4268     static char *
4269 zoff99 30 navigation_item_destination(struct navigation *nav, struct navigation_itm *itm, struct navigation_itm *next, char *prefix)
4270 zoff99 2 {
4271 zoff99 27 char *ret = NULL, *name1, *sep, *name2;
4272     char *n1, *n2;
4273     int i, sex;
4274     int vocabulary1 = 65535;
4275     int vocabulary2 = 65535;
4276 zoff99 2 struct attr attr;
4277    
4278 zoff99 27 if (!prefix)
4279 zoff99 41 {
4280 zoff99 27 prefix = "";
4281 zoff99 41 }
4282 zoff99 40
4283 zoff99 30 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name, &attr, NULL))
4284 zoff99 41 {
4285 zoff99 27 vocabulary1 = attr.u.num;
4286 zoff99 41 }
4287 zoff99 40
4288 zoff99 30 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name_systematic, &attr, NULL))
4289 zoff99 41 {
4290 zoff99 27 vocabulary2 = attr.u.num;
4291 zoff99 41 }
4292 zoff99 40
4293 zoff99 27 n1 = itm->way.name1;
4294     n2 = itm->way.name2;
4295 zoff99 40
4296 zoff99 2 if (!vocabulary1)
4297 zoff99 27 n1 = NULL;
4298 zoff99 40
4299 zoff99 2 if (!vocabulary2)
4300 zoff99 27 n2 = NULL;
4301 zoff99 40
4302 zoff99 41 if (!n1 && !n2 && (item_is_ramp(itm->way.item)) && vocabulary2)
4303 zoff99 27 {
4304     //dbg(1,">> Next is ramp %lx current is %lx \n", itm->way.item.type, next->way.item.type);
4305    
4306 zoff99 40
4307     // disabled for now !!!!!!!! -------------------------
4308     #if 0
4309 zoff99 27 if (next->way.item.type == type_ramp)
4310 zoff99 40 {
4311 zoff99 2 return NULL;
4312 zoff99 40 }
4313     #endif
4314     // disabled for now !!!!!!!! -------------------------
4315    
4316    
4317     //else
4318     //{
4319     // return g_strdup_printf("%s%s",prefix,_("into the ramp"));
4320     //}
4321    
4322     #if 0
4323 zoff99 30 if (itm->way.item.type == type_highway_city || itm->way.item.type == type_highway_land)
4324 zoff99 27 {
4325     #ifdef HAVE_API_ANDROID
4326 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4327 zoff99 27 android_send_generic_text(1,"+*#O:exit\n");
4328     gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
4329     android_send_generic_text(1,xy);
4330     g_free(xy);
4331     #endif
4332 zoff99 28 #endif
4333 zoff99 27 return g_strdup_printf("%s%s", prefix, _("exit")); /* %FIXME Can this even be reached? and "exit" is the wrong text anyway ! */
4334     }
4335 zoff99 2 else
4336 zoff99 40 #endif
4337 zoff99 27 {
4338 zoff99 40 if (itm->way.street_dest_text)
4339     {
4340 zoff99 27 #ifdef HAVE_API_ANDROID
4341 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4342 zoff99 40 gchar* xy=g_strdup_printf("+*#0:%s\n", itm->way.street_dest_text);
4343     android_send_generic_text(1,xy);
4344     g_free(xy);
4345     gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
4346     android_send_generic_text(1,xy);
4347     g_free(xy);
4348 zoff99 27 #endif
4349 zoff99 28 #endif
4350 zoff99 40
4351     // say the name on the exit sign/destinaion sign
4352     return g_strdup_printf("%s%s", prefix, itm->way.street_dest_text);
4353     }
4354     else
4355     {
4356     #ifdef HAVE_API_ANDROID
4357     #ifdef NAVIT_SAY_DEBUG_PRINT
4358     android_send_generic_text(1,"+*#O:into the ramp\n");
4359     gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
4360     android_send_generic_text(1,xy);
4361     g_free(xy);
4362     #endif
4363     #endif
4364    
4365     return g_strdup_printf("%s%s", prefix, _("into the ramp"));
4366     }
4367 zoff99 27 }
4368    
4369 zoff99 2 }
4370 zoff99 27
4371 zoff99 40 if (!n1 && !n2 && !itm->way.street_dest_text)
4372 zoff99 27 {
4373 zoff99 2 return NULL;
4374 zoff99 27 }
4375    
4376 zoff99 40 if (itm->way.street_dest_text)
4377 zoff99 27 {
4378 zoff99 40 #ifdef HAVE_API_ANDROID
4379     #ifdef NAVIT_SAY_DEBUG_PRINT
4380     gchar* xy=g_strdup_printf("+*#0:%s\n", itm->way.street_dest_text);
4381     android_send_generic_text(1,xy);
4382     g_free(xy);
4383     gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
4384     android_send_generic_text(1,xy);
4385     g_free(xy);
4386     #endif
4387     #endif
4388     // say the name on the exit sign/destinaion sign
4389     return g_strdup_printf("%s%s", prefix, itm->way.street_dest_text);
4390     }
4391     else if (n1)
4392     {
4393 zoff99 27 sex = -1;
4394     name1 = NULL;
4395     for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++)
4396     {
4397     if (contains_suffix(n1, suffixes[i].fullname))
4398     {
4399     sex = suffixes[i].sex;
4400     name1 = g_strdup(n1);
4401 zoff99 2 break;
4402     }
4403 zoff99 27 if (contains_suffix(n1, suffixes[i].abbrev))
4404     {
4405     sex = suffixes[i].sex;
4406 zoff99 41
4407     // TODO: replacing strings here maybe not so good?!?
4408 zoff99 30 name1 = replace_suffix(n1, suffixes[i].abbrev, suffixes[i].fullname);
4409 zoff99 2 break;
4410     }
4411     }
4412 zoff99 27
4413     if (n2)
4414     {
4415     name2 = n2;
4416     sep = " ";
4417 zoff99 2 }
4418 zoff99 27 else
4419     {
4420     name2 = "";
4421     sep = "";
4422 zoff99 2 }
4423 zoff99 27
4424     gchar* xy;
4425     switch (sex)
4426     {
4427     case -1:
4428     #ifdef HAVE_API_ANDROID
4429 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4430 zoff99 27 android_send_generic_text(1,"+*#O:%sinto the street %s%s%s\n");
4431     xy=g_strdup_printf("+*#1:%s\n", prefix);
4432     android_send_generic_text(1,xy);
4433     g_free(xy);
4434     xy=g_strdup_printf("+*#1:%s\n", n1);
4435     android_send_generic_text(1,xy);
4436     g_free(xy);
4437     xy=g_strdup_printf("+*#1:%s\n", sep);
4438     android_send_generic_text(1,xy);
4439     g_free(xy);
4440     xy=g_strdup_printf("+*#1:%s\n", name2);
4441     android_send_generic_text(1,xy);
4442     g_free(xy);
4443     #endif
4444 zoff99 28 #endif
4445 zoff99 27 // TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name
4446 zoff99 30 ret = g_strdup_printf(_("%sinto the street %s%s%s"), prefix, n1, sep, name2);
4447 zoff99 27 break;
4448     case 1:
4449     #ifdef HAVE_API_ANDROID
4450 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4451 zoff99 27 android_send_generic_text(1,"+*#O:%sinto the %s%s%s|male form\n");
4452     xy=g_strdup_printf("+*#1:%s\n", prefix);
4453     android_send_generic_text(1,xy);
4454     g_free(xy);
4455     xy=g_strdup_printf("+*#1:%s\n", name1);
4456     android_send_generic_text(1,xy);
4457     g_free(xy);
4458     xy=g_strdup_printf("+*#1:%s\n", sep);
4459     android_send_generic_text(1,xy);
4460     g_free(xy);
4461     xy=g_strdup_printf("+*#1:%s\n", name2);
4462     android_send_generic_text(1,xy);
4463     g_free(xy);
4464     #endif
4465 zoff99 28 #endif
4466 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
4467 zoff99 30 ret = g_strdup_printf(_("%sinto the %s%s%s|male form"), prefix, name1, sep, name2);
4468 zoff99 27 break;
4469     case 2:
4470     #ifdef HAVE_API_ANDROID
4471 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4472 zoff99 27 android_send_generic_text(1,"+*#O:%sinto the %s%s%s|female form\n");
4473     xy=g_strdup_printf("+*#1:%s\n", prefix);
4474     android_send_generic_text(1,xy);
4475     g_free(xy);
4476     xy=g_strdup_printf("+*#1:%s\n", name1);
4477     android_send_generic_text(1,xy);
4478     g_free(xy);
4479     xy=g_strdup_printf("+*#1:%s\n", sep);
4480     android_send_generic_text(1,xy);
4481     g_free(xy);
4482     xy=g_strdup_printf("+*#1:%s\n", name2);
4483     android_send_generic_text(1,xy);
4484     g_free(xy);
4485     #endif
4486 zoff99 28 #endif
4487 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
4488 zoff99 30 ret = g_strdup_printf(_("%sinto the %s%s%s|female form"), prefix, name1, sep, name2);
4489 zoff99 27 break;
4490     case 3:
4491     #ifdef HAVE_API_ANDROID
4492 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4493 zoff99 27 android_send_generic_text(1,"+*#O:%sinto the %s%s%s|neutral form\n");
4494     xy=g_strdup_printf("+*#1:%s\n", prefix);
4495     android_send_generic_text(1,xy);
4496     g_free(xy);
4497     xy=g_strdup_printf("+*#1:%s\n", name1);
4498     android_send_generic_text(1,xy);
4499     g_free(xy);
4500     xy=g_strdup_printf("+*#1:%s\n", sep);
4501     android_send_generic_text(1,xy);
4502     g_free(xy);
4503     xy=g_strdup_printf("+*#1:%s\n", name2);
4504     android_send_generic_text(1,xy);
4505     g_free(xy);
4506     #endif
4507 zoff99 28 #endif
4508 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
4509 zoff99 30 ret = g_strdup_printf(_("%sinto the %s%s%s|neutral form"), prefix, name1, sep, name2);
4510 zoff99 27 break;
4511     }
4512 zoff99 2 g_free(name1);
4513 zoff99 27
4514     }
4515     else
4516     {
4517     #ifdef HAVE_API_ANDROID
4518 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
4519 zoff99 27 android_send_generic_text(1,"+*#O:sinto the %s\n");
4520     gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
4521     android_send_generic_text(1,xy);
4522     g_free(xy);
4523     xy=g_strdup_printf("+*#1:%s\n", n2);
4524     android_send_generic_text(1,xy);
4525     g_free(xy);
4526     #endif
4527 zoff99 28 #endif
4528 zoff99 27 // TRANSLATORS: gives the name of the next road to turn into (into the E17)
4529     ret = g_strdup_printf(_("%sinto the %s"), prefix, n2);
4530     }
4531    
4532     name1 = ret;
4533    
4534     while (name1 && *name1)
4535     {
4536     switch (*name1)
4537     {
4538     case '|':
4539     *name1 = '\0';
4540     break;
4541     case '/':
4542     *name1++ = ' ';
4543     break;
4544     default:
4545     name1++;
4546 zoff99 2 }
4547     }
4548 zoff99 27
4549 zoff99 2 return ret;
4550     }
4551    
4552 zoff99 41
4553    
4554    
4555     #define DONT_KNOW_LEVEL -997
4556    
4557    
4558 zoff99 2 static char *
4559 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)
4560 zoff99 40 {
4561     __F_START__
4562    
4563     // TRANSLATORS: right, as in 'Turn right'
4564     char *dir = _("right");
4565     char *strength = "";
4566     int distance = itm->dest_length - cmd->itm->dest_length;
4567     char *d, *ret = NULL;
4568     int delta = cmd->delta;
4569 zoff99 41 int delta_real = cmd->delta_real;
4570 zoff99 40 int level;
4571     int level_now = 99;
4572 zoff99 41 int level3;
4573 zoff99 40 int strength_needed;
4574     int skip_roads;
4575     int count_roundabout;
4576     struct navigation_itm *cur;
4577     struct navigation_way *w;
4578     int against_oneway = 0;
4579 zoff99 41 int keep_dir = 0;
4580     int old_dir = 0;
4581 zoff99 40
4582 zoff99 41 if (want_this_level == DONT_KNOW_LEVEL)
4583     {
4584     level3 = 1;
4585     }
4586     else
4587     {
4588     level3 = want_this_level;
4589     }
4590    
4591    
4592     int cur_vehicle_speed = 0;
4593     if ((global_navit) && (global_navit->vehicle))
4594     {
4595     cur_vehicle_speed = global_navit->vehicle->speed; // in km/h
4596     }
4597    
4598 zoff99 40 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
4599     {
4600     //dbg(0, "itm->way.flags=%x\n", itm->way.flags);
4601     //dbg(0, "itm->next->way.flags=%x\n", itm->next->way.flags);
4602     //dbg(0, "itm->way.dir=%d itm->next->way.dir=%d\n", itm->way.dir, itm->next->way.dir);
4603    
4604     //dbg(0, "2 itm->way.flags=%x\n", cmd->itm->way.flags);
4605     //dbg(0, "2 itm->next->way.flags=%x\n", cmd->itm->next->way.flags);
4606     //dbg(0, "2 itm->way.dir=%d itm->next->way.dir=%d\n", cmd->itm->way.dir, cmd->itm->next->way.dir);
4607    
4608     int flags_old = navigation_item_get_flags(&itm->way);
4609     int flags_new = 0;
4610     if (itm->next)
4611     {
4612     flags_new = navigation_item_get_flags(&itm->next->way);
4613     }
4614     //dbg(0, "(2211)old flags=%x new flags=%x\n", flags_old, flags_new);
4615    
4616     // long long wayid_old = navigation_item_get_wayid(&(itm->way));
4617     // long long wayid_new = navigation_item_get_wayid(&(itm->next->way));
4618     // dbg(0, "WID old_way_id=%lld new_way_id=%lld\n", wayid_old, wayid_new);
4619    
4620    
4621     if ( (itm->way.dir == 1) && ((itm->next->way.dir == -1) && (itm->next->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)) )
4622     {
4623     against_oneway = 1;
4624     //dbg(0, "SPEAK: (1)going against oneway street!\n");
4625     }
4626     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)) )
4627     {
4628     against_oneway = 1;
4629     //dbg(0, "SPEAK: (2)going against oneway street!\n");
4630     }
4631     }
4632    
4633     //dbg(0, "d=%d d3=%d\n", distance, (distance - cmd->length));
4634 zoff99 41 level_now = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length, 0);
4635 zoff99 40 //dbg(0, "level_now=%d\n", level_now);
4636    
4637     w = itm->next->way.next;
4638     strength_needed = 0;
4639    
4640 zoff99 41 if (angle_delta(itm->next->way.angle2, itm->angle_end) < 0) // left
4641 zoff99 40 {
4642     while (w)
4643     {
4644 zoff99 41 if (angle_delta(w->angle2, itm->angle_end) < 0) // other ways are going left
4645 zoff99 40 {
4646     strength_needed = 1;
4647     break;
4648     }
4649     w = w->next;
4650     }
4651     }
4652 zoff99 41 else // right
4653 zoff99 40 {
4654     while (w)
4655     {
4656 zoff99 41 if (angle_delta(w->angle2, itm->angle_end) > 0) // other ways are going right
4657 zoff99 40 {
4658     strength_needed = 1;
4659     break;
4660     }
4661     w = w->next;
4662     }
4663     }
4664    
4665    
4666 zoff99 41 if ((strength_needed == 0) && (delta < 9)) // for corrected turn (delta will be 8), use strength ("slight")
4667     {
4668     strength_needed = 1;
4669     }
4670    
4671 zoff99 40 //dbg(0, "cmd->delta=%d\n", delta);
4672    
4673     if (delta < 0)
4674     {
4675     // TRANSLATORS: left, as in 'Turn left'
4676     dir = _("left");
4677     delta = -delta;
4678 zoff99 41
4679     old_dir = -1; // left
4680 zoff99 40 }
4681 zoff99 41 else if (delta > 0)
4682     {
4683 zoff99 40
4684 zoff99 41 old_dir = 1; // right
4685    
4686     // dir = right
4687     }
4688     else // delta == 0 // go straight
4689     {
4690     dir = _("straight");
4691     strength_needed = 0;
4692     }
4693    
4694    
4695     keep_dir = 0;
4696    
4697 zoff99 40 if (strength_needed)
4698     {
4699     if (delta < 45)
4700     {
4701     // TRANSLATORS: Don't forget the ending space
4702     // TRANSLATORS: EXAMPLE: turn slight right
4703 zoff99 41 strength = _("slighty ");
4704     // TRANSLATORS: Don't forget the ending space
4705     // TRANSLATORS: EXAMPLE: turn slight right
4706 zoff99 40 strength = _("slight ");
4707 zoff99 41
4708     if (delta_real == 0) // keep left/right
4709     {
4710     if (old_dir == -1)
4711     {
4712     keep_dir = -1;
4713     }
4714     else
4715     {
4716     keep_dir = 1;
4717     }
4718     }
4719 zoff99 40 }
4720     else if (delta < 105)
4721     {
4722     strength = "";
4723     }
4724     else if (delta < 165)
4725     {
4726     // TRANSLATORS: Don't forget the ending space
4727     // TRANSLATORS: EXAMPLE: turn hard right
4728     strength = _("hard ");
4729     }
4730     else if (delta < 180)
4731     {
4732     // TRANSLATORS: Don't forget the ending space
4733     // TRANSLATORS: EXAMPLE: turn really hard right
4734     strength = _("really hard ");
4735     }
4736     else
4737     {
4738     // TRANSLATORS: Don't forget the ending space
4739     strength = "";
4740     }
4741     }
4742    
4743    
4744     if (type != attr_navigation_long_exact)
4745     {
4746     //dbg(0, "round distance d=%d dr=%d\n", distance, round_distance(distance));
4747     distance = round_distance(distance);
4748     }
4749    
4750    
4751    
4752    
4753     if (type == attr_navigation_speech)
4754     {
4755 zoff99 41 dbg(0, "NAV_TURNAROUND:003 ta=%d talimit=%d\n", nav->turn_around, nav->turn_around_limit);
4756    
4757 zoff99 40 if (nav->turn_around && nav->turn_around == nav->turn_around_limit)
4758     {
4759 zoff99 41 dbg(0, "NAV_TURNAROUND:004\n");
4760    
4761 zoff99 40 return2 g_strdup(_("When possible, please turn around"));
4762     }
4763 zoff99 41
4764     if (!connect)
4765     {
4766     if (want_this_level == DONT_KNOW_LEVEL)
4767     {
4768     level3 = navigation_get_announce_level_cmd(nav, itm, cmd, distance - cmd->length, ((float)cur_vehicle_speed / 3.6f) );
4769     }
4770     else
4771     {
4772     level3 = want_this_level;
4773     }
4774     }
4775    
4776     if (want_this_level == DONT_KNOW_LEVEL)
4777     {
4778     level_now = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length, ((float)cur_vehicle_speed / 3.6f) );
4779     }
4780     else
4781     {
4782     level_now = want_this_level;
4783     }
4784 zoff99 40 }
4785    
4786    
4787    
4788     switch (level3)
4789     {
4790     case 3:
4791     if (distance > 500)
4792     {
4793     d = get_distance(nav, distance, type, 1);
4794     ret = g_strdup_printf(_("Follow the road for the next %s"), d);
4795     g_free(d);
4796     }
4797     else
4798     {
4799     ret = g_strdup("");
4800     }
4801     return2 ret;
4802     // break;
4803     case 2:
4804     d = g_strdup(_("soon"));
4805     break;
4806     case 1:
4807     d = get_distance(nav, distance, attr_navigation_short, 0);
4808     break;
4809     case 0:
4810     // d = g_strdup(_("now"));
4811     d = g_strdup("");
4812     break;
4813     }
4814    
4815    
4816     // are there more commands left?
4817     if (cmd->itm->next)
4818     {
4819     int tellstreetname = 0;
4820     char *destination = NULL;
4821    
4822     if (type == attr_navigation_speech)
4823     {
4824     if (level3 == 1)
4825     {
4826     tellstreetname = 1; // Ok so we tell the name of the street
4827     }
4828     else // if (level3 == 0)
4829     {
4830     tellstreetname = 0;
4831     }
4832     }
4833     else
4834     {
4835     tellstreetname = 1;
4836     }
4837    
4838     if (global_speak_streetnames == 0)
4839     {
4840     // never speak streetnames (user config option)
4841     tellstreetname = 0;
4842     }
4843    
4844     if (nav->tell_street_name && tellstreetname)
4845     {
4846     destination = navigation_item_destination(nav, cmd->itm, itm, " ");
4847     }
4848    
4849    
4850     if (connect == 0)
4851     {
4852     //dbg(0, "level3=%5$d str=%1$s%2$s %3$s%4$s\n", strength, dir, d, destination ? destination : "", level3);
4853    
4854     if (level3 == 0)
4855     {
4856     if (against_oneway == 1)
4857     {
4858 zoff99 41 #if 1
4859 zoff99 40 if (delta < 10)
4860     {
4861     ret = g_strdup_printf("%s", _("oncoming traffic!")); // just say "attention oneway street!"
4862     }
4863     else
4864     {
4865     ret = g_strdup_printf("%s, %s", dir, _("oncoming traffic!")); // just say "left" or "right" at the turn + "attention oneway street!"
4866     }
4867 zoff99 41 #endif
4868    
4869 zoff99 40 }
4870     else
4871     {
4872 zoff99 41 #if 1
4873 zoff99 40 if (delta >= 10)
4874     {
4875     ret = g_strdup(dir); // just say "left" or "right" at the turn
4876     }
4877     else
4878     {
4879     ret = g_strdup("");
4880     }
4881 zoff99 41 #endif
4882    
4883     #if 0
4884     if (delta == 0)
4885     {
4886     ret = g_strdup(dir); // just say "left" or "right" or "straight" at the turn
4887     }
4888     else
4889     {
4890     if (keep_dir != 0)
4891     {
4892     if (keep_dir == -1)
4893     {
4894     // TRANSLATORS: The argument is the distance. Example: 'keep left in 100 meters'
4895     ret = g_strdup_printf(_("keep left %s"), "");
4896     }
4897     else
4898     {
4899     // TRANSLATORS: The argument is the distance. Example: 'keep right in 100 meters'
4900     ret = g_strdup_printf(_("keep right %s"), "");
4901     }
4902     }
4903     else
4904     {
4905     if (delta >= 10)
4906     {
4907     ret = g_strdup(dir); // just say "left" or "right" at the turn
4908     }
4909     else
4910     {
4911     ret = g_strdup("");
4912     }
4913     }
4914     }
4915     #endif
4916    
4917 zoff99 40 }
4918     }
4919     else // if (level3 == 1)
4920     {
4921     if ((against_oneway == 1) && (delta < 10))
4922     {
4923     ret = g_strdup(""); // probably just going against a oneway street, but travelling straight on. dont say anything now
4924     }
4925     else
4926     {
4927     if (delta >= 10)
4928     {
4929     // 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'
4930     ret = g_strdup_printf_4_str(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
4931     }
4932     else
4933     {
4934     ret = g_strdup("");
4935     }
4936     }
4937     }
4938    
4939     }
4940     else // (connect == 1)
4941     {
4942     if (level3 == 0)
4943     {
4944     if (against_oneway == 1)
4945     {
4946     if (delta < 10)
4947     {
4948     ret = g_strdup_printf("%s %s", _("then"), _("oncoming traffic!"));
4949     }
4950     else
4951     {
4952     ret = g_strdup_printf("%s %s %s", _("then"), dir, _("oncoming traffic!"));
4953     }
4954     }
4955     else
4956     {
4957     if (delta >= 10)
4958     {
4959     ret = g_strdup_printf("%s %s", _("then"), dir);
4960     }
4961     else
4962     {
4963     ret = g_strdup("");
4964     }
4965     }
4966     }
4967     else // if (level3 == 1)
4968     {
4969     if (against_oneway == 1)
4970     {
4971     if (delta < 10)
4972     {
4973     // nothing
4974     ret = g_strdup("");
4975     }
4976     else
4977     {
4978 zoff99 50 // TRANSLATORS: First argument is strength, second direction, third distance, fourth destination
4979 zoff99 40 ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
4980     }
4981     }
4982     else
4983     {
4984     if (delta >= 10)
4985     {
4986 zoff99 50 // TRANSLATORS: First argument is strength, second direction, third distance, fourth destination
4987 zoff99 40 ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
4988     }
4989     else
4990     {
4991     ret = g_strdup("");
4992     }
4993     }
4994     }
4995     }
4996    
4997    
4998     if (destination)
4999     {
5000     g_free(destination);
5001     destination = NULL;
5002     }
5003     }
5004     // no more commands left, must be at destination
5005     else
5006     {
5007     if (!connect)
5008     {
5009     d = get_distance(nav, distance, type, 1);
5010    
5011     // TRANSLATORS: EXAMPLE: You have reached your destination in 300 meters
5012     ret = g_strdup_printf(_("You have reached your destination %s"), d);
5013    
5014     g_free(d);
5015     }
5016     else
5017     {
5018     ret = g_strdup(_("then you have reached your destination."));
5019     }
5020     }
5021    
5022     return2 ret;
5023    
5024     __F_END__
5025     }
5026    
5027     int navigation_is_low_level_street(enum item_type t)
5028     {
5029     if (global_vehicle_profile == 0) // only in car profile!
5030     {
5031     if (t == type_street_service)
5032     {
5033     return 1;
5034     }
5035     else if (t == type_street_parking_lane)
5036     {
5037     return 1;
5038     }
5039     else if (t == type_track_ground)
5040     {
5041     return 1;
5042     }
5043     else if (t == type_track_grass)
5044     {
5045     return 1;
5046     }
5047     else if (t == type_track_gravelled)
5048     {
5049     return 1;
5050     }
5051     else if (t == type_track_unpaved)
5052     {
5053     return 1;
5054     }
5055     else if (t == type_track_paved)
5056     {
5057     return 1;
5058     }
5059     }
5060    
5061     return 0;
5062     }
5063    
5064 zoff99 41
5065    
5066 zoff99 40 static char *
5067 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)
5068 zoff99 2 {
5069 zoff99 40 __F_START__
5070    
5071 zoff99 27 // TRANSLATORS: right, as in 'Turn right'
5072     char *dir = _("right");
5073     char *strength = "";
5074     int distance = itm->dest_length - cmd->itm->dest_length;
5075     char *d, *ret = NULL;
5076     int delta = cmd->delta;
5077 zoff99 41 int delta_real = cmd->delta_real;
5078 zoff99 2 int level;
5079 zoff99 40 int level_now = 99;
5080 zoff99 2 int strength_needed;
5081     int skip_roads;
5082 zoff99 46 int count_roundabout; // car mode ----
5083 zoff99 2 struct navigation_itm *cur;
5084     struct navigation_way *w;
5085 zoff99 40 int against_oneway = 0;
5086 zoff99 46 int keep_dir = 0; // car mode ----
5087 zoff99 41 int old_dir = 0;
5088 zoff99 27
5089     if (connect)
5090     {
5091 zoff99 2 level = -2; // level = -2 means "connect to another maneuver via 'then ...'"
5092     }
5093 zoff99 27 else
5094     {
5095 zoff99 41 if (want_this_level == DONT_KNOW_LEVEL)
5096     {
5097     level = 1;
5098     }
5099     else
5100     {
5101     level = want_this_level;
5102     }
5103 zoff99 27 }
5104 zoff99 2
5105 zoff99 41 int cur_vehicle_speed = 0;
5106     if ((global_navit) && (global_navit->vehicle))
5107     {
5108     cur_vehicle_speed = global_navit->vehicle->speed; // in km/h
5109     }
5110    
5111    
5112 zoff99 40 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
5113     {
5114     //dbg(0, "itm->way.flags=%x\n", itm->way.flags);
5115     //dbg(0, "itm->next->way.flags=%x\n", itm->next->way.flags);
5116    
5117     // int flags_old = navigation_item_get_flags(&itm->way);
5118     // int flags_new = navigation_item_get_flags(&itm->next->way);
5119     // dbg(0, "old flags=%x new flags=%x\n", flags_old, flags_new);
5120    
5121     if ( (itm->way.dir == 1) && ((itm->next->way.dir == -1) && (itm->next->way.flags & NAVIT_AF_ONEWAY_BICYCLE_NO)) )
5122     {
5123     against_oneway = 1;
5124     //dbg(0, "SPEAK: (1)going against oneway street!\n");
5125     }
5126     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)) )
5127     {
5128     against_oneway = 1;
5129     //dbg(0, "SPEAK: (2)going against oneway street!\n");
5130     }
5131     }
5132    
5133 zoff99 2 w = itm->next->way.next;
5134     strength_needed = 0;
5135 zoff99 27
5136 zoff99 40 //dbg(0, "STRENGTH:001:strength_needed = %d delta = %d\n", strength_needed, delta);
5137    
5138     if (angle_delta(itm->next->way.angle2, itm->angle_end) < 0) // left
5139 zoff99 27 {
5140     while (w)
5141     {
5142 zoff99 40 if (angle_delta(w->angle2, itm->angle_end) < 0) // other ways are going left
5143 zoff99 27 {
5144 zoff99 2 strength_needed = 1;
5145 zoff99 40 // dbg(0, "STRENGTH:002:strength_needed = %d\n", strength_needed);
5146 zoff99 2 break;
5147     }
5148     w = w->next;
5149     }
5150 zoff99 27 }
5151 zoff99 40 else // right
5152 zoff99 27 {
5153     while (w)
5154     {
5155 zoff99 40 if (angle_delta(w->angle2, itm->angle_end) > 0) // other ways are going right
5156 zoff99 27 {
5157 zoff99 2 strength_needed = 1;
5158 zoff99 40 // dbg(0, "STRENGTH:003:strength_needed = %d\n", strength_needed);
5159 zoff99 2 break;
5160     }
5161     w = w->next;
5162     }
5163     }
5164    
5165 zoff99 46 if ((strength_needed == 0) && (delta < 9)) // for corrected turn (delta will be 8), use strength ("slight")
5166 zoff99 40 {
5167     strength_needed = 1;
5168     }
5169    
5170 zoff99 46 // dbg(0, "STRAI:K001:strength_needed=%d delta=%d delta_real=%d\n", strength_needed, delta, delta_real);
5171    
5172 zoff99 40 //dbg(0, "cmd->delta=%d\n", delta);
5173    
5174 zoff99 27 if (delta < 0)
5175     {
5176     #ifdef HAVE_API_ANDROID
5177 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5178 zoff99 27 android_send_generic_text(1,"+*#O:left\n");
5179     #endif
5180 zoff99 28 #endif
5181 zoff99 27 // TRANSLATORS: left, as in 'Turn left'
5182     dir = _("left");
5183     delta = -delta;
5184 zoff99 41
5185     old_dir = -1; // left
5186    
5187 zoff99 2 }
5188 zoff99 40 else if (delta > 0)
5189 zoff99 27 {
5190 zoff99 41
5191     old_dir = 1; // right
5192    
5193 zoff99 27 // dir = right
5194     #ifdef HAVE_API_ANDROID
5195 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5196 zoff99 27 android_send_generic_text(1,"+*#O:right\n");
5197     #endif
5198 zoff99 28 #endif
5199 zoff99 27 }
5200 zoff99 40 else // delta == 0 // go straight
5201     {
5202     dir = _("straight");
5203     strength_needed = 0;
5204     // dbg(0, "STRENGTH:004:strength_needed = %d\n", strength_needed);
5205     }
5206 zoff99 2
5207 zoff99 46 dbg(0, "STRAI:K002:*:strength_needed=%d delta=%d delta_real=%d\n", strength_needed, delta, delta_real);
5208 zoff99 40
5209 zoff99 46
5210 zoff99 41 keep_dir = 0;
5211    
5212 zoff99 27 if (strength_needed)
5213     {
5214 zoff99 40 // dbg(0, "STRENGTH:005:\n");
5215    
5216    
5217 zoff99 27 if (delta < 45)
5218     {
5219     #ifdef HAVE_API_ANDROID
5220 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5221 zoff99 27 android_send_generic_text(1,"+*#O:slight \n");
5222     #endif
5223 zoff99 28 #endif
5224 zoff99 27 // TRANSLATORS: Don't forget the ending space
5225     // TRANSLATORS: EXAMPLE: turn slight right
5226 zoff99 41 strength = _("slighty ");
5227     // TRANSLATORS: Don't forget the ending space
5228     // TRANSLATORS: EXAMPLE: turn slight right
5229 zoff99 27 strength = _("slight ");
5230 zoff99 40
5231 zoff99 41 if (delta_real == 0) // keep left/right
5232     {
5233     if (old_dir == -1)
5234     {
5235     keep_dir = -1;
5236     }
5237     else
5238     {
5239     keep_dir = 1;
5240     }
5241     }
5242    
5243 zoff99 46 dbg(0, "STRENGTH:006:strength_needed = %s\n", strength);
5244 zoff99 40
5245 zoff99 2 }
5246 zoff99 27 else if (delta < 105)
5247     {
5248     strength = "";
5249     }
5250     else if (delta < 165)
5251     {
5252     #ifdef HAVE_API_ANDROID
5253 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5254 zoff99 27 android_send_generic_text(1,"+*#O:hard \n");
5255     #endif
5256 zoff99 28 #endif
5257 zoff99 27 // TRANSLATORS: Don't forget the ending space
5258     // TRANSLATORS: EXAMPLE: turn hard right
5259     strength = _("hard ");
5260     }
5261     else if (delta < 180)
5262     {
5263     #ifdef HAVE_API_ANDROID
5264 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5265 zoff99 27 android_send_generic_text(1,"+*#O:really hard \n");
5266     #endif
5267 zoff99 28 #endif
5268 zoff99 27 // TRANSLATORS: Don't forget the ending space
5269     // TRANSLATORS: EXAMPLE: turn really hard right
5270     strength = _("really hard ");
5271     }
5272     else
5273     {
5274     // dbg(1,"delta=%d\n", delta);
5275     strength = "";
5276     }
5277 zoff99 2 }
5278 zoff99 27
5279 zoff99 40 // dbg(0, "STRENGTH:010:strength_needed = %s\n", strength);
5280    
5281    
5282 zoff99 27 if (type != attr_navigation_long_exact)
5283     {
5284     distance = round_distance(distance);
5285     }
5286    
5287     if (type == attr_navigation_speech)
5288     {
5289 zoff99 41 dbg(0, "NAV_TURNAROUND:001 ta=%d talimit=%d\n", nav->turn_around, nav->turn_around_limit);
5290    
5291 zoff99 27 if (nav->turn_around && nav->turn_around == nav->turn_around_limit)
5292     {
5293 zoff99 41
5294     dbg(0, "NAV_TURNAROUND:002:*******\n");
5295    
5296 zoff99 27 #ifdef HAVE_API_ANDROID
5297 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5298 zoff99 27 android_send_generic_text(1,"+*#O:When possible, please turn around\n");
5299     #endif
5300 zoff99 28 #endif
5301 zoff99 40 return2 g_strdup(_("When possible, please turn around"));
5302 zoff99 2 }
5303 zoff99 27
5304     if (!connect)
5305     {
5306 zoff99 41 if (want_this_level == DONT_KNOW_LEVEL)
5307     {
5308     level = navigation_get_announce_level_cmd(nav, itm, cmd, distance - cmd->length, ((float)cur_vehicle_speed / 3.6f) );
5309     }
5310     else
5311     {
5312     level = want_this_level;
5313     }
5314 zoff99 27 }
5315 zoff99 40
5316 zoff99 41 if (want_this_level == DONT_KNOW_LEVEL)
5317     {
5318     level_now = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length, ((float)cur_vehicle_speed / 3.6f) );
5319     }
5320     else
5321     {
5322     level_now = want_this_level;
5323     }
5324    
5325 zoff99 2 }
5326    
5327 zoff99 41 #ifdef NAVIT_DEBUG_COORD_LIST
5328 zoff99 40 int need_clear = 1;
5329     #endif
5330    
5331    
5332 zoff99 46 #if 1
5333     // ------------------- jandegr -------------------
5334    
5335     struct navigation_way *candidate_way;
5336    
5337 zoff99 34 if (cmd->itm->prev->way.flags & NAVIT_AF_ROUNDABOUT)
5338 zoff99 27 {
5339 zoff99 2 cur = cmd->itm->prev;
5340     count_roundabout = 0;
5341 zoff99 40
5342 zoff99 46 // ----- fix -----
5343 zoff99 40 struct navigation_itm *cur_orig = cur->next;
5344    
5345     enum item_type cur_street_type = 0;
5346     int exit_is_lover_street_type = 0;
5347     cur_street_type = cur_orig->way.item.type;
5348     // dbg(0, "curr item type=%s\n", item_to_name(cur_orig->way.item.type));
5349     exit_is_lover_street_type = navigation_is_low_level_street(cur_street_type);
5350    
5351     int next_exit_is_lower_street_type = 0;
5352 zoff99 46 // ----- fix -----
5353 zoff99 40
5354 zoff99 46
5355     dbg(0, "ROUNDABT:001:enter\n");
5356    
5357 zoff99 34 while (cur && (cur->way.flags & NAVIT_AF_ROUNDABOUT))
5358 zoff99 27 {
5359 zoff99 46
5360     // dbg(0, "ROUNDABT:002:loop-1:w\n");
5361    
5362     candidate_way=cur->next->way.next;
5363     while (candidate_way)
5364     {
5365    
5366     dbg(0, "ROUNDABT:002:loop-2:w2 type=%s\n", item_to_name(candidate_way->item.type));
5367    
5368     // If the next segment has no exit or the exit isn't allowed, don't count it
5369     if (candidate_way && is_way_allowed(nav, candidate_way, 3))
5370     {
5371    
5372     dbg(0, "ROUNDABT:003:is_allowed type=%s\n", item_to_name(candidate_way->item.type));
5373    
5374     // only count street_service (and lesser streets) if we also exit on street_service (or any lesser street)
5375     if (cur->next)
5376     {
5377     next_exit_is_lower_street_type = navigation_is_low_level_street(candidate_way->item.type);
5378    
5379     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));
5380     }
5381    
5382     if ((exit_is_lover_street_type == 1) || (next_exit_is_lower_street_type == 0))
5383     {
5384     count_roundabout++;
5385    
5386     dbg(0, "ROUNDABT:005:found:count_roundabout=%d\n", count_roundabout);
5387    
5388     /* As soon as we have an allowed one on this node,
5389     * stop further counting for this node.
5390     */
5391     candidate_way = candidate_way->next;
5392     break;
5393     }
5394     }
5395     candidate_way=candidate_way->next;
5396     }
5397     cur = cur->prev;
5398     }
5399    
5400     /*try to figure out if the entry node has a usable exit as well
5401     *
5402     * this will fail for left-hand driving areas
5403     */
5404     if (cur && cur->next)
5405     {
5406     dbg(0, "ROUNDABT:007:entry-check\n");
5407    
5408     candidate_way = cur->next->way.next;
5409     while (candidate_way)
5410     {
5411     dbg(0, "ROUNDABT:008:loop-3:w3 type=%s\n", item_to_name(candidate_way->item.type));
5412    
5413     if (candidate_way && is_way_allowed(nav,candidate_way,3)
5414     && (cur->angle_end < candidate_way->angle2) && ( candidate_way->angle2 > cur->next->way.angle2 ))
5415     /*for the entry node only count exits to the right ?*/
5416     {
5417     count_roundabout++;
5418    
5419     dbg(0, "ROUNDABT:009:entry:found:count_roundabout=%d\n", count_roundabout);
5420     /* As soon as we have an allowed one on this node,
5421     * stop further counting for this node.
5422     */
5423     break;
5424     }
5425     candidate_way = candidate_way->next;
5426     }
5427     }
5428    
5429     switch (level)
5430     {
5431     #if 0
5432     case 3:
5433     d=get_distance(nav, distance, type, 1);
5434     return g_strdup_printf(_("Follow the road for the next %s"), d);
5435     #endif
5436     case 2:
5437     return2 g_strdup(_("Enter the roundabout soon"));
5438     case 1:
5439     // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit
5440     return2 g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
5441     case -2:
5442     // TRANSLATORS: EXAMPLE: ... then leave the roundabout at the second exit
5443     return2 g_strdup_printf(_("then leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
5444     case 0:
5445     // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit
5446     return2 g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
5447     }
5448     }
5449    
5450    
5451     // ------------------- jandegr -------------------
5452     #endif
5453    
5454    
5455    
5456    
5457    
5458    
5459    
5460     #if 0
5461     // ------------------- zoff -------------------
5462    
5463     if (cmd->itm->prev->way.flags & NAVIT_AF_ROUNDABOUT)
5464     {
5465     cur = cmd->itm->prev;
5466     count_roundabout = 0;
5467    
5468     struct navigation_itm *cur_orig = cur->next;
5469    
5470     enum item_type cur_street_type = 0;
5471     int exit_is_lover_street_type = 0;
5472     cur_street_type = cur_orig->way.item.type;
5473     // dbg(0, "curr item type=%s\n", item_to_name(cur_orig->way.item.type));
5474     exit_is_lover_street_type = navigation_is_low_level_street(cur_street_type);
5475    
5476     int next_exit_is_lower_street_type = 0;
5477    
5478     while (cur && (cur->way.flags & NAVIT_AF_ROUNDABOUT))
5479     {
5480 zoff99 27 // If the next segment has no exit or the exit isn't allowed, don't count it
5481 zoff99 30 if (cur->next->way.next && is_way_allowed(nav, cur->next->way.next, 3))
5482 zoff99 27 {
5483 zoff99 40
5484     // only count street_service (and lesser streets) if we also exit on street_service (or any lesser street)
5485     if (cur->next)
5486     {
5487     next_exit_is_lower_street_type = navigation_is_low_level_street(cur->next->way.next->item.type);
5488     }
5489    
5490     if ((exit_is_lover_street_type == 1) || (next_exit_is_lower_street_type == 0))
5491     {
5492     count_roundabout++;
5493    
5494 zoff99 41 #ifdef NAVIT_DEBUG_COORD_LIST
5495 zoff99 40 if (need_clear == 1)
5496     {
5497     need_clear = 0;
5498     global_debug_coord_list_items = 0;
5499    
5500     struct coord c2[5];
5501    
5502     if (navigation_get_real_item_first_coord(&(cur_orig->way), c2))
5503     {
5504     global_debug_coord_list[global_debug_coord_list_items].x = c2[0].x;
5505     global_debug_coord_list[global_debug_coord_list_items].y = c2[0].y;
5506     global_debug_coord_list_items++;
5507     global_debug_coord_list[global_debug_coord_list_items].x = c2[1].x;
5508     global_debug_coord_list[global_debug_coord_list_items].y = c2[1].y;
5509     global_debug_coord_list_items++;
5510     }
5511    
5512     }
5513    
5514     struct coord c1[5];
5515     if (navigation_get_real_item_first_coord(cur->next->way.next, c1))
5516     {
5517     if ((global_debug_coord_list_items + 2) > MAX_DEBUG_COORDS)
5518     {
5519     global_debug_coord_list_items = 0;
5520     }
5521    
5522     global_debug_coord_list[global_debug_coord_list_items].x = c1[0].x;
5523     global_debug_coord_list[global_debug_coord_list_items].y = c1[0].y;
5524     global_debug_coord_list_items++;
5525     global_debug_coord_list[global_debug_coord_list_items].x = c1[1].x;
5526     global_debug_coord_list[global_debug_coord_list_items].y = c1[1].y;
5527     global_debug_coord_list_items++;
5528     }
5529     #endif
5530    
5531     }
5532 zoff99 2 }
5533     cur = cur->prev;
5534     }
5535 zoff99 27
5536     gchar* xy;
5537    
5538     switch (level)
5539     {
5540     case 2:
5541     #ifdef HAVE_API_ANDROID
5542 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5543 zoff99 27 android_send_generic_text(1,"+*#O:Enter the roundabout soon\n");
5544     #endif
5545 zoff99 28 #endif
5546 zoff99 40 return2 g_strdup(_("Enter the roundabout soon"));
5547    
5548    
5549    
5550    
5551 zoff99 27 case 1:
5552 zoff99 40
5553    
5554     #ifdef HAVE_API_ANDROID
5555     #ifdef NAVIT_SAY_DEBUG_PRINT
5556     android_send_generic_text(1,"+*#O:Leave the roundabout at the %s\n");
5557     xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
5558     android_send_generic_text(1,xy);
5559     g_free(xy);
5560     #endif
5561     #endif
5562     // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit
5563     return2 g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
5564    
5565    
5566     // ---- DISABLED ----
5567     #if 0
5568 zoff99 27 d = get_distance(nav, distance, type, 1);
5569    
5570     #ifdef HAVE_API_ANDROID
5571 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5572 zoff99 27 android_send_generic_text(1,"+*#O:In %s, enter the roundabout\n");
5573     xy=g_strdup_printf("+*#1:%s\n", d);
5574     android_send_generic_text(1,xy);
5575     g_free(xy);
5576     #endif
5577 zoff99 28 #endif
5578 zoff99 27 // TRANSLATORS: %s is the distance to the roundabout
5579     // TRANSLATORS: EXAMPLE: In 300m, enter the roundabout
5580     ret = g_strdup_printf(_("In %s, enter the roundabout"), d);
5581     g_free(d);
5582 zoff99 40 return2 ret;
5583     #endif
5584     // ---- DISABLED ----
5585    
5586    
5587    
5588 zoff99 27 case -2:
5589     #ifdef HAVE_API_ANDROID
5590 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5591 zoff99 27 android_send_generic_text(1,"+*#O:then leave the roundabout at the %s\n");
5592     xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
5593     android_send_generic_text(1,xy);
5594     g_free(xy);
5595     #endif
5596 zoff99 28 #endif
5597 zoff99 27 // TRANSLATORS: EXAMPLE: ... then leave the roundabout at the second exit
5598 zoff99 40 return2 g_strdup_printf(_("then leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
5599    
5600    
5601 zoff99 27 case 0:
5602     #ifdef HAVE_API_ANDROID
5603 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5604 zoff99 27 android_send_generic_text(1,"+*#O:Leave the roundabout at the %s\n");
5605     xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
5606     android_send_generic_text(1,xy);
5607     g_free(xy);
5608     #endif
5609 zoff99 28 #endif
5610 zoff99 27 // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit
5611 zoff99 40 return2 g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
5612 zoff99 27 }
5613     }
5614    
5615 zoff99 46 // ------------------- zoff -------------------
5616     #endif
5617    
5618    
5619    
5620    
5621    
5622    
5623    
5624    
5625    
5626 zoff99 40 // -- NEW 002 --
5627     if (cmd->itm)
5628     {
5629     // put correct destination into struct (to later show in GUI)
5630     navigation_select_announced_destinations(cmd);
5631     // string is in cmd->itm->way.street_dest_text
5632     }
5633     // -- NEW 002 --
5634    
5635    
5636    
5637 zoff99 27 switch (level)
5638     {
5639     case 3:
5640 zoff99 40 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
5641     {
5642     if (distance > 500)
5643     {
5644     d = get_distance(nav, distance, type, 1);
5645 zoff99 27
5646     #ifdef HAVE_API_ANDROID
5647 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5648 zoff99 40 android_send_generic_text(1,"+*#O:Follow the road for the next %s\n");
5649     gchar* xy=g_strdup_printf("+*#1:%s\n", d);
5650     android_send_generic_text(1,xy);
5651     g_free(xy);
5652 zoff99 27 #endif
5653 zoff99 28 #endif
5654 zoff99 40
5655     ret = g_strdup_printf(_("Follow the road for the next %s"), d);
5656     g_free(d);
5657     }
5658     else
5659     {
5660     ret = g_strdup("");
5661     }
5662     }
5663     else
5664     {
5665     d = get_distance(nav, distance, type, 1);
5666    
5667     #ifdef HAVE_API_ANDROID
5668     #ifdef NAVIT_SAY_DEBUG_PRINT
5669     android_send_generic_text(1,"+*#O:Follow the road for the next %s\n");
5670     gchar* xy=g_strdup_printf("+*#1:%s\n", d);
5671     android_send_generic_text(1,xy);
5672     g_free(xy);
5673     #endif
5674     #endif
5675     // TRANSLATORS: EXAMPLE: Follow the road for the next 300 meters
5676     ret = g_strdup_printf(_("Follow the road for the next %s"), d);
5677     g_free(d);
5678     }
5679     return2 ret;
5680 zoff99 2 case 2:
5681 zoff99 27 #ifdef HAVE_API_ANDROID
5682 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5683 zoff99 27 android_send_generic_text(1,"+*#O:soon\n");
5684     #endif
5685 zoff99 28 #endif
5686 zoff99 40
5687     // dbg(0, "SPK:*soon*\n");
5688    
5689    
5690 zoff99 27 d = g_strdup(_("soon"));
5691     break;
5692 zoff99 2 case 1:
5693 zoff99 27 d = get_distance(nav, distance, attr_navigation_short, 0);
5694     break;
5695     case 0:
5696 zoff99 50 // DISABLE S_R // skip_roads = count_possible_turns(nav, cmd->prev ? cmd->prev->itm : nav->first, cmd->itm, cmd->delta);
5697     skip_roads = 0;
5698 zoff99 48
5699     dbg(0, "count_possible_turns:1:%d", skip_roads);
5700    
5701 zoff99 40 if ((skip_roads > 0) && ((global_vehicle_profile != 1) && (global_vehicle_profile != 2)))
5702 zoff99 27 {
5703     if (get_count_str(skip_roads + 1))
5704     {
5705 zoff99 48
5706     // marker -1- //
5707    
5708 zoff99 27 #ifdef HAVE_API_ANDROID
5709 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5710 zoff99 27 android_send_generic_text(1,"+*#O:Take the %1$s road to the %2$s\n");
5711     gchar* xy=g_strdup_printf("+*#1:%s\n", get_count_str(skip_roads + 1));
5712     android_send_generic_text(1,xy);
5713     g_free(xy);
5714     xy=g_strdup_printf("+*#1:%s\n", dir);
5715     android_send_generic_text(1,xy);
5716     g_free(xy);
5717     #endif
5718 zoff99 28 #endif
5719 zoff99 27 // TRANSLATORS: First argument is the how manieth street to take, second the direction
5720 zoff99 40 ret = g_strdup_printf_2_str(_("Take the %1$s road to the %2$s"), get_count_str(skip_roads + 1), dir);
5721     return2 ret;
5722 zoff99 27 }
5723     else
5724     {
5725     #ifdef HAVE_API_ANDROID
5726 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5727 zoff99 27 android_send_generic_text(1,"+*#O:after %i roads\n");
5728     gchar* xy=g_strdup_printf("+*#1:%i\n", skip_roads);
5729     android_send_generic_text(1,xy);
5730     g_free(xy);
5731     #endif
5732 zoff99 28 #endif
5733 zoff99 27 d = g_strdup_printf(_("after %i roads"), skip_roads);
5734     }
5735     }
5736     else
5737     {
5738     #ifdef HAVE_API_ANDROID
5739 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5740 zoff99 27 android_send_generic_text(1,"+*#O:now\n");
5741     #endif
5742 zoff99 28 #endif
5743 zoff99 27 d = g_strdup(_("now"));
5744     }
5745 zoff99 40
5746 zoff99 27 break;
5747 zoff99 40
5748 zoff99 2 case -2:
5749 zoff99 50 // DISABLE S_R // skip_roads = count_possible_turns(nav, cmd->prev->itm, cmd->itm, cmd->delta);
5750     skip_roads = 0;
5751 zoff99 48
5752     dbg(0, "count_possible_turns:2:%d", skip_roads);
5753    
5754 zoff99 40 if ((skip_roads > 0) && ((global_vehicle_profile != 1) && (global_vehicle_profile != 2)))
5755 zoff99 27 {
5756     // TRANSLATORS: First argument is the how manieth street to take, second the direction
5757     // TRANSLATORS: EXAMPLE: ... then take the second road to the right
5758     if (get_count_str(skip_roads + 1))
5759     {
5760 zoff99 48
5761     // marker -2- //
5762    
5763 zoff99 27 #ifdef HAVE_API_ANDROID
5764 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5765 zoff99 27 android_send_generic_text(1,"+*#O:then take the %1$s road to the %2$s\n");
5766     gchar* xy=g_strdup_printf("+*#1:%s\n", get_count_str(skip_roads + 1));
5767     android_send_generic_text(1,xy);
5768     g_free(xy);
5769     xy=g_strdup_printf("+*#1:%s\n", dir);
5770     android_send_generic_text(1,xy);
5771     g_free(xy);
5772     #endif
5773 zoff99 28 #endif
5774 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);
5775     return2 ret;
5776 zoff99 27 }
5777     else
5778     {
5779     #ifdef HAVE_API_ANDROID
5780 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5781 zoff99 27 android_send_generic_text(1,"+*#O:after %i roads\n");
5782     gchar* xy=g_strdup_printf("+*#1:%i\n", skip_roads);
5783     android_send_generic_text(1,xy);
5784     g_free(xy);
5785     #endif
5786 zoff99 28 #endif
5787 zoff99 27 d = g_strdup_printf(_("after %i roads"), skip_roads);
5788     }
5789 zoff99 2
5790     }
5791 zoff99 27 else
5792     {
5793     d = g_strdup("");
5794 zoff99 2 }
5795 zoff99 27 break;
5796     default:
5797     #ifdef HAVE_API_ANDROID
5798 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5799 zoff99 27 android_send_generic_text(1,"+*#O:error\n");
5800     #endif
5801 zoff99 28 #endif
5802 zoff99 27 d = g_strdup(_("error"));
5803     }
5804 zoff99 2
5805 zoff99 41
5806    
5807 zoff99 27 if (cmd->itm->next)
5808     {
5809 zoff99 40 // dbg(0, "SPK:000a\n");
5810    
5811 zoff99 2 int tellstreetname = 0;
5812     char *destination = NULL;
5813 zoff99 27
5814     if (type == attr_navigation_speech)
5815 zoff99 41 {
5816 zoff99 27 if (level == 1)
5817 zoff99 41 {
5818     cmd->itm->streetname_told = 1;
5819 zoff99 2 tellstreetname = 1; // Ok so we tell the name of the street
5820     }
5821    
5822 zoff99 27 if (level == 0)
5823     {
5824     if (cmd->itm->streetname_told == 0) // we are right at the intersection
5825     {
5826     tellstreetname = 1;
5827     }
5828 zoff99 2 else
5829 zoff99 27 {
5830     cmd->itm->streetname_told = 0; // reset just in case we come to the same street again
5831     }
5832 zoff99 2 }
5833    
5834     }
5835     else
5836 zoff99 27 {
5837     tellstreetname = 1;
5838     }
5839 zoff99 2
5840 zoff99 27 if (global_speak_streetnames == 0)
5841     {
5842     // never speak streetnames (user config option)
5843     tellstreetname = 0;
5844     }
5845 zoff99 2
5846 zoff99 41
5847    
5848     if (override_tellstreetname != -1)
5849     {
5850    
5851 zoff99 40 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5852 zoff99 41 dbg(0, "SPK:level=%d street_dest_text=%p tellstreetname=%d\n", level, cmd->itm->way.street_dest_text, tellstreetname);
5853 zoff99 40 #endif
5854 zoff99 41 if (nav->tell_street_name && tellstreetname)
5855     {
5856     destination = navigation_item_destination(nav, cmd->itm, itm, " ");
5857 zoff99 40 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5858 zoff99 41 dbg(0, "SPK:levelX=%d dest=%s\n", level, destination);
5859 zoff99 40 #endif
5860 zoff99 41 }
5861     else if ((global_speak_streetnames == 1) && (cmd->itm->way.street_dest_text))
5862     {
5863     destination = navigation_item_destination(nav, cmd->itm, itm, " ");
5864 zoff99 40 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5865 zoff99 41 dbg(0, "SPK:levely=%d dest=%s d=%s\n", level, destination, cmd->itm->way.street_dest_text);
5866 zoff99 40 #endif
5867 zoff99 27
5868 zoff99 41 cmd->itm->streetname_told = 0;
5869     }
5870 zoff99 40 }
5871    
5872 zoff99 41
5873 zoff99 40 // dbg(0, "SPK:001\n");
5874    
5875 zoff99 27 if (level != -2)
5876     {
5877 zoff99 40
5878     //dbg(0, "SPK:002\n");
5879    
5880 zoff99 27 #ifdef HAVE_API_ANDROID
5881 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5882 zoff99 27 android_send_generic_text(1,"+*#O:Turn %1$s%2$s %3$s%4$s\n");
5883     gchar* xy=g_strdup_printf("+*#1:%s\n", strength);
5884     android_send_generic_text(1,xy);
5885     g_free(xy);
5886     xy=g_strdup_printf("+*#1:%s\n", dir);
5887     android_send_generic_text(1,xy);
5888     g_free(xy);
5889     xy=g_strdup_printf("+*#1:%s\n", d);
5890     android_send_generic_text(1,xy);
5891     g_free(xy);
5892     xy=g_strdup_printf("+*#1:%s\n", destination ? destination : "");
5893     android_send_generic_text(1,xy);
5894     g_free(xy);
5895     #endif
5896 zoff99 28 #endif
5897 zoff99 40
5898 zoff99 41 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)) // bicycle mode
5899 zoff99 40 {
5900     //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);
5901    
5902     if (level_now == 0)
5903     {
5904     if (against_oneway == 1)
5905     {
5906     if (delta < 8)
5907     {
5908     ret = g_strdup_printf("%s", _("oncoming traffic!")); // just say "attention oneway street!"
5909     }
5910     else
5911     {
5912     ret = g_strdup_printf("%s, %s", dir, _("oncoming traffic!")); // just say "left" or "right" at the turn + "attention oneway street!"
5913     }
5914     }
5915     else
5916     {
5917     ret = g_strdup(dir); // just say "left" or "right" at the turn
5918     }
5919     }
5920     else
5921     {
5922     if ((against_oneway == 1) && (delta < 8))
5923     {
5924     ret = g_strdup(""); // probably just going against a oneway street, but travelling straight on. dont say anything now
5925     }
5926     else
5927     {
5928     if (delta == 0)
5929     {
5930     // 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'
5931     ret = g_strdup_printf_4_str(_("%1$s%2$s %3$s%4$s"), "", dir, d, destination ? destination : "");
5932     }
5933     else
5934     {
5935     // 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'
5936     ret = g_strdup_printf_4_str(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
5937     }
5938     }
5939     }
5940     }
5941 zoff99 41 else // car mode
5942 zoff99 40 {
5943     if (delta == 0)
5944     {
5945     // 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'
5946     ret = g_strdup_printf_4_str(_("%1$s%2$s %3$s%4$s"), "", dir, d, destination ? destination : "");
5947     }
5948     else
5949     {
5950 zoff99 41 if (keep_dir != 0)
5951     {
5952     if (keep_dir == -1)
5953     {
5954     // TRANSLATORS: The argument is the distance. Example: 'keep left in 100 meters'
5955     ret = g_strdup_printf(_("keep left %s"), d);
5956 zoff99 46
5957     // dirty hack, so we don't need new translations
5958     char *ret2 = g_strdup_printf("%s%s", ret, destination ? destination : "");
5959     g_free(ret);
5960     ret = ret2;
5961     // ret2 = NULL;
5962 zoff99 41 }
5963     else
5964     {
5965     // TRANSLATORS: The argument is the distance. Example: 'keep right in 100 meters'
5966     ret = g_strdup_printf(_("keep right %s"), d);
5967 zoff99 46
5968     // dirty hack, so we don't need new translations
5969     char *ret2 = g_strdup_printf("%s%s", ret, destination ? destination : "");
5970     g_free(ret);
5971     ret = ret2;
5972     // ret2 = NULL;
5973 zoff99 41 }
5974     }
5975     else
5976     {
5977     // 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'
5978     ret = g_strdup_printf_4_str(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
5979     }
5980 zoff99 40 }
5981     }
5982 zoff99 27 }
5983 zoff99 41 else // (level == -2)
5984 zoff99 27 {
5985 zoff99 40
5986     //dbg(0, "SPK:007\n");
5987    
5988    
5989 zoff99 27 #ifdef HAVE_API_ANDROID
5990 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
5991 zoff99 27 android_send_generic_text(1,"+*#O:then turn %1$s%2$s %3$s%4$s\n");
5992     gchar* xy=g_strdup_printf("+*#1:%s\n", strength);
5993     android_send_generic_text(1,xy);
5994     g_free(xy);
5995     xy=g_strdup_printf("+*#1:%s\n", dir);
5996     android_send_generic_text(1,xy);
5997     g_free(xy);
5998     xy=g_strdup_printf("+*#1:%s\n", d);
5999     android_send_generic_text(1,xy);
6000     g_free(xy);
6001     xy=g_strdup_printf("+*#1:%s\n", destination ? destination : "");
6002     android_send_generic_text(1,xy);
6003     g_free(xy);
6004     #endif
6005 zoff99 28 #endif
6006 zoff99 41 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)) // bicycle mode
6007 zoff99 40 {
6008     if ((against_oneway == 1) && (delta < 8))
6009     {
6010     ret = g_strdup(""); // probably just going against a oneway street, but travelling straight on. dont say anything now
6011     }
6012     else
6013     {
6014     if (delta == 0)
6015     {
6016     // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
6017     ret = g_strdup_printf_4_str(_("then %1$s%2$s %3$s%4$s"), "", dir, d, destination ? destination : "");
6018     }
6019     else
6020     {
6021     // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
6022     ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
6023     }
6024     }
6025     }
6026 zoff99 41 else // car mode
6027 zoff99 40 {
6028     if (delta == 0)
6029     {
6030     // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
6031     ret = g_strdup_printf_4_str(_("then %1$s%2$s %3$s%4$s"), "", dir, d, destination ? destination : "");
6032     }
6033     else
6034     {
6035 zoff99 41 if (keep_dir != 0)
6036     {
6037     if (keep_dir == -1)
6038     {
6039     ret = g_strdup_printf("%s", _("then keep left"));
6040     }
6041     else
6042     {
6043     ret = g_strdup_printf("%s", _("then keep right"));
6044     }
6045     }
6046     else
6047     {
6048     // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
6049     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!
6050     // ret = g_strdup_printf_4_str(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : "");
6051     }
6052 zoff99 40 }
6053     }
6054 zoff99 27 }
6055 zoff99 2 g_free(destination);
6056 zoff99 27 }
6057     else
6058     {
6059     if (!connect)
6060     {
6061     #ifdef HAVE_API_ANDROID
6062 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
6063 zoff99 27 android_send_generic_text(1,"+*#O:You have reached your destination %s\n");
6064     gchar* xy=g_strdup_printf("+*#1:%s\n", d);
6065     android_send_generic_text(1,xy);
6066     g_free(xy);
6067     #endif
6068 zoff99 28 #endif
6069 zoff99 27 // TRANSLATORS: EXAMPLE: You have reached your destination in 300 meters
6070     ret = g_strdup_printf(_("You have reached your destination %s"), d);
6071 zoff99 2 }
6072 zoff99 27 else
6073     {
6074     #ifdef HAVE_API_ANDROID
6075 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
6076 zoff99 27 android_send_generic_text(1,"+*#O:then you have reached your destination.\n");
6077     #endif
6078 zoff99 28 #endif
6079 zoff99 40 ret = g_strdup(_("then you have reached your destination."));
6080 zoff99 27 }
6081 zoff99 2 }
6082     g_free(d);
6083 zoff99 40
6084     return2 ret;
6085    
6086     __F_END__
6087 zoff99 2 }
6088    
6089 zoff99 41
6090    
6091     static char *
6092     show_maneuver(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type, int connect)
6093     {
6094     return show_maneuver_at_level(nav, itm, cmd, type, connect, DONT_KNOW_LEVEL, 0);
6095     }
6096    
6097    
6098    
6099    
6100 zoff99 2 /**
6101     * @brief Creates announcements for maneuvers, plus maneuvers immediately following the next maneuver
6102     *
6103     * This function does create an announcement for the current maneuver and for maneuvers
6104     * immediately following that maneuver, if these are too close and we're in speech navigation.
6105     *
6106     * @return An announcement that should be made
6107     */
6108 zoff99 40 // central entry point for TTS maneuvers --------------
6109     // central entry point for TTS maneuvers --------------
6110     // central entry point for TTS maneuvers --------------
6111 zoff99 2 static char *
6112 zoff99 30 show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type)
6113 zoff99 2 {
6114 zoff99 40 __F_START__
6115    
6116 zoff99 27 struct navigation_command *cur, *prev;
6117     int distance = itm->dest_length - cmd->itm->dest_length;
6118 zoff99 40 int level, dist, i, time, level2;
6119 zoff99 27 int speech_time, time2nav;
6120     char *ret, *old, *buf, *next;
6121 zoff99 41 char *ret22;
6122 zoff99 2
6123 zoff99 40 char *temp_txt = NULL;
6124    
6125    
6126     //dbg(0, "Enter\n");
6127    
6128 zoff99 27 if (type != attr_navigation_speech)
6129     {
6130 zoff99 41 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6131     {
6132     return2 show_maneuver_bicycle(nav, itm, cmd, type, 0, DONT_KNOW_LEVEL); // not for speech, so just return the real values
6133     }
6134     else
6135     {
6136     return2 show_maneuver(nav, itm, cmd, type, 0); // not for speech, so just return the real values
6137     }
6138 zoff99 2 }
6139    
6140    
6141 zoff99 41 int cur_vehicle_speed = 0;
6142     if ((global_navit) && (global_navit->vehicle))
6143     {
6144     cur_vehicle_speed = global_navit->vehicle->speed; // in km/h
6145     }
6146    
6147    
6148     dbg(0, "SPEECH:[-0v-] current speed=%d\n", cur_vehicle_speed);
6149    
6150    
6151     // -- bicycle mode START -------------------------------------
6152     // -- bicycle mode START -------------------------------------
6153     // -- bicycle mode START -------------------------------------
6154 zoff99 40 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6155 zoff99 27 {
6156 zoff99 41 level = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length, 0);
6157 zoff99 2
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     //dbg(0, "(nn)distance=%d cmd->length=%d (minus)=%d\n", distance, cmd->length, (distance - cmd->length));
6162 zoff99 2
6163 zoff99 40 // in bike mode level should only be "0" or "1" or "3" !
6164 zoff99 2
6165 zoff99 40 if (level > 2)
6166     {
6167     //dbg(0, "just say the current command\n");
6168     return2 show_maneuver_bicycle(nav, itm, cmd, type, 0, level); // just say the current command
6169 zoff99 2 }
6170 zoff99 27
6171 zoff99 40 if (cmd->itm->told)
6172 zoff99 27 {
6173 zoff99 40 // current command should not be spoken again!
6174     //dbg(0, "current command should not be spoken again\n");
6175     return2 g_strdup("");
6176 zoff99 27 }
6177 zoff99 40
6178    
6179     //dbg(0, "xx 017a fsp, itm->told=%d l=%d\n", cmd->itm->told, level);
6180     if (level == 0)
6181 zoff99 27 {
6182 zoff99 40 // this command is spoken (now)
6183     //dbg(0, "this command is spoken (now)\n");
6184     cmd->itm->told = 1;
6185 zoff99 27 }
6186 zoff99 40 //dbg(0, "xx 017b fsp, itm->told=%d\n", cmd->itm->told);
6187 zoff99 2
6188 zoff99 40
6189     // current maneuver -------
6190     ret = show_maneuver_bicycle(nav, itm, cmd, type, 0, level); // generate TTS text for current command
6191     //dbg(0, "ret cmd=%s\n", ret);
6192     time2nav = navigation_time(itm, cmd->itm->prev);
6193     //dbg(0, "time2nav = %d\n", time2nav);
6194     old = NULL;
6195     // current maneuver -------
6196    
6197     cur = cmd->next;
6198     prev = cmd;
6199    
6200     if (cur && cur->itm) // we have a next command
6201     {
6202     dist = prev->itm->dest_length - cur->itm->dest_length;
6203 zoff99 41 level2 = navigation_get_announce_level(nav, itm->next->way.item.type, dist, 0);
6204 zoff99 40 //dbg(0, "(next)level2 = %d\n", level2);
6205     //dbg(0, "(next)dist=%d\n", dist);
6206    
6207     if ((level2 < 2) && (dist < (2 * level_static_for_bicycle[0])))
6208     {
6209     //dbg(0, "link next command, and dont say it again!\n");
6210     old = ret;
6211     buf = show_maneuver_bicycle(nav, prev->itm, cur, type, 1, 0); // generate TTS text for next command, and dont say the next command again!
6212     //dbg(0, "next cmd=%s\n", next);
6213     ret = g_strdup_printf("%s, %s", old, buf);
6214     //dbg(0, "next cmd concat=%s\n", ret);
6215     g_free(buf);
6216     g_free(old);
6217     if (level == 0)
6218     {
6219     // dont say this next command again!
6220     cur->itm->told = 1;
6221     }
6222     }
6223 zoff99 2 }
6224 zoff99 40 }
6225 zoff99 41 // -- bicycle mode END -------------------------------------
6226     // -- bicycle mode END -------------------------------------
6227     // -- bicycle mode END -------------------------------------
6228 zoff99 40 else
6229     {
6230 zoff99 2
6231    
6232 zoff99 40
6233     // -------------------------------------------------
6234     // -------------------------------------------------
6235     // -- ******************************************* --
6236 zoff99 41 // CAR MODE
6237 zoff99 40 // -- ******************************************* --
6238     // -------------------------------------------------
6239     // -------------------------------------------------
6240    
6241 zoff99 41 level = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length, ((float)cur_vehicle_speed / 3.6f));
6242 zoff99 40 //dbg(0, "level = %d\n", level);
6243     //dbg(0, "(nn)itm->way.flags=%x\n", itm->way.flags);
6244     //dbg(0, "(nn)itm->next->way.flags=%x\n", itm->next->way.flags);
6245    
6246     long temp_ts = -1;
6247     debug_get_timestamp_millis(&temp_ts);
6248     if (global_last_spoken == -1)
6249     {
6250     temp_ts = 99999999;
6251 zoff99 2 }
6252    
6253 zoff99 41 int time2nav_2 = navigation_time_real_speed(itm, cmd->itm->prev, cur_vehicle_speed);
6254 zoff99 27
6255 zoff99 40 dbg(0, "SPEECH:[-00-] last spoken ago=%f\n", (float)((temp_ts - global_last_spoken) / 1000.0f));
6256     dbg(0, "SPEECH:[-01-] meters to next maneuver=%d\n", (distance - cmd->length));
6257     dbg(0, "SPEECH:[-02-] level=%d\n", level);
6258    
6259     #ifdef HAVE_API_ANDROID
6260     temp_txt = g_strdup_printf("SPEECH:[-00-] last spoken ago=%f\n", (float)((temp_ts - global_last_spoken) / 1000.0f));
6261     android_send_generic_text(20, temp_txt);
6262     g_free(temp_txt);
6263    
6264     temp_txt = g_strdup_printf("SPEECH:[-01-] meters to next maneuver=%d\n", (distance - cmd->length));
6265     android_send_generic_text(20, temp_txt);
6266     g_free(temp_txt);
6267    
6268     temp_txt = g_strdup_printf("SPEECH:[-02-] level=%d\n", level);
6269     android_send_generic_text(20, temp_txt);
6270     g_free(temp_txt);
6271     #endif
6272    
6273     dbg(0, "SPEECH:[-03-] time2nav secs=%f\n", ((float)time2nav_2 / 10.0f));
6274 zoff99 41
6275     int dist_to_next_spoken_command = -1;
6276     float secs_to_next_spoken_command = -1;
6277     if (level > 0)
6278     {
6279     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) ) );
6280    
6281     if (cur_vehicle_speed > 0)
6282     {
6283     secs_to_next_spoken_command = ((float)dist_to_next_spoken_command / ((float)cur_vehicle_speed / 3.6f));
6284     }
6285     else
6286     {
6287     secs_to_next_spoken_command = ((float)dist_to_next_spoken_command / ((float)itm->speed / 3.6f));
6288     }
6289     }
6290    
6291    
6292     // current maneuver -------
6293     ret22 = show_maneuver_at_level(nav, itm, cmd, type, 0, level, 0);
6294     // current maneuver -------
6295    
6296     if (nav->speech)
6297     {
6298     speech_time = speech_estimate_duration(nav->speech, ret22);
6299     dbg(0, "SPEECH:[-CUR-] secs=%f text=%s\n", ((float)speech_time)/10.0f, ret22);
6300     }
6301     else
6302     {
6303     speech_time = -1;
6304     dbg(0, "SPEECH:[-CUR-] secs=-1 text=%s\n", ret22);
6305     }
6306    
6307    
6308     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);
6309    
6310     if (level == 3)
6311     {
6312 zoff99 47
6313     // ===========----------- LEVEL 3 -----------===========
6314    
6315 zoff99 41 #if 0
6316     if (((float)((temp_ts - global_last_spoken) / 1000.0f)) < 3.0f)
6317     {
6318     dbg(0, "SPEECH:[-NOOP-] 004: already spoken in the last 3 secs.\n");
6319     return2 g_strdup(""); // dont speak this command now!
6320     }
6321     #endif
6322    
6323 zoff99 47 if (secs_to_next_spoken_command < 7 )
6324 zoff99 41 {
6325     if (ret22)
6326     {
6327     g_free(ret22);
6328     ret22 = NULL;
6329     }
6330 zoff99 47
6331     #ifdef _DEBUG_BUILD_
6332     // speak debug ----
6333     navit_say(global_navit, "level 3a wieder in 7 sekunden");
6334     // speak debug ----
6335     #endif
6336    
6337     dbg(0, "SPEECH:[-NOOP-] 006b: want to speak again in less than %d secs. level=%d\n", 7, level);
6338 zoff99 41 return2 g_strdup(""); // dont speak this command now!
6339     }
6340    
6341     if (secs_to_next_spoken_command < (((float)speech_time/10.0f) + 3) )
6342     {
6343     if (ret22)
6344     {
6345     g_free(ret22);
6346     ret22 = NULL;
6347     }
6348 zoff99 47
6349     #ifdef _DEBUG_BUILD_
6350     // speak debug ----
6351     temp_txt = g_strdup_printf("level 3b wieder in %d sekunden", (int)(((float)speech_time/10.0f) + 3));
6352     navit_say(global_navit, temp_txt);
6353     g_free(temp_txt);
6354     // speak debug ----
6355     #endif
6356    
6357 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 );
6358     return2 g_strdup(""); // dont speak this command now!
6359     }
6360 zoff99 47 // ===========----------- LEVEL 3 -----------===========
6361    
6362    
6363 zoff99 41 }
6364     else if (level == 2)
6365     {
6366 zoff99 47
6367     // ===========----------- LEVEL 2 -----------===========
6368    
6369    
6370     #if 0
6371     if (secs_to_next_spoken_command < 3 )
6372 zoff99 41 {
6373     if (ret22)
6374     {
6375     g_free(ret22);
6376     ret22 = NULL;
6377     }
6378 zoff99 47
6379     #ifdef _DEBUG_BUILD_
6380     // speak debug ----
6381     navit_say(global_navit, "level 2a wieder in 3 sekunden");
6382     // speak debug ----
6383     #endif
6384    
6385     dbg(0, "SPEECH:[-NOOP-] 007b: want to speak again in less than %d secs. level=%d\n", 3, level);
6386 zoff99 41 return2 g_strdup(""); // dont speak this command now!
6387     }
6388 zoff99 47 #endif
6389 zoff99 41
6390     #if 1
6391     if (secs_to_next_spoken_command < (((float)speech_time/10.0f) + 1) )
6392     {
6393     if (ret22)
6394     {
6395     g_free(ret22);
6396     ret22 = NULL;
6397     }
6398 zoff99 47
6399     #ifdef _DEBUG_BUILD_
6400     // speak debug ----
6401     temp_txt = g_strdup_printf("level 2b wieder in %d sekunden", (int)(((float)speech_time/10.0f) + 1));
6402     navit_say(global_navit, temp_txt);
6403     // speak debug ----
6404     #endif
6405    
6406     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);
6407 zoff99 41 return2 g_strdup(""); // dont speak this command now!
6408     }
6409     #endif
6410    
6411 zoff99 47 #if 0
6412 zoff99 41 if (((float)((temp_ts - global_last_spoken) / 1000.0f)) < 5.0f)
6413     {
6414     if (ret22)
6415     {
6416     g_free(ret22);
6417     ret22 = NULL;
6418     }
6419    
6420 zoff99 47 #ifdef _DEBUG_BUILD_
6421     // speak debug ----
6422     navit_say(global_navit, "level 2c schon vor 5 sekunden");
6423     // speak debug ----
6424     #endif
6425    
6426 zoff99 41 dbg(0, "SPEECH:[-NOOP-] 005: already spoken in the last 5 secs. level=%d\n", level);
6427     return2 g_strdup(""); // dont speak this command now!
6428     }
6429 zoff99 47 #endif
6430    
6431     // ===========----------- LEVEL 2 -----------===========
6432    
6433    
6434 zoff99 41 }
6435     else if (level == 1)
6436     {
6437 zoff99 47
6438     // ===========----------- LEVEL 1 -----------===========
6439    
6440    
6441 zoff99 41 #if 0
6442     if (((float)time2nav_2 / 10.0f) < 5.0f)
6443     {
6444     dbg(0, "SPEECH:[-NOOP-] 001: less than 5 secs. to maneuver\n");
6445     return2 g_strdup(""); // dont speak this command now!
6446     }
6447     #endif
6448    
6449     #if 0
6450     if ((distance - cmd->length) < 50)
6451     {
6452     dbg(0, "SPEECH:[-NOOP-] 003: less than 50 meters to maneuver\n");
6453     return2 g_strdup(""); // dont speak this command now!
6454     }
6455     #endif
6456    
6457    
6458     if (dist_to_next_spoken_command < 18)
6459     {
6460     if (ret22)
6461     {
6462     g_free(ret22);
6463     ret22 = NULL;
6464     }
6465    
6466 zoff99 47 #ifdef _DEBUG_BUILD_
6467     // speak debug ----
6468     temp_txt = g_strdup_printf("level 1a wieder in %d sekunden", 18);
6469     navit_say(global_navit, temp_txt);
6470     g_free(temp_txt);
6471     // speak debug ----
6472     #endif
6473    
6474    
6475 zoff99 41 dbg(0, "SPEECH:[-NOOP-] 011: less than 18 meters to next announcement\n");
6476     return2 g_strdup(""); // dont speak this command now!
6477     }
6478    
6479 zoff99 47 #if 0
6480 zoff99 41 if (((float)((temp_ts - global_last_spoken) / 1000.0f)) < 4.0f)
6481     {
6482     if (ret22)
6483     {
6484     g_free(ret22);
6485     ret22 = NULL;
6486     }
6487    
6488     dbg(0, "SPEECH:[-NOOP-] 002: already spoken in the last 4 secs. level=%d\n", level);
6489     return2 g_strdup(""); // dont speak this command now!
6490     }
6491 zoff99 47 #endif
6492 zoff99 41
6493     if (secs_to_next_spoken_command < (((float)speech_time/10.0f) + 1) )
6494     {
6495     if (secs_to_next_spoken_command < 3.0f)
6496     {
6497     if (ret22)
6498     {
6499     g_free(ret22);
6500     ret22 = NULL;
6501     }
6502    
6503 zoff99 47 #ifdef _DEBUG_BUILD_
6504     // speak debug ----
6505     temp_txt = g_strdup_printf("level 1b wieder in %d sekunden", 3);
6506     navit_say(global_navit, temp_txt);
6507     g_free(temp_txt);
6508     // speak debug ----
6509     #endif
6510    
6511    
6512 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);
6513     return2 g_strdup(""); // dont speak this command now!
6514     }
6515     else
6516     {
6517     // if we have at least 3 seconds left, still say level 1 announcement (without the streetname/destination name)
6518     dbg(0, "SPEECH:[-NOOP-] 008lo: use level=%d announcement without destination name\n", level);
6519     if (ret22)
6520     {
6521     g_free(ret22);
6522     ret22 = NULL;
6523     }
6524     ret22 = show_maneuver_at_level(nav, itm, cmd, type, 0, level, -1);
6525     if (nav->speech)
6526     {
6527     speech_time = speech_estimate_duration(nav->speech, ret22);
6528     dbg(0, "SPEECH:[-CUR-] :lo: secs=%f text=%s\n", ((float)speech_time)/10.0f, ret22);
6529     }
6530     else
6531     {
6532     speech_time = -1;
6533     dbg(0, "SPEECH:[-CUR-] :lo: secs=-1 text=%s\n", next);
6534     }
6535    
6536     if (secs_to_next_spoken_command < (((float)speech_time/10.0f) + 0) )
6537     {
6538     if (ret22)
6539     {
6540     g_free(ret22);
6541     ret22 = NULL;
6542     }
6543    
6544 zoff99 47 #ifdef _DEBUG_BUILD_
6545     // speak debug ----
6546     temp_txt = g_strdup_printf("level 1c wieder in %d sekunden", (int)(((float)speech_time/10.0f) + 0));
6547     navit_say(global_navit, temp_txt);
6548     g_free(temp_txt);
6549     // speak debug ----
6550     #endif
6551    
6552    
6553 zoff99 41 dbg(0, "SPEECH:[-NOOP-] 008loEE: giving up on this announcement\n");
6554     return2 g_strdup(""); // dont speak this command now!
6555     }
6556     }
6557     }
6558 zoff99 47
6559     // ===========----------- LEVEL 1 -----------===========
6560    
6561 zoff99 41 }
6562    
6563    
6564    
6565 zoff99 47
6566    
6567    
6568 zoff99 40 #ifdef HAVE_API_ANDROID
6569     temp_txt = g_strdup_printf("SPEECH:[-03-] time2nav secs=%f\n", ((float)time2nav_2 / 10.0f));
6570     android_send_generic_text(20, temp_txt);
6571     g_free(temp_txt);
6572     #endif
6573    
6574     if (level > 1)
6575 zoff99 27 {
6576 zoff99 40 dbg(0, "SPEECH:[-R1-]\n");
6577 zoff99 47 return2 ret22; // We accumulate maneuvers only if they are close (level-0 and level-1)
6578 zoff99 27 }
6579 zoff99 40
6580     if (cmd->itm->told)
6581 zoff99 27 {
6582 zoff99 40 #ifdef HAVE_API_ANDROID
6583     #ifdef NAVIT_SAY_DEBUG_PRINT
6584     android_send_generic_text(1,"+*#C1:*CANCEL*\n");
6585     #endif
6586     #endif
6587     dbg(0, "SPEECH:[-R2-]\n");
6588     #ifdef HAVE_API_ANDROID
6589     temp_txt = g_strdup("SPEECH:[-R2-]\n");
6590     android_send_generic_text(20, temp_txt);
6591     g_free(temp_txt);
6592     #endif
6593 zoff99 41 if (ret22)
6594     {
6595     g_free(ret22);
6596     ret22 = NULL;
6597     }
6598 zoff99 40
6599 zoff99 41
6600 zoff99 40 return2 g_strdup("");
6601 zoff99 2 }
6602    
6603 zoff99 41
6604 zoff99 40 // current maneuver -------
6605 zoff99 41 ret = ret22;
6606     time2nav = navigation_time_real_speed(itm, cmd->itm->prev, cur_vehicle_speed);
6607     // current maneuver -------
6608    
6609    
6610     #if 0
6611     if (nav->speech)
6612     {
6613     speech_time = speech_estimate_duration(nav->speech, ret);
6614     dbg(0, "SPEECH:[-CUR-] secs=%f text=%s\n", ((float)speech_time)/10.0f, ret);
6615     }
6616     else
6617     {
6618     speech_time = -1;
6619     dbg(0, "SPEECH:[-CUR-] secs=-1 text=%s\n", next);
6620     }
6621     #endif
6622    
6623    
6624 zoff99 40 old = NULL;
6625    
6626     dbg(0, "SPEECH:[-04-] time2nav secs=%f\n", ((float)time2nav / 10.0f));
6627     #ifdef HAVE_API_ANDROID
6628     temp_txt = g_strdup_printf("SPEECH:[-04-] time2nav secs=%f\n", ((float)time2nav / 10.0f));
6629     android_send_generic_text(20, temp_txt);
6630     g_free(temp_txt);
6631     #endif
6632    
6633    
6634 zoff99 41
6635    
6636     // next maneuver -------
6637 zoff99 40 cur = cmd->next;
6638     prev = cmd;
6639 zoff99 41 // next maneuver -------
6640 zoff99 40
6641 zoff99 41
6642 zoff99 40 i = 0;
6643     int max_announcements = 3;
6644     if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6645 zoff99 27 {
6646 zoff99 40 max_announcements = 2;
6647     }
6648    
6649 zoff99 41 while (cur && cur->itm) // only accumulate at "level 0" or "level 1"
6650 zoff99 40 {
6651     // We don't merge more than "max_announcements" announcements...
6652     if (i > (max_announcements - 2))
6653     {
6654     break;
6655     }
6656    
6657 zoff99 41 dist = prev->itm->dest_length - cur->itm->dest_length; // distance between next 2 maneuvers in meters
6658    
6659     if (dist > 420) // too far apart, bail out
6660     {
6661     break;
6662     }
6663    
6664 zoff99 40 next = show_maneuver(nav, prev->itm, cur, type, 0);
6665     if (nav->speech)
6666     {
6667     speech_time = speech_estimate_duration(nav->speech, next);
6668 zoff99 41 dbg(0, "SPEECH:[-NXT-] secs=%f text=%s\n", ((float)speech_time)/10.0f, next);
6669 zoff99 40 }
6670     else
6671     {
6672     speech_time = -1;
6673 zoff99 41 dbg(0, "SPEECH:[-NXT-] secs=-1 text=%s\n", next);
6674 zoff99 40 }
6675     g_free(next);
6676    
6677     if (speech_time == -1)
6678     {
6679     // user didn't set cps
6680 zoff99 41 speech_time = 25; // assume 2.5 seconds
6681     dbg(0, "SPEECH:[-NXT-](2) secs=%f\n", ((float)speech_time)/10.0f);
6682 zoff99 40 }
6683    
6684 zoff99 41 //if (cur_vehicle_speed > 0)
6685     //{
6686     // time = ((float)dist / ((float)cur_vehicle_speed / 3.6f)) * 10;
6687     //}
6688     //else
6689     //{
6690     // time = navigation_time_real_speed(prev->itm, cur->itm->prev, cur_vehicle_speed);
6691 zoff99 40 time = navigation_time(prev->itm, cur->itm->prev);
6692 zoff99 41 //}
6693    
6694     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);
6695 zoff99 27 #ifdef HAVE_API_ANDROID
6696 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);
6697     android_send_generic_text(20, temp_txt);
6698     g_free(temp_txt);
6699     #endif
6700    
6701    
6702     if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6703     {
6704 zoff99 41 // !! should never get here !!
6705 zoff99 40 }
6706     else
6707     {
6708 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);
6709    
6710     if (i == 0)
6711     {
6712     if (dist < 170) // distance between maneuvers less than 170m --> always merge maneuvers
6713     {
6714     }
6715     else
6716     {
6717     // **OLD** // if (time >= (speech_time + 35)) // (time to turn) >= (time to speak command + 3.5 secs.)
6718 zoff99 47 if (time > ((global_level1_announcement * 10.0f) - 3) ) // more than "global_level1_announcement" seconds to next maneuver -> don't merge it
6719 zoff99 41 {
6720     dbg(0, "SPEECH:*break first*\n");
6721     break;
6722     }
6723     }
6724 zoff99 40 }
6725 zoff99 41 else
6726     {
6727 zoff99 47 if (time > (global_level0_announcement * 10.0f)) // more than "global_level0_announcement" seconds to next maneuver -> don't merge it
6728 zoff99 41 {
6729     dbg(0, "SPEECH:*break next*\n");
6730     break;
6731     }
6732     }
6733 zoff99 40 }
6734    
6735     old = ret;
6736     buf = show_maneuver(nav, prev->itm, cur, type, 1);
6737     ret = g_strdup_printf("%s, %s", old, buf);
6738     g_free(buf);
6739    
6740     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);
6741 zoff99 41 // if (nav->speech && speech_estimate_duration(nav->speech, ret) > time2nav)
6742     // {
6743     // g_free(ret);
6744     // ret = old;
6745     // i = (max_announcements - 1); // This will terminate the loop
6746     // dbg(0, "SPEECH:*terminate loop*\n");
6747     // }
6748     // else
6749     // {
6750 zoff99 40 g_free(old);
6751 zoff99 41 // }
6752 zoff99 40
6753    
6754     if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6755     {
6756 zoff99 41 // !! should never get here !!
6757 zoff99 40 }
6758     else
6759     {
6760 zoff99 41 #if 0
6761 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);
6762     // If the two maneuvers are *really* close, we shouldn't tell the second one again, because TTS won't be fast enough
6763     if (time <= speech_time)
6764     {
6765     #ifdef HAVE_API_ANDROID
6766 zoff99 28 #ifdef NAVIT_SAY_DEBUG_PRINT
6767 zoff99 40 android_send_generic_text(1,"+*#C2:*CANCEL*\n");
6768 zoff99 27 #endif
6769 zoff99 28 #endif
6770 zoff99 40 //dbg(0, "cancel speak:%s\n", ret);
6771     cur->itm->told = 1;
6772     }
6773 zoff99 41 #endif
6774 zoff99 40 }
6775    
6776     prev = cur;
6777     cur = cur->next;
6778     i++;
6779 zoff99 2 }
6780    
6781 zoff99 40 // -------------------------------------------------
6782     // -------------------------------------------------
6783     // -- ******************************************* --
6784 zoff99 41 // CAR MODE
6785 zoff99 40 // -- ******************************************* --
6786     // -------------------------------------------------
6787     // -------------------------------------------------
6788    
6789 zoff99 2 }
6790    
6791 zoff99 40 dbg(0, "SPEECH:[-Re-]\n");
6792     #ifdef HAVE_API_ANDROID
6793     temp_txt = g_strdup("SPEECH:[-Re-]\n");
6794     android_send_generic_text(20, temp_txt);
6795     g_free(temp_txt);
6796     #endif
6797    
6798     return2 ret;
6799    
6800     __F_END__
6801 zoff99 2 }
6802 zoff99 40 // central entry point for TTS maneuvers --------------
6803     // central entry point for TTS maneuvers --------------
6804     // central entry point for TTS maneuvers --------------
6805 zoff99 2
6806 zoff99 40
6807    
6808     // ----- global var, BAD!! -------
6809     int global_spoke_last_position_update = 0;
6810 zoff99 41 int previous_dest_length = -1;
6811     int previous_dest_length_save = -1;
6812     struct navigation_command *last_first_cmd_save = NULL;
6813     int global_turn_around_spoken = 0;
6814 zoff99 40 // ----- global var, BAD!! -------
6815    
6816 zoff99 30 static void navigation_call_callbacks(struct navigation *this_, int force_speech)
6817 zoff99 2 {
6818 zoff99 40 __F_START__
6819    
6820 zoff99 2 int distance, level = 0;
6821 zoff99 40 int level_cur;
6822     int distance_orig;
6823 zoff99 27 void *p = this_;
6824 zoff99 41 int dont_speak_yet = 0;
6825     int level_last_save = 99;
6826 zoff99 30
6827 zoff99 2 if (!this_->cmd_first)
6828 zoff99 30 {
6829 zoff99 40 //dbg(0, "ret 0001\n");
6830     global_spoke_last_position_update = 0;
6831     return2;
6832 zoff99 30 }
6833    
6834 zoff99 41 // EMPTY: calls nothing!!
6835     // ****** // callback_list_call(this_->callback, 1, &p);
6836 zoff99 40
6837     //if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
6838     //{
6839     // force_speech = 7;
6840     //}
6841    
6842     //dbg(0, "force_speech=%d turn_around=%d turn_around_limit=%d\n", force_speech, this_->turn_around, this_->turn_around_limit);
6843    
6844     distance = this_->first->dest_length - this_->cmd_first->itm->dest_length;
6845     //dbg(0, "fdl=%d cmdidl=%d\n", this_->first->dest_length, this_->cmd_first->itm->dest_length);
6846     distance_orig = distance;
6847     distance = round_distance(distance);
6848 zoff99 41
6849     int cur_vehicle_speed = 0;
6850     if ((global_navit) && (global_navit->vehicle))
6851     {
6852     cur_vehicle_speed = global_navit->vehicle->speed;
6853     }
6854    
6855     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);
6856    
6857    
6858 zoff99 30 if (this_->turn_around_limit && this_->turn_around == this_->turn_around_limit)
6859 zoff99 27 {
6860 zoff99 41
6861     dbg(0, "NAV_TURNAROUND:005 ta=%d talimit=%d\n", this_->turn_around, this_->turn_around_limit);
6862    
6863 zoff99 40 //dbg(0, "xx 001 d=%d rd=%d dt=%d\n", distance_orig, distance_orig, this_->distance_turn);
6864 zoff99 41 #if 0
6865 zoff99 27 while (distance > this_->distance_turn)
6866     {
6867     this_->level_last = 4;
6868     level = 4;
6869     force_speech = 2;
6870 zoff99 40
6871 zoff99 2 if (this_->distance_turn >= 500)
6872 zoff99 40 {
6873 zoff99 27 this_->distance_turn *= 2;
6874 zoff99 40 }
6875 zoff99 2 else
6876 zoff99 40 {
6877 zoff99 27 this_->distance_turn = 500;
6878 zoff99 40 }
6879 zoff99 41 #endif
6880 zoff99 40
6881 zoff99 41 // we need to force a maneuver for "turn around" ------------------
6882     this_->level_last = 4;
6883     level = 4;
6884     force_speech = 2;
6885     // this_->distance_turn *= 100;
6886    
6887     #if 1
6888     global_driven_away_from_route = 0;
6889     global_spoke_last_position_update = 0;
6890     global_last_spoken = -1;
6891     previous_dest_length = -1;
6892     previous_dest_length_save = -1;
6893     last_first_cmd_save = NULL;
6894     #endif
6895    
6896     this_->level_last = 99;
6897    
6898    
6899     this_->level_last = level;
6900     this_->curr_delay = 0;
6901    
6902     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);
6903     dbg(0, "NCC_:========= END ==========\n");
6904    
6905     global_spoke_last_position_update = 1;
6906    
6907     // ----------------------------------
6908     // ----------------------------------
6909     // calls -> calls navit_speak
6910     //
6911     callback_list_call(this_->callback_speech, 1, &p);
6912     // ----------------------------------
6913     // ----------------------------------
6914    
6915    
6916     return2;
6917    
6918     // we need to force a maneuver for "turn around" ------------------
6919    
6920     #if 0
6921     dbg(0, "NCC_:loop 001 d=%d dt=%d force_speech=%d\n", distance, this_->distance_turn, force_speech);
6922 zoff99 2 }
6923 zoff99 41 #endif
6924    
6925 zoff99 27 }
6926 zoff99 41 else if (!this_->turn_around_limit || this_->turn_around != this_->turn_around_limit)
6927 zoff99 27 {
6928     this_->distance_turn = 50;
6929 zoff99 40
6930 zoff99 41 global_turn_around_spoken = 0; // reset turn around speak flag
6931    
6932 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);
6933     //dbg(0, "xx 002a d=%d d2=%d diff=%d\n", distance, (distance - this_->cmd_first->length), (this_->cmd_first->itm->length - distance_orig));
6934    
6935     //dbg(0, "xx 002a ll001=%d\n", (this_->cmd_first->itm->prev->dest_length - this_->cmd_first->itm->dest_length));
6936    
6937 zoff99 27 distance -= this_->cmd_first->length;
6938 zoff99 40
6939 zoff99 41
6940     level = navigation_get_announce_level_cmd(this_, this_->first, this_->cmd_first, distance_orig, ((float)cur_vehicle_speed / 3.6f) );
6941     level_cur = navigation_get_announce_level(this_, this_->first->way.item.type, distance_orig, ((float)cur_vehicle_speed / 3.6f));
6942    
6943    
6944    
6945     if (last_first_cmd_save != this_->cmd_first)
6946     {
6947     last_first_cmd_save = this_->cmd_first;
6948     previous_dest_length = previous_dest_length_save;
6949     }
6950     previous_dest_length_save = this_->cmd_first->itm->dest_length;
6951     // level_last_save = this_->level_last;
6952    
6953     //dbg(0, "NCC_:\n");
6954     //dbg(0, "NCC_:0---passed item?---\n");
6955     // 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);
6956    
6957     #if 1
6958     if (previous_dest_length == -1)
6959     {
6960     dbg(0, "NCC_:no prev nav command\n");
6961     }
6962     else
6963     {
6964     if (distance_orig > 40)
6965     {
6966     if ((distance_orig + 25) >= (previous_dest_length - this_->cmd_first->itm->dest_length))
6967     {
6968     // we are still within 25 meters of the previous navigation command item
6969     dont_speak_yet = 1;
6970     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));
6971     }
6972     }
6973     #if 1
6974     else if (distance_orig > 20)
6975     {
6976     if ((distance_orig) > (previous_dest_length - this_->cmd_first->itm->dest_length))
6977     {
6978     // we are still at the position of the previous navigation command item
6979     dont_speak_yet = 1;
6980     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));
6981     }
6982     }
6983     #endif
6984     }
6985     #endif
6986    
6987     //dbg(0, "NCC_:1---passed item?---\n");
6988     //dbg(0, "NCC_:\n");
6989    
6990    
6991    
6992    
6993 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);
6994    
6995 zoff99 27 if (level < this_->level_last)
6996     {
6997 zoff99 2 /* only tell if the level is valid for more than 3 seconds */
6998 zoff99 27 int speed_distance = this_->first->speed * 30 / 36;
6999 zoff99 40
7000 zoff99 41 dbg(0, "NCC_:speed_distance=%d\n", speed_distance);
7001    
7002    
7003 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);
7004    
7005     if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2))
7006 zoff99 27 {
7007 zoff99 40
7008     level = level_cur;
7009    
7010     if ((level_cur > 0) && (global_spoke_last_position_update > 0))
7011     {
7012     // skip this time, speak command on the next update
7013 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);
7014 zoff99 40 }
7015     else
7016     {
7017     this_->level_last = level_cur;
7018     force_speech = 3;
7019 zoff99 41 dbg(0, "NCC_:force_speech(2)=%d\n", force_speech);
7020 zoff99 40 }
7021 zoff99 2 }
7022 zoff99 40 else
7023     {
7024 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)
7025 zoff99 40 {
7026     //dbg(0, "distance %d speed_distance %d\n", distance, speed_distance);
7027     //dbg(0, "level %d < %d\n", level, this_->level_last);
7028     this_->level_last = level;
7029     force_speech = 3;
7030 zoff99 41 dbg(0, "NCC_:force_speech(3)=%d\n", force_speech);
7031 zoff99 40 //dbg(0, "xx 004\n");
7032     }
7033     }
7034 zoff99 2 }
7035 zoff99 27
7036 zoff99 40
7037 zoff99 27 if (!item_is_equal(this_->cmd_first->itm->way.item, this_->item_last))
7038     {
7039 zoff99 40 //dbg(0, "xx 005\n");
7040    
7041 zoff99 27 this_->item_last = this_->cmd_first->itm->way.item;
7042 zoff99 40 this_->level_last = 99; // new item, reset command level
7043    
7044 zoff99 41 dbg(0, "NCC_:Ni---new navigation command item!!---\n");
7045    
7046 zoff99 2 if (this_->delay)
7047 zoff99 40 {
7048 zoff99 27 this_->curr_delay = this_->delay;
7049 zoff99 40 }
7050 zoff99 2 else
7051 zoff99 40 {
7052 zoff99 41 // if ((level_cur > 0) && (global_spoke_last_position_update > 0) && (distance_orig > 50))
7053     // {
7054     // // skip this time, speak command on the next update
7055     // dbg(0, "NCC_:SKIP[2] speech this update, speak at next update (%d)!\n", global_spoke_last_position_update);
7056     // }
7057     // else
7058     // {
7059 zoff99 40 force_speech = 5;
7060 zoff99 41 dbg(0, "NCC_:force_speech(4)=%d\n", force_speech);
7061     // }
7062 zoff99 40 }
7063 zoff99 27 }
7064     else
7065     {
7066 zoff99 40 //dbg(0, "xx 006\n");
7067    
7068 zoff99 27 if (this_->curr_delay)
7069     {
7070 zoff99 2 this_->curr_delay--;
7071 zoff99 40
7072 zoff99 2 if (!this_->curr_delay)
7073 zoff99 40 {
7074 zoff99 27 force_speech = 4;
7075 zoff99 41 dbg(0, "NCC_:force_speech(5)=%d\n", force_speech);
7076 zoff99 40 }
7077 zoff99 2 }
7078     }
7079     }
7080 zoff99 27
7081 zoff99 40 if (global_spoke_last_position_update > 0)
7082     {
7083     //dbg(0,"globalslp(1)=%d\n", global_spoke_last_position_update);
7084     global_spoke_last_position_update--;
7085     //dbg(0,"globalslp(2)=%d\n", global_spoke_last_position_update);
7086     }
7087    
7088 zoff99 41
7089     #if 0
7090 zoff99 40 //dbg(0,"XA 000\n");
7091 zoff99 41 if ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)) // bicycle mode
7092 zoff99 40 {
7093     if ((this_->previous) && (!item_is_equal(this_->cmd_first->itm->way.item, this_->previous->way.item)))
7094     {
7095     // item has changed, check if we missed a spoken level 0 command
7096     if (this_->previous->told == 0)
7097     {
7098 zoff99 41 dbg(0, "NCC_:MISSED a level 0 spoken command!\n");
7099 zoff99 40
7100     char *dir2 = _("right");
7101     int delta2 = this_->cmd_previous->delta;
7102 zoff99 41 dbg(0, "NCC_:missed delta = %d\n", delta2);
7103 zoff99 40 if (delta2 < 0)
7104     {
7105     // TRANSLATORS: left, as in 'Turn left'
7106     dir2 = _("left");
7107     delta2 = -delta2;
7108     }
7109    
7110     if (delta2 > 20)
7111     {
7112 zoff99 41 dbg(0,"NCC_:XA 002a\n");
7113 zoff99 40 navit_say(this_->navit, dir2);
7114     this_->previous->told = 1;
7115     }
7116     }
7117     }
7118     }
7119 zoff99 41 #endif
7120 zoff99 40
7121 zoff99 41
7122 zoff99 40 this_->previous = this_->cmd_first->itm;
7123     this_->cmd_previous = this_->cmd_first;
7124    
7125 zoff99 41 #if 1
7126     if ((dont_speak_yet == 1) && (force_speech))
7127 zoff99 27 {
7128 zoff99 41 dbg(0,"NCC_:this_->level_last = 99\n");
7129     this_->level_last = 99;
7130     }
7131     #endif
7132 zoff99 40
7133 zoff99 41 if (global_driven_away_from_route == 1)
7134     {
7135     dbg(0,"NCC_:** NEW PATH **\n");
7136     global_driven_away_from_route = 0;
7137     global_spoke_last_position_update = 0;
7138     global_last_spoken = -1;
7139     previous_dest_length = -1;
7140     previous_dest_length_save = -1;
7141     last_first_cmd_save = NULL;
7142    
7143     this_->level_last = 99;
7144 zoff99 2 }
7145 zoff99 40
7146 zoff99 41 if ( (dont_speak_yet == 0) || ((global_vehicle_profile == 1) || (global_vehicle_profile == 2)) )
7147     {
7148     if (force_speech)
7149     {
7150     this_->level_last = level;
7151     this_->curr_delay = 0;
7152    
7153     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);
7154     dbg(0, "NCC_:========= END ==========\n");
7155    
7156     global_spoke_last_position_update = 1;
7157    
7158     // ----------------------------------
7159     // ----------------------------------
7160     // calls -> calls navit_speak
7161     //
7162     callback_list_call(this_->callback_speech, 1, &p);
7163     // ----------------------------------
7164     // ----------------------------------
7165     }
7166     }
7167    
7168 zoff99 40 __F_END__
7169 zoff99 2 }
7170    
7171 zoff99 40
7172     // ----------- main place where navigation commands are generated ------------
7173     // ----------- main place where navigation commands are generated ------------
7174     // ----------- main place where navigation commands are generated ------------
7175 zoff99 30 static void navigation_update(struct navigation *this_, struct route *route, struct attr *attr)
7176 zoff99 2 {
7177 zoff99 40 __F_START__
7178    
7179 zoff99 2 struct map *map;
7180     struct map_rect *mr;
7181 zoff99 27 struct item *ritem; /* Holds an item from the route map */
7182     struct item *sitem; /* Holds the corresponding item from the actual map */
7183     struct attr street_item, street_direction;
7184 zoff99 2 struct navigation_itm *itm;
7185     struct attr vehicleprofile;
7186 zoff99 27 int mode = 0, incr = 0, first = 1;
7187 zoff99 40
7188     //dbg(0, "Enter\n");
7189    
7190 zoff99 2 if (attr->type != attr_route_status)
7191 zoff99 40 {
7192     //dbg(0, "return 001\n");
7193     return2;
7194     }
7195 zoff99 2
7196 zoff99 40 #ifdef NAVIT_ROUTING_DEBUG_PRINT
7197     dbg(0, "RS:001:route_status=%s\n", route_status_to_name(attr->u.num));
7198     #endif
7199    
7200 zoff99 41
7201     dbg(0, "NCC_:NU:RRRRSSSSSS::route_status=%s\n", route_status_to_name(attr->u.num));
7202    
7203     if (attr->u.num == route_status_path_done_new)
7204     {
7205     // route calculated new, you drove a different path?
7206     global_driven_away_from_route = 1;
7207     }
7208    
7209    
7210 zoff99 40 //dbg(1, "enter %d\n", mode);
7211 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)
7212 zoff99 40 {
7213 zoff99 41 dbg(0, "NCC_:NU:navigation_flush\n");
7214 zoff99 2 navigation_flush(this_);
7215 zoff99 40 }
7216    
7217 zoff99 30 if (attr->u.num != route_status_path_done_new && attr->u.num != route_status_path_done_incremental)
7218 zoff99 40 {
7219     //dbg(0, "return 002\n");
7220 zoff99 41 dbg(0, "NCC_:NU:ret 001\n");
7221    
7222 zoff99 40 return2;
7223     }
7224 zoff99 27
7225     if (!this_->route)
7226 zoff99 40 {
7227     //dbg(0, "return 003\n");
7228 zoff99 41 dbg(0, "NCC_:NU:ret 002\n");
7229    
7230 zoff99 40 return2;
7231     }
7232    
7233 zoff99 27 map = route_get_map(this_->route);
7234     if (!map)
7235 zoff99 40 {
7236     //dbg(0, "return 004\n");
7237     return2;
7238     }
7239    
7240 zoff99 27 mr = map_rect_new(map, NULL);
7241 zoff99 40
7242 zoff99 27 if (!mr)
7243 zoff99 40 {
7244     //dbg(0, "return 005\n");
7245     return2;
7246     }
7247    
7248 zoff99 2 if (route_get_attr(route, attr_vehicleprofile, &vehicleprofile, NULL))
7249 zoff99 40 {
7250 zoff99 27 this_->vehicleprofile = vehicleprofile.u.vehicleprofile;
7251 zoff99 40 }
7252 zoff99 2 else
7253 zoff99 40 {
7254 zoff99 27 this_->vehicleprofile = NULL;
7255 zoff99 40 }
7256    
7257 zoff99 27 //dbg(1,"enter\n");
7258    
7259 zoff99 41 dbg(0, "NCC_:NU:------ LOOP START ------\n");
7260    
7261     int first_item = 1;
7262     this_->turn_around = 0;
7263    
7264 zoff99 27 while ((ritem = map_rect_get_item(mr)))
7265     {
7266 zoff99 41
7267     dbg(0, "NAVR:001:%s\n", item_to_name(ritem->type));
7268    
7269     #if 0
7270 zoff99 30 if (ritem->type == type_route_start && this_->turn_around > -this_->turn_around_limit + 1)
7271 zoff99 40 {
7272 zoff99 2 this_->turn_around--;
7273 zoff99 40 }
7274    
7275 zoff99 30 if (ritem->type == type_route_start_reverse && this_->turn_around < this_->turn_around_limit)
7276 zoff99 40 {
7277 zoff99 2 this_->turn_around++;
7278 zoff99 41 dbg(0, "NAVR:001.1:** TURN AROUND **\n");
7279 zoff99 40 }
7280 zoff99 41 #endif
7281 zoff99 40
7282 zoff99 41 #if 1
7283     if (first_item == 1)
7284 zoff99 40 {
7285 zoff99 41 first_item = 0;
7286     if (ritem->type == type_route_start_reverse)
7287     {
7288     this_->turn_around = this_->turn_around_limit;
7289    
7290     dbg(0, "NAV_TURNAROUND:006 ta=%d talimit=%d\n", this_->turn_around, this_->turn_around_limit);
7291    
7292     dbg(0, "NAVR:001.1:T_A:** TURN AROUND **:%s\n", item_to_name(ritem->type));
7293     }
7294     else
7295     {
7296     dbg(0, "NAVR:001.1:T_A:first item=%s\n", item_to_name(ritem->type));
7297     }
7298     }
7299     #endif
7300    
7301    
7302     dbg(0, "NAVR:001:X1:%s\n", item_to_name(ritem->type));
7303     if ((ritem->type != type_street_route) && (ritem->type != type_street_route_waypoint))
7304     {
7305     dbg(0, "NAVR:001:X2R:%s\n", item_to_name(ritem->type));
7306 zoff99 2 continue;
7307 zoff99 40 }
7308 zoff99 41 dbg(0, "NAVR:001:X3:%s\n", item_to_name(ritem->type));
7309 zoff99 27
7310     if (first && item_attr_get(ritem, attr_street_item, &street_item))
7311     {
7312     first = 0;
7313 zoff99 2 if (!item_attr_get(ritem, attr_direction, &street_direction))
7314 zoff99 40 {
7315 zoff99 27 street_direction.u.num = 0;
7316 zoff99 40 }
7317    
7318 zoff99 27 sitem = street_item.u.item;
7319     //dbg(1,"sitem=%p\n", sitem);
7320     itm = item_hash_lookup(this_->hash, sitem);
7321     //dbg(2,"itm for item with id (0x%x,0x%x) is %p\n", sitem->id_hi, sitem->id_lo, itm);
7322    
7323     if (itm && itm->way.dir != street_direction.u.num)
7324     {
7325     //dbg(2,"wrong direction\n");
7326 zoff99 41 dbg(0, "NAVR:001.2:*+ WRONG DIRECTION +*\n");
7327 zoff99 27 itm = NULL;
7328 zoff99 2 }
7329 zoff99 40
7330 zoff99 41 dbg(0, "NCC_:NU:navigation_destroy_itms_cmds\n");
7331 zoff99 2 navigation_destroy_itms_cmds(this_, itm);
7332 zoff99 40
7333 zoff99 27 if (itm)
7334     {
7335 zoff99 41 dbg(0, "NCC_:NU:navigation_itm_update\n");
7336    
7337 zoff99 2 navigation_itm_update(itm, ritem);
7338     break;
7339     }
7340 zoff99 27 //dbg(1,"not on track\n");
7341 zoff99 2 }
7342 zoff99 41
7343     dbg(0, "NAVR:001:X4:%s\n", item_to_name(ritem->type));
7344     dbg(0, "NCC_:NU:navigation_itm_new\n");
7345 zoff99 2 navigation_itm_new(this_, ritem);
7346 zoff99 41 dbg(0, "NAVR:001:X5:%s\n", item_to_name(ritem->type));
7347    
7348 zoff99 2 }
7349 zoff99 40
7350 zoff99 41
7351     dbg(0, "NCC_:NU:------ LOOP END ------\n");
7352    
7353    
7354 zoff99 40 //dbg(2, "turn_around=%d\n", this_->turn_around);
7355    
7356 zoff99 27 if (first)
7357 zoff99 40 {
7358    
7359     #ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
7360     dbg(0, "DEST::route_clear_freetext_list\n");
7361     route_clear_freetext_list();
7362     #endif
7363    
7364 zoff99 41 dbg(0, "NCC_:NU:navigation_destroy_itms_cmds[first]\n");
7365    
7366 zoff99 2 navigation_destroy_itms_cmds(this_, NULL);
7367 zoff99 40 }
7368 zoff99 27 else
7369     {
7370     if (!ritem)
7371     {
7372 zoff99 41 dbg(0, "NCC_:NU:navigation_itm_new[!ritem]\n");
7373 zoff99 2 navigation_itm_new(this_, NULL);
7374 zoff99 40 //dbg(0, "Enter: make_maneuvers\n");
7375 zoff99 41 dbg(0, "NAVR:001.2:*= MAKE MANEUVERS =*\n");
7376     dbg(0, "NCC_:NU:make_maneuvers[!ritem]\n");
7377 zoff99 27 make_maneuvers(this_, this_->route);
7378 zoff99 40 //dbg(0, "end : make_maneuvers\n");
7379 zoff99 2 }
7380 zoff99 41
7381     dbg(0, "NCC_:NU:calculate_dest_distance\n");
7382 zoff99 2 calculate_dest_distance(this_, incr);
7383 zoff99 40
7384     // calls navit_speak later !! ----------
7385 zoff99 2 navigation_call_callbacks(this_, FALSE);
7386 zoff99 40 // calls navit_speak later !! ----------
7387 zoff99 2 }
7388     map_rect_destroy(mr);
7389 zoff99 40
7390     __F_END__
7391 zoff99 2 }
7392 zoff99 40 // ----------- main place where navigation commands are generated ------------
7393     // ----------- main place where navigation commands are generated ------------
7394     // ----------- main place where navigation commands are generated ------------
7395 zoff99 2
7396 zoff99 40
7397 zoff99 27 static void navigation_flush(struct navigation *this_)
7398 zoff99 2 {
7399 zoff99 40 __F_START__
7400 zoff99 2 navigation_destroy_itms_cmds(this_, NULL);
7401 zoff99 40 __F_END__
7402 zoff99 2 }
7403    
7404 zoff99 27 void navigation_destroy(struct navigation *this_)
7405 zoff99 2 {
7406     navigation_flush(this_);
7407     item_hash_destroy(this_->hash);
7408     callback_list_destroy(this_->callback);
7409     callback_list_destroy(this_->callback_speech);
7410     g_free(this_);
7411     }
7412    
7413 zoff99 30 int navigation_register_callback(struct navigation *this_, enum attr_type type, struct callback *cb)
7414 zoff99 2 {
7415 zoff99 40 __F_START__
7416    
7417 zoff99 2 if (type == attr_navigation_speech)
7418 zoff99 40 {
7419 zoff99 2 callback_list_add(this_->callback_speech, cb);
7420 zoff99 40 }
7421 zoff99 2 else
7422 zoff99 40 {
7423 zoff99 2 callback_list_add(this_->callback, cb);
7424 zoff99 40 }
7425    
7426     return2 1;
7427    
7428     __F_END__
7429 zoff99 2 }
7430    
7431 zoff99 30 void navigation_unregister_callback(struct navigation *this_, enum attr_type type, struct callback *cb)
7432 zoff99 2 {
7433 zoff99 40 __F_START__
7434    
7435 zoff99 2 if (type == attr_navigation_speech)
7436 zoff99 40 {
7437 zoff99 2 callback_list_remove_destroy(this_->callback_speech, cb);
7438 zoff99 40 }
7439 zoff99 2 else
7440 zoff99 40 {
7441 zoff99 2 callback_list_remove_destroy(this_->callback, cb);
7442 zoff99 40 }
7443    
7444     __F_END__
7445 zoff99 2 }
7446    
7447     struct map *
7448     navigation_get_map(struct navigation *this_)
7449     {
7450     struct attr *attrs[5];
7451 zoff99 27 struct attr type, navigation, data, description;
7452     type.type = attr_type;
7453     type.u.str = "navigation";
7454     navigation.type = attr_navigation;
7455     navigation.u.navigation = this_;
7456     data.type = attr_data;
7457     data.u.str = "";
7458     description.type = attr_description;
7459     description.u.str = "Navigation";
7460    
7461     attrs[0] = &type;
7462     attrs[1] = &navigation;
7463     attrs[2] = &data;
7464     attrs[3] = &description;
7465     attrs[4] = NULL;
7466 zoff99 41
7467 zoff99 27 if (!this_->map)
7468 zoff99 41 {
7469 zoff99 27 this_->map = map_new(NULL, attrs);
7470 zoff99 41 }
7471    
7472 zoff99 27 return this_->map;
7473 zoff99 2 }
7474    
7475 zoff99 27 struct map_priv
7476     {
7477 zoff99 2 struct navigation *navigation;
7478     };
7479    
7480 zoff99 27 struct map_rect_priv
7481     {
7482 zoff99 2 struct navigation *nav;
7483     struct navigation_command *cmd;
7484     struct navigation_command *cmd_next;
7485     struct navigation_itm *itm;
7486     struct navigation_itm *itm_next;
7487     struct navigation_itm *cmd_itm;
7488     struct navigation_itm *cmd_itm_next;
7489     struct item item;
7490     enum attr_type attr_next;
7491     int ccount;
7492     int debug_idx;
7493     struct navigation_way *ways;
7494     int show_all;
7495     char *str;
7496     };
7497    
7498 zoff99 30 static int navigation_map_item_coord_get(void *priv_data, struct coord *c, int count)
7499 zoff99 2 {
7500 zoff99 27 struct map_rect_priv *this = priv_data;
7501 zoff99 40
7502 zoff99 27 if (this->ccount || !count)
7503 zoff99 41 {
7504     // dbg(0, "NAVICG:return 001 %d %d\n", this->ccount, count);
7505 zoff99 2 return 0;
7506 zoff99 41 }
7507 zoff99 40
7508 zoff99 41 if (this->item.type == type_nav_waypoint)
7509     {
7510     if (this->itm->way.dir == 99)
7511     {
7512     dbg(0, "NAVICG:waypoint:END of seg\n");
7513     *c = this->itm->end;
7514     }
7515     else
7516     {
7517     dbg(0, "NAVICG:waypoint:start of seg\n");
7518     *c = this->itm->start;
7519     }
7520     }
7521     else
7522     {
7523     // dbg(0, "NAVICG:normal type=%s cc=%d\n", item_to_name(this->item.type), this->ccount);
7524     *c = this->itm->start;
7525     }
7526    
7527 zoff99 27 this->ccount = 1;
7528 zoff99 40
7529 zoff99 2 return 1;
7530     }
7531    
7532 zoff99 30 static int navigation_map_item_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
7533 zoff99 2 {
7534 zoff99 27 struct map_rect_priv *this_ = priv_data;
7535     struct navigation_command *cmd = this_->cmd;
7536     struct navigation_itm *itm = this_->itm;
7537     struct navigation_itm *prev = itm->prev;
7538     attr->type = attr_type;
7539 zoff99 2
7540 zoff99 27 if (this_->str)
7541     {
7542 zoff99 2 g_free(this_->str);
7543 zoff99 27 this_->str = NULL;
7544 zoff99 2 }
7545    
7546 zoff99 27 if (cmd)
7547     {
7548 zoff99 2 if (cmd->itm != itm)
7549 zoff99 40 {
7550 zoff99 27 cmd = NULL;
7551 zoff99 40 }
7552 zoff99 2 }
7553 zoff99 40
7554 zoff99 27 switch (attr_type)
7555     {
7556     case attr_navigation_short:
7557     this_->attr_next = attr_navigation_long;
7558     if (cmd)
7559     {
7560 zoff99 40 //dbg(0, "attr_navigation_short\n");
7561 zoff99 30 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type);
7562 zoff99 2 return 1;
7563     }
7564 zoff99 27 return 0;
7565     case attr_navigation_long:
7566     this_->attr_next = attr_navigation_long_exact;
7567     if (cmd)
7568     {
7569 zoff99 40 //dbg(0, "attr_navigation_long\n");
7570 zoff99 30 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type);
7571 zoff99 2 return 1;
7572     }
7573 zoff99 27 return 0;
7574     case attr_navigation_long_exact:
7575     this_->attr_next = attr_navigation_speech;
7576     if (cmd)
7577     {
7578 zoff99 40 //dbg(0, "attr_navigation_long_exact\n");
7579 zoff99 30 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type);
7580 zoff99 2 return 1;
7581     }
7582 zoff99 27 return 0;
7583     case attr_navigation_speech:
7584     this_->attr_next = attr_length;
7585     if (cmd)
7586     {
7587 zoff99 40 //dbg(0, "attr_navigation_speech\n");
7588     //dbg(0, "Enter: attr_navigation_speech\n");
7589 zoff99 30 this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, this_->cmd, attr_type);
7590 zoff99 40 //dbg(0, "back : attr_navigation_speech\n");
7591 zoff99 2 return 1;
7592     }
7593 zoff99 41 else if (this_->nav->turn_around_limit && this_->nav->turn_around == this_->nav->turn_around_limit)
7594     {
7595     if (global_turn_around_spoken == 0)
7596     {
7597     this_->str = attr->u.str = g_strdup(_("When possible, please turn around"));
7598     global_turn_around_spoken = 1;
7599     return 1;
7600     }
7601     else
7602     {
7603     return 0;
7604     }
7605     }
7606 zoff99 27 return 0;
7607     case attr_length:
7608     this_->attr_next = attr_time;
7609     if (cmd)
7610     {
7611 zoff99 30 attr->u.num = this_->cmd_itm->dest_length - cmd->itm->dest_length;
7612 zoff99 2 return 1;
7613     }
7614 zoff99 27 return 0;
7615     case attr_time:
7616     this_->attr_next = attr_destination_length;
7617     if (cmd)
7618     {
7619     attr->u.num = this_->cmd_itm->dest_time - cmd->itm->dest_time;
7620 zoff99 2 return 1;
7621     }
7622 zoff99 27 return 0;
7623 zoff99 40
7624 zoff99 27 case attr_destination_length:
7625     attr->u.num = itm->dest_length;
7626     this_->attr_next = attr_destination_time;
7627     return 1;
7628 zoff99 40
7629 zoff99 27 case attr_destination_time:
7630     attr->u.num = itm->dest_time;
7631     this_->attr_next = attr_street_name;
7632     return 1;
7633 zoff99 40
7634 zoff99 27 case attr_street_name:
7635     attr->u.str = itm->way.name1;
7636     this_->attr_next = attr_street_name_systematic;
7637     if (attr->u.str)
7638 zoff99 2 return 1;
7639 zoff99 27 return 0;
7640 zoff99 40
7641 zoff99 27 case attr_street_name_systematic:
7642     attr->u.str = itm->way.name2;
7643 zoff99 40 this_->attr_next = attr_street_destination;
7644     if (attr->u.str)
7645     return 1;
7646     return 0;
7647    
7648     case attr_street_destination:
7649     attr->u.str = itm->way.street_dest_text;
7650 zoff99 27 this_->attr_next = attr_debug;
7651     if (attr->u.str)
7652 zoff99 40 {
7653 zoff99 27 return 1;
7654 zoff99 40 }
7655 zoff99 27 return 0;
7656 zoff99 40
7657 zoff99 27 case attr_debug:
7658     switch (this_->debug_idx)
7659     {
7660     case 0:
7661     this_->debug_idx++;
7662 zoff99 30 this_->str = attr->u.str = g_strdup_printf("angle:%d (- %d)", itm->way.angle2, itm->angle_end);
7663 zoff99 27 return 1;
7664     case 1:
7665     this_->debug_idx++;
7666 zoff99 30 this_->str = attr->u.str = g_strdup_printf("item type:%s", item_to_name(itm->way.item.type));
7667 zoff99 27 return 1;
7668     case 2:
7669     this_->debug_idx++;
7670     if (cmd)
7671     {
7672 zoff99 30 this_->str = attr->u.str = g_strdup_printf("delta:%d", cmd->delta);
7673 zoff99 27 return 1;
7674     }
7675     case 3:
7676     this_->debug_idx++;
7677     if (prev)
7678     {
7679 zoff99 30 this_->str = attr->u.str = g_strdup_printf("prev street_name:%s", prev->way.name1);
7680 zoff99 27 return 1;
7681     }
7682     case 4:
7683     this_->debug_idx++;
7684     if (prev)
7685     {
7686 zoff99 30 this_->str = attr->u.str = g_strdup_printf("prev street_name_systematic:%s", prev->way.name2);
7687 zoff99 27 return 1;
7688     }
7689     case 5:
7690     this_->debug_idx++;
7691     if (prev)
7692     {
7693 zoff99 30 this_->str = attr->u.str = g_strdup_printf("prev angle:(%d -) %d", prev->way.angle2, prev->angle_end);
7694 zoff99 27 return 1;
7695     }
7696     case 6:
7697     this_->debug_idx++;
7698     this_->ways = itm->way.next;
7699     if (prev)
7700     {
7701 zoff99 30 this_->str = attr->u.str = g_strdup_printf("prev item type:%s", item_to_name(prev->way.item.type));
7702 zoff99 27 return 1;
7703     }
7704     case 7:
7705     if (this_->ways && prev)
7706     {
7707 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);
7708 zoff99 27 this_->ways = this_->ways->next;
7709     return 1;
7710     }
7711     this_->debug_idx++;
7712     case 8:
7713     this_->debug_idx++;
7714     if (prev)
7715     {
7716     int delta = 0;
7717 zoff99 41 int delta_real = 0;
7718 zoff99 27 char *reason = NULL;
7719 zoff99 41 maneuver_required2(this_->nav, prev, itm, &delta, &delta_real, &reason);
7720 zoff99 30 this_->str = attr->u.str = g_strdup_printf("reason:%s", reason);
7721 zoff99 27 return 1;
7722     }
7723    
7724     default:
7725     this_->attr_next = attr_none;
7726     return 0;
7727 zoff99 2 }
7728 zoff99 40
7729 zoff99 27 case attr_any:
7730     while (this_->attr_next != attr_none)
7731     {
7732 zoff99 30 if (navigation_map_item_attr_get(priv_data, this_->attr_next, attr))
7733 zoff99 27 return 1;
7734     }
7735     return 0;
7736 zoff99 40
7737 zoff99 2 default:
7738 zoff99 27 attr->type = attr_none;
7739 zoff99 2 return 0;
7740     }
7741     }
7742    
7743 zoff99 30 static struct item_methods navigation_map_item_methods = { NULL, navigation_map_item_coord_get, NULL, navigation_map_item_attr_get, };
7744 zoff99 2
7745 zoff99 27 static void navigation_map_destroy(struct map_priv *priv)
7746 zoff99 2 {
7747     g_free(priv);
7748     }
7749    
7750 zoff99 27 static void navigation_map_rect_init(struct map_rect_priv *priv)
7751 zoff99 2 {
7752 zoff99 27 priv->cmd_next = priv->nav->cmd_first;
7753     priv->cmd_itm_next = priv->itm_next = priv->nav->first;
7754 zoff99 2 }
7755    
7756     static struct map_rect_priv *
7757     navigation_map_rect_new(struct map_priv *priv, struct map_selection *sel)
7758     {
7759 zoff99 27 struct navigation *nav = priv->navigation;
7760 zoff99 2 struct map_rect_priv *ret=g_new0(struct map_rect_priv, 1);
7761 zoff99 27 ret->nav = nav;
7762 zoff99 40
7763 zoff99 2 navigation_map_rect_init(ret);
7764 zoff99 40
7765 zoff99 27 ret->item.meth = &navigation_map_item_methods;
7766     ret->item.priv_data = ret;
7767 zoff99 40
7768 zoff99 2 #ifdef DEBUG
7769     ret->show_all=1;
7770     #endif
7771 zoff99 40
7772 zoff99 2 return ret;
7773     }
7774    
7775 zoff99 27 static void navigation_map_rect_destroy(struct map_rect_priv *priv)
7776 zoff99 2 {
7777     g_free(priv);
7778     }
7779    
7780 zoff99 41
7781    
7782     void navigation_dump_items(struct navigation *this_)
7783     {
7784     if (this_->first)
7785     {
7786     dbg(0, "NAVR:dump:=================++++++++++++================\n");
7787     struct navigation_itm *i;
7788     int count = 0;
7789    
7790     i = this_->first;
7791     while (i)
7792     {
7793     count++;
7794     i = i->next;
7795     }
7796    
7797     i = this_->first;
7798     while (i)
7799     {
7800     count--;
7801     dbg(0, "NAVR:dump:count=%d %p %d\n", count, i, i->way.dir);
7802     i = i->next;
7803     }
7804     dbg(0, "NAVR:dump:=================++++++++++++================\n");
7805     }
7806     }
7807    
7808    
7809     // -----------------------------------
7810     static int save_last_dest_count = -1;
7811     // -----------------------------------
7812    
7813 zoff99 2 static struct item *
7814     navigation_map_get_item(struct map_rect_priv *priv)
7815     {
7816 zoff99 27 struct item *ret = &priv->item;
7817 zoff99 2 int delta;
7818 zoff99 40
7819 zoff99 41 int fake_dir1;
7820     int fake_dir2;
7821    
7822     dbg(0, "NAVR:ROUTE:Enter:\n");
7823     dbg(0, "NAVR:ROUTE:Enter:------------------------\n");
7824    
7825 zoff99 2 if (!priv->itm_next)
7826 zoff99 40 {
7827 zoff99 41 dbg(0, "NAVR:ROUTE:006:0000\n");
7828 zoff99 2 return NULL;
7829 zoff99 40 }
7830    
7831 zoff99 41 int stepped_to_waypoint = 0;
7832    
7833     // now check if we missed a waypoint, if so -> move back to waypoint -------------------------
7834     if (priv->itm)
7835     {
7836     if (save_last_dest_count != -1)
7837     {
7838     int count_back = (save_last_dest_count - priv->itm->dest_count - 1);
7839     int count_forw = count_back;
7840     dbg(0, "NAVR:ROUTE:006:cback:%d = (%d - %d - 1)\n", count_back, save_last_dest_count, priv->itm->dest_count);
7841    
7842     struct navigation_itm *i = priv->itm;
7843    
7844     // go to first item to check
7845     while (count_back > 0)
7846     {
7847     count_back--;
7848     if (i->prev)
7849     {
7850     i = i->prev;
7851     dbg(0, "NAVR:ROUTE:006:cback:stepping back to item #%d dir=%d\n", i->dest_count, i->way.dir);
7852     }
7853     }
7854    
7855     // now step forward until waypoint found, or just skip the whole thing if we dont find any waypoint
7856     while (count_forw > 0)
7857     {
7858     if (i)
7859     {
7860     dbg(0, "NAVR:ROUTE:006:cback:stepping forw to item #%d dir=%d\n", i->dest_count, i->way.dir);
7861    
7862     if ((i->way.dir == 99) || (i->way.dir == -99))
7863     {
7864     // found a waypoint
7865     priv->itm = i;
7866     stepped_to_waypoint = 1;
7867    
7868     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);
7869    
7870     break;
7871     }
7872    
7873     count_forw--;
7874     if (i->next)
7875     {
7876     i = i->next;
7877     }
7878     }
7879     }
7880    
7881     }
7882     }
7883     // now check if we missed a waypoint, if so -> move back to waypoint -------------------------
7884    
7885    
7886     if (priv->itm)
7887     {
7888     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);
7889     fake_dir1 = priv->itm->way.dir;
7890     save_last_dest_count = priv->itm->dest_count;
7891     }
7892     else
7893     {
7894     dbg(0, "NAVR:ROUTE:006:8888:1: NULL\n");
7895     fake_dir1 = 0;
7896     save_last_dest_count = -1;
7897     }
7898    
7899     if (stepped_to_waypoint != 1)
7900     {
7901     priv->itm = priv->itm_next;
7902     }
7903    
7904    
7905     fake_dir2 = priv->itm->way.dir;
7906     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);
7907 zoff99 27 priv->cmd = priv->cmd_next;
7908     priv->cmd_itm = priv->cmd_itm_next;
7909 zoff99 40
7910 zoff99 41 if ((priv->itm->way.dir == 99) || (priv->itm->way.dir == -99))
7911     {
7912     // return fake waypoint item!! ---------
7913     ret->type = type_nav_waypoint;
7914     ret->id_lo = priv->itm->dest_count;
7915     priv->ccount = 0;
7916    
7917     priv->itm_next = priv->itm->next;
7918    
7919     dbg(0, "NAVR:ROUTE:006:fake:%s dir=%d ,,,,,\n", item_to_name(ret->type), priv->itm->way.dir);
7920    
7921     return ret;
7922     }
7923    
7924    
7925    
7926     // navigation_dump_items(priv->nav);
7927    
7928 zoff99 2 if (!priv->cmd)
7929 zoff99 40 {
7930 zoff99 41 dbg(0, "NAVR:ROUTE:006:1111\n");
7931 zoff99 2 return NULL;
7932 zoff99 40 }
7933    
7934 zoff99 41
7935 zoff99 27 if (!priv->show_all && priv->itm->prev != NULL)
7936 zoff99 40 {
7937 zoff99 41 dbg(0, "NAVR:ROUTE:006:112a\n");
7938 zoff99 27 priv->itm = priv->cmd->itm;
7939 zoff99 40 }
7940    
7941 zoff99 27 priv->itm_next = priv->itm->next;
7942 zoff99 40
7943 zoff99 2 if (priv->itm->prev)
7944 zoff99 40 {
7945 zoff99 27 ret->type = type_nav_none;
7946 zoff99 40 }
7947 zoff99 2 else
7948 zoff99 40 {
7949 zoff99 27 ret->type = type_nav_position;
7950 zoff99 40 }
7951    
7952 zoff99 41 dbg(0, "NAVR:ROUTE:006:2222 %p dir=%d\n", priv->itm, priv->itm->way.dir);
7953    
7954 zoff99 27 if (priv->cmd->itm == priv->itm)
7955     {
7956 zoff99 41
7957     dbg(0, "NAVR:ROUTE:006:3333 %p dir=%d %p\n", priv->itm, priv->itm->way.dir, route_get_map(global_navit->route));
7958     // item_dump_coords(priv->itm, route_get_map(global_navit->route));
7959    
7960 zoff99 27 priv->cmd_itm_next = priv->cmd->itm;
7961     priv->cmd_next = priv->cmd->next;
7962 zoff99 40
7963 zoff99 2 if (priv->cmd_itm_next && !priv->cmd_itm_next->next)
7964 zoff99 40 {
7965 zoff99 27 ret->type = type_nav_destination;
7966 zoff99 40 }
7967 zoff99 27 else
7968     {
7969 zoff99 34 if (priv->itm && priv->itm->prev && !(priv->itm->way.flags & NAVIT_AF_ROUNDABOUT) && (priv->itm->prev->way.flags & NAVIT_AF_ROUNDABOUT))
7970 zoff99 27 {
7971     enum item_type r = type_none, l = type_none;
7972     switch (((180 + 22) - priv->cmd->roundabout_delta) / 45)
7973     {
7974     case 0:
7975     case 1:
7976     r = type_nav_roundabout_r1;
7977     l = type_nav_roundabout_l7;
7978     break;
7979     case 2:
7980     r = type_nav_roundabout_r2;
7981     l = type_nav_roundabout_l6;
7982     break;
7983     case 3:
7984     r = type_nav_roundabout_r3;
7985     l = type_nav_roundabout_l5;
7986     break;
7987     case 4:
7988     r = type_nav_roundabout_r4;
7989     l = type_nav_roundabout_l4;
7990     break;
7991     case 5:
7992     r = type_nav_roundabout_r5;
7993     l = type_nav_roundabout_l3;
7994     break;
7995     case 6:
7996     r = type_nav_roundabout_r6;
7997     l = type_nav_roundabout_l2;
7998     break;
7999     case 7:
8000     r = type_nav_roundabout_r7;
8001     l = type_nav_roundabout_l1;
8002     break;
8003     case 8:
8004     r = type_nav_roundabout_r8;
8005     l = type_nav_roundabout_l8;
8006     break;
8007 zoff99 2 }
8008 zoff99 40 // dbg(0, "delta %d\n", priv->cmd->delta);
8009    
8010 zoff99 2 if (priv->cmd->delta < 0)
8011 zoff99 40 {
8012 zoff99 27 ret->type = l;
8013 zoff99 40 }
8014 zoff99 2 else
8015 zoff99 40 {
8016 zoff99 27 ret->type = r;
8017 zoff99 40 }
8018 zoff99 27 }
8019     else
8020     {
8021     delta = priv->cmd->delta;
8022     if (delta < 0)
8023     {
8024     delta = -delta;
8025 zoff99 2 if (delta < 45)
8026 zoff99 27 ret->type = type_nav_left_1;
8027 zoff99 2 else if (delta < 105)
8028 zoff99 27 ret->type = type_nav_left_2;
8029     else if (delta < 165)
8030     ret->type = type_nav_left_3;
8031 zoff99 2 else
8032 zoff99 27 ret->type = type_none;
8033     }
8034 zoff99 40 else if (delta > 0)
8035 zoff99 27 {
8036 zoff99 2 if (delta < 45)
8037 zoff99 27 ret->type = type_nav_right_1;
8038 zoff99 2 else if (delta < 105)
8039 zoff99 27 ret->type = type_nav_right_2;
8040     else if (delta < 165)
8041     ret->type = type_nav_right_3;
8042 zoff99 2 else
8043 zoff99 27 ret->type = type_none;
8044 zoff99 2 }
8045 zoff99 40 else // delta == 0
8046     {
8047     ret->type = type_nav_straight;
8048     }
8049 zoff99 2 }
8050     }
8051     }
8052 zoff99 40
8053 zoff99 27 priv->ccount = 0;
8054     priv->debug_idx = 0;
8055     priv->attr_next = attr_navigation_short;
8056 zoff99 2
8057 zoff99 27 ret->id_lo = priv->itm->dest_count;
8058 zoff99 40
8059 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);
8060 zoff99 41
8061    
8062     // check for "turn around" and return "type_nav_turnaround" !! ---------------
8063     if ((priv->nav->turn_around && priv->nav->turn_around == priv->nav->turn_around_limit) && (ret->type == type_nav_position))
8064     {
8065 zoff99 46 // dbg(0, "priv->itm->dest_count=%d\n", priv->itm->dest_count);
8066 zoff99 41 ret->type = type_nav_turnaround_right;
8067     }
8068     // check for "turn around" and return "type_nav_turnaround" !! ---------------
8069    
8070 zoff99 46 // dbg(0, "NAVR:ROUTE:007a:%s ,,,,, priv->itm->dest_count=%d\n", item_to_name(ret->type), priv->itm->dest_count);
8071 zoff99 41
8072 zoff99 2 return ret;
8073     }
8074    
8075     static struct item *
8076     navigation_map_get_item_byid(struct map_rect_priv *priv, int id_hi, int id_lo)
8077     {
8078     struct item *ret;
8079     navigation_map_rect_init(priv);
8080 zoff99 27 while ((ret = navigation_map_get_item(priv)))
8081     {
8082     if (ret->id_hi == id_hi && ret->id_lo == id_lo)
8083 zoff99 2 return ret;
8084     }
8085     return NULL;
8086     }
8087    
8088 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, };
8089 zoff99 2
8090 zoff99 40 struct map_priv *
8091 zoff99 30 navigation_map_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl)
8092 zoff99 2 {
8093     struct map_priv *ret;
8094     struct attr *navigation_attr;
8095    
8096 zoff99 27 navigation_attr = attr_search(attrs, NULL, attr_navigation);
8097 zoff99 40
8098 zoff99 27 if (!navigation_attr)
8099 zoff99 40 {
8100 zoff99 34 return NULL;
8101 zoff99 40 }
8102    
8103 zoff99 34 ret=g_new0(struct map_priv, 1);
8104 zoff99 27 *meth = navigation_map_meth;
8105     ret->navigation = navigation_attr->u.navigation;
8106 zoff99 2
8107 zoff99 41 level_static_for_bicycle[0] = 22; // in meters
8108 zoff99 40 level_static_for_bicycle[1] = 100; // in meters
8109     level_static_for_bicycle[2] = -1; // dont announce
8110    
8111 zoff99 2 return ret;
8112     }
8113    
8114 zoff99 27 void navigation_set_route(struct navigation *this_, struct route *route)
8115 zoff99 2 {
8116 zoff99 40 __F_START__
8117    
8118 zoff99 2 struct attr callback;
8119 zoff99 27 this_->route = route;
8120 zoff99 30 this_->route_cb = callback_new_attr_1(callback_cast(navigation_update), attr_route_status, this_);
8121     callback_add_names(this_->route_cb, "navigation_set_route", "navigation_update");
8122 zoff99 27 callback.type = attr_callback;
8123     callback.u.callback = this_->route_cb;
8124 zoff99 2 route_add_attr(route, &callback);
8125 zoff99 40
8126     __F_END__
8127 zoff99 2 }
8128    
8129 zoff99 27 void navigation_init(void)
8130 zoff99 2 {
8131 zoff99 40 #ifdef PLUGSSS
8132 zoff99 2 plugin_register_map_type("navigation", navigation_map_new);
8133 zoff99 40 #endif
8134 zoff99 2 }
8135 zoff99 40
8136    
8137 zoff99 51

   
Visit the ZANavi Wiki