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

Diff of /navit/navit/navigation.c

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

Revision 26 Revision 27
1/**
2 * ZANavi, Zoff Android Navigation system.
3 * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
1/** 20/**
2 * Navit, a modular navigation system. 21 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team 22 * Copyright (C) 2005-2008 Navit Team
4 * 23 *
5 * This program is free software; you can redistribute it and/or 24 * This program is free software; you can redistribute it and/or
40#include "plugin.h" 59#include "plugin.h"
41#include "navit_nls.h" 60#include "navit_nls.h"
42 61
43/* #define DEBUG */ 62/* #define DEBUG */
44 63
45static int roundabout_extra_length=50; 64static int roundabout_extra_length = 50;
46 65
47
48struct suffix { 66struct suffix
67{
49 char *fullname; 68 char *fullname;
50 char *abbrev; 69 char *abbrev;
51 int sex; 70 int sex;
52} suffixes[]= { 71} suffixes[] =
72{
53 {"weg",NULL,1}, 73{ "weg", NULL, 1 },
54 {"platz","pl.",1}, 74{ "platz", "pl.", 1 },
55 {"ring",NULL,1}, 75{ "ring", NULL, 1 },
56 {"allee",NULL,2}, 76{ "allee", NULL, 2 },
57 {"gasse",NULL,2}, 77{ "gasse", NULL, 2 },
58 {"straße","str.",2}, 78{ "straße", "str.", 2 },
59 {"strasse",NULL,2}, 79{ "strasse", NULL, 2 }, };
60};
61 80
62struct navigation { 81struct navigation
82{
63 struct route *route; 83 struct route *route;
64 struct map *map; 84 struct map *map;
65 struct item_hash *hash; 85 struct item_hash *hash;
66 struct vehicleprofile *vehicleprofile; 86 struct vehicleprofile *vehicleprofile;
67 struct navigation_itm *first; 87 struct navigation_itm *first;
76 struct item item_last; 96 struct item item_last;
77 int turn_around; 97 int turn_around;
78 int turn_around_limit; 98 int turn_around_limit;
79 int distance_turn; 99 int distance_turn;
80 struct callback *route_cb; 100 struct callback *route_cb;
81 int announce[route_item_last-route_item_first+1][3]; 101 int announce[route_item_last - route_item_first + 1][3];
82 int tell_street_name; 102 int tell_street_name;
83 int delay; 103 int delay;
84 int curr_delay; 104 int curr_delay;
85}; 105};
86 106
107int distances[] =
87int distances[]={1,2,3,4,5,10,25,50,75,100,150,200,250,300,400,500,750,-1}; 108{ 1, 2, 3, 4, 5, 10, 25, 50, 75, 100, 150, 200, 250, 300, 400, 500, 750, -1 };
88 109
89
90struct navigation_command { 110struct navigation_command
111{
91 struct navigation_itm *itm; 112 struct navigation_itm *itm;
92 struct navigation_command *next; 113 struct navigation_command *next;
93 struct navigation_command *prev; 114 struct navigation_command *prev;
94 int delta; 115 int delta;
95 int roundabout_delta; 116 int roundabout_delta;
101/** 122/**
102 * @brief Calculates the delta between two angles 123 * @brief Calculates the delta between two angles
103 * @param angle1 The first angle 124 * @param angle1 The first angle
104 * @param angle2 The second angle 125 * @param angle2 The second angle
105 * @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 126 * @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
106 */ 127 */
107 128
108static int
109angle_delta(int angle1, int angle2) 129static int angle_delta(int angle1, int angle2)
110{ 130{
111 int delta=angle2-angle1; 131 int delta = angle2 - angle1;
112 if (delta <= -180) 132 if (delta <= -180)
113 delta+=360; 133 delta += 360;
114 if (delta > 180) 134 if (delta > 180)
115 delta-=360; 135 delta -= 360;
116 return delta; 136 return delta;
117} 137}
118 138
119static int
120angle_median(int angle1, int angle2) 139static int angle_median(int angle1, int angle2)
121{ 140{
122 int delta=angle_delta(angle1, angle2); 141 int delta = angle_delta(angle1, angle2);
123 int ret=angle1+delta/2; 142 int ret = angle1 + delta / 2;
124 if (ret < 0) 143 if (ret < 0)
125 ret+=360; 144 ret += 360;
126 if (ret > 360) 145 if (ret > 360)
127 ret-=360; 146 ret -= 360;
128 return ret; 147 return ret;
129} 148}
130 149
131static int
132angle_opposite(int angle) 150static int angle_opposite(int angle)
133{ 151{
134 return ((angle+180)%360); 152 return ((angle + 180) % 360);
135} 153}
136 154
137int 155int navigation_get_attr(struct navigation *this_, enum attr_type type,
138navigation_get_attr(struct navigation *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter) 156 struct attr *attr, struct attr_iter *iter)
139{ 157{
140 struct map_rect *mr; 158 struct map_rect *mr;
141 struct item *item; 159 struct item *item;
142 dbg(1,"enter %s\n", attr_to_name(type)); 160 dbg(1, "enter %s\n", attr_to_name(type));
143 switch (type) { 161 switch (type)
162 {
144 case attr_map: 163 case attr_map:
145 attr->u.map=this_->map; 164 attr->u.map = this_->map;
146 break; 165 break;
147 case attr_item_type: 166 case attr_item_type:
148 case attr_length: 167 case attr_length:
149 case attr_navigation_speech: 168 case attr_navigation_speech:
150 mr=map_rect_new(this_->map, NULL); 169 mr = map_rect_new(this_->map, NULL);
151 while ((item=map_rect_get_item(mr))) { 170 while ((item = map_rect_get_item(mr)))
171 {
152 if (item->type != type_nav_none && item->type != type_nav_position) { 172 if (item->type != type_nav_none && item->type
173 != type_nav_position)
174 {
153 if (type == attr_item_type) 175 if (type == attr_item_type)
154 attr->u.item_type=item->type; 176 attr->u.item_type = item->type;
155 else { 177 else
178 {
156 if (!item_attr_get(item, type, attr)) 179 if (!item_attr_get(item, type, attr))
157 item=NULL; 180 item = NULL;
181 }
182 break;
158 } 183 }
159 break;
160 }
161 } 184 }
162 map_rect_destroy(mr); 185 map_rect_destroy(mr);
163 if (!item) 186 if (!item)
187 return 0;
188 break;
189 default:
164 return 0; 190 return 0;
165 break;
166 default:
167 return 0;
168 } 191 }
169 attr->type=type; 192 attr->type = type;
170 return 1; 193 return 1;
171} 194}
172 195
173int
174navigation_set_attr(struct navigation *this_, struct attr *attr) 196int navigation_set_attr(struct navigation *this_, struct attr *attr)
175{ 197{
176 switch (attr->type) { 198 switch (attr->type)
199 {
177 case attr_speech: 200 case attr_speech:
178 this_->speech=attr->u.speech; 201 this_->speech = attr->u.speech;
179 return 1; 202 return 1;
180 default: 203 default:
181 return 0; 204 return 0;
182 } 205 }
183} 206}
184
185 207
186struct navigation * 208struct navigation *
187navigation_new(struct attr *parent, struct attr **attrs) 209navigation_new(struct attr *parent, struct attr **attrs)
188{ 210{
189 int i,j; 211 int i, j;
190 struct attr * attr; 212 struct attr * attr;
191 struct navigation *ret=g_new0(struct navigation, 1); 213 struct navigation *ret=g_new0(struct navigation, 1);
192 ret->hash=item_hash_new(); 214 ret->hash = item_hash_new();
193 ret->callback=callback_list_new(); 215 ret->callback = callback_list_new();
194 ret->callback_speech=callback_list_new(); 216 ret->callback_speech = callback_list_new();
195 ret->level_last=-2; 217 ret->level_last = -2;
196 ret->distance_turn=50; 218 ret->distance_turn = 50;
197 ret->turn_around_limit=3; 219 ret->turn_around_limit = 3;
198 ret->navit=parent->u.navit; 220 ret->navit = parent->u.navit;
199 ret->tell_street_name=1; 221 ret->tell_street_name = 1;
200 222
201 for (j = 0 ; j <= route_item_last-route_item_first ; j++) { 223 for (j = 0; j <= route_item_last - route_item_first; j++)
224 {
202 for (i = 0 ; i < 3 ; i++) { 225 for (i = 0; i < 3; i++)
226 {
203 ret->announce[j][i]=-1; 227 ret->announce[j][i] = -1;
204 }
205 } 228 }
229 }
206 230
207 if ((attr=attr_search(attrs, NULL, attr_tell_street_name))) { 231 if ((attr = attr_search(attrs, NULL, attr_tell_street_name)))
232 {
208 ret->tell_street_name = attr->u.num; 233 ret->tell_street_name = attr->u.num;
209 } 234 }
210 if ((attr=attr_search(attrs, NULL, attr_delay))) { 235 if ((attr = attr_search(attrs, NULL, attr_delay)))
236 {
211 ret->delay = attr->u.num; 237 ret->delay = attr->u.num;
212 } 238 }
213 239
214 return ret; 240 return ret;
215} 241}
216 242
217int
218navigation_set_announce(struct navigation *this_, enum item_type type, int *level) 243int navigation_set_announce(struct navigation *this_, enum item_type type,
244 int *level)
219{ 245{
220 int i; 246 int i;
221 if (type < route_item_first || type > route_item_last) { 247 if (type < route_item_first || type > route_item_last)
248 {
222 dbg(0,"street type %d out of range [%d,%d]", type, route_item_first, route_item_last); 249 dbg(0, "street type %d out of range [%d,%d]", type, route_item_first,
250 route_item_last);
223 return 0; 251 return 0;
224 } 252 }
225 for (i = 0 ; i < 3 ; i++) 253 for (i = 0; i < 3; i++)
226 this_->announce[type-route_item_first][i]=level[i]; 254 this_->announce[type - route_item_first][i] = level[i];
227 return 1; 255 return 1;
228} 256}
229 257
230static int 258static int navigation_get_announce_level(struct navigation *this_,
231navigation_get_announce_level(struct navigation *this_, enum item_type type, int dist) 259 enum item_type type, int dist)
232{ 260{
233 int i; 261 int i;
234 262
235 if (type < route_item_first || type > route_item_last) 263 if (type < route_item_first || type > route_item_last)
236 return -1; 264 return -1;
237 for (i = 0 ; i < 3 ; i++) { 265 for (i = 0; i < 3; i++)
266 {
238 if (dist <= this_->announce[type-route_item_first][i]) 267 if (dist <= this_->announce[type - route_item_first][i])
239 return i; 268 return i;
240 } 269 }
241 return i; 270 return i;
242} 271}
243
244 272
245/** 273/**
246 * @brief Holds a way that one could possibly drive from a navigation item 274 * @brief Holds a way that one could possibly drive from a navigation item
247 */ 275 */
248struct navigation_way { 276struct navigation_way
277{
249 struct navigation_way *next; /**< Pointer to a linked-list of all navigation_ways from this navigation item */ 278 struct navigation_way *next; /**< Pointer to a linked-list of all navigation_ways from this navigation item */
250 short dir; /**< The direction -1 or 1 of the way */ 279 short dir; /**< The direction -1 or 1 of the way */
251 short angle2; /**< The angle one has to steer to drive from the old item to this street */ 280 short angle2; /**< The angle one has to steer to drive from the old item to this street */
252 int flags; /**< The flags of the way */ 281 int flags; /**< The flags of the way */
253 struct item item; /**< The item of the way */ 282 struct item item; /**< The item of the way */
254 char *name1; 283 char *name1;
255 char *name2; 284 char *name2;
256}; 285};
257 286
258struct navigation_itm { 287struct navigation_itm
288{
259 struct navigation_way way; 289 struct navigation_way way;
260 int angle_end; 290 int angle_end;
261 struct coord start,end; 291 struct coord start, end;
262 int time; 292 int time;
263 int length; 293 int length;
264 int speed; 294 int speed;
265 int dest_time; 295 int dest_time;
266 int dest_length; 296 int dest_length;
267 int told; /**< Indicates if this item's announcement has been told earlier and should not be told again*/ 297 int told; /**< Indicates if this item's announcement has been told earlier and should not be told again*/
268 int streetname_told; /**< Indicates if this item's streetname has been told in speech navigation*/ 298 int streetname_told; /**< Indicates if this item's streetname has been told in speech navigation*/
269 int dest_count; 299 int dest_count;
270 struct navigation_itm *next; 300 struct navigation_itm *next;
271 struct navigation_itm *prev; 301 struct navigation_itm *prev;
272}; 302};
273 303
274static int is_way_allowed(struct navigation *nav, struct navigation_way *way, int mode); 304static int is_way_allowed(struct navigation *nav, struct navigation_way *way,
305 int mode);
275 306
276static int 307static int navigation_get_announce_level_cmd(struct navigation *this_,
277navigation_get_announce_level_cmd(struct navigation *this_, struct navigation_itm *itm, struct navigation_command *cmd, int distance) 308 struct navigation_itm *itm, struct navigation_command *cmd,
309 int distance)
278{ 310{
279 int level2,level=navigation_get_announce_level(this_, itm->way.item.type, distance); 311 int level2, level = navigation_get_announce_level(this_,
312 itm->way.item.type, distance);
280 if (this_->cmd_first->itm->prev) { 313 if (this_->cmd_first->itm->prev)
281 level2=navigation_get_announce_level(this_, cmd->itm->prev->way.item.type, distance); 314 {
315 level2 = navigation_get_announce_level(this_,
316 cmd->itm->prev->way.item.type, distance);
282 if (level2 > level) 317 if (level2 > level)
283 level=level2; 318 level = level2;
284 } 319 }
285 return level; 320 return level;
286} 321}
287 322
288/* 0=N,90=E */ 323/* 0=N,90=E */
289static int
290road_angle(struct coord *c1, struct coord *c2, int dir) 324static int road_angle(struct coord *c1, struct coord *c2, int dir)
291{ 325{
292 int ret=transform_get_angle_delta(c1, c2, dir); 326 int ret = transform_get_angle_delta(c1, c2, dir);
293 dbg(1, "road_angle(0x%x,0x%x - 0x%x,0x%x)=%d\n", c1->x, c1->y, c2->x, c2->y, ret); 327 // dbg(1, "road_angle(0x%x,0x%x - 0x%x,0x%x)=%d\n", c1->x, c1->y, c2->x, c2->y, ret);
294 return ret; 328 return ret;
295} 329}
296 330
297static char
298*get_count_str(int n) 331static char *get_count_str(int n)
299{ 332{
300 switch (n) { 333 switch (n)
334 {
301 case 0: 335 case 0:
302 /* TRANSLATORS: the following counts refer to streets */ 336#ifdef HAVE_API_ANDROID
337 android_send_generic_text(1,"+*#O:zeroth\n");
338#endif
339 // TRANSLATORS: the following counts refer to streets (example: turn right after the zeroth street)
303 return _("zeroth"); // Not sure if this exists, neither if it will ever be needed 340 return _("zeroth"); // Not sure if this exists, neither if it will ever be needed
304 case 1: 341 case 1:
342#ifdef HAVE_API_ANDROID
343 android_send_generic_text(1,"+*#O:first\n");
344#endif
345 // TRANSLATORS: the following counts refer to streets (example: turn right after the first street)
305 return _("first"); 346 return _("first");
306 case 2: 347 case 2:
348#ifdef HAVE_API_ANDROID
349 android_send_generic_text(1,"+*#O:second\n");
350#endif
351 // TRANSLATORS: the following counts refer to streets (example: turn right after the second street)
307 return _("second"); 352 return _("second");
308 case 3: 353 case 3:
354#ifdef HAVE_API_ANDROID
355 android_send_generic_text(1,"+*#O:third\n");
356#endif
357 // TRANSLATORS: the following counts refer to streets (example: turn right after the third street)
309 return _("third"); 358 return _("third");
310 case 4: 359 case 4:
360#ifdef HAVE_API_ANDROID
361 android_send_generic_text(1,"+*#O:fourth\n");
362#endif
363 // TRANSLATORS: the following counts refer to streets (example: turn right after the fourth street)
311 return _("fourth"); 364 return _("fourth");
312 case 5: 365 case 5:
366#ifdef HAVE_API_ANDROID
367 android_send_generic_text(1,"+*#O:fifth\n");
368#endif
369 // TRANSLATORS: the following counts refer to streets (example: turn right after the fifth street)
313 return _("fifth"); 370 return _("fifth");
314 case 6: 371 case 6:
372#ifdef HAVE_API_ANDROID
373 android_send_generic_text(1,"+*#O:sixth\n");
374#endif
375 // TRANSLATORS: the following counts refer to streets (example: turn right after the sixth street)
315 return _("sixth"); 376 return _("sixth");
377 case 7:
378#ifdef HAVE_API_ANDROID
379 android_send_generic_text(1,"+*#O:seventh\n");
380#endif
381 // TRANSLATORS: the following counts refer to streets (example: turn right after the seventh street)
382 return _("seventh");
383 case 8:
384#ifdef HAVE_API_ANDROID
385 android_send_generic_text(1,"+*#O:eighth\n");
386#endif
387 // TRANSLATORS: the following counts refer to streets (example: turn right after the eighth street)
388 return _("eighth");
389 case 9:
390#ifdef HAVE_API_ANDROID
391 android_send_generic_text(1,"+*#O:ninth\n");
392#endif
393 // TRANSLATORS: the following counts refer to streets (example: turn right after the ninth street)
394 return _("ninth");
316 default: 395 default:
317 return NULL; 396 return NULL;
318 } 397 }
319} 398}
320 399
321static char
322*get_exit_count_str(int n) 400static char *get_exit_count_str(int n)
323{ 401{
324 switch (n) { 402 switch (n)
403 {
325 case 0: 404 case 0:
326 /* TRANSLATORS: the following counts refer to roundabout exits */ 405#ifdef HAVE_API_ANDROID
406 android_send_generic_text(1,"+*#O:zeroth exit\n");
407#endif
408 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the zeroth exit)
327 return _("zeroth exit"); // Not sure if this exists, neither if it will ever be needed 409 return _("zeroth exit"); // Not sure if this exists, neither if it will ever be needed
328 case 1: 410 case 1:
411#ifdef HAVE_API_ANDROID
412 android_send_generic_text(1,"+*#O:first exit\n");
413#endif
414 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the first exit)
329 return _("first exit"); 415 return _("first exit");
330 case 2: 416 case 2:
417#ifdef HAVE_API_ANDROID
418 android_send_generic_text(1,"+*#O:second exit\n");
419#endif
420 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the second exit)
331 return _("second exit"); 421 return _("second exit");
332 case 3: 422 case 3:
423#ifdef HAVE_API_ANDROID
424 android_send_generic_text(1,"+*#O:third exit\n");
425#endif
426 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the third exit)
333 return _("third exit"); 427 return _("third exit");
334 case 4: 428 case 4:
429#ifdef HAVE_API_ANDROID
430 android_send_generic_text(1,"+*#O:fourth exit\n");
431#endif
432 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the fourth exit)
335 return _("fourth exit"); 433 return _("fourth exit");
336 case 5: 434 case 5:
435#ifdef HAVE_API_ANDROID
436 android_send_generic_text(1,"+*#O:fifth exit\n");
437#endif
438 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the fifth exit)
337 return _("fifth exit"); 439 return _("fifth exit");
338 case 6: 440 case 6:
441#ifdef HAVE_API_ANDROID
442 android_send_generic_text(1,"+*#O:sixth exit\n");
443#endif
444 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the sixth exit)
339 return _("sixth exit"); 445 return _("sixth exit");
446 case 7:
447#ifdef HAVE_API_ANDROID
448 android_send_generic_text(1,"+*#O:seventh exit\n");
449#endif
450 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the seventh exit)
451 return _("seventh exit");
452 case 8:
453#ifdef HAVE_API_ANDROID
454 android_send_generic_text(1,"+*#O:eighth exit\n");
455#endif
456 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the eighth exit)
457 return _("eighth exit");
458 case 9:
459#ifdef HAVE_API_ANDROID
460 android_send_generic_text(1,"+*#O:ninth exit\n");
461#endif
462 // TRANSLATORS: the following counts refer to roundabout exits (example: leave the roundabout at the ninth exit)
463 return _("ninth exit");
340 default: 464 default:
341 return NULL; 465 return NULL;
342 } 466 }
343} 467}
344static int
345round_distance(int dist) 468static int round_distance(int dist)
346{ 469{
347 if (dist < 100) { 470 if (dist < 100)
471 {
348 dist=(dist+5)/10; 472 dist = (dist + 5) / 10;
349 return dist*10; 473 return dist * 10;
350 } 474 }
351 if (dist < 250) { 475 if (dist < 250)
476 {
352 dist=(dist+13)/25; 477 dist = (dist + 13) / 25;
353 return dist*25; 478 return dist * 25;
354 } 479 }
355 if (dist < 500) { 480 if (dist < 500)
481 {
356 dist=(dist+25)/50; 482 dist = (dist + 25) / 50;
357 return dist*50; 483 return dist * 50;
358 } 484 }
359 if (dist < 1000) { 485 if (dist < 1000)
486 {
360 dist=(dist+50)/100; 487 dist = (dist + 50) / 100;
361 return dist*100; 488 return dist * 100;
362 } 489 }
363 if (dist < 5000) { 490 if (dist < 5000)
491 {
364 dist=(dist+50)/100; 492 dist = (dist + 50) / 100;
365 return dist*100; 493 return dist * 100;
366 } 494 }
367 if (dist < 100000) { 495 if (dist < 100000)
496 {
368 dist=(dist+500)/1000; 497 dist = (dist + 500) / 1000;
369 return dist*1000; 498 return dist * 1000;
370 } 499 }
371 dist=(dist+5000)/10000; 500 dist = (dist + 5000) / 10000;
372 return dist*10000; 501 return dist * 10000;
373} 502}
374 503
375static int
376round_for_vocabulary(int vocabulary, int dist, int factor) 504static int round_for_vocabulary(int vocabulary, int dist, int factor)
377{ 505{
378 if (!(vocabulary & 256)) { 506 if (!(vocabulary & 256))
507 {
379 if (factor != 1) 508 if (factor != 1)
380 dist=(dist+factor/2)/factor; 509 dist = (dist + factor / 2) / factor;
510 }
381 } else 511 else
382 factor=1; 512 factor = 1;
383 if (!(vocabulary & 255)) { 513 if (!(vocabulary & 255))
514 {
384 int i=0,d=0,m=0; 515 int i = 0, d = 0, m = 0;
385 while (distances[i] > 0) { 516 while (distances[i] > 0)
517 {
386 if (!i || abs(distances[i]-dist) <= d) { 518 if (!i || abs(distances[i] - dist) <= d)
519 {
387 d=abs(distances[i]-dist); 520 d = abs(distances[i] - dist);
388 m=i; 521 m = i;
389 } 522 }
390 if (distances[i] > dist) 523 if (distances[i] > dist)
391 break; 524 break;
392 i++; 525 i++;
393 } 526 }
394 dbg(0,"converted %d to %d with factor %d\n",dist,distances[m],factor); 527 // dbg(0, "converted %d to %d with factor %d\n", dist, distances[m], factor);
395 dist=distances[m]; 528 dist = distances[m];
396 } 529 }
397 return dist*factor; 530 return dist * factor;
398} 531}
399 532
400static int
401vocabulary_last(int vocabulary) 533static int vocabulary_last(int vocabulary)
402{ 534{
403 int i=0; 535 int i = 0;
404 if (vocabulary == 65535) 536 if (vocabulary == 65535)
405 return 1000; 537 return 1000;
406 while (distances[i] > 0) 538 while (distances[i] > 0)
407 i++; 539 i++;
408 return distances[i-1]; 540 return distances[i - 1];
409} 541}
410 542
411static char * 543static char *
412get_distance(struct navigation *nav, int dist, enum attr_type type, int is_length) 544get_distance(struct navigation *nav, int dist, enum attr_type type,
545 int is_length)
413{ 546{
414 int imperial=0,vocabulary=65535; 547 int imperial = 0, vocabulary = 65535;
415 struct attr attr; 548 struct attr attr;
416 549
417 if (type == attr_navigation_long) { 550 if (type == attr_navigation_long)
551 {
418 if (is_length) 552 if (is_length)
553 {
554#ifdef HAVE_API_ANDROID
555 android_send_generic_text(1,"+*#O:%d m\n");
556#endif
419 return g_strdup_printf(_("%d m"), dist); 557 return g_strdup_printf(_("%d m"), dist);
558 }
420 else 559 else
560 {
561#ifdef HAVE_API_ANDROID
562 android_send_generic_text(1,"+*#O:in %d m\n");
563#endif
421 return g_strdup_printf(_("in %d m"), dist); 564 return g_strdup_printf(_("in %d m"), dist);
565 }
422 } 566 }
423 if (navit_get_attr(nav->navit, attr_imperial, &attr, NULL)) 567 if (navit_get_attr(nav->navit, attr_imperial, &attr, NULL))
424 imperial=attr.u.num; 568 imperial = attr.u.num;
425 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_distances, &attr, NULL)) 569 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_distances,
570 &attr, NULL))
426 vocabulary=attr.u.num; 571 vocabulary = attr.u.num;
427 if (imperial) { 572 if (imperial)
573 {
428 if (dist*FEET_PER_METER < vocabulary_last(vocabulary)) { 574 if (dist * FEET_PER_METER < vocabulary_last(vocabulary))
575 {
429 dist=round_for_vocabulary(vocabulary, dist*FEET_PER_METER, 1); 576 dist = round_for_vocabulary(vocabulary, dist * FEET_PER_METER, 1);
430 if (is_length) 577 if (is_length)
578 {
579#ifdef HAVE_API_ANDROID
580 android_send_generic_text(1,"+*#O:%d feet\n");
581#endif
431 return g_strdup_printf(_("%d feet"), dist); 582 return g_strdup_printf(_("%d feet"), dist);
583 }
432 else 584 else
585 {
586#ifdef HAVE_API_ANDROID
587 android_send_generic_text(1,"+*#O:in %d feet\n");
588#endif
433 return g_strdup_printf(_("in %d feet"), dist); 589 return g_strdup_printf(_("in %d feet"), dist);
434 } 590 }
435 } else { 591 }
592 }
593 else
594 {
436 if (dist < vocabulary_last(vocabulary)) { 595 if (dist < vocabulary_last(vocabulary))
596 {
437 dist=round_for_vocabulary(vocabulary, dist, 1); 597 dist = round_for_vocabulary(vocabulary, dist, 1);
438 if (is_length) 598 if (is_length)
599 {
600#ifdef HAVE_API_ANDROID
601 android_send_generic_text(1,"+*#O:%d meters\n");
602 gchar* xy=g_strdup_printf("+*#1:%d\n", dist);
603 android_send_generic_text(1,xy);
604 g_free(xy);
605#endif
439 return g_strdup_printf(_("%d meters"), dist); 606 return g_strdup_printf(_("%d meters"), dist);
607 }
440 else 608 else
609 {
610#ifdef HAVE_API_ANDROID
611 android_send_generic_text(1,"+*#O:in %d meters\n");
612 gchar* xy=g_strdup_printf("+*#1:%d\n", dist);
613 android_send_generic_text(1,xy);
614 g_free(xy);
615#endif
441 return g_strdup_printf(_("in %d meters"), dist); 616 return g_strdup_printf(_("in %d meters"), dist);
617 }
442 } 618 }
443 } 619 }
444 if (imperial) 620 if (imperial)
445 dist=round_for_vocabulary(vocabulary, dist*FEET_PER_METER*1000/FEET_PER_MILE, 1000); 621 {
622 dist = round_for_vocabulary(vocabulary,
623 dist * FEET_PER_METER * 1000 / FEET_PER_MILE, 1000);
624 }
446 else 625 else
626 {
447 dist=round_for_vocabulary(vocabulary, dist, 1000); 627 dist = round_for_vocabulary(vocabulary, dist, 1000);
628 }
629
448 if (dist < 5000) { 630 if (dist < 5000)
631 {
449 int rem=(dist/100)%10; 632 int rem = (dist / 100) % 10;
450 if (rem) { 633 if (rem)
634 {
451 if (imperial) { 635 if (imperial)
636 {
452 if (is_length) 637 if (is_length)
638 {
639#ifdef HAVE_API_ANDROID
640 android_send_generic_text(1,"+*#O:%d.%d miles\n");
641#endif
453 return g_strdup_printf(_("%d.%d miles"), dist/1000, rem); 642 return g_strdup_printf(_("%d.%d miles"), dist / 1000, rem);
643 }
454 else 644 else
645 {
646#ifdef HAVE_API_ANDROID
647 android_send_generic_text(1,"+*#O:in %d.%d miles\n");
648#endif
455 return g_strdup_printf(_("in %d.%d miles"), dist/1000, rem); 649 return g_strdup_printf(_("in %d.%d miles"), dist / 1000,
650 rem);
651 }
652 }
456 } else { 653 else
654 {
457 if (is_length) 655 if (is_length)
656 {
657#ifdef HAVE_API_ANDROID
658 android_send_generic_text(1,"+*#O:%d.%d kilometers\n");
659#endif
458 return g_strdup_printf(_("%d.%d kilometers"), dist/1000, rem); 660 return g_strdup_printf(_("%d.%d kilometers"), dist / 1000,
661 rem);
662 }
459 else 663 else
664 {
665#ifdef HAVE_API_ANDROID
666 android_send_generic_text(1,"+*#O:in %d.%d kilometers\n");
667#endif
460 return g_strdup_printf(_("in %d.%d kilometers"), dist/1000, rem); 668 return g_strdup_printf(_("in %d.%d kilometers"),
669 dist / 1000, rem);
461 } 670 }
462 } 671 }
463 } 672 }
673 }
464 if (imperial) { 674 if (imperial)
675 {
465 if (is_length) 676 if (is_length)
677 return g_strdup_printf(
466 return g_strdup_printf(ngettext("one mile","%d miles", dist/1000), dist/1000); 678 ngettext("one mile", "%d miles", dist / 1000), dist / 1000);
467 else 679 else
468 return g_strdup_printf(ngettext("in one mile","in %d miles", dist/1000), dist/1000); 680 return g_strdup_printf(
469 } else { 681 ngettext("in one mile", "in %d miles", dist / 1000),
682 dist / 1000);
683 }
684 else
685 {
470 if (is_length) 686 if (is_length)
471 return g_strdup_printf(ngettext("one kilometer","%d kilometers", dist/1000), dist/1000); 687 {
688#ifdef HAVE_API_ANDROID
689 android_send_generic_text(1,"+*#O:one kilometer|%d kilometers\n");
690#endif
691 return g_strdup_printf(
692 ngettext("one kilometer", "%d kilometers", dist / 1000),
693 dist / 1000);
694 }
472 else 695 else
473 return g_strdup_printf(ngettext("in one kilometer","in %d kilometers", dist/1000), dist/1000); 696 {
697#ifdef HAVE_API_ANDROID
698 android_send_generic_text(1,"+*#O:in one kilometer|in %d kilometers\n");
699#endif
700 return g_strdup_printf(
701 ngettext("in one kilometer", "in %d kilometers",
702 dist / 1000), dist / 1000);
474 } 703 }
704 }
475} 705}
476
477 706
478/** 707/**
479 * @brief This calculates the angle with which an item starts or ends 708 * @brief This calculates the angle with which an item starts or ends
480 * 709 *
481 * This function can be used to get the angle an item (from a route graph map) 710 * This function can be used to get the angle an item (from a route graph map)
484 * 713 *
485 * This is meant to be used with items from a route graph map 714 * This is meant to be used with items from a route graph map
486 * With other items this will probably not be optimal... 715 * With other items this will probably not be optimal...
487 * 716 *
488 * @param w The way which should be calculated 717 * @param w The way which should be calculated
489 */ 718 */
490static void
491calculate_angle(struct navigation_way *w) 719static void calculate_angle(struct navigation_way *w)
492{ 720{
493 struct coord cbuf[2]; 721 struct coord cbuf[2];
494 struct item *ritem; // the "real" item 722 struct item *ritem; // the "real" item
495 struct coord c; 723 struct coord c;
496 struct map_rect *mr; 724 struct map_rect *mr;
497 struct attr attr; 725 struct attr attr;
498 726
499 w->angle2=361; 727 w->angle2 = 361;
500 mr = map_rect_new(w->item.map, NULL); 728 mr = map_rect_new(w->item.map, NULL);
501 if (!mr) 729 if (!mr)
502 return; 730 return;
503 731
504 ritem = map_rect_get_item_byid(mr, w->item.id_hi, w->item.id_lo); 732 ritem = map_rect_get_item_byid(mr, w->item.id_hi, w->item.id_lo);
505 if (!ritem) { 733 if (!ritem)
734 {
506 dbg(1,"Item from segment not found on map!\n"); 735 dbg(1, "Item from segment not found on map!\n");
507 map_rect_destroy(mr); 736 map_rect_destroy(mr);
508 return; 737 return;
509 } 738 }
510 739
511 if (ritem->type < type_line || ritem->type >= type_area) { 740 if (ritem->type < type_line || ritem->type >= type_area)
741 {
512 map_rect_destroy(mr); 742 map_rect_destroy(mr);
513 return; 743 return;
514 } 744 }
515 if (item_attr_get(ritem, attr_flags, &attr)) 745 if (item_attr_get(ritem, attr_flags, &attr))
516 w->flags=attr.u.num; 746 w->flags = attr.u.num;
517 else 747 else
518 w->flags=0; 748 w->flags = 0;
519 if (item_attr_get(ritem, attr_street_name, &attr)) 749 if (item_attr_get(ritem, attr_street_name, &attr))
520 w->name1=map_convert_string(ritem->map,attr.u.str); 750 w->name1 = map_convert_string(ritem->map, attr.u.str);
521 else 751 else
522 w->name1=NULL; 752 w->name1 = NULL;
523 if (item_attr_get(ritem, attr_street_name_systematic, &attr)) 753 if (item_attr_get(ritem, attr_street_name_systematic, &attr))
524 w->name2=map_convert_string(ritem->map,attr.u.str); 754 w->name2 = map_convert_string(ritem->map, attr.u.str);
525 else 755 else
526 w->name2=NULL; 756 w->name2 = NULL;
527 757
528 if (w->dir < 0) { 758 if (w->dir < 0)
759 {
529 if (item_coord_get(ritem, cbuf, 2) != 2) { 760 if (item_coord_get(ritem, cbuf, 2) != 2)
761 {
762 dbg(1,
530 dbg(1,"Using calculate_angle() with a less-than-two-coords-item?\n"); 763 "Using calculate_angle() with a less-than-two-coords-item?\n");
531 map_rect_destroy(mr); 764 map_rect_destroy(mr);
532 return; 765 return;
533 } 766 }
534 767
535 while (item_coord_get(ritem, &c, 1)) { 768 while (item_coord_get(ritem, &c, 1))
769 {
536 cbuf[0] = cbuf[1]; 770 cbuf[0] = cbuf[1];
537 cbuf[1] = c; 771 cbuf[1] = c;
538 } 772 }
539 773
540 } else { 774 }
775 else
776 {
541 if (item_coord_get(ritem, cbuf, 2) != 2) { 777 if (item_coord_get(ritem, cbuf, 2) != 2)
778 {
779 dbg(1,
542 dbg(1,"Using calculate_angle() with a less-than-two-coords-item?\n"); 780 "Using calculate_angle() with a less-than-two-coords-item?\n");
543 map_rect_destroy(mr); 781 map_rect_destroy(mr);
544 return; 782 return;
545 } 783 }
546 c = cbuf[0]; 784 c = cbuf[0];
547 cbuf[0] = cbuf[1]; 785 cbuf[0] = cbuf[1];
548 cbuf[1] = c; 786 cbuf[1] = c;
549 } 787 }
550 788
551 map_rect_destroy(mr); 789 map_rect_destroy(mr);
552 790
553 w->angle2=road_angle(&cbuf[1],&cbuf[0],0); 791 w->angle2 = road_angle(&cbuf[1], &cbuf[0], 0);
554} 792}
555 793
556/** 794/**
557 * @brief Returns the time (in seconds) one will drive between two navigation items 795 * @brief Returns the time (in seconds) one will drive between two navigation items
558 * 796 *
561 * 799 *
562 * @param from The first item 800 * @param from The first item
563 * @param to The last item 801 * @param to The last item
564 * @return The travel time in seconds, or -1 on error 802 * @return The travel time in seconds, or -1 on error
565 */ 803 */
566static int 804static int navigation_time(struct navigation_itm *from,
567navigation_time(struct navigation_itm *from, struct navigation_itm *to) 805 struct navigation_itm *to)
568{ 806{
569 struct navigation_itm *cur; 807 struct navigation_itm *cur;
570 int time; 808 int time;
571 809
572 time = 0; 810 time = 0;
573 cur = from; 811 cur = from;
574 while (cur) { 812 while (cur)
813 {
575 time += cur->time; 814 time += cur->time;
576 815
577 if (cur == to) { 816 if (cur == to)
817 {
578 break; 818 break;
579 } 819 }
580 cur = cur->next; 820 cur = cur->next;
581 } 821 }
582 822
583 if (!cur) { 823 if (!cur)
824 {
584 return -1; 825 return -1;
585 } 826 }
586 827
587 return time; 828 return time;
588} 829}
590/** 831/**
591 * @brief Clears the ways one can drive from itm 832 * @brief Clears the ways one can drive from itm
592 * 833 *
593 * @param itm The item that should have its ways cleared 834 * @param itm The item that should have its ways cleared
594 */ 835 */
595static void
596navigation_itm_ways_clear(struct navigation_itm *itm) 836static void navigation_itm_ways_clear(struct navigation_itm *itm)
597{ 837{
598 struct navigation_way *c,*n; 838 struct navigation_way *c, *n;
599 839
600 c = itm->way.next; 840 c = itm->way.next;
601 while (c) { 841 while (c)
842 {
602 n = c->next; 843 n = c->next;
603 map_convert_free(c->name1); 844 map_convert_free(c->name1);
604 map_convert_free(c->name2); 845 map_convert_free(c->name2);
605 g_free(c); 846 g_free(c);
606 c = n; 847 c = n;
616 * and the next navigation item are excluded. 857 * and the next navigation item are excluded.
617 * 858 *
618 * @param itm The item that should be updated 859 * @param itm The item that should be updated
619 * @param graph_map The route graph's map that these items are on 860 * @param graph_map The route graph's map that these items are on
620 */ 861 */
621static void
622navigation_itm_ways_update(struct navigation_itm *itm, struct map *graph_map) 862static void navigation_itm_ways_update(struct navigation_itm *itm,
863 struct map *graph_map)
623{ 864{
624 struct map_selection coord_sel; 865 struct map_selection coord_sel;
625 struct map_rect *g_rect; // Contains a map rectangle from the route graph's map 866 struct map_rect *g_rect; // Contains a map rectangle from the route graph's map
626 struct item *i,*sitem; 867 struct item *i, *sitem;
627 struct attr sitem_attr,direction_attr; 868 struct attr sitem_attr, direction_attr;
628 struct navigation_way *w,*l; 869 struct navigation_way *w, *l;
629 870
630 navigation_itm_ways_clear(itm); 871 navigation_itm_ways_clear(itm);
631 872
632 // These values cause the code in route.c to get us only the route graph point and connected segments 873 // These values cause the code in route.c to get us only the route graph point and connected segments
633 coord_sel.next = NULL; 874 coord_sel.next = NULL;
634 coord_sel.u.c_rect.lu = itm->start; 875 coord_sel.u.c_rect.lu = itm->start;
635 coord_sel.u.c_rect.rl = itm->start; 876 coord_sel.u.c_rect.rl = itm->start;
636 // the selection's order is ignored 877 // the selection's order is ignored
637 878
638 g_rect = map_rect_new(graph_map, &coord_sel); 879 g_rect = map_rect_new(graph_map, &coord_sel);
639 880
640 i = map_rect_get_item(g_rect); 881 i = map_rect_get_item(g_rect);
641 if (!i || i->type != type_rg_point) { // probably offroad? 882 if (!i || i->type != type_rg_point)
883 { // probably offroad?
642 return ; 884 return;
643 } 885 }
644 886
645 w = NULL; 887 w = NULL;
646 888
647 while (1) { 889 while (1)
890 {
648 i = map_rect_get_item(g_rect); 891 i = map_rect_get_item(g_rect);
649 892
650 if (!i) { 893 if (!i)
894 {
651 break; 895 break;
652 } 896 }
653 897
654 if (i->type != type_rg_segment) { 898 if (i->type != type_rg_segment)
899 {
655 continue; 900 continue;
656 } 901 }
657 902
658 if (!item_attr_get(i,attr_street_item,&sitem_attr)) { 903 if (!item_attr_get(i, attr_street_item, &sitem_attr))
904 {
905 dbg(1,
659 dbg(1, "Got no street item for route graph item in entering_straight()\n"); 906 "Got no street item for route graph item in entering_straight()\n");
660 continue; 907 continue;
661 } 908 }
662 909
663 if (!item_attr_get(i,attr_direction,&direction_attr)) { 910 if (!item_attr_get(i, attr_direction, &direction_attr))
911 {
664 continue; 912 continue;
665 } 913 }
666 914
667 sitem = sitem_attr.u.item; 915 sitem = sitem_attr.u.item;
668 if (sitem->type == type_street_turn_restriction_no || sitem->type == type_street_turn_restriction_only) 916 if (sitem->type == type_street_turn_restriction_no || sitem->type
917 == type_street_turn_restriction_only)
669 continue; 918 continue;
670 919
671 if (item_is_equal(itm->way.item,*sitem) || ((itm->prev) && item_is_equal(itm->prev->way.item,*sitem))) { 920 if (item_is_equal(itm->way.item, *sitem) || ((itm->prev)
921 && item_is_equal(itm->prev->way.item, *sitem)))
922 {
672 continue; 923 continue;
673 } 924 }
674 925
675 l = w; 926 l = w;
676 w = g_new(struct navigation_way, 1); 927 w = g_new(struct navigation_way, 1);
679 w->next = l; 930 w->next = l;
680 calculate_angle(w); 931 calculate_angle(w);
681 } 932 }
682 933
683 map_rect_destroy(g_rect); 934 map_rect_destroy(g_rect);
684 935
685 itm->way.next = w; 936 itm->way.next = w;
686} 937}
687 938
688static void 939static void navigation_destroy_itms_cmds(struct navigation *this_,
689navigation_destroy_itms_cmds(struct navigation *this_, struct navigation_itm *end) 940 struct navigation_itm *end)
690{ 941{
691 struct navigation_itm *itm; 942 struct navigation_itm *itm;
692 struct navigation_command *cmd; 943 struct navigation_command *cmd;
693 dbg(2,"enter this_=%p this_->first=%p this_->cmd_first=%p end=%p\n", this_, this_->first, this_->cmd_first, end); 944 // dbg(2, "enter this_=%p this_->first=%p this_->cmd_first=%p end=%p\n", this_, this_->first, this_->cmd_first, end);
694 if (this_->cmd_first) 945 if (this_->cmd_first)
946 {
695 dbg(2,"this_->cmd_first->itm=%p\n", this_->cmd_first->itm); 947 // dbg(2, "this_->cmd_first->itm=%p\n", this_->cmd_first->itm);
948 }
696 while (this_->first && this_->first != end) { 949 while (this_->first && this_->first != end)
950 {
697 itm=this_->first; 951 itm = this_->first;
698 dbg(3,"destroying %p\n", itm); 952 // dbg(3, "destroying %p\n", itm);
699 item_hash_remove(this_->hash, &itm->way.item); 953 item_hash_remove(this_->hash, &itm->way.item);
700 this_->first=itm->next; 954 this_->first = itm->next;
701 if (this_->first) 955 if (this_->first)
702 this_->first->prev=NULL; 956 this_->first->prev = NULL;
703 if (this_->cmd_first && this_->cmd_first->itm == itm->next) { 957 if (this_->cmd_first && this_->cmd_first->itm == itm->next)
958 {
704 cmd=this_->cmd_first; 959 cmd = this_->cmd_first;
705 this_->cmd_first=cmd->next; 960 this_->cmd_first = cmd->next;
706 if (cmd->next) { 961 if (cmd->next)
962 {
707 cmd->next->prev = NULL; 963 cmd->next->prev = NULL;
708 } 964 }
709 g_free(cmd); 965 g_free(cmd);
710 } 966 }
711 map_convert_free(itm->way.name1); 967 map_convert_free(itm->way.name1);
712 map_convert_free(itm->way.name2); 968 map_convert_free(itm->way.name2);
713 navigation_itm_ways_clear(itm); 969 navigation_itm_ways_clear(itm);
714 g_free(itm); 970 g_free(itm);
715 } 971 }
716 if (! this_->first) 972 if (!this_->first)
717 this_->last=NULL; 973 this_->last = NULL;
718 if (! this_->first && end) 974 if (!this_->first && end)
975 {
719 dbg(0,"end wrong\n"); 976 // dbg(0, "end wrong\n");
977 }
720 dbg(2,"ret this_->first=%p this_->cmd_first=%p\n",this_->first, this_->cmd_first); 978 // dbg(2, "ret this_->first=%p this_->cmd_first=%p\n", this_->first, this_->cmd_first);
721} 979}
722 980
723static void
724navigation_itm_update(struct navigation_itm *itm, struct item *ritem) 981static void navigation_itm_update(struct navigation_itm *itm,
982 struct item *ritem)
725{ 983{
726 struct attr length, time, speed; 984 struct attr length, time, speed;
727 985
728 if (! item_attr_get(ritem, attr_length, &length)) { 986 if (!item_attr_get(ritem, attr_length, &length))
987 {
729 dbg(0,"no length\n"); 988 // dbg(0, "no length\n");
730 return; 989 return;
731 } 990 }
732 if (! item_attr_get(ritem, attr_time, &time)) { 991 if (!item_attr_get(ritem, attr_time, &time))
992 {
733 dbg(0,"no time\n"); 993 // dbg(0, "no time\n");
734 return; 994 return;
735 } 995 }
736 if (! item_attr_get(ritem, attr_speed, &speed)) { 996 if (!item_attr_get(ritem, attr_speed, &speed))
997 {
737 dbg(0,"no time\n"); 998 // dbg(0, "no time\n");
738 return; 999 return;
739 } 1000 }
740 1001
741 dbg(1,"length=%d time=%d speed=%d\n", length.u.num, time.u.num, speed.u.num); 1002 // dbg(1, "length=%d time=%d speed=%d\n", length.u.num, time.u.num, speed.u.num);
742 itm->length=length.u.num; 1003 itm->length = length.u.num;
743 itm->time=time.u.num; 1004 itm->time = time.u.num;
744 itm->speed=speed.u.num; 1005 itm->speed = speed.u.num;
745} 1006}
746 1007
747/** 1008/**
748 * @brief This check if an item is part of a roundabout 1009 * @brief This check if an item is part of a roundabout
749 * 1010 *
750 * @param itm The item to be checked 1011 * @param itm The item to be checked
751 * @return True if the item is part of a roundabout 1012 * @return True if the item is part of a roundabout
752 */ 1013 */
753static int
754check_roundabout(struct navigation_itm *itm, struct map *graph_map) 1014static int check_roundabout(struct navigation_itm *itm, struct map *graph_map)
755{ 1015{
756 struct map_selection coord_sel; 1016 struct map_selection coord_sel;
757 struct map_rect *g_rect; // Contains a map rectangle from the route graph's map 1017 struct map_rect *g_rect; // Contains a map rectangle from the route graph's map
758 struct item *i,*sitem; 1018 struct item *i, *sitem;
759 struct attr sitem_attr,flags_attr; 1019 struct attr sitem_attr, flags_attr;
760 1020
761 // These values cause the code in route.c to get us only the route graph point and connected segments 1021 // These values cause the code in route.c to get us only the route graph point and connected segments
762 coord_sel.next = NULL; 1022 coord_sel.next = NULL;
763 coord_sel.u.c_rect.lu = itm->start; 1023 coord_sel.u.c_rect.lu = itm->start;
764 coord_sel.u.c_rect.rl = itm->start; 1024 coord_sel.u.c_rect.rl = itm->start;
765 // the selection's order is ignored 1025 // the selection's order is ignored
766 1026
767 g_rect = map_rect_new(graph_map, &coord_sel); 1027 g_rect = map_rect_new(graph_map, &coord_sel);
768 1028
769 i = map_rect_get_item(g_rect); 1029 i = map_rect_get_item(g_rect);
770 if (!i || i->type != type_rg_point) { // probably offroad? 1030 if (!i || i->type != type_rg_point)
1031 { // probably offroad?
771 map_rect_destroy(g_rect); 1032 map_rect_destroy(g_rect);
772 return 0; 1033 return 0;
773 } 1034 }
774 1035
775 while (1) { 1036 while (1)
1037 {
776 i = map_rect_get_item(g_rect); 1038 i = map_rect_get_item(g_rect);
777 1039
778 if (!i) { 1040 if (!i)
1041 {
779 break; 1042 break;
780 } 1043 }
781 1044
782 if (i->type != type_rg_segment) { 1045 if (i->type != type_rg_segment)
1046 {
783 continue; 1047 continue;
784 } 1048 }
785 1049
786 if (!item_attr_get(i,attr_street_item,&sitem_attr)) { 1050 if (!item_attr_get(i, attr_street_item, &sitem_attr))
1051 {
787 continue; 1052 continue;
788 } 1053 }
789 1054
790 sitem = sitem_attr.u.item; 1055 sitem = sitem_attr.u.item;
791 if (item_is_equal(itm->way.item,*sitem)) { 1056 if (item_is_equal(itm->way.item, *sitem))
1057 {
792 if (item_attr_get(i,attr_flags,&flags_attr) && (flags_attr.u.num & AF_ROUNDABOUT)) { 1058 if (item_attr_get(i, attr_flags, &flags_attr) && (flags_attr.u.num
1059 & AF_ROUNDABOUT))
1060 {
793 map_rect_destroy(g_rect); 1061 map_rect_destroy(g_rect);
794 return 1; 1062 return 1;
795 } 1063 }
796 } 1064 }
797 } 1065 }
802 1070
803static struct navigation_itm * 1071static struct navigation_itm *
804navigation_itm_new(struct navigation *this_, struct item *ritem) 1072navigation_itm_new(struct navigation *this_, struct item *ritem)
805{ 1073{
806 struct navigation_itm *ret=g_new0(struct navigation_itm, 1); 1074 struct navigation_itm *ret=g_new0(struct navigation_itm, 1);
807 int i=0; 1075 int i = 0;
808 struct item *sitem; 1076 struct item *sitem;
809 struct map *graph_map = NULL; 1077 struct map *graph_map = NULL;
810 struct attr street_item,direction,route_attr; 1078 struct attr street_item, direction, route_attr;
811 struct map_rect *mr; 1079 struct map_rect *mr;
812 struct attr attr; 1080 struct attr attr;
813 struct coord c[5]; 1081 struct coord c[5];
814 1082
815 if (ritem) { 1083 if (ritem)
1084 {
816 ret->streetname_told=0; 1085 ret->streetname_told = 0;
817 if (! item_attr_get(ritem, attr_street_item, &street_item)) { 1086 if (!item_attr_get(ritem, attr_street_item, &street_item))
1087 {
818 dbg(1, "no street item\n"); 1088 //dbg(1, "no street item\n");
819 g_free(ret); 1089 g_free(ret);
820 ret = NULL; 1090 ret = NULL;
821 return ret; 1091 return ret;
822 } 1092 }
823 if (item_attr_get(ritem, attr_direction, &direction)) 1093 if (item_attr_get(ritem, attr_direction, &direction))
824 ret->way.dir=direction.u.num; 1094 ret->way.dir = direction.u.num;
825 else 1095 else
826 ret->way.dir=0; 1096 ret->way.dir = 0;
827 1097
828 sitem=street_item.u.item; 1098 sitem = street_item.u.item;
829 ret->way.item=*sitem; 1099 ret->way.item = *sitem;
830 item_hash_insert(this_->hash, sitem, ret); 1100 item_hash_insert(this_->hash, sitem, ret);
831 mr=map_rect_new(sitem->map, NULL); 1101 mr = map_rect_new(sitem->map, NULL);
832 if (! (sitem=map_rect_get_item_byid(mr, sitem->id_hi, sitem->id_lo))) 1102 if (!(sitem = map_rect_get_item_byid(mr, sitem->id_hi, sitem->id_lo)))
833 return NULL; 1103 return NULL;
834 if (item_attr_get(sitem, attr_street_name, &attr)) 1104 if (item_attr_get(sitem, attr_street_name, &attr))
835 ret->way.name1=map_convert_string(sitem->map,attr.u.str); 1105 ret->way.name1 = map_convert_string(sitem->map, attr.u.str);
836 if (item_attr_get(sitem, attr_street_name_systematic, &attr)) 1106 if (item_attr_get(sitem, attr_street_name_systematic, &attr))
837 ret->way.name2=map_convert_string(sitem->map,attr.u.str); 1107 ret->way.name2 = map_convert_string(sitem->map, attr.u.str);
838 navigation_itm_update(ret, ritem); 1108 navigation_itm_update(ret, ritem);
839 1109
840 while (item_coord_get(ritem, &c[i], 1)) { 1110 while (item_coord_get(ritem, &c[i], 1))
1111 {
841 dbg(1, "coord %d 0x%x 0x%x\n", i, c[i].x ,c[i].y); 1112 //dbg(1, "coord %d 0x%x 0x%x\n", i, c[i].x, c[i].y);
842 1113
843 if (i < 4) 1114 if (i < 4)
844 i++; 1115 i++;
845 else { 1116 else
1117 {
846 c[2]=c[3]; 1118 c[2] = c[3];
847 c[3]=c[4]; 1119 c[3] = c[4];
848 }
849 } 1120 }
1121 }
850 dbg(1,"count=%d\n", i); 1122 //dbg(1, "count=%d\n", i);
851 i--; 1123 i--;
852 1124
853 ret->way.angle2=road_angle(&c[0], &c[1], 0); 1125 ret->way.angle2 = road_angle(&c[0], &c[1], 0);
854 ret->angle_end=road_angle(&c[i-1], &c[i], 0); 1126 ret->angle_end = road_angle(&c[i - 1], &c[i], 0);
855 1127
856 ret->start=c[0]; 1128 ret->start = c[0];
857 ret->end=c[i]; 1129 ret->end = c[i];
858 1130
859 item_attr_get(ritem, attr_route, &route_attr); 1131 item_attr_get(ritem, attr_route, &route_attr);
860 graph_map = route_get_graph_map(route_attr.u.route); 1132 graph_map = route_get_graph_map(route_attr.u.route);
861 if (check_roundabout(ret, graph_map)) { 1133 if (check_roundabout(ret, graph_map))
1134 {
862 ret->way.flags |= AF_ROUNDABOUT; 1135 ret->way.flags |= AF_ROUNDABOUT;
863 } 1136 }
864 1137
865 dbg(1,"i=%d start %d end %d '%s' '%s'\n", i, ret->way.angle2, ret->angle_end, ret->way.name1, ret->way.name2); 1138 // dbg(1, "i=%d start %d end %d '%s' '%s'\n", i, ret->way.angle2, ret->angle_end, ret->way.name1, ret->way.name2);
866 map_rect_destroy(mr); 1139 map_rect_destroy(mr);
867 } else { 1140 }
1141 else
1142 {
868 if (this_->last) 1143 if (this_->last)
869 ret->start=ret->end=this_->last->end; 1144 ret->start = ret->end = this_->last->end;
870 } 1145 }
871 if (! this_->first) 1146 if (!this_->first)
872 this_->first=ret; 1147 this_->first = ret;
873 if (this_->last) { 1148 if (this_->last)
1149 {
874 this_->last->next=ret; 1150 this_->last->next = ret;
875 ret->prev=this_->last; 1151 ret->prev = this_->last;
876 if (graph_map) { 1152 if (graph_map)
1153 {
877 navigation_itm_ways_update(ret,graph_map); 1154 navigation_itm_ways_update(ret, graph_map);
878 }
879 } 1155 }
1156 }
880 dbg(1,"ret=%p\n", ret); 1157 //dbg(1, "ret=%p\n", ret);
881 this_->last=ret; 1158 this_->last = ret;
882 return ret; 1159 return ret;
883} 1160}
884 1161
885/** 1162/**
886 * @brief Counts how many times a driver could turn right/left 1163 * @brief Counts how many times a driver could turn right/left
892 * @param from The navigation item which should form the start 1169 * @param from The navigation item which should form the start
893 * @param to The navigation item which should form the end 1170 * @param to The navigation item which should form the end
894 * @param direction Set to < 0 to count turns to the left >= 0 for turns to the right 1171 * @param direction Set to < 0 to count turns to the left >= 0 for turns to the right
895 * @return The number of possibilities to turn or -1 on error 1172 * @return The number of possibilities to turn or -1 on error
896 */ 1173 */
897static int 1174static int count_possible_turns(struct navigation *nav,
898count_possible_turns(struct navigation *nav, struct navigation_itm *from, struct navigation_itm *to, int direction) 1175 struct navigation_itm *from, struct navigation_itm *to, int direction)
899{ 1176{
900 int count; 1177 int count;
901 struct navigation_itm *curr; 1178 struct navigation_itm *curr;
902 struct navigation_way *w; 1179 struct navigation_way *w;
903 1180
904 count = 0; 1181 count = 0;
905 curr = from->next; 1182 curr = from->next;
906 while (curr && (curr != to)) { 1183 while (curr && (curr != to))
1184 {
907 w = curr->way.next; 1185 w = curr->way.next;
908 1186
909 while (w) { 1187 while (w)
1188 {
910 if (is_way_allowed(nav, w, 4)) { 1189 if (is_way_allowed(nav, w, 4))
1190 {
911 if (direction < 0) { 1191 if (direction < 0)
1192 {
912 if (angle_delta(curr->prev->angle_end, w->angle2) < 0) { 1193 if (angle_delta(curr->prev->angle_end, w->angle2) < 0)
1194 {
913 count++; 1195 count++;
914 break; 1196 break;
915 } 1197 }
1198 }
916 } else { 1199 else
1200 {
917 if (angle_delta(curr->prev->angle_end, w->angle2) > 0) { 1201 if (angle_delta(curr->prev->angle_end, w->angle2) > 0)
1202 {
918 count++; 1203 count++;
919 break; 1204 break;
920 } 1205 }
921 } 1206 }
922 } 1207 }
923 w = w->next; 1208 w = w->next;
924 } 1209 }
925 curr = curr->next; 1210 curr = curr->next;
926 } 1211 }
927 1212
1213 if (!curr)
928 if (!curr) { // from does not lead to to? 1214 { // from does not lead to to?
929 return -1; 1215 return -1;
930 } 1216 }
931 1217
932 return count; 1218 return count;
933} 1219}
941 * only if the rest of the navigation already has been calculated. 1227 * only if the rest of the navigation already has been calculated.
942 * 1228 *
943 * @param this_ The navigation whose destination / time should be calculated 1229 * @param this_ The navigation whose destination / time should be calculated
944 * @param incr Set this to true to only calculate the first item. See description. 1230 * @param incr Set this to true to only calculate the first item. See description.
945 */ 1231 */
946static void
947calculate_dest_distance(struct navigation *this_, int incr) 1232static void calculate_dest_distance(struct navigation *this_, int incr)
948{ 1233{
949 int len=0, time=0, count=0; 1234 int len = 0, time = 0, count = 0;
950 struct navigation_itm *next,*itm=this_->last; 1235 struct navigation_itm *next, *itm = this_->last;
951 dbg(1, "enter this_=%p, incr=%d\n", this_, incr); 1236 //dbg(1, "enter this_=%p, incr=%d\n", this_, incr);
952 if (incr) { 1237 if (incr)
1238 {
953 if (itm) { 1239 if (itm)
954 dbg(2, "old values: (%p) time=%d lenght=%d\n", itm, itm->dest_length, itm->dest_time); 1240 {
1241 //dbg(2, "old values: (%p) time=%d lenght=%d\n", itm,
1242 // itm->dest_length, itm->dest_time);
1243 }
955 } else { 1244 else
1245 {
956 dbg(2, "old values: itm is null\n"); 1246 //dbg(2, "old values: itm is null\n");
957 } 1247 }
958 itm=this_->first; 1248 itm = this_->first;
959 next=itm->next; 1249 next = itm->next;
960 dbg(2, "itm values: time=%d lenght=%d\n", itm->length, itm->time); 1250 //dbg(2, "itm values: time=%d lenght=%d\n", itm->length, itm->time);
961 dbg(2, "next values: (%p) time=%d lenght=%d\n", next, next->dest_length, next->dest_time); 1251 //dbg(2, "next values: (%p) time=%d lenght=%d\n", next, next->dest_length, next->dest_time);
962 itm->dest_length=next->dest_length+itm->length; 1252 itm->dest_length = next->dest_length + itm->length;
963 itm->dest_count=next->dest_count+1; 1253 itm->dest_count = next->dest_count + 1;
964 itm->dest_time=next->dest_time+itm->time; 1254 itm->dest_time = next->dest_time + itm->time;
965 dbg(2, "new values: time=%d lenght=%d\n", itm->dest_length, itm->dest_time); 1255 //dbg(2, "new values: time=%d lenght=%d\n", itm->dest_length, itm->dest_time);
966 return; 1256 return;
967 } 1257 }
968 while (itm) { 1258 while (itm)
1259 {
969 len+=itm->length; 1260 len += itm->length;
970 time+=itm->time; 1261 time += itm->time;
971 itm->dest_length=len; 1262 itm->dest_length = len;
972 itm->dest_time=time; 1263 itm->dest_time = time;
973 itm->dest_count=count++; 1264 itm->dest_count = count++;
974 itm=itm->prev; 1265 itm = itm->prev;
975 } 1266 }
976 dbg(1,"len %d time %d\n", len, time); 1267 //dbg(1, "len %d time %d\n", len, time);
977} 1268}
978 1269
979/** 1270/**
980 * @brief Checks if two navigation items are on the same street 1271 * @brief Checks if two navigation items are on the same street
981 * 1272 *
985 * 1276 *
986 * @param old The first item to be checked 1277 * @param old The first item to be checked
987 * @param new The second item to be checked 1278 * @param new The second item to be checked
988 * @return True if both old and new are on the same street 1279 * @return True if both old and new are on the same street
989 */ 1280 */
990static int
991is_same_street2(char *old_name1, char *old_name2, char *new_name1, char *new_name2) 1281static int is_same_street2(char *old_name1, char *old_name2, char *new_name1,
1282 char *new_name2)
992{ 1283{
993 if (old_name1 && new_name1 && !strcmp(old_name1, new_name1)) { 1284 if (old_name1 && new_name1 && !strcmp(old_name1, new_name1))
1285 {
994 dbg(1,"is_same_street: '%s' '%s' vs '%s' '%s' yes (1.)\n", old_name2, new_name2, old_name1, new_name1); 1286 // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' yes (1.)\n", old_name2, new_name2, old_name1, new_name1);
995 return 1; 1287 return 1;
996 } 1288 }
997 if (old_name2 && new_name2 && !strcmp(old_name2, new_name2)) { 1289 if (old_name2 && new_name2 && !strcmp(old_name2, new_name2))
1290 {
998 dbg(1,"is_same_street: '%s' '%s' vs '%s' '%s' yes (2.)\n", old_name2, new_name2, old_name1, new_name1); 1291 // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' yes (2.)\n", old_name2, new_name2, old_name1, new_name1);
999 return 1; 1292 return 1;
1000 } 1293 }
1001 dbg(1,"is_same_street: '%s' '%s' vs '%s' '%s' no\n", old_name2, new_name2, old_name1, new_name1); 1294 // dbg(1, "is_same_street: '%s' '%s' vs '%s' '%s' no\n", old_name2, new_name2, old_name1, new_name1);
1002 return 0; 1295 return 0;
1003} 1296}
1004 1297
1005#if 0 1298#if 0
1006/** 1299/**
1018static int 1311static int
1019is_same_street_systematic(struct navigation_itm *old, struct navigation_itm *new) 1312is_same_street_systematic(struct navigation_itm *old, struct navigation_itm *new)
1020{ 1313{
1021 int slashold,slashnew; 1314 int slashold,slashnew;
1022 if (!old->name2 || !new->name2) 1315 if (!old->name2 || !new->name2)
1023 return 1; 1316 return 1;
1024 slashold=strcspn(old->name2, "/"); 1317 slashold=strcspn(old->name2, "/");
1025 slashnew=strcspn(new->name2, "/"); 1318 slashnew=strcspn(new->name2, "/");
1026 if (slashold != slashnew || strncmp(old->name2, new->name2, slashold)) 1319 if (slashold != slashnew || strncmp(old->name2, new->name2, slashold))
1027 return 0; 1320 return 0;
1028 return 1; 1321 return 1;
1029} 1322}
1030
1031 1323
1032/** 1324/**
1033 * @brief Check if there are multiple possibilities to drive from old 1325 * @brief Check if there are multiple possibilities to drive from old
1034 * 1326 *
1035 * This function checks, if there are multiple streets connected to the exit of "old". 1327 * This function checks, if there are multiple streets connected to the exit of "old".
1037 * being connected there, and it is not useful if navit creates a maneuver there. 1329 * being connected there, and it is not useful if navit creates a maneuver there.
1038 * 1330 *
1039 * @param new The navigation item we're driving to 1331 * @param new The navigation item we're driving to
1040 * @return True if there are multiple streets 1332 * @return True if there are multiple streets
1041 */ 1333 */
1042static int 1334static int
1043maneuver_multiple_streets(struct navigation_itm *new) 1335maneuver_multiple_streets(struct navigation_itm *new)
1044{ 1336{
1045 if (new->way.next) { 1337 if (new->way.next)
1338 {
1046 return 1; 1339 return 1;
1047 } else { 1340 }
1341 else
1342 {
1048 return 0; 1343 return 0;
1049 } 1344 }
1050} 1345}
1051
1052 1346
1053/** 1347/**
1054 * @brief Check if the new item is entered "straight" 1348 * @brief Check if the new item is entered "straight"
1055 * 1349 *
1056 * This function checks if the new item is entered "straight" from the old item, i.e. if there 1350 * This function checks if the new item is entered "straight" from the old item, i.e. if there
1058 * 1352 *
1059 * @param new The navigation item we're driving to 1353 * @param new The navigation item we're driving to
1060 * @param diff The absolute angle one needs to steer to drive to this item 1354 * @param diff The absolute angle one needs to steer to drive to this item
1061 * @return True if the new item is entered "straight" 1355 * @return True if the new item is entered "straight"
1062 */ 1356 */
1063static int 1357static int
1064maneuver_straight(struct navigation_itm *new, int diff) 1358maneuver_straight(struct navigation_itm *new, int diff)
1065{ 1359{
1066 int curr_diff; 1360 int curr_diff;
1067 struct navigation_way *w; 1361 struct navigation_way *w;
1068 1362
1069 w = new->way.next; 1363 w = new->way.next;
1070 dbg(1,"diff=%d\n", diff); 1364 dbg(1,"diff=%d\n", diff);
1071 while (w) { 1365 while (w)
1366 {
1072 curr_diff=abs(angle_delta(new->prev->angle_end, w->angle2)); 1367 curr_diff=abs(angle_delta(new->prev->angle_end, w->angle2));
1073 dbg(1,"curr_diff=%d\n", curr_diff); 1368 dbg(1,"curr_diff=%d\n", curr_diff);
1074 if (curr_diff < diff) { 1369 if (curr_diff < diff)
1370 {
1075 return 0; 1371 return 0;
1076 } 1372 }
1077 w = w->next; 1373 w = w->next;
1078 } 1374 }
1079 return 1; 1375 return 1;
1080} 1376}
1081#endif 1377#endif
1082 1378
1083static int maneuver_category(enum item_type type) 1379static int maneuver_category(enum item_type type)
1084{ 1380{
1085 switch (type) { 1381 switch (type)
1382 {
1086 case type_street_0: 1383 case type_street_0:
1384 return 1;
1385 case type_street_1_city:
1386 return 2;
1387 case type_street_2_city:
1388 return 3;
1389 case type_street_3_city:
1390 return 4;
1391 case type_street_4_city:
1392 return 5;
1393 case type_highway_city:
1394 return 7;
1395 case type_street_1_land:
1396 return 2;
1397 case type_street_2_land:
1398 return 3;
1399 case type_street_3_land:
1400 return 4;
1401 case type_street_4_land:
1402 return 5;
1403 case type_street_n_lanes:
1404 return 6;
1405 case type_highway_land:
1406 return 7;
1407 case type_ramp:
1408 return 0;
1409 case type_roundabout:
1410 return 0;
1411 case type_ferry:
1412 return 0;
1413 default:
1414 return 0;
1415 }
1416
1417}
1418
1419static int is_way_allowed(struct navigation *nav, struct navigation_way *way,
1420 int mode)
1421{
1422 if (!nav->vehicleprofile)
1423 {
1087 return 1; 1424 return 1;
1088 case type_street_1_city:
1089 return 2;
1090 case type_street_2_city:
1091 return 3;
1092 case type_street_3_city:
1093 return 4;
1094 case type_street_4_city:
1095 return 5;
1096 case type_highway_city:
1097 return 7;
1098 case type_street_1_land:
1099 return 2;
1100 case type_street_2_land:
1101 return 3;
1102 case type_street_3_land:
1103 return 4;
1104 case type_street_4_land:
1105 return 5;
1106 case type_street_n_lanes:
1107 return 6;
1108 case type_highway_land:
1109 return 7;
1110 case type_ramp:
1111 return 0;
1112 case type_roundabout:
1113 return 0;
1114 case type_ferry:
1115 return 0;
1116 default:
1117 return 0;
1118 } 1425 }
1119 1426 return !way->flags || ((way->flags
1120 1427 & (way->dir >= 0 ? nav->vehicleprofile->flags_forward_mask
1121} 1428 : nav->vehicleprofile->flags_reverse_mask))
1122 1429 == nav->vehicleprofile->flags);
1123static int
1124is_way_allowed(struct navigation *nav, struct navigation_way *way, int mode)
1125{
1126 if (!nav->vehicleprofile)
1127 return 1;
1128 return !way->flags || ((way->flags & (way->dir >= 0 ? nav->vehicleprofile->flags_forward_mask : nav->vehicleprofile->flags_reverse_mask)) == nav->vehicleprofile->flags);
1129} 1430}
1130 1431
1131/** 1432/**
1132 * @brief Checks if navit has to create a maneuver to drive from old to new 1433 * @brief Checks if navit has to create a maneuver to drive from old to new
1133 * 1434 *
1138 * @param new The new navigation item, where we're going to 1439 * @param new The new navigation item, where we're going to
1139 * @param delta The angle the user has to steer to navigate from old to new 1440 * @param delta The angle the user has to steer to navigate from old to new
1140 * @param reason A text string explaining how the return value resulted 1441 * @param reason A text string explaining how the return value resulted
1141 * @return True if navit should guide the user, false otherwise 1442 * @return True if navit should guide the user, false otherwise
1142 */ 1443 */
1143static int 1444static int maneuver_required2(struct navigation *nav,
1144maneuver_required2(struct navigation *nav, struct navigation_itm *old, struct navigation_itm *new, int *delta, char **reason) 1445 struct navigation_itm *old, struct navigation_itm *new, int *delta,
1446 char **reason)
1145{ 1447{
1146 int ret=0,d,dw,dlim; 1448 int ret = 0, d, dw, dlim;
1147 char *r=NULL; 1449 char *r = NULL;
1148 struct navigation_way *w; 1450 struct navigation_way *w;
1149 int cat,ncat,wcat,maxcat,left=-180,right=180,is_unambigous=0,is_same_street; 1451 int cat, ncat, wcat, maxcat, left = -180, right = 180, is_unambigous = 0,
1452 is_same_street;
1150 1453
1151 dbg(1,"enter %p %p %p\n",old, new, delta); 1454 //dbg(1, "enter %p %p %p\n", old, new, delta);
1152 d=angle_delta(old->angle_end, new->way.angle2); 1455 d = angle_delta(old->angle_end, new->way.angle2);
1153 if (!new->way.next) { 1456 if (!new->way.next)
1457 {
1154 /* No announcement necessary */ 1458 /* No announcement necessary */
1155 r="no: Only one possibility"; 1459 r = "no: Only one possibility";
1460 }
1156 } else if (!new->way.next->next && new->way.next->item.type == type_ramp && !is_way_allowed(nav,new->way.next,1)) { 1461 else if (!new->way.next->next && new->way.next->item.type == type_ramp
1462 && !is_way_allowed(nav, new->way.next, 1))
1463 {
1157 /* If the other way is only a ramp and it is one-way in the wrong direction, no announcement necessary */ 1464 /* If the other way is only a ramp and it is one-way in the wrong direction, no announcement necessary */
1158 r="no: Only ramp"; 1465 r = "no: Only ramp";
1159 } 1466 }
1160 if (! r) { 1467 if (!r)
1468 {
1161 if ((old->way.flags & AF_ROUNDABOUT) && ! (new->way.flags & AF_ROUNDABOUT)) { 1469 if ((old->way.flags & AF_ROUNDABOUT) && !(new->way.flags
1470 & AF_ROUNDABOUT))
1471 {
1162 r="yes: leaving roundabout"; 1472 r = "yes: leaving roundabout";
1163 ret=1; 1473 ret = 1;
1474 }
1164 } else if (!(old->way.flags & AF_ROUNDABOUT) && (new->way.flags & AF_ROUNDABOUT)) { 1475 else if (!(old->way.flags & AF_ROUNDABOUT) && (new->way.flags
1476 & AF_ROUNDABOUT))
1477 {
1165 r="no: entering roundabout"; 1478 r = "no: entering roundabout";
1479 }
1166 } else if ((old->way.flags & AF_ROUNDABOUT) && (new->way.flags & AF_ROUNDABOUT)) 1480 else if ((old->way.flags & AF_ROUNDABOUT) && (new->way.flags
1481 & AF_ROUNDABOUT))
1167 r="no: staying in roundabout"; 1482 r = "no: staying in roundabout";
1168 } 1483 }
1169 if (!r && abs(d) > 75) { 1484 if (!r && abs(d) > 75)
1485 {
1170 /* always make an announcement if you have to make a sharp turn */ 1486 /* always make an announcement if you have to make a sharp turn */
1171 r="yes: delta over 75"; 1487 r = "yes: delta over 75";
1172 ret=1; 1488 ret = 1;
1173 } 1489 }
1174 cat=maneuver_category(old->way.item.type); 1490 cat = maneuver_category(old->way.item.type);
1175 ncat=maneuver_category(new->way.item.type); 1491 ncat = maneuver_category(new->way.item.type);
1176 if (!r) { 1492 if (!r)
1493 {
1177 /* Check whether the street keeps its name */ 1494 /* Check whether the street keeps its name */
1178 is_same_street=is_same_street2(old->way.name1, old->way.name2, new->way.name1, new->way.name2); 1495 is_same_street = is_same_street2(old->way.name1, old->way.name2,
1496 new->way.name1, new->way.name2);
1179 w = new->way.next; 1497 w = new->way.next;
1180 maxcat=-1; 1498 maxcat = -1;
1181 while (w) { 1499 while (w)
1500 {
1182 dw=angle_delta(old->angle_end, w->angle2); 1501 dw = angle_delta(old->angle_end, w->angle2);
1183 if (dw < 0) { 1502 if (dw < 0)
1503 {
1184 if (dw > left) 1504 if (dw > left)
1185 left=dw; 1505 left = dw;
1506 }
1186 } else { 1507 else
1508 {
1187 if (dw < right) 1509 if (dw < right)
1188 right=dw; 1510 right = dw;
1189 } 1511 }
1190 wcat=maneuver_category(w->item.type); 1512 wcat = maneuver_category(w->item.type);
1191 /* If any other street has the same name but isn't a highway (a highway might split up temporarily), then 1513 /* If any other street has the same name but isn't a highway (a highway might split up temporarily), then
1192 we can't use the same name criterium */ 1514 we can't use the same name criterium */
1193 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)) 1515 if (is_same_street && is_same_street2(old->way.name1,
1516 old->way.name2, w->name1, w->name2) && (cat != 7 || wcat
1517 != 7) && is_way_allowed(nav, w, 2))
1194 is_same_street=0; 1518 is_same_street = 0;
1195 /* Even if the ramp has the same name, announce it */ 1519 /* Even if the ramp has the same name, announce it */
1196 if (new->way.item.type == type_ramp && old->way.item.type != type_ramp) 1520 if (new->way.item.type == type_ramp && old->way.item.type
1521 != type_ramp)
1197 is_same_street=0; 1522 is_same_street = 0;
1198 /* Mark if the street has a higher or the same category */ 1523 /* Mark if the street has a higher or the same category */
1199 if (wcat > maxcat) 1524 if (wcat > maxcat)
1200 maxcat=wcat; 1525 maxcat = wcat;
1201 w = w->next; 1526 w = w->next;
1202 } 1527 }
1203 /* get the delta limit for checking for other streets. It is lower if the street has no other 1528 /* get the delta limit for checking for other streets. It is lower if the street has no other
1204 streets of the same or higher category */ 1529 streets of the same or higher category */
1205 if (ncat < cat) 1530 if (ncat < cat)
1206 dlim=80; 1531 dlim = 80;
1207 else 1532 else
1208 dlim=120; 1533 dlim = 120;
1209 /* if the street is really straight, the others might be closer to straight */ 1534 /* if the street is really straight, the others might be closer to straight */
1210 if (abs(d) < 20) 1535 if (abs(d) < 20)
1211 dlim/=2; 1536 dlim /= 2;
1212 if ((maxcat == ncat && maxcat == cat) || (ncat == 0 && cat == 0)) 1537 if ((maxcat == ncat && maxcat == cat) || (ncat == 0 && cat == 0))
1213 dlim=abs(d)*620/256; 1538 dlim = abs(d) * 620 / 256;
1214 else if (maxcat < ncat && maxcat < cat) 1539 else if (maxcat < ncat && maxcat < cat)
1215 dlim=abs(d)*128/256; 1540 dlim = abs(d) * 128 / 256;
1216 if (left < -dlim && right > dlim) 1541 if (left < -dlim && right > dlim)
1217 is_unambigous=1; 1542 is_unambigous = 1;
1218 if (!is_same_street && is_unambigous < 1) { 1543 if (!is_same_street && is_unambigous < 1)
1544 {
1219 ret=1; 1545 ret = 1;
1220 r="yes: not same street or ambigous"; 1546 r = "yes: not same street or ambigous";
1547 }
1221 } else 1548 else
1222 r="no: same street and unambigous"; 1549 r = "no: same street and unambigous";
1223#ifdef DEBUG 1550#ifdef DEBUG
1224 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); 1551 // 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);
1225#endif 1552#endif
1226 } 1553 }
1227 *delta=d; 1554 *delta = d;
1228 if (reason) 1555 if (reason)
1556 {
1229 *reason=r; 1557 *reason = r;
1558 }
1230 return ret; 1559 return ret;
1231
1232 1560
1233#if 0 1561#if 0
1234 if (new->item.type == old->item.type || (new->item.type != type_ramp && old->item.type != type_ramp)) { 1562 if (new->item.type == old->item.type || (new->item.type != type_ramp && old->item.type != type_ramp))
1563 {
1235 if (is_same_street2(old, new)) { 1564 if (is_same_street2(old, new))
1565 {
1236 if (! entering_straight(new, abs(*delta))) { 1566 if (! entering_straight(new, abs(*delta)))
1567 {
1237 dbg(1, "maneuver_required: Not driving straight: yes\n"); 1568 dbg(1, "maneuver_required: Not driving straight: yes\n");
1238 if (reason) 1569 if (reason)
1239 *reason="yes: Not driving straight"; 1570 *reason="yes: Not driving straight";
1240 return 1; 1571 return 1;
1241 } 1572 }
1242 1573
1243 if (check_multiple_streets(new)) { 1574 if (check_multiple_streets(new))
1575 {
1244 if (entering_straight(new,abs(*delta)*2)) { 1576 if (entering_straight(new,abs(*delta)*2))
1577 {
1245 if (reason) 1578 if (reason)
1246 *reason="no: delta < ext_limit for same name"; 1579 *reason="no: delta < ext_limit for same name";
1247 return 0; 1580 return 0;
1248 } 1581 }
1249 if (reason) 1582 if (reason)
1250 *reason="yes: delta > ext_limit for same name"; 1583 *reason="yes: delta > ext_limit for same name";
1251 return 1; 1584 return 1;
1585 }
1252 } else { 1586 else
1587 {
1253 dbg(1, "maneuver_required: Staying on the same street: no\n"); 1588 dbg(1, "maneuver_required: Staying on the same street: no\n");
1254 if (reason) 1589 if (reason)
1255 *reason="no: Staying on same street"; 1590 *reason="no: Staying on same street";
1256 return 0; 1591 return 0;
1257 } 1592 }
1258 } 1593 }
1594 }
1259 } else 1595 else
1260 dbg(1, "maneuver_required: old or new is ramp\n"); 1596 dbg(1, "maneuver_required: old or new is ramp\n");
1261#if 0 1597#if 0
1262 if (old->item.type == type_ramp && (new->item.type == type_highway_city || new->item.type == type_highway_land)) { 1598 if (old->item.type == type_ramp && (new->item.type == type_highway_city || new->item.type == type_highway_land))
1599 {
1263 dbg(1, "no_maneuver_required: old is ramp new is highway\n"); 1600 dbg(1, "no_maneuver_required: old is ramp new is highway\n");
1264 if (reason) 1601 if (reason)
1265 *reason="no: old is ramp new is highway"; 1602 *reason="no: old is ramp new is highway";
1266 return 0; 1603 return 0;
1267 } 1604 }
1268#endif 1605#endif
1269#if 0 1606#if 0
1270 if (old->crossings_end == 2) { 1607 if (old->crossings_end == 2)
1608 {
1271 dbg(1, "maneuver_required: only 2 connections: no\n"); 1609 dbg(1, "maneuver_required: only 2 connections: no\n");
1272 return 0; 1610 return 0;
1273 } 1611 }
1274#endif 1612#endif
1275 dbg(1,"delta=%d-%d=%d\n", new->way.angle2, old->angle_end, *delta); 1613 dbg(1,"delta=%d-%d=%d\n", new->way.angle2, old->angle_end, *delta);
1276 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))) { 1614 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)))
1615 {
1277 dbg(1, "maneuver_required: highway changed name\n"); 1616 dbg(1, "maneuver_required: highway changed name\n");
1278 if (reason) 1617 if (reason)
1279 *reason="yes: highway changed name"; 1618 *reason="yes: highway changed name";
1280 return 1; 1619 return 1;
1281 } 1620 }
1282 if (abs(*delta) < straight_limit) { 1621 if (abs(*delta) < straight_limit)
1622 {
1283 if (! entering_straight(new,abs(*delta))) { 1623 if (! entering_straight(new,abs(*delta)))
1624 {
1284 if (reason) 1625 if (reason)
1285 *reason="yes: not straight"; 1626 *reason="yes: not straight";
1286 dbg(1, "maneuver_required: not driving straight: yes\n"); 1627 dbg(1, "maneuver_required: not driving straight: yes\n");
1287 return 1; 1628 return 1;
1288 } 1629 }
1289 1630
1290 dbg(1, "maneuver_required: delta(%d) < %d: no\n", *delta, straight_limit); 1631 dbg(1, "maneuver_required: delta(%d) < %d: no\n", *delta, straight_limit);
1291 if (reason) 1632 if (reason)
1292 *reason="no: delta < limit"; 1633 *reason="no: delta < limit";
1293 return 0; 1634 return 0;
1294 } 1635 }
1295 if (abs(*delta) < ext_straight_limit) { 1636 if (abs(*delta) < ext_straight_limit)
1637 {
1296 if (entering_straight(new,abs(*delta)*2)) { 1638 if (entering_straight(new,abs(*delta)*2))
1639 {
1297 if (reason) 1640 if (reason)
1298 *reason="no: delta < ext_limit"; 1641 *reason="no: delta < ext_limit";
1299 return 0; 1642 return 0;
1300 } 1643 }
1301 } 1644 }
1302 1645
1303 if (! check_multiple_streets(new)) { 1646 if (! check_multiple_streets(new))
1647 {
1304 dbg(1, "maneuver_required: only one possibility: no\n"); 1648 dbg(1, "maneuver_required: only one possibility: no\n");
1305 if (reason) 1649 if (reason)
1306 *reason="no: only one possibility"; 1650 *reason="no: only one possibility";
1307 return 0; 1651 return 0;
1308 } 1652 }
1309 1653
1310 dbg(1, "maneuver_required: delta=%d: yes\n", *delta); 1654 dbg(1, "maneuver_required: delta=%d: yes\n", *delta);
1311 if (reason) 1655 if (reason)
1312 *reason="yes: delta >= limit"; 1656 *reason="yes: delta >= limit";
1313 return 1; 1657 return 1;
1314#endif 1658#endif
1315} 1659}
1316 1660
1317static struct navigation_command * 1661static struct navigation_command *
1318command_new(struct navigation *this_, struct navigation_itm *itm, int delta) 1662command_new(struct navigation *this_, struct navigation_itm *itm, int delta)
1319{ 1663{
1320 struct navigation_command *ret=g_new0(struct navigation_command, 1); 1664 struct navigation_command *ret=g_new0(struct navigation_command, 1);
1321 dbg(1,"enter this_=%p itm=%p delta=%d\n", this_, itm, delta); 1665 //dbg(1, "enter this_=%p itm=%p delta=%d\n", this_, itm, delta);
1322 ret->delta=delta; 1666 ret->delta = delta;
1323 ret->itm=itm; 1667 ret->itm = itm;
1324 if (itm && itm->prev && itm->way.next && itm->prev->way.next && !(itm->way.flags & AF_ROUNDABOUT) && (itm->prev->way.flags & AF_ROUNDABOUT)) { 1668 if (itm && itm->prev && itm->way.next && itm->prev->way.next
1669 && !(itm->way.flags & AF_ROUNDABOUT) && (itm->prev->way.flags
1670 & AF_ROUNDABOUT))
1671 {
1325 int len=0; 1672 int len = 0;
1326 int angle=0; 1673 int angle = 0;
1327 int entry_angle; 1674 int entry_angle;
1328 struct navigation_itm *itm2=itm->prev; 1675 struct navigation_itm *itm2 = itm->prev;
1329 int exit_angle=angle_median(itm->prev->angle_end, itm->way.next->angle2); 1676 int exit_angle = angle_median(itm->prev->angle_end,
1677 itm->way.next->angle2);
1330 dbg(1,"exit %d median from %d,%d\n", exit_angle,itm->prev->angle_end, itm->way.next->angle2); 1678 //dbg(1, "exit %d median from %d,%d\n", exit_angle, itm->prev->angle_end, itm->way.next->angle2);
1331 while (itm2 && (itm2->way.flags & AF_ROUNDABOUT)) { 1679 while (itm2 && (itm2->way.flags & AF_ROUNDABOUT))
1680 {
1332 len+=itm2->length; 1681 len += itm2->length;
1333 angle=itm2->angle_end; 1682 angle = itm2->angle_end;
1334 itm2=itm2->prev; 1683 itm2 = itm2->prev;
1335 } 1684 }
1336 if (itm2 && itm2->next && itm2->next->way.next) { 1685 if (itm2 && itm2->next && itm2->next->way.next)
1686 {
1337 itm2=itm2->next; 1687 itm2 = itm2->next;
1338 entry_angle=angle_median(angle_opposite(itm2->way.angle2), itm2->way.next->angle2); 1688 entry_angle = angle_median(angle_opposite(itm2->way.angle2),
1689 itm2->way.next->angle2);
1339 dbg(1,"entry %d median from %d(%d),%d\n", entry_angle,angle_opposite(itm2->way.angle2), itm2->way.angle2, itm2->way.next->angle2); 1690 // dbg(1, "entry %d median from %d(%d),%d\n", entry_angle, angle_opposite(itm2->way.angle2), itm2->way.angle2, itm2->way.next->angle2);
1691 }
1340 } else { 1692 else
1693 {
1341 entry_angle=angle_opposite(angle); 1694 entry_angle = angle_opposite(angle);
1342 } 1695 }
1343 dbg(0,"entry %d exit %d\n", entry_angle, exit_angle); 1696 //dbg(0, "entry %d exit %d\n", entry_angle, exit_angle);
1344 ret->roundabout_delta=angle_delta(entry_angle, exit_angle); 1697 ret->roundabout_delta = angle_delta(entry_angle, exit_angle);
1345 ret->length=len+roundabout_extra_length; 1698 ret->length = len + roundabout_extra_length;
1346 } 1699 }
1347 if (this_->cmd_last) { 1700 if (this_->cmd_last)
1701 {
1348 this_->cmd_last->next=ret; 1702 this_->cmd_last->next = ret;
1349 ret->prev = this_->cmd_last; 1703 ret->prev = this_->cmd_last;
1350 } 1704 }
1351 this_->cmd_last=ret; 1705 this_->cmd_last = ret;
1352 1706
1353 if (!this_->cmd_first) 1707 if (!this_->cmd_first)
1354 this_->cmd_first=ret; 1708 this_->cmd_first = ret;
1355 return ret; 1709 return ret;
1356} 1710}
1357 1711
1358static void
1359make_maneuvers(struct navigation *this_, struct route *route) 1712static void make_maneuvers(struct navigation *this_, struct route *route)
1360{ 1713{
1361 struct navigation_itm *itm, *last=NULL, *last_itm=NULL; 1714 struct navigation_itm *itm, *last = NULL, *last_itm = NULL;
1362 int delta; 1715 int delta;
1363 itm=this_->first; 1716 itm = this_->first;
1364 this_->cmd_last=NULL; 1717 this_->cmd_last = NULL;
1365 this_->cmd_first=NULL; 1718 this_->cmd_first = NULL;
1366 while (itm) { 1719 while (itm)
1720 {
1367 if (last) { 1721 if (last)
1722 {
1368 if (maneuver_required2(this_, last_itm, itm,&delta,NULL)) { 1723 if (maneuver_required2(this_, last_itm, itm, &delta, NULL))
1724 {
1369 command_new(this_, itm, delta); 1725 command_new(this_, itm, delta);
1370 } 1726 }
1727 }
1371 } else 1728 else
1372 last=itm; 1729 last = itm;
1373 last_itm=itm; 1730 last_itm = itm;
1374 itm=itm->next; 1731 itm = itm->next;
1375 } 1732 }
1376 command_new(this_, last_itm, 0); 1733 command_new(this_, last_itm, 0);
1377} 1734}
1378 1735
1379static int
1380contains_suffix(char *name, char *suffix) 1736static int contains_suffix(char *name, char *suffix)
1381{ 1737{
1382 if (!suffix) 1738 if (!suffix)
1383 return 0; 1739 return 0;
1384 if (strlen(name) < strlen(suffix)) 1740 if (strlen(name) < strlen(suffix))
1385 return 0; 1741 return 0;
1386 return !g_strcasecmp(name+strlen(name)-strlen(suffix), suffix); 1742 return !g_strcasecmp(name + strlen(name) - strlen(suffix), suffix);
1387} 1743}
1388 1744
1389static char * 1745static char *
1390replace_suffix(char *name, char *search, char *replace) 1746replace_suffix(char *name, char *search, char *replace)
1391{ 1747{
1392 int len=strlen(name)-strlen(search); 1748 int len = strlen(name) - strlen(search);
1393 char *ret=g_malloc(len+strlen(replace)+1); 1749 char *ret = g_malloc(len + strlen(replace) + 1);
1394 strncpy(ret, name, len); 1750 strncpy(ret, name, len);
1395 strcpy(ret+len, replace); 1751 strcpy(ret + len, replace);
1396 if (isupper(name[len])) { 1752 if (isupper(name[len]))
1753 {
1397 ret[len]=toupper(ret[len]); 1754 ret[len] = toupper(ret[len]);
1398 } 1755 }
1399 1756
1400 return ret; 1757 return ret;
1401} 1758}
1402 1759
1403static char * 1760static char *
1404navigation_item_destination(struct navigation *nav, struct navigation_itm *itm, struct navigation_itm *next, char *prefix) 1761navigation_item_destination(struct navigation *nav, struct navigation_itm *itm,
1762 struct navigation_itm *next, char *prefix)
1405{ 1763{
1406 char *ret=NULL,*name1,*sep,*name2; 1764 char *ret = NULL, *name1, *sep, *name2;
1407 char *n1,*n2; 1765 char *n1, *n2;
1408 int i,sex; 1766 int i, sex;
1409 int vocabulary1=65535; 1767 int vocabulary1 = 65535;
1410 int vocabulary2=65535; 1768 int vocabulary2 = 65535;
1411 struct attr attr; 1769 struct attr attr;
1412 1770
1413 if (! prefix) 1771 if (!prefix)
1414 prefix=""; 1772 prefix = "";
1415 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name, &attr, NULL)) 1773 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name,
1774 &attr, NULL))
1416 vocabulary1=attr.u.num; 1775 vocabulary1 = attr.u.num;
1417 if (nav->speech && speech_get_attr(nav->speech, attr_vocabulary_name_systematic, &attr, NULL)) 1776 if (nav->speech && speech_get_attr(nav->speech,
1777 attr_vocabulary_name_systematic, &attr, NULL))
1418 vocabulary2=attr.u.num; 1778 vocabulary2 = attr.u.num;
1419 n1=itm->way.name1; 1779 n1 = itm->way.name1;
1420 n2=itm->way.name2; 1780 n2 = itm->way.name2;
1421 if (!vocabulary1) 1781 if (!vocabulary1)
1422 n1=NULL; 1782 n1 = NULL;
1423 if (!vocabulary2) 1783 if (!vocabulary2)
1424 n2=NULL; 1784 n2 = NULL;
1425 if(!n1 && !n2 && itm->way.item.type == type_ramp && vocabulary2) { 1785 if (!n1 && !n2 && itm->way.item.type == type_ramp && vocabulary2)
1786 {
1426 dbg(1,">> Next is ramp %lx current is %lx \n", itm->way.item.type, next->way.item.type); 1787 //dbg(1,">> Next is ramp %lx current is %lx \n", itm->way.item.type, next->way.item.type);
1427 1788
1428 if(next->way.item.type == type_ramp) 1789 if (next->way.item.type == type_ramp)
1429 return NULL; 1790 return NULL;
1430 if(itm->way.item.type == type_highway_city || itm->way.item.type == type_highway_land ) 1791 if (itm->way.item.type == type_highway_city || itm->way.item.type
1792 == type_highway_land)
1793 {
1794#ifdef HAVE_API_ANDROID
1795 android_send_generic_text(1,"+*#O:exit\n");
1796 gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
1797 android_send_generic_text(1,xy);
1798 g_free(xy);
1799#endif
1431 return g_strdup_printf("%s%s",prefix,_("exit")); /* %FIXME Can this even be reached? */ 1800 return g_strdup_printf("%s%s", prefix, _("exit")); /* %FIXME Can this even be reached? and "exit" is the wrong text anyway ! */
1801 }
1432 else 1802 else
1803 {
1804#ifdef HAVE_API_ANDROID
1805 android_send_generic_text(1,"+*#O:into the ramp\n");
1806 gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
1807 android_send_generic_text(1,xy);
1808 g_free(xy);
1809#endif
1433 return g_strdup_printf("%s%s",prefix,_("into the ramp")); 1810 return g_strdup_printf("%s%s", prefix, _("into the ramp"));
1434 1811 }
1812
1435 } 1813 }
1814
1436 if (!n1 && !n2) 1815 if (!n1 && !n2)
1816 {
1437 return NULL; 1817 return NULL;
1818 }
1819
1438 if (n1) { 1820 if (n1)
1821 {
1439 sex=-1; 1822 sex = -1;
1440 name1=NULL; 1823 name1 = NULL;
1441 for (i = 0 ; i < sizeof(suffixes)/sizeof(suffixes[0]) ; i++) { 1824 for (i = 0; i < sizeof(suffixes) / sizeof(suffixes[0]); i++)
1825 {
1442 if (contains_suffix(n1,suffixes[i].fullname)) { 1826 if (contains_suffix(n1, suffixes[i].fullname))
1827 {
1443 sex=suffixes[i].sex; 1828 sex = suffixes[i].sex;
1444 name1=g_strdup(n1); 1829 name1 = g_strdup(n1);
1445 break; 1830 break;
1446 } 1831 }
1447 if (contains_suffix(n1,suffixes[i].abbrev)) { 1832 if (contains_suffix(n1, suffixes[i].abbrev))
1833 {
1448 sex=suffixes[i].sex; 1834 sex = suffixes[i].sex;
1449 name1=replace_suffix(n1, suffixes[i].abbrev, suffixes[i].fullname); 1835 name1 = replace_suffix(n1, suffixes[i].abbrev,
1836 suffixes[i].fullname);
1450 break; 1837 break;
1451 } 1838 }
1452 } 1839 }
1840
1453 if (n2) { 1841 if (n2)
1842 {
1454 name2=n2; 1843 name2 = n2;
1455 sep=" "; 1844 sep = " ";
1845 }
1456 } else { 1846 else
1847 {
1457 name2=""; 1848 name2 = "";
1458 sep=""; 1849 sep = "";
1459 } 1850 }
1851
1852 gchar* xy;
1460 switch (sex) { 1853 switch (sex)
1854 {
1461 case -1: 1855 case -1:
1856#ifdef HAVE_API_ANDROID
1857 android_send_generic_text(1,"+*#O:%sinto the street %s%s%s\n");
1858 xy=g_strdup_printf("+*#1:%s\n", prefix);
1859 android_send_generic_text(1,xy);
1860 g_free(xy);
1861 xy=g_strdup_printf("+*#1:%s\n", n1);
1862 android_send_generic_text(1,xy);
1863 g_free(xy);
1864 xy=g_strdup_printf("+*#1:%s\n", sep);
1865 android_send_generic_text(1,xy);
1866 g_free(xy);
1867 xy=g_strdup_printf("+*#1:%s\n", name2);
1868 android_send_generic_text(1,xy);
1869 g_free(xy);
1870#endif
1462 /* TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name */ 1871 // TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name
1463 ret=g_strdup_printf(_("%sinto the street %s%s%s"),prefix,n1, sep, name2); 1872 ret = g_strdup_printf(_("%sinto the street %s%s%s"), prefix,
1873 n1, sep, name2);
1464 break; 1874 break;
1465 case 1: 1875 case 1:
1876#ifdef HAVE_API_ANDROID
1877 android_send_generic_text(1,"+*#O:%sinto the %s%s%s|male form\n");
1878 xy=g_strdup_printf("+*#1:%s\n", prefix);
1879 android_send_generic_text(1,xy);
1880 g_free(xy);
1881 xy=g_strdup_printf("+*#1:%s\n", name1);
1882 android_send_generic_text(1,xy);
1883 g_free(xy);
1884 xy=g_strdup_printf("+*#1:%s\n", sep);
1885 android_send_generic_text(1,xy);
1886 g_free(xy);
1887 xy=g_strdup_printf("+*#1:%s\n", name2);
1888 android_send_generic_text(1,xy);
1889 g_free(xy);
1890#endif
1466 /* TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name. Male form. The stuff after | doesn't have to be included */ 1891 // TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name. Male form. The stuff after | doesn't have to be included
1467 ret=g_strdup_printf(_("%sinto the %s%s%s|male form"),prefix,name1, sep, name2); 1892 ret = g_strdup_printf(_("%sinto the %s%s%s|male form"), prefix,
1893 name1, sep, name2);
1468 break; 1894 break;
1469 case 2: 1895 case 2:
1896#ifdef HAVE_API_ANDROID
1897 android_send_generic_text(1,"+*#O:%sinto the %s%s%s|female form\n");
1898 xy=g_strdup_printf("+*#1:%s\n", prefix);
1899 android_send_generic_text(1,xy);
1900 g_free(xy);
1901 xy=g_strdup_printf("+*#1:%s\n", name1);
1902 android_send_generic_text(1,xy);
1903 g_free(xy);
1904 xy=g_strdup_printf("+*#1:%s\n", sep);
1905 android_send_generic_text(1,xy);
1906 g_free(xy);
1907 xy=g_strdup_printf("+*#1:%s\n", name2);
1908 android_send_generic_text(1,xy);
1909 g_free(xy);
1910#endif
1470 /* TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name. Female form. The stuff after | doesn't have to be included */ 1911 // TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name. Female form. The stuff after | doesn't have to be included
1471 ret=g_strdup_printf(_("%sinto the %s%s%s|female form"),prefix,name1, sep, name2); 1912 ret = g_strdup_printf(_("%sinto the %s%s%s|female form"),
1913 prefix, name1, sep, name2);
1472 break; 1914 break;
1473 case 3: 1915 case 3:
1916#ifdef HAVE_API_ANDROID
1917 android_send_generic_text(1,"+*#O:%sinto the %s%s%s|neutral form\n");
1918 xy=g_strdup_printf("+*#1:%s\n", prefix);
1919 android_send_generic_text(1,xy);
1920 g_free(xy);
1921 xy=g_strdup_printf("+*#1:%s\n", name1);
1922 android_send_generic_text(1,xy);
1923 g_free(xy);
1924 xy=g_strdup_printf("+*#1:%s\n", sep);
1925 android_send_generic_text(1,xy);
1926 g_free(xy);
1927 xy=g_strdup_printf("+*#1:%s\n", name2);
1928 android_send_generic_text(1,xy);
1929 g_free(xy);
1930#endif
1474 /* TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name. Neutral form. The stuff after | doesn't have to be included */ 1931 // TRANSLATORS: Arguments: 1: Prefix (Space if required) 2: Street Name 3: Separator (Space if required), 4: Systematic Street Name. Neutral form. The stuff after | doesn't have to be included
1475 ret=g_strdup_printf(_("%sinto the %s%s%s|neutral form"),prefix,name1, sep, name2); 1932 ret = g_strdup_printf(_("%sinto the %s%s%s|neutral form"),
1933 prefix, name1, sep, name2);
1476 break; 1934 break;
1477 } 1935 }
1478 g_free(name1); 1936 g_free(name1);
1479 1937
1938 }
1480 } else 1939 else
1940 {
1941#ifdef HAVE_API_ANDROID
1942 android_send_generic_text(1,"+*#O:sinto the %s\n");
1943 gchar* xy=g_strdup_printf("+*#1:%s\n", prefix);
1944 android_send_generic_text(1,xy);
1945 g_free(xy);
1946 xy=g_strdup_printf("+*#1:%s\n", n2);
1947 android_send_generic_text(1,xy);
1948 g_free(xy);
1949#endif
1481 /* TRANSLATORS: gives the name of the next road to turn into (into the E17) */ 1950 // TRANSLATORS: gives the name of the next road to turn into (into the E17)
1482 ret=g_strdup_printf(_("%sinto the %s"),prefix,n2); 1951 ret = g_strdup_printf(_("%sinto the %s"), prefix, n2);
1952 }
1953
1483 name1=ret; 1954 name1 = ret;
1955
1484 while (name1 && *name1) { 1956 while (name1 && *name1)
1957 {
1485 switch (*name1) { 1958 switch (*name1)
1959 {
1486 case '|': 1960 case '|':
1487 *name1='\0'; 1961 *name1 = '\0';
1488 break; 1962 break;
1489 case '/': 1963 case '/':
1490 *name1++=' '; 1964 *name1++ = ' ';
1491 break; 1965 break;
1492 default: 1966 default:
1493 name1++; 1967 name1++;
1494 }
1495 } 1968 }
1969 }
1970
1496 return ret; 1971 return ret;
1497} 1972}
1498 1973
1499static char * 1974static char *
1500show_maneuver(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type, int connect) 1975show_maneuver(struct navigation *nav, struct navigation_itm *itm,
1976 struct navigation_command *cmd, enum attr_type type, int connect)
1501{ 1977{
1502 /* TRANSLATORS: right, as in 'Turn right' */ 1978 // TRANSLATORS: right, as in 'Turn right'
1503 char *dir=_("right"),*strength=""; 1979 char *dir = _("right");
1980 char *strength = "";
1504 int distance=itm->dest_length-cmd->itm->dest_length; 1981 int distance = itm->dest_length - cmd->itm->dest_length;
1505 char *d,*ret=NULL; 1982 char *d, *ret = NULL;
1506 int delta=cmd->delta; 1983 int delta = cmd->delta;
1507 int level; 1984 int level;
1508 int strength_needed; 1985 int strength_needed;
1509 int skip_roads; 1986 int skip_roads;
1510 int count_roundabout; 1987 int count_roundabout;
1511 struct navigation_itm *cur; 1988 struct navigation_itm *cur;
1512 struct navigation_way *w; 1989 struct navigation_way *w;
1513 1990
1514 if (connect) { 1991 if (connect)
1992 {
1515 level = -2; // level = -2 means "connect to another maneuver via 'then ...'" 1993 level = -2; // level = -2 means "connect to another maneuver via 'then ...'"
1516 } else { 1994 }
1995 else
1996 {
1517 level=1; 1997 level = 1;
1518 } 1998 }
1519 1999
1520 w = itm->next->way.next; 2000 w = itm->next->way.next;
1521 strength_needed = 0; 2001 strength_needed = 0;
2002
1522 if (angle_delta(itm->next->way.angle2,itm->angle_end) < 0) { 2003 if (angle_delta(itm->next->way.angle2, itm->angle_end) < 0)
2004 {
1523 while (w) { 2005 while (w)
2006 {
1524 if (angle_delta(w->angle2,itm->angle_end) < 0) { 2007 if (angle_delta(w->angle2, itm->angle_end) < 0)
2008 {
1525 strength_needed = 1; 2009 strength_needed = 1;
1526 break; 2010 break;
1527 } 2011 }
1528 w = w->next; 2012 w = w->next;
1529 } 2013 }
1530 } else { 2014 }
2015 else
2016 {
1531 while (w) { 2017 while (w)
2018 {
1532 if (angle_delta(w->angle2,itm->angle_end) > 0) { 2019 if (angle_delta(w->angle2, itm->angle_end) > 0)
2020 {
1533 strength_needed = 1; 2021 strength_needed = 1;
1534 break; 2022 break;
1535 } 2023 }
1536 w = w->next; 2024 w = w->next;
1537 } 2025 }
1538 } 2026 }
1539 2027
1540 if (delta < 0) { 2028 if (delta < 0)
2029 {
2030#ifdef HAVE_API_ANDROID
2031 android_send_generic_text(1,"+*#O:left\n");
2032#endif
1541 /* TRANSLATORS: left, as in 'Turn left' */ 2033 // TRANSLATORS: left, as in 'Turn left'
1542 dir=_("left"); 2034 dir = _("left");
1543 delta=-delta; 2035 delta = -delta;
1544 } 2036 }
2037 else
2038 {
2039 // dir = right
2040#ifdef HAVE_API_ANDROID
2041 android_send_generic_text(1,"+*#O:right\n");
2042#endif
2043 }
1545 2044
1546 if (strength_needed) { 2045 if (strength_needed)
2046 {
1547 if (delta < 45) { 2047 if (delta < 45)
2048 {
2049#ifdef HAVE_API_ANDROID
2050 android_send_generic_text(1,"+*#O:slight \n");
2051#endif
1548 /* TRANSLATORS: Don't forget the ending space */ 2052 // TRANSLATORS: Don't forget the ending space
2053 // TRANSLATORS: EXAMPLE: turn slight right
1549 strength=_("easily "); 2054 strength = _("slight ");
2055 }
1550 } else if (delta < 105) { 2056 else if (delta < 105)
2057 {
1551 strength=""; 2058 strength = "";
2059 }
1552 } else if (delta < 165) { 2060 else if (delta < 165)
2061 {
2062#ifdef HAVE_API_ANDROID
2063 android_send_generic_text(1,"+*#O:hard \n");
2064#endif
1553 /* TRANSLATORS: Don't forget the ending space */ 2065 // TRANSLATORS: Don't forget the ending space
2066 // TRANSLATORS: EXAMPLE: turn hard right
1554 strength=_("strongly "); 2067 strength = _("hard ");
2068 }
1555 } else if (delta < 180) { 2069 else if (delta < 180)
2070 {
2071#ifdef HAVE_API_ANDROID
2072 android_send_generic_text(1,"+*#O:really hard \n");
2073#endif
1556 /* TRANSLATORS: Don't forget the ending space */ 2074 // TRANSLATORS: Don't forget the ending space
2075 // TRANSLATORS: EXAMPLE: turn really hard right
1557 strength=_("really strongly "); 2076 strength = _("really hard ");
2077 }
1558 } else { 2078 else
2079 {
1559 dbg(1,"delta=%d\n", delta); 2080 // dbg(1,"delta=%d\n", delta);
1560 /* TRANSLATORS: Don't forget the ending space */ 2081 // TRANSLATORS: Don't forget the ending space
1561 strength=_("unknown "); 2082 //strength=_("unknown ");
1562 } 2083 strength = "";
1563 } 2084 }
2085 }
2086
1564 if (type != attr_navigation_long_exact) 2087 if (type != attr_navigation_long_exact)
2088 {
1565 distance=round_distance(distance); 2089 distance = round_distance(distance);
2090 }
2091
1566 if (type == attr_navigation_speech) { 2092 if (type == attr_navigation_speech)
2093 {
1567 if (nav->turn_around && nav->turn_around == nav->turn_around_limit) 2094 if (nav->turn_around && nav->turn_around == nav->turn_around_limit)
2095 {
2096#ifdef HAVE_API_ANDROID
2097 android_send_generic_text(1,"+*#O:When possible, please turn around\n");
2098#endif
1568 return g_strdup(_("When possible, please turn around")); 2099 return g_strdup(_("When possible, please turn around"));
2100 }
2101
1569 if (!connect) { 2102 if (!connect)
2103 {
1570 level=navigation_get_announce_level_cmd(nav, itm, cmd, distance-cmd->length); 2104 level = navigation_get_announce_level_cmd(nav, itm, cmd,
2105 distance - cmd->length);
1571 } 2106 }
1572 dbg(1,"distance=%d level=%d type=0x%x\n", distance, level, itm->way.item.type); 2107 // dbg(1,"distance=%d level=%d type=0x%x\n", distance, level, itm->way.item.type);
1573 } 2108 }
1574 2109
1575 if (cmd->itm->prev->way.flags & AF_ROUNDABOUT) { 2110 if (cmd->itm->prev->way.flags & AF_ROUNDABOUT)
2111 {
1576 cur = cmd->itm->prev; 2112 cur = cmd->itm->prev;
1577 count_roundabout = 0; 2113 count_roundabout = 0;
1578 while (cur && (cur->way.flags & AF_ROUNDABOUT)) { 2114 while (cur && (cur->way.flags & AF_ROUNDABOUT))
1579 if (cur->next->way.next && is_way_allowed(nav,cur->next->way.next,3)) { // If the next segment has no exit or the exit isn't allowed, don't count it 2115 {
2116 // If the next segment has no exit or the exit isn't allowed, don't count it
2117 if (cur->next->way.next && is_way_allowed(nav, cur->next->way.next,
2118 3))
2119 {
1580 count_roundabout++; 2120 count_roundabout++;
1581 } 2121 }
1582 cur = cur->prev; 2122 cur = cur->prev;
1583 } 2123 }
2124
2125 gchar* xy;
2126
1584 switch (level) { 2127 switch (level)
2128 {
1585 case 2: 2129 case 2:
2130#ifdef HAVE_API_ANDROID
2131 android_send_generic_text(1,"+*#O:Enter the roundabout soon\n");
2132#endif
1586 return g_strdup(_("Enter the roundabout soon")); 2133 return g_strdup(_("Enter the roundabout soon"));
1587 case 1: 2134 case 1:
1588 d = get_distance(nav, distance, type, 0); 2135 d = get_distance(nav, distance, type, 1);
2136
2137#ifdef HAVE_API_ANDROID
2138 android_send_generic_text(1,"+*#O:In %s, enter the roundabout\n");
2139 xy=g_strdup_printf("+*#1:%s\n", d);
2140 android_send_generic_text(1,xy);
2141 g_free(xy);
2142#endif
1589 /* TRANSLATORS: %s is the distance to the roundabout */ 2143 // TRANSLATORS: %s is the distance to the roundabout
2144 // TRANSLATORS: EXAMPLE: In 300m, enter the roundabout
1590 ret = g_strdup_printf(_("In %s, enter the roundabout"), d); 2145 ret = g_strdup_printf(_("In %s, enter the roundabout"), d);
2146 g_free(d);
2147 return ret;
2148 case -2:
2149#ifdef HAVE_API_ANDROID
2150 android_send_generic_text(1,"+*#O:then leave the roundabout at the %s\n");
2151 xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
2152 android_send_generic_text(1,xy);
2153 g_free(xy);
2154#endif
2155 // TRANSLATORS: EXAMPLE: ... then leave the roundabout at the second exit
2156 return g_strdup_printf(
2157 _("then leave the roundabout at the %s"),
2158 get_exit_count_str(count_roundabout));
2159 case 0:
2160#ifdef HAVE_API_ANDROID
2161 android_send_generic_text(1,"+*#O:Leave the roundabout at the %s\n");
2162 xy=g_strdup_printf("+*#1:%s\n", get_exit_count_str(count_roundabout));
2163 android_send_generic_text(1,xy);
2164 g_free(xy);
2165#endif
2166 // TRANSLATORS: EXAMPLE: Leave the roundabout at the second exit
2167 return g_strdup_printf(_("Leave the roundabout at the %s"),
2168 get_exit_count_str(count_roundabout));
2169 }
2170 }
2171
2172 switch (level)
2173 {
2174 case 3:
2175 d = get_distance(nav, distance, type, 1);
2176
2177#ifdef HAVE_API_ANDROID
2178 android_send_generic_text(1,"+*#O:Follow the road for the next %s\n");
2179 gchar* xy=g_strdup_printf("+*#1:%s\n", d);
2180 android_send_generic_text(1,xy);
2181 g_free(xy);
2182#endif
2183 // TRANSLATORS: EXAMPLE: Follow the road for the next 300 meters
2184 ret = g_strdup_printf(_("Follow the road for the next %s"), d);
1591 g_free(d); 2185 g_free(d);
1592 return ret; 2186 return ret;
2187 case 2:
2188#ifdef HAVE_API_ANDROID
2189 android_send_generic_text(1,"+*#O:soon\n");
2190#endif
2191 d = g_strdup(_("soon"));
2192 break;
2193 case 1:
2194 d = get_distance(nav, distance, attr_navigation_short, 0);
2195 break;
2196 case 0:
2197 skip_roads = count_possible_turns(nav,
2198 cmd->prev ? cmd->prev->itm : nav->first, cmd->itm,
2199 cmd->delta);
2200 if (skip_roads > 0)
2201 {
2202 if (get_count_str(skip_roads + 1))
2203 {
2204#ifdef HAVE_API_ANDROID
2205 android_send_generic_text(1,"+*#O:Take the %1$s road to the %2$s\n");
2206 gchar* xy=g_strdup_printf("+*#1:%s\n", get_count_str(skip_roads + 1));
2207 android_send_generic_text(1,xy);
2208 g_free(xy);
2209 xy=g_strdup_printf("+*#1:%s\n", dir);
2210 android_send_generic_text(1,xy);
2211 g_free(xy);
2212#endif
2213 // TRANSLATORS: First argument is the how manieth street to take, second the direction
2214 ret = g_strdup_printf(_("Take the %1$s road to the %2$s"),
2215 get_count_str(skip_roads + 1), dir);
2216 return ret;
2217 }
2218 else
2219 {
2220#ifdef HAVE_API_ANDROID
2221 android_send_generic_text(1,"+*#O:after %i roads\n");
2222 gchar* xy=g_strdup_printf("+*#1:%i\n", skip_roads);
2223 android_send_generic_text(1,xy);
2224 g_free(xy);
2225#endif
2226 d = g_strdup_printf(_("after %i roads"), skip_roads);
2227 }
2228 }
2229 else
2230 {
2231#ifdef HAVE_API_ANDROID
2232 android_send_generic_text(1,"+*#O:now\n");
2233#endif
2234 d = g_strdup(_("now"));
2235 }
2236 break;
1593 case -2: 2237 case -2:
1594 return g_strdup_printf(_("then leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
1595 case 0:
1596 return g_strdup_printf(_("Leave the roundabout at the %s"), get_exit_count_str(count_roundabout));
1597 }
1598 }
1599
1600 switch(level) {
1601 case 3:
1602 d=get_distance(nav, distance, type, 1);
1603 ret=g_strdup_printf(_("Follow the road for the next %s"), d);
1604 g_free(d);
1605 return ret;
1606 case 2:
1607 d=g_strdup(_("soon"));
1608 break;
1609 case 1:
1610 d=get_distance(nav, distance, attr_navigation_short, 0);
1611 break;
1612 case 0:
1613 skip_roads = count_possible_turns(nav,cmd->prev?cmd->prev->itm:nav->first,cmd->itm,cmd->delta); 2238 skip_roads = count_possible_turns(nav, cmd->prev->itm, cmd->itm,
2239 cmd->delta);
1614 if (skip_roads > 0) { 2240 if (skip_roads > 0)
1615 if (get_count_str(skip_roads+1)) { 2241 {
1616 /* TRANSLATORS: First argument is the how manieth street to take, second the direction */ 2242 // TRANSLATORS: First argument is the how manieth street to take, second the direction
1617 ret = g_strdup_printf(_("Take the %1$s road to the %2$s"), get_count_str(skip_roads+1), dir); 2243 // TRANSLATORS: EXAMPLE: ... then take the second road to the right
2244 if (get_count_str(skip_roads + 1))
2245 {
2246#ifdef HAVE_API_ANDROID
2247 android_send_generic_text(1,"+*#O:then take the %1$s road to the %2$s\n");
2248 gchar* xy=g_strdup_printf("+*#1:%s\n", get_count_str(skip_roads + 1));
2249 android_send_generic_text(1,xy);
2250 g_free(xy);
2251 xy=g_strdup_printf("+*#1:%s\n", dir);
2252 android_send_generic_text(1,xy);
2253 g_free(xy);
2254#endif
2255 ret = g_strdup_printf(
2256 _("then take the %1$s road to the %2$s"),
2257 get_count_str(skip_roads + 1), dir);
1618 return ret; 2258 return ret;
1619 } else { 2259 }
2260 else
2261 {
2262#ifdef HAVE_API_ANDROID
2263 android_send_generic_text(1,"+*#O:after %i roads\n");
2264 gchar* xy=g_strdup_printf("+*#1:%i\n", skip_roads);
2265 android_send_generic_text(1,xy);
2266 g_free(xy);
2267#endif
1620 d = g_strdup_printf(_("after %i roads"), skip_roads); 2268 d = g_strdup_printf(_("after %i roads"), skip_roads);
1621 } 2269 }
1622 } else { 2270
1623 d=g_strdup(_("now"));
1624 } 2271 }
1625 break;
1626 case -2:
1627 skip_roads = count_possible_turns(nav,cmd->prev->itm,cmd->itm,cmd->delta);
1628 if (skip_roads > 0) {
1629 /* TRANSLATORS: First argument is the how manieth street to take, second the direction */
1630 if (get_count_str(skip_roads+1)) {
1631 ret = g_strdup_printf(_("then take the %1$s road to the %2$s"), get_count_str(skip_roads+1), dir);
1632 return ret;
1633 } else { 2272 else
1634 d = g_strdup_printf(_("after %i roads"), skip_roads);
1635 } 2273 {
1636
1637 } else {
1638 d = g_strdup(""); 2274 d = g_strdup("");
1639 } 2275 }
1640 break; 2276 break;
1641 default: 2277 default:
2278#ifdef HAVE_API_ANDROID
2279 android_send_generic_text(1,"+*#O:error\n");
2280#endif
1642 d=g_strdup(_("error")); 2281 d = g_strdup(_("error"));
1643 } 2282 }
2283
1644 if (cmd->itm->next) { 2284 if (cmd->itm->next)
2285 {
1645 int tellstreetname = 0; 2286 int tellstreetname = 0;
1646 char *destination = NULL; 2287 char *destination = NULL;
1647 2288
1648 if(type == attr_navigation_speech) { // In voice mode 2289 if (type == attr_navigation_speech)
2290 { // In voice mode
1649 // In Voice Mode only tell the street name in level 1 or in level 0 if level 1 2291 // In Voice Mode only tell the street name in level 1 or in level 0 if level 1
1650 // was skipped 2292 // was skipped
1651 2293
2294 if (level == 1)
1652 if (level == 1) { // we are close to the intersection 2295 { // we are close to the intersection
1653 cmd->itm->streetname_told = 1; // remeber to be checked when we turn 2296 cmd->itm->streetname_told = 1; // remeber to be checked when we turn
1654 tellstreetname = 1; // Ok so we tell the name of the street 2297 tellstreetname = 1; // Ok so we tell the name of the street
1655 } 2298 }
1656 2299
1657 if (level == 0) { 2300 if (level == 0)
2301 {
1658 if(cmd->itm->streetname_told == 0) // we are right at the intersection 2302 if (cmd->itm->streetname_told == 0) // we are right at the intersection
2303 {
1659 tellstreetname = 1; 2304 tellstreetname = 1;
2305 }
1660 else 2306 else
2307 {
1661 cmd->itm->streetname_told = 0; // reset just in case we come to the same street again 2308 cmd->itm->streetname_told = 0; // reset just in case we come to the same street again
2309 }
1662 } 2310 }
1663 2311
1664 } 2312 }
1665 else 2313 else
2314 {
1666 tellstreetname = 1; 2315 tellstreetname = 1;
2316 }
1667 2317
2318 if (global_speak_streetnames == 0)
2319 {
2320 // never speak streetnames (user config option)
2321 tellstreetname = 0;
2322 }
2323
1668 if(nav->tell_street_name && tellstreetname) 2324 if (nav->tell_street_name && tellstreetname)
2325 {
1669 destination=navigation_item_destination(nav, cmd->itm, itm, " "); 2326 destination = navigation_item_destination(nav, cmd->itm, itm, " ");
2327 }
1670 2328
1671 if (level != -2) { 2329 if (level != -2)
2330 {
2331#ifdef HAVE_API_ANDROID
2332 android_send_generic_text(1,"+*#O:Turn %1$s%2$s %3$s%4$s\n");
2333 gchar* xy=g_strdup_printf("+*#1:%s\n", strength);
2334 android_send_generic_text(1,xy);
2335 g_free(xy);
2336 xy=g_strdup_printf("+*#1:%s\n", dir);
2337 android_send_generic_text(1,xy);
2338 g_free(xy);
2339 xy=g_strdup_printf("+*#1:%s\n", d);
2340 android_send_generic_text(1,xy);
2341 g_free(xy);
2342 xy=g_strdup_printf("+*#1:%s\n", destination ? destination : "");
2343 android_send_generic_text(1,xy);
2344 g_free(xy);
2345#endif
1672 /* 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' */ 2346 // 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'
1673 ret=g_strdup_printf(_("Turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination:""); 2347 ret = g_strdup_printf(_("Turn %1$s%2$s %3$s%4$s"), strength, dir,
2348 d, destination ? destination : "");
2349 }
1674 } else { 2350 else
2351 {
2352#ifdef HAVE_API_ANDROID
2353 android_send_generic_text(1,"+*#O:then turn %1$s%2$s %3$s%4$s\n");
2354 gchar* xy=g_strdup_printf("+*#1:%s\n", strength);
2355 android_send_generic_text(1,xy);
2356 g_free(xy);
2357 xy=g_strdup_printf("+*#1:%s\n", dir);
2358 android_send_generic_text(1,xy);
2359 g_free(xy);
2360 xy=g_strdup_printf("+*#1:%s\n", d);
2361 android_send_generic_text(1,xy);
2362 g_free(xy);
2363 xy=g_strdup_printf("+*#1:%s\n", destination ? destination : "");
2364 android_send_generic_text(1,xy);
2365 g_free(xy);
2366#endif
1675 /* TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination */ 2367 // TRANSLATORS: First argument is strength, second direction, third how many roads to skip, fourth destination
1676 ret=g_strdup_printf(_("then turn %1$s%2$s %3$s%4$s"), strength, dir, d, destination ? destination:""); 2368 ret = g_strdup_printf(_("then turn %1$s%2$s %3$s%4$s"), strength,
2369 dir, d, destination ? destination : "");
1677 } 2370 }
1678 g_free(destination); 2371 g_free(destination);
1679 } else { 2372 }
2373 else
2374 {
1680 if (!connect) { 2375 if (!connect)
2376 {
2377#ifdef HAVE_API_ANDROID
2378 android_send_generic_text(1,"+*#O:You have reached your destination %s\n");
2379 gchar* xy=g_strdup_printf("+*#1:%s\n", d);
2380 android_send_generic_text(1,xy);
2381 g_free(xy);
2382#endif
2383 // TRANSLATORS: EXAMPLE: You have reached your destination in 300 meters
1681 ret=g_strdup_printf(_("You have reached your destination %s"), d); 2384 ret = g_strdup_printf(_("You have reached your destination %s"), d);
2385 }
1682 } else { 2386 else
2387 {
2388#ifdef HAVE_API_ANDROID
2389 android_send_generic_text(1,"+*#O:then you have reached your destination.\n");
2390#endif
1683 ret=g_strdup_printf(_("then you have reached your destination.")); 2391 ret = g_strdup_printf(_("then you have reached your destination."));
1684 } 2392 }
1685 } 2393 }
1686 g_free(d); 2394 g_free(d);
1687 return ret; 2395 return ret;
1688} 2396}
1694 * immediately following that maneuver, if these are too close and we're in speech navigation. 2402 * immediately following that maneuver, if these are too close and we're in speech navigation.
1695 * 2403 *
1696 * @return An announcement that should be made 2404 * @return An announcement that should be made
1697 */ 2405 */
1698static char * 2406static char *
1699show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm, struct navigation_command *cmd, enum attr_type type) 2407show_next_maneuvers(struct navigation *nav, struct navigation_itm *itm,
2408 struct navigation_command *cmd, enum attr_type type)
1700{ 2409{
1701 struct navigation_command *cur,*prev; 2410 struct navigation_command *cur, *prev;
1702 int distance=itm->dest_length-cmd->itm->dest_length; 2411 int distance = itm->dest_length - cmd->itm->dest_length;
1703 int level, dist, i, time; 2412 int level, dist, i, time;
1704 int speech_time,time2nav; 2413 int speech_time, time2nav;
1705 char *ret,*old,*buf,*next; 2414 char *ret, *old, *buf, *next;
1706 2415
1707 if (type != attr_navigation_speech) { 2416 if (type != attr_navigation_speech)
2417 {
1708 return show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only in speech navigation 2418 return show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only in speech navigation
1709 } 2419 }
1710 2420
1711 level=navigation_get_announce_level(nav, itm->way.item.type, distance-cmd->length); 2421 level = navigation_get_announce_level(nav, itm->way.item.type,
2422 distance - cmd->length);
1712 2423
1713 if (level > 1) { 2424 if (level > 1)
2425 {
1714 return show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only if they are close 2426 return show_maneuver(nav, itm, cmd, type, 0); // We accumulate maneuvers only if they are close
1715 } 2427 }
1716 2428
1717 if (cmd->itm->told) { 2429 if (cmd->itm->told)
2430 {
2431#ifdef HAVE_API_ANDROID
2432 android_send_generic_text(1,"+*#C1:*CANCEL*\n");
2433#endif
1718 return g_strdup(""); 2434 return g_strdup("");
1719 } 2435 }
1720 2436
1721 ret = show_maneuver(nav, itm, cmd, type, 0); 2437 ret = show_maneuver(nav, itm, cmd, type, 0);
1722 time2nav = navigation_time(itm,cmd->itm->prev); 2438 time2nav = navigation_time(itm, cmd->itm->prev);
1723 old = NULL; 2439 old = NULL;
1724 2440
1725 cur = cmd->next; 2441 cur = cmd->next;
1726 prev = cmd; 2442 prev = cmd;
1727 i = 0; 2443 i = 0;
1728 while (cur && cur->itm) { 2444 while (cur && cur->itm)
2445 {
1729 // We don't merge more than 3 announcements... 2446 // We don't merge more than 3 announcements...
2447 if (i > 1)
1730 if (i > 1) { // if you change this, please also change the value below, that is used to terminate the loop 2448 { // if you change this, please also change the value below, that is used to terminate the loop
1731 break; 2449 break;
1732 } 2450 }
1733 2451
1734 next = show_maneuver(nav,prev->itm, cur, type, 0); 2452 next = show_maneuver(nav, prev->itm, cur, type, 0);
1735 if (nav->speech) 2453 if (nav->speech)
2454 {
1736 speech_time = speech_estimate_duration(nav->speech,next); 2455 speech_time = speech_estimate_duration(nav->speech, next);
2456 }
1737 else 2457 else
2458 {
1738 speech_time = -1; 2459 speech_time = -1;
2460 }
1739 g_free(next); 2461 g_free(next);
1740 2462
1741 if (speech_time == -1) { // user didn't set cps 2463 if (speech_time == -1)
2464 { // user didn't set cps
1742 speech_time = 30; // assume 3 seconds 2465 speech_time = 30; // assume 3 seconds
1743 } 2466 }
1744 2467
1745 dist = prev->itm->dest_length - cur->itm->dest_length; 2468 dist = prev->itm->dest_length - cur->itm->dest_length;
1746 time = navigation_time(prev->itm,cur->itm->prev); 2469 time = navigation_time(prev->itm, cur->itm->prev);
1747 2470
2471 if (time >= (speech_time + 30))
1748 if (time >= (speech_time + 30)) { // 3 seconds for understanding what has been said 2472 { // 3 seconds for understanding what has been said
1749 break; 2473 break;
1750 } 2474 }
1751 2475
1752 old = ret; 2476 old = ret;
1753 buf = show_maneuver(nav, prev->itm, cur, type, 1); 2477 buf = show_maneuver(nav, prev->itm, cur, type, 1);
1754 ret = g_strdup_printf("%s, %s", old, buf); 2478 ret = g_strdup_printf("%s, %s", old, buf);
1755 g_free(buf); 2479 g_free(buf);
2480
1756 if (nav->speech && speech_estimate_duration(nav->speech,ret) > time2nav) { 2481 if (nav->speech && speech_estimate_duration(nav->speech, ret)
2482 > time2nav)
2483 {
1757 g_free(ret); 2484 g_free(ret);
1758 ret = old; 2485 ret = old;
1759 i = 2; // This will terminate the loop 2486 i = 2; // This will terminate the loop
2487 }
1760 } else { 2488 else
2489 {
1761 g_free(old); 2490 g_free(old);
1762 } 2491 }
1763 2492
1764 // If the two maneuvers are *really* close, we shouldn't tell the second one again, because TTS won't be fast enough 2493 // If the two maneuvers are *really* close, we shouldn't tell the second one again, because TTS won't be fast enough
1765 if (time <= speech_time) { 2494 if (time <= speech_time)
2495 {
2496#ifdef HAVE_API_ANDROID
2497 android_send_generic_text(1,"+*#C2:*CANCEL*\n");
2498#endif
1766 cur->itm->told = 1; 2499 cur->itm->told = 1;
1767 } 2500 }
1768 2501
1769 prev = cur; 2502 prev = cur;
1770 cur = cur->next; 2503 cur = cur->next;
1772 } 2505 }
1773 2506
1774 return ret; 2507 return ret;
1775} 2508}
1776 2509
1777static void
1778navigation_call_callbacks(struct navigation *this_, int force_speech) 2510static void navigation_call_callbacks(struct navigation *this_,
2511 int force_speech)
1779{ 2512{
1780 int distance, level = 0; 2513 int distance, level = 0;
1781 void *p=this_; 2514 void *p = this_;
1782 if (!this_->cmd_first) 2515 if (!this_->cmd_first)
1783 return; 2516 return;
1784 callback_list_call(this_->callback, 1, &p); 2517 callback_list_call(this_->callback, 1, &p);
1785 dbg(1,"force_speech=%d turn_around=%d turn_around_limit=%d\n", force_speech, this_->turn_around, this_->turn_around_limit); 2518 //dbg(1,"force_speech=%d turn_around=%d turn_around_limit=%d\n", force_speech, this_->turn_around, this_->turn_around_limit);
2519 distance = round_distance(
1786 distance=round_distance(this_->first->dest_length-this_->cmd_first->itm->dest_length); 2520 this_->first->dest_length - this_->cmd_first->itm->dest_length);
1787 if (this_->turn_around_limit && this_->turn_around == this_->turn_around_limit) { 2521 if (this_->turn_around_limit && this_->turn_around
2522 == this_->turn_around_limit)
2523 {
1788 dbg(1,"distance=%d distance_turn=%d\n", distance, this_->distance_turn); 2524 //dbg(1,"distance=%d distance_turn=%d\n", distance, this_->distance_turn);
1789 while (distance > this_->distance_turn) { 2525 while (distance > this_->distance_turn)
2526 {
1790 this_->level_last=4; 2527 this_->level_last = 4;
1791 level=4; 2528 level = 4;
1792 force_speech=2; 2529 force_speech = 2;
1793 if (this_->distance_turn >= 500) 2530 if (this_->distance_turn >= 500)
1794 this_->distance_turn*=2; 2531 this_->distance_turn *= 2;
1795 else 2532 else
1796 this_->distance_turn=500; 2533 this_->distance_turn = 500;
2534 }
1797 } 2535 }
1798 } else if (!this_->turn_around_limit || this_->turn_around == -this_->turn_around_limit+1) { 2536 else if (!this_->turn_around_limit || this_->turn_around
2537 == -this_->turn_around_limit + 1)
2538 {
1799 this_->distance_turn=50; 2539 this_->distance_turn = 50;
1800 distance-=this_->cmd_first->length; 2540 distance -= this_->cmd_first->length;
1801 level=navigation_get_announce_level_cmd(this_, this_->first, this_->cmd_first, distance); 2541 level = navigation_get_announce_level_cmd(this_, this_->first,
2542 this_->cmd_first, distance);
1802 if (level < this_->level_last) { 2543 if (level < this_->level_last)
2544 {
1803 /* only tell if the level is valid for more than 3 seconds */ 2545 /* only tell if the level is valid for more than 3 seconds */
1804 int speed_distance=this_->first->speed*30/36; 2546 int speed_distance = this_->first->speed * 30 / 36;
1805 if (distance < speed_distance || navigation_get_announce_level_cmd(this_, this_->first, this_->cmd_first, distance-speed_distance) == level) { 2547 if (distance < speed_distance || navigation_get_announce_level_cmd(
2548 this_, this_->first, this_->cmd_first,
2549 distance - speed_distance) == level)
2550 {
1806 dbg(1,"distance %d speed_distance %d\n",distance,speed_distance); 2551 dbg(1, "distance %d speed_distance %d\n", distance,
2552 speed_distance);
1807 dbg(1,"level %d < %d\n", level, this_->level_last); 2553 dbg(1, "level %d < %d\n", level, this_->level_last);
1808 this_->level_last=level; 2554 this_->level_last = level;
1809 force_speech=3; 2555 force_speech = 3;
1810 }
1811 } 2556 }
2557 }
2558
1812 if (!item_is_equal(this_->cmd_first->itm->way.item, this_->item_last)) { 2559 if (!item_is_equal(this_->cmd_first->itm->way.item, this_->item_last))
2560 {
1813 this_->item_last=this_->cmd_first->itm->way.item; 2561 this_->item_last = this_->cmd_first->itm->way.item;
1814 if (this_->delay) 2562 if (this_->delay)
1815 this_->curr_delay=this_->delay; 2563 this_->curr_delay = this_->delay;
1816 else 2564 else
1817 force_speech=5; 2565 force_speech = 5;
2566 }
1818 } else { 2567 else
2568 {
1819 if (this_->curr_delay) { 2569 if (this_->curr_delay)
2570 {
1820 this_->curr_delay--; 2571 this_->curr_delay--;
1821 if (!this_->curr_delay) 2572 if (!this_->curr_delay)
1822 force_speech=4; 2573 force_speech = 4;
1823 }
1824 } 2574 }
1825 } 2575 }
2576 }
2577
1826 if (force_speech) { 2578 if (force_speech)
2579 {
1827 this_->level_last=level; 2580 this_->level_last = level;
1828 this_->curr_delay=0; 2581 this_->curr_delay = 0;
1829 dbg(1,"force_speech=%d distance=%d level=%d type=0x%x\n", force_speech, distance, level, this_->first->way.item.type); 2582 dbg(1, "force_speech=%d distance=%d level=%d type=0x%x\n",
2583 force_speech, distance, level, this_->first->way.item.type);
1830 callback_list_call(this_->callback_speech, 1, &p); 2584 callback_list_call(this_->callback_speech, 1, &p);
1831 } 2585 }
1832} 2586}
1833 2587
1834static void
1835navigation_update(struct navigation *this_, struct route *route, struct attr *attr) 2588static void navigation_update(struct navigation *this_, struct route *route,
2589 struct attr *attr)
1836{ 2590{
1837 struct map *map; 2591 struct map *map;
1838 struct map_rect *mr; 2592 struct map_rect *mr;
1839 struct item *ritem; /* Holds an item from the route map */ 2593 struct item *ritem; /* Holds an item from the route map */
1840 struct item *sitem; /* Holds the corresponding item from the actual map */ 2594 struct item *sitem; /* Holds the corresponding item from the actual map */
1841 struct attr street_item,street_direction; 2595 struct attr street_item, street_direction;
1842 struct navigation_itm *itm; 2596 struct navigation_itm *itm;
1843 struct attr vehicleprofile; 2597 struct attr vehicleprofile;
1844 int mode=0, incr=0, first=1; 2598 int mode = 0, incr = 0, first = 1;
1845 if (attr->type != attr_route_status) 2599 if (attr->type != attr_route_status)
1846 return; 2600 return;
1847 2601
1848 dbg(1,"enter %d\n", mode); 2602 dbg(1, "enter %d\n", mode);
1849 if (attr->u.num == route_status_no_destination || attr->u.num == route_status_not_found || attr->u.num == route_status_path_done_new) 2603 if (attr->u.num == route_status_no_destination || attr->u.num
2604 == route_status_not_found || attr->u.num
2605 == route_status_path_done_new)
1850 navigation_flush(this_); 2606 navigation_flush(this_);
1851 if (attr->u.num != route_status_path_done_new && attr->u.num != route_status_path_done_incremental) 2607 if (attr->u.num != route_status_path_done_new && attr->u.num
2608 != route_status_path_done_incremental)
1852 return; 2609 return;
1853 2610
1854 if (! this_->route) 2611 if (!this_->route)
1855 return; 2612 return;
1856 map=route_get_map(this_->route); 2613 map = route_get_map(this_->route);
1857 if (! map) 2614 if (!map)
1858 return; 2615 return;
1859 mr=map_rect_new(map, NULL); 2616 mr = map_rect_new(map, NULL);
1860 if (! mr) 2617 if (!mr)
1861 return; 2618 return;
1862 if (route_get_attr(route, attr_vehicleprofile, &vehicleprofile, NULL)) 2619 if (route_get_attr(route, attr_vehicleprofile, &vehicleprofile, NULL))
1863 this_->vehicleprofile=vehicleprofile.u.vehicleprofile; 2620 this_->vehicleprofile = vehicleprofile.u.vehicleprofile;
1864 else 2621 else
1865 this_->vehicleprofile=NULL; 2622 this_->vehicleprofile = NULL;
1866 dbg(1,"enter\n"); 2623 //dbg(1,"enter\n");
2624
1867 while ((ritem=map_rect_get_item(mr))) { 2625 while ((ritem = map_rect_get_item(mr)))
2626 {
1868 if (ritem->type == type_route_start && this_->turn_around > -this_->turn_around_limit+1) 2627 if (ritem->type == type_route_start && this_->turn_around
2628 > -this_->turn_around_limit + 1)
1869 this_->turn_around--; 2629 this_->turn_around--;
1870 if (ritem->type == type_route_start_reverse && this_->turn_around < this_->turn_around_limit) 2630 if (ritem->type == type_route_start_reverse && this_->turn_around
2631 < this_->turn_around_limit)
1871 this_->turn_around++; 2632 this_->turn_around++;
1872 if (ritem->type != type_street_route) 2633 if (ritem->type != type_street_route)
1873 continue; 2634 continue;
2635
1874 if (first && item_attr_get(ritem, attr_street_item, &street_item)) { 2636 if (first && item_attr_get(ritem, attr_street_item, &street_item))
2637 {
1875 first=0; 2638 first = 0;
1876 if (!item_attr_get(ritem, attr_direction, &street_direction)) 2639 if (!item_attr_get(ritem, attr_direction, &street_direction))
1877 street_direction.u.num=0; 2640 street_direction.u.num = 0;
1878 sitem=street_item.u.item; 2641 sitem = street_item.u.item;
1879 dbg(1,"sitem=%p\n", sitem); 2642 //dbg(1,"sitem=%p\n", sitem);
1880 itm=item_hash_lookup(this_->hash, sitem); 2643 itm = item_hash_lookup(this_->hash, sitem);
1881 dbg(2,"itm for item with id (0x%x,0x%x) is %p\n", sitem->id_hi, sitem->id_lo, itm); 2644 //dbg(2,"itm for item with id (0x%x,0x%x) is %p\n", sitem->id_hi, sitem->id_lo, itm);
2645
1882 if (itm && itm->way.dir != street_direction.u.num) { 2646 if (itm && itm->way.dir != street_direction.u.num)
2647 {
1883 dbg(2,"wrong direction\n"); 2648 //dbg(2,"wrong direction\n");
1884 itm=NULL; 2649 itm = NULL;
1885 } 2650 }
1886 navigation_destroy_itms_cmds(this_, itm); 2651 navigation_destroy_itms_cmds(this_, itm);
1887 if (itm) { 2652 if (itm)
2653 {
1888 navigation_itm_update(itm, ritem); 2654 navigation_itm_update(itm, ritem);
1889 break; 2655 break;
1890 } 2656 }
1891 dbg(1,"not on track\n"); 2657 //dbg(1,"not on track\n");
1892 } 2658 }
1893 navigation_itm_new(this_, ritem); 2659 navigation_itm_new(this_, ritem);
1894 } 2660 }
1895 dbg(2,"turn_around=%d\n", this_->turn_around); 2661 dbg(2, "turn_around=%d\n", this_->turn_around);
1896 if (first) 2662 if (first)
1897 navigation_destroy_itms_cmds(this_, NULL); 2663 navigation_destroy_itms_cmds(this_, NULL);
1898 else { 2664 else
2665 {
1899 if (! ritem) { 2666 if (!ritem)
2667 {
1900 navigation_itm_new(this_, NULL); 2668 navigation_itm_new(this_, NULL);
1901 make_maneuvers(this_,this_->route); 2669 make_maneuvers(this_, this_->route);
1902 } 2670 }
1903 calculate_dest_distance(this_, incr); 2671 calculate_dest_distance(this_, incr);
1904 profile(0,"end"); 2672 //profile(0,"end");
1905 navigation_call_callbacks(this_, FALSE); 2673 navigation_call_callbacks(this_, FALSE);
1906 } 2674 }
1907 map_rect_destroy(mr); 2675 map_rect_destroy(mr);
1908} 2676}
1909 2677
1910static void
1911navigation_flush(struct navigation *this_) 2678static void navigation_flush(struct navigation *this_)
1912{ 2679{
1913 navigation_destroy_itms_cmds(this_, NULL); 2680 navigation_destroy_itms_cmds(this_, NULL);
1914} 2681}
1915 2682
1916
1917void
1918navigation_destroy(struct navigation *this_) 2683void navigation_destroy(struct navigation *this_)
1919{ 2684{
1920 navigation_flush(this_); 2685 navigation_flush(this_);
1921 item_hash_destroy(this_->hash); 2686 item_hash_destroy(this_->hash);
1922 callback_list_destroy(this_->callback); 2687 callback_list_destroy(this_->callback);
1923 callback_list_destroy(this_->callback_speech); 2688 callback_list_destroy(this_->callback_speech);
1924 g_free(this_); 2689 g_free(this_);
1925} 2690}
1926 2691
1927int
1928navigation_register_callback(struct navigation *this_, enum attr_type type, struct callback *cb) 2692int navigation_register_callback(struct navigation *this_, enum attr_type type,
2693 struct callback *cb)
1929{ 2694{
1930 if (type == attr_navigation_speech) 2695 if (type == attr_navigation_speech)
1931 callback_list_add(this_->callback_speech, cb); 2696 callback_list_add(this_->callback_speech, cb);
1932 else 2697 else
1933 callback_list_add(this_->callback, cb); 2698 callback_list_add(this_->callback, cb);
1934 return 1; 2699 return 1;
1935} 2700}
1936 2701
1937void 2702void navigation_unregister_callback(struct navigation *this_,
1938navigation_unregister_callback(struct navigation *this_, enum attr_type type, struct callback *cb) 2703 enum attr_type type, struct callback *cb)
1939{ 2704{
1940 if (type == attr_navigation_speech) 2705 if (type == attr_navigation_speech)
1941 callback_list_remove_destroy(this_->callback_speech, cb); 2706 callback_list_remove_destroy(this_->callback_speech, cb);
1942 else 2707 else
1943 callback_list_remove_destroy(this_->callback, cb); 2708 callback_list_remove_destroy(this_->callback, cb);
1945 2710
1946struct map * 2711struct map *
1947navigation_get_map(struct navigation *this_) 2712navigation_get_map(struct navigation *this_)
1948{ 2713{
1949 struct attr *attrs[5]; 2714 struct attr *attrs[5];
1950 struct attr type,navigation,data,description; 2715 struct attr type, navigation, data, description;
1951 type.type=attr_type; 2716 type.type = attr_type;
1952 type.u.str="navigation"; 2717 type.u.str = "navigation";
1953 navigation.type=attr_navigation; 2718 navigation.type = attr_navigation;
1954 navigation.u.navigation=this_; 2719 navigation.u.navigation = this_;
1955 data.type=attr_data; 2720 data.type = attr_data;
1956 data.u.str=""; 2721 data.u.str = "";
1957 description.type=attr_description; 2722 description.type = attr_description;
1958 description.u.str="Navigation"; 2723 description.u.str = "Navigation";
1959 2724
1960 attrs[0]=&type; 2725 attrs[0] = &type;
1961 attrs[1]=&navigation; 2726 attrs[1] = &navigation;
1962 attrs[2]=&data; 2727 attrs[2] = &data;
1963 attrs[3]=&description; 2728 attrs[3] = &description;
1964 attrs[4]=NULL; 2729 attrs[4] = NULL;
1965 if (! this_->map) 2730 if (!this_->map)
1966 this_->map=map_new(NULL, attrs); 2731 this_->map = map_new(NULL, attrs);
1967 return this_->map; 2732 return this_->map;
1968} 2733}
1969 2734
1970struct map_priv { 2735struct map_priv
2736{
1971 struct navigation *navigation; 2737 struct navigation *navigation;
1972}; 2738};
1973 2739
1974struct map_rect_priv { 2740struct map_rect_priv
2741{
1975 struct navigation *nav; 2742 struct navigation *nav;
1976 struct navigation_command *cmd; 2743 struct navigation_command *cmd;
1977 struct navigation_command *cmd_next; 2744 struct navigation_command *cmd_next;
1978 struct navigation_itm *itm; 2745 struct navigation_itm *itm;
1979 struct navigation_itm *itm_next; 2746 struct navigation_itm *itm_next;
1986 struct navigation_way *ways; 2753 struct navigation_way *ways;
1987 int show_all; 2754 int show_all;
1988 char *str; 2755 char *str;
1989}; 2756};
1990 2757
1991static int
1992navigation_map_item_coord_get(void *priv_data, struct coord *c, int count) 2758static int navigation_map_item_coord_get(void *priv_data, struct coord *c,
2759 int count)
1993{ 2760{
1994 struct map_rect_priv *this=priv_data; 2761 struct map_rect_priv *this = priv_data;
1995 if (this->ccount || ! count) 2762 if (this->ccount || !count)
1996 return 0; 2763 return 0;
1997 *c=this->itm->start; 2764 *c = this->itm->start;
1998 this->ccount=1; 2765 this->ccount = 1;
1999 return 1; 2766 return 1;
2000} 2767}
2001 2768
2002static int 2769static int navigation_map_item_attr_get(void *priv_data,
2003navigation_map_item_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) 2770 enum attr_type attr_type, struct attr *attr)
2004{ 2771{
2005 struct map_rect_priv *this_=priv_data; 2772 struct map_rect_priv *this_ = priv_data;
2006 struct navigation_command *cmd=this_->cmd; 2773 struct navigation_command *cmd = this_->cmd;
2007 struct navigation_itm *itm=this_->itm; 2774 struct navigation_itm *itm = this_->itm;
2008 struct navigation_itm *prev=itm->prev; 2775 struct navigation_itm *prev = itm->prev;
2009 attr->type=attr_type; 2776 attr->type = attr_type;
2010 2777
2011 if (this_->str) { 2778 if (this_->str)
2779 {
2012 g_free(this_->str); 2780 g_free(this_->str);
2013 this_->str=NULL; 2781 this_->str = NULL;
2014 } 2782 }
2015 2783
2016 if (cmd) { 2784 if (cmd)
2785 {
2017 if (cmd->itm != itm) 2786 if (cmd->itm != itm)
2018 cmd=NULL; 2787 cmd = NULL;
2019 } 2788 }
2020 switch(attr_type) { 2789 switch (attr_type)
2790 {
2021 case attr_navigation_short: 2791 case attr_navigation_short:
2022 this_->attr_next=attr_navigation_long; 2792 this_->attr_next = attr_navigation_long;
2023 if (cmd) { 2793 if (cmd)
2794 {
2024 this_->str=attr->u.str=show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type); 2795 this_->str = attr->u.str = show_next_maneuvers(this_->nav,
2796 this_->cmd_itm, cmd, attr_type);
2797 return 1;
2798 }
2799 return 0;
2800 case attr_navigation_long:
2801 this_->attr_next = attr_navigation_long_exact;
2802 if (cmd)
2803 {
2804 this_->str = attr->u.str = show_next_maneuvers(this_->nav,
2805 this_->cmd_itm, cmd, attr_type);
2806 return 1;
2807 }
2808 return 0;
2809 case attr_navigation_long_exact:
2810 this_->attr_next = attr_navigation_speech;
2811 if (cmd)
2812 {
2813 this_->str = attr->u.str = show_next_maneuvers(this_->nav,
2814 this_->cmd_itm, cmd, attr_type);
2815 return 1;
2816 }
2817 return 0;
2818 case attr_navigation_speech:
2819 this_->attr_next = attr_length;
2820 if (cmd)
2821 {
2822 this_->str = attr->u.str = show_next_maneuvers(this_->nav,
2823 this_->cmd_itm, this_->cmd, attr_type);
2824 return 1;
2825 }
2826 return 0;
2827 case attr_length:
2828 this_->attr_next = attr_time;
2829 if (cmd)
2830 {
2831 attr->u.num = this_->cmd_itm->dest_length
2832 - cmd->itm->dest_length;
2833 return 1;
2834 }
2835 return 0;
2836 case attr_time:
2837 this_->attr_next = attr_destination_length;
2838 if (cmd)
2839 {
2840 attr->u.num = this_->cmd_itm->dest_time - cmd->itm->dest_time;
2841 return 1;
2842 }
2843 return 0;
2844 case attr_destination_length:
2845 attr->u.num = itm->dest_length;
2846 this_->attr_next = attr_destination_time;
2025 return 1; 2847 return 1;
2026 } 2848 case attr_destination_time:
2027 return 0; 2849 attr->u.num = itm->dest_time;
2028 case attr_navigation_long: 2850 this_->attr_next = attr_street_name;
2029 this_->attr_next=attr_navigation_long_exact;
2030 if (cmd) {
2031 this_->str=attr->u.str=show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type);
2032 return 1; 2851 return 1;
2033 }
2034 return 0;
2035 case attr_navigation_long_exact:
2036 this_->attr_next=attr_navigation_speech;
2037 if (cmd) {
2038 this_->str=attr->u.str=show_next_maneuvers(this_->nav, this_->cmd_itm, cmd, attr_type);
2039 return 1;
2040 }
2041 return 0;
2042 case attr_navigation_speech:
2043 this_->attr_next=attr_length;
2044 if (cmd) {
2045 this_->str=attr->u.str=show_next_maneuvers(this_->nav, this_->cmd_itm, this_->cmd, attr_type);
2046 return 1;
2047 }
2048 return 0;
2049 case attr_length:
2050 this_->attr_next=attr_time;
2051 if (cmd) {
2052 attr->u.num=this_->cmd_itm->dest_length-cmd->itm->dest_length;
2053 return 1;
2054 }
2055 return 0;
2056 case attr_time:
2057 this_->attr_next=attr_destination_length;
2058 if (cmd) {
2059 attr->u.num=this_->cmd_itm->dest_time-cmd->itm->dest_time;
2060 return 1;
2061 }
2062 return 0;
2063 case attr_destination_length:
2064 attr->u.num=itm->dest_length;
2065 this_->attr_next=attr_destination_time;
2066 return 1;
2067 case attr_destination_time:
2068 attr->u.num=itm->dest_time;
2069 this_->attr_next=attr_street_name;
2070 return 1;
2071 case attr_street_name: 2852 case attr_street_name:
2072 attr->u.str=itm->way.name1; 2853 attr->u.str = itm->way.name1;
2073 this_->attr_next=attr_street_name_systematic; 2854 this_->attr_next = attr_street_name_systematic;
2074 if (attr->u.str) 2855 if (attr->u.str)
2075 return 1;
2076 return 0;
2077 case attr_street_name_systematic:
2078 attr->u.str=itm->way.name2;
2079 this_->attr_next=attr_debug;
2080 if (attr->u.str)
2081 return 1;
2082 return 0;
2083 case attr_debug:
2084 switch(this_->debug_idx) {
2085 case 0:
2086 this_->debug_idx++;
2087 this_->str=attr->u.str=g_strdup_printf("angle:%d (- %d)", itm->way.angle2, itm->angle_end);
2088 return 1;
2089 case 1:
2090 this_->debug_idx++;
2091 this_->str=attr->u.str=g_strdup_printf("item type:%s", item_to_name(itm->way.item.type));
2092 return 1;
2093 case 2:
2094 this_->debug_idx++;
2095 if (cmd) {
2096 this_->str=attr->u.str=g_strdup_printf("delta:%d", cmd->delta);
2097 return 1; 2856 return 1;
2098 } 2857 return 0;
2099 case 3: 2858 case attr_street_name_systematic:
2100 this_->debug_idx++; 2859 attr->u.str = itm->way.name2;
2101 if (prev) { 2860 this_->attr_next = attr_debug;
2102 this_->str=attr->u.str=g_strdup_printf("prev street_name:%s", prev->way.name1); 2861 if (attr->u.str)
2103 return 1; 2862 return 1;
2863 return 0;
2864 case attr_debug:
2865 switch (this_->debug_idx)
2104 } 2866 {
2105 case 4: 2867 case 0:
2106 this_->debug_idx++; 2868 this_->debug_idx++;
2107 if (prev) { 2869 this_->str = attr->u.str = g_strdup_printf(
2108 this_->str=attr->u.str=g_strdup_printf("prev street_name_systematic:%s", prev->way.name2); 2870 "angle:%d (- %d)", itm->way.angle2, itm->angle_end);
2109 return 1; 2871 return 1;
2110 }
2111 case 5: 2872 case 1:
2112 this_->debug_idx++; 2873 this_->debug_idx++;
2113 if (prev) { 2874 this_->str = attr->u.str = g_strdup_printf("item type:%s",
2114 this_->str=attr->u.str=g_strdup_printf("prev angle:(%d -) %d", prev->way.angle2, prev->angle_end); 2875 item_to_name(itm->way.item.type));
2115 return 1; 2876 return 1;
2116 }
2117 case 6: 2877 case 2:
2118 this_->debug_idx++; 2878 this_->debug_idx++;
2879 if (cmd)
2880 {
2881 this_->str = attr->u.str = g_strdup_printf("delta:%d",
2882 cmd->delta);
2883 return 1;
2884 }
2885 case 3:
2886 this_->debug_idx++;
2887 if (prev)
2888 {
2889 this_->str = attr->u.str = g_strdup_printf(
2890 "prev street_name:%s", prev->way.name1);
2891 return 1;
2892 }
2893 case 4:
2894 this_->debug_idx++;
2895 if (prev)
2896 {
2897 this_->str = attr->u.str = g_strdup_printf(
2898 "prev street_name_systematic:%s",
2899 prev->way.name2);
2900 return 1;
2901 }
2902 case 5:
2903 this_->debug_idx++;
2904 if (prev)
2905 {
2906 this_->str = attr->u.str = g_strdup_printf(
2907 "prev angle:(%d -) %d", prev->way.angle2,
2908 prev->angle_end);
2909 return 1;
2910 }
2911 case 6:
2912 this_->debug_idx++;
2119 this_->ways=itm->way.next; 2913 this_->ways = itm->way.next;
2120 if (prev) { 2914 if (prev)
2121 this_->str=attr->u.str=g_strdup_printf("prev item type:%s", item_to_name(prev->way.item.type)); 2915 {
2916 this_->str = attr->u.str = g_strdup_printf(
2917 "prev item type:%s",
2918 item_to_name(prev->way.item.type));
2919 return 1;
2920 }
2921 case 7:
2922 if (this_->ways && prev)
2923 {
2924 this_->str
2925 = attr->u.str
2926 = g_strdup_printf(
2927 "other item angle:%d delta:%d flags:%d dir:%d type:%s id:(0x%x,0x%x)",
2928 this_->ways->angle2,
2929 angle_delta(prev->angle_end,
2930 this_->ways->angle2),
2931 this_->ways->flags,
2932 this_->ways->dir,
2933 item_to_name(
2934 this_->ways->item.type),
2935 this_->ways->item.id_hi,
2936 this_->ways->item.id_lo);
2937 this_->ways = this_->ways->next;
2938 return 1;
2939 }
2940 this_->debug_idx++;
2941 case 8:
2942 this_->debug_idx++;
2943 if (prev)
2944 {
2945 int delta = 0;
2946 char *reason = NULL;
2947 maneuver_required2(this_->nav, prev, itm, &delta,
2948 &reason);
2949 this_->str = attr->u.str = g_strdup_printf("reason:%s",
2950 reason);
2951 return 1;
2952 }
2953
2954 default:
2955 this_->attr_next = attr_none;
2956 return 0;
2957 }
2958 case attr_any:
2959 while (this_->attr_next != attr_none)
2960 {
2961 if (navigation_map_item_attr_get(priv_data, this_->attr_next,
2962 attr))
2122 return 1; 2963 return 1;
2123 } 2964 }
2124 case 7:
2125 if (this_->ways && prev) {
2126 this_->str=attr->u.str=g_strdup_printf("other item angle:%d delta:%d flags:%d dir:%d type:%s id:(0x%x,0x%x)", this_->ways->angle2, angle_delta(prev->angle_end, this_->ways->angle2), this_->ways->flags, this_->ways->dir, item_to_name(this_->ways->item.type), this_->ways->item.id_hi, this_->ways->item.id_lo);
2127 this_->ways=this_->ways->next;
2128 return 1; 2965 return 0;
2129 }
2130 this_->debug_idx++;
2131 case 8:
2132 this_->debug_idx++;
2133 if (prev) {
2134 int delta=0;
2135 char *reason=NULL;
2136 maneuver_required2(this_->nav, prev, itm, &delta, &reason);
2137 this_->str=attr->u.str=g_strdup_printf("reason:%s",reason);
2138 return 1;
2139 }
2140
2141 default: 2966 default:
2142 this_->attr_next=attr_none; 2967 attr->type = attr_none;
2143 return 0; 2968 return 0;
2144 } 2969 }
2145 case attr_any:
2146 while (this_->attr_next != attr_none) {
2147 if (navigation_map_item_attr_get(priv_data, this_->attr_next, attr))
2148 return 1;
2149 }
2150 return 0;
2151 default:
2152 attr->type=attr_none;
2153 return 0;
2154 }
2155} 2970}
2156 2971
2157static struct item_methods navigation_map_item_methods = { 2972static struct item_methods navigation_map_item_methods =
2158 NULL, 2973{ NULL, navigation_map_item_coord_get, NULL, navigation_map_item_attr_get, };
2159 navigation_map_item_coord_get,
2160 NULL,
2161 navigation_map_item_attr_get,
2162};
2163 2974
2164
2165static void
2166navigation_map_destroy(struct map_priv *priv) 2975static void navigation_map_destroy(struct map_priv *priv)
2167{ 2976{
2168 g_free(priv); 2977 g_free(priv);
2169} 2978}
2170 2979
2171static void
2172navigation_map_rect_init(struct map_rect_priv *priv) 2980static void navigation_map_rect_init(struct map_rect_priv *priv)
2173{ 2981{
2174 priv->cmd_next=priv->nav->cmd_first; 2982 priv->cmd_next = priv->nav->cmd_first;
2175 priv->cmd_itm_next=priv->itm_next=priv->nav->first; 2983 priv->cmd_itm_next = priv->itm_next = priv->nav->first;
2176} 2984}
2177 2985
2178static struct map_rect_priv * 2986static struct map_rect_priv *
2179navigation_map_rect_new(struct map_priv *priv, struct map_selection *sel) 2987navigation_map_rect_new(struct map_priv *priv, struct map_selection *sel)
2180{ 2988{
2181 struct navigation *nav=priv->navigation; 2989 struct navigation *nav = priv->navigation;
2182 struct map_rect_priv *ret=g_new0(struct map_rect_priv, 1); 2990 struct map_rect_priv *ret=g_new0(struct map_rect_priv, 1);
2183 ret->nav=nav; 2991 ret->nav = nav;
2184 navigation_map_rect_init(ret); 2992 navigation_map_rect_init(ret);
2185 ret->item.meth=&navigation_map_item_methods; 2993 ret->item.meth = &navigation_map_item_methods;
2186 ret->item.priv_data=ret; 2994 ret->item.priv_data = ret;
2187#ifdef DEBUG 2995#ifdef DEBUG
2188 ret->show_all=1; 2996 ret->show_all=1;
2189#endif 2997#endif
2190 return ret; 2998 return ret;
2191} 2999}
2192 3000
2193static void
2194navigation_map_rect_destroy(struct map_rect_priv *priv) 3001static void navigation_map_rect_destroy(struct map_rect_priv *priv)
2195{ 3002{
2196 g_free(priv); 3003 g_free(priv);
2197} 3004}
2198 3005
2199static struct item * 3006static struct item *
2200navigation_map_get_item(struct map_rect_priv *priv) 3007navigation_map_get_item(struct map_rect_priv *priv)
2201{ 3008{
2202 struct item *ret=&priv->item; 3009 struct item *ret = &priv->item;
2203 int delta; 3010 int delta;
2204 if (!priv->itm_next) 3011 if (!priv->itm_next)
2205 return NULL; 3012 return NULL;
2206 priv->itm=priv->itm_next; 3013 priv->itm = priv->itm_next;
2207 priv->cmd=priv->cmd_next; 3014 priv->cmd = priv->cmd_next;
2208 priv->cmd_itm=priv->cmd_itm_next; 3015 priv->cmd_itm = priv->cmd_itm_next;
2209 if (!priv->cmd) 3016 if (!priv->cmd)
2210 return NULL; 3017 return NULL;
2211 if (!priv->show_all && priv->itm->prev != NULL) 3018 if (!priv->show_all && priv->itm->prev != NULL)
2212 priv->itm=priv->cmd->itm; 3019 priv->itm = priv->cmd->itm;
2213 priv->itm_next=priv->itm->next; 3020 priv->itm_next = priv->itm->next;
2214 if (priv->itm->prev) 3021 if (priv->itm->prev)
2215 ret->type=type_nav_none; 3022 ret->type = type_nav_none;
2216 else 3023 else
2217 ret->type=type_nav_position; 3024 ret->type = type_nav_position;
2218 if (priv->cmd->itm == priv->itm) { 3025 if (priv->cmd->itm == priv->itm)
3026 {
2219 priv->cmd_itm_next=priv->cmd->itm; 3027 priv->cmd_itm_next = priv->cmd->itm;
2220 priv->cmd_next=priv->cmd->next; 3028 priv->cmd_next = priv->cmd->next;
2221 if (priv->cmd_itm_next && !priv->cmd_itm_next->next) 3029 if (priv->cmd_itm_next && !priv->cmd_itm_next->next)
2222 ret->type=type_nav_destination; 3030 ret->type = type_nav_destination;
2223 else { 3031 else
2224 if (priv->itm && priv->itm->prev && !(priv->itm->way.flags & AF_ROUNDABOUT) && (priv->itm->prev->way.flags & AF_ROUNDABOUT)) { 3032 {
3033 if (priv->itm && priv->itm->prev && !(priv->itm->way.flags
3034 & AF_ROUNDABOUT) && (priv->itm->prev->way.flags
3035 & AF_ROUNDABOUT))
3036 {
2225 enum item_type r=type_none,l=type_none; 3037 enum item_type r = type_none, l = type_none;
2226 switch (((180+22)-priv->cmd->roundabout_delta)/45) { 3038 switch (((180 + 22) - priv->cmd->roundabout_delta) / 45)
3039 {
2227 case 0: 3040 case 0:
2228 case 1: 3041 case 1:
2229 r=type_nav_roundabout_r1; 3042 r = type_nav_roundabout_r1;
2230 l=type_nav_roundabout_l7; 3043 l = type_nav_roundabout_l7;
2231 break; 3044 break;
2232 case 2: 3045 case 2:
2233 r=type_nav_roundabout_r2; 3046 r = type_nav_roundabout_r2;
2234 l=type_nav_roundabout_l6; 3047 l = type_nav_roundabout_l6;
2235 break; 3048 break;
2236 case 3: 3049 case 3:
2237 r=type_nav_roundabout_r3; 3050 r = type_nav_roundabout_r3;
2238 l=type_nav_roundabout_l5; 3051 l = type_nav_roundabout_l5;
2239 break; 3052 break;
2240 case 4: 3053 case 4:
2241 r=type_nav_roundabout_r4; 3054 r = type_nav_roundabout_r4;
2242 l=type_nav_roundabout_l4; 3055 l = type_nav_roundabout_l4;
2243 break; 3056 break;
2244 case 5: 3057 case 5:
2245 r=type_nav_roundabout_r5; 3058 r = type_nav_roundabout_r5;
2246 l=type_nav_roundabout_l3; 3059 l = type_nav_roundabout_l3;
2247 break; 3060 break;
2248 case 6: 3061 case 6:
2249 r=type_nav_roundabout_r6; 3062 r = type_nav_roundabout_r6;
2250 l=type_nav_roundabout_l2; 3063 l = type_nav_roundabout_l2;
2251 break; 3064 break;
2252 case 7: 3065 case 7:
2253 r=type_nav_roundabout_r7; 3066 r = type_nav_roundabout_r7;
2254 l=type_nav_roundabout_l1; 3067 l = type_nav_roundabout_l1;
2255 break; 3068 break;
2256 case 8: 3069 case 8:
2257 r=type_nav_roundabout_r8; 3070 r = type_nav_roundabout_r8;
2258 l=type_nav_roundabout_l8; 3071 l = type_nav_roundabout_l8;
2259 break; 3072 break;
2260 } 3073 }
2261 dbg(1,"delta %d\n",priv->cmd->delta); 3074 dbg(1, "delta %d\n", priv->cmd->delta);
2262 if (priv->cmd->delta < 0) 3075 if (priv->cmd->delta < 0)
2263 ret->type=l; 3076 ret->type = l;
2264 else 3077 else
2265 ret->type=r; 3078 ret->type = r;
3079 }
2266 } else { 3080 else
3081 {
2267 delta=priv->cmd->delta; 3082 delta = priv->cmd->delta;
2268 if (delta < 0) { 3083 if (delta < 0)
3084 {
2269 delta=-delta; 3085 delta = -delta;
2270 if (delta < 45) 3086 if (delta < 45)
2271 ret->type=type_nav_left_1; 3087 ret->type = type_nav_left_1;
2272 else if (delta < 105) 3088 else if (delta < 105)
2273 ret->type=type_nav_left_2; 3089 ret->type = type_nav_left_2;
2274 else if (delta < 165) 3090 else if (delta < 165)
2275 ret->type=type_nav_left_3; 3091 ret->type = type_nav_left_3;
2276 else 3092 else
2277 ret->type=type_none; 3093 ret->type = type_none;
3094 }
2278 } else { 3095 else
3096 {
2279 if (delta < 45) 3097 if (delta < 45)
2280 ret->type=type_nav_right_1; 3098 ret->type = type_nav_right_1;
2281 else if (delta < 105) 3099 else if (delta < 105)
2282 ret->type=type_nav_right_2; 3100 ret->type = type_nav_right_2;
2283 else if (delta < 165) 3101 else if (delta < 165)
2284 ret->type=type_nav_right_3; 3102 ret->type = type_nav_right_3;
2285 else 3103 else
2286 ret->type=type_none; 3104 ret->type = type_none;
2287 } 3105 }
2288 } 3106 }
2289 } 3107 }
2290 } 3108 }
2291 priv->ccount=0; 3109 priv->ccount = 0;
2292 priv->debug_idx=0; 3110 priv->debug_idx = 0;
2293 priv->attr_next=attr_navigation_short; 3111 priv->attr_next = attr_navigation_short;
2294 3112
2295 ret->id_lo=priv->itm->dest_count; 3113 ret->id_lo = priv->itm->dest_count;
2296 dbg(1,"type=%d\n", ret->type); 3114 dbg(1, "type=%d\n", ret->type);
2297 return ret; 3115 return ret;
2298} 3116}
2299 3117
2300static struct item * 3118static struct item *
2301navigation_map_get_item_byid(struct map_rect_priv *priv, int id_hi, int id_lo) 3119navigation_map_get_item_byid(struct map_rect_priv *priv, int id_hi, int id_lo)
2302{ 3120{
2303 struct item *ret; 3121 struct item *ret;
2304 navigation_map_rect_init(priv); 3122 navigation_map_rect_init(priv);
2305 while ((ret=navigation_map_get_item(priv))) { 3123 while ((ret = navigation_map_get_item(priv)))
3124 {
2306 if (ret->id_hi == id_hi && ret->id_lo == id_lo) 3125 if (ret->id_hi == id_hi && ret->id_lo == id_lo)
2307 return ret; 3126 return ret;
2308 } 3127 }
2309 return NULL; 3128 return NULL;
2310} 3129}
2311 3130
2312static struct map_methods navigation_map_meth = { 3131static struct map_methods navigation_map_meth =
2313 projection_mg, 3132{ projection_mg, "utf-8", navigation_map_destroy, navigation_map_rect_new,
2314 "utf-8", 3133 navigation_map_rect_destroy, navigation_map_get_item,
2315 navigation_map_destroy, 3134 navigation_map_get_item_byid, NULL, NULL, NULL, };
2316 navigation_map_rect_new,
2317 navigation_map_rect_destroy,
2318 navigation_map_get_item,
2319 navigation_map_get_item_byid,
2320 NULL,
2321 NULL,
2322 NULL,
2323};
2324 3135
2325static struct map_priv * 3136static struct map_priv *
2326navigation_map_new(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) 3137navigation_map_new(struct map_methods *meth, struct attr **attrs,
3138 struct callback_list *cbl)
2327{ 3139{
2328 struct map_priv *ret; 3140 struct map_priv *ret;
2329 struct attr *navigation_attr; 3141 struct attr *navigation_attr;
2330 3142
2331 navigation_attr=attr_search(attrs, NULL, attr_navigation); 3143 navigation_attr = attr_search(attrs, NULL, attr_navigation);
2332 if (! navigation_attr) 3144 if (!navigation_attr)
2333 return NULL;
2334 ret=g_new0(struct map_priv, 1); 3145 return NULL;ret=g_new0(struct map_priv, 1);
2335 *meth=navigation_map_meth; 3146 *meth = navigation_map_meth;
2336 ret->navigation=navigation_attr->u.navigation; 3147 ret->navigation = navigation_attr->u.navigation;
2337 3148
2338 return ret; 3149 return ret;
2339} 3150}
2340 3151
2341void
2342navigation_set_route(struct navigation *this_, struct route *route) 3152void navigation_set_route(struct navigation *this_, struct route *route)
2343{ 3153{
2344 struct attr callback; 3154 struct attr callback;
2345 this_->route=route; 3155 this_->route = route;
2346 this_->route_cb=callback_new_attr_1(callback_cast(navigation_update), attr_route_status, this_); 3156 this_->route_cb = callback_new_attr_1(callback_cast(navigation_update),
3157 attr_route_status, this_);
2347 callback.type=attr_callback; 3158 callback.type = attr_callback;
2348 callback.u.callback=this_->route_cb; 3159 callback.u.callback = this_->route_cb;
2349 route_add_attr(route, &callback); 3160 route_add_attr(route, &callback);
2350} 3161}
2351 3162
2352void
2353navigation_init(void) 3163void navigation_init(void)
2354{ 3164{
2355 plugin_register_map_type("navigation", navigation_map_new); 3165 plugin_register_map_type("navigation", navigation_map_new);
2356} 3166}

Legend:
Removed from v.26  
changed lines
  Added in v.27

   
Visit the ZANavi Wiki