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

Contents of /navit/navit/navit.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 56 - (show annotations) (download)
Sun Mar 19 08:44:36 2017 UTC (7 years, 1 month ago) by zoff99
File MIME type: text/plain
File size: 172435 byte(s)
updates
1 /**
2 * ZANavi, Zoff Android Navigation system.
3 * Copyright (C) 2011-2014 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
20 /**
21 * Navit, a modular navigation system.
22 * Copyright (C) 2005-2009 Navit Team
23 *
24 * This program is free software; you can redistribute it and/or
25 * modify it under the terms of the GNU General Public License
26 * version 2 as published by the Free Software Foundation.
27 *
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program; if not, write to the
35 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
36 * Boston, MA 02110-1301, USA.
37 */
38
39 #define _USE_MATH_DEFINES 1
40 #include "config.h"
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <signal.h>
47 #include <string.h>
48 #include <fcntl.h>
49 #include <glib.h>
50 #include <math.h>
51 #include <time.h>
52 #include "debug.h"
53 #include "navit.h"
54 #include "callback.h"
55 #include "gui.h"
56 #include "item.h"
57 #include "projection.h"
58 #include "map.h"
59 #include "mapset.h"
60 #include "main.h"
61 #include "coord.h"
62 #include "point.h"
63 #include "transform.h"
64 #include "param.h"
65 #include "menu.h"
66 #include "graphics.h"
67 #include "popup.h"
68 #include "data_window.h"
69 #include "route.h"
70 #include "navigation.h"
71 #include "speech.h"
72 #include "track.h"
73 #include "vehicle.h"
74 #include "layout.h"
75 #include "log.h"
76 #include "attr.h"
77 #include "event.h"
78 #include "file.h"
79 #include "profile.h"
80 #include "command.h"
81 #include "navit_nls.h"
82 #include "map.h"
83 #include "util.h"
84 #include "messages.h"
85 #include "vehicleprofile.h"
86 #include "sunriset.h"
87 #include "bookmarks.h"
88 #include "map.h"
89 #ifdef HAVE_API_WIN32_BASE
90 #include <windows.h>
91 #include "util.h"
92 #endif
93 #ifdef HAVE_API_WIN32_CE
94 #include "libc.h"
95 #endif
96
97
98
99
100
101
102
103
104
105
106
107
108
109 // #define NAVIT_FUNC_CALLS_DEBUG_PRINT 1
110
111
112 // --------------- debug function calls ------------------
113 // --------------- debug function calls ------------------
114 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
115 #undef return2
116 #define return2 dbg_func(0, global_func_indent_counter, "return(%d)\n", __LINE__);global_func_indent_counter--;return
117
118 #define __F_START__ global_func_indent_counter++;dbg_func(0, global_func_indent_counter, "enter\n");
119 #define __F_END__ dbg_func(0, global_func_indent_counter, "leave\n");global_func_indent_counter--;
120 #else
121 #undef return2
122 #define return2 return
123
124 #define __F_START__
125 #define __F_END__
126 #endif
127 // --------------- debug function calls ------------------
128 // --------------- debug function calls ------------------
129
130
131
132
133
134
135 /**
136 * @defgroup navit the navit core instance. navit is the object containing nearly everything: A set of maps, one or more vehicle, a graphics object for rendering the map, a gui object for displaying the user interface, a route object, a navigation object and so on. Be warned that it is theoretically possible to have more than one navit object
137 * @{
138 */
139
140 struct gui *main_loop_gui;
141
142 struct attr_iter
143 {
144 union
145 {
146 GList *list;
147 struct mapset_handle *mapset_handle;
148 } u;
149 };
150
151 static int dist_to_street = 100000;
152
153 static void navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv);
154 static void navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt);
155 static int navit_set_attr_do(struct navit *this_, struct attr *attr, int init);
156 static int navit_get_cursor_pnt(struct navit *this_, struct point *p, int keep_orientation, int *dir);
157 static void navit_cmd_zoom_to_route(struct navit *this);
158 static void navit_cmd_set_center_cursor(struct navit *this_);
159 static void navit_cmd_announcer_toggle(struct navit *this_);
160 static void navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv);
161
162 int allow_gui_internal = 0; // disable old GUI internal. it will not work anymore!
163 int routing_mode = 0;
164 int MYSTERY_SPEED = 2;
165 int offline_search_filter_duplicates = 0;
166 int offline_search_break_searching = 0;
167 char *navit_maps_dir;
168 char *navit_share_dir;
169 char *navit_data_dir;
170 int cancel_drawing_global = 0;
171 int global_speak_streetnames = 1;
172 int allow_large_mapfiles = 1; // allow the use of large (>2GB) mapfiles // -> value unused for now
173 int cache_size_file = 1024 * 1024 * 10; // default value was: 20971520 (~20 MB)
174 int draw_polylines_fast = 0; // default: 0
175 int limit_order_corrected = 4; // remain at this order level for drawing streets etc.
176 int shift_order = 0; // shift order level (for displaying objects) by this values (should only be bigger than zero!!)
177 int global_search_street_size_factor = 1; // make search radius for streets bigger (not used on indexsearch)
178 int disable_map_drawing = 0; // dont draw the map and dont read data from file (hopefully saving resources)
179 int hold_drawing = 0; // 0 -> draw normal , 1 -> dont do any drawing
180 int global_stop_demo_vehicle = 0; // 0 -> demo vehicle can move, 1 -> demo vehicle stands still
181 int global_show_route_rectangles = 0; // 1 -> show route rectangles, 0 -> dont show route rectangles
182 int global_traffic_light_delay = 0; // 0 -> dont account for traffic lights in route, >0 -> calc a delay for each traffic light
183 int global_clinedrawing_active = 0; // 0 -> java line drawing, 1 -> C line drawing
184 int global_draw_multipolygons = 1; // 0 -> dont draw lines and triangles from multipolygons, 1 -> draw them
185 int global_have_dpi_value = 240;
186 float global_dpi_factor = 1.0f;
187 int global_order_level_for_fast_draw = 13;
188 int global_show_english_labels = 1; // 0 -> only "normal" names/labels shown on map
189 // 1 -> show "normal, english"
190 // 2 -> show only "english" labels
191 int global_routing_engine = 0; // 0 -> offline ZANavi, 1 -> online OSRM
192 float global_overspill_factor = 1.0f; // overspill factor from Java code
193 int global_avoid_sharp_turns_flag = 0; // 0 -> normal routing, 1 -> try to avoid sharp turns / u-turns
194 int global_avoid_sharp_turns_min_angle = 40; // at what angle is it a sharp turn?
195 int global_avoid_sharp_turns_min_penalty = 1000; // routing penalty for sharp turns (DEFAULT = 1000)
196
197 int global_search_radius_for_housenumbers = 300; // search this far around street-coord to find potential housenumbers for this street
198 int global_vehicle_profile = 0; // 0 -> car, 1 -> bicycle, 2 -> bicylce no one-ways
199 int global_cycle_lanes_prio = 5; // how much prio weight will be subtracted from prio weight if a road has a cycle lane (painted white line for bicycles)
200 int global_cycle_track_prio = 1; // unused for now!!
201
202 double global_v_pos_lat = 0.0; // global vehicle position
203 double global_v_pos_lng = 0.0; // global vehicle position
204 double global_v_pos_dir = 0.0; // global vehicle direction
205
206 struct coord global_vehicle_pos_onscreen;
207 struct coord_geo global_last_vehicle_pos_geo;
208 double ggggg_lat = 0;
209 double ggggg_lon = 0;
210
211
212 int global_demo_vehicle = 0;
213 int global_demo_vehicle_short_switch = 0;
214 long global_last_spoken = -1;
215 long global_last_spoken_base = 0;
216 float global_road_speed_factor = 0.85f;
217
218 float global_level0_announcement = 5.0f;
219 float global_level1_announcement = 11.0f;
220 float global_level2_announcement = 24.3f;
221 float global_levelx_announcement_factor = 6.0f / 4.0f;
222
223 float global_b_level0_announcement = 4.8f;
224 float global_b_level1_announcement = 11.1f;
225 float global_b_level2_announcement = 21.1f;
226 float global_b_levelx_announcement_factor = 6.0f / 4.0f;
227
228 int global_driven_away_from_route = 0;
229
230 int global_enhance_cycleway = 0;
231 int global_tracking_show_real_gps_pos = 0;
232 int global_show_maps_debug_view = 0;
233 int global_cancel_preview_map_drawing = 0;
234 int global_night_mode = 0;
235 int global_test_number = -1;
236
237 GList *global_all_cbs = NULL;
238
239 struct coord global_debug_route_seg_winner_start;
240 struct coord global_debug_route_seg_winner_end;
241 struct coord global_debug_seg_winner_start;
242 struct coord global_debug_seg_winner_end;
243 struct coord global_debug_route_seg_winner_p_start;
244 struct coord global_debug_route_seg_winner_p_end;
245 struct coord global_debug_seg_winner_p_start;
246 struct coord global_debug_seg_route_start;
247 struct coord global_debug_seg_route_end;
248 struct coord global_debug_trlast_start;
249 struct coord global_debug_trlast_end;
250
251 struct coord *global_debug_coord_list;
252 int global_debug_coord_list_items = 0;
253 int global_has_gpsfix = 0;
254 int global_pos_is_underground = 0;
255
256
257 int global_sharp_turn_list_count = 0;
258 struct global_sharp_turn *global_sharp_turn_list = NULL;
259
260 int global_freetext_list_count = 0;
261 struct global_freetext *global_freetext_list = NULL;
262
263
264 GHashTable *global_transform_hash = NULL;
265 GHashTable *global_transform_hash2 = NULL;
266
267 long long draw_lines_count_2 = 0;
268 long long draw_lines_count_3 = 0;
269 long long draw_lines_count_4 = 0;
270 int poi_on_map_count = 0;
271 int label_on_map_count = 0;
272 int label_district_on_map_count = 0;
273 int label_major_on_map_count = 0;
274 int poi_icon_on_map_count = 0;
275
276 int mapdraw_time[11 + 5]; // time to draw map on screen (in 1/1000 of a second) [add 5, just in case we inc it 2 times at same time because of threads]
277 int cur_mapdraw_time_index = 0;
278
279 int route_status_previous = 0;
280 long long global_route_memory_size = 0;
281 int global_old_vehicle_speed = -1;
282 int global_old_vehicle_speed_for_autozoom = -1;
283 long global_scale = 100;
284
285 void navit_add_mapset(struct navit *this_, struct mapset *ms)
286 {
287 this_->mapsets = g_list_append(this_->mapsets, ms);
288 }
289
290 struct mapset *
291 navit_get_mapset(struct navit *this_)
292 {
293 if (this_->mapsets)
294 {
295 return this_->mapsets->data;
296 }
297 else
298 {
299 //DBG dbg(0,"No mapsets enabled! Is it on purpose? Navit can't draw a map. Please check your navit.xml\n");
300 }
301 return NULL;
302 }
303
304 struct tracking *
305 navit_get_tracking(struct navit *this_)
306 {
307 return this_->tracking;
308 }
309
310 /**
311 * @brief Get the user data directory.
312 * @param[in] create - create the directory if it does not exist
313 *
314 * @return char * to the data directory string.
315 *
316 * returns the directory used to store user data files (center.txt,
317 * destination.txt, bookmark.txt, ...)
318 *
319 */
320 char*
321 navit_get_user_data_directory(int create)
322 {
323 char *dir;
324 // dir = getenv("NAVIT_USER_DATADIR");
325 dir = navit_share_dir;
326 if (create && !file_exists(dir))
327 {
328 //DBG dbg(0, "creating dir %s\n", dir);
329 if (file_mkdir(dir, 0))
330 {
331 //DBG dbg(0, "failed creating dir %s\n", dir);
332 return NULL;
333 }
334 }
335 return dir;
336 } /* end: navit_get_user_data_directory(gboolean create) */
337
338 void navit_draw_async(struct navit *this_, int async)
339 {
340 __F_START__
341
342 //dbg(0,"EEnter this_->blocked=%d\n",this_->blocked);
343 if (this_->blocked)
344 {
345 this_->blocked |= 2;
346 //dbg(0,"set this_->blocked=%d\n",this_->blocked);
347 // dbg(0,"DO__DRAW:ndasync return 001\n");
348 return2;
349 }
350
351 transform_setup_source_rect(this_->trans);
352 //dbg(0,"call graphics_draw\n");
353
354 // dbg(0,"DO__DRAW:gras_draw call\n");
355 graphics_draw(this_->gra, this_->displaylist, this_->mapsets->data, this_->trans, this_->layout_current, async, NULL, this_->graphics_flags | 1);
356 // dbg(0,"DO__DRAW:ndasync leave\n");
357
358 __F_END__
359 }
360
361 void navit_draw(struct navit *this_)
362 {
363 __F_START__
364
365 //dbg(0,"EEnter this_->ready=%d\n",this_->ready);
366 if (this_->ready == 3)
367 {
368 // dbg(0,"navit_draw_async_001\n");
369 // dbg(0,"DO__DRAW:navit_draw_async call\n");
370 navit_draw_async(this_, 0);
371 }
372
373 __F_END__
374 }
375
376 int navit_get_ready(struct navit *this_)
377 {
378 return this_->ready;
379 }
380
381 // UNUSED -----
382 // UNUSED -----
383 void navit_draw_displaylist(struct navit *this_)
384 {
385 if (this_->ready == 3)
386 {
387 // //DBG dbg(0,"call graphics_displaylist_draw 2")
388 graphics_displaylist_draw(this_->gra, this_->displaylist, this_->trans, this_->layout_current, this_->graphics_flags | 1);
389 }
390 }
391
392 static void navit_map_progress(struct navit *this_)
393 {
394 struct map *map;
395 struct mapset *ms;
396 struct mapset_handle *msh;
397 struct attr attr;
398 struct point p;
399 if (this_->ready != 3)
400 return;
401 p.x = 10;
402 p.y = 32;
403
404 ms = this_->mapsets->data;
405 msh = mapset_open(ms);
406 while (msh && (map = mapset_next(msh, 0)))
407 {
408 if (map_get_attr(map, attr_progress, &attr, NULL))
409 {
410 char *str = g_strdup_printf("%s ", attr.u.str);
411 graphics_draw_mode(this_->gra, draw_mode_begin);
412 graphics_draw_text_std(this_->gra, 16, str, &p);
413 g_free(str);
414 p.y += 32;
415 graphics_draw_mode(this_->gra, draw_mode_end);
416 }
417 }
418 mapset_close(msh);
419 }
420
421 static void navit_redraw_route(struct navit *this_, struct route *route, struct attr *attr)
422 {
423 __F_START__
424
425 int updated;
426
427 if ((this_->route) && (this_->route->route_status_was_updated == 1))
428 {
429 this_->route->route_status_was_updated = 0;
430 // send route_status to java
431 #ifdef HAVE_API_ANDROID
432 android_return_generic_int(1, this_->route->route_status);
433 #endif
434 }
435
436 if (attr->type != attr_route_status)
437 {
438 return2;
439 }
440
441 updated = attr->u.num;
442
443 if (this_->ready != 3)
444 {
445 return2;
446 }
447
448 if (updated != route_status_path_done_new)
449 {
450 return2;
451 }
452
453 if (this_->vehicle)
454 {
455 if (this_->vehicle->follow_curr == 1)
456 {
457 ////DBG dbg(0,"disabled -> we want redraw!!\n");
458 // return2;
459 }
460
461 if (this_->vehicle->follow_curr <= this_->vehicle->follow)
462 {
463 this_->vehicle->follow_curr = this_->vehicle->follow;
464 }
465 }
466
467 // *++*-- DISABLED --*++* // navit_draw(this_);
468
469 __F_END__
470 }
471
472 void navit_handle_resize(struct navit *this_, int w, int h)
473 {
474 __F_START__
475
476 struct map_selection sel;
477
478 int callback = (this_->ready == 1);
479 this_->ready = this_->ready | 2;
480
481 memset(&sel, 0, sizeof(sel));
482
483 this_->w = w;
484 this_->h = h;
485 sel.u.p_rect.rl.x = w;
486 sel.u.p_rect.rl.y = h;
487 transform_set_screen_selection(this_->trans, &sel);
488 graphics_init(this_->gra);
489 graphics_set_rect(this_->gra, &sel.u.p_rect);
490
491 if (callback)
492 {
493 // HINT: this triggers all the OSD drawing (next turn, ETA, etc.)
494 callback_list_call_attr_1(this_->attr_cbl, attr_graphics_ready, this_);
495 }
496
497 if (this_->ready == 3)
498 {
499 // dbg(0,"navit_draw_async_007\n");
500 navit_draw_async(this_, 0);
501 }
502
503 __F_END__
504 }
505
506 void navit_resize(void *data, int w, int h)
507 {
508 struct navit *this = data;
509 if (!this->ignore_graphics_events)
510 {
511 //DBG dbg(0,"11\n");
512 navit_handle_resize(this, w, h);
513 }
514 }
515
516 int navit_get_width(struct navit *this_)
517 {
518 return this_->w;
519 }
520
521 int navit_get_height(struct navit *this_)
522 {
523 return this_->h;
524 }
525
526 static void navit_popup(void *data)
527 {
528 struct navit *this_ = data;
529 popup(this_, 1, &this_->pressed);
530 this_->button_timeout = NULL;
531 this_->popped = 1;
532 }
533
534 int navit_ignore_button(struct navit *this_)
535 {
536 if (this_->ignore_button)
537 return 1;
538
539 this_->ignore_button = 1;
540 return 0;
541 }
542
543 void navit_ignore_graphics_events(struct navit *this_, int ignore)
544 {
545 this_->ignore_graphics_events = ignore;
546 }
547
548 void update_transformation(struct transformation *tr, struct point *old, struct point *new, struct point *rot)
549 {
550 struct coord co, cn;
551 struct coord c, *cp;
552 int yaw;
553 double angleo, anglen;
554
555 if (!transform_reverse(tr, old, &co))
556 return;
557 if (rot)
558 {
559 angleo = atan2(old->y - rot->y, old->x - rot->x) * 180 / M_PI;
560 anglen = atan2(new->y - rot->y, new->x - rot->x) * 180 / M_PI;
561 yaw = transform_get_yaw(tr) + angleo - anglen;
562 transform_set_yaw(tr, yaw % 360);
563 }
564 if (!transform_reverse(tr, new, &cn))
565 return;
566 cp = transform_get_center(tr);
567 c.x = cp->x + co.x - cn.x;
568 c.y = cp->y + co.y - cn.y;
569 // dbg(1, "from 0x%x,0x%x to 0x%x,0x%x\n", cp->x, cp->y, c.x, c.y);
570 transform_set_center(tr, &c);
571 }
572
573 void navit_set_timeout(struct navit *this_)
574 {
575 // --------- DISABLE -----------
576 return;
577 // --------- DISABLE -----------
578 }
579
580 int navit_handle_button(struct navit *this_, int pressed, int button, struct point *p, struct callback *popup_callback)
581 {
582 int border = 16;
583
584 // dbg(1, "enter %d %d (ignore %d)\n", pressed, button, this_->ignore_button);
585 callback_list_call_attr_4(this_->attr_cbl, attr_button, this_, GINT_TO_POINTER(pressed), GINT_TO_POINTER(button), p);
586 if (this_->ignore_button)
587 {
588 this_->ignore_button = 0;
589 return 0;
590 }
591 if (pressed)
592 {
593 this_->pressed = *p;
594 this_->last = *p;
595 this_->zoomed = 0;
596 if (button == 1)
597 {
598 this_->button_pressed = 1;
599 this_->moved = 0;
600 this_->popped = 0;
601 // ---- DISBALED --------
602 /*
603 if (popup_callback)
604 this_->button_timeout = event_add_timeout(500, 0, popup_callback);
605 */
606 }
607 if (button == 2)
608 navit_set_center_screen(this_, p, 1);
609 if (button == 3)
610 popup(this_, button, p);
611 if (button == 4 && this_->use_mousewheel)
612 {
613 this_->zoomed = 1;
614 navit_zoom_in(this_, 2, p);
615 }
616 if (button == 5 && this_->use_mousewheel)
617 {
618 this_->zoomed = 1;
619 navit_zoom_out(this_, 2, p);
620 }
621 }
622 else
623 {
624
625 this_->button_pressed = 0;
626 if (this_->button_timeout)
627 {
628 event_remove_timeout(this_->button_timeout);
629 this_->button_timeout = NULL;
630 if (!this_->moved && !transform_within_border(this_->trans, p, border))
631 {
632 navit_set_center_screen(this_, p, !this_->zoomed);
633 }
634 }
635 if (this_->motion_timeout)
636 {
637 event_remove_timeout(this_->motion_timeout);
638 this_->motion_timeout = NULL;
639 }
640 if (this_->moved)
641 {
642 struct point pr;
643 pr.x = this_->w / 2;
644 pr.y = this_->h;
645 #if 0
646 update_transformation(this_->trans, &this_->pressed, p, &pr);
647 #else
648 update_transformation(this_->trans, &this_->pressed, p, NULL);
649 #endif
650 graphics_draw_drag(this_->gra, NULL);
651 transform_copy(this_->trans, this_->trans_cursor);
652 graphics_overlay_disable(this_->gra, 0);
653 if (!this_->zoomed)
654 {
655 navit_set_timeout(this_);
656 }
657 navit_draw(this_);
658 }
659 else
660 return 1;
661 }
662 return 0;
663 }
664
665 static void navit_button(void *data, int pressed, int button, struct point *p)
666 {
667 struct navit *this = data;
668 // dbg(1, "enter %d %d ignore %d\n", pressed, button, this->ignore_graphics_events);
669 if (!this->ignore_graphics_events)
670 {
671 if (!this->popup_callback)
672 {
673 this->popup_callback = callback_new_1(callback_cast(navit_popup), this);
674 callback_add_names(this->popup_callback, "navit_button", "navit_popup");
675 }
676 navit_handle_button(this, pressed, button, p, this->popup_callback);
677 }
678 }
679
680 // UNUSED ---
681 // UNUSED ---
682 static void navit_motion_timeout(struct navit *this_)
683 {
684 int dx, dy;
685
686 if (this_->drag_bitmap)
687 {
688 struct point point;
689 point.x = (this_->current.x - this_->pressed.x);
690 point.y = (this_->current.y - this_->pressed.y);
691 if (graphics_draw_drag(this_->gra, &point))
692 {
693 graphics_overlay_disable(this_->gra, 1);
694 graphics_draw_mode(this_->gra, draw_mode_end);
695 this_->moved = 1;
696 this_->motion_timeout = NULL;
697 return;
698 }
699 }
700 dx = (this_->current.x - this_->last.x);
701 dy = (this_->current.y - this_->last.y);
702 if (dx || dy)
703 {
704 struct transformation *tr;
705 struct point pr;
706 this_->last = this_->current;
707 graphics_overlay_disable(this_->gra, 1);
708 tr = transform_dup(this_->trans);
709 pr.x = this_->w / 2;
710 pr.y = this_->h;
711 #if 0
712 update_transformation(tr, &this_->pressed, &this_->current, &pr);
713 #else
714 update_transformation(tr, &this_->pressed, &this_->current, NULL);
715 #endif
716 #if 0
717 graphics_displaylist_move(this_->displaylist, dx, dy);
718 #endif
719 graphics_draw_cancel(this_->gra, this_->displaylist); // --> calls "do_draw" normally
720 graphics_displaylist_draw(this_->gra, this_->displaylist, tr, this_->layout_current, this_->graphics_flags);
721
722 transform_destroy(tr);
723 this_->moved = 1;
724 }
725 this_->motion_timeout = NULL;
726 return;
727 }
728
729 void navit_handle_motion(struct navit *this_, struct point *p)
730 {
731 __F_START__
732
733 int dx, dy;
734
735 if (this_->button_pressed && !this_->popped)
736 {
737 dx = (p->x - this_->pressed.x);
738 dy = (p->y - this_->pressed.y);
739 if (dx < -8 || dx > 8 || dy < -8 || dy > 8)
740 {
741 this_->moved = 1;
742 if (this_->button_timeout)
743 {
744 event_remove_timeout(this_->button_timeout);
745 this_->button_timeout = NULL;
746 }
747 this_->current = *p;
748
749 // -------- DISABLE -------
750 // -------- DISABLE -------
751 // -------- DISABLE -------
752 /*
753 if (!this_->motion_timeout_callback)
754 this_->motion_timeout_callback = callback_new_1(callback_cast(navit_motion_timeout), this_);
755 if (!this_->motion_timeout)
756 this_->motion_timeout = event_add_timeout(100, 0, this_->motion_timeout_callback);
757 */
758 // -------- DISABLE -------
759 // -------- DISABLE -------
760 // -------- DISABLE -------
761 }
762 }
763
764 __F_END__
765 }
766
767 void navit_motion(void *data, struct point *p)
768 {
769 struct navit *this = data;
770 if (!this->ignore_graphics_events)
771 {
772 navit_handle_motion(this, p);
773 }
774 }
775
776 void navit_predraw(struct navit *this_)
777 {
778 __F_START__
779
780 GList *l;
781 struct navit_vehicle *nv;
782 transform_copy(this_->trans, this_->trans_cursor);
783 l = this_->vehicles;
784 while (l)
785 {
786 nv = l->data;
787 ////DBG dbg(0,"* here *\n");
788 ////DBG dbg(0,"vehicle_draw_004\n");
789 navit_vehicle_draw(this_, nv, NULL);
790 l = g_list_next(l);
791 }
792
793 __F_END__
794 }
795
796 static void navit_scale(struct navit *this_, long scale, struct point *p, int draw)
797 {
798 struct coord c1, c2, *center;
799
800 if (scale < this_->zoom_min)
801 {
802 scale = this_->zoom_min;
803 }
804
805 if (scale > this_->zoom_max)
806 {
807 scale = this_->zoom_max;
808 }
809
810 global_scale = scale;
811
812 // return scale value to android
813 #ifdef HAVE_API_ANDROID
814 android_return_generic_int(3, (int)scale);
815 #endif
816
817 //dbg(0, "zoom to scale=%d", (int)scale);
818
819
820 if (p)
821 {
822 transform_reverse(this_->trans, p, &c1);
823 }
824
825 transform_set_scale(this_->trans, scale);
826
827 if (p)
828 {
829 transform_reverse(this_->trans, p, &c2);
830 center = transform_center(this_->trans);
831 center->x += c1.x - c2.x;
832 center->y += c1.y - c2.y;
833 }
834
835 //DBG dbg(0,"aa331\n");
836
837 if (draw)
838 {
839 navit_draw(this_);
840 }
841
842 //DBG dbg(0,"leave\n");
843 }
844
845 /**
846 * @brief Automatically adjusts zoom level
847 *
848 * This function automatically adjusts the current
849 * zoom level according to the current speed.
850 *
851 * @param this_ The navit struct
852 * @param center The "immovable" point - i.e. the vehicles position if we're centering on the vehicle
853 * @param speed The vehicles speed in meters per second
854 * @param dir The direction into which the vehicle moves
855 */
856 static long navit_autozoom(struct navit *this_, struct coord *center, int speed, int draw, int *lold, int *lnew)
857 {
858 struct point pc;
859 int w, h;
860 float distance;
861 long new_scale;
862 long scale;
863
864 if (!this_->autozoom_active)
865 {
866 return -1;
867 }
868
869 if (global_old_vehicle_speed < 1)
870 {
871 return -1;
872 }
873
874 // --- no autozoom at slow speed ---
875 //if (speed < 20)
876 //{
877 // return -1;
878 //}
879 // --- no autozoom at slow speed ---
880
881
882
883 // this is kaputt!!
884 #if 0
885 if (global_old_vehicle_speed_for_autozoom > 0)
886 {
887 if (abs(global_old_vehicle_speed_for_autozoom - speed) < 10)
888 {
889 // change in speed not significant
890 return;
891 }
892 }
893 global_old_vehicle_speed_for_autozoom = speed;
894 #endif
895 // this is kaputt!!
896
897
898
899 // distance = speed * this_->autozoom_secs;
900 if (speed > 109)
901 {
902 distance = (float)speed * 16.4f;
903 }
904 else if (speed > 75)
905 {
906 distance = (float)speed * 10.3f;
907 }
908 else
909 {
910 distance = (float)speed * 7.3f;
911 }
912
913 // dbg(0,"autozoom: dis1=%f\n", distance);
914
915 // if overspill > 1 ?
916 if (global_overspill_factor > 1.0f)
917 {
918 distance = distance * global_overspill_factor;
919 }
920
921
922 // scale = this_->trans->scale * 16;
923 scale = transform_get_scale(this_->trans);
924
925 transform_get_size(this_->trans, &w, &h);
926 transform(this_->trans, transform_get_projection(this_->trans), center, &pc, 1, 0, 0, NULL);
927
928 #if 0
929 // dbg(0,"autozoom:ovrspll=%f\n", global_overspill_factor);
930 dbg(0,"autozoom: dist=%f\n", distance);
931 dbg(0,"autozoom: scale=%d\n", (int)scale);
932 dbg(0,"autozoom:o speed=%d\n", speed);
933 dbg(0,"autozoom:n speed=%d\n", global_old_vehicle_speed);
934 #endif
935
936 /* We make sure that the point we want to see is within a certain range
937 * around the vehicle. The radius of this circle is the size of the
938 * screen. This doesn't necessarily mean the point is visible because of
939 * perspective etc. Quite rough, but should be enough. */
940
941 if (w > h)
942 {
943 new_scale = (long)( (distance / (float)h) * 16);
944 }
945 else
946 {
947 new_scale = (long)( (distance / (float)w) * 16);
948 }
949
950 if (new_scale < this_->autozoom_min)
951 {
952 new_scale = this_->autozoom_min;
953 }
954
955 #if 0
956 dbg(0,"autozoom:w n.scale=%d o.scale=%d\n", (int)new_scale, (int)scale);
957 #endif
958
959 //if (abs(new_scale - scale) < 2)
960 //{
961 // return; // Smoothing
962 //}
963
964 if (new_scale > scale)
965 {
966 // zoom out
967 if (new_scale > (scale + 20))
968 {
969 scale = scale + 10;
970 }
971 else if (new_scale > (scale + 5))
972 {
973 scale = scale + 4;
974 }
975 else
976 {
977 scale = scale + 1;
978 }
979 }
980 else if (new_scale < scale)
981 {
982 // zoom in
983 if ((new_scale + 220500) < scale) // lower threshold
984 {
985 scale = (int)((float)scale * 0.85f);
986 // dbg(0,"autozoom:step 8\n");
987 }
988 else if ((new_scale + 130500) < scale) // lower threshold
989 {
990 scale = (int)((float)scale * 0.85f);
991 // dbg(0,"autozoom:step 7\n");
992 }
993 else if ((new_scale + 4000) < scale) // lower threshold
994 {
995 scale = (int)((float)scale * 0.85f);
996 // dbg(0,"autozoom:step 6\n");
997 }
998 else if ((new_scale + 1850) < scale) // lower threshold
999 {
1000 // scale = scale - 1000;
1001 scale = (int)((float)scale * 0.85f);
1002 // dbg(0,"autozoom:step 5\n");
1003 }
1004 else if ((new_scale + 90) < scale) // lower threshold
1005 {
1006 // scale = scale - 200;
1007 scale = (int)((float)scale * 0.85f);
1008 // dbg(0,"autozoom:step 4\n");
1009 }
1010 else if ((new_scale + 25) < scale) // lower threshold
1011 {
1012 scale = scale - 8;
1013 // dbg(0,"autozoom:step 3\n");
1014 }
1015 else if ((new_scale + 7) < scale) // lower threshold
1016 {
1017 scale = scale - 2;
1018 // dbg(0,"autozoom:step 2\n");
1019 }
1020 else
1021 {
1022 scale = scale - 1;
1023 // dbg(0,"autozoom:step 1\n");
1024 }
1025 }
1026 else
1027 {
1028 // no change
1029 return -1;
1030 }
1031
1032 // dbg(0,"autozoom:n scale=%d\n", (int)scale);
1033
1034 // OLD zoom is applied here -------------------------
1035 struct coord c_left;
1036 struct point p_left;
1037 p_left.x = 0;
1038 p_left.y = 200;
1039 transform_reverse(this_->trans, &p_left, &c_left);
1040 struct coord c_right;
1041 struct point p_right;
1042 p_right.x = 200;
1043 p_right.y = 200;
1044 transform_reverse(this_->trans, &p_right, &c_right);
1045 // OLD zoom is applied here -------------------------
1046
1047
1048 if (scale >= this_->autozoom_min)
1049 {
1050 navit_scale(this_, (long) scale, &pc, 0);
1051 }
1052 else
1053 {
1054 //if (scale != this_->autozoom_min)
1055 //{
1056 navit_scale(this_, this_->autozoom_min, &pc, 0);
1057 //}
1058 }
1059
1060 // new zoom is applied here already -----------------
1061 struct point p_new_left;
1062 transform(global_navit->trans, transform_get_projection(this_->trans), &c_left, &p_new_left, 1, 0, 0, NULL);
1063 struct point p_new_right;
1064 transform(global_navit->trans, transform_get_projection(this_->trans), &c_right, &p_new_right, 1, 0, 0, NULL);
1065
1066 *lold = 200;
1067 *lnew = abs(p_new_right.x - p_new_left.x);
1068 // new zoom is applied here already -----------------
1069
1070
1071 // return new scale value
1072 return scale;
1073 }
1074
1075 /**
1076 * Change the current zoom level, zooming closer to the ground
1077 *
1078 * @param navit The navit instance
1079 * @param factor The zoom factor, usually 2
1080 * @param p The invariant point (if set to NULL, default to center)
1081 * @returns nothing
1082 */
1083 void navit_zoom_in(struct navit *this_, int factor, struct point *p)
1084 {
1085 long scale = transform_get_scale(this_->trans) / factor;
1086 if (scale < 1)
1087 {
1088 scale = 1;
1089 }
1090 ////DBG dbg(0,"zoom in -> scale=%d",scale);
1091 navit_scale(this_, scale, p, 1);
1092 }
1093
1094 /**
1095 * Change the current zoom level
1096 *
1097 * @param navit The navit instance
1098 * @param factor The zoom factor, usually 2
1099 * @param p The invariant point (if set to NULL, default to center)
1100 * @returns nothing
1101 */
1102 void navit_zoom_out(struct navit *this_, int factor, struct point *p)
1103 {
1104 long scale = transform_get_scale(this_->trans) * factor;
1105 ////DBG dbg(0,"zoom out -> scale=%d",scale);
1106 navit_scale(this_, scale, p, 1);
1107 }
1108
1109 int navit_get_cur_pnt(struct navit *this_, struct point *p)
1110 {
1111 return navit_get_cursor_pnt(this_, p, 0, NULL);
1112 }
1113
1114 void navit_zoom_in_cursor(struct navit *this_, int factor)
1115 {
1116 struct point p;
1117 if (this_->vehicle && this_->vehicle->follow_curr <= 1 && navit_get_cursor_pnt(this_, &p, 0, NULL))
1118 {
1119 navit_zoom_in(this_, factor, &p);
1120 this_->vehicle->follow_curr = this_->vehicle->follow;
1121 }
1122 else
1123 {
1124 navit_zoom_in(this_, factor, NULL);
1125 }
1126 }
1127
1128 void navit_zoom_to_scale_no_draw(struct navit *this_, int new_scale)
1129 {
1130 long scale = transform_get_scale(this_->trans);
1131 long new_scale_long = new_scale;
1132
1133 // only do something if scale changed!
1134 if (scale != new_scale_long)
1135 {
1136 navit_scale(this_, new_scale_long, NULL, 0);
1137 }
1138 }
1139
1140
1141 void navit_zoom_to_scale(struct navit *this_, int new_scale)
1142 {
1143 long scale = transform_get_scale(this_->trans);
1144 long new_scale_long = new_scale;
1145 //DBG dbg(0,"zoom to scale -> old scale=%d",scale);
1146 //DBG dbg(0,"zoom to scale -> want scale=%d",new_scale_long);
1147
1148 // only do something if scale changed!
1149 if (scale != new_scale_long)
1150 {
1151 navit_scale(this_, new_scale_long, NULL, 1);
1152 }
1153 }
1154
1155 void navit_zoom_to_scale_with_center_point(struct navit *this_, int new_scale, struct point *p)
1156 {
1157 long scale = transform_get_scale(this_->trans);
1158 long new_scale_long = new_scale;
1159
1160 //dbg(0, "zoom to scale -> old scale=%d", scale);
1161 //dbg(0, "zoom to scale -> want scale=%d", new_scale_long);
1162
1163 // only do something if scale changed!
1164 if (scale != new_scale_long)
1165 {
1166 navit_scale(this_, new_scale_long, p, 1);
1167 }
1168 }
1169
1170 void navit_zoom_out_cursor(struct navit *this_, int factor)
1171 {
1172 struct point p;
1173 if (this_->vehicle && this_->vehicle->follow_curr <= 1 && navit_get_cursor_pnt(this_, &p, 0, NULL))
1174 {
1175 navit_zoom_out(this_, 2, &p);
1176 this_->vehicle->follow_curr = this_->vehicle->follow;
1177 }
1178 else
1179 {
1180 navit_zoom_out(this_, 2, NULL);
1181 }
1182 }
1183
1184 static int navit_cmd_zoom_in(struct navit *this_)
1185 {
1186 navit_zoom_in_cursor(this_, 2);
1187 return 0;
1188 }
1189
1190 static int navit_cmd_zoom_out(struct navit *this_)
1191 {
1192 navit_zoom_out_cursor(this_, 2);
1193 return 0;
1194 }
1195
1196 static void navit_cmd_say(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1197 {
1198 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str)
1199 {
1200 navit_say(this, in[0]->u.str);
1201 }
1202 }
1203
1204 static GHashTable *cmd_int_var_hash = NULL;
1205 static GHashTable *cmd_attr_var_hash = NULL;
1206
1207 /**
1208 * Store key value pair for the command system (for int typed values)
1209 *
1210 * @param navit The navit instance
1211 * @param function unused (needed to match command function signiture)
1212 * @param in input attributes in[0] is the key string, in[1] is the integer value to store
1213 * @param out output attributes, unused
1214 * @param valid unused
1215 * @returns nothing
1216 */
1217 static void navit_cmd_set_int_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1218 {
1219 char*key;
1220 struct attr*val;
1221 if (!cmd_int_var_hash)
1222 {
1223 cmd_int_var_hash = g_hash_table_new(g_str_hash, g_str_equal);
1224 }
1225
1226 if ((in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) && (in && in[1] && ATTR_IS_NUMERIC(in[1]->type)))
1227 {
1228 val = g_new(struct attr,1);
1229 attr_dup_content(in[1], val);
1230 key = g_strdup(in[0]->u.str);
1231 g_hash_table_insert(cmd_int_var_hash, key, val);
1232 }
1233 }
1234
1235 /**
1236 * Store key value pair for the command system (for attr typed values, can be used as opaque handles)
1237 *
1238 * @param navit The navit instance
1239 * @param function unused (needed to match command function signiture)
1240 * @param in input attributes in[0] is the key string, in[1] is the attr* value to store
1241 * @param out output attributes, unused
1242 * @param valid unused
1243 * @returns nothing
1244 */
1245 //TODO free stored attributes on navit_destroy
1246 static void navit_cmd_set_attr_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1247 {
1248 char*key;
1249 struct attr*val;
1250 if (!cmd_attr_var_hash)
1251 {
1252 cmd_attr_var_hash = g_hash_table_new(g_str_hash, g_str_equal);
1253 }
1254
1255 if ((in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str) && (in && in[1]))
1256 {
1257 val = attr_dup(in[1]);
1258 //val = in[1];
1259 key = g_strdup(in[0]->u.str);
1260 g_hash_table_insert(cmd_attr_var_hash, key, val);
1261 }
1262 }
1263
1264 /**
1265 * command to toggle the active state of a named layer of the current layout
1266 *
1267 * @param navit The navit instance
1268 * @param function unused (needed to match command function signiture)
1269 * @param in input attribute in[0] is the name of the layer
1270 * @param out output unused
1271 * @param valid unused
1272 * @returns nothing
1273 */
1274 static void navit_cmd_toggle_layer(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1275 {
1276 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str)
1277 {
1278 if (this->layout_current && this->layout_current->layers)
1279 {
1280 GList* layers = this->layout_current->layers;
1281 while (layers)
1282 {
1283 struct layer*l = layers->data;
1284 if (l && !strcmp(l->name, in[0]->u.str))
1285 {
1286 l->active ^= 1;
1287 navit_draw(this);
1288 return;
1289 }
1290 layers = g_list_next(layers);
1291 }
1292 }
1293 }
1294 }
1295
1296
1297 void navit_enhance_cycleway(struct navit *this)
1298 {
1299 GList *itms;
1300 struct itemgra *itm;
1301 struct element *e;
1302 GList *es, *types;
1303 int found = 0;
1304 GList* layers = this->layout_current->layers;
1305
1306 global_enhance_cycleway = 1;
1307
1308 while (layers)
1309 {
1310
1311 struct layer*l = layers->data;
1312 if (l)
1313 {
1314
1315 itms = l->itemgras;
1316 while (itms)
1317 {
1318 itm = itms->data;
1319 found = 0;
1320
1321 types = itm->type;
1322 while (types)
1323 {
1324 if (GPOINTER_TO_INT(types->data) == type_cycleway)
1325 {
1326 found = 1;
1327 }
1328 types = g_list_next(types);
1329 }
1330
1331 if (found == 1)
1332 {
1333
1334 dbg(0, "CYC:001:min=%d max=%d\n", itm->order.min, itm->order.max);
1335
1336 if (itm->order.min == 14)
1337 {
1338 itm->order.min = 10;
1339 }
1340
1341 es = itm->elements;
1342 while (es)
1343 {
1344 e = es->data;
1345
1346 if (e->type == element_polyline)
1347 {
1348 e->u.polyline.width = e->u.polyline.width * 2;
1349 }
1350
1351 es = g_list_next(es);
1352 }
1353 }
1354
1355 itms = g_list_next(itms);
1356 }
1357
1358 }
1359 layers = g_list_next(layers);
1360
1361 }
1362
1363 }
1364
1365
1366 void navit_reset_cycleway(struct navit *this)
1367 {
1368 GList *itms;
1369 struct itemgra *itm;
1370 struct element *e;
1371 GList *es, *types;
1372 int found = 0;
1373 GList* layers = this->layout_current->layers;
1374
1375 global_enhance_cycleway = 0;
1376
1377 while (layers)
1378 {
1379
1380 struct layer*l = layers->data;
1381 if (l)
1382 {
1383
1384 itms = l->itemgras;
1385 while (itms)
1386 {
1387 itm = itms->data;
1388 found = 0;
1389
1390 types = itm->type;
1391 while (types)
1392 {
1393 if (GPOINTER_TO_INT(types->data) == type_cycleway)
1394 {
1395 found = 1;
1396 }
1397 types = g_list_next(types);
1398 }
1399
1400 if (found == 1)
1401 {
1402 if (itm->order.min == 10)
1403 {
1404 itm->order.min = 14;
1405 }
1406
1407 es = itm->elements;
1408 while (es)
1409 {
1410 e = es->data;
1411
1412 if (e->type == element_polyline)
1413 {
1414 e->u.polyline.width = e->u.polyline.width / 2;
1415 }
1416
1417 es = g_list_next(es);
1418 }
1419 }
1420
1421 itms = g_list_next(itms);
1422 }
1423
1424 }
1425 layers = g_list_next(layers);
1426
1427 }
1428
1429 }
1430
1431
1432 void navit_layer_toggle_active(struct navit *this, char *name, int draw)
1433 {
1434 if (name)
1435 {
1436 if (this->layout_current && this->layout_current->layers)
1437 {
1438 GList* layers = this->layout_current->layers;
1439 while (layers)
1440 {
1441 struct layer *l = layers->data;
1442 if (l && !strcmp(l->name, name))
1443 {
1444 l->active ^= 1;
1445 if (draw == 1)
1446 {
1447 navit_draw(this);
1448 }
1449 return;
1450 }
1451 layers = g_list_next(layers);
1452 }
1453 }
1454 }
1455 }
1456
1457
1458
1459 /**
1460 * command to set the active state of a named layer of the current layout
1461 *
1462 * @param navit The navit instance
1463 * @param name name of the layer
1464 * @param active 0 -> inactive, 1 -> active
1465 * @param draw 0 -> dont redraw, 1 -> redraw
1466 * @returns nothing
1467 */
1468 void navit_layer_set_active(struct navit *this, char *name, int active, int draw)
1469 {
1470 if (name)
1471 {
1472 if (this->layout_current && this->layout_current->layers)
1473 {
1474 GList* layers = this->layout_current->layers;
1475 while (layers)
1476 {
1477 struct layer *l = layers->data;
1478 if (l && !strcmp(l->name, name))
1479 {
1480 l->active = active;
1481 if (draw == 1)
1482 {
1483 navit_draw(this);
1484 }
1485 return;
1486 }
1487 layers = g_list_next(layers);
1488 }
1489 }
1490 }
1491 }
1492
1493 /**
1494 * adds an item with the current coordinate of the vehicle to a named map
1495 *
1496 * @param navit The navit instance
1497 * @param function unused (needed to match command function signiture)
1498 * @param in input attribute in[0] is the name of the map
1499 * @param out output attribute, 0 on error or the id of the created item on success
1500 * @param valid unused
1501 * @returns nothing
1502 */
1503 static void navit_cmd_map_add_curr_pos(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1504 {
1505 struct attr **list = g_new0(struct attr *,2);
1506 struct attr*val = g_new0(struct attr,1);
1507 struct mapset* ms;
1508 struct map_selection sel;
1509 const int selection_range = 10;
1510 enum item_type item_type;
1511 struct item *it;
1512 struct map* curr_map = NULL;
1513 struct coord curr_coord;
1514 struct map_rect *mr;
1515
1516 val->type = attr_type_item_begin;
1517 val->u.item = NULL; //return invalid item on error
1518 list[0] = val;
1519 list[1] = NULL;
1520 *out = list;
1521 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str && //map name
1522 in[1] && ATTR_IS_STRING(in[1]->type) && in[1]->u.str //item type
1523 )
1524 {
1525
1526 if (!(ms = navit_get_mapset(this)))
1527 {
1528 return;
1529 }
1530
1531 if ((item_type = item_from_name(in[1]->u.str)) == type_none)
1532 {
1533 return;
1534 }
1535
1536 curr_map = mapset_get_map_by_name(ms, in[0]->u.str);
1537
1538 //no map with the given name found
1539 if (!curr_map)
1540 {
1541 return;
1542 }
1543
1544 if (this->vehicle && this->vehicle->vehicle)
1545 {
1546 struct attr pos_attr;
1547 if (vehicle_get_attr(this->vehicle->vehicle, attr_position_coord_geo, &pos_attr, NULL))
1548 {
1549 transform_from_geo(projection_mg, pos_attr.u.coord_geo, &curr_coord);
1550 }
1551 else
1552 {
1553 return;
1554 }
1555 }
1556 else
1557 {
1558 return;
1559 }
1560
1561 sel.next = NULL;
1562 sel.order = 18;
1563 sel.range.min = type_none;
1564 sel.range.max = type_tec_common;
1565 sel.u.c_rect.lu.x = curr_coord.x - selection_range;
1566 sel.u.c_rect.lu.y = curr_coord.y + selection_range;
1567 sel.u.c_rect.rl.x = curr_coord.x + selection_range;
1568 sel.u.c_rect.rl.y = curr_coord.y - selection_range;
1569
1570 mr = map_rect_new(curr_map, &sel);
1571 if (mr)
1572 {
1573 it = map_rect_create_item(mr, item_type);
1574 item_coord_set(it, &curr_coord, 1, change_mode_modify);
1575 val->u.item = it;
1576 }
1577 map_rect_destroy(mr);
1578 }
1579 }
1580
1581 /**
1582 * sets an attribute (name value pair) of a map item specified by map name and item id
1583 *
1584 * @param navit The navit instance
1585 * @param function unused (needed to match command function signiture)
1586 * @param in input attribute in[0] - name of the map ; in[1] - item ; in[2] - attr name ; in[3] - attr value
1587 * @param out output attribute, 0 on error, 1 on success
1588 * @param valid unused
1589 * @returns nothing
1590 */
1591 static void navit_cmd_map_item_set_attr(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1592 {
1593 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str && //map name
1594 in[1] && ATTR_IS_ITEM(in[1]->type) && //item
1595 in[2] && ATTR_IS_STRING(in[2]->type) && in[2]->u.str && //attr_type str
1596 in[3] && ATTR_IS_STRING(in[3]->type) && in[3]->u.str //attr_value str
1597 )
1598 {
1599 struct attr attr_to_set;
1600 struct map* curr_map = NULL;
1601 struct mapset *ms;
1602 struct map_selection sel;
1603 const int selection_range = 500;
1604 struct coord curr_coord;
1605 struct item *it;
1606
1607 if (ATTR_IS_STRING(attr_from_name(in[2]->u.str)))
1608 {
1609 attr_to_set.u.str = in[3]->u.str;
1610 attr_to_set.type = attr_from_name(in[2]->u.str);
1611 }
1612 else if (ATTR_IS_INT(attr_from_name(in[2]->u.str)))
1613 {
1614 attr_to_set.u.num = atoi(in[3]->u.str);
1615 attr_to_set.type = attr_from_name(in[2]->u.str);
1616 }
1617 else if (ATTR_IS_DOUBLE(attr_from_name(in[2]->u.str)))
1618 {
1619 double* val = g_new0(double,1);
1620 *val = atof(in[3]->u.str);
1621 attr_to_set.u.numd = val;
1622 attr_to_set.type = attr_from_name(in[2]->u.str);
1623 }
1624
1625 ms = navit_get_mapset(this);
1626
1627 curr_map = mapset_get_map_by_name(ms, in[0]->u.str);
1628
1629 if (!curr_map)
1630 {
1631 return;
1632 }
1633 sel.next = NULL;
1634 sel.order = 18;
1635 sel.range.min = type_none;
1636 sel.range.max = type_tec_common;
1637 sel.u.c_rect.lu.x = curr_coord.x - selection_range;
1638 sel.u.c_rect.lu.y = curr_coord.y + selection_range;
1639 sel.u.c_rect.rl.x = curr_coord.x + selection_range;
1640 sel.u.c_rect.rl.y = curr_coord.y - selection_range;
1641
1642 it = in[1]->u.item;
1643 if (it)
1644 {
1645 item_attr_set(it, &attr_to_set, change_mode_modify);
1646 }
1647 }
1648 }
1649
1650 /**
1651 * Get attr variable given a key string for the command system (for opaque usage)
1652 *
1653 * @param navit The navit instance
1654 * @param function unused (needed to match command function signiture)
1655 * @param in input attribute in[0] is the key string
1656 * @param out output attribute, the attr for the given key string if exists or NULL
1657 * @param valid unused
1658 * @returns nothing
1659 */
1660 static void navit_cmd_get_attr_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1661 {
1662 struct attr **list = g_new0(struct attr *,2);
1663 if (!cmd_int_var_hash)
1664 {
1665 struct attr*val = g_new0(struct attr,1);
1666 val->type = attr_type_item_begin;
1667 val->u.item = NULL;
1668 list[0] = val;
1669 }
1670 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str)
1671 {
1672 struct attr*ret = g_hash_table_lookup(cmd_attr_var_hash, in[0]->u.str);
1673 if (ret)
1674 {
1675 list[0] = attr_dup(ret);
1676 }
1677 else
1678 {
1679 struct attr*val = g_new0(struct attr,1);
1680 val->type = attr_type_int_begin;
1681 val->u.item = NULL;
1682 list[0] = val;
1683 }
1684 }
1685 list[1] = NULL;
1686 *out = list;
1687 }
1688
1689 /**
1690 * Get value given a key string for the command system
1691 *
1692 * @param navit The navit instance
1693 * @param function unused (needed to match command function signiture)
1694 * @param in input attribute in[0] is the key string
1695 * @param out output attribute, the value for the given key string if exists or 0
1696 * @param valid unused
1697 * @returns nothing
1698 */
1699 static void navit_cmd_get_int_var(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1700 {
1701 struct attr **list = g_new0(struct attr *,2);
1702 if (!cmd_int_var_hash)
1703 {
1704 struct attr*val = g_new0(struct attr,1);
1705 val->type = attr_type_int_begin;
1706 val->u.num = 0;
1707 list[0] = val;
1708 }
1709 if (in && in[0] && ATTR_IS_STRING(in[0]->type) && in[0]->u.str)
1710 {
1711 struct attr*ret = g_hash_table_lookup(cmd_int_var_hash, in[0]->u.str);
1712 if (ret)
1713 {
1714 list[0] = ret;
1715 }
1716 else
1717 {
1718 struct attr*val = g_new0(struct attr,1);
1719 val->type = attr_type_int_begin;
1720 val->u.num = 0;
1721 list[0] = val;
1722 }
1723 }
1724 list[1] = NULL;
1725 *out = list;
1726 }
1727
1728 GList *cmd_int_var_stack = NULL;
1729
1730 /**
1731 * Push an integer to the stack for the command system
1732 *
1733 * @param navit The navit instance
1734 * @param function unused (needed to match command function signiture)
1735 * @param in input attribute in[0] is the integer attibute to push
1736 * @param out output attributes, unused
1737 * @param valid unused
1738 * @returns nothing
1739 */
1740 static void navit_cmd_push_int(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1741 {
1742 if (in && in[0] && ATTR_IS_NUMERIC(in[0]->type))
1743 {
1744 struct attr*val = g_new(struct attr,1);
1745 attr_dup_content(in[0], val);
1746 cmd_int_var_stack = g_list_prepend(cmd_int_var_stack, val);
1747 }
1748 }
1749
1750 /**
1751 * Pop an integer from the command system's integer stack
1752 *
1753 * @param navit The navit instance
1754 * @param function unused (needed to match command function signiture)
1755 * @param in input attributes unused
1756 * @param out output attribute, the value popped if stack isn't empty or 0
1757 * @param valid unused
1758 * @returns nothing
1759 */
1760 static void navit_cmd_pop_int(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1761 {
1762 struct attr **list = g_new0(struct attr *,2);
1763 if (!cmd_int_var_stack)
1764 {
1765 struct attr*val = g_new0(struct attr,1);
1766 val->type = attr_type_int_begin;
1767 val->u.num = 0;
1768 list[0] = val;
1769 }
1770 else
1771 {
1772 list[0] = cmd_int_var_stack->data;
1773 cmd_int_var_stack = g_list_remove_link(cmd_int_var_stack, cmd_int_var_stack);
1774 }
1775 list[1] = NULL;
1776 *out = list;
1777 }
1778
1779 /**
1780 * Get current size of command system's integer stack
1781 *
1782 * @param navit The navit instance
1783 * @param function unused (needed to match command function signiture)
1784 * @param in input attributes unused
1785 * @param out output attribute, the size of stack
1786 * @param valid unused
1787 * @returns nothing
1788 */
1789 static void navit_cmd_int_stack_size(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1790 {
1791 struct attr **list;
1792 struct attr *attr = g_new0(struct attr ,1);
1793 attr->type = attr_type_int_begin;
1794 if (!cmd_int_var_stack)
1795 {
1796 attr->u.num = 0;
1797 }
1798 else
1799 {
1800 attr->u.num = g_list_length(cmd_int_var_stack);
1801 }list = g_new0(struct attr *,2);
1802 list[0] = attr;
1803 list[1] = NULL;
1804 *out = list;
1805 cmd_int_var_stack = g_list_remove_link(cmd_int_var_stack, cmd_int_var_stack);
1806 }
1807
1808 static void navit_cmd_set_destination(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1809 {
1810 struct pcoord pc;
1811 char *description = NULL;
1812 if (!in)
1813 return;
1814 if (!in[0])
1815 return;
1816 pc.pro = transform_get_projection(this->trans);
1817 if (ATTR_IS_COORD(in[0]->type))
1818 {
1819 pc.x = in[0]->u.coord->x;
1820 pc.y = in[0]->u.coord->y;
1821 in++;
1822 }
1823 else if (ATTR_IS_PCOORD(in[0]->type))
1824 {
1825 pc = *in[0]->u.pcoord;
1826 in++;
1827 }
1828 else if (in[1] && in[2] && ATTR_IS_INT(in[0]->type) && ATTR_IS_INT(in[1]->type) && ATTR_IS_INT(in[2]->type))
1829 {
1830 pc.pro = in[0]->u.num;
1831 pc.x = in[1]->u.num;
1832 pc.y = in[2]->u.num;
1833 in += 3;
1834 }
1835 else if (in[1] && ATTR_IS_INT(in[0]->type) && ATTR_IS_INT(in[1]->type))
1836 {
1837 pc.x = in[0]->u.num;
1838 pc.y = in[1]->u.num;
1839 in += 2;
1840 }
1841 else
1842 {
1843 return;
1844 }
1845 if (in[0] && ATTR_IS_STRING(in[0]->type))
1846 {
1847 description = in[0]->u.str;
1848 }
1849 navit_set_destination(this, &pc, description, 1);
1850 }
1851
1852 static void navit_cmd_fmt_coordinates(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1853 {
1854 struct attr attr;
1855 attr.type = attr_type_string_begin;
1856 attr.u.str = "Fix me";
1857 if (out)
1858 {
1859 *out = attr_generic_add_attr(*out, &attr);
1860 }
1861 }
1862
1863 /**
1864 * Join several string attributes into one
1865 *
1866 * @param navit The navit instance
1867 * @param function unused (needed to match command function signiture)
1868 * @param in input attributes in[0] - separator, in[1..] - attributes to join
1869 * @param out output attribute joined attribute as string
1870 * @param valid unused
1871 * @returns nothing
1872 */
1873 static void navit_cmd_strjoin(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1874 {
1875 struct attr attr;
1876 gchar *ret, *sep;
1877 int i;
1878 attr.type = attr_type_string_begin;
1879 attr.u.str = NULL;
1880 if (in[0] && in[1])
1881 {
1882 sep = attr_to_text(in[0], NULL, 1);
1883 ret = attr_to_text(in[1], NULL, 1);
1884 for (i = 2; in[i]; i++)
1885 {
1886 gchar *in_i = attr_to_text(in[i], NULL, 1);
1887 gchar *r = g_strjoin(sep, ret, in_i, NULL);
1888 g_free(in_i);
1889 g_free(ret);
1890 ret = r;
1891 }
1892 g_free(sep);
1893 attr.u.str = ret;
1894 if (out)
1895 {
1896 *out = attr_generic_add_attr(*out, &attr);
1897 }
1898 g_free(ret);
1899 }
1900 }
1901
1902 /**
1903 * Call external program
1904 *
1905 * @param navit The navit instance
1906 * @param function unused (needed to match command function signiture)
1907 * @param in input attributes in[0] - name of executable, in[1..] - parameters
1908 * @param out output attribute unused
1909 * @param valid unused
1910 * @returns nothing
1911 */
1912 static void navit_cmd_spawn(struct navit *this, char *function, struct attr **in, struct attr ***out, int *valid)
1913 {
1914 int i, j, nparms, nvalid;
1915 const char ** argv = NULL;
1916 struct spawn_process_info *pi;
1917
1918 nparms = 0;
1919 nvalid = 0;
1920 if (in)
1921 {
1922 while (in[nparms])
1923 {
1924 if (in[nparms]->type != attr_none)
1925 nvalid++;
1926 nparms++;
1927 }
1928 }
1929
1930 if (nvalid > 0)
1931 {
1932 argv=g_new(char*,nvalid+1);
1933 for (i = 0, j = 0; in[i]; i++)
1934 {
1935 if (in[i]->type != attr_none)
1936 {
1937 argv[j++] = attr_to_text(in[i], NULL, 1);
1938 }
1939 else
1940 {
1941 //DBG dbg(0, "Parameter #%i is attr_none - skipping\n", i);
1942 }
1943 }
1944 argv[j] = NULL;
1945 pi = spawn_process(argv);
1946
1947 // spawn_process() testing suite - uncomment following code to test.
1948 //sleep(3);
1949 // example of non-blocking wait
1950 //int st=spawn_process_check_status(pi,0);//DBG dbg(0,"status %i\n",st);
1951 // example of blocking wait
1952 //st=spawn_process_check_status(pi,1);//DBG dbg(0,"status %i\n",st);
1953 // example of wait after process is finished and status is
1954 // already tested
1955 //st=spawn_process_check_status(pi,1);//DBG dbg(0,"status %i\n",st);
1956 // example of wait after process is finished and status is
1957 // already tested - unblocked
1958 //st=spawn_process_check_status(pi,0);//DBG dbg(0,"status %i\n",st);
1959
1960 // End testing suite
1961 spawn_process_info_free(pi);
1962 for (i = 0; argv[i]; i++)
1963 g_free(argv[i]);
1964 g_free(argv);
1965 }
1966 }
1967
1968 static struct command_table
1969 commands[] =
1970 { { "zoom_in", command_cast(navit_cmd_zoom_in) }, { "zoom_out", command_cast(navit_cmd_zoom_out) }, { "zoom_to_route", command_cast(navit_cmd_zoom_to_route) }, { "say", command_cast(navit_cmd_say) }, { "set_center_cursor", command_cast(navit_cmd_set_center_cursor) }, { "set_destination", command_cast(navit_cmd_set_destination) }, { "announcer_toggle", command_cast(navit_cmd_announcer_toggle) }, { "fmt_coordinates", command_cast(navit_cmd_fmt_coordinates) }, { "set_int_var", command_cast(navit_cmd_set_int_var) }, { "get_int_var", command_cast(navit_cmd_get_int_var) }, { "push_int", command_cast(navit_cmd_push_int) }, { "pop_int", command_cast(navit_cmd_pop_int) }, { "int_stack_size", command_cast(navit_cmd_int_stack_size) }, { "toggle_layer", command_cast(navit_cmd_toggle_layer) }, { "strjoin", command_cast(navit_cmd_strjoin) }, { "spawn", command_cast(navit_cmd_spawn) }, { "map_add_curr_pos", command_cast(navit_cmd_map_add_curr_pos) }, { "map_item_set_attr", command_cast(navit_cmd_map_item_set_attr) }, { "set_attr_var", command_cast(navit_cmd_set_attr_var) }, { "get_attr_var", command_cast(navit_cmd_get_attr_var) }, };
1971
1972 void navit_command_add_table(struct navit*this_, struct command_table *commands, int count)
1973 {
1974 command_add_table(this_->attr_cbl, commands, count, this_);
1975 }
1976
1977
1978 struct navit *
1979 navit_new(struct attr *parent, struct attr **attrs)
1980 {
1981 struct navit *this_=g_new0(struct navit, 1);
1982 struct pcoord center;
1983 struct coord co;
1984 struct coord_geo g;
1985 enum projection pro = projection_mg;
1986 int zoom = 256;
1987 g.lat = 53.13;
1988 g.lng = 11.70;
1989
1990
1991 global_demo_vehicle = 0;
1992 global_demo_vehicle_short_switch = 0;
1993
1994
1995 // set base for timestamps
1996 struct timeval tv2;
1997 if (gettimeofday(&tv2, NULL) == -1)
1998 {
1999 global_last_spoken_base = 0;
2000 }
2001 else
2002 {
2003 global_last_spoken_base = (long)tv2.tv_sec;
2004 }
2005
2006 global_debug_coord_list = g_new0(struct coord, (2 * (MAX_DEBUG_COORDS + 2)));
2007 global_debug_coord_list_items = 0;
2008
2009 global_debug_route_seg_winner_start.x = 0;
2010 global_debug_route_seg_winner_start.y = 0;
2011 global_debug_route_seg_winner_end.x = 0;
2012 global_debug_route_seg_winner_end.y = 0;
2013
2014 global_debug_seg_winner_start.x = 0;
2015 global_debug_seg_winner_start.y = 0;
2016 global_debug_seg_winner_end.x = 0;
2017 global_debug_seg_winner_end.y = 0;
2018
2019 global_debug_route_seg_winner_p_start.x = 0;
2020 global_debug_route_seg_winner_p_start.y = 0;
2021
2022 global_debug_seg_winner_p_start.x = 0;
2023 global_debug_seg_winner_p_start.y = 0;
2024
2025 global_debug_seg_route_start.x = 0;
2026 global_debug_seg_route_start.y = 0;
2027
2028 global_debug_seg_route_end.x = 0;
2029 global_debug_seg_route_end.y = 0;
2030
2031
2032
2033 this_->self.type = attr_navit;
2034 this_->self.u.navit = this_;
2035 this_->attr_cbl = callback_list_new("navit_new:this_->attr_cbl");
2036
2037 this_->orientation = -1;
2038 this_->tracking_flag = 1;
2039 this_->recentdest_count = 10;
2040 this_->osd_configuration = -1;
2041
2042 // changed default to 1
2043 this_->center_timeout = 1;
2044 this_->use_mousewheel = 1;
2045 this_->autozoom_secs = 10;
2046 this_->autozoom_min = 5;
2047 this_->autozoom_active = 0;
2048 this_->zoom_min = 1;
2049 this_->zoom_max = 1048576; //-> order=-2 // 2097152 -> order=-3;
2050 this_->follow_cursor = 1;
2051 this_->radius = 30;
2052 this_->border = 16;
2053
2054 // dbg(0, "GGGGG:set global_navit\n");
2055 global_navit = this_;
2056
2057 this_->trans = transform_new();
2058 this_->trans_cursor = transform_new();
2059 transform_from_geo(pro, &g, &co);
2060 center.x = co.x;
2061 center.y = co.y;
2062 center.pro = pro;
2063
2064 transform_init();
2065
2066 //DBG dbg(0, "setting center from xmlfile [hardcoded]\n");
2067 transform_setup(this_->trans, &center, zoom, (this_->orientation != -1) ? this_->orientation : 0);
2068
2069 // initialze trans_cursor here
2070 transform_copy(this_->trans, this_->trans_cursor);
2071 // initialze trans_cursor here
2072
2073
2074 dbg(0, "ii 001\n");
2075 this_->bookmarks = bookmarks_new(&this_->self, NULL, this_->trans);
2076 //this_->bookmarks = NULL;
2077 dbg(0, "ii 002\n");
2078
2079 this_->prevTs = 0;
2080
2081 for (; *attrs; attrs++)
2082 {
2083 navit_set_attr_do(this_, *attrs, 1);
2084 }
2085 this_->displaylist = graphics_displaylist_new();
2086 command_add_table(this_->attr_cbl, commands, sizeof(commands) / sizeof(struct command_table), this_);
2087
2088 dbg(0, "ii 009\n");
2089
2090 // this_->messages = messagelist_new(attrs);
2091
2092 dbg(0, "111111\n");
2093
2094 return this_;
2095 }
2096
2097 static int navit_set_gui(struct navit *this_, struct gui *gui)
2098 {
2099 if (this_->gui)
2100 return 0;
2101
2102 this_->gui = gui;
2103
2104 if (gui_has_main_loop(this_->gui))
2105 {
2106 if (!main_loop_gui)
2107 {
2108 main_loop_gui = this_->gui;
2109 }
2110 else
2111 {
2112 //DBG dbg(0, "gui with main loop already active, ignoring this instance");
2113 return 0;
2114 }
2115 }
2116 return 1;
2117 }
2118
2119 void navit_add_message(struct navit *this_, char *message)
2120 {
2121 // message_new(this_->messages, message);
2122 }
2123
2124 struct message *navit_get_messages(struct navit *this_)
2125 {
2126 // return message_get(this_->messages);
2127 }
2128
2129 static int navit_set_graphics(struct navit *this_, struct graphics *gra)
2130 {
2131 if (this_->gra)
2132 {
2133 return 0;
2134 }
2135
2136 this_->gra = gra;
2137
2138 /*
2139 this_->resize_callback = callback_new_attr_1(callback_cast(navit_resize), attr_resize, this_);
2140 graphics_add_callback(gra, this_->resize_callback);
2141 this_->button_callback = callback_new_attr_1(callback_cast(navit_button), attr_button, this_);
2142 graphics_add_callback(gra, this_->button_callback);
2143 this_->motion_callback = callback_new_attr_1(callback_cast(navit_motion), attr_motion, this_);
2144 graphics_add_callback(gra, this_->motion_callback);
2145 */
2146
2147 // this draw the vehicle // very stupid
2148 this_->predraw_callback = callback_new_attr_1(callback_cast(navit_predraw), attr_predraw, this_);
2149 callback_add_names(this_->predraw_callback, "navit_set_graphics", "navit_predraw");
2150 graphics_add_callback(gra, this_->predraw_callback);
2151
2152 return 1;
2153 }
2154
2155 struct graphics *
2156 navit_get_graphics(struct navit *this_)
2157 {
2158 return this_->gra;
2159 }
2160
2161 struct vehicleprofile *
2162 navit_get_vehicleprofile(struct navit *this_)
2163 {
2164 return this_->vehicleprofile;
2165 }
2166
2167 GList *
2168 navit_get_vehicleprofiles(struct navit *this_)
2169 {
2170 return this_->vehicleprofiles;
2171 }
2172
2173 static void navit_projection_set(struct navit *this_, enum projection pro, int draw)
2174 {
2175
2176
2177 ////DBG dbg(0,"EEnter\n");
2178 struct coord_geo g;
2179 struct coord *c;
2180
2181 c = transform_center(this_->trans);
2182 transform_to_geo(transform_get_projection(this_->trans), c, &g);
2183 transform_set_projection(this_->trans, pro);
2184 transform_from_geo(pro, &g, c);
2185 if (draw)
2186 {
2187 navit_draw(this_);
2188 }
2189 }
2190
2191 /**
2192 * Start the route computing to a given set of coordinates
2193 *
2194 * @param navit The navit instance
2195 * @param c The coordinate to start routing to
2196 * @param description A label which allows the user to later identify this destination in the former destinations selection
2197 * @returns nothing
2198 */
2199 void navit_set_destination(struct navit *this_, struct pcoord *c, const char *description, int async)
2200 {
2201
2202
2203 ////DBG dbg(0,"EEnter\n");
2204 char *destination_file;
2205 if (c)
2206 {
2207 this_->destination = *c;
2208 this_->destination_valid = 1;
2209 //dbg(0, "navit->navit_set_destination %i\n", c->x);
2210 //dbg(0, "navit->navit_set_destination %i\n", c->y);
2211 }
2212 else
2213 {
2214 this_->destination_valid = 0;
2215 }
2216 //destination_file = bookmarks_get_destination_file(TRUE);
2217 //bookmarks_append_coord(this_->bookmarks, destination_file, c, 1, "former_destination", description, NULL, this_->recentdest_count);
2218 //g_free(destination_file);
2219 callback_list_call_attr_0(this_->attr_cbl, attr_destination);
2220 if (this_->route)
2221 {
2222 //dbg(0, "navit->navit_set_destination 2: %i %i\n", c->x, c->y);
2223
2224 route_set_destination(this_->route, c, async);
2225 if (this_->ready == 3)
2226 {
2227 navit_draw(this_);
2228 }
2229 }
2230 }
2231
2232 /**
2233 * add a waypoint to an active route
2234 *
2235 * @param navit The navit instance
2236 * @param c The coordinate of the waypoint
2237 * @param description A dummy string
2238 * @returns nothing
2239 */
2240 void navit_add_waypoint_to_route(struct navit *this_, struct pcoord *c, const char *description, int async)
2241 {
2242
2243
2244 if (this_->destination_valid == 1)
2245 {
2246 //int count = 0;
2247 //count = g_list_length(this_->route->destinations);
2248 //DBG dbg(0, "count=%d\n", count);
2249
2250 //dbg(0, "navit->navit_add_waypoint_to_route 1: %i %i\n", c->x, c->y);
2251
2252 route_add_destination(this_->route, c, async);
2253
2254 this_->destination = *c;
2255 this_->destination_valid = 1;
2256 }
2257 else
2258 {
2259 //dbg(0, "navit->navit_add_waypoint_to_route 2: %i %i\n", c->x, c->y);
2260 navit_set_destination(this_, c, description, async);
2261 }
2262 }
2263
2264 /**
2265 * Start the route computing to a given set of coordinates including waypoints
2266 *
2267 * @param navit The navit instance
2268 * @param c The coordinate to start routing to
2269 * @param description A label which allows the user to later identify this destination in the former destinations selection
2270 * @returns nothing
2271 */
2272 void navit_set_destinations(struct navit *this_, struct pcoord *c, int count, const char *description, int async)
2273 {
2274
2275
2276 ////DBG dbg(0,"EEnter\n");
2277 char *destination_file;
2278 if (c && count)
2279 {
2280 this_->destination = c[count - 1];
2281 this_->destination_valid = 1;
2282 //dbg(0, "navit->navit_set_destinations 1: %i %i\n", c[count-1].x, c[count-1].y);
2283 }
2284 else
2285 {
2286 this_->destination_valid = 0;
2287 }
2288 //destination_file = bookmarks_get_destination_file(TRUE);
2289 //bookmarks_append_coord(this_->bookmarks, destination_file, c, count, "former_itinerary", description, NULL, this_->recentdest_count);
2290 //g_free(destination_file);
2291 callback_list_call_attr_0(this_->attr_cbl, attr_destination);
2292 if (this_->route)
2293 {
2294 route_set_destinations(this_->route, c, count, async);
2295 if (this_->ready == 3)
2296 {
2297 navit_draw(this_);
2298 }
2299 }
2300 }
2301
2302 /**
2303 * @brief Checks if a route is calculated
2304 *
2305 * This function checks if a route is calculated.
2306 *
2307 * @param this_ The navit struct whose route should be checked.
2308 * @return True if the route is set, false otherwise.
2309 */
2310 int navit_check_route(struct navit *this_)
2311 {
2312
2313
2314 ////DBG dbg(0,"EEnter\n");
2315 if (this_->route)
2316 {
2317 return route_get_path_set(this_->route);
2318 }
2319
2320 return 0;
2321 }
2322
2323 static int navit_former_destinations_active(struct navit *this_)
2324 {
2325
2326
2327 ////DBG dbg(0,"EEnter\n");
2328
2329 return 0;
2330 // disable this function!!
2331
2332
2333 char *destination_file = bookmarks_get_destination_file(FALSE);
2334 FILE *f;
2335 int active = 0;
2336 char buffer[3];
2337 f = fopen(destination_file, "r");
2338 if (f)
2339 {
2340 if (!fseek(f, -2, SEEK_END) && fread(buffer, 2, 1, f) == 1 && (buffer[0] != '\n' || buffer[1] != '\n'))
2341 {
2342 active = 1;
2343 }
2344 fclose(f);
2345 }
2346 g_free(destination_file);
2347
2348 return active;
2349 }
2350
2351 static void navit_add_former_destinations_from_file(struct navit *this_)
2352 {
2353
2354
2355 ////DBG dbg(0,"EEnter\n");
2356 char *destination_file = bookmarks_get_destination_file(FALSE);
2357 struct attr *attrs[4];
2358 struct map_rect *mr;
2359 struct item *item;
2360 int i, valid = 0, count = 0;
2361 struct coord c[16];
2362 struct pcoord pc[16];
2363 struct attr parent;
2364 struct attr type;
2365 struct attr data;
2366 struct attr flags;
2367
2368 parent.type = attr_navit;
2369 parent.u.navit = this_;
2370
2371 type.type = attr_type;
2372 type.u.str = "textfile";
2373
2374 data.type = attr_data;
2375 data.u.str = destination_file;
2376
2377 flags.type = attr_flags;
2378 flags.u.num = 1;
2379
2380 attrs[0] = &type;
2381 attrs[1] = &data;
2382 attrs[2] = &flags;
2383 attrs[3] = NULL;
2384
2385 this_->former_destination = map_new(&parent, attrs);
2386 g_free(destination_file);
2387 if (!this_->route || !navit_former_destinations_active(this_))
2388 return;
2389 mr = map_rect_new(this_->former_destination, NULL);
2390 while ((item = map_rect_get_item(mr)))
2391 {
2392 if ((item->type == type_former_destination || item->type == type_former_itinerary || item->type == type_former_itinerary_part) && (count = item_coord_get(item, c, 16)))
2393 valid = 1;
2394 }
2395 map_rect_destroy(mr);
2396 if (valid && count > 0)
2397 {
2398 for (i = 0; i < count; i++)
2399 {
2400 pc[i].pro = map_projection(this_->former_destination);
2401 pc[i].x = c[i].x;
2402 pc[i].y = c[i].y;
2403 }
2404 if (count == 1)
2405 {
2406 route_set_destination(this_->route, &pc[0], 1);
2407 }
2408 else
2409 {
2410 route_set_destinations(this_->route, pc, count, 1);
2411 }
2412 this_->destination = pc[count - 1];
2413 this_->destination_valid = 1;
2414 }
2415 }
2416
2417 void navit_textfile_debug_log(struct navit *this_, const char *fmt, ...)
2418 {
2419
2420
2421 ////DBG dbg(0,"EEnter\n");
2422 va_list ap;
2423 char *str1, *str2;
2424 va_start(ap, fmt);
2425 if (this_->textfile_debug_log && this_->vehicle)
2426 {
2427 str1 = g_strdup_vprintf(fmt, ap);
2428 str2 = g_strdup_printf("0x%x 0x%x%s%s\n", this_->vehicle->coord.x, this_->vehicle->coord.y, strlen(str1) ? " " : "", str1);
2429 log_write(this_->textfile_debug_log, str2, strlen(str2), 0);
2430 g_free(str2);
2431 g_free(str1);
2432 }
2433 va_end(ap);
2434 }
2435
2436 void navit_textfile_debug_log_at(struct navit *this_, struct pcoord *pc, const char *fmt, ...)
2437 {
2438
2439
2440 ////DBG dbg(0,"EEnter\n");
2441 va_list ap;
2442 char *str1, *str2;
2443 va_start(ap, fmt);
2444 if (this_->textfile_debug_log && this_->vehicle)
2445 {
2446 str1 = g_strdup_vprintf(fmt, ap);
2447 str2 = g_strdup_printf("0x%x 0x%x%s%s\n", pc->x, pc->y, strlen(str1) ? " " : "", str1);
2448 log_write(this_->textfile_debug_log, str2, strlen(str2), 0);
2449 g_free(str2);
2450 g_free(str1);
2451 }
2452 va_end(ap);
2453 }
2454
2455 void navit_say(struct navit *this_, char *text)
2456 {
2457
2458
2459 ////DBG dbg(0,"EEnter\n");
2460 if (this_->speech)
2461 {
2462 //dbg(0,"say(1) s=%s\n", text);
2463 speech_say(this_->speech, text);
2464 }
2465 }
2466
2467 /**
2468 * @brief Toggles the navigation announcer for navit
2469 * @param this_ The navit object
2470 */
2471 static void navit_cmd_announcer_toggle(struct navit *this_)
2472 {
2473
2474
2475 struct attr attr, speechattr;
2476
2477 // search for the speech attribute
2478 if (!navit_get_attr(this_, attr_speech, &speechattr, NULL))
2479 return;
2480 // find out if the corresponding attribute attr_active has been set
2481 if (speech_get_attr(speechattr.u.speech, attr_active, &attr, NULL))
2482 {
2483 // flip it then...
2484 attr.u.num = !attr.u.num;
2485 }
2486 else
2487 {
2488 // otherwise disable it because voice is enabled by default
2489 attr.type = attr_active;
2490 attr.u.num = 0;
2491 }
2492
2493 // apply the new state
2494 if (!speech_set_attr(speechattr.u.speech, &attr))
2495 return;
2496
2497 // announce that the speech attribute has changed
2498 callback_list_call_attr_0(this_->attr_cbl, attr_speech);
2499 }
2500
2501 void navit_cmd_announcer_on(struct navit *this_)
2502 {
2503
2504
2505 struct attr attr, speechattr;
2506
2507 // search for the speech attribute
2508 if (!navit_get_attr(this_, attr_speech, &speechattr, NULL))
2509 return;
2510
2511 attr.type = attr_active;
2512 attr.u.num = 1;
2513
2514 // apply the new state
2515 if (!speech_set_attr(speechattr.u.speech, &attr))
2516 return;
2517
2518 // announce that the speech attribute has changed
2519 callback_list_call_attr_0(this_->attr_cbl, attr_speech);
2520 }
2521
2522 void navit_cmd_announcer_off(struct navit *this_)
2523 {
2524
2525
2526 struct attr attr, speechattr;
2527
2528 // search for the speech attribute
2529 if (!navit_get_attr(this_, attr_speech, &speechattr, NULL))
2530 return;
2531
2532 attr.type = attr_active;
2533 attr.u.num = 0;
2534
2535 // apply the new state
2536 if (!speech_set_attr(speechattr.u.speech, &attr))
2537 return;
2538
2539 // announce that the speech attribute has changed
2540 callback_list_call_attr_0(this_->attr_cbl, attr_speech);
2541 }
2542
2543 void navit_speak(struct navit *this_)
2544 {
2545
2546
2547 ////DBG dbg(0,"EEnter\n");
2548 struct navigation *nav = this_->navigation;
2549 struct map *map = NULL;
2550 struct map_rect *mr = NULL;
2551 struct item *item;
2552 struct attr attr;
2553
2554 if (!speech_get_attr(this_->speech, attr_active, &attr, NULL))
2555 {
2556 attr.u.num = 1;
2557 }
2558
2559 // dbg(1, "this_.speech->active %i\n", attr.u.num);
2560
2561 dbg(0, "NAV_TURNAROUND:008:enter\n");
2562
2563 if (!attr.u.num)
2564 {
2565 return;
2566 }
2567
2568 if (nav)
2569 map = navigation_get_map(nav);
2570
2571 if (map)
2572 mr = map_rect_new(map, NULL);
2573
2574 if (mr)
2575 {
2576 while ((item = map_rect_get_item(mr)) && (item->type == type_nav_position || item->type == type_nav_none))
2577 {
2578 dbg(0, "NAV_TURNAROUND:008a:%s\n", item_to_name(item->type));
2579 }
2580
2581 dbg(0, "NAV_TURNAROUND:008b:item=%p\n", item);
2582
2583 if (item && item_attr_get(item, attr_navigation_speech, &attr)) // this calls --> navigation_map_item_attr_get(...) --> show_next_maneuvers(...)
2584 {
2585 //dbg(0,"say(2) s=X%sX\n", attr.u.str);
2586
2587 dbg(0, "NAV_TURNAROUND:009:%s\n", attr.u.str);
2588
2589 if (strlen(attr.u.str) > 0)
2590 {
2591 speech_say(this_->speech, attr.u.str);
2592 }
2593 //navit_add_message(this_, attr.u.str);
2594 // navit_textfile_debug_log(this_, "type=announcement label=\"%s\"", attr.u.str);
2595 }
2596 map_rect_destroy(mr);
2597 }
2598 }
2599
2600 static void navit_window_roadbook_update(struct navit *this_)
2601 {
2602
2603
2604 ////DBG dbg(0,"EEnter\n");
2605 struct navigation *nav = this_->navigation;
2606 struct map *map = NULL;
2607 struct map_rect *mr = NULL;
2608 struct item *item;
2609 struct attr attr;
2610 struct param_list param[5];
2611 int secs;
2612
2613 // dbg(1, "enter\n");
2614 datawindow_mode(this_->roadbook_window, 1);
2615 if (nav)
2616 map = navigation_get_map(nav);
2617 if (map)
2618 mr = map_rect_new(map, NULL);
2619 ////DBG dbg(0,"nav=%p map=%p mr=%p\n", nav, map, mr);
2620 if (mr)
2621 {
2622 ////DBG dbg(0,"while loop\n");
2623 while ((item = map_rect_get_item(mr)))
2624 {
2625 ////DBG dbg(0,"item=%p\n", item);
2626 attr.u.str = NULL;
2627 if (item->type != type_nav_position)
2628 {
2629 item_attr_get(item, attr_navigation_long, &attr);
2630 if (attr.u.str == NULL)
2631 {
2632 continue;
2633 }
2634 dbg(2, "Command='%s'\n", attr.u.str);
2635 param[0].value = g_strdup(attr.u.str);
2636 }
2637 else
2638 param[0].value = _("Position");
2639 param[0].name = _("Command");
2640
2641 item_attr_get(item, attr_length, &attr);
2642 dbg(2, "Length=%d\n", attr.u.num);
2643 param[1].name = _("Length");
2644
2645 if (attr.u.num >= 2000)
2646 {
2647 param[1].value = g_strdup_printf("%5.1f %s", (float) attr.u.num / 1000, _("km"));
2648 }
2649 else
2650 {
2651 param[1].value = g_strdup_printf("%7d %s", attr.u.num, _("m"));
2652 }
2653
2654 item_attr_get(item, attr_time, &attr);
2655 dbg(2, "Time=%d\n", attr.u.num);
2656 secs = attr.u.num / 10;
2657 param[2].name = _("Time");
2658 if (secs >= 3600)
2659 {
2660 param[2].value = g_strdup_printf("%d:%02d:%02d", secs / 60, (secs / 60) % 60, secs % 60);
2661 }
2662 else
2663 {
2664 param[2].value = g_strdup_printf("%d:%02d", secs / 60, secs % 60);
2665 }
2666
2667 item_attr_get(item, attr_destination_length, &attr);
2668 dbg(2, "Destlength=%d\n", attr.u.num);
2669 param[3].name = _("Destination Length");
2670 if (attr.u.num >= 2000)
2671 {
2672 param[3].value = g_strdup_printf("%5.1f %s", (float) attr.u.num / 1000, _("km"));
2673 }
2674 else
2675 {
2676 param[3].value = g_strdup_printf("%d %s", attr.u.num, _("m"));
2677 }
2678
2679 item_attr_get(item, attr_destination_time, &attr);
2680 dbg(2, "Desttime=%d\n", attr.u.num);
2681 secs = attr.u.num / 10;
2682 param[4].name = _("Destination Time");
2683 if (secs >= 3600)
2684 {
2685 param[4].value = g_strdup_printf("%d:%02d:%02d", secs / 3600, (secs / 60) % 60, secs % 60);
2686 }
2687 else
2688 {
2689 param[4].value = g_strdup_printf("%d:%02d", secs / 60, secs % 60);
2690 }
2691 datawindow_add(this_->roadbook_window, param, 5);
2692 }
2693 map_rect_destroy(mr);
2694 }
2695 datawindow_mode(this_->roadbook_window, 0);
2696 }
2697
2698 void navit_window_roadbook_destroy(struct navit *this_)
2699 {
2700
2701
2702 ////DBG dbg(0, "enter\n");
2703 navigation_unregister_callback(this_->navigation, attr_navigation_long, this_->roadbook_callback);
2704 this_->roadbook_window = NULL;
2705 this_->roadbook_callback = NULL;
2706 }
2707
2708 void navit_window_roadbook_new(struct navit *this_)
2709 {
2710
2711
2712 if (!this_->gui || this_->roadbook_callback || this_->roadbook_window)
2713 {
2714 return;
2715 }
2716
2717 this_->roadbook_callback = callback_new_1(callback_cast(navit_window_roadbook_update), this_);
2718 navigation_register_callback(this_->navigation, attr_navigation_long, this_->roadbook_callback);
2719 this_->roadbook_window = gui_datawindow_new(this_->gui, _("Roadbook"), NULL, callback_new_1(callback_cast(navit_window_roadbook_destroy), this_));
2720 navit_window_roadbook_update(this_);
2721 }
2722
2723 void navit_remove_all_maps(struct navit *this_)
2724 {
2725
2726
2727
2728 dbg(0,"ROUTExxPOSxx:navit_remove_all_maps:enter\n");
2729
2730 struct mapset *ms;
2731 struct map *map3;
2732
2733 // hold map drawing
2734 // this_->ready = 1;
2735
2736 // first: stop navigation!
2737 //if (global_navit->destination_valid != 0)
2738 //{
2739 navit_set_destination(global_navit, NULL, NULL, 0);
2740 //}
2741
2742
2743 if (this_->tracking)
2744 {
2745 tracking_flush(this_->tracking);
2746 }
2747
2748 if (this_->route)
2749 {
2750 struct attr callback;
2751 // this_->route_cb=callback_new_attr_1(callback_cast(navit_redraw_route), attr_route_status, this_);
2752
2753
2754 callback.type = attr_callback;
2755 callback.u.callback = this_->route_cb;
2756 route_remove_attr(this_->route, &callback);
2757
2758 this_->route->ms = NULL;
2759 // route_set_mapset(this_->route, ms);
2760 // route_set_projection(this_->route, transform_get_projection(this_->trans));
2761
2762 //*********route_destroy(this_->route);
2763
2764 //route_path_destroy(this_->route->path2,1);
2765 //this_->route->path2 = NULL;
2766 //route_graph_destroy(this_->route->graph);
2767 //this_->route->graph=NULL;
2768 }
2769
2770 /*
2771 map_rect_destroy(displaylist->mr);
2772 if (!route_selection)
2773 map_selection_destroy(displaylist->sel);
2774 mapset_close(displaylist->msh);
2775 displaylist->mr=NULL;
2776 displaylist->sel=NULL;
2777 displaylist->m=NULL;
2778 displaylist->msh=NULL;
2779 profile(1,"callback\n");
2780 callback_call_1(displaylist->cb, cancel);
2781 */
2782
2783 struct displaylist *dl = navit_get_displaylist(this_);
2784 dl->m = NULL;
2785 dl->msh = NULL;
2786
2787 if (this_->mapsets)
2788 {
2789 struct mapset_handle *msh;
2790 ms = this_->mapsets->data;
2791 msh = mapset_open(ms);
2792 ////DBG dbg(0,"removing map bb0\n");
2793 while (msh && (map3 = mapset_next(msh, 0)))
2794 {
2795 ////DBG dbg(0,"removing map bb1\n");
2796 struct attr map_name_attr;
2797 if (map_get_attr(map3, attr_name, &map_name_attr, NULL))
2798 {
2799 //DBG dbg(0, "map name=%s", map_name_attr.u.str);
2800 if (strncmp("_ms_sdcard_map:", map_name_attr.u.str, 15) == 0)
2801 {
2802 dbg(0, "removing map name=%s", map_name_attr.u.str);
2803 //DBG dbg(0, "removing map a0\n");
2804 struct attr active;
2805 active.type = attr_active;
2806 active.u.num = 0;
2807 //map_set_attr(map3, &active);
2808
2809 //DBG dbg(0, "removing map a1\n");
2810 struct attr map_attr;
2811 map_attr.u.map = map3;
2812 map_attr.type = attr_map;
2813 mapset_remove_attr(ms, &map_attr);
2814
2815 //DBG dbg(0, "removing map a2\n");
2816 map3->refcount = 1;
2817 map_destroy(map3);
2818 //DBG dbg(0, "removing map a3\n");
2819 map3 = NULL;
2820 }
2821 else if (strncmp("-special-:", map_name_attr.u.str, 10) == 0)
2822 {
2823 dbg(0, "removing (special) map name=%s", map_name_attr.u.str);
2824 struct attr active;
2825 active.type = attr_active;
2826 active.u.num = 0;
2827
2828 struct attr map_attr;
2829 map_attr.u.map = map3;
2830 map_attr.type = attr_map;
2831 mapset_remove_attr(ms, &map_attr);
2832
2833 map3->refcount = 1;
2834 map_destroy(map3);
2835 map3 = NULL;
2836 }
2837 }
2838 }
2839 mapset_close(msh);
2840 //DBG dbg(0, "removing map bb4\n");
2841 }
2842
2843 dl->ms = this_->mapsets->data;
2844
2845 // int async = 0;
2846 // transform_setup_source_rect(this_->trans);
2847 // graphics_draw(this_->gra, this_->displaylist, this_->mapsets->data, this_->trans, this_->layout_current, async, NULL, this_->graphics_flags|1);
2848 //this_->displaylist->ms=this_->mapsets->data;
2849
2850 }
2851
2852 void navit_map_active_flag(struct navit *this_, int activate, const char *mapname)
2853 {
2854 // activate = 0 -> deactivate
2855 // activate = 1 -> activate
2856
2857
2858
2859 struct mapset *ms;
2860 struct map *map3;
2861
2862 if (this_->mapsets)
2863 {
2864 struct mapset_handle *msh;
2865 ms = this_->mapsets->data;
2866 msh = mapset_open(ms);
2867 while (msh && (map3 = mapset_next(msh, 0)))
2868 {
2869 struct attr map_name_attr;
2870 if (map_get_attr(map3, attr_name, &map_name_attr, NULL))
2871 {
2872 dbg(0, "map name=%s\n", map_name_attr.u.str);
2873 if (strcmp(mapname, map_name_attr.u.str) == 0)
2874 {
2875 dbg(0, "setting active flag on map:%s\n", map_name_attr.u.str);
2876
2877 struct attr active;
2878 active.type = attr_active;
2879 active.u.num = activate;
2880 map_set_attr(map3, &active);
2881 }
2882 }
2883 }
2884 mapset_close(msh);
2885 }
2886
2887 }
2888
2889 void navit_add_all_maps(struct navit *this_)
2890 {
2891 __F_START__
2892
2893 struct map *map3;
2894
2895 if (this_->mapsets)
2896 {
2897 //DBG dbg(0, "xADDx all maps - start\n");
2898
2899 struct mapset *ms;
2900 ms = this_->mapsets->data;
2901
2902 struct attr type;
2903 struct attr parent;
2904 struct attr data;
2905 struct attr flags;
2906 struct map *map2;
2907 struct attr map2_attr;
2908 struct attr *attrs[4];
2909 char *map_file;
2910
2911 dbg(0, "001\n");
2912
2913 parent.type = attr_navit;
2914 parent.u.navit = this_;
2915 type.type = attr_type;
2916 type.u.str = "binfile";
2917 data.type = attr_data;
2918 map_file = g_strdup_printf("%sborders.bin", navit_maps_dir);
2919 data.u.str = map_file;
2920
2921 ////DBG dbg(0,"map name=%s",map_file);
2922
2923 flags.type = attr_flags;
2924 flags.u.num = 0;
2925 attrs[0] = &type;
2926 attrs[1] = &data;
2927 attrs[2] = &flags;
2928 attrs[3] = NULL;
2929 map2 = map_new(&parent, attrs);
2930 if (map2)
2931 {
2932 map2_attr.u.data = map2;
2933 map2_attr.type = attr_map;
2934 // mapset_add_attr_name(ms, &map2_attr);
2935 mapset_add_attr_name_str(ms, &map2_attr, "/sdcard/zanavi/maps/borders.bin");
2936 struct attr active;
2937 active.type = attr_active;
2938 active.u.num = 0;
2939 //map_set_attr(map2, &active);
2940
2941 active.type = attr_route_active;
2942 active.u.num = 0; // by default deactivate rounting on this map
2943 map_set_attr(map2, &active);
2944 }
2945 g_free(map_file);
2946
2947
2948
2949 /*
2950 parent.type = attr_navit;
2951 parent.u.navit = this_;
2952 type.type = attr_type;
2953 type.u.str = "binfile";
2954 data.type = attr_data;
2955 map_file = g_strdup_printf("%scoastline.bin", navit_maps_dir);
2956 data.u.str = map_file;
2957
2958 ////DBG dbg(0,"map name=%s",map_file);
2959
2960 flags.type = attr_flags;
2961 flags.u.num = 0;
2962 attrs[0] = &type;
2963 attrs[1] = &data;
2964 attrs[2] = &flags;
2965 attrs[3] = NULL;
2966 map2 = map_new(&parent, attrs);
2967 if (map2)
2968 {
2969 map2_attr.u.data = map2;
2970 map2_attr.type = attr_map;
2971 // mapset_add_attr_name(ms, &map2_attr);
2972 mapset_add_attr_name_str(ms, &map2_attr, "/sdcard/zanavi/maps/coastline.bin");
2973 struct attr active;
2974 active.type = attr_active;
2975 active.u.num = 0;
2976 //map_set_attr(map2, &active);
2977
2978 active.type = attr_route_active;
2979 active.u.num = 0; // by default deactivate rounting on this map
2980 map_set_attr(map2, &active);
2981 }
2982 g_free(map_file);
2983
2984
2985 */
2986
2987
2988 // gpx tracks map --------------------
2989 parent.type = attr_navit;
2990 parent.u.navit = this_;
2991 type.type = attr_type;
2992 type.u.str = "textfile";
2993 data.type = attr_data;
2994 map_file = g_strdup_printf("%sgpxtracks.txt", navit_maps_dir);
2995 data.u.str = map_file;
2996
2997 flags.type = attr_flags;
2998 flags.u.num = 0;
2999 attrs[0] = &type;
3000 attrs[1] = &data;
3001 attrs[2] = &flags;
3002 attrs[3] = NULL;
3003 map2 = map_new(&parent, attrs);
3004 if (map2)
3005 {
3006 map2_attr.u.data = map2;
3007 map2_attr.type = attr_map;
3008 mapset_add_attr_name_str(ms, &map2_attr, "-special-:gpxtracks.txt");
3009 struct attr active;
3010 active.type = attr_active;
3011 active.u.num = 0;
3012 //map_set_attr(map2, &active);
3013 }
3014 g_free(map_file);
3015 // gpx tracks map --------------------
3016
3017
3018 // traffic map --------------------
3019 parent.type = attr_navit;
3020 parent.u.navit = this_;
3021 type.type = attr_type;
3022 type.u.str = "textfile";
3023 data.type = attr_data;
3024 map_file = g_strdup_printf("%straffic.txt", navit_maps_dir);
3025 data.u.str = map_file;
3026
3027 flags.type = attr_flags;
3028 flags.u.num = 0;
3029 attrs[0] = &type;
3030 attrs[1] = &data;
3031 attrs[2] = &flags;
3032 attrs[3] = NULL;
3033 map2 = map_new(&parent, attrs);
3034 if (map2)
3035 {
3036 map2_attr.u.data = map2;
3037 map2_attr.type = attr_map;
3038 mapset_add_attr_name_str(ms, &map2_attr, "-special-:traffic.txt");
3039 struct attr active;
3040 active.type = attr_active;
3041 active.u.num = 0;
3042 //map_set_attr(map2, &active);
3043 }
3044 g_free(map_file);
3045 // traffic map --------------------
3046
3047
3048 dbg(0, "002\n");
3049
3050
3051 // world map2 --------------------
3052 parent.type = attr_navit;
3053 parent.u.navit = this_;
3054 type.type = attr_type;
3055 type.u.str = "textfile";
3056 data.type = attr_data;
3057 map_file = g_strdup_printf("%sworldmap2.txt", navit_maps_dir);
3058 data.u.str = map_file;
3059
3060 dbg(0, "activate map:%s\n", map_file);
3061
3062 flags.type = attr_flags;
3063 flags.u.num = 0;
3064 attrs[0] = &type;
3065 attrs[1] = &data;
3066 attrs[2] = &flags;
3067 attrs[3] = NULL;
3068 map2 = map_new(&parent, attrs);
3069 if (map2)
3070 {
3071 map2_attr.u.data = map2;
3072 map2_attr.type = attr_map;
3073 mapset_add_attr_name_str(ms, &map2_attr, "-special-:worldmap2.txt");
3074 struct attr active;
3075 active.type = attr_active;
3076 active.u.num = 1; // by default activate map
3077 // map_set_attr(map2, &active);
3078
3079 active.type = attr_route_active;
3080 active.u.num = 0; // by default deactivate routing on this map
3081 map_set_attr(map2, &active);
3082
3083 }
3084 g_free(map_file);
3085 // world map2 --------------------
3086
3087
3088 // world map5 --------------------
3089 parent.type = attr_navit;
3090 parent.u.navit = this_;
3091 type.type = attr_type;
3092 type.u.str = "textfile";
3093 data.type = attr_data;
3094 map_file = g_strdup_printf("%sworldmap5.txt", navit_maps_dir);
3095 data.u.str = map_file;
3096
3097 dbg(0, "activate map:%s\n", map_file);
3098
3099 flags.type = attr_flags;
3100 flags.u.num = 0;
3101 attrs[0] = &type;
3102 attrs[1] = &data;
3103 attrs[2] = &flags;
3104 attrs[3] = NULL;
3105 map2 = map_new(&parent, attrs);
3106 if (map2)
3107 {
3108 map2_attr.u.data = map2;
3109 map2_attr.type = attr_map;
3110 mapset_add_attr_name_str(ms, &map2_attr, "-special-:worldmap5.txt");
3111 struct attr active;
3112 active.type = attr_active;
3113 active.u.num = 1; // by default activate map
3114 // map_set_attr(map2, &active);
3115
3116 active.type = attr_route_active;
3117 active.u.num = 0; // by default deactivate routing on this map
3118 map_set_attr(map2, &active);
3119 }
3120 g_free(map_file);
3121 // world map5 --------------------
3122
3123 dbg(0, "003\n");
3124
3125
3126 #if 0
3127 // world map6 --------------------
3128 parent.type = attr_navit;
3129 parent.u.navit = this_;
3130 type.type = attr_type;
3131 type.u.str = "textfile";
3132 data.type = attr_data;
3133 map_file = g_strdup_printf("%sworldmap6.txt", navit_maps_dir);
3134 data.u.str = map_file;
3135
3136 dbg(0, "activate map:%s\n", map_file);
3137
3138 flags.type = attr_flags;
3139 flags.u.num = 0;
3140 attrs[0] = &type;
3141 attrs[1] = &data;
3142 attrs[2] = &flags;
3143 attrs[3] = NULL;
3144 map2 = map_new(&parent, attrs);
3145 if (map2)
3146 {
3147 map2_attr.u.data = map2;
3148 map2_attr.type = attr_map;
3149 mapset_add_attr_name_str(ms, &map2_attr, "-special-:worldmap6.txt");
3150 struct attr active;
3151 active.type = attr_active;
3152 active.u.num = 1; // by default activate map
3153 // map_set_attr(map2, &active);
3154
3155 active.type = attr_route_active;
3156 active.u.num = 0; // by default deactivate routing on this map
3157 map_set_attr(map2, &active);
3158 }
3159 g_free(map_file);
3160 // world map6 --------------------
3161 #endif
3162
3163 dbg(0, "004\n");
3164
3165
3166 int i = 1;
3167 for (i = 1; i < 10; i++)
3168 {
3169 struct map *map22;
3170 struct attr map22_attr;
3171 parent.type = attr_navit;
3172 parent.u.navit = this_;
3173 type.type = attr_type;
3174 type.u.str = "binfile";
3175 data.type = attr_data;
3176 map_file = g_strdup_printf("%snavitmap_00%d.bin", navit_maps_dir, i);
3177 data.u.str = map_file;
3178 flags.type = attr_flags;
3179 flags.u.num = 0;
3180 attrs[0] = &type;
3181 attrs[1] = &data;
3182 attrs[2] = &flags;
3183 attrs[3] = NULL;
3184 map22 = map_new(&parent, attrs);
3185 if (map22)
3186 {
3187 //DBG dbg(0, "*add* map name=%s\n", map_file);
3188 map22_attr.u.data = map22;
3189 map22_attr.type = attr_map;
3190 // mapset_add_attr_name(ms, &map22_attr);
3191 char *map_name_str;
3192 map_name_str = g_strdup_printf("/sdcard/zanavi/maps/navitmap_00%d.bin", i);
3193 mapset_add_attr_name_str(ms, &map22_attr, map_name_str);
3194 struct attr active;
3195 active.type = attr_active;
3196 active.u.num = 0;
3197 //map_set_attr(map22, &active);
3198 g_free(map_name_str);
3199 }
3200 g_free(map_file);
3201 }
3202
3203 i = 10;
3204 for (i = 10; i < 61; i++)
3205 {
3206 parent.type = attr_navit;
3207 parent.u.navit = this_;
3208 type.type = attr_type;
3209 type.u.str = "binfile";
3210 data.type = attr_data;
3211 map_file = g_strdup_printf("%snavitmap_0%d.bin", navit_maps_dir, i);
3212 data.u.str = map_file;
3213 ////DBG dbg(0,"map name=%s",map_file);
3214 flags.type = attr_flags;
3215 flags.u.num = 0;
3216 attrs[0] = &type;
3217 attrs[1] = &data;
3218 attrs[2] = &flags;
3219 attrs[3] = NULL;
3220 map2 = map_new(&parent, attrs);
3221 if (map2)
3222 {
3223 map2_attr.u.data = map2;
3224 map2_attr.type = attr_map;
3225 // mapset_add_attr_name(ms, &map2_attr);
3226 char *map_name_str;
3227 map_name_str = g_strdup_printf("/sdcard/zanavi/maps/navitmap_0%d.bin", i);
3228 mapset_add_attr_name_str(ms, &map2_attr, map_name_str);
3229 struct attr active;
3230 active.type = attr_active;
3231 active.u.num = 0;
3232 //map_set_attr(map2, &active);
3233 g_free(map_name_str);
3234 }
3235 g_free(map_file);
3236 }
3237 }
3238
3239 /*
3240 if (this_->mapsets)
3241 {
3242 struct mapset_handle *msh;
3243 struct map *map;
3244 struct mapset *ms;
3245
3246 //DBG dbg(0,"xx ms callbacks xx\n");
3247
3248 ms=this_->mapsets->data;
3249 this_->progress_cb=callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
3250 msh=mapset_open(ms);
3251 while (msh && (map=mapset_next(msh, 0)))
3252 {
3253 //pass new callback instance for each map in the mapset to make map callback list destruction work correctly
3254 struct callback *pcb = callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
3255 map_add_callback(map, pcb);
3256 }
3257 mapset_close(msh);
3258 }
3259 */
3260
3261 /*
3262 struct attr parent;
3263 parent.type = attr_navit;
3264 parent.u.navit = global_navit;
3265
3266 struct attr *attrs_r[2];
3267 attrs_r[0] = NULL;
3268 attrs_r[1] = NULL;
3269 */
3270
3271 //***this_->route = route_new(&parent, attrs_r);
3272
3273
3274 //int async = 0;
3275 //transform_setup_source_rect(this_->trans);
3276 //graphics_draw(this_->gra, this_->displaylist, this_->mapsets->data, this_->trans, this_->layout_current, async, NULL, this_->graphics_flags|1);
3277
3278 if (this_->mapsets)
3279 {
3280 dbg(0, "005\n");
3281
3282 struct displaylist *dl = navit_get_displaylist(this_);
3283 dbg(0, "005a dl=%p\n", dl);
3284 dbg(0, "005a1 ms=%p\n", this_->mapsets);
3285 dbg(0, "005a2 ms=%p\n", this_->mapsets->data);
3286 dl->ms = this_->mapsets->data;
3287 dbg(0, "005b\n");
3288 dl->m = NULL;
3289 dbg(0, "005c\n");
3290 dl->msh = NULL;
3291
3292 dbg(0, "005.1\n");
3293
3294 if (this_->route)
3295 {
3296 dbg(0, "005.2\n");
3297
3298 struct mapset *ms;
3299 dbg(0, "005.3\n");
3300 ms = this_->mapsets->data;
3301 dbg(0, "005.4\n");
3302 route_set_mapset(this_->route, ms);
3303
3304 dbg(0, "005.5\n");
3305
3306 struct attr callback;
3307 this_->route_cb = callback_new_attr_1(callback_cast(navit_redraw_route), attr_route_status, this_);
3308 dbg(0, "005.6\n");
3309 callback_add_names(this_->route_cb, "navit_add_all_maps", "navit_redraw_route");
3310 dbg(0, "005.7\n");
3311 callback.type = attr_callback;
3312 dbg(0, "005.8\n");
3313 callback.u.callback = this_->route_cb;
3314 dbg(0, "005.9\n");
3315 route_add_attr(this_->route, &callback);
3316 dbg(0, "005.10\n");
3317 // ***** route_set_projection(this_->route, transform_get_projection(this_->trans));
3318
3319
3320 }
3321
3322
3323 dbg(0, "006\n");
3324
3325
3326 if (this_->tracking)
3327 {
3328 struct mapset *ms;
3329 ms = this_->mapsets->data;
3330
3331 tracking_set_mapset(this_->tracking, ms);
3332 if (this_->route)
3333 {
3334 tracking_set_route(this_->tracking, this_->route);
3335 }
3336 }
3337
3338 }
3339
3340 // ready for drawing map
3341 // this_->ready = 3;
3342
3343 // draw map
3344 // navit_draw(this_);
3345
3346 __F_END__
3347 }
3348
3349 void navit_reload_maps(struct navit *this_)
3350 {
3351
3352
3353
3354 dbg(0,"ROUTExxPOSxx:navit_reload_maps:enter\n");
3355
3356 navit_remove_all_maps(this_);
3357 navit_add_all_maps(this_);
3358 }
3359
3360
3361 // --- forward def ----
3362 void navit_set_vehicle_position_to_screen_center(struct navit *this_);
3363 // --- forward def ----
3364
3365 void navit_init(struct navit *this_)
3366 {
3367
3368
3369 ////DBG dbg(0,"EEnter\n");
3370 struct mapset *ms;
3371 struct map *map;
3372 int callback;
3373 char *center_file;
3374
3375 // dbg(0,"GGGGG:set global_navit\n");
3376 // global_navit = this_;
3377
3378 // default value
3379 navit_maps_dir = "/sdcard/zanavi/maps/";
3380
3381 global_img_waypoint = NULL;
3382
3383 //DBG dbg(0, "enter gui %p graphics %p\n", this_->gui, this_->gra);
3384
3385 if (!this_->gui && !(this_->flags & 2))
3386 {
3387 dbg(0, "no gui\n");
3388 navit_destroy(this_);
3389 return;
3390 }
3391
3392 if (!this_->gra && !(this_->flags & 1))
3393 {
3394 dbg(0, "no graphics\n");
3395 navit_destroy(this_);
3396 return;
3397 }
3398
3399
3400 #ifdef NAVIT_FREE_TEXT_DEBUG_PRINT
3401 dbg(0, "DEST::route_clear_freetext_list(000)\n");
3402 route_clear_freetext_list();
3403 #endif
3404
3405
3406 //DBG dbg(0, "Connecting gui to graphics\n");
3407
3408 if (this_->gui && this_->gra && gui_set_graphics(this_->gui, this_->gra))
3409 {
3410 struct attr attr_type_gui, attr_type_graphics;
3411 gui_get_attr(this_->gui, attr_type, &attr_type_gui, NULL);
3412 graphics_get_attr(this_->gra, attr_type, &attr_type_graphics, NULL);
3413
3414 dbg(0, "failed to connect to graphics\n");
3415 navit_destroy(this_);
3416 return;
3417 }
3418
3419 if (this_->speech && this_->navigation)
3420 {
3421 struct attr speech;
3422 speech.type = attr_speech;
3423 speech.u.speech = this_->speech;
3424 navigation_set_attr(this_->navigation, &speech);
3425 }
3426
3427 //DBG dbg(0, "Initializing graphics\n");
3428 //DBG dbg(0, "Setting Vehicle\n");
3429 navit_set_vehicle(this_, this_->vehicle);
3430
3431 //DBG dbg(0, "Adding dynamic maps to mapset %p\n", this_->mapsets);
3432 if (this_->mapsets)
3433 {
3434 struct mapset_handle *msh;
3435 ms = this_->mapsets->data;
3436 // **D** // this_->progress_cb=callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
3437 msh = mapset_open(ms);
3438 while (msh && (map = mapset_next(msh, 0)))
3439 {
3440 //pass new callback instance for each map in the mapset to make map callback list destruction work correctly
3441 // **D** // struct callback *pcb = callback_new_attr_1(callback_cast(navit_map_progress), attr_progress, this_);
3442 // **D** // map_add_callback(map, pcb);
3443 }
3444 mapset_close(msh);
3445
3446 if (this_->route)
3447 {
3448 if ((map = route_get_map(this_->route)))
3449 {
3450 struct attr map_a, map_name;
3451 map_a.type = attr_map;
3452 map_a.u.map = map;
3453 map_name.type = attr_name;
3454 map_name.u.str = "_ms_route";
3455 map_set_attr(map_a.u.map, &map_name);
3456 mapset_add_attr(ms, &map_a);
3457 }
3458
3459 if ((map = route_get_graph_map(this_->route)))
3460 {
3461 struct attr map_a, active, map_name;
3462 map_a.type = attr_map;
3463 map_a.u.map = map;
3464 active.type = attr_active;
3465 active.u.num = 0;
3466 map_name.type = attr_name;
3467 map_name.u.str = "_ms_route_graph";
3468 map_set_attr(map_a.u.map, &map_name);
3469 mapset_add_attr(ms, &map_a);
3470 map_set_attr(map, &active);
3471 }
3472 route_set_mapset(this_->route, ms);
3473 route_set_projection(this_->route, transform_get_projection(this_->trans));
3474 }
3475
3476 if (this_->tracking)
3477 {
3478 tracking_set_mapset(this_->tracking, ms);
3479 if (this_->route)
3480 {
3481 tracking_set_route(this_->tracking, this_->route);
3482 }
3483 }
3484
3485 if (this_->navigation)
3486 {
3487 if ((map = navigation_get_map(this_->navigation)))
3488 {
3489 struct attr map_a, active, map_name;
3490 map_a.type = attr_map;
3491 map_a.u.map = map;
3492 active.type = attr_active;
3493 active.u.num = 0;
3494 map_name.type = attr_name;
3495 map_name.u.str = "_ms_navigation";
3496 map_set_attr(map_a.u.map, &map_name);
3497 mapset_add_attr(ms, &map_a);
3498 map_set_attr(map, &active);
3499 }
3500 }
3501
3502 if (this_->tracking)
3503 {
3504 if ((map = tracking_get_map(this_->tracking)))
3505 {
3506 struct attr map_a, active, map_name;
3507 map_a.type = attr_map;
3508 map_a.u.map = map;
3509 active.type = attr_active;
3510 active.u.num = 0;
3511 map_name.type = attr_name;
3512 map_name.u.str = "_ms_tracking";
3513 map_set_attr(map_a.u.map, &map_name);
3514 mapset_add_attr(ms, &map_a);
3515 map_set_attr(map, &active);
3516 }
3517 }
3518 // *DISABLED* navit_add_former_destinations_from_file(this_);
3519 }
3520
3521 if (this_->route)
3522 {
3523 /*
3524 *DISABLED* done in "navit_add_all_maps"
3525
3526 struct attr callback;
3527 this_->route_cb = callback_new_attr_1(callback_cast(navit_redraw_route), attr_route_status, this_);
3528 callback_add_names(this_->route_cb, "navit_init", "navit_redraw_route");
3529 callback.type = attr_callback;
3530 callback.u.callback = this_->route_cb;
3531 route_add_attr(this_->route, &callback);
3532 */
3533 }
3534
3535 if (this_->navigation)
3536 {
3537 if (this_->speech)
3538 {
3539 this_->nav_speech_cb = callback_new_1(callback_cast(navit_speak), this_);
3540 callback_add_names(this_->nav_speech_cb, "navit_init", "navit_speak");
3541 navigation_register_callback(this_->navigation, attr_navigation_speech, this_->nav_speech_cb);
3542 }
3543
3544 if (this_->route)
3545 {
3546 navigation_set_route(this_->navigation, this_->route);
3547 }
3548 }
3549
3550 dbg(0, "Setting Center\n");
3551 center_file = bookmarks_get_center_file(FALSE);
3552 //dbg(0, "g0\n");
3553 bookmarks_set_center_from_file(this_->bookmarks, center_file);
3554 g_free(center_file);
3555
3556 dbg(0, "Set Vehicle Position to Center\n");
3557 navit_set_vehicle_position_to_screen_center(this_);
3558
3559 #if 0
3560 if (this_->menubar)
3561 {
3562 men=menu_add(this_->menubar, "Data", menu_type_submenu, NULL);
3563 if (men)
3564 {
3565 navit_add_menu_windows_items(this_, men);
3566 }
3567 }
3568 #endif
3569
3570 #if 0
3571 navit_window_roadbook_new(this_);
3572 navit_window_items_new(this_);
3573 #endif
3574
3575 //dbg(0, "g1\n");
3576 //messagelist_init(this_->messages);
3577
3578 //dbg(0, "g2\n");
3579 navit_set_cursors(this_);
3580
3581 callback_list_call_attr_1(this_->attr_cbl, attr_navit, this_);
3582 callback = (this_->ready == 2);
3583 dbg(0, "pre this_->ready=%d\n", this_->ready);
3584 this_->ready = this_->ready | 1;
3585 dbg(0, "set this_->ready=%d\n", this_->ready);
3586 ////DBG dbg(0,"ready=%d\n",this_->ready);
3587
3588
3589 //if (this_->ready == 3)
3590 //{
3591 // ////DBG dbg(0,"navit_draw_async_003\n");
3592 // navit_draw_async(this_, 1);
3593 //}
3594
3595 dbg(0, "init ready=%d\n", this_->ready);
3596
3597 // draw???????
3598 // dbg(0,"init DRAW 11\n");
3599 // ready to draw map
3600 // navit_draw(this_);
3601 // dbg(0,"init DRAW 22\n");
3602 // draw???????
3603
3604 if (callback)
3605 {
3606 callback_list_call_attr_1(this_->attr_cbl, attr_graphics_ready, this_);
3607 }
3608 #if 0
3609 routech_test(this_);
3610 #endif
3611 //dbg(0, "1111111111\n");
3612 }
3613
3614
3615
3616 // ----- forward def! -----
3617 void navit_set_position_without_map_drawing(struct navit *this_, struct pcoord *c);
3618 // ----- forward def! -----
3619
3620 void navit_set_vehicle_position_to_screen_center_only_for_route_struct(struct navit *this_)
3621 {
3622 struct coord c;
3623 char *center_file;
3624 center_file = bookmarks_get_center_file(FALSE);
3625 bookmarks_get_center_from_file(this_->bookmarks, center_file, &c);
3626 g_free(center_file);
3627
3628 struct pcoord pc;
3629 pc.x = c.x;
3630 pc.y = c.y;
3631 pc.pro = transform_get_projection(this_->trans);
3632 // result: pc.x, pc.y
3633
3634 // set position
3635 navit_set_position_without_map_drawing(this_, &pc);
3636 }
3637
3638 void navit_set_vehicle_position_to_screen_center(struct navit *this_)
3639 {
3640
3641 // map center to pixel x,y on screen
3642 // enum projection pro = transform_get_projection(this_->trans);
3643 // struct point pnt;
3644 // struct coord *c992;
3645 // c992 = transform_get_center(this_->trans);
3646 // transform(this_->trans, pro, c992, &pnt, 1, 0, 0, NULL);
3647 // dbg(0, "navit_set_vehicle_position_to_screen_center pnt.x=%d pnt.y=%d\n", pnt.x, pnt.y);
3648 // result: pnt.x, pnt.y
3649
3650
3651 // geo to pixel-on-screen
3652 // struct coord c99;
3653 // struct coord_geo g99;
3654 // g99.lat = lat;
3655 // g99.lng = lon;
3656 // dbg(0,"zzzzz %f, %f\n",a, b);
3657 // dbg(0,"yyyyy %f, %f\n",g99.lat, g99.lng);
3658 // transform_from_geo(projection_mg, &g99, &c99);
3659 // dbg(0,"%d %d %f %f\n",c99.x, c99.y, g99.lat, g99.lng);
3660
3661 // enum projection pro = transform_get_projection(global_navit->trans_cursor);
3662 // struct point pnt;
3663 // transform(global_navit->trans, pro, &c99, &pnt, 1, 0, 0, NULL);
3664 // dbg(0,"x=%d\n",pnt.x);
3665 // dbg(0,"y=%d\n",pnt.y);
3666
3667
3668 struct coord c;
3669 char *center_file;
3670 center_file = bookmarks_get_center_file(FALSE);
3671 bookmarks_get_center_from_file(this_->bookmarks, center_file, &c);
3672 g_free(center_file);
3673
3674
3675 // coord to geo
3676 struct coord_geo g22;
3677 // struct coord c22;
3678 ////DBG // dbg(0,"%f, %f\n",a, b);
3679 ////DBG // dbg(0,"%d, %d\n",p.x, p.y);
3680 transform_to_geo(projection_mg, &c, &g22);
3681 dbg(0,"navit_set_vehicle_position_to_screen_center: %d, %d, %f, %f\n",c.x, c.y, g22.lat, g22.lng);
3682 // result = g_strdup_printf("%f:%f", g22.lat, g22.lng);
3683
3684
3685 // set vehicle position to pixel x,y
3686 //struct point p;
3687 //struct coord c;
3688
3689 // pixel-x
3690 //p.x = pnt.x;
3691 // pixel-y
3692 //p.y = pnt.y;
3693
3694 //transform_reverse(this_->trans, &p, &c);
3695
3696 struct pcoord pc;
3697 pc.x = c.x;
3698 pc.y = c.y;
3699 pc.pro = transform_get_projection(this_->trans);
3700 // result: pc.x, pc.y
3701
3702 // set position
3703 navit_set_position_without_map_drawing(this_, &pc);
3704
3705
3706 //center.pro = projection_screen;
3707 //center.x = 0;
3708 //center.y = 0;
3709 //DBG dbg(0, "veh new 5\n");
3710 // transform_setup(this_->vehicle->vehicle->trans, &pc, 16, 0);
3711 // transform_set_center(this_->vehicle->vehicle->trans, &c);
3712 // zzzzzzzzzzzzzz int vehicle_set_cursor_data_01(struct vehicle *this, struct point *pnt)
3713
3714 if ((this_) && (this_->vehicle))
3715 {
3716 this_->vehicle->coord.x = c.x;
3717 this_->vehicle->coord.y = c.y;
3718 }
3719
3720 if ((this_) && (this_->vehicle) && (this_->vehicle->vehicle))
3721 {
3722 float speed = 0;
3723 float direction = 0;
3724 double height = 0;
3725 float radius = 0;
3726 long gpstime = 0;
3727 vehicle_update_(this_->vehicle->vehicle, g22.lat, g22.lng, speed, direction, height, radius, gpstime);
3728 }
3729 else
3730 {
3731 dbg(0, "navit_set_vehicle_position_to_screen_center: no vehicle set !!\n");
3732 }
3733 }
3734
3735
3736
3737
3738 void navit_zoom_to_rect(struct navit *this_, struct coord_rect *r)
3739 {
3740 struct coord c;
3741 int scale = 16;
3742
3743 c.x = (r->rl.x + r->lu.x) / 2;
3744 c.y = (r->rl.y + r->lu.y) / 2;
3745 transform_set_center(this_->trans, &c);
3746
3747 while (scale < 1 << 20)
3748 {
3749 struct point p1, p2;
3750 transform_set_scale(this_->trans, scale);
3751 transform_setup_source_rect(this_->trans);
3752 transform(this_->trans, transform_get_projection(this_->trans), &r->lu, &p1, 1, 0, 0, NULL);
3753 transform(this_->trans, transform_get_projection(this_->trans), &r->rl, &p2, 1, 0, 0, NULL);
3754
3755 if (p1.x < 0 || p2.x < 0 || p1.x > this_->w || p2.x > this_->w || p1.y < 0 || p2.y < 0 || p1.y > this_->h || p2.y > this_->h)
3756 {
3757 scale *= 2;
3758 }
3759 else
3760 {
3761 break;
3762 }
3763 }
3764
3765 dbg(0, "scale=%d\n", scale);
3766 dbg(0, "this_->ready=%d\n", this_->ready);
3767
3768 if (this_->ready == 3)
3769 {
3770 // dbg(0,"navit_draw_async_004\n");
3771 //dbg(0,"DO__DRAW:navit_draw_async call\n");
3772 navit_draw_async(this_, 0);
3773 }
3774 }
3775
3776 void navit_zoom_to_route(struct navit *this_, int orientation)
3777 {
3778 struct map *map;
3779 struct map_rect *mr = NULL;
3780 struct item *item;
3781 struct coord c;
3782 struct coord_rect r;
3783 int count = 0;
3784
3785 if (!this_->route)
3786 {
3787 return;
3788 }
3789
3790 map = route_get_map(this_->route);
3791
3792 if (map)
3793 {
3794 mr = map_rect_new(map, NULL);
3795 }
3796
3797 if (mr)
3798 {
3799 while ((item = map_rect_get_item(mr)))
3800 {
3801 while (item_coord_get(item, &c, 1))
3802 {
3803 if (!count)
3804 {
3805 r.lu = r.rl = c;
3806 }
3807 else
3808 {
3809 coord_rect_extend(&r, &c);
3810 }
3811 count++;
3812 }
3813 }
3814 map_rect_destroy(mr);
3815 }
3816
3817 if (!count)
3818 {
3819 return;
3820 }
3821
3822 if (orientation != -1)
3823 {
3824 transform_set_yaw(this_->trans, orientation);
3825 }
3826
3827 // if overspill > 1 ?
3828 if (global_overspill_factor > 1.0f)
3829 {
3830 coord_rect_extend_by_percent(&r, (global_overspill_factor - 1.0f));
3831 }
3832
3833 navit_zoom_to_rect(this_, &r);
3834 }
3835
3836 static void navit_cmd_zoom_to_route(struct navit *this)
3837 {
3838
3839
3840 ////DBG dbg(0,"EEnter\n");
3841 navit_zoom_to_route(this, 0);
3842 }
3843
3844 /**
3845 * show point on map
3846 *
3847 * @param navit The navit instance
3848 * @param center The point where to center the map, including its projection
3849 * @returns nothing
3850 */
3851 void navit_set_center(struct navit *this_, struct pcoord *center, int set_timeout)
3852 {
3853
3854
3855 ////DBG dbg(0,"EEnter\n");
3856 struct coord *c = transform_center(this_->trans);
3857 struct coord c1, c2;
3858 enum projection pro = transform_get_projection(this_->trans);
3859
3860 if (pro != center->pro)
3861 {
3862 c1.x = center->x;
3863 c1.y = center->y;
3864 transform_from_to(&c1, center->pro, &c2, pro);
3865 }
3866 else
3867 {
3868 c2.x = center->x;
3869 c2.y = center->y;
3870 }
3871
3872 *c = c2;
3873 if (set_timeout)
3874 {
3875 navit_set_timeout(this_);
3876 }
3877
3878 if (this_->ready == 3)
3879 {
3880 navit_draw(this_);
3881 }
3882 }
3883
3884
3885 void navit_set_center_no_draw(struct navit *this_, struct pcoord *center, int set_timeout)
3886 {
3887
3888
3889 ////DBG dbg(0,"EEnter\n");
3890 struct coord *c = transform_center(this_->trans);
3891 struct coord c1, c2;
3892 enum projection pro = transform_get_projection(this_->trans);
3893
3894 if (pro != center->pro)
3895 {
3896 c1.x = center->x;
3897 c1.y = center->y;
3898 transform_from_to(&c1, center->pro, &c2, pro);
3899 }
3900 else
3901 {
3902 c2.x = center->x;
3903 c2.y = center->y;
3904 }
3905
3906 *c = c2;
3907 if (set_timeout)
3908 {
3909 navit_set_timeout(this_);
3910 }
3911 }
3912
3913 static void navit_set_center_coord_screen(struct navit *this_, struct coord *c, struct point *p, int set_timeout)
3914 {
3915
3916
3917 ////DBG dbg(0,"EEnter\n");
3918 int width, height;
3919 struct point po;
3920 transform_set_center(this_->trans, c);
3921 transform_get_size(this_->trans, &width, &height);
3922 po.x = width / 2;
3923 po.y = height / 2;
3924 update_transformation(this_->trans, &po, p, NULL);
3925 if (set_timeout)
3926 {
3927 navit_set_timeout(this_);
3928 }
3929 }
3930
3931 /**
3932 * Links all vehicles to a cursor depending on the current profile.
3933 *
3934 * @param this_ A navit instance
3935 * @author Ralph Sennhauser (10/2009)
3936 */
3937 void navit_set_cursors(struct navit *this_)
3938 {
3939
3940
3941 struct attr name;
3942 struct navit_vehicle *nv;
3943 struct cursor *c;
3944 GList *v;
3945
3946 //dbg(0, "Enter\n");
3947
3948 v = g_list_first(this_->vehicles); // GList of navit_vehicles
3949 while (v)
3950 {
3951 dbg(0, "* found vehicle *\n");
3952 nv = v->data;
3953 if (vehicle_get_attr(nv->vehicle, attr_cursorname, &name, NULL))
3954 {
3955 if (!strcmp(name.u.str, "none"))
3956 {
3957 c = NULL;
3958 }
3959 else
3960 {
3961 c = layout_get_cursor(this_->layout_current, name.u.str);
3962 }
3963 }
3964 else
3965 {
3966 c = layout_get_cursor(this_->layout_current, "default");
3967 }
3968 vehicle_set_cursor(nv->vehicle, c, 0);
3969 v = g_list_next(v);
3970 }
3971 return;
3972 }
3973
3974 void navit_remove_cursors(struct navit *this_)
3975 {
3976
3977
3978 struct attr name;
3979 struct navit_vehicle *nv;
3980 struct cursor *c;
3981 GList *v;
3982
3983 //dbg(0, "Enter\n");
3984 name.type = attr_cursor;
3985
3986 v = g_list_first(this_->vehicles); // GList of navit_vehicles
3987 while (v)
3988 {
3989 dbg(0, "* found vehicle *\n");
3990 nv = v->data;
3991 vehicle_remove_attr(nv->vehicle, &name);
3992 v = g_list_next(v);
3993 }
3994 return;
3995 }
3996
3997 static int navit_get_cursor_pnt(struct navit *this_, struct point *p, int keep_orientation, int *dir)
3998 {
3999 //// dbg(0,"EEnter\n");
4000
4001 int width, height;
4002 struct navit_vehicle *nv = this_->vehicle;
4003
4004 // valid values: 0 - 50 (0 -> center of screen, 50 -> bottom of screen)
4005 // float offset = this_->radius; // Cursor offset from the center of the screen (percent). // percent of what??
4006
4007 float offset = 0;
4008
4009
4010 #if 0
4011
4012 /* Better improve track.c to get that issue resolved or make it configurable with being off the default, the jumping back to the center is a bit annoying */
4013 float min_offset = 0.; // Percent offset at min_offset_speed.
4014 float max_offset = 30.; // Percent offset at max_offset_speed.
4015 int min_offset_speed = 2; // Speed in km/h
4016 int max_offset_speed = 50; // Speed ini km/h
4017 // Calculate cursor offset from the center of the screen, upon speed.
4018 if (nv->speed <= min_offset_speed)
4019 {
4020 offset = min_offset;
4021 }
4022 else if (nv->speed > max_offset_speed)
4023 {
4024 offset = max_offset;
4025 }
4026 else
4027 {
4028 offset = (max_offset - min_offset) / (max_offset_speed - min_offset_speed) * (nv->speed - min_offset_speed);
4029 }
4030
4031 #endif
4032
4033 transform_get_size(this_->trans, &width, &height);
4034
4035 if (height == 0)
4036 {
4037 offset = 0;
4038 }
4039 else
4040 {
4041 // dbg(0, "VEHICLE_OFFSET:a:r=%d %d %d\n", (int)this_->radius, (int)(height - this_->radius), (int)((height - this_->radius) - (height / 2)));
4042 offset = (float)((height - this_->radius) - (height / 2)) / (float)height * (float)50.0;
4043 // dbg(0, "VEHICLE_OFFSET:b:o=%d\n", (int)offset);
4044 }
4045
4046
4047 // dbg(0, "VEHICLE_OFFSET:or=%d keep_or=%d\n", this_->orientation, keep_orientation);
4048
4049 if (this_->orientation == -1 || keep_orientation)
4050 {
4051 p->x = 50 * width / 100; // = (width / 2) // why doesnt it just say that?
4052 p->y = (50 + (int)offset) * height / 100;
4053
4054 // dbg(0, "VEHICLE_OFFSET:2:%d %d %d\n", p->y, width, height);
4055
4056 if (dir)
4057 {
4058 *dir = keep_orientation ? this_->orientation : nv->dir;
4059 }
4060 }
4061 else
4062 {
4063 int mdir;
4064 if (this_->tracking && this_->tracking_flag)
4065 {
4066 mdir = tracking_get_angle(this_->tracking) - this_->orientation;
4067 // dbg(0, "+++++tr angle=%d\n", tracking_get_angle(this_->tracking));
4068 // dbg(0, "+++++this ori=%d\n", this_->orientation);
4069 }
4070 else
4071 {
4072 mdir = nv->dir - this_->orientation;
4073 }
4074
4075 p->x = (50 - offset * sin(M_PI * mdir / 180.)) * width / 100;
4076 p->y = (50 + offset * cos(M_PI * mdir / 180.)) * height / 100;
4077
4078 // dbg(0, "VEHICLE_OFFSET:3:%d %d %d\n", p->y, width, height);
4079
4080 if (dir)
4081 {
4082 *dir = this_->orientation;
4083 }
4084 }
4085 return 1;
4086 }
4087
4088 void navit_set_center_cursor(struct navit *this_, int autozoom, int keep_orientation)
4089 {
4090
4091
4092 ////DBG dbg(0,"EEnter\n");
4093 int dir;
4094 struct point pn;
4095 struct navit_vehicle *nv = this_->vehicle;
4096 navit_get_cursor_pnt(this_, &pn, keep_orientation, &dir);
4097 transform_set_yaw(this_->trans, dir);
4098 navit_set_center_coord_screen(this_, &nv->coord, &pn, 0);
4099 // OLD // navit_aXXutozoom(this_, &nv->coord, nv->speed, 0);
4100 }
4101
4102 static void navit_set_center_cursor_draw(struct navit *this_)
4103 {
4104
4105
4106 //dbg(0,"EEnter\n");
4107 navit_set_center_cursor(this_, 1, 0);
4108 if (this_->ready == 3)
4109 {
4110 // dbg(0,"navit_draw_async_005\n");
4111 //dbg(0,"DO__DRAW:navit_draw_async call (AS)\n");
4112 // zzz554 // navit_draw_async(this_, 1);
4113 }
4114 }
4115
4116 static void navit_cmd_set_center_cursor(struct navit *this_)
4117 {
4118
4119
4120 ////DBG dbg(0,"EEnter\n");
4121 navit_set_center_cursor_draw(this_);
4122 }
4123
4124 void navit_set_center_screen(struct navit *this_, struct point *p, int set_timeout)
4125 {
4126
4127
4128 ////DBG dbg(0,"EEnter\n");
4129 struct coord c;
4130 struct pcoord pc;
4131 transform_reverse(this_->trans, p, &c);
4132 pc.x = c.x;
4133 pc.y = c.y;
4134 pc.pro = transform_get_projection(this_->trans);
4135 navit_set_center(this_, &pc, set_timeout);
4136 }
4137
4138 #if 0
4139 switch((*attrs)->type)
4140 {
4141 case attr_zoom:
4142 zoom=(*attrs)->u.num;
4143 break;
4144 case attr_center:
4145 g=*((*attrs)->u.coord_geo);
4146 break;
4147 #endif
4148
4149 static int navit_set_attr_do(struct navit *this_, struct attr *attr, int init)
4150 {
4151
4152 int dir = 0, orient_old = 0, attr_updated = 0;
4153 struct coord co;
4154 long zoom;
4155 GList *l;
4156 struct navit_vehicle *nv;
4157 struct layout *lay;
4158 struct attr active;
4159 active.type = attr_active;
4160 active.u.num = 0;
4161
4162 switch (attr->type)
4163 {
4164 case attr_autozoom:
4165 attr_updated = (this_->autozoom_secs != attr->u.num);
4166 this_->autozoom_secs = attr->u.num;
4167 break;
4168 case attr_autozoom_active:
4169 attr_updated = (this_->autozoom_active != attr->u.num);
4170 this_->autozoom_active = attr->u.num;
4171 break;
4172 case attr_center:
4173 transform_from_geo(transform_get_projection(this_->trans), attr->u.coord_geo, &co);
4174 // dbg(1, "0x%x,0x%x\n", co.x, co.y);
4175 transform_set_center(this_->trans, &co);
4176 break;
4177 case attr_drag_bitmap:
4178 attr_updated = (this_->drag_bitmap != !!attr->u.num);
4179 this_->drag_bitmap = !!attr->u.num;
4180 break;
4181 case attr_flags:
4182 attr_updated = (this_->flags != attr->u.num);
4183 this_->flags = attr->u.num;
4184 break;
4185 case attr_flags_graphics:
4186 attr_updated = (this_->graphics_flags != attr->u.num);
4187 this_->graphics_flags = attr->u.num;
4188 break;
4189 case attr_follow:
4190 if (!this_->vehicle)
4191 return 0;
4192 attr_updated = (this_->vehicle->follow_curr != attr->u.num);
4193 this_->vehicle->follow_curr = attr->u.num;
4194 break;
4195 case attr_layout:
4196 if (this_->layout_current != attr->u.layout)
4197 {
4198 this_->layout_current = attr->u.layout;
4199 graphics_font_destroy_all(this_->gra);
4200 navit_set_cursors(this_);
4201 if (this_->ready == 3)
4202 navit_draw(this_);
4203 attr_updated = 1;
4204 }
4205 break;
4206 case attr_layout_name:
4207 l = this_->layouts;
4208 while (l)
4209 {
4210 lay = l->data;
4211 if (!strcmp(lay->name, attr->u.str))
4212 {
4213 struct attr attr;
4214 attr.type = attr_layout;
4215 attr.u.layout = lay;
4216 return navit_set_attr_do(this_, &attr, init);
4217 }
4218 l = g_list_next(l);
4219 }
4220 return 0;
4221 case attr_map_border:
4222 if (this_->border != attr->u.num)
4223 {
4224 this_->border = attr->u.num;
4225 attr_updated = 1;
4226 }
4227 break;
4228 case attr_orientation:
4229 orient_old = this_->orientation;
4230 this_->orientation = attr->u.num;
4231 if (!init)
4232 {
4233 if (this_->orientation != -1)
4234 {
4235 dir = this_->orientation;
4236 }
4237 else
4238 {
4239 if (this_->vehicle)
4240 {
4241 dir = this_->vehicle->dir;
4242 }
4243 }
4244 transform_set_yaw(this_->trans, dir);
4245 if (orient_old != this_->orientation)
4246 {
4247 #if 0
4248 if (this_->ready == 3)
4249 navit_draw(this_);
4250 #endif
4251 attr_updated = 1;
4252 }
4253 }
4254 break;
4255 case attr_osd_configuration:
4256 //DBG dbg(0, "setting osd_configuration to %d (was %d)\n", attr->u.num, this_->osd_configuration);
4257 attr_updated = (this_->osd_configuration != attr->u.num);
4258 this_->osd_configuration = attr->u.num;
4259 break;
4260 case attr_pitch:
4261 attr_updated = (this_->pitch != attr->u.num);
4262 this_->pitch = attr->u.num;
4263 transform_set_pitch(this_->trans, this_->pitch);
4264 if (!init && attr_updated && this_->ready == 3)
4265 navit_draw(this_);
4266 break;
4267 case attr_projection:
4268 if (this_->trans && transform_get_projection(this_->trans) != attr->u.projection)
4269 {
4270 navit_projection_set(this_, attr->u.projection, !init);
4271 attr_updated = 1;
4272 }
4273 break;
4274 case attr_radius:
4275 attr_updated = (this_->radius != attr->u.num);
4276 this_->radius = attr->u.num;
4277 break;
4278 case attr_recent_dest:
4279 attr_updated = (this_->recentdest_count != attr->u.num);
4280 this_->recentdest_count = attr->u.num;
4281 break;
4282 case attr_speech:
4283 if (this_->speech && this_->speech != attr->u.speech)
4284 {
4285 attr_updated = 1;
4286 this_->speech = attr->u.speech;
4287 }
4288 break;
4289 case attr_timeout:
4290 attr_updated = (this_->center_timeout != attr->u.num);
4291 this_->center_timeout = attr->u.num;
4292 break;
4293 case attr_tracking:
4294 attr_updated = (this_->tracking_flag != !!attr->u.num);
4295 // dbg(0, "set attr:attr_tracking old=%d\n", this_->tracking_flag);
4296 this_->tracking_flag = !!attr->u.num;
4297 // dbg(0, "set attr:attr_tracking new=%d\n", this_->tracking_flag);
4298 break;
4299 case attr_transformation:
4300 this_->trans = attr->u.transformation;
4301 break;
4302 case attr_use_mousewheel:
4303 attr_updated = (this_->use_mousewheel != !!attr->u.num);
4304 this_->use_mousewheel = !!attr->u.num;
4305 break;
4306 case attr_vehicle:
4307 l = this_->vehicles;
4308 while (l)
4309 {
4310 nv = l->data;
4311 if (nv->vehicle == attr->u.vehicle)
4312 {
4313 if (!this_->vehicle || this_->vehicle->vehicle != attr->u.vehicle)
4314 {
4315 if (this_->vehicle)
4316 {
4317 vehicle_set_attr(this_->vehicle->vehicle, &active);
4318 }
4319 active.u.num = 1;
4320 vehicle_set_attr(nv->vehicle, &active);
4321 attr_updated = 1;
4322 }
4323 navit_set_vehicle(this_, nv);
4324 }
4325 l = g_list_next(l);
4326 }
4327 break;
4328 case attr_zoom:
4329 zoom = transform_get_scale(this_->trans);
4330 attr_updated = (zoom != attr->u.num);
4331 transform_set_scale(this_->trans, attr->u.num);
4332 if (attr_updated && !init)
4333 navit_draw(this_);
4334 break;
4335 case attr_zoom_min:
4336 attr_updated = (attr->u.num != this_->zoom_min);
4337 this_->zoom_min = attr->u.num;
4338 break;
4339 case attr_zoom_max:
4340 attr_updated = (attr->u.num != this_->zoom_max);
4341 this_->zoom_max = attr->u.num;
4342 break;
4343 case attr_message:
4344 //navit_add_message(this_, attr->u.str);
4345 break;
4346 case attr_follow_cursor:
4347 attr_updated = (this_->follow_cursor != !!attr->u.num);
4348 this_->follow_cursor = !!attr->u.num;
4349 break;
4350 case attr_imperial:
4351 attr_updated = (this_->imperial != attr->u.num);
4352 this_->imperial = attr->u.num;
4353 break;
4354 default:
4355 return 0;
4356 }
4357
4358 if (attr_updated && !init)
4359 {
4360 // dbg(0, "set attr:call callback_list_call_attr_2\n");
4361 callback_list_call_attr_2(this_->attr_cbl, attr->type, this_, attr);
4362
4363 if (attr->type == attr_osd_configuration)
4364 {
4365 graphics_draw_mode(this_->gra, draw_mode_end);
4366 }
4367 }
4368
4369 return 1;
4370 }
4371
4372 int navit_set_attr(struct navit *this_, struct attr *attr)
4373 {
4374 return navit_set_attr_do(this_, attr, 0);
4375 }
4376
4377 int navit_get_attr(struct navit *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
4378 {
4379
4380 struct message *msg;
4381 int len, offset;
4382 int ret = 1;
4383
4384 switch (type)
4385 {
4386 case attr_message:
4387 return 0;
4388 /*
4389 msg = navit_get_messages(this_);
4390
4391 if (!msg)
4392 {
4393 return 0;
4394 }
4395
4396 len = 0;
4397 while (msg)
4398 {
4399 len += strlen(msg->text) + 1;
4400 msg = msg->next;
4401 }
4402 attr->u.str = g_malloc(len + 1);
4403
4404 msg = navit_get_messages(this_);
4405 offset = 0;
4406 while (msg)
4407 {
4408 g_stpcpy((attr->u.str + offset), msg->text);
4409 offset += strlen(msg->text);
4410 attr->u.str[offset] = '\n';
4411 offset++;
4412
4413 msg = msg->next;
4414 }
4415
4416 attr->u.str[len] = '\0';
4417 */
4418 break;
4419 case attr_imperial:
4420 attr->u.num = this_->imperial;
4421 break;
4422 case attr_bookmark_map:
4423 attr->u.map = bookmarks_get_map(this_->bookmarks);
4424 break;
4425 case attr_bookmarks:
4426 attr->u.bookmarks = this_->bookmarks;
4427 break;
4428 case attr_callback_list:
4429 attr->u.callback_list = this_->attr_cbl;
4430 break;
4431 case attr_destination:
4432 if (!this_->destination_valid)
4433 return 0;
4434 attr->u.pcoord = &this_->destination;
4435 break;
4436 case attr_displaylist:
4437 attr->u.displaylist = this_->displaylist;
4438 return (attr->u.displaylist != NULL);
4439 case attr_follow:
4440 if (!this_->vehicle)
4441 return 0;
4442 attr->u.num = this_->vehicle->follow_curr;
4443 break;
4444 case attr_former_destination_map:
4445 attr->u.map = this_->former_destination;
4446 break;
4447 case attr_graphics:
4448 attr->u.graphics = this_->gra;
4449 ret = (attr->u.graphics != NULL);
4450 break;
4451 case attr_gui:
4452 attr->u.gui = this_->gui;
4453 ret = (attr->u.gui != NULL);
4454 break;
4455 case attr_layout:
4456 if (iter)
4457 {
4458 if (iter->u.list)
4459 {
4460 iter->u.list = g_list_next(iter->u.list);
4461 }
4462 else
4463 {
4464 iter->u.list = this_->layouts;
4465 }
4466 if (!iter->u.list)
4467 {
4468 return 0;
4469 }
4470 attr->u.layout = (struct layout *) iter->u.list->data;
4471 }
4472 else
4473 {
4474 attr->u.layout = this_->layout_current;
4475 }
4476 break;
4477 case attr_map:
4478 if (iter && this_->mapsets)
4479 {
4480 if (!iter->u.mapset_handle)
4481 {
4482 iter->u.mapset_handle = mapset_open((struct mapset *) this_->mapsets->data);
4483 }
4484 attr->u.map = mapset_next(iter->u.mapset_handle, 0);
4485 if (!attr->u.map)
4486 {
4487 mapset_close(iter->u.mapset_handle);
4488 return 0;
4489 }
4490 }
4491 else
4492 {
4493 return 0;
4494 }
4495 break;
4496 case attr_mapset:
4497 attr->u.mapset = this_->mapsets->data;
4498 ret = (attr->u.mapset != NULL);
4499 break;
4500 case attr_navigation:
4501 attr->u.navigation = this_->navigation;
4502 break;
4503 case attr_orientation:
4504 attr->u.num = this_->orientation;
4505 break;
4506 case attr_osd_configuration:
4507 attr->u.num = this_->osd_configuration;
4508 break;
4509 case attr_pitch:
4510 attr->u.num = transform_get_pitch(this_->trans);
4511 break;
4512 case attr_projection:
4513 if (this_->trans)
4514 {
4515 attr->u.num = transform_get_projection(this_->trans);
4516 }
4517 else
4518 {
4519 return 0;
4520 }
4521 break;
4522 case attr_route:
4523 attr->u.route = this_->route;
4524 break;
4525 case attr_speech:
4526 attr->u.speech = this_->speech;
4527 break;
4528 case attr_tracking:
4529 attr->u.num = this_->tracking_flag;
4530 break;
4531 case attr_trackingo:
4532 attr->u.tracking = this_->tracking;
4533 break;
4534 case attr_transformation:
4535 attr->u.transformation = this_->trans;
4536 break;
4537 case attr_vehicle:
4538 if (iter)
4539 {
4540 if (iter->u.list)
4541 {
4542 iter->u.list = g_list_next(iter->u.list);
4543 }
4544 else
4545 {
4546 iter->u.list = this_->vehicles;
4547 }
4548 if (!iter->u.list)
4549 return 0;
4550 attr->u.vehicle = ((struct navit_vehicle*) iter->u.list->data)->vehicle;
4551 }
4552 else
4553 {
4554 if (this_->vehicle)
4555 {
4556 attr->u.vehicle = this_->vehicle->vehicle;
4557 }
4558 else
4559 {
4560 return 0;
4561 }
4562 }
4563 break;
4564 case attr_vehicleprofile:
4565 attr->u.vehicleprofile = this_->vehicleprofile;
4566 break;
4567 case attr_zoom:
4568 attr->u.num = transform_get_scale(this_->trans);
4569 break;
4570 case attr_autozoom_active:
4571 attr->u.num = this_->autozoom_active;
4572 break;
4573 case attr_follow_cursor:
4574 attr->u.num = this_->follow_cursor;
4575 break;
4576 default:
4577 return 0;
4578 }
4579 attr->type = type;
4580
4581 return ret;
4582 }
4583
4584 void displaylist_shift_order_in_map_layers(struct navit *this_, int shift_value)
4585 {
4586
4587
4588
4589 GList *l;
4590 struct layout *lay;
4591 GList *l2;
4592 struct layer *layer;
4593 GList *ig;
4594 struct itemgra *itemgr;
4595 GList *elements;
4596 struct element *e;
4597
4598 // loop through all the layouts
4599 l = this_->layouts;
4600 while (l)
4601 {
4602 lay = l->data;
4603 //dbg(0,"layout name=%s\n", lay->name);
4604 if (!strcmp(lay->name, "Android-Car"))
4605 {
4606 //dbg(0,"layout found\n");
4607 l2 = lay->layers;
4608 while (l2)
4609 {
4610 layer = l2->data;
4611 //dbg(0,"layer name=%s\n", layer->name);
4612 // only change the zoom of these layers
4613 if ((!strcmp(layer->name, "polygons001"))
4614 || (!strcmp(layer->name, "polygons"))
4615 || (!strcmp(layer->name, "streets"))
4616 || (!strcmp(layer->name, "streets_STR_ONLY"))
4617 || (!strcmp(layer->name, "streets_1"))
4618 || (!strcmp(layer->name, "streets_1_STR_ONLY"))
4619 || (!strcmp(layer->name, "streets_2"))
4620 || (!strcmp(layer->name, "streets_2_STR_ONLY"))
4621 || (!strcmp(layer->name, "route_001"))
4622 || (!strcmp(layer->name, "route_002"))
4623 || (!strcmp(layer->name, "route_003"))
4624 )
4625 {
4626 //dbg(0,"layer found\n");
4627 ig = layer->itemgras;
4628 while (ig)
4629 {
4630 //dbg(0,"*itgr*\n");
4631 itemgr = ig->data;
4632
4633 // now shift "order"-value of itemgra by "shift_value"
4634 // ! max order == 18 !
4635 // ! min order == -2 !
4636
4637
4638 int was_shifted = 0;
4639
4640 //if (itemgr->order.min < 20)
4641 //{
4642 itemgr->order.min = itemgr->order.min - shift_value;
4643 was_shifted = 1;
4644 //}
4645 //if (itemgr->order.min < -2)
4646 //{
4647 // itemgr->order.min = -2;
4648 //}
4649 if (itemgr->order.min > 18)
4650 {
4651 itemgr->order.min = 18;
4652 }
4653
4654 // ------------------------------
4655
4656 if (itemgr->order.max < 18)
4657 {
4658 itemgr->order.max = itemgr->order.max - shift_value;
4659 was_shifted = 1;
4660 }
4661 //
4662 //if (itemgr->order.max < -2)
4663 //{
4664 // itemgr->order.max = -2;
4665 //}
4666 if (itemgr->order.max > 18)
4667 {
4668 itemgr->order.max = 18;
4669 }
4670
4671 float sv_001 = ((float) shift_value * 1.34f);
4672 float sv_002 = ((float) shift_value * 0.75f);
4673
4674 if (was_shifted == 1)
4675 {
4676 // loop thru all the elements in this "itemgra"
4677 elements = itemgr->elements;
4678 while (elements)
4679 {
4680 e = elements->data;
4681
4682 if (e->type == element_polyline)
4683 {
4684 // shift polyline width
4685 e->u.polyline.width = ((float) e->u.polyline.width / sv_001) + 0;
4686 if (e->u.polyline.width < 1)
4687 {
4688 e->u.polyline.width = 1;
4689 }
4690 }
4691
4692 if (e->type == element_circle)
4693 {
4694 // shift circle witdh
4695 e->u.circle.width = ((float) e->u.circle.width / sv_001) + 0;
4696 if (e->u.circle.width < 1)
4697 {
4698 e->u.circle.width = 1;
4699 }
4700
4701 e->u.circle.radius = ((float) e->u.circle.radius / sv_001) + 0;
4702 if (e->u.circle.radius < 1)
4703 {
4704 e->u.circle.radius = 1;
4705 }
4706 }
4707
4708 if (e->type == element_text)
4709 {
4710 // shift text size
4711 e->text_size = (float) e->text_size / sv_002;
4712 if (e->text_size < 1)
4713 {
4714 e->text_size = 1;
4715 }
4716 }
4717 elements = g_list_next(elements);
4718 }
4719 // loop thru all the elements in this "itemgra"
4720 }
4721
4722 ig = g_list_next(ig);
4723 }
4724 }
4725 l2 = g_list_next(l2);
4726 }
4727 }
4728 l = g_list_next(l);
4729 }
4730
4731 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4732 dbg(0,"+#+:leave\n");
4733 #endif
4734 }
4735
4736 void displaylist_shift_for_dpi_value_in_layers(struct navit *this_, double factor)
4737 {
4738
4739
4740
4741 GList *l;
4742 struct layout *lay;
4743 GList *l2;
4744 struct layer *layer;
4745 GList *ig;
4746 struct itemgra *itemgr;
4747 GList *elements;
4748 struct element *e;
4749
4750 // loop through all the layouts
4751 l = this_->layouts;
4752 while (l)
4753 {
4754 lay = l->data;
4755 //dbg(0,"layout name=%s\n", lay->name);
4756 if (!strcmp(lay->name, "Android-Car"))
4757 {
4758 //dbg(0,"layout found\n");
4759 l2 = lay->layers;
4760 while (l2)
4761 {
4762 layer = l2->data;
4763 //dbg(0,"layer name=%s\n", layer->name);
4764 // only change the zoom of these layers
4765 /*
4766 if ((!strcmp(layer->name, "polygons001"))
4767 || (!strcmp(layer->name, "polygons"))
4768 || (!strcmp(layer->name, "streets"))
4769 || (!strcmp(layer->name, "streets_1"))
4770 || (!strcmp(layer->name, "streets_2"))
4771 || (!strcmp(layer->name, "route_001"))
4772 || (!strcmp(layer->name, "route_002"))
4773 || (!strcmp(layer->name, "route_003"))
4774 )
4775 */
4776 //{
4777 //dbg(0,"layer found\n");
4778 ig = layer->itemgras;
4779 while (ig)
4780 {
4781 //dbg(0,"*itgr*\n");
4782 itemgr = ig->data;
4783
4784 // loop thru all the elements in this "itemgra"
4785 elements = itemgr->elements;
4786 while (elements)
4787 {
4788 e = elements->data;
4789
4790 if (e->type == element_polyline)
4791 {
4792 // polyline width
4793 e->u.polyline.width = (int)((float)e->u.polyline.width * factor) + 0;
4794 if (e->u.polyline.width < 1)
4795 {
4796 e->u.polyline.width = 1;
4797 }
4798 }
4799
4800 if (e->type == element_circle)
4801 {
4802 // circle witdh
4803 e->u.circle.width = (int)((float)e->u.circle.width * factor) + 0;
4804 if (e->u.circle.width < 1)
4805 {
4806 e->u.circle.width = 1;
4807 }
4808
4809 e->u.circle.radius = (int)((float)e->u.circle.radius * factor) + 0;
4810 if (e->u.circle.radius < 1)
4811 {
4812 e->u.circle.radius = 1;
4813 }
4814
4815 // text size
4816 e->text_size = (int)((float)(e->text_size * factor));
4817 if (e->text_size < 1)
4818 {
4819 e->text_size = 1;
4820 }
4821
4822 }
4823
4824 if (e->type == element_text)
4825 {
4826 // text size
4827 e->text_size = (int)((float)(e->text_size * factor));
4828 if (e->text_size < 1)
4829 {
4830 e->text_size = 1;
4831 }
4832 }
4833 elements = g_list_next(elements);
4834 }
4835 // loop thru all the elements in this "itemgra"
4836 ig = g_list_next(ig);
4837 }
4838 //}
4839 l2 = g_list_next(l2);
4840 }
4841 }
4842 l = g_list_next(l);
4843 }
4844
4845 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4846 dbg(0,"+#+:leave\n");
4847 #endif
4848 }
4849
4850
4851 static int navit_add_log(struct navit *this_, struct log *log)
4852 {
4853
4854
4855 struct attr type_attr;
4856 if (!log_get_attr(log, attr_type, &type_attr, NULL))
4857 return 0;
4858 if (!strcmp(type_attr.u.str, "textfile_debug"))
4859 {
4860 char *header = "type=track_tracked\n";
4861 if (this_->textfile_debug_log)
4862 return 0;
4863 log_set_header(log, header, strlen(header));
4864 this_->textfile_debug_log = log;
4865 return 1;
4866 }
4867 return 0;
4868 }
4869
4870 static int navit_add_layout(struct navit *this_, struct layout *layout)
4871 {
4872
4873
4874 ////DBG dbg(0,"EEnter\n");
4875 struct attr active;
4876 this_->layouts = g_list_append(this_->layouts, layout);
4877 layout_get_attr(layout, attr_active, &active, NULL);
4878 if (active.u.num || !this_->layout_current)
4879 {
4880 this_->layout_current = layout;
4881 return 1;
4882 }
4883 return 0;
4884 }
4885
4886 int navit_add_attr(struct navit *this_, struct attr *attr)
4887 {
4888
4889
4890 ////DBG dbg(0,"EEnter\n");
4891
4892 int ret = 1;
4893 switch (attr->type)
4894 {
4895 case attr_callback:
4896 navit_add_callback(this_, attr->u.callback);
4897 break;
4898 case attr_log:
4899 ret = navit_add_log(this_, attr->u.log);
4900 break;
4901 case attr_gui:
4902 ret = navit_set_gui(this_, attr->u.gui);
4903 break;
4904 case attr_graphics:
4905 ret = navit_set_graphics(this_, attr->u.graphics);
4906 break;
4907 case attr_layout:
4908 ret = navit_add_layout(this_, attr->u.layout);
4909 break;
4910 case attr_route:
4911 this_->route = attr->u.route;
4912 break;
4913 case attr_mapset:
4914 this_->mapsets = g_list_append(this_->mapsets, attr->u.mapset);
4915 break;
4916 case attr_navigation:
4917 this_->navigation = attr->u.navigation;
4918 break;
4919 case attr_recent_dest:
4920 this_->recentdest_count = attr->u.num;
4921 break;
4922 case attr_speech:
4923 this_->speech = attr->u.speech;
4924 break;
4925 case attr_tracking:
4926 this_->tracking = attr->u.tracking;
4927 break;
4928 case attr_vehicle:
4929 ret = navit_add_vehicle(this_, attr->u.vehicle);
4930 break;
4931 case attr_vehicleprofile:
4932 this_->vehicleprofiles = g_list_prepend(this_->vehicleprofiles, attr->u.vehicleprofile);
4933 break;
4934 case attr_autozoom_min:
4935 this_->autozoom_min = attr->u.num;
4936 break;
4937 default:
4938 return 0;
4939 }
4940 callback_list_call_attr_2(this_->attr_cbl, attr->type, this_, attr);
4941
4942 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4943 dbg(0,"+#+:leave\n");
4944 #endif
4945
4946 return ret;
4947 }
4948
4949 int navit_remove_attr(struct navit *this_, struct attr *attr)
4950 {
4951
4952
4953 int ret = 1;
4954 switch (attr->type)
4955 {
4956 case attr_callback:
4957 navit_remove_callback(this_, attr->u.callback);
4958 break;
4959 default:
4960 return 0;
4961 }
4962
4963 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
4964 dbg(0,"+#+:leave\n");
4965 #endif
4966
4967 return ret;
4968 }
4969
4970 struct attr_iter *
4971 navit_attr_iter_new(void)
4972 {
4973
4974
4975 return g_new0(struct attr_iter, 1);
4976 }
4977
4978 void navit_attr_iter_destroy(struct attr_iter *iter)
4979 {
4980
4981
4982 g_free(iter);
4983 }
4984
4985 void navit_add_callback(struct navit *this_, struct callback *cb)
4986 {
4987
4988
4989 ////DBG dbg(0,"EEnter\n");
4990
4991 callback_list_add(this_->attr_cbl, cb);
4992 }
4993
4994 void navit_remove_callback(struct navit *this_, struct callback *cb)
4995 {
4996
4997
4998 ////DBG dbg(0,"EEnter\n");
4999
5000 callback_list_remove(this_->attr_cbl, cb);
5001 }
5002
5003 /**
5004 * Toggle the cursor update : refresh the map each time the cursor has moved (instead of only when it reaches a border)
5005 *
5006 * @param navit The navit instance
5007 * @returns nothing
5008 */
5009 static void navit_vehicle_draw(struct navit *this_, struct navit_vehicle *nv, struct point *pnt)
5010 {
5011 __F_START__
5012
5013 struct point cursor_pnt;
5014 enum projection pro;
5015
5016 if (this_->blocked)
5017 {
5018 return2;
5019 }
5020
5021 if (pnt)
5022 {
5023 cursor_pnt = *pnt;
5024 }
5025 else
5026 {
5027 pro = transform_get_projection(this_->trans_cursor);
5028 if (!pro)
5029 {
5030 return2;
5031 }
5032 transform(this_->trans_cursor, pro, &nv->coord, &cursor_pnt, 1, 0, 0, NULL);
5033 }
5034
5035 //dbg(0,"xx=%d\n",cursor_pnt.x);
5036 //dbg(0,"yy=%d\n",cursor_pnt.y);
5037
5038 global_vehicle_pos_onscreen.x = cursor_pnt.x;
5039 global_vehicle_pos_onscreen.y = cursor_pnt.y;
5040
5041 //dbg(0,"xx=%d\n",cursor_pnt.x);
5042 //dbg(0,"yy=%d\n",cursor_pnt.y);
5043 //dbg(0,"vehicle_draw_001\n");
5044 vehicle_draw(nv->vehicle, this_->gra, &cursor_pnt, 0, nv->dir - transform_get_yaw(this_->trans_cursor), nv->speed);
5045 #if 0
5046 if (pnt)
5047 pnt2=*pnt;
5048 else
5049 {
5050 pro=transform_get_projection(this_->trans);
5051 transform(this_->trans, pro, &nv->coord, &pnt2, 1);
5052 }
5053 #if 1
5054 cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, pnt == NULL);
5055 #else
5056 cursor_draw(nv->cursor, &pnt2, nv->dir-transform_get_angle(this_->trans, 0), nv->speed > 2, 1);
5057 #endif
5058 #endif
5059
5060 __F_END__
5061 }
5062
5063
5064
5065 // --- this gets called at every positon update (from GPS, or demo vehicle!!) !! ------
5066 // --- this gets called at every positon update (from GPS, or demo vehicle!!) !! ------
5067 // --- this gets called at every positon update (from GPS, or demo vehicle!!) !! ------
5068 static void navit_vehicle_update(struct navit *this_, struct navit_vehicle *nv)
5069 {
5070
5071 __F_START__
5072
5073 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5074 dbg(0, "\n");
5075 dbg(0, "==================================================================================\n");
5076 dbg(0, "==================================================================================\n");
5077 dbg(0, "\n");
5078 #endif
5079
5080
5081 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5082 dbg(0, "ROUTExxPOSxx:navit_vehicle_update:enter\n");
5083 #endif
5084
5085 #ifdef NAVIT_MEASURE_TIME_DEBUG
5086 clock_t s_ = debug_measure_start();
5087 #endif
5088
5089 struct attr attr_valid, attr_dir, attr_speed, attr_pos;
5090 struct pcoord cursor_pc;
5091 struct point cursor_pnt, *pnt = &cursor_pnt;
5092 struct point old_cursor_pnt;
5093 struct tracking *tracking = NULL;
5094 struct pcoord pc[16];
5095
5096 enum projection pro = transform_get_projection(this_->trans_cursor);
5097
5098 int count;
5099 int old_dir;
5100 int old_pos_invalid;
5101 int (*get_attr)(void *, enum attr_type, struct attr *, struct attr_iter *);
5102 void *attr_object;
5103 char *destination_file;
5104 long new_scale_value;
5105 long old_scale_value;
5106 int l_old;
5107 int l_new;
5108
5109 if (this_->ready != 3)
5110 {
5111 //profile(0,"return 1\n");
5112 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5113 dbg(0, "ROUTExxPOSxx:return 003\n");
5114 #endif
5115
5116
5117 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5118 dbg(0, "\n");
5119 dbg(0, "==================================================================================\n");
5120 dbg(0, "==================================================================================\n");
5121 dbg(0, "\n");
5122 #endif
5123
5124 return2;
5125 }
5126
5127 // **OLD** navit_layout_switch(this_);
5128 if (this_->vehicle == nv && this_->tracking_flag)
5129 {
5130 tracking = this_->tracking;
5131 }
5132 //// else tracking = NULL !! -> important for next "if" clause!!
5133
5134 // ------ DEBUG ------ remember real GPS postion (unchanged) -------
5135 // ------ DEBUG ------ remember real GPS postion (unchanged) -------
5136 // ------ DEBUG ------ remember real GPS postion (unchanged) -------
5137 struct attr attr_pos_unchanged;
5138 if (vehicle_get_attr(nv->vehicle, attr_position_coord_geo, &attr_pos_unchanged, NULL))
5139 {
5140 if (attr_pos_unchanged.u.coord_geo)
5141 {
5142 global_v_pos_lat = attr_pos_unchanged.u.coord_geo->lat;
5143 global_v_pos_lng = attr_pos_unchanged.u.coord_geo->lng;
5144
5145 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5146 struct coord cc999;
5147 transform_from_geo(pro, attr_pos_unchanged.u.coord_geo, &cc999);
5148 dbg(0, "ROUTExxPOSxx:navit_vehicle_update: %d %d\n", cc999.x, cc999.y);
5149 #endif
5150
5151 }
5152 }
5153
5154 if (vehicle_get_attr(nv->vehicle, attr_position_direction, &attr_pos_unchanged, NULL))
5155 {
5156 global_v_pos_dir = *attr_pos_unchanged.u.numd;
5157
5158 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5159 dbg(0, "ROUTExxPOSxx:navit_vehicle_update: dir=%f\n", (float)global_v_pos_dir);
5160 #endif
5161 }
5162 // ------ DEBUG ------ remember real GPS postion (unchanged) -------
5163 // ------ DEBUG ------ remember real GPS postion (unchanged) -------
5164 // ------ DEBUG ------ remember real GPS postion (unchanged) -------
5165
5166
5167 if (tracking)
5168 {
5169 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5170 dbg(0, "ROUTExxPOSxx:tracking_update: 001\n");
5171 #endif
5172
5173 // set postition from tracking (changing it to nearest street)
5174 tracking_update(tracking, nv->vehicle, this_->vehicleprofile, pro);
5175 attr_object = tracking;
5176 get_attr = (int(*)(void *, enum attr_type, struct attr *, struct attr_iter *)) tracking_get_attr;
5177
5178 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5179 dbg(0, "ROUTExxPOSxx:tracking_update: 001-a\n");
5180 #endif
5181 }
5182 else
5183 {
5184 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5185 dbg(0, "ROUTExxPOSxx:tracking_update (unchanged): 001.bb\n");
5186 #endif
5187
5188 // set position from vehicle (unchanged)
5189 attr_object = nv->vehicle;
5190 get_attr = (int(*)(void *, enum attr_type, struct attr *, struct attr_iter *)) vehicle_get_attr;
5191
5192 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5193 dbg(0, "ROUTExxPOSxx:tracking_update (unchanged): 001.bb-a\n");
5194 #endif
5195 }
5196
5197 if (get_attr(attr_object, attr_position_valid, &attr_valid, NULL))
5198 {
5199 if (!attr_valid.u.num != attr_position_valid_invalid)
5200 {
5201 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5202 dbg(0, "ROUTExxPOSxx:return 001\n");
5203 #endif
5204
5205 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5206 dbg(0, "\n");
5207 dbg(0, "==================================================================================\n");
5208 dbg(0, "==================================================================================\n");
5209 dbg(0, "\n");
5210 #endif
5211
5212 return2;
5213 }
5214 }
5215
5216
5217 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5218 struct attr attr_pos_99;
5219 if (get_attr(attr_object, attr_position_coord_geo, &attr_pos_99, NULL))
5220 {
5221 if (attr_pos_99.u.coord_geo)
5222 {
5223 struct coord cc999;
5224 transform_from_geo(pro, attr_pos_99.u.coord_geo, &cc999);
5225 dbg(0, "ROUTExxPOSxx:get pos: %d %d\n", cc999.x, cc999.y);
5226 }
5227 }
5228 #endif
5229
5230
5231 // load attrs with data from vehicle
5232 if (!get_attr(attr_object, attr_position_direction, &attr_dir, NULL) || !get_attr(attr_object, attr_position_speed, &attr_speed, NULL) || !get_attr(attr_object, attr_position_coord_geo, &attr_pos, NULL))
5233 {
5234 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5235 dbg(0, "ROUTExxPOSxx:return 002\n");
5236 #endif
5237
5238 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5239 dbg(0, "\n");
5240 dbg(0, "==================================================================================\n");
5241 dbg(0, "==================================================================================\n");
5242 dbg(0, "\n");
5243 #endif
5244
5245 return2;
5246 }
5247 // load attrs with data from vehicle
5248
5249
5250 // save old value
5251 old_dir = nv->dir;
5252 global_old_vehicle_speed = nv->speed;
5253 old_scale_value = transform_get_scale(this_->trans);
5254
5255 nv->dir = *attr_dir.u.numd;
5256 nv->speed = *attr_speed.u.numd;
5257
5258 // old values ---------
5259 if ((global_last_vehicle_pos_geo.lat != 0.0) && (global_last_vehicle_pos_geo.lng != 0.0))
5260 {
5261 transform_from_geo(pro, &global_last_vehicle_pos_geo, &nv->coord);
5262 transform(this_->trans_cursor, pro, &nv->coord, &old_cursor_pnt, 1, 0, 0, NULL);
5263 old_pos_invalid = 0;
5264
5265 // XXX // dbg(0,"old values lat:%f lon:%f px:%d py:%d\n", global_last_vehicle_pos_geo.lat, global_last_vehicle_pos_geo.lng, old_cursor_pnt.x, old_cursor_pnt.y);
5266 }
5267 else
5268 {
5269 old_pos_invalid = 1;
5270 }
5271 // old values ---------
5272
5273 transform_from_geo(pro, attr_pos.u.coord_geo, &nv->coord);
5274
5275 // save this position
5276 global_last_vehicle_pos_geo.lat = attr_pos.u.coord_geo->lat;
5277 global_last_vehicle_pos_geo.lng = attr_pos.u.coord_geo->lng;
5278
5279 ggggg_lat = attr_pos.u.coord_geo->lat;
5280 ggggg_lon = attr_pos.u.coord_geo->lng;
5281 // dbg(0, "PPPOS:%f %f lll=%f", global_last_vehicle_pos_geo.lat, global_last_vehicle_pos_geo.lng, ggggg_lat);
5282
5283 // save this position
5284
5285
5286 // XXX // dbg(0,"v1 lat:%f lon:%f x:%d y:%d\n",attr_pos.u.coord_geo->lat, attr_pos.u.coord_geo->lng, nv->coord.x, nv->coord.y);
5287
5288 //if (nv != this_->vehicle)
5289 //{
5290 // if (hold_drawing == 0)
5291 // {
5292 // navit_vehicle_draw(this_, nv, NULL);
5293 // }
5294 // return;
5295 //}
5296 cursor_pc.x = nv->coord.x;
5297 cursor_pc.y = nv->coord.y;
5298 cursor_pc.pro = pro;
5299
5300 if (this_->route)
5301 {
5302 if (tracking)
5303 {
5304 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5305 dbg(0, "ROUTExxPOSxx:navit_vehicle_update: 001\n");
5306 #endif
5307 route_set_position_from_tracking(this_->route, tracking, pro);
5308 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5309 dbg(0, "ROUTExxPOSxx:navit_vehicle_update: 001-a\n");
5310 #endif
5311 }
5312 else
5313 {
5314 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5315 dbg(0, "ROUTExxPOSxx:YYYYY:navit_vehicle_update: 002\n");
5316 #endif
5317 route_set_position(this_->route, &cursor_pc);
5318 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5319 dbg(0, "ROUTExxPOSxx:navit_vehicle_update: 002-a\n");
5320 #endif
5321 }
5322 }
5323
5324 // --------------------------------------------------------------
5325 // --------------------------------------------------------------
5326 // this calls: graphics_load_mapset (and draws the map)
5327 // --------------------------------------------------------------
5328 /// -------**++**-- DISABLE --**++**---- callback_list_call_attr_0(this_->attr_cbl, attr_position);
5329 // --------------------------------------------------------------
5330 // --------------------------------------------------------------
5331
5332 // navit_textfile_debug_log(this_, "type=trackpoint_tracked");
5333 /*
5334 if (this_->gui && nv->speed > MYSTERY_SPEED)
5335 {
5336 // stupid!!!! this gets called every second!!! fixme!!!!!!
5337 navit_disable_suspend();
5338 // stupid!!!! this gets called every second!!! fixme!!!!!!
5339 }
5340 */
5341
5342 transform(this_->trans_cursor, pro, &nv->coord, &cursor_pnt, 1, 0, 0, NULL);
5343 // XXX // dbg(0,"v2 px:%d py:%d x:%d y:%d\n", cursor_pnt.x, cursor_pnt.y, nv->coord.x, nv->coord.y);
5344
5345 // ------- AUTOZOOM ---------
5346 l_old = 0;
5347 l_new = 0;
5348 new_scale_value = navit_autozoom(this_, &nv->coord, nv->speed, 0, &l_old, &l_new);
5349 // dbg(0, "l_old=%d l_new=%d\n", l_old, l_new);
5350 // ------- AUTOZOOM ---------
5351
5352 if (old_pos_invalid == 0)
5353 {
5354 int delta_x = cursor_pnt.x - old_cursor_pnt.x;
5355 int delta_y = cursor_pnt.y - old_cursor_pnt.y;
5356 int delta_angle = nv->dir - old_dir;
5357 int delta_zoom = 0;
5358
5359 if (new_scale_value != -1)
5360 {
5361 delta_zoom = (int)(new_scale_value - old_scale_value);
5362 }
5363
5364 #ifdef HAVE_API_ANDROID
5365 //dbg(0,"delta x=%d, y=%d, angle=%d\n", delta_x, delta_y, delta_angle);
5366 set_vehicle_values_to_java_delta(delta_x, delta_y, delta_angle, delta_zoom, l_old, l_new);
5367 #endif
5368 }
5369
5370
5371
5372 // -------- ??????????
5373 // -------- ??????????
5374 // -------- ??????????
5375 // -------- ??????????
5376 // -------- ??????????
5377 if (this_->button_pressed != 1 && this_->follow_cursor && nv->follow_curr <= nv->follow && (nv->follow_curr == 1 || !transform_within_border(this_->trans_cursor, &cursor_pnt, this_->border)))
5378 {
5379 if (hold_drawing == 0)
5380 {
5381 //dbg(0,"call:navit_set_center_cursor_draw:start\n");
5382 navit_set_center_cursor_draw(this_);
5383 //dbg(0,"call:navit_set_center_cursor_draw:end\n");
5384 }
5385 }
5386 else
5387 {
5388 if (hold_drawing == 0)
5389 {
5390 navit_vehicle_draw(this_, nv, pnt);
5391 }
5392 }
5393 // -------- ??????????
5394 // -------- ??????????
5395 // -------- ??????????
5396 // -------- ??????????
5397 // -------- ??????????
5398
5399
5400
5401
5402 if (nv->follow_curr > 1)
5403 {
5404 nv->follow_curr--;
5405 }
5406 else
5407 {
5408 nv->follow_curr = nv->follow;
5409 }
5410
5411
5412
5413 // where does this go????? ----------
5414 // where does this go????? ----------
5415 //
5416 // i think this updates the OSD GUIs
5417 //
5418 callback_list_call_attr_2(this_->attr_cbl, attr_position_coord_geo, this_, nv->vehicle);
5419 // where does this go????? ----------
5420 // where does this go????? ----------
5421
5422
5423
5424 /* Finally, if we reached our destination, stop navigation. */
5425 if (this_->route)
5426 {
5427 switch (route_destination_reached(this_->route))
5428 {
5429 case 1:
5430 route_remove_waypoint(this_->route);
5431 count = route_get_destinations(this_->route, pc, 16);
5432
5433 // destination_file = bookmarks_get_destination_file(TRUE);
5434 // bookmarks_append_coord(this_->bookmarks, destination_file, pc, count, "former_itinerary_part", NULL, NULL, this_->recentdest_count);
5435
5436 #ifdef HAVE_API_ANDROID
5437 // waypoint reached
5438 android_return_generic_int(5, 1);
5439 #ifdef NAVIT_SAY_DEBUG_PRINT
5440 android_send_generic_text(1,"+*#O:Waypoint reached\n");
5441 #endif
5442 if (global_routing_engine != 1) // not OSRM routing
5443 {
5444 // say it
5445 navit_say(this_, _("Waypoint reached"));
5446 }
5447 #endif
5448 break;
5449 case 2:
5450 navit_set_destination(this_, NULL, NULL, 0);
5451 // ** inform java that we reached our destination **
5452 #ifdef HAVE_API_ANDROID
5453 android_return_generic_int(4, 1);
5454 #ifdef NAVIT_SAY_DEBUG_PRINT
5455 android_send_generic_text(1,"+*#O:You have reached your destination\n");
5456 #endif
5457 // say it
5458 navit_say(this_, _("You have reached your destination"));
5459 #endif
5460 break;
5461 }
5462 }
5463
5464 if (hold_drawing == 0)
5465 {
5466 // draw???????
5467 // navit_draw(this_);
5468 if (this_->ready == 3)
5469 {
5470 //dbg(0,"location update:draw:start\n");
5471 // dbg(0,"navit_draw_async_006\n");
5472 // zzz554 //
5473 navit_draw_async(this_, 0);
5474 //dbg(0,"location update:draw:end\n");
5475 }
5476 // draw???????
5477 }
5478
5479 #ifdef NAVIT_MEASURE_TIME_DEBUG
5480 debug_mrp("navit_vehicle_update:", debug_measure_end(s_));
5481 #endif
5482
5483 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5484 dbg(0, "ROUTExxPOSxx:navit_vehicle_update:leave\n");
5485 #endif
5486
5487 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5488 dbg(0, "\n");
5489 dbg(0, "==================================================================================\n");
5490 dbg(0, "==================================================================================\n");
5491 dbg(0, "\n");
5492 #endif
5493
5494 __F_END__
5495
5496 }
5497 // --- this gets called at every positon update (from GPS, or demo vehicle!!) !! ------
5498 // --- this gets called at every positon update (from GPS, or demo vehicle!!) !! ------
5499 // --- this gets called at every positon update (from GPS, or demo vehicle!!) !! ------
5500
5501
5502
5503 int navit_is_demo_vehicle()
5504 {
5505 if (global_demo_vehicle == 1)
5506 {
5507 return 1;
5508 }
5509
5510 return 0;
5511 }
5512
5513
5514 /**
5515 * Set the position of the vehicle
5516 *
5517 * @param navit The navit instance
5518 * @param c The coordinate to set as position
5519 * @returns nothing
5520 */
5521 void navit_set_position(struct navit *this_, struct pcoord *c)
5522 {
5523 __F_START__
5524
5525 //DBG dbg(0,"EEnter\n");
5526
5527 if (this_->route)
5528 {
5529 //#ifdef NAVIT_ROUTING_DEBUG_PRINT
5530 // dbg(0, "ROUTExxPOSxx:YYYYY:navit_set_position: 001\n");
5531 //#endif
5532 // ******* NOT USE ******** // route_set_position(this_->route, c);
5533 // ******* NOT USE ******** // callback_list_call_attr_0(this_->attr_cbl, attr_position);
5534 }
5535
5536 if (this_->ready == 3)
5537 {
5538 navit_draw(this_);
5539 }
5540
5541 __F_END__
5542 }
5543
5544 /**
5545 * Set the position of the vehicle, without drawing the map
5546 *
5547 */
5548 void navit_set_position_without_map_drawing(struct navit *this_, struct pcoord *c)
5549 {
5550
5551
5552
5553 if (this_->route)
5554 {
5555 #ifdef NAVIT_ROUTING_DEBUG_PRINT
5556 dbg(0, "ROUTExxPOSxx:YYYYY:navit_set_position_without_map_drawing: 001\n");
5557 #endif
5558 route_set_position(this_->route, c);
5559 callback_list_call_attr_0(this_->attr_cbl, attr_position);
5560 }
5561 }
5562
5563
5564 int navit_set_vehicleprofile(struct navit *this_, char *name)
5565 {
5566
5567
5568 ////DBG dbg(0,"EEnter\n");
5569
5570 struct attr attr;
5571 GList *l;
5572 l = this_->vehicleprofiles;
5573 while (l)
5574 {
5575 if (vehicleprofile_get_attr(l->data, attr_name, &attr, NULL))
5576 {
5577 if (!strcmp(attr.u.str, name))
5578 {
5579 this_->vehicleprofile = l->data;
5580 if (this_->route)
5581 {
5582 route_set_profile(this_->route, this_->vehicleprofile);
5583 }
5584 return 1;
5585 }
5586 }
5587 l = g_list_next(l);
5588 }
5589 return 0;
5590 }
5591
5592 static void navit_set_vehicle(struct navit *this_, struct navit_vehicle *nv)
5593 {
5594
5595
5596 ////DBG dbg(0,"EEnter\n");
5597
5598 struct attr attr;
5599 this_->vehicle = nv;
5600
5601 if (nv && vehicle_get_attr(nv->vehicle, attr_profilename, &attr, NULL))
5602 {
5603 if (navit_set_vehicleprofile(this_, attr.u.str))
5604 {
5605 return;
5606 }
5607 }
5608
5609 if (!navit_set_vehicleprofile(this_, "car"))
5610 {
5611 /* We do not have a fallback "car" profile
5612 * so lets set any profile */
5613 GList *l;
5614 l = this_->vehicleprofiles;
5615 if (l)
5616 {
5617 this_->vehicleprofile = l->data;
5618 if (this_->route)
5619 {
5620 route_set_profile(this_->route, this_->vehicleprofile);
5621 }
5622 }
5623 }
5624 }
5625
5626 /**
5627 * Register a new vehicle
5628 *
5629 * @param navit The navit instance
5630 * @param v The vehicle instance
5631 * @returns 1 for success
5632 */
5633 int navit_add_vehicle(struct navit *this_, struct vehicle *v)
5634 {
5635
5636
5637
5638 struct navit_vehicle *nv=g_new0(struct navit_vehicle, 1);
5639 struct attr follow, active, animate;
5640 nv->vehicle = v;
5641 nv->follow = 0;
5642 nv->last.x = 0;
5643 nv->last.y = 0;
5644
5645 global_last_vehicle_pos_geo.lat = 0;
5646 global_last_vehicle_pos_geo.lng = 0;
5647
5648 // global_cur_vehicle_pos_geo.lat = 0;
5649 // global_cur_vehicle_pos_geo.lon = 0;
5650
5651 nv->animate_cursor = 0;
5652 if ((vehicle_get_attr(v, attr_follow, &follow, NULL)))
5653 nv->follow = follow.u.num;
5654
5655 nv->follow_curr = nv->follow;
5656 this_->vehicles = g_list_append(this_->vehicles, nv);
5657
5658 if ((vehicle_get_attr(v, attr_active, &active, NULL)) && active.u.num)
5659 navit_set_vehicle(this_, nv);
5660
5661 if ((vehicle_get_attr(v, attr_animate, &animate, NULL)))
5662 nv->animate_cursor = animate.u.num;
5663
5664 nv->callback.type = attr_callback;
5665
5666 // gets called via this callback in vehicle_android.c [in function: vehicle_android_callback]
5667 nv->callback.u.callback = callback_new_attr_2(callback_cast(navit_vehicle_update), attr_position_coord_geo, this_, nv);
5668 callback_add_names(nv->callback.u.callback, "navit_add_vehicle", "navit_vehicle_update");
5669
5670 //dbg(0,"EEnter 11\n");
5671 vehicle_add_attr(nv->vehicle, &nv->callback);
5672 //dbg(0,"EEnter 22\n");
5673 vehicle_set_attr(nv->vehicle, &this_->self);
5674 //dbg(0,"EEnter 33\n");
5675
5676 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
5677 dbg(0,"+#+:leave\n");
5678 #endif
5679
5680 return 1;
5681 }
5682
5683 struct gui *
5684 navit_get_gui(struct navit *this_)
5685 {
5686 return this_->gui;
5687 }
5688
5689 struct transformation *
5690 navit_get_trans(struct navit *this_)
5691 {
5692 return this_->trans;
5693 }
5694
5695 struct route *
5696 navit_get_route(struct navit *this_)
5697 {
5698 return this_->route;
5699 }
5700
5701 struct navigation *
5702 navit_get_navigation(struct navit *this_)
5703 {
5704 return this_->navigation;
5705 }
5706
5707 struct displaylist *
5708 navit_get_displaylist(struct navit *this_)
5709 {
5710 return this_->displaylist;
5711 }
5712
5713 void navit_layout_switch(struct navit *n)
5714 {
5715
5716
5717 ////DBG dbg(0,"EEnter\n");
5718
5719 int currTs = 0;
5720 struct attr iso8601_attr, geo_attr, valid_attr, layout_attr;
5721 double trise, tset, trise_actual;
5722 struct layout *l;
5723 int year, month, day;
5724
5725 if (navit_get_attr(n, attr_layout, &layout_attr, NULL) != 1)
5726 {
5727 return; //No layout - nothing to switch
5728 }
5729 if (!n->vehicle)
5730 return;
5731 l = layout_attr.u.layout;
5732
5733 if (l->dayname || l->nightname)
5734 {
5735 //Ok, we know that we have profile to switch
5736
5737 //Check that we aren't calculating too fast
5738 if (vehicle_get_attr(n->vehicle->vehicle, attr_position_time_iso8601, &iso8601_attr, NULL) == 1)
5739 {
5740 currTs = iso8601_to_secs(iso8601_attr.u.str);
5741 // dbg(1, "currTs: %u:%u\n", currTs % 86400 / 3600, ((currTs % 86400) % 3600) / 60);
5742 }
5743 if (currTs - (n->prevTs) < 60)
5744 {
5745 //We've have to wait a little
5746 return;
5747 }
5748 if (sscanf(iso8601_attr.u.str, "%d-%02d-%02dT", &year, &month, &day) != 3)
5749 return;
5750 if (vehicle_get_attr(n->vehicle->vehicle, attr_position_valid, &valid_attr, NULL) && valid_attr.u.num == attr_position_valid_invalid)
5751 {
5752 return; //No valid fix yet
5753 }
5754 if (vehicle_get_attr(n->vehicle->vehicle, attr_position_coord_geo, &geo_attr, NULL) != 1)
5755 {
5756 //No position - no sun
5757 return;
5758 }
5759
5760 //We calculate sunrise anyway, cause it is needed both for day and for night
5761 if (__sunriset__(year, month, day, geo_attr.u.coord_geo->lng, geo_attr.u.coord_geo->lat, -5, 1, &trise, &tset) != 0)
5762 {
5763 //near the pole sun never rises/sets, so we should never switch profiles
5764 // dbg(1, "trise: %u:%u, sun never visible, never switch profile\n", HOURS(trise), MINUTES(trise));
5765 n->prevTs = currTs;
5766 return;
5767 }
5768
5769 trise_actual = trise;
5770 // dbg(1, "trise: %u:%u\n", HOURS(trise), MINUTES(trise));
5771 if (l->dayname)
5772 {
5773
5774 if ((HOURS(trise) * 60 + MINUTES(trise) == (currTs % 86400) / 60) || (n->prevTs == 0 && ((HOURS(trise) * 60 + MINUTES(trise) < (currTs % 86400) / 60))))
5775 {
5776 //The sun is rising now!
5777 if (strcmp(l->name, l->dayname))
5778 {
5779 navit_set_layout_by_name(n, l->dayname);
5780 }
5781 }
5782 }
5783 if (l->nightname)
5784 {
5785 if (__sunriset__(year, month, day, geo_attr.u.coord_geo->lng, geo_attr.u.coord_geo->lat, -5, 1, &trise, &tset) != 0)
5786 {
5787 //near the pole sun never rises/sets, so we should never switch profiles
5788 // dbg(1,"tset: %u:%u, sun always visible, never switch profile\n",HOURS(tset), MINUTES(tset));
5789 n->prevTs = currTs;
5790 return;
5791 }
5792 // dbg(1, "tset: %u:%u\n", HOURS(tset), MINUTES(tset));
5793 if (HOURS(tset) * 60 + MINUTES(tset) == ((currTs % 86400) / 60) || (n->prevTs == 0 && (((HOURS(tset) * 60 + MINUTES(tset) < (currTs % 86400) / 60)) || ((HOURS(trise_actual) * 60 + MINUTES(trise_actual) > (currTs % 86400) / 60)))))
5794 {
5795 //Time to sleep
5796 if (strcmp(l->name, l->nightname))
5797 {
5798 navit_set_layout_by_name(n, l->nightname);
5799 }
5800 }
5801 }
5802
5803 n->prevTs = currTs;
5804 }
5805 }
5806
5807 int navit_set_vehicle_by_name(struct navit *n, const char *name)
5808 {
5809
5810
5811 ////DBG dbg(0,"EEnter\n");
5812
5813 struct vehicle *v;
5814 struct attr_iter *iter;
5815 struct attr vehicle_attr, name_attr;
5816
5817 iter = navit_attr_iter_new();
5818
5819 while (navit_get_attr(n, attr_vehicle, &vehicle_attr, iter))
5820 {
5821 v = vehicle_attr.u.vehicle;
5822 vehicle_get_attr(v, attr_name, &name_attr, NULL);
5823 if (name_attr.type == attr_name)
5824 {
5825 if (!strcmp(name, name_attr.u.str))
5826 {
5827 navit_set_attr(n, &vehicle_attr);
5828 navit_attr_iter_destroy(iter);
5829 return 1;
5830 }
5831 }
5832 }
5833 navit_attr_iter_destroy(iter);
5834 return 0;
5835 }
5836
5837 int navit_set_layout_by_name(struct navit *n, const char *name)
5838 {
5839
5840
5841 ////DBG dbg(0,"EEnter\n");
5842
5843 struct layout *l;
5844 struct attr_iter iter;
5845 struct attr layout_attr;
5846
5847 iter.u.list = 0x00;
5848
5849 if (navit_get_attr(n, attr_layout, &layout_attr, &iter) != 1)
5850 {
5851 return 0; //No layouts - nothing to do
5852 }
5853 if (iter.u.list == NULL)
5854 {
5855 return 0;
5856 }
5857
5858 iter.u.list = g_list_first(iter.u.list);
5859
5860 while (iter.u.list)
5861 {
5862 l = (struct layout*) iter.u.list->data;
5863 if (!strcmp(name, l->name))
5864 {
5865 layout_attr.u.layout = l;
5866 layout_attr.type = attr_layout;
5867 navit_set_attr(n, &layout_attr);
5868 iter.u.list = g_list_first(iter.u.list);
5869 return 1;
5870 }
5871 iter.u.list = g_list_next(iter.u.list);
5872 }
5873
5874 iter.u.list = g_list_first(iter.u.list);
5875 return 0;
5876 }
5877
5878 void navit_disable_suspend()
5879 {
5880
5881
5882 ////DBG dbg(0,"EEnter\n");
5883
5884 gui_disable_suspend(global_navit->gui);
5885 callback_list_call_attr_0(global_navit->attr_cbl, attr_unsuspend);
5886 }
5887
5888 /**
5889 * @brief Dumps item attrs to string
5890 *
5891 * @param item item
5892 * @param pretty 0 -> normal, 1 -> pretty output
5893 * @return string with attrs separated by '\n'
5894 */
5895 char* navit_item_dump(struct item *item, int pretty)
5896 {
5897 char *temp_str = NULL;
5898 char *ret_value = NULL;
5899 struct attr attr;
5900 struct attr attr2;
5901 int had_flags = 0;
5902 int *f;
5903 int flags;
5904
5905 if (item == NULL)
5906 {
5907 ret_value = g_strdup("");
5908 return ret_value;
5909 }
5910
5911 if (pretty == 1)
5912 {
5913 ret_value = g_strdup_printf("+*TYPE*+:%s", item_to_name(item->type));
5914 }
5915 else
5916 {
5917 ret_value = g_strdup_printf("type=%s", item_to_name(item->type));
5918 }
5919
5920 while (item_attr_get(item, attr_any, &attr))
5921 {
5922 if (attr.type == attr_flags)
5923 {
5924 had_flags = 1;
5925
5926 flags = attr.u.num;
5927 if (flags == 0)
5928 {
5929 f = item_get_default_flags(item->type);
5930 if (f)
5931 {
5932 flags = *f;
5933 }
5934 else
5935 {
5936 flags = 0;
5937 }
5938 }
5939
5940 if (pretty == 1)
5941 {
5942 temp_str = g_strdup_printf("%s\n%s=%s", ret_value, attr_to_name(attr.type), flags_to_text(flags));
5943 }
5944 else
5945 {
5946 temp_str = g_strdup_printf("%s\n%s='%s'", ret_value, attr_to_name(attr.type), flags_to_text(flags));
5947 }
5948 }
5949 else
5950 {
5951 if (pretty == 1)
5952 {
5953 temp_str = g_strdup_printf("%s\n%s=%s", ret_value, attr_to_name(attr.type), attr_to_text(&attr, NULL, 1));
5954 }
5955 else
5956 {
5957 temp_str = g_strdup_printf("%s\n%s='%s'", ret_value, attr_to_name(attr.type), attr_to_text(&attr, NULL, 1));
5958 }
5959 }
5960 g_free(ret_value);
5961 ret_value = g_strdup(temp_str);
5962 g_free(temp_str);
5963 }
5964
5965 if (had_flags == 0)
5966 {
5967 f = item_get_default_flags(item->type);
5968 if (f)
5969 {
5970 flags = *f;
5971
5972 if (pretty == 1)
5973 {
5974 temp_str = g_strdup_printf("%s\n%s=%s", ret_value, attr_to_name(attr_flags), flags_to_text(flags));
5975 }
5976 else
5977 {
5978 temp_str = g_strdup_printf("%s\n%s='%s'", ret_value, attr_to_name(attr_flags), flags_to_text(flags));
5979 }
5980
5981 g_free(ret_value);
5982 ret_value = g_strdup(temp_str);
5983 g_free(temp_str);
5984 }
5985 }
5986
5987 // g_free(item);
5988
5989 return ret_value;
5990 }
5991
5992 int navit_normal_item(enum item_type type)
5993 {
5994 if ((type > type_none) && (type < type_waypoint))
5995 {
5996 return 1;
5997 }
5998 else if ((type >= type_poi_land_feature) && (type <= type_poi_zoo))
5999 {
6000 return 1;
6001 }
6002 else if ((type >= type_traffic_signals) && (type <= type_poi_cafe))
6003 {
6004 return 1;
6005 }
6006 else if ((type >= type_poi_peak) && (type <= type_poi_ruins))
6007 {
6008 return 1;
6009 }
6010 else if ((type >= type_poi_post_box) && (type <= type_house_number))
6011 {
6012 return 1;
6013 }
6014 else if ((type >= type_poi_playground) && (type <= type_poi_shop_photo))
6015 {
6016 return 1;
6017 }
6018 else if (type == type_place_label)
6019 {
6020 return 1;
6021 }
6022 else if ((type >= type_line) && (type <= type_ferry))
6023 {
6024 return 1;
6025 }
6026 else if (type == type_street_unkn)
6027 {
6028 return 1;
6029 }
6030 else if (type == type_street_service)
6031 {
6032 return 1;
6033 }
6034 else if (type == type_street_pedestrian)
6035 {
6036 return 1;
6037 }
6038 else if (type == type_street_parking_lane)
6039 {
6040 return 1;
6041 }
6042 else if (type == type_ramp_highway_land)
6043 {
6044 return 1;
6045 }
6046 else if (type == type_ramp_street_4_city)
6047 {
6048 return 1;
6049 }
6050 else if (type == type_ramp_street_3_city)
6051 {
6052 return 1;
6053 }
6054 else if (type == type_ramp_street_2_city)
6055 {
6056 return 1;
6057 }
6058 else if ((type >= type_aeroway_runway) && (type <= type_footway_and_piste_nordic))
6059 {
6060 return 1;
6061 }
6062 else if ((type >= type_house_number_interpolation_even) && (type <= type_city_wall))
6063 {
6064 return 1;
6065 }
6066 else if ((type >= type_border_city) && (type <= type_border_county))
6067 {
6068 return 1;
6069 }
6070 else if ((type >= type_forest_way_1) && (type <= type_forest_way_4))
6071 {
6072 return 1;
6073 }
6074 else if ((type >= type_area) && (type <= type_poly_museum))
6075 {
6076 return 1;
6077 }
6078 else if ((type >= type_poly_commercial_center) && (type <= type_tundra))
6079 {
6080 return 1;
6081 }
6082 else if ((type >= type_poly_building) && (type <= type_poly_terminal))
6083 {
6084 return 1;
6085 }
6086 else if ((type >= type_poly_sports_centre) && (type <= type_poly_aeroway_runway))
6087 {
6088 return 1;
6089 }
6090
6091 return 0;
6092 }
6093
6094 char* navit_find_nearest_item_dump(struct mapset *ms, struct pcoord *pc, int pretty)
6095 {
6096 int max_dist = 0; // smallest rectangle possible
6097 int dist, mindist = 0, pos;
6098 int mindist_hn = 0;
6099 struct mapset_handle *h;
6100 struct map *m;
6101 struct map_rect *mr;
6102 struct item *item;
6103 struct coord lp;
6104 struct street_data *sd;
6105 struct coord c;
6106 struct coord_geo g;
6107 struct map_selection sel;
6108 struct attr street_name_attr;
6109 struct attr hn_attr;
6110 char *ret_str = NULL;
6111
6112
6113
6114
6115 mindist = 1000;
6116
6117 h = mapset_open(ms);
6118 if (!h)
6119 {
6120 // dbg(0,"return 1\n");
6121 ret_str = g_strdup("");
6122 return ret_str;
6123 }
6124
6125 while ((m = mapset_next(h, 0)))
6126 {
6127 c.x = pc->x;
6128 c.y = pc->y;
6129 if (map_projection(m) != pc->pro)
6130 {
6131 transform_to_geo(pc->pro, &c, &g);
6132 transform_from_geo(map_projection(m), &g, &c);
6133 }
6134
6135 sel.next = NULL;
6136 sel.order = 18;
6137 sel.range.min = type_none;
6138 sel.range.max = type_last;
6139 sel.u.c_rect.lu.x = c.x - max_dist;
6140 sel.u.c_rect.lu.y = c.y + max_dist;
6141 sel.u.c_rect.rl.x = c.x + max_dist;
6142 sel.u.c_rect.rl.y = c.y - max_dist;
6143
6144 mr = map_rect_new(m, &sel);
6145 if (!mr)
6146 {
6147 continue;
6148 }
6149
6150 while ((item = map_rect_get_item(mr)))
6151 {
6152 if (navit_normal_item(item->type) == 1)
6153 {
6154 //dbg(0,"*type=%s\n", item_to_name(item->type));
6155
6156 struct coord c2[101];
6157 int count22 = item_coord_get(item, c2, 100);
6158 if (count22 == 0)
6159 {
6160 continue;
6161 }
6162 else if (count22 > 1)
6163 {
6164 dist = transform_distance_polyline_sq__v2(c2, count22, &c);
6165 if (dist < mindist)
6166 {
6167 mindist = dist;
6168 if (ret_str != NULL)
6169 {
6170 g_free(ret_str);
6171 }
6172 ret_str = navit_item_dump(item, pretty);
6173 }
6174 }
6175 else
6176 {
6177 dist = transform_distance_sq(&c, &c2);
6178 if (dist <= (mindist + 4))
6179 {
6180 mindist = dist;
6181 if (ret_str != NULL)
6182 {
6183 g_free(ret_str);
6184 }
6185 ret_str = navit_item_dump(item, pretty);
6186 }
6187 }
6188 // dbg(0,"*end\n");
6189 }
6190 }
6191
6192 if (mr)
6193 {
6194 map_rect_destroy(mr);
6195 }
6196 }
6197 mapset_close(h);
6198
6199 if (ret_str == NULL)
6200 {
6201 // dbg(0,"was NULL\n");
6202 ret_str = g_strdup("");
6203 }
6204
6205 return ret_str;
6206 }
6207
6208 /**
6209 * @brief Finds the nearest street to a given coordinate
6210 *
6211 * @param ms The mapset to search in for the street
6212 * @param pc The coordinate to find a street nearby [ input in pcoord(x,y) ]
6213 * @return The nearest street
6214 */
6215 char*
6216 navit_find_nearest_street(struct mapset *ms, struct pcoord *pc)
6217 {
6218 int max_dist = 0; // smallest rectangle possible
6219 int dist, mindist = 0, pos;
6220 struct mapset_handle *h;
6221 struct map *m;
6222 struct map_rect *mr;
6223 struct item *item;
6224 struct coord lp;
6225 struct street_data *sd;
6226 struct coord c;
6227 struct coord_geo g;
6228 struct map_selection sel;
6229 struct attr street_name_attr;
6230 char *street_name = NULL;
6231
6232
6233
6234
6235 mindist = 10000; // start with small radius at the beginning!
6236 street_name = g_strdup(" ");
6237
6238 h = mapset_open(ms);
6239
6240 if (!h)
6241 {
6242 // set global value :-(
6243 dist_to_street = mindist;
6244 return street_name;
6245 }
6246
6247 while ((m = mapset_next(h, 0)))
6248 {
6249 c.x = pc->x;
6250 c.y = pc->y;
6251 if (map_projection(m) != pc->pro)
6252 {
6253 transform_to_geo(pc->pro, &c, &g);
6254 transform_from_geo(map_projection(m), &g, &c);
6255 }
6256
6257 sel.next = NULL;
6258 sel.order = 18;
6259 sel.range.min = type_line;
6260 sel.range.max = type_area;
6261 sel.u.c_rect.lu.x = c.x - max_dist;
6262 sel.u.c_rect.lu.y = c.y + max_dist;
6263 sel.u.c_rect.rl.x = c.x + max_dist;
6264 sel.u.c_rect.rl.y = c.y - max_dist;
6265
6266 mr = map_rect_new(m, &sel);
6267 if (!mr)
6268 {
6269 continue;
6270 }
6271
6272 while ((item = map_rect_get_item(mr)))
6273 {
6274 if (item_get_default_flags(item->type))
6275 {
6276 sd = street_get_data(item);
6277 if (!sd)
6278 {
6279 continue;
6280 }
6281
6282 //dbg(0,"6 sd x:%d sd y:%d count:%d\n", sd->c->x, sd->c->y, sd->count);
6283 //dbg(0,"6 c x:%d c y:%d\n", c.x, c.y);
6284 dist = transform_distance_polyline_sq__v2(sd->c, sd->count, &c);
6285 //dbg(0,"mindist:%d dist:%d\n", mindist, dist);
6286 if (dist < mindist)
6287 {
6288 //dbg(0,"6.a\n");
6289 mindist = dist;
6290
6291 if (item_attr_get(item, attr_street_name, &street_name_attr))
6292 {
6293 if (street_name)
6294 {
6295 g_free(street_name);
6296 street_name = NULL;
6297 }
6298 street_name = g_strdup_printf("%s", street_name_attr.u.str);
6299 //dbg(0,"r3 %s\n", street_name);
6300 }
6301 else if (item_attr_get(item, attr_label, &street_name_attr))
6302 {
6303 if (street_name)
6304 {
6305 g_free(street_name);
6306 street_name = NULL;
6307 }
6308 street_name = g_strdup_printf("%s", street_name_attr.u.str);
6309 //dbg(0,"r1 %s\n", street_name);
6310 }
6311 else if (item_attr_get(item, attr_street_name_systematic, &street_name_attr))
6312 {
6313 if (street_name)
6314 {
6315 g_free(street_name);
6316 street_name = NULL;
6317 }
6318 street_name = g_strdup_printf("%s", street_name_attr.u.str);
6319 //dbg(0,"r4 %s\n", street_name);
6320 }
6321 else
6322 {
6323 //if (street_name)
6324 //{
6325 // g_free(street_name);
6326 // street_name = NULL;
6327 //}
6328 //street_name = g_strdup_printf("---");
6329 }
6330 }
6331 street_data_free(sd);
6332 }
6333 }
6334
6335 if (mr)
6336 {
6337 map_rect_destroy(mr);
6338 }
6339 }
6340 mapset_close(h);
6341 // set global value :-(
6342 dist_to_street = mindist;
6343 return street_name;
6344 }
6345
6346 /**
6347 * @brief Finds the nearest street or housenumber to a given coordinate
6348 *
6349 * @param ms The mapset to search in for the street
6350 * @param pc The coordinate to find a street nearby [ input in pcoord(x,y) ]
6351 * @return The nearest street or housenumber
6352 */
6353 char*
6354 navit_find_nearest_street_hn(struct mapset *ms, struct pcoord *pc)
6355 {
6356 int max_dist = 0; // smallest rectangle possible
6357 int dist, mindist = 0, pos;
6358 int mindist_hn = 0;
6359 struct mapset_handle *h;
6360 struct map *m;
6361 struct map_rect *mr;
6362 struct item *item;
6363 struct coord lp;
6364 struct street_data *sd;
6365 struct coord c;
6366 struct coord_geo g;
6367 struct map_selection sel;
6368 struct attr street_name_attr;
6369 struct attr hn_attr;
6370 char *street_name = NULL;
6371 char *street_name_saved = NULL;
6372
6373
6374
6375
6376 // first find a street
6377 street_name_saved = navit_find_nearest_street(ms, pc);
6378 // street_name = g_strdup_printf(" ");
6379 street_name = g_strdup(street_name_saved);
6380 // first find a street
6381
6382 mindist = dist_to_street; // start with small radius at the beginning! (only use housenumber of different street, if we are really close to it!!)
6383 // global value -> this is naughty :-)
6384
6385 if (mindist < 8)
6386 {
6387 // so we can find other housenumbers if we are very close
6388 mindist = 8;
6389 }
6390
6391 mindist_hn = 10000;
6392
6393 //dbg(0,"given streetname %s %s dist %d\n", street_name, street_name_saved, dist_to_street);
6394
6395
6396 h = mapset_open(ms);
6397
6398 if (!h)
6399 {
6400 if (street_name_saved)
6401 {
6402 g_free(street_name_saved);
6403 street_name_saved = NULL;
6404 }
6405 return street_name;
6406 }
6407
6408 while ((m = mapset_next(h, 0)))
6409 {
6410 c.x = pc->x;
6411 c.y = pc->y;
6412 if (map_projection(m) != pc->pro)
6413 {
6414 transform_to_geo(pc->pro, &c, &g);
6415 transform_from_geo(map_projection(m), &g, &c);
6416 }
6417
6418 sel.next = NULL;
6419 sel.order = 18;
6420 sel.range.min = type_none;
6421 sel.range.max = type_area;
6422 sel.u.c_rect.lu.x = c.x - max_dist;
6423 sel.u.c_rect.lu.y = c.y + max_dist;
6424 sel.u.c_rect.rl.x = c.x + max_dist;
6425 sel.u.c_rect.rl.y = c.y - max_dist;
6426
6427 mr = map_rect_new(m, &sel);
6428 if (!mr)
6429 {
6430 continue;
6431 }
6432
6433 while ((item = map_rect_get_item(mr)))
6434 {
6435 if (item->type == type_house_number)
6436 {
6437 //dbg(0,"hn found\n");
6438 struct coord c2;
6439 int rrr = item_coord_get(item, &c2, 1);
6440 if (rrr)
6441 {
6442 dist = transform_distance_sq(&c, &c2);
6443 //dbg(0,"dist=%d\n", dist);
6444 if (dist < mindist)
6445 {
6446 if (item_attr_get(item, attr_street_name, &street_name_attr))
6447 {
6448 if (item_attr_get(item, attr_house_number, &hn_attr))
6449 {
6450 if (street_name)
6451 {
6452 g_free(street_name);
6453 street_name = NULL;
6454 }
6455 street_name = g_strdup_printf("%s %s", street_name_attr.u.str, hn_attr.u.str);
6456 //dbg(0,"sn 1\n");
6457 mindist = dist;
6458 mindist_hn = dist;
6459 }
6460 }
6461 }
6462 // else try to find housenumbers for our current street
6463 // just take the nearest housenumber for our current street
6464 else if (dist < mindist_hn)
6465 {
6466 //dbg(0,"sn 2.1\n");
6467 if (item_attr_get(item, attr_street_name, &street_name_attr))
6468 {
6469 //dbg(0,"sn 2.2\n");
6470 if (item_attr_get(item, attr_house_number, &hn_attr))
6471 {
6472 //dbg(0,"sn 2.3\n");
6473 if ((street_name != NULL) && (street_name_saved != NULL))
6474 {
6475 // dbg(0,"sn 2.4 -%s- -%s-\n", street_name_saved, street_name_attr.u.str);
6476 if (!strcmp(street_name_saved, street_name_attr.u.str))
6477 {
6478 g_free(street_name);
6479 street_name = NULL;
6480
6481 // dbg(0,"sn 2.99\n");
6482
6483 street_name = g_strdup_printf("%s %s", street_name_attr.u.str, hn_attr.u.str);
6484 mindist_hn = dist;
6485 }
6486 }
6487 }
6488 }
6489 }
6490 }
6491 }
6492
6493 #if 0
6494 //else if (item->type > type_line)
6495 if (1 == 0) // DISABLED !!!!!!
6496
6497 {
6498 if (item_get_default_flags(item->type))
6499 {
6500 sd = street_get_data(item);
6501 if (!sd)
6502 {
6503 continue;
6504 }
6505 dist = transform_distance_polyline_sq(sd->c, sd->count, &c, &lp, &pos);
6506 if (dist < mindist)
6507 {
6508 mindist = dist;
6509
6510 if (item_attr_get(item, attr_label, &street_name_attr))
6511 {
6512 if (street_name)
6513 {
6514