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