… | |
… | |
66 | struct suffix |
66 | struct suffix |
67 | { |
67 | { |
68 | char *fullname; |
68 | char *fullname; |
69 | char *abbrev; |
69 | char *abbrev; |
70 | int sex; |
70 | int sex; |
71 | } suffixes[] = |
71 | } suffixes[] = { { "weg", NULL, 1 }, { "platz", "pl.", 1 }, { "ring", NULL, 1 }, { "allee", NULL, 2 }, { "gasse", NULL, 2 }, { "straße", "str.", 2 }, { "strasse", NULL, 2 }, }; |
72 | { |
|
|
73 | { "weg", NULL, 1 }, |
|
|
74 | { "platz", "pl.", 1 }, |
|
|
75 | { "ring", NULL, 1 }, |
|
|
76 | { "allee", NULL, 2 }, |
|
|
77 | { "gasse", NULL, 2 }, |
|
|
78 | { "straße", "str.", 2 }, |
|
|
79 | { "strasse", NULL, 2 }, }; |
|
|
80 | |
72 | |
81 | struct navigation |
73 | struct navigation |
82 | { |
74 | { |
83 | struct route *route; |
75 | struct route *route; |
84 | struct map *map; |
76 | struct map *map; |
… | |
… | |
102 | int tell_street_name; |
94 | int tell_street_name; |
103 | int delay; |
95 | int delay; |
104 | int curr_delay; |
96 | int curr_delay; |
105 | }; |
97 | }; |
106 | |
98 | |
107 | int distances[] = |
|
|
108 | { 1, 2, 3, 4, 5, 10, 25, 50, 75, 100, 150, 200, 250, 300, 400, 500, 750, -1 }; |
99 | int distances[] = { 1, 2, 3, 4, 5, 10, 25, 50, 75, 100, 150, 200, 250, 300, 400, 500, 750, -1 }; |
109 | |
100 | |
110 | struct navigation_command |
101 | struct navigation_command |
111 | { |
102 | { |
112 | struct navigation_itm *itm; |
103 | struct navigation_itm *itm; |
113 | struct navigation_command *next; |
104 | struct navigation_command *next; |
… | |
… | |
150 | static int angle_opposite(int angle) |
141 | static int angle_opposite(int angle) |
151 | { |
142 | { |
152 | return ((angle + 180) % 360); |
143 | return ((angle + 180) % 360); |
153 | } |
144 | } |
154 | |
145 | |
155 | int navigation_get_attr(struct navigation *this_, enum attr_type type, |
146 | int navigation_get_attr(struct navigation *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter) |
156 | struct attr *attr, struct attr_iter *iter) |
|
|
157 | { |
147 | { |
158 | struct map_rect *mr; |
148 | struct map_rect *mr; |
159 | struct item *item; |
149 | struct item *item; |
160 | dbg(1, "enter %s\n", attr_to_name(type)); |
150 | dbg(1, "enter %s\n", attr_to_name(type)); |
161 | switch (type) |
151 | switch (type) |
… | |
… | |
167 | case attr_length: |
157 | case attr_length: |
168 | case attr_navigation_speech: |
158 | case attr_navigation_speech: |
169 | mr = map_rect_new(this_->map, NULL); |
159 | mr = map_rect_new(this_->map, NULL); |
170 | while ((item = map_rect_get_item(mr))) |
160 | while ((item = map_rect_get_item(mr))) |
171 | { |
161 | { |
172 | if (item->type != type_nav_none && item->type |
162 | if (item->type != type_nav_none && item->type != type_nav_position) |
173 | != type_nav_position) |
|
|
174 | { |
163 | { |
175 | if (type == attr_item_type) |
164 | if (type == attr_item_type) |
176 | attr->u.item_type = item->type; |
165 | attr->u.item_type = item->type; |
177 | else |
166 | else |
178 | { |
167 | { |
… | |
… | |
238 | } |
227 | } |
239 | |
228 | |
240 | return ret; |
229 | return ret; |
241 | } |
230 | } |
242 | |
231 | |
243 | int navigation_set_announce(struct navigation *this_, enum item_type type, |
232 | int navigation_set_announce(struct navigation *this_, enum item_type type, int *level) |
244 | int *level) |
|
|
245 | { |
233 | { |
246 | int i; |
234 | int i; |
247 | if (type < route_item_first || type > route_item_last) |
235 | if (type < route_item_first || type > route_item_last) |
248 | { |
236 | { |
249 | dbg(0, "street type %d out of range [%d,%d]", type, route_item_first, |
237 | dbg(0, "street type %d out of range [%d,%d]", type, route_item_first, route_item_last); |
250 | route_item_last); |
|
|
251 | return 0; |
238 | return 0; |
252 | } |
239 | } |
253 | for (i = 0; i < 3; i++) |
240 | for (i = 0; i < 3; i++) |
254 | this_->announce[type - route_item_first][i] = level[i]; |
241 | this_->announce[type - route_item_first][i] = level[i]; |
255 | return 1; |
242 | return 1; |
256 | } |
243 | } |
257 | |
244 | |
258 | static int navigation_get_announce_level(struct navigation *this_, |
245 | static int navigation_get_announce_level(struct navigation *this_, enum item_type type, int dist) |
259 | enum item_type type, int dist) |
|
|
260 | { |
246 | { |
261 | int i; |
247 | int i; |
262 | |
248 | |
263 | if (type < route_item_first || type > route_item_last) |
249 | if (type < route_item_first || type > route_item_last) |
264 | return -1; |
250 | return -1; |
… | |
… | |
299 | int dest_count; |
285 | int dest_count; |
300 | struct navigation_itm *next; |
286 | struct navigation_itm *next; |
301 | struct navigation_itm *prev; |
287 | struct navigation_itm *prev; |
302 | }; |
288 | }; |
303 | |
289 | |
304 | static int is_way_allowed(struct navigation *nav, struct navigation_way *way, |
290 | static int is_way_allowed(struct navigation *nav, struct navigation_way *way, int mode); |
305 | int mode); |
|
|
306 | |
291 | |
307 | static int navigation_get_announce_level_cmd(struct navigation *this_, |
292 | static int navigation_get_announce_level_cmd(struct navigation *this_, struct navigation_itm *itm, struct navigation_command *cmd, int distance) |
308 | struct navigation_itm *itm, struct navigation_command *cmd, |
|
|
309 | int distance) |
|
|
310 | { |
293 | { |
311 | int level2, level = navigation_get_announce_level(this_, |
294 | int level2, level = navigation_get_announce_level(this_, itm->way.item.type, distance); |
312 | itm->way.item.type, distance); |
|
|
313 | if (this_->cmd_first->itm->prev) |
295 | if (this_->cmd_first->itm->prev) |
314 | { |
296 | { |
315 | level2 = navigation_get_announce_level(this_, |
297 | level2 = navigation_get_announce_level(this_, cmd->itm->prev->way.item.type, distance); |
316 | cmd->itm->prev->way.item.type, distance); |
|
|
317 | if (level2 > level) |
298 | if (level2 > level) |
318 | level = level2; |
299 | level = level2; |
319 | } |
300 | } |
320 | return level; |
301 | return level; |
321 | } |
302 | } |
… | |
… | |
579 | i++; |
560 | i++; |
580 | return distances[i - 1]; |
561 | return distances[i - 1]; |
581 | } |
562 | } |
582 | |
563 | |
583 | static char * |
564 | static char * |
584 | get_distance(struct navigation *nav, int dist, enum attr_type type, |
565 | get_distance(struct navigation *nav, int dist, enum attr_type type, int is_length) |
585 | int is_length) |
|
|
586 | { |
566 | { |
587 | int imperial = 0, vocabulary = 65535; |
567 | int imperial = 0, vocabulary = 65535; |
588 | struct attr attr; |
568 | struct attr attr; |
589 | |
569 | |
590 | if (type == attr_navigation_long) |
570 | if (type == attr_navigation_long) |
… | |
… | |
608 | return g_strdup_printf(_("in %d m"), dist); |
588 | return g_strdup_printf(_("in %d m"), dist); |
609 | } |
589 | } |
610 | } |
590 | } |
611 | if (navit_get_attr(nav->navit, attr_imperial, &attr, NULL)) |
591 | if (navit_get_attr(nav->navit, attr_imperial, &attr, NULL)) |
612 | imperial = attr.u.num; |
592 | imperial = attr.u.num; |
613 | if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_distances, |
593 | if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_distances, &attr, NULL)) |
614 | &attr, NULL)) |
|
|
615 | vocabulary = attr.u.num; |
594 | vocabulary = attr.u.num; |
616 | if (imperial) |
595 | if (imperial) |
617 | { |
596 | { |
618 | if (dist * FEET_PER_METER < vocabulary_last(vocabulary)) |
597 | if (dist * FEET_PER_METER < vocabulary_last(vocabulary)) |
619 | { |
598 | { |
… | |
… | |
669 | } |
648 | } |
670 | } |
649 | } |
671 | } |
650 | } |
672 | if (imperial) |
651 | if (imperial) |
673 | { |
652 | { |
674 | dist = round_for_vocabulary(vocabulary, |
653 | dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER * 1000 / FEET_PER_MILE, 1000); |
675 | dist * FEET_PER_METER * 1000 / FEET_PER_MILE, 1000); |
|
|
676 | } |
654 | } |
677 | else |
655 | else |
678 | { |
656 | { |
679 | dist = round_for_vocabulary(vocabulary, dist, 1000); |
657 | dist = round_for_vocabulary(vocabulary, dist, 1000); |
680 | } |
658 | } |
… | |
… | |
700 | #ifdef HAVE_API_ANDROID |
678 | #ifdef HAVE_API_ANDROID |
701 | #ifdef NAVIT_SAY_DEBUG_PRINT |
679 | #ifdef NAVIT_SAY_DEBUG_PRINT |
702 | android_send_generic_text(1,"+*#O:in %d.%d miles\n"); |
680 | android_send_generic_text(1,"+*#O:in %d.%d miles\n"); |
703 | #endif |
681 | #endif |
704 | #endif |
682 | #endif |
705 | return g_strdup_printf(_("in %d.%d miles"), dist / 1000, |
683 | return g_strdup_printf(_("in %d.%d miles"), dist / 1000, rem); |
706 | rem); |
|
|
707 | } |
684 | } |
708 | } |
685 | } |
709 | else |
686 | else |
710 | { |
687 | { |
711 | if (is_length) |
688 | if (is_length) |
… | |
… | |
713 | #ifdef HAVE_API_ANDROID |
690 | #ifdef HAVE_API_ANDROID |
714 | #ifdef NAVIT_SAY_DEBUG_PRINT |
691 | #ifdef NAVIT_SAY_DEBUG_PRINT |
715 | android_send_generic_text(1,"+*#O:%d.%d kilometers\n"); |
692 | android_send_generic_text(1,"+*#O:%d.%d kilometers\n"); |
716 | #endif |
693 | #endif |
717 | #endif |
694 | #endif |
718 | return g_strdup_printf(_("%d.%d kilometers"), dist / 1000, |
695 | return g_strdup_printf(_("%d.%d kilometers"), dist / 1000, rem); |
719 | rem); |
|
|
720 | } |
696 | } |
721 | else |
697 | else |
722 | { |
698 | { |
723 | #ifdef HAVE_API_ANDROID |
699 | #ifdef HAVE_API_ANDROID |
724 | #ifdef NAVIT_SAY_DEBUG_PRINT |
700 | #ifdef NAVIT_SAY_DEBUG_PRINT |
725 | android_send_generic_text(1,"+*#O:in %d.%d kilometers\n"); |
701 | android_send_generic_text(1,"+*#O:in %d.%d kilometers\n"); |
726 | #endif |
702 | #endif |
727 | #endif |
703 | #endif |
728 | return g_strdup_printf(_("in %d.%d kilometers"), |
704 | return g_strdup_printf(_("in %d.%d kilometers"), dist / 1000, rem); |
729 | dist / 1000, rem); |
|
|
730 | } |
705 | } |
731 | } |
706 | } |
732 | } |
707 | } |
733 | } |
708 | } |
734 | if (imperial) |
709 | if (imperial) |
735 | { |
710 | { |
736 | if (is_length) |
711 | if (is_length) |
737 | return g_strdup_printf( |
|
|
738 | ngettext("one mile", "%d miles", dist / 1000), dist / 1000); |
712 | return g_strdup_printf(ngettext("one mile", "%d miles", dist / 1000), dist / 1000); |
739 | else |
713 | else |
740 | return g_strdup_printf( |
714 | return g_strdup_printf(ngettext("in one mile", "in %d miles", dist / 1000), dist / 1000); |
741 | ngettext("in one mile", "in %d miles", dist / 1000), |
|
|
742 | dist / 1000); |
|
|
743 | } |
715 | } |
744 | else |
716 | else |
745 | { |
717 | { |
746 | if (is_length) |
718 | if (is_length) |
747 | { |
719 | { |
748 | #ifdef HAVE_API_ANDROID |
720 | #ifdef HAVE_API_ANDROID |
749 | #ifdef NAVIT_SAY_DEBUG_PRINT |
721 | #ifdef NAVIT_SAY_DEBUG_PRINT |
750 | android_send_generic_text(1,"+*#O:one kilometer|%d kilometers\n"); |
722 | android_send_generic_text(1,"+*#O:one kilometer|%d kilometers\n"); |
751 | #endif |
723 | #endif |
752 | #endif |
724 | #endif |
753 | return g_strdup_printf( |
|
|
754 | ngettext("one kilometer", "%d kilometers", dist / 1000), |
725 | return g_strdup_printf(ngettext("one kilometer", "%d kilometers", dist / 1000), dist / 1000); |
755 | dist / 1000); |
|
|
756 | } |
726 | } |
757 | else |
727 | else |
758 | { |
728 | { |
759 | #ifdef HAVE_API_ANDROID |
729 | #ifdef HAVE_API_ANDROID |
760 | #ifdef NAVIT_SAY_DEBUG_PRINT |
730 | #ifdef NAVIT_SAY_DEBUG_PRINT |
761 | android_send_generic_text(1,"+*#O:in one kilometer|in %d kilometers\n"); |
731 | android_send_generic_text(1,"+*#O:in one kilometer|in %d kilometers\n"); |
762 | #endif |
732 | #endif |
763 | #endif |
733 | #endif |
764 | return g_strdup_printf( |
734 | return g_strdup_printf(ngettext("in one kilometer", "in %d kilometers", dist / 1000), dist / 1000); |
765 | ngettext("in one kilometer", "in %d kilometers", |
|
|
766 | dist / 1000), dist / 1000); |
|
|
767 | } |
735 | } |
768 | } |
736 | } |
769 | } |
737 | } |
770 | |
738 | |
771 | /** |
739 | /** |
… | |
… | |
821 | |
789 | |
822 | if (w->dir < 0) |
790 | if (w->dir < 0) |
823 | { |
791 | { |
824 | if (item_coord_get(ritem, cbuf, 2) != 2) |
792 | if (item_coord_get(ritem, cbuf, 2) != 2) |
825 | { |
793 | { |
826 | dbg(1, |
|
|
827 | "Using calculate_angle() with a less-than-two-coords-item?\n"); |
794 | dbg(1, "Using calculate_angle() with a less-than-two-coords-item?\n"); |
828 | map_rect_destroy(mr); |
795 | map_rect_destroy(mr); |
829 | return; |
796 | return; |
830 | } |
797 | } |
831 | |
798 | |
832 | while (item_coord_get(ritem, &c, 1)) |
799 | while (item_coord_get(ritem, &c, 1)) |
… | |
… | |
838 | } |
805 | } |
839 | else |
806 | else |
840 | { |
807 | { |
841 | if (item_coord_get(ritem, cbuf, 2) != 2) |
808 | if (item_coord_get(ritem, cbuf, 2) != 2) |
842 | { |
809 | { |
843 | dbg(1, |
|
|
844 | "Using calculate_angle() with a less-than-two-coords-item?\n"); |
810 | dbg(1, "Using calculate_angle() with a less-than-two-coords-item?\n"); |
845 | map_rect_destroy(mr); |
811 | map_rect_destroy(mr); |
846 | return; |
812 | return; |
847 | } |
813 | } |
848 | c = cbuf[0]; |
814 | c = cbuf[0]; |
849 | cbuf[0] = cbuf[1]; |
815 | cbuf[0] = cbuf[1]; |
… | |
… | |
863 | * |
829 | * |
864 | * @param from The first item |
830 | * @param from The first item |
865 | * @param to The last item |
831 | * @param to The last item |
866 | * @return The travel time in seconds, or -1 on error |
832 | * @return The travel time in seconds, or -1 on error |
867 | */ |
833 | */ |
868 | static int navigation_time(struct navigation_itm *from, |
834 | static int navigation_time(struct navigation_itm *from, struct navigation_itm *to) |
869 | struct navigation_itm *to) |
|
|
870 | { |
835 | { |
871 | struct navigation_itm *cur; |
836 | struct navigation_itm *cur; |
872 | int time; |
837 | int time; |
873 | |
838 | |
874 | time = 0; |
839 | time = 0; |
… | |
… | |
921 | * and the next navigation item are excluded. |
886 | * and the next navigation item are excluded. |
922 | * |
887 | * |
923 | * @param itm The item that should be updated |
888 | * @param itm The item that should be updated |
924 | * @param graph_map The route graph's map that these items are on |
889 | * @param graph_map The route graph's map that these items are on |
925 | */ |
890 | */ |
926 | static void navigation_itm_ways_update(struct navigation_itm *itm, |
891 | static void navigation_itm_ways_update(struct navigation_itm *itm, struct map *graph_map) |
927 | struct map *graph_map) |
|
|
928 | { |
892 | { |
929 | struct map_selection coord_sel; |
893 | struct map_selection coord_sel; |
930 | struct map_rect *g_rect; // Contains a map rectangle from the route graph's map |
894 | struct map_rect *g_rect; // Contains a map rectangle from the route graph's map |
931 | struct item *i, *sitem; |
895 | struct item *i, *sitem; |
932 | struct attr sitem_attr, direction_attr; |
896 | struct attr sitem_attr, direction_attr; |
… | |
… | |
964 | continue; |
928 | continue; |
965 | } |
929 | } |
966 | |
930 | |
967 | if (!item_attr_get(i, attr_street_item, &sitem_attr)) |
931 | if (!item_attr_get(i, attr_street_item, &sitem_attr)) |
968 | { |
932 | { |
969 | dbg(1, |
|
|
970 | "Got no street item for route graph item in entering_straight()\n"); |
933 | dbg(1, "Got no street item for route graph item in entering_straight()\n"); |
971 | continue; |
934 | continue; |
972 | } |
935 | } |
973 | |
936 | |
974 | if (!item_attr_get(i, attr_direction, &direction_attr)) |
937 | if (!item_attr_get(i, attr_direction, &direction_attr)) |
975 | { |
938 | { |
976 | continue; |
939 | continue; |
977 | } |
940 | } |
978 | |
941 | |
979 | sitem = sitem_attr.u.item; |
942 | sitem = sitem_attr.u.item; |
980 | if (sitem->type == type_street_turn_restriction_no || sitem->type |
943 | if (sitem->type == type_street_turn_restriction_no || sitem->type == type_street_turn_restriction_only) |
981 | == type_street_turn_restriction_only) |
|
|
982 | continue; |
944 | continue; |
983 | |
945 | |
984 | if (item_is_equal(itm->way.item, *sitem) || ((itm->prev) |
946 | if (item_is_equal(itm->way.item, *sitem) || ((itm->prev) && item_is_equal(itm->prev->way.item, *sitem))) |
985 | && item_is_equal(itm->prev->way.item, *sitem))) |
|
|
986 | { |
947 | { |
987 | continue; |
948 | continue; |
988 | } |
949 | } |
989 | |
950 | |
990 | l = w; |
951 | l = w; |
… | |
… | |
998 | map_rect_destroy(g_rect); |
959 | map_rect_destroy(g_rect); |
999 | |
960 | |
1000 | itm->way.next = w; |
961 | itm->way.next = w; |
1001 | } |
962 | } |
1002 | |
963 | |
1003 | static void navigation_destroy_itms_cmds(struct navigation *this_, |
964 | static void navigation_destroy_itms_cmds(struct navigation *this_, struct navigation_itm *end) |
1004 | struct navigation_itm *end) |
|
|
1005 | { |
965 | { |
1006 | struct navigation_itm *itm; |
966 | struct navigation_itm *itm; |
1007 | struct navigation_command *cmd; |
967 | struct navigation_command *cmd; |
1008 | // dbg(2, "enter this_=%p this_->first=%p this_->cmd_first=%p end=%p\n", this_, this_->first, this_->cmd_first, end); |
968 | // dbg(2, "enter this_=%p this_->first=%p this_->cmd_first=%p end=%p\n", this_, this_->first, this_->cmd_first, end); |
1009 | if (this_->cmd_first) |
969 | if (this_->cmd_first) |
… | |
… | |
1040 | // dbg(0, "end wrong\n"); |
1000 | // dbg(0, "end wrong\n"); |
1041 | } |
1001 | } |
1042 | // dbg(2, "ret this_->first=%p this_->cmd_first=%p\n", this_->first, this_->cmd_first); |
1002 | // dbg(2, "ret this_->first=%p this_->cmd_first=%p\n", this_->first, this_->cmd_first); |
1043 | } |
1003 | } |
1044 | |
1004 | |
1045 | static void navigation_itm_update(struct navigation_itm *itm, |
1005 | static void navigation_itm_update(struct navigation_itm *itm, struct item *ritem) |
1046 | struct item *ritem) |
|
|
1047 | { |
1006 | { |
1048 | struct attr length, time, speed; |
1007 | struct attr length, time, speed; |
1049 | |
1008 | |
1050 | if (!item_attr_get(ritem, attr_length, &length)) |
1009 | if (!item_attr_get(ritem, attr_length, &length)) |
1051 | { |
1010 | { |
… | |
… | |
1117 | } |
1076 | } |
1118 | |
1077 | |
1119 | sitem = sitem_attr.u.item; |
1078 | sitem = sitem_attr.u.item; |
1120 | if (item_is_equal(itm->way.item, *sitem)) |
1079 | if (item_is_equal(itm->way.item, *sitem)) |
1121 | { |
1080 | { |
1122 | if (item_attr_get(i, attr_flags, &flags_attr) && (flags_attr.u.num |
1081 | if (item_attr_get(i, attr_flags, &flags_attr) && (flags_attr.u.num & AF_ROUNDABOUT)) |
1123 | & AF_ROUNDABOUT)) |
|
|
1124 | { |
1082 | { |
1125 | map_rect_destroy(g_rect); |
1083 | map_rect_destroy(g_rect); |
1126 | return 1; |
1084 | return 1; |
1127 | } |
1085 | } |
1128 | } |
1086 | } |
… | |
… | |
1233 | * @param from The navigation item which should form the start |
1191 | * @param from The navigation item which should form the start |
1234 | * @param to The navigation item which should form the end |
1192 | * @param to The navigation item which should form the end |
1235 | * @param direction Set to < 0 to count turns to the left >= 0 for turns to the right |
1193 | * @param direction Set to < 0 to count turns to the left >= 0 for turns to the right |
1236 | * @return The number of possibilities to turn or -1 on error |
1194 | * @return The number of possibilities to turn or -1 on error |
1237 | */ |
1195 | */ |
1238 | static int count_possible_turns(struct navigation *nav, |
1196 | static int count_possible_turns(struct navigation *nav, struct navigation_itm *from, struct navigation_itm *to, int direction) |
1239 | struct navigation_itm *from, struct navigation_itm *to, int direction) |
|
|
1240 | { |
1197 | { |
1241 | int count; |
1198 | int count; |
1242 | struct navigation_itm *curr; |
1199 | struct navigation_itm *curr; |
1243 | struct navigation_way *w; |
1200 | struct navigation_way *w; |
1244 | |
1201 | |
… | |
… | |
1340 | * |
1297 | * |
1341 | * @param old The first item to be checked |
1298 | * @param old The first item to be checked |
1342 | * @param new The second item to be checked |
1299 | * @param new The second item to be checked |
1343 | * @return True if both old and new are on the same street |
1300 | * @return True if both old and new are on the same street |
1344 | */ |
1301 | */ |
1345 | static int is_same_street2(char *old_name1, char *old_name2, char *new_name1, |
1302 | static int is_same_street2(char *old_name1, char *old_name2, char *new_name1, char *new_name2) |
1346 | char *new_name2) |
|
|
1347 | { |
1303 | { |
1348 | if (old_name1 && new_name1 && !strcmp(old_name1, new_name1)) |
1304 | if (old_name1 && new_name1 && !strcmp(old_name1, new_name1)) |
1349 | { |
1305 | { |
1350 | // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' yes (1.)\n", old_name2, new_name2, old_name1, new_name1); |
1306 | // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' yes (1.)\n", old_name2, new_name2, old_name1, new_name1); |
1351 | return 1; |
1307 | return 1; |
… | |
… | |
1478 | return 0; |
1434 | return 0; |
1479 | } |
1435 | } |
1480 | |
1436 | |
1481 | } |
1437 | } |
1482 | |
1438 | |
1483 | static int is_way_allowed(struct navigation *nav, struct navigation_way *way, |
1439 | static int is_way_allowed(struct navigation *nav, struct navigation_way *way, int mode) |
1484 | int mode) |
|
|
1485 | { |
1440 | { |
1486 | if (!nav->vehicleprofile) |
1441 | if (!nav->vehicleprofile) |
1487 | { |
1442 | { |
1488 | return 1; |
1443 | return 1; |
1489 | } |
1444 | } |
1490 | return !way->flags || ((way->flags |
1445 | return !way->flags || ((way->flags & (way->dir >= 0 ? nav->vehicleprofile->flags_forward_mask : nav->vehicleprofile->flags_reverse_mask)) == nav->vehicleprofile->flags); |
1491 | & (way->dir >= 0 ? nav->vehicleprofile->flags_forward_mask |
|
|
1492 | : nav->vehicleprofile->flags_reverse_mask)) |
|
|
1493 | == nav->vehicleprofile->flags); |
|
|
1494 | } |
1446 | } |
1495 | |
1447 | |
1496 | /** |
1448 | /** |
1497 | * @brief Checks if navit has to create a maneuver to drive from old to new |
1449 | * @brief Checks if navit has to create a maneuver to drive from old to new |
1498 | * |
1450 | * |
… | |
… | |
1503 | * @param new The new navigation item, where we're going to |
1455 | * @param new The new navigation item, where we're going to |
1504 | * @param delta The angle the user has to steer to navigate from old to new |
1456 | * @param delta The angle the user has to steer to navigate from old to new |
1505 | * @param reason A text string explaining how the return value resulted |
1457 | * @param reason A text string explaining how the return value resulted |
1506 | * @return True if navit should guide the user, false otherwise |
1458 | * @return True if navit should guide the user, false otherwise |
1507 | */ |
1459 | */ |
1508 | static int maneuver_required2(struct navigation *nav, |
1460 | static int maneuver_required2(struct navigation *nav, struct navigation_itm *old, struct navigation_itm *new, int *delta, char **reason) |
1509 | struct navigation_itm *old, struct navigation_itm *new, int *delta, |
|
|
1510 | char **reason) |
|
|
1511 | { |
1461 | { |
1512 | int ret = 0, d, dw, dlim; |
1462 | int ret = 0, d, dw, dlim; |
1513 | char *r = NULL; |
1463 | char *r = NULL; |
1514 | struct navigation_way *w; |
1464 | struct navigation_way *w; |
1515 | int cat, ncat, wcat, maxcat, left = -180, right = 180, is_unambigous = 0, |
1465 | int cat, ncat, wcat, maxcat, left = -180, right = 180, is_unambigous = 0, is_same_street; |
1516 | is_same_street; |
|
|
1517 | |
1466 | |
1518 | //dbg(1, "enter %p %p %p\n", old, new, delta); |
1467 | //dbg(1, "enter %p %p %p\n", old, new, delta); |
1519 | d = angle_delta(old->angle_end, new->way.angle2); |
1468 | d = angle_delta(old->angle_end, new->way.angle2); |
1520 | if (!new->way.next) |
1469 | if (!new->way.next) |
1521 | { |
1470 | { |
1522 | /* No announcement necessary */ |
1471 | /* No announcement necessary */ |
1523 | r = "no: Only one possibility"; |
1472 | r = "no: Only one possibility"; |
1524 | } |
1473 | } |
1525 | else if (!new->way.next->next && new->way.next->item.type == type_ramp |
1474 | else if (!new->way.next->next && new->way.next->item.type == type_ramp && !is_way_allowed(nav, new->way.next, 1)) |
1526 | && !is_way_allowed(nav, new->way.next, 1)) |
|
|
1527 | { |
1475 | { |
1528 | /* If the other way is only a ramp and it is one-way in the wrong direction, no announcement necessary */ |
1476 | /* If the other way is only a ramp and it is one-way in the wrong direction, no announcement necessary */ |
1529 | r = "no: Only ramp"; |
1477 | r = "no: Only ramp"; |
1530 | } |
1478 | } |
1531 | if (!r) |
1479 | if (!r) |
1532 | { |
1480 | { |
1533 | if ((old->way.flags & AF_ROUNDABOUT) && !(new->way.flags |
1481 | if ((old->way.flags & AF_ROUNDABOUT) && !(new->way.flags & AF_ROUNDABOUT)) |
1534 | & AF_ROUNDABOUT)) |
|
|
1535 | { |
1482 | { |
1536 | r = "yes: leaving roundabout"; |
1483 | r = "yes: leaving roundabout"; |
1537 | ret = 1; |
1484 | ret = 1; |
1538 | } |
1485 | } |
1539 | else if (!(old->way.flags & AF_ROUNDABOUT) && (new->way.flags |
1486 | else if (!(old->way.flags & AF_ROUNDABOUT) && (new->way.flags & AF_ROUNDABOUT)) |
1540 | & AF_ROUNDABOUT)) |
|
|
1541 | { |
1487 | { |
1542 | r = "no: entering roundabout"; |
1488 | r = "no: entering roundabout"; |
1543 | } |
1489 | } |
1544 | else if ((old->way.flags & AF_ROUNDABOUT) && (new->way.flags |
1490 | else if ((old->way.flags & AF_ROUNDABOUT) && (new->way.flags & AF_ROUNDABOUT)) |
1545 | & AF_ROUNDABOUT)) |
|
|
1546 | r = "no: staying in roundabout"; |
1491 | r = "no: staying in roundabout"; |
1547 | } |
1492 | } |
1548 | if (!r && abs(d) > 75) |
1493 | if (!r && abs(d) > 75) |
1549 | { |
1494 | { |
1550 | /* always make an announcement if you have to make a sharp turn */ |
1495 | /* always make an announcement if you have to make a sharp turn */ |
… | |
… | |
1554 | cat = maneuver_category(old->way.item.type); |
1499 | cat = maneuver_category(old->way.item.type); |
1555 | ncat = maneuver_category(new->way.item.type); |
1500 | ncat = maneuver_category(new->way.item.type); |
1556 | if (!r) |
1501 | if (!r) |
1557 | { |
1502 | { |
1558 | /* Check whether the street keeps its name */ |
1503 | /* Check whether the street keeps its name */ |
1559 | is_same_street = is_same_street2(old->way.name1, old->way.name2, |
1504 | is_same_street = is_same_street2(old->way.name1, old->way.name2, new->way.name1, new->way.name2); |
1560 | new->way.name1, new->way.name2); |
|
|
1561 | w = new->way.next; |
1505 | w = new->way.next; |
1562 | maxcat = -1; |
1506 | maxcat = -1; |
1563 | while (w) |
1507 | while (w) |
1564 | { |
1508 | { |
1565 | dw = angle_delta(old->angle_end, w->angle2); |
1509 | dw = angle_delta(old->angle_end, w->angle2); |
… | |
… | |
1574 | right = dw; |
1518 | right = dw; |
1575 | } |
1519 | } |
1576 | wcat = maneuver_category(w->item.type); |
1520 | wcat = maneuver_category(w->item.type); |
1577 | /* If any other street has the same name but isn't a highway (a highway might split up temporarily), then |
1521 | /* If any other street has the same name but isn't a highway (a highway might split up temporarily), then |
1578 | we can't use the same name criterium */ |
1522 | we can't use the same name criterium */ |
1579 | if (is_same_street && is_same_street2(old->way.name1, |
1523 | if (is_same_street && is_same_street2(old->way.name1, old->way.name2, w->name1, w->name2) && (cat != 7 || wcat != 7) && is_way_allowed(nav, w, 2)) |
1580 | old->way.name2, w->name1, w->name2) && (cat != 7 || wcat |
|
|
1581 | != 7) && is_way_allowed(nav, w, 2)) |
|
|
1582 | is_same_street = 0; |
1524 | is_same_street = 0; |
1583 | /* Even if the ramp has the same name, announce it */ |
1525 | /* Even if the ramp has the same name, announce it */ |
1584 | if (new->way.item.type == type_ramp && old->way.item.type |
1526 | if (new->way.item.type == type_ramp && old->way.item.type != type_ramp) |
1585 | != type_ramp) |
|
|
1586 | is_same_street = 0; |
1527 | is_same_street = 0; |
1587 | /* Mark if the street has a higher or the same category */ |
1528 | /* Mark if the street has a higher or the same category */ |
1588 | if (wcat > maxcat) |
1529 | if (wcat > maxcat) |
1589 | maxcat = wcat; |
1530 | maxcat = wcat; |
1590 | w = w->next; |
1531 | w = w->next; |
… | |
… | |
1727 | { |
1668 | { |
1728 | struct navigation_command *ret=g_new0(struct navigation_command, 1); |
1669 | struct navigation_command *ret=g_new0(struct navigation_command, 1); |
1729 | //dbg(1, "enter this_=%p itm=%p delta=%d\n", this_, itm, delta); |
1670 | //dbg(1, "enter this_=%p itm=%p delta=%d\n", this_, itm, delta); |
1730 | ret->delta = delta; |
1671 | ret->delta = delta; |
1731 | ret->itm = itm; |
1672 | ret->itm = itm; |
1732 | if (itm && itm->prev && itm->way.next && itm->prev->way.next |
1673 | if (itm && itm->prev && itm->way.next && itm->prev->way.next && !(itm->way.flags & AF_ROUNDABOUT) && (itm->prev->way.flags & AF_ROUNDABOUT)) |
1733 | && !(itm->way.flags & AF_ROUNDABOUT) && (itm->prev->way.flags |
|
|
1734 | & AF_ROUNDABOUT)) |
|
|
1735 | { |
1674 | { |
1736 | int len = 0; |
1675 | int len = 0; |
1737 | int angle = 0; |
1676 | int angle = 0; |
1738 | int entry_angle; |
1677 | int entry_angle; |
1739 | struct navigation_itm *itm2 = itm->prev; |
1678 | struct navigation_itm *itm2 = itm->prev; |
1740 | int exit_angle = angle_median(itm->prev->angle_end, |
1679 | int exit_angle = angle_median(itm->prev->angle_end, itm->way.next->angle2); |
1741 | itm->way.next->angle2); |
|
|
1742 | //dbg(1, "exit %d median from %d,%d\n", exit_angle, itm->prev->angle_end, itm->way.next->angle2); |
1680 | //dbg(1, "exit %d median from %d,%d\n", exit_angle, itm->prev->angle_end, itm->way.next->angle2); |
1743 | while (itm2 && (itm2->way.flags & AF_ROUNDABOUT)) |
1681 | while (itm2 && (itm2->way.flags & AF_ROUNDABOUT)) |
1744 | { |
1682 | { |
1745 | len += itm2->length; |
1683 | len += itm2->length; |
1746 | angle = itm2->angle_end; |
1684 | angle = itm2->angle_end; |
1747 | itm2 = itm2->prev; |
1685 | itm2 = itm2->prev; |
1748 | } |
1686 | } |
1749 | if (itm2 && itm2->next && itm2->next->way.next) |
1687 | if (itm2 && itm2->next && itm2->next->way.next) |
1750 | { |
1688 | { |
1751 | itm2 = itm2->next; |
1689 | itm2 = itm2->next; |
1752 | entry_angle = angle_median(angle_opposite(itm2->way.angle2), |
1690 | entry_angle = angle_median(angle_opposite(itm2->way.angle2), itm2->way.next->angle2); |
1753 | itm2->way.next->angle2); |
|
|
1754 | // dbg(1, "entry %d median from %d(%d),%d\n", entry_angle, angle_opposite(itm2->way.angle2), itm2->way.angle2, itm2->way.next->angle2); |
1691 | // dbg(1, "entry %d median from %d(%d),%d\n", entry_angle, angle_opposite(itm2->way.angle2), itm2->way.angle2, itm2->way.next->angle2); |
1755 | } |
1692 | } |
1756 | else |
1693 | else |
1757 | { |
1694 | { |
1758 | entry_angle = angle_opposite(angle); |
1695 | entry_angle = angle_opposite(angle); |
… | |
… | |
1820 | |
1757 | |
1821 | return ret; |
1758 | return ret; |
1822 | } |
1759 | } |
1823 | |
1760 | |
1824 | static char * |
1761 | static char * |
1825 | navigation_item_destination(struct navigation *nav, struct navigation_itm *itm, |
1762 | navigation_item_destination(struct navigation *nav, struct navigation_itm *itm, struct navigation_itm *next, char *prefix) |
1826 | struct navigation_itm *next, char *prefix) |
|
|
1827 | { |
1763 | { |
1828 | char *ret = NULL, *name1, *sep, *name2; |
1764 | char *ret = NULL, *name1, *sep, *name2; |
1829 | char *n1, *n2; |
1765 | char *n1, *n2; |
1830 | int i, sex; |
1766 | int i, sex; |
1831 | int vocabulary1 = 65535; |
1767 | int vocabulary1 = 65535; |
1832 | int vocabulary2 = 65535; |
1768 | int vocabulary2 = 65535; |
1833 | struct attr attr; |
1769 | struct attr attr; |
1834 | |
1770 | |
1835 | if (!prefix) |
1771 | if (!prefix) |
1836 | prefix = ""; |
1772 | prefix = ""; |
1837 | if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name, |
1773 | if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name, &attr, NULL)) |
1838 | &attr, NULL)) |
|
|
1839 | vocabulary1 = attr.u.num; |
1774 | vocabulary1 = attr.u.num; |
1840 | if (nav->speech && speech_get_attr(nav->speech, |
1775 | if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name_systematic, &attr, NULL)) |
1841 | attr_vocabulary_name_systematic, &attr, NULL)) |
|
|
1842 | vocabulary2 = attr.u.num; |
1776 | vocabulary2 = attr.u.num; |
1843 | n1 = itm->way.name1; |
1777 | n1 = itm->way.name1; |
1844 | n2 = itm->way.name2; |
1778 | n2 = itm->way.name2; |
1845 | if (!vocabulary1) |
1779 | if (!vocabulary1) |
1846 | n1 = NULL; |
1780 | n1 = NULL; |
… | |
… | |
1850 | { |
1784 | { |
1851 | //dbg(1,">> Next is ramp %lx current is %lx \n", itm->way.item.type, next->way.item.type); |
1785 | //dbg(1,">> Next is ramp %lx current is %lx \n", itm->way.item.type, next->way.item.type); |
1852 | |
1786 | |
1853 | if (next->way.item.type == type_ramp) |
1787 | if (next->way.item.type == type_ramp) |
1854 | return NULL; |
1788 | return NULL; |
1855 | if (itm->way.item.type == type_highway_city || itm->way.item.type |
1789 | if (itm->way.item.type == type_highway_city || itm->way.item.type == type_highway_land) |
1856 | == type_highway_land) |
|
|
1857 | { |
1790 | { |
1858 | #ifdef HAVE_API_ANDROID |
1791 | #ifdef HAVE_API_ANDROID |
1859 | #ifdef NAVIT_SAY_DEBUG_PRINT |
1792 | #ifdef NAVIT_SAY_DEBUG_PRINT |
1860 | android_send_generic_text(1,"+*#O:exit\n"); |
1793 | android_send_generic_text(1,"+*#O:exit\n"); |
1861 | gchar* xy=g_strdup_printf("+*#1:%s\n", prefix); |
1794 | gchar* xy=g_strdup_printf("+*#1:%s\n", prefix); |
… | |
… | |
1898 | break; |
1831 | break; |
1899 | } |
1832 | } |
1900 | if (contains_suffix(n1, suffixes[i].abbrev)) |
1833 | if (contains_suffix(n1, suffixes[i].abbrev)) |
1901 | { |
1834 | { |
1902 | sex = suffixes[i].sex; |
1835 | sex = suffixes[i].sex; |
1903 | name1 = replace_suffix(n1, suffixes[i].abbrev, |
1836 | name1 = replace_suffix(n1, suffixes[i].abbrev, suffixes[i].fullname); |
1904 | suffixes[i].fullname); |
|
|
1905 | break; |
1837 | break; |
1906 | } |
1838 | } |
1907 | } |
1839 | } |
1908 | |
1840 | |
1909 | if (n2) |
1841 | if (n2) |
… | |
… | |
1937 | android_send_generic_text(1,xy); |
1869 | android_send_generic_text(1,xy); |
1938 | g_free(xy); |
1870 | g_free(xy); |
1939 | #endif |
1871 | #endif |
1940 | #endif |
1872 | #endif |
1941 | // TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name |
1873 | // TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name |
1942 | ret = g_strdup_printf(_("%sinto the street %s%s%s"), prefix, |
1874 | ret = g_strdup_printf(_("%sinto the street %s%s%s"), prefix, n1, sep, name2); |
1943 | n1, sep, name2); |
|
|
1944 | break; |
1875 | break; |
1945 | case 1: |
1876 | case 1: |
1946 | #ifdef HAVE_API_ANDROID |
1877 | #ifdef HAVE_API_ANDROID |
1947 | #ifdef NAVIT_SAY_DEBUG_PRINT |
1878 | #ifdef NAVIT_SAY_DEBUG_PRINT |
1948 | android_send_generic_text(1,"+*#O:%sinto the %s%s%s|male form\n"); |
1879 | android_send_generic_text(1,"+*#O:%sinto the %s%s%s|male form\n"); |
… | |
… | |
1959 | android_send_generic_text(1,xy); |
1890 | android_send_generic_text(1,xy); |
1960 | g_free(xy); |
1891 | g_free(xy); |
1961 | #endif |
1892 | #endif |
1962 | #endif |
1893 | #endif |
1963 | // 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 |
1894 | // 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 |
1964 | ret = g_strdup_printf(_("%sinto the %s%s%s|male form"), prefix, |
1895 | ret = g_strdup_printf(_("%sinto the %s%s%s|male form"), prefix, name1, sep, name2); |
1965 | name1, sep, name2); |
|
|
1966 | break; |
1896 | break; |
1967 | case 2: |
1897 | case 2: |
1968 | #ifdef HAVE_API_ANDROID |
1898 | #ifdef HAVE_API_ANDROID |
1969 | #ifdef NAVIT_SAY_DEBUG_PRINT |
1899 | #ifdef NAVIT_SAY_DEBUG_PRINT |
1970 | android_send_generic_text(1,"+*#O:%sinto the %s%s%s|female form\n"); |
1900 | android_send_generic_text(1,"+*#O:%sinto the %s%s%s|female form\n"); |
… | |
… | |
1981 | android_send_generic_text(1,xy); |
1911 | android_send_generic_text(1,xy); |
1982 | g_free(xy); |
1912 | g_free(xy); |
1983 | #endif |
1913 | #endif |
1984 | #endif |
1914 | #endif |
1985 | // 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 |
1915 | // 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 |
1986 | ret = g_strdup_printf(_("%sinto the %s%s%s|female form"), |
1916 | ret = g_strdup_printf(_("%sinto the %s%s%s|female form"), prefix, name1, sep, name2); |
1987 | prefix, name1, sep, name2); |
|
|
1988 | break; |
1917 | break; |
1989 | case 3: |
1918 | case 3: |
1990 | #ifdef HAVE_API_ANDROID |
1919 | #ifdef HAVE_API_ANDROID |
1991 | #ifdef NAVIT_SAY_DEBUG_PRINT |
1920 | #ifdef NAVIT_SAY_DEBUG_PRINT |
1992 | android_send_generic_text(1,"+*#O:%sinto the %s%s%s|neutral form\n"); |
1921 | android_send_generic_text(1,"+*#O:%sinto the %s%s%s|neutral form\n"); |
… | |
… | |
2003 | android_send_generic_text(1,xy); |
1932 | android_send_generic_text(1,xy); |
2004 | g_free(xy); |
1933 | g_free(xy); |
2005 | #endif |
1934 | #endif |
2006 | #endif |
1935 | #endif |
2007 | // 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 |
1936 | // 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 |
2008 | ret = g_strdup_printf(_("%sinto the %s%s%s|neutral form"), |
1937 | ret = g_strdup_printf(_("%sinto the %s%s%s|neutral form"), prefix, name1, sep, name2); |
2009 | prefix, name1, sep, name2); |
|
|
2010 | break; |
1938 | break; |
2011 | } |
1939 | } |
2012 | g_free(name1); |
1940 | g_free(name1); |
2013 | |
1941 | |
2014 | } |
1942 | } |
… | |
… | |
2048 | |
1976 | |
2049 | return ret; |
1977 | return ret; |
2050 | } |
1978 | } |
2051 | |
1979 | |
2052 | static char * |
1980 | static char * |
2053 | show_maneuver(struct navigation *nav, struct navigation_itm *itm, |
1981 | show_maneuver(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type, int connect) |
2054 | struct navigation_command *cmd, enum attr_type type, int connect) |
|
|
2055 | { |
1982 | { |
2056 | // TRANSLATORS: right, as in 'Turn right' |
1983 | // TRANSLATORS: right, as in 'Turn right' |
2057 | char *dir = _("right"); |
1984 | char *dir = _("right"); |
2058 | char *strength = ""; |
1985 | char *strength = ""; |
2059 | int distance = itm->dest_length - cmd->itm->dest_length; |
1986 | int distance = itm->dest_length - cmd->itm->dest_length; |
… | |
… | |
2189 | return g_strdup(_("When possible, please turn around")); |
2116 | return g_strdup(_("When possible, please turn around")); |
2190 | } |
2117 | } |
2191 | |
2118 | |
2192 | if (!connect) |
2119 | if (!connect) |
2193 | { |
2120 | { |
2194 | level = navigation_get_announce_level_cmd(nav, itm, cmd, |
2121 | level = navigation_get_announce_level_cmd(nav, itm, cmd, distance - cmd->length); |
2195 | distance - cmd->length); |
|
|
2196 | } |
2122 | } |
2197 | // dbg(1,"distance=%d level=%d type=0x%x\n", distance, level, itm->way.item.type); |
2123 | // dbg(1,"distance=%d level=%d type=0x%x\n", distance, level, itm->way.item.type); |
2198 | } |
2124 | } |
2199 | |
2125 | |
2200 | if (cmd->itm->prev->way.flags & AF_ROUNDABOUT) |
2126 | if (cmd->itm->prev->way.flags & AF_ROUNDABOUT) |
… | |
… | |
2202 | cur = cmd->itm->prev; |
2128 | cur = cmd->itm->prev; |
2203 | count_roundabout = 0; |
2129 | count_roundabout = 0; |
2204 | while (cur && (cur->way.flags & AF_ROUNDABOUT)) |
2130 | while (cur && (cur->way.flags & AF_ROUNDABOUT)) |
2205 | { |
2131 | { |
2206 | // If the next segment has no exit or the exit isn't allowed, don't count it |
2132 | // If the next segment has no exit or the exit isn't allowed, don't count it |
2207 | if (cur->next->way.next && is_way_allowed(nav, cur->next->way.next, |
2133 | if (cur->next->way.next && is_way_allowed(nav, cur->next->way.next, 3)) |
2208 | 3)) |
|
|
2209 | { |
2134 | { |
2210 | count_roundabout++; |
2135 | count_roundabout++; |
2211 | } |
2136 | } |
2212 | cur = cur->prev; |
2137 | cur = cur->prev; |
2213 | } |
2138 | } |
… | |
… | |
2247 | android_send_generic_text(1,xy); |
2172 | android_send_generic_text(1,xy); |
2248 | g_free(xy); |
2173 | g_free(xy); |
2249 | #endif |
2174 | #endif |
2250 | #endif |
2175 | #endif |
2251 | // TRANSLATORS: EXAMPLE: ... then leave the roundabout at the second exit |
2176 | // TRANSLATORS: EXAMPLE: ... then leave the roundabout at the second exit |
2252 | return g_strdup_printf( |
2177 | return g_strdup_printf(_("then leave the roundabout at the %s"), get_exit_count_str(count_roundabout)); |
2253 | _("then leave the roundabout at the %s"), |
|
|
2254 | get_exit_count_str(count_roundabout)); |
|
|
2255 | case 0: |
2178 | case 0: |
2256 | #ifdef HAVE_API_ANDROID |
2179 | #ifdef HAVE_API_ANDROID |
2257 | #ifdef NAVIT_SAY_DEBUG_PRINT |
2180 | #ifdef NAVIT_SAY_DEBUG_PRINT |
2258 | android_send_generic_text(1,"+*#O:Leave the roundabout at the %s\n"); |
2181 | android_send_generic_text(1,"+*#O:Leave the roundabout at the %s\n"); |
2259 | xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout)); |
2182 | xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout)); |
2260 | android_send_generic_text(1,xy); |
2183 | android_send_generic_text(1,xy); |
2261 | g_free(xy); |
2184 | g_free(xy); |
2262 | #endif |
2185 | #endif |
2263 | #endif |
2186 | #endif |
2264 | // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit |
2187 | // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit |
2265 | return g_strdup_printf(_("Leave the roundabout at the %s"), |
2188 | return g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout)); |
2266 | get_exit_count_str(count_roundabout)); |
|
|
2267 | } |
2189 | } |
2268 | } |
2190 | } |
2269 | |
2191 | |
2270 | switch (level) |
2192 | switch (level) |
2271 | { |
2193 | { |
… | |
… | |
2294 | break; |
2216 | break; |
2295 | case 1: |
2217 | case 1: |
2296 | d = get_distance(nav, distance, attr_navigation_short, 0); |
2218 | d = get_distance(nav, distance, attr_navigation_short, 0); |
2297 | break; |
2219 | break; |
2298 | case 0: |
2220 | case 0: |
2299 | skip_roads = count_possible_turns(nav, |
2221 | skip_roads = count_possible_turns(nav, cmd->prev ? cmd->prev->itm : nav->first, cmd->itm, cmd->delta); |
2300 | cmd->prev ? cmd->prev->itm : nav->first, cmd->itm, |
|
|
2301 | cmd->delta); |
|
|
2302 | if (skip_roads > 0) |
2222 | if (skip_roads > 0) |
2303 | { |
2223 | { |
2304 | if (get_count_str(skip_roads + 1)) |
2224 | if (get_count_str(skip_roads + 1)) |
2305 | { |
2225 | { |
2306 | #ifdef HAVE_API_ANDROID |
2226 | #ifdef HAVE_API_ANDROID |
… | |
… | |
2313 | android_send_generic_text(1,xy); |
2233 | android_send_generic_text(1,xy); |
2314 | g_free(xy); |
2234 | g_free(xy); |
2315 | #endif |
2235 | #endif |
2316 | #endif |
2236 | #endif |
2317 | // TRANSLATORS: First argument is the how manieth street to take, second the direction |
2237 | // TRANSLATORS: First argument is the how manieth street to take, second the direction |
2318 | ret = g_strdup_printf(_("Take the %1$s road to the %2$s"), |
2238 | ret = g_strdup_printf(_("Take the %1$s road to the %2$s"), get_count_str(skip_roads + 1), dir); |
2319 | get_count_str(skip_roads + 1), dir); |
|
|
2320 | return ret; |
2239 | return ret; |
2321 | } |
2240 | } |
2322 | else |
2241 | else |
2323 | { |
2242 | { |
2324 | #ifdef HAVE_API_ANDROID |
2243 | #ifdef HAVE_API_ANDROID |
… | |
… | |
2341 | #endif |
2260 | #endif |
2342 | d = g_strdup(_("now")); |
2261 | d = g_strdup(_("now")); |
2343 | } |
2262 | } |
2344 | break; |
2263 | break; |
2345 | case -2: |
2264 | case -2: |
2346 | skip_roads = count_possible_turns(nav, cmd->prev->itm, cmd->itm, |
2265 | skip_roads = count_possible_turns(nav, cmd->prev->itm, cmd->itm, cmd->delta); |
2347 | cmd->delta); |
|
|
2348 | if (skip_roads > 0) |
2266 | if (skip_roads > 0) |
2349 | { |
2267 | { |
2350 | // TRANSLATORS: First argument is the how manieth street to take, second the direction |
2268 | // TRANSLATORS: First argument is the how manieth street to take, second the direction |
2351 | // TRANSLATORS: EXAMPLE: ... then take the second road to the right |
2269 | // TRANSLATORS: EXAMPLE: ... then take the second road to the right |
2352 | if (get_count_str(skip_roads + 1)) |
2270 | if (get_count_str(skip_roads + 1)) |
… | |
… | |
2360 | xy=g_strdup_printf("+*#1:%s\n", dir); |
2278 | xy=g_strdup_printf("+*#1:%s\n", dir); |
2361 | android_send_generic_text(1,xy); |
2279 | android_send_generic_text(1,xy); |
2362 | g_free(xy); |
2280 | g_free(xy); |
2363 | #endif |
2281 | #endif |
2364 | #endif |
2282 | #endif |
2365 | ret = g_strdup_printf( |
2283 | ret = g_strdup_printf(_("then take the %1$s road to the %2$s"), get_count_str(skip_roads + 1), dir); |
2366 | _("then take the %1$s road to the %2$s"), |
|
|
2367 | get_count_str(skip_roads + 1), dir); |
|
|
2368 | return ret; |
2284 | return ret; |
2369 | } |
2285 | } |
2370 | else |
2286 | else |
2371 | { |
2287 | { |
2372 | #ifdef HAVE_API_ANDROID |
2288 | #ifdef HAVE_API_ANDROID |
… | |
… | |
2458 | android_send_generic_text(1,xy); |
2374 | android_send_generic_text(1,xy); |
2459 | g_free(xy); |
2375 | g_free(xy); |
2460 | #endif |
2376 | #endif |
2461 | #endif |
2377 | #endif |
2462 | // 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' |
2378 | // TRANSLATORS: The first argument is strength, the second direction, the third distance and the fourth destination Example: 'Turn 'slightly' 'left' in '100 m' 'onto baker street' |
2463 | ret = g_strdup_printf(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, |
2379 | ret = g_strdup_printf(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : ""); |
2464 | d, destination ? destination : ""); |
|
|
2465 | } |
2380 | } |
2466 | else |
2381 | else |
2467 | { |
2382 | { |
2468 | #ifdef HAVE_API_ANDROID |
2383 | #ifdef HAVE_API_ANDROID |
2469 | #ifdef NAVIT_SAY_DEBUG_PRINT |
2384 | #ifdef NAVIT_SAY_DEBUG_PRINT |
… | |
… | |
2481 | android_send_generic_text(1,xy); |
2396 | android_send_generic_text(1,xy); |
2482 | g_free(xy); |
2397 | g_free(xy); |
2483 | #endif |
2398 | #endif |
2484 | #endif |
2399 | #endif |
2485 | // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination |
2400 | // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination |
2486 | ret = g_strdup_printf(_("then turn %1$s%2$s %3$s%4$s"), strength, |
2401 | ret = g_strdup_printf(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination : ""); |
2487 | dir, d, destination ? destination : ""); |
|
|
2488 | } |
2402 | } |
2489 | g_free(destination); |
2403 | g_free(destination); |
2490 | } |
2404 | } |
2491 | else |
2405 | else |
2492 | { |
2406 | { |
… | |
… | |
2524 | * immediately following that maneuver, if these are too close and we're in speech navigation. |
2438 | * immediately following that maneuver, if these are too close and we're in speech navigation. |
2525 | * |
2439 | * |
2526 | * @return An announcement that should be made |
2440 | * @return An announcement that should be made |
2527 | */ |
2441 | */ |
2528 | static char * |
2442 | static char * |
2529 | show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm, |
2443 | show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type) |
2530 | struct navigation_command *cmd, enum attr_type type) |
|
|
2531 | { |
2444 | { |
2532 | struct navigation_command *cur, *prev; |
2445 | struct navigation_command *cur, *prev; |
2533 | int distance = itm->dest_length - cmd->itm->dest_length; |
2446 | int distance = itm->dest_length - cmd->itm->dest_length; |
2534 | int level, dist, i, time; |
2447 | int level, dist, i, time; |
2535 | int speech_time, time2nav; |
2448 | int speech_time, time2nav; |
… | |
… | |
2538 | if (type != attr_navigation_speech) |
2451 | if (type != attr_navigation_speech) |
2539 | { |
2452 | { |
2540 | return show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only in speech navigation |
2453 | return show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only in speech navigation |
2541 | } |
2454 | } |
2542 | |
2455 | |
2543 | level = navigation_get_announce_level(nav, itm->way.item.type, |
2456 | level = navigation_get_announce_level(nav, itm->way.item.type, distance - cmd->length); |
2544 | distance - cmd->length); |
|
|
2545 | |
2457 | |
2546 | if (level > 1) |
2458 | if (level > 1) |
2547 | { |
2459 | { |
2548 | return show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only if they are close |
2460 | return show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only if they are close |
2549 | } |
2461 | } |
… | |
… | |
2600 | old = ret; |
2512 | old = ret; |
2601 | buf = show_maneuver(nav, prev->itm, cur, type, 1); |
2513 | buf = show_maneuver(nav, prev->itm, cur, type, 1); |
2602 | ret = g_strdup_printf("%s, %s", old, buf); |
2514 | ret = g_strdup_printf("%s, %s", old, buf); |
2603 | g_free(buf); |
2515 | g_free(buf); |
2604 | |
2516 | |
2605 | if (nav->speech && speech_estimate_duration(nav->speech, ret) |
2517 | if (nav->speech && speech_estimate_duration(nav->speech, ret) > time2nav) |
2606 | > time2nav) |
|
|
2607 | { |
2518 | { |
2608 | g_free(ret); |
2519 | g_free(ret); |
2609 | ret = old; |
2520 | ret = old; |
2610 | i = 2; // This will terminate the loop |
2521 | i = 2; // This will terminate the loop |
2611 | } |
2522 | } |
… | |
… | |
2631 | } |
2542 | } |
2632 | |
2543 | |
2633 | return ret; |
2544 | return ret; |
2634 | } |
2545 | } |
2635 | |
2546 | |
2636 | static void navigation_call_callbacks(struct navigation *this_, |
2547 | static void navigation_call_callbacks(struct navigation *this_, int force_speech) |
2637 | int force_speech) |
|
|
2638 | { |
2548 | { |
2639 | int distance, level = 0; |
2549 | int distance, level = 0; |
2640 | void *p = this_; |
2550 | void *p = this_; |
|
|
2551 | |
2641 | if (!this_->cmd_first) |
2552 | if (!this_->cmd_first) |
|
|
2553 | { |
2642 | return; |
2554 | return; |
|
|
2555 | } |
|
|
2556 | |
2643 | callback_list_call(this_->callback, 1, &p); |
2557 | callback_list_call(this_->callback, 1, &p); |
2644 | //dbg(1,"force_speech=%d turn_around=%d turn_around_limit=%d\n", force_speech, this_->turn_around, this_->turn_around_limit); |
2558 | //dbg(1,"force_speech=%d turn_around=%d turn_around_limit=%d\n", force_speech, this_->turn_around, this_->turn_around_limit); |
2645 | distance = round_distance( |
|
|
2646 | this_->first->dest_length - this_->cmd_first->itm->dest_length); |
2559 | distance = round_distance(this_->first->dest_length - this_->cmd_first->itm->dest_length); |
2647 | if (this_->turn_around_limit && this_->turn_around |
2560 | if (this_->turn_around_limit && this_->turn_around == this_->turn_around_limit) |
2648 | == this_->turn_around_limit) |
|
|
2649 | { |
2561 | { |
2650 | //dbg(1,"distance=%d distance_turn=%d\n", distance, this_->distance_turn); |
2562 | //dbg(1,"distance=%d distance_turn=%d\n", distance, this_->distance_turn); |
2651 | while (distance > this_->distance_turn) |
2563 | while (distance > this_->distance_turn) |
2652 | { |
2564 | { |
2653 | this_->level_last = 4; |
2565 | this_->level_last = 4; |
… | |
… | |
2657 | this_->distance_turn *= 2; |
2569 | this_->distance_turn *= 2; |
2658 | else |
2570 | else |
2659 | this_->distance_turn = 500; |
2571 | this_->distance_turn = 500; |
2660 | } |
2572 | } |
2661 | } |
2573 | } |
2662 | else if (!this_->turn_around_limit || this_->turn_around |
2574 | else if (!this_->turn_around_limit || this_->turn_around == -this_->turn_around_limit + 1) |
2663 | == -this_->turn_around_limit + 1) |
|
|
2664 | { |
2575 | { |
2665 | this_->distance_turn = 50; |
2576 | this_->distance_turn = 50; |
2666 | distance -= this_->cmd_first->length; |
2577 | distance -= this_->cmd_first->length; |
2667 | level = navigation_get_announce_level_cmd(this_, this_->first, |
2578 | level = navigation_get_announce_level_cmd(this_, this_->first, this_->cmd_first, distance); |
2668 | this_->cmd_first, distance); |
|
|
2669 | if (level < this_->level_last) |
2579 | if (level < this_->level_last) |
2670 | { |
2580 | { |
2671 | /* only tell if the level is valid for more than 3 seconds */ |
2581 | /* only tell if the level is valid for more than 3 seconds */ |
2672 | int speed_distance = this_->first->speed * 30 / 36; |
2582 | int speed_distance = this_->first->speed * 30 / 36; |
2673 | if (distance < speed_distance || navigation_get_announce_level_cmd( |
2583 | if (distance < speed_distance || navigation_get_announce_level_cmd(this_, this_->first, this_->cmd_first, distance - speed_distance) == level) |
2674 | this_, this_->first, this_->cmd_first, |
|
|
2675 | distance - speed_distance) == level) |
|
|
2676 | { |
2584 | { |
2677 | dbg(1, "distance %d speed_distance %d\n", distance, |
2585 | dbg(1, "distance %d speed_distance %d\n", distance, speed_distance); |
2678 | speed_distance); |
|
|
2679 | dbg(1, "level %d < %d\n", level, this_->level_last); |
2586 | dbg(1, "level %d < %d\n", level, this_->level_last); |
2680 | this_->level_last = level; |
2587 | this_->level_last = level; |
2681 | force_speech = 3; |
2588 | force_speech = 3; |
2682 | } |
2589 | } |
2683 | } |
2590 | } |
… | |
… | |
2703 | |
2610 | |
2704 | if (force_speech) |
2611 | if (force_speech) |
2705 | { |
2612 | { |
2706 | this_->level_last = level; |
2613 | this_->level_last = level; |
2707 | this_->curr_delay = 0; |
2614 | this_->curr_delay = 0; |
2708 | dbg(1, "force_speech=%d distance=%d level=%d type=0x%x\n", |
2615 | dbg(1, "force_speech=%d distance=%d level=%d type=0x%x\n", force_speech, distance, level, this_->first->way.item.type); |
2709 | force_speech, distance, level, this_->first->way.item.type); |
|
|
2710 | callback_list_call(this_->callback_speech, 1, &p); |
2616 | callback_list_call(this_->callback_speech, 1, &p); |
2711 | } |
2617 | } |
2712 | } |
2618 | } |
2713 | |
2619 | |
2714 | static void navigation_update(struct navigation *this_, struct route *route, |
2620 | static void navigation_update(struct navigation *this_, struct route *route, struct attr *attr) |
2715 | struct attr *attr) |
|
|
2716 | { |
2621 | { |
2717 | struct map *map; |
2622 | struct map *map; |
2718 | struct map_rect *mr; |
2623 | struct map_rect *mr; |
2719 | struct item *ritem; /* Holds an item from the route map */ |
2624 | struct item *ritem; /* Holds an item from the route map */ |
2720 | struct item *sitem; /* Holds the corresponding item from the actual map */ |
2625 | struct item *sitem; /* Holds the corresponding item from the actual map */ |
… | |
… | |
2724 | int mode = 0, incr = 0, first = 1; |
2629 | int mode = 0, incr = 0, first = 1; |
2725 | if (attr->type != attr_route_status) |
2630 | if (attr->type != attr_route_status) |
2726 | return; |
2631 | return; |
2727 | |
2632 | |
2728 | dbg(1, "enter %d\n", mode); |
2633 | dbg(1, "enter %d\n", mode); |
2729 | if (attr->u.num == route_status_no_destination || attr->u.num |
2634 | if (attr->u.num == route_status_no_destination || attr->u.num == route_status_not_found || attr->u.num == route_status_path_done_new) |
2730 | == route_status_not_found || attr->u.num |
|
|
2731 | == route_status_path_done_new) |
|
|
2732 | navigation_flush(this_); |
2635 | navigation_flush(this_); |
2733 | if (attr->u.num != route_status_path_done_new && attr->u.num |
2636 | if (attr->u.num != route_status_path_done_new && attr->u.num != route_status_path_done_incremental) |
2734 | != route_status_path_done_incremental) |
|
|
2735 | return; |
2637 | return; |
2736 | |
2638 | |
2737 | if (!this_->route) |
2639 | if (!this_->route) |
2738 | return; |
2640 | return; |
2739 | map = route_get_map(this_->route); |
2641 | map = route_get_map(this_->route); |
… | |
… | |
2748 | this_->vehicleprofile = NULL; |
2650 | this_->vehicleprofile = NULL; |
2749 | //dbg(1,"enter\n"); |
2651 | //dbg(1,"enter\n"); |
2750 | |
2652 | |
2751 | while ((ritem = map_rect_get_item(mr))) |
2653 | while ((ritem = map_rect_get_item(mr))) |
2752 | { |
2654 | { |
2753 | if (ritem->type == type_route_start && this_->turn_around |
2655 | if (ritem->type == type_route_start && this_->turn_around > -this_->turn_around_limit + 1) |
2754 | > -this_->turn_around_limit + 1) |
|
|
2755 | this_->turn_around--; |
2656 | this_->turn_around--; |
2756 | if (ritem->type == type_route_start_reverse && this_->turn_around |
2657 | if (ritem->type == type_route_start_reverse && this_->turn_around < this_->turn_around_limit) |
2757 | < this_->turn_around_limit) |
|
|
2758 | this_->turn_around++; |
2658 | this_->turn_around++; |
2759 | if (ritem->type != type_street_route) |
2659 | if (ritem->type != type_street_route) |
2760 | continue; |
2660 | continue; |
2761 | |
2661 | |
2762 | if (first && item_attr_get(ritem, attr_street_item, &street_item)) |
2662 | if (first && item_attr_get(ritem, attr_street_item, &street_item)) |
… | |
… | |
2813 | callback_list_destroy(this_->callback); |
2713 | callback_list_destroy(this_->callback); |
2814 | callback_list_destroy(this_->callback_speech); |
2714 | callback_list_destroy(this_->callback_speech); |
2815 | g_free(this_); |
2715 | g_free(this_); |
2816 | } |
2716 | } |
2817 | |
2717 | |
2818 | int navigation_register_callback(struct navigation *this_, enum attr_type type, |
2718 | int navigation_register_callback(struct navigation *this_, enum attr_type type, struct callback *cb) |
2819 | struct callback *cb) |
|
|
2820 | { |
2719 | { |
2821 | if (type == attr_navigation_speech) |
2720 | if (type == attr_navigation_speech) |
2822 | callback_list_add(this_->callback_speech, cb); |
2721 | callback_list_add(this_->callback_speech, cb); |
2823 | else |
2722 | else |
2824 | callback_list_add(this_->callback, cb); |
2723 | callback_list_add(this_->callback, cb); |
2825 | return 1; |
2724 | return 1; |
2826 | } |
2725 | } |
2827 | |
2726 | |
2828 | void navigation_unregister_callback(struct navigation *this_, |
2727 | void navigation_unregister_callback(struct navigation *this_, enum attr_type type, struct callback *cb) |
2829 | enum attr_type type, struct callback *cb) |
|
|
2830 | { |
2728 | { |
2831 | if (type == attr_navigation_speech) |
2729 | if (type == attr_navigation_speech) |
2832 | callback_list_remove_destroy(this_->callback_speech, cb); |
2730 | callback_list_remove_destroy(this_->callback_speech, cb); |
2833 | else |
2731 | else |
2834 | callback_list_remove_destroy(this_->callback, cb); |
2732 | callback_list_remove_destroy(this_->callback, cb); |
… | |
… | |
2879 | struct navigation_way *ways; |
2777 | struct navigation_way *ways; |
2880 | int show_all; |
2778 | int show_all; |
2881 | char *str; |
2779 | char *str; |
2882 | }; |
2780 | }; |
2883 | |
2781 | |
2884 | static int navigation_map_item_coord_get(void *priv_data, struct coord *c, |
2782 | static int navigation_map_item_coord_get(void *priv_data, struct coord *c, int count) |
2885 | int count) |
|
|
2886 | { |
2783 | { |
2887 | struct map_rect_priv *this = priv_data; |
2784 | struct map_rect_priv *this = priv_data; |
2888 | if (this->ccount || !count) |
2785 | if (this->ccount || !count) |
2889 | return 0; |
2786 | return 0; |
2890 | *c = this->itm->start; |
2787 | *c = this->itm->start; |
2891 | this->ccount = 1; |
2788 | this->ccount = 1; |
2892 | return 1; |
2789 | return 1; |
2893 | } |
2790 | } |
2894 | |
2791 | |
2895 | static int navigation_map_item_attr_get(void *priv_data, |
2792 | static int navigation_map_item_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) |
2896 | enum attr_type attr_type, struct attr *attr) |
|
|
2897 | { |
2793 | { |
2898 | struct map_rect_priv *this_ = priv_data; |
2794 | struct map_rect_priv *this_ = priv_data; |
2899 | struct navigation_command *cmd = this_->cmd; |
2795 | struct navigation_command *cmd = this_->cmd; |
2900 | struct navigation_itm *itm = this_->itm; |
2796 | struct navigation_itm *itm = this_->itm; |
2901 | struct navigation_itm *prev = itm->prev; |
2797 | struct navigation_itm *prev = itm->prev; |
… | |
… | |
2916 | { |
2812 | { |
2917 | case attr_navigation_short: |
2813 | case attr_navigation_short: |
2918 | this_->attr_next = attr_navigation_long; |
2814 | this_->attr_next = attr_navigation_long; |
2919 | if (cmd) |
2815 | if (cmd) |
2920 | { |
2816 | { |
2921 | this_->str = attr->u.str = show_next_maneuvers(this_->nav, |
2817 | this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type); |
2922 | this_->cmd_itm, cmd, attr_type); |
|
|
2923 | return 1; |
2818 | return 1; |
2924 | } |
2819 | } |
2925 | return 0; |
2820 | return 0; |
2926 | case attr_navigation_long: |
2821 | case attr_navigation_long: |
2927 | this_->attr_next = attr_navigation_long_exact; |
2822 | this_->attr_next = attr_navigation_long_exact; |
2928 | if (cmd) |
2823 | if (cmd) |
2929 | { |
2824 | { |
2930 | this_->str = attr->u.str = show_next_maneuvers(this_->nav, |
2825 | this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type); |
2931 | this_->cmd_itm, cmd, attr_type); |
|
|
2932 | return 1; |
2826 | return 1; |
2933 | } |
2827 | } |
2934 | return 0; |
2828 | return 0; |
2935 | case attr_navigation_long_exact: |
2829 | case attr_navigation_long_exact: |
2936 | this_->attr_next = attr_navigation_speech; |
2830 | this_->attr_next = attr_navigation_speech; |
2937 | if (cmd) |
2831 | if (cmd) |
2938 | { |
2832 | { |
2939 | this_->str = attr->u.str = show_next_maneuvers(this_->nav, |
2833 | this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type); |
2940 | this_->cmd_itm, cmd, attr_type); |
|
|
2941 | return 1; |
2834 | return 1; |
2942 | } |
2835 | } |
2943 | return 0; |
2836 | return 0; |
2944 | case attr_navigation_speech: |
2837 | case attr_navigation_speech: |
2945 | this_->attr_next = attr_length; |
2838 | this_->attr_next = attr_length; |
2946 | if (cmd) |
2839 | if (cmd) |
2947 | { |
2840 | { |
2948 | this_->str = attr->u.str = show_next_maneuvers(this_->nav, |
2841 | this_->str = attr->u.str = show_next_maneuvers(this_->nav, this_->cmd_itm, this_->cmd, attr_type); |
2949 | this_->cmd_itm, this_->cmd, attr_type); |
|
|
2950 | return 1; |
2842 | return 1; |
2951 | } |
2843 | } |
2952 | return 0; |
2844 | return 0; |
2953 | case attr_length: |
2845 | case attr_length: |
2954 | this_->attr_next = attr_time; |
2846 | this_->attr_next = attr_time; |
2955 | if (cmd) |
2847 | if (cmd) |
2956 | { |
2848 | { |
2957 | attr->u.num = this_->cmd_itm->dest_length |
2849 | attr->u.num = this_->cmd_itm->dest_length - cmd->itm->dest_length; |
2958 | - cmd->itm->dest_length; |
|
|
2959 | return 1; |
2850 | return 1; |
2960 | } |
2851 | } |
2961 | return 0; |
2852 | return 0; |
2962 | case attr_time: |
2853 | case attr_time: |
2963 | this_->attr_next = attr_destination_length; |
2854 | this_->attr_next = attr_destination_length; |
… | |
… | |
2990 | case attr_debug: |
2881 | case attr_debug: |
2991 | switch (this_->debug_idx) |
2882 | switch (this_->debug_idx) |
2992 | { |
2883 | { |
2993 | case 0: |
2884 | case 0: |
2994 | this_->debug_idx++; |
2885 | this_->debug_idx++; |
2995 | this_->str = attr->u.str = g_strdup_printf( |
2886 | this_->str = attr->u.str = g_strdup_printf("angle:%d (- %d)", itm->way.angle2, itm->angle_end); |
2996 | "angle:%d (- %d)", itm->way.angle2, itm->angle_end); |
|
|
2997 | return 1; |
2887 | return 1; |
2998 | case 1: |
2888 | case 1: |
2999 | this_->debug_idx++; |
2889 | this_->debug_idx++; |
3000 | this_->str = attr->u.str = g_strdup_printf("item type:%s", |
2890 | this_->str = attr->u.str = g_strdup_printf("item type:%s", item_to_name(itm->way.item.type)); |
3001 | item_to_name(itm->way.item.type)); |
|
|
3002 | return 1; |
2891 | return 1; |
3003 | case 2: |
2892 | case 2: |
3004 | this_->debug_idx++; |
2893 | this_->debug_idx++; |
3005 | if (cmd) |
2894 | if (cmd) |
3006 | { |
2895 | { |
3007 | this_->str = attr->u.str = g_strdup_printf("delta:%d", |
2896 | this_->str = attr->u.str = g_strdup_printf("delta:%d", cmd->delta); |
3008 | cmd->delta); |
|
|
3009 | return 1; |
2897 | return 1; |
3010 | } |
2898 | } |
3011 | case 3: |
2899 | case 3: |
3012 | this_->debug_idx++; |
2900 | this_->debug_idx++; |
3013 | if (prev) |
2901 | if (prev) |
3014 | { |
2902 | { |
3015 | this_->str = attr->u.str = g_strdup_printf( |
2903 | this_->str = attr->u.str = g_strdup_printf("prev street_name:%s", prev->way.name1); |
3016 | "prev street_name:%s", prev->way.name1); |
|
|
3017 | return 1; |
2904 | return 1; |
3018 | } |
2905 | } |
3019 | case 4: |
2906 | case 4: |
3020 | this_->debug_idx++; |
2907 | this_->debug_idx++; |
3021 | if (prev) |
2908 | if (prev) |
3022 | { |
2909 | { |
3023 | this_->str = attr->u.str = g_strdup_printf( |
2910 | this_->str = attr->u.str = g_strdup_printf("prev street_name_systematic:%s", prev->way.name2); |
3024 | "prev street_name_systematic:%s", |
|
|
3025 | prev->way.name2); |
|
|
3026 | return 1; |
2911 | return 1; |
3027 | } |
2912 | } |
3028 | case 5: |
2913 | case 5: |
3029 | this_->debug_idx++; |
2914 | this_->debug_idx++; |
3030 | if (prev) |
2915 | if (prev) |
3031 | { |
2916 | { |
3032 | this_->str = attr->u.str = g_strdup_printf( |
2917 | this_->str = attr->u.str = g_strdup_printf("prev angle:(%d -) %d", prev->way.angle2, prev->angle_end); |
3033 | "prev angle:(%d -) %d", prev->way.angle2, |
|
|
3034 | prev->angle_end); |
|
|
3035 | return 1; |
2918 | return 1; |
3036 | } |
2919 | } |
3037 | case 6: |
2920 | case 6: |
3038 | this_->debug_idx++; |
2921 | this_->debug_idx++; |
3039 | this_->ways = itm->way.next; |
2922 | this_->ways = itm->way.next; |
3040 | if (prev) |
2923 | if (prev) |
3041 | { |
2924 | { |
3042 | this_->str = attr->u.str = g_strdup_printf( |
2925 | this_->str = attr->u.str = g_strdup_printf("prev item type:%s", item_to_name(prev->way.item.type)); |
3043 | "prev item type:%s", |
|
|
3044 | item_to_name(prev->way.item.type)); |
|
|
3045 | return 1; |
2926 | return 1; |
3046 | } |
2927 | } |
3047 | case 7: |
2928 | case 7: |
3048 | if (this_->ways && prev) |
2929 | if (this_->ways && prev) |
3049 | { |
2930 | { |
3050 | this_->str |
2931 | 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); |
3051 | = attr->u.str |
|
|
3052 | = g_strdup_printf( |
|
|
3053 | "other item angle:%d delta:%d flags:%d dir:%d type:%s id:(0x%x,0x%x)", |
|
|
3054 | this_->ways->angle2, |
|
|
3055 | angle_delta(prev->angle_end, |
|
|
3056 | this_->ways->angle2), |
|
|
3057 | this_->ways->flags, |
|
|
3058 | this_->ways->dir, |
|
|
3059 | item_to_name( |
|
|
3060 | this_->ways->item.type), |
|
|
3061 | this_->ways->item.id_hi, |
|
|
3062 | this_->ways->item.id_lo); |
|
|
3063 | this_->ways = this_->ways->next; |
2932 | this_->ways = this_->ways->next; |
3064 | return 1; |
2933 | return 1; |
3065 | } |
2934 | } |
3066 | this_->debug_idx++; |
2935 | this_->debug_idx++; |
3067 | case 8: |
2936 | case 8: |
3068 | this_->debug_idx++; |
2937 | this_->debug_idx++; |
3069 | if (prev) |
2938 | if (prev) |
3070 | { |
2939 | { |
3071 | int delta = 0; |
2940 | int delta = 0; |
3072 | char *reason = NULL; |
2941 | char *reason = NULL; |
3073 | maneuver_required2(this_->nav, prev, itm, &delta, |
2942 | maneuver_required2(this_->nav, prev, itm, &delta, &reason); |
3074 | &reason); |
|
|
3075 | this_->str = attr->u.str = g_strdup_printf("reason:%s", |
2943 | this_->str = attr->u.str = g_strdup_printf("reason:%s", reason); |
3076 | reason); |
|
|
3077 | return 1; |
2944 | return 1; |
3078 | } |
2945 | } |
3079 | |
2946 | |
3080 | default: |
2947 | default: |
3081 | this_->attr_next = attr_none; |
2948 | this_->attr_next = attr_none; |
3082 | return 0; |
2949 | return 0; |
3083 | } |
2950 | } |
3084 | case attr_any: |
2951 | case attr_any: |
3085 | while (this_->attr_next != attr_none) |
2952 | while (this_->attr_next != attr_none) |
3086 | { |
2953 | { |
3087 | if (navigation_map_item_attr_get(priv_data, this_->attr_next, |
2954 | if (navigation_map_item_attr_get(priv_data, this_->attr_next, attr)) |
3088 | attr)) |
|
|
3089 | return 1; |
2955 | return 1; |
3090 | } |
2956 | } |
3091 | return 0; |
2957 | return 0; |
3092 | default: |
2958 | default: |
3093 | attr->type = attr_none; |
2959 | attr->type = attr_none; |
3094 | return 0; |
2960 | return 0; |
3095 | } |
2961 | } |
3096 | } |
2962 | } |
3097 | |
2963 | |
3098 | static struct item_methods navigation_map_item_methods = |
2964 | static struct item_methods navigation_map_item_methods = { NULL, navigation_map_item_coord_get, NULL, navigation_map_item_attr_get, }; |
3099 | { NULL, navigation_map_item_coord_get, NULL, navigation_map_item_attr_get, }; |
|
|
3100 | |
2965 | |
3101 | static void navigation_map_destroy(struct map_priv *priv) |
2966 | static void navigation_map_destroy(struct map_priv *priv) |
3102 | { |
2967 | { |
3103 | g_free(priv); |
2968 | g_free(priv); |
3104 | } |
2969 | } |
… | |
… | |
3154 | priv->cmd_next = priv->cmd->next; |
3019 | priv->cmd_next = priv->cmd->next; |
3155 | if (priv->cmd_itm_next && !priv->cmd_itm_next->next) |
3020 | if (priv->cmd_itm_next && !priv->cmd_itm_next->next) |
3156 | ret->type = type_nav_destination; |
3021 | ret->type = type_nav_destination; |
3157 | else |
3022 | else |
3158 | { |
3023 | { |
3159 | if (priv->itm && priv->itm->prev && !(priv->itm->way.flags |
3024 | if (priv->itm && priv->itm->prev && !(priv->itm->way.flags & AF_ROUNDABOUT) && (priv->itm->prev->way.flags & AF_ROUNDABOUT)) |
3160 | & AF_ROUNDABOUT) && (priv->itm->prev->way.flags |
|
|
3161 | & AF_ROUNDABOUT)) |
|
|
3162 | { |
3025 | { |
3163 | enum item_type r = type_none, l = type_none; |
3026 | enum item_type r = type_none, l = type_none; |
3164 | switch (((180 + 22) - priv->cmd->roundabout_delta) / 45) |
3027 | switch (((180 + 22) - priv->cmd->roundabout_delta) / 45) |
3165 | { |
3028 | { |
3166 | case 0: |
3029 | case 0: |
… | |
… | |
3252 | return ret; |
3115 | return ret; |
3253 | } |
3116 | } |
3254 | return NULL; |
3117 | return NULL; |
3255 | } |
3118 | } |
3256 | |
3119 | |
3257 | static struct map_methods navigation_map_meth = |
3120 | 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, }; |
3258 | { projection_mg, "utf-8", navigation_map_destroy, navigation_map_rect_new, |
|
|
3259 | navigation_map_rect_destroy, navigation_map_get_item, |
|
|
3260 | navigation_map_get_item_byid, NULL, NULL, NULL, }; |
|
|
3261 | |
3121 | |
3262 | static struct map_priv * |
3122 | static struct map_priv * |
3263 | navigation_map_new(struct map_methods *meth, struct attr **attrs, |
3123 | navigation_map_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) |
3264 | struct callback_list *cbl) |
|
|
3265 | { |
3124 | { |
3266 | struct map_priv *ret; |
3125 | struct map_priv *ret; |
3267 | struct attr *navigation_attr; |
3126 | struct attr *navigation_attr; |
3268 | |
3127 | |
3269 | navigation_attr = attr_search(attrs, NULL, attr_navigation); |
3128 | navigation_attr = attr_search(attrs, NULL, attr_navigation); |
… | |
… | |
3277 | |
3136 | |
3278 | void navigation_set_route(struct navigation *this_, struct route *route) |
3137 | void navigation_set_route(struct navigation *this_, struct route *route) |
3279 | { |
3138 | { |
3280 | struct attr callback; |
3139 | struct attr callback; |
3281 | this_->route = route; |
3140 | this_->route = route; |
3282 | this_->route_cb = callback_new_attr_1(callback_cast(navigation_update), |
3141 | this_->route_cb = callback_new_attr_1(callback_cast(navigation_update), attr_route_status, this_); |
3283 | attr_route_status, this_); |
3142 | callback_add_names(this_->route_cb, "navigation_set_route", "navigation_update"); |
3284 | callback.type = attr_callback; |
3143 | callback.type = attr_callback; |
3285 | callback.u.callback = this_->route_cb; |
3144 | callback.u.callback = this_->route_cb; |
3286 | route_add_attr(route, &callback); |
3145 | route_add_attr(route, &callback); |
3287 | } |
3146 | } |
3288 | |
3147 | |