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

Contents of /navit/navit/vehicle.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 40 - (show annotations) (download)
Wed Mar 4 14:00:54 2015 UTC (9 years, 1 month ago) by zoff99
File MIME type: text/plain
File size: 25356 byte(s)
new market version, lots of fixes
1 /**
2 * ZANavi, Zoff Android Navigation system.
3 * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
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 #include <stdio.h>
40 #include <string.h>
41 #include <glib.h>
42 #include <time.h>
43 #include "config.h"
44 #include "debug.h"
45 #include "coord.h"
46 #include "item.h"
47 #include "log.h"
48 #include "plugin.h"
49 #include "transform.h"
50 #include "util.h"
51 #include "event.h"
52 // #include "coord.h"
53 #include "navit.h"
54 #include "transform.h"
55 #include "projection.h"
56 #include "point.h"
57 #include "graphics.h"
58 #include "callback.h"
59 #include "color.h"
60 #include "layout.h"
61 #include "vehicle.h"
62
63 // forward rev
64 struct navit *global_navit;
65
66 struct vehicle
67 {
68 struct vehicle_methods meth;
69 struct vehicle_priv *priv;
70 struct callback_list *cbl;
71 struct log *nmea_log, *gpx_log;
72 char *gpx_desc;
73 struct attr **attrs;
74
75 // cursor
76 struct cursor *cursor;
77 int cursor_fixed;
78 struct callback *animate_callback;
79 struct event_timeout *animate_timer;
80 struct point cursor_pnt;
81 struct graphics *gra;
82 struct graphics_gc *bg;
83 struct transformation *trans;
84 int angle;
85 int speed;
86 int sequence;
87 GHashTable *log_to_cb;
88 };
89
90 static void vehicle_draw_do(struct vehicle *this_, int lazy);
91 static void vehicle_log_nmea(struct vehicle *this_, struct log *log);
92 static void vehicle_log_gpx(struct vehicle *this_, struct log *log);
93 static void vehicle_log_textfile(struct vehicle *this_, struct log *log);
94 static void vehicle_log_binfile(struct vehicle *this_, struct log *log);
95 static int vehicle_add_log(struct vehicle *this_, struct log *log);
96 void vehicle_remove_cursor(struct vehicle *this_);
97 extern int hold_drawing; // in navit.c
98
99 /**
100 * Creates a new vehicle
101 */
102 struct vehicle *
103 vehicle_new(struct attr *parent, struct attr **attrs)
104 {
105 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
106 dbg(0,"+#+:enter\n");
107 #endif
108 struct vehicle *this_;
109 struct attr *source;
110 struct vehicle_priv *(*vehicletype_new)(struct vehicle_methods * meth, struct callback_list * cbl, struct attr ** attrs);
111 char *type, *colon;
112 struct pcoord center;
113
114 //DBG dbg(0, "enter\n");
115 source = attr_search(attrs, NULL, attr_source);
116 if (!source)
117 {
118 //DBG dbg(0, "no source\n");
119 return NULL;
120 }
121
122 type = g_strdup(source->u.str);
123 colon = strchr(type, ':');
124 if (colon)
125 {
126 *colon = '\0';
127 }
128 ////DBG dbg(0, "source='%s' type='%s'\n", source->u.str, type);
129
130 #ifdef PLUGSSS
131 vehicletype_new = plugin_get_vehicle_type(type);
132 if (!vehicletype_new)
133 {
134 //DBG dbg(0, "invalid type '%s'\n", type);
135 g_free(type);
136 return NULL;
137 }
138 #endif
139
140 this_ = g_new0(struct vehicle, 1);
141 this_->cbl = callback_list_new("vehicle_new:this_->cbl");
142
143
144
145 #ifdef PLUGSSS
146 this_->priv = vehicletype_new(&this_->meth, this_->cbl, attrs);
147 #else
148
149 if (strncmp("demo", type, 4) == 0)
150 {
151 this_->priv = vehicle_demo_new(&this_->meth, this_->cbl, attrs);
152 }
153 else if (strncmp("android", type, 7) == 0)
154 {
155 this_->priv = vehicle_android_new_android(&this_->meth, this_->cbl, attrs);
156 }
157 #endif
158
159 g_free(type);
160
161
162 //DBG dbg(0, "veh new 2\n");
163 if (!this_->priv)
164 {
165 //DBG dbg(0, "vehicletype_new failed\n");
166 callback_list_destroy(this_->cbl);
167 g_free(this_);
168 return NULL;
169 }
170 //DBG dbg(0, "veh new 3\n");
171 this_->attrs = attr_list_dup(attrs);
172 //DBG dbg(0, "veh new 4\n");
173 this_->trans = transform_new();
174
175 // set bad 0/0 location ??? i dont know really
176 /*
177 struct coord_geo g;
178 struct coord co;
179 enum projection pro=projection_mg;
180 g.lat=53.13;
181 g.lng=11.70;
182 transform_from_geo(pro, &g, &co);
183 center.x=co.x;
184 center.y=co.y;
185 center.pro = pro;
186 */
187
188 center.pro = projection_screen;
189 center.x = 0;
190 center.y = 0;
191 //DBG dbg(0, "veh new 5\n");
192 transform_setup(this_->trans, &center, 16, 0);
193 //DBG dbg(0, "veh new 6\n");
194
195 this_->log_to_cb = g_hash_table_new(NULL, NULL);
196 //DBG dbg(0, "leave\n");
197 return this_;
198 }
199
200 /**
201 * Destroys a vehicle
202 *
203 * @param this_ The vehicle to destroy
204 */
205 void vehicle_destroy(struct vehicle *this_)
206 {
207 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
208 dbg(0,"+#+:enter\n");
209 #endif
210 if (this_->animate_callback)
211 {
212 callback_destroy(this_->animate_callback);
213 event_remove_timeout(this_->animate_timer);
214 }
215 transform_destroy(this_->trans);
216 this_->meth.destroy(this_->priv);
217 callback_list_destroy(this_->cbl);
218 attr_list_free(this_->attrs);
219 if (this_->bg)
220 graphics_gc_destroy(this_->bg);
221 if (this_->gra)
222 graphics_free(this_->gra);
223 g_free(this_);
224 }
225
226 /**
227 * Creates an attribute iterator to be used with vehicles
228 */
229 struct attr_iter *
230 vehicle_attr_iter_new(void)
231 {
232 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
233 dbg(0,"+#+:enter\n");
234 #endif
235 return (struct attr_iter *)g_new0(void *,1);
236 }
237
238 /**
239 * Destroys a vehicle attribute iterator
240 *
241 * @param iter a vehicle attr_iter
242 */
243 void vehicle_attr_iter_destroy(struct attr_iter *iter)
244 {
245 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
246 dbg(0,"+#+:enter\n");
247 #endif
248 g_free(iter);
249 }
250
251 /**
252 * Generic get function
253 *
254 * @param this_ Pointer to a vehicle structure
255 * @param type The attribute type to look for
256 * @param attr Pointer to an attr structure to store the attribute
257 * @param iter A vehicle attr_iter
258 */
259 int vehicle_get_attr(struct vehicle *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
260 {
261 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
262 dbg(0,"+#+:enter\n");
263 #endif
264 ////DBG dbg(0,"enter\n");
265 int ret;
266 if (this_->meth.position_attr_get)
267 {
268 ret = this_->meth.position_attr_get(this_->priv, type, attr);
269 if (ret)
270 {
271 return ret;
272 }
273 }
274 if (type == attr_log_gpx_desc)
275 {
276 attr->u.str = this_->gpx_desc;
277 return 1;
278 }
279 ////DBG dbg(0,"before return\n");
280
281 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
282 dbg(0,"+#+:leave\n");
283 #endif
284
285 return attr_generic_get_attr(this_->attrs, NULL, type, attr, iter);
286 }
287
288 /**
289 * Generic set function
290 *
291 * @param this_ Pointer to a vehicle structure
292 * @param attr Pointer to an attr structure for the attribute to be set
293 * @return nonzero on success, zero on failure
294 */
295 int vehicle_set_attr(struct vehicle *this_, struct attr *attr)
296 {
297 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
298 dbg(0,"+#+:enter\n");
299 #endif
300 int ret = 1;
301 if (this_->meth.set_attr)
302 {
303 //dbg(0,"xx 1\n");
304 ret = this_->meth.set_attr(this_->priv, attr);
305 //dbg(0,"xx 1.1\n");
306 }
307
308 if (ret == 1 && attr->type == attr_log_gpx_desc)
309 {
310 g_free(this_->gpx_desc);
311 this_->gpx_desc = attr->u.str;
312 }
313
314 if (ret == 1 && attr->type != attr_navit && attr->type != attr_pdl_gps_update)
315 {
316 //dbg(0,"xx 3\n");
317 this_->attrs = attr_generic_set_attr(this_->attrs, attr);
318 }
319
320 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
321 dbg(0,"+#+:leave\n");
322 #endif
323
324 return ret != 0;
325 }
326
327 /**
328 * Generic add function
329 *
330 * @param this_ A vehicle
331 * @param attr A struct attr
332 */
333 int vehicle_add_attr(struct vehicle *this_, struct attr *attr)
334 {
335 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
336 dbg(0,"+#+:enter\n");
337 #endif
338 int ret = 1;
339
340 switch (attr->type)
341 {
342 case attr_callback:
343 callback_list_add(this_->cbl, attr->u.callback);
344 break;
345 case attr_log:
346 ret = vehicle_add_log(this_, attr->u.log);
347 break;
348 // currently supporting oldstyle cursor config.
349 case attr_cursor:
350 this_->cursor_fixed = 1;
351 vehicle_set_cursor(this_, attr->u.cursor, 1);
352 break;
353 default:
354 break;
355 }
356
357 if (ret)
358 {
359 this_->attrs = attr_generic_add_attr(this_->attrs, attr);
360 }
361
362 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
363 dbg(0,"+#+:leave\n");
364 #endif
365
366 return ret;
367 }
368
369 /**
370 * @brief Generic remove function.
371 *
372 * Used to remove a callback from the vehicle.
373 * @param this_ A vehicle
374 * @param attr
375 */
376 int vehicle_remove_attr(struct vehicle *this_, struct attr *attr)
377 {
378 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
379 dbg(0,"+#+:enter\n");
380 #endif
381 struct callback *cb;
382 switch (attr->type)
383 {
384 case attr_callback:
385 callback_list_remove(this_->cbl, attr->u.callback);
386 break;
387 case attr_log:
388 cb = g_hash_table_lookup(this_->log_to_cb, attr->u.log);
389 if (!cb)
390 return 0;
391 g_hash_table_remove(this_->log_to_cb, attr->u.log);
392 callback_list_remove(this_->cbl, cb);
393 break;
394 case attr_cursor:
395 vehicle_remove_cursor(this_);
396 break;
397 default:
398 this_->attrs = attr_generic_remove_attr(this_->attrs, attr);
399 return 0;
400 }
401 return 1;
402 }
403
404 /**
405 * Sets the cursor of a vehicle.
406 *
407 * @param this_ A vehicle
408 * @param cursor A cursor
409 * @author Ralph Sennhauser (10/2009)
410 */
411 void vehicle_set_cursor(struct vehicle *this_, struct cursor *cursor, int overwrite)
412 {
413 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
414 dbg(0,"+#+:enter\n");
415 #endif
416 struct point sc;
417 if (this_->cursor_fixed && !overwrite)
418 {
419 return;
420 }
421
422 #if 0
423 if (this_->animate_callback)
424 {
425 event_remove_timeout(this_->animate_timer);
426 this_->animate_timer = NULL; // dangling pointer! prevent double freeing.
427 callback_destroy(this_->animate_callback);
428 this_->animate_callback = NULL; // dangling pointer! prevent double freeing.
429 }
430
431 if (cursor && cursor->interval)
432 {
433 this_->animate_callback = callback_new_2(callback_cast(vehicle_draw_do), this_, 0);
434 //dbg(0, "event_add_timeout %d,%d,%p", cursor->interval, 1, this_->animate_callback);
435 this_->animate_timer = event_add_timeout(cursor->interval, 1, this_->animate_callback);
436 }
437
438 if (cursor && this_->gra && this_->cursor)
439 {
440 this_->cursor_pnt.x += (this_->cursor->w - cursor->w) / 2;
441 this_->cursor_pnt.y += (this_->cursor->h - cursor->h) / 2;
442 graphics_overlay_resize(this_->gra, &this_->cursor_pnt, cursor->w, cursor->h, 65535, 0);
443 }
444 #endif
445
446 // ###############################################
447 // ###############################################
448 // set fixed size of navigation cursor to 50,50 !!
449 if (cursor)
450 {
451 cursor->w = 50;
452 cursor->h = 50;
453 }
454
455 if (this_->cursor)
456 {
457 this_->cursor->w = 50;
458 this_->cursor->h = 50;
459 }
460 // set fixed size of navigation cursor to 50,50 !!
461 // ###############################################
462 // ###############################################
463
464
465 if (cursor)
466 {
467 sc.x = cursor->w / 2;
468 sc.y = cursor->h / 2;
469 //if (!this_->cursor && this_->gra)
470 //{
471 // graphics_overlay_disable(this_->gra, 0);
472 //}
473 }
474 else
475 {
476 sc.x = sc.y = 0;
477 //if (this_->cursor && this_->gra)
478 //{
479 // graphics_overlay_disable(this_->gra, 1);
480 //}
481 }
482
483 transform_set_screen_center(this_->trans, &sc);
484
485 this_->cursor = cursor;
486
487 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
488 dbg(0,"+#+:leave\n");
489 #endif
490
491 }
492
493 void vehicle_remove_cursor(struct vehicle *this_)
494 {
495 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
496 dbg(0,"+#+:enter\n");
497 #endif
498 struct point sc;
499
500 if (this_->animate_callback)
501 {
502 event_remove_timeout(this_->animate_timer);
503 this_->animate_timer = NULL; // dangling pointer! prevent double freeing.
504 callback_destroy(this_->animate_callback);
505 this_->animate_callback = NULL; // dangling pointer! prevent double freeing.
506 }
507
508 if (this_->cursor && this_->gra)
509 {
510 }
511
512 if (this_->cursor && this_->gra)
513 {
514 graphics_overlay_disable(this_->gra, 1);
515 }
516
517 this_->cursor = NULL;
518 }
519
520 /**
521 * Draws a vehicle on top of a graphics.
522 *
523 * @param this_ The vehicle
524 * @param gra The graphics
525 * @param pnt Screen coordinates of the vehicle.
526 * @param lazy use lazy draw mode.
527 * @param angle The angle relative to the map.
528 * @param speed The speed of the vehicle.
529 */
530 void vehicle_draw(struct vehicle *this_, struct graphics *gra, struct point *pnt, int lazy, int angle, int speed)
531 {
532 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
533 dbg(0,"+#+:enter\n");
534 #endif
535
536 //if (hold_drawing > 0)
537 //{
538 // return;
539 //}
540
541 if (angle < 0)
542 {
543 angle += 360;
544 }
545
546 //// dbg(1, "enter this=%p gra=%p pnt=%p lazy=%d dir=%d speed=%d\n", this_, gra,
547 // pnt, lazy, angle, speed);
548 //dbg(0, "point %d,%d\n", pnt->x, pnt->y);
549 this_->cursor_pnt = *pnt;
550 this_->angle = angle;
551 this_->speed = speed;
552 if (!this_->cursor)
553 {
554 return;
555 }
556
557 //dbg(0,"cpx:%d, cpy:%d, cw:%d, ch:%d\n", this_->cursor_pnt.x, this_->cursor_pnt.y, this_->cursor->w, this_->cursor->h);
558
559 //*** this_->cursor_pnt.x -= this_->cursor->w / 2;
560 //*** this_->cursor_pnt.y -= this_->cursor->h / 2;
561
562 #if 0
563 if (!this_->gra)
564 {
565 struct color c;
566 dbg(0,"Create new Vehicle Overlay Graphics\n");
567 this_->gra = graphics_overlay_new("type:vehicle",gra, &this_->cursor_pnt, this_->cursor->w, this_->cursor->h, 65535, 0);
568 if (this_->gra)
569 {
570 this_->bg = graphics_gc_new(this_->gra);
571 c.r = 0;
572 c.g = 0;
573 c.b = 0;
574 c.a = 0;
575 graphics_gc_set_foreground(this_->bg, &c);
576 graphics_background_gc(this_->gra, this_->bg);
577 }
578 }
579 #endif
580
581 // ++++++++++ // transform_set_yaw(this_->trans, -this_->angle);
582 // vehicle_draw_do(this_, lazy);
583
584 #ifdef HAVE_API_ANDROID
585 //dbg(0,"x=%d y=%d angle=%d speed=%d\n",this_->cursor_pnt.x, this_->cursor_pnt.y, angle, speed);
586
587 //int dx = 0;
588 //int dy = 0;
589 //int dangle = 0;
590
591 //struct navit_vehicle *nv2 = global_navit->vehicle;
592 //struct point pnt2;
593 //dbg(0,"dir=%d dx=%d, dy=%d\n", nv2->dir, dx, dy);
594 //transform(this_->trans, projection_mg, &nv2->coord, &pnt2, 1, 0, 0, NULL);
595 //dbg(0,"px=%d, py=%d\n", pnt2.x, pnt2.y);
596
597 set_vehicle_values_to_java(this_->cursor_pnt.x, this_->cursor_pnt.y, angle, speed);
598 #endif
599
600 }
601
602 int vehicle_get_cursor_data(struct vehicle *this, struct point *pnt, int *angle, int *speed)
603 {
604 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
605 dbg(0,"+#+:enter\n");
606 #endif
607 *pnt = this->cursor_pnt;
608 *angle = this->angle;
609 *speed = this->speed;
610 return 1;
611 }
612
613 //int vehicle_set_cursor_data_01(struct vehicle *this, struct point *pnt)
614 //{
615 //#ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
616 // dbg(0,"+#+:enter\n");
617 //#endif
618 // this->cursor_pnt.x = pnt->.x;
619 // this->cursor_pnt.y = pnt->.y;
620 // return 1;
621 //}
622
623
624 static void vehicle_draw_do(struct vehicle *this_, int lazy)
625 {
626 // UNUSED ---------
627 }
628
629 /**
630 * Writes to an NMEA log.
631 *
632 * @param this_ Pointer to the vehicle structure of the data source
633 * @param log Pointer to a log structure for the log file
634 */
635 static void vehicle_log_nmea(struct vehicle *this_, struct log *log)
636 {
637 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
638 dbg(0,"+#+:enter\n");
639 #endif
640 struct attr pos_attr;
641
642 if (!this_->meth.position_attr_get)
643 {
644 return;
645 }
646
647 if (!this_->meth.position_attr_get(this_->priv, attr_position_nmea, &pos_attr))
648 {
649 return;
650 }
651
652 log_write(log, pos_attr.u.str, strlen(pos_attr.u.str), 0);
653 }
654
655
656 void vehicle_log_gpx_add_tag(char *tag, char **logstr)
657 {
658 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
659 dbg(0,"+#+:enter\n");
660 #endif
661 char *ext_start = "\t<extensions>\n";
662 char *ext_end = "\t</extensions>\n";
663 char *trkpt_end = "</trkpt>";
664 char *start = NULL, *end = NULL;
665 if (!*logstr)
666 {
667 start = g_strdup(ext_start);
668 end = g_strdup(ext_end);
669 }
670 else
671 {
672 char *str = strstr(*logstr, ext_start);
673 int len;
674 if (str)
675 {
676 len = str - *logstr + strlen(ext_start);
677 start = g_strdup(*logstr);
678 start[len] = '\0';
679 end = g_strdup(str + strlen(ext_start));
680 }
681 else
682 {
683 str = strstr(*logstr, trkpt_end);
684 len = str - *logstr;
685 end = g_strdup_printf("%s%s", ext_end, str);
686 str = g_strdup(*logstr);
687 str[len] = '\0';
688 start = g_strdup_printf("%s%s", str, ext_start);
689 g_free(str);
690 }
691 }
692 *logstr = g_strdup_printf("%s%s%s", start, tag, end);
693 g_free(start);
694 g_free(end);
695 }
696
697 /**
698 * Writes to a GPX log.
699 *
700 * @param this_ Pointer to the vehicle structure of the data source
701 * @param log Pointer to a log structure for the log file
702 */
703 static void vehicle_log_gpx(struct vehicle *this_, struct log *log)
704 {
705 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
706 dbg(0,"+#+:enter\n");
707 #endif
708 struct attr attr, *attrp, fix_attr;
709 enum attr_type *attr_types;
710 char *logstr;
711 char *extensions = "\t<extensions>\n";
712
713 if (!this_->meth.position_attr_get)
714 return;
715 if (log_get_attr(log, attr_attr_types, &attr, NULL))
716 attr_types = attr.u.attr_types;
717 else
718 attr_types = NULL;
719 if (this_->meth.position_attr_get(this_->priv, attr_position_fix_type, &fix_attr))
720 {
721 if (fix_attr.u.num == 0)
722 return;
723 }
724 if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &attr))
725 return;
726 logstr = g_strdup_printf("<trkpt lat=\"%f\" lon=\"%f\">\n", attr.u.coord_geo->lat, attr.u.coord_geo->lng);
727 if (attr_types && attr_types_contains_default(attr_types, attr_position_time_iso8601, 0))
728 {
729 if (this_->meth.position_attr_get(this_->priv, attr_position_time_iso8601, &attr))
730 {
731 logstr = g_strconcat_printf(logstr, "\t<time>%s</time>\n", attr.u.str);
732 }
733 else
734 {
735 char *timep = current_to_iso8601();
736 logstr = g_strconcat_printf(logstr, "\t<time>%s</time>\n", timep);
737 g_free(timep);
738 }
739 }
740 if (this_->gpx_desc)
741 {
742 logstr = g_strconcat_printf(logstr, "\t<desc>%s</desc>\n", this_->gpx_desc);
743 g_free(this_->gpx_desc);
744 this_->gpx_desc = NULL;
745 }
746 if (attr_types_contains_default(attr_types, attr_position_height, 0) && this_->meth.position_attr_get(this_->priv, attr_position_height, &attr))
747 logstr = g_strconcat_printf(logstr, "\t<ele>%.6f</ele>\n", *attr.u.numd);
748 // <magvar> magnetic variation in degrees; we might use position_magnetic_direction and position_direction to figure it out
749 // <geoidheight> Height (in meters) of geoid (mean sea level) above WGS84 earth ellipsoid. As defined in NMEA GGA message (field 11, which vehicle_wince.c ignores)
750 // <name> GPS name (arbitrary)
751 // <cmt> comment
752 // <src> Source of data
753 // <link> Link to additional information (URL)
754 // <sym> Text of GPS symbol name
755 // <type> Type (classification)
756 // <fix> Type of GPS fix {'none'|'2d'|'3d'|'dgps'|'pps'}, leave out if unknown. Similar to position_fix_type but more detailed.
757 if (attr_types_contains_default(attr_types, attr_position_sats_used, 0) && this_->meth.position_attr_get(this_->priv, attr_position_sats_used, &attr))
758 logstr = g_strconcat_printf(logstr, "\t<sat>%d</sat>\n", attr.u.num);
759 if (attr_types_contains_default(attr_types, attr_position_hdop, 0) && this_->meth.position_attr_get(this_->priv, attr_position_hdop, &attr))
760 logstr = g_strconcat_printf(logstr, "\t<hdop>%.6f</hdop>\n", *attr.u.numd);
761 // <vdop>, <pdop> Vertical and position dilution of precision, no corresponding attribute
762 if (attr_types_contains_default(attr_types, attr_position_direction, 0) && this_->meth.position_attr_get(this_->priv, attr_position_direction, &attr))
763 logstr = g_strconcat_printf(logstr, "\t<course>%.1f</course>\n", *attr.u.numd);
764 if (attr_types_contains_default(attr_types, attr_position_speed, 0) && this_->meth.position_attr_get(this_->priv, attr_position_speed, &attr))
765 logstr = g_strconcat_printf(logstr, "\t<speed>%.2f</speed>\n", (*attr.u.numd / 3.6));
766 if (attr_types_contains_default(attr_types, attr_profilename, 0) && (attrp = attr_search(this_->attrs, NULL, attr_profilename)))
767 {
768 logstr = g_strconcat_printf(logstr, "%s\t\t<navit:profilename>%s</navit:profilename>\n", extensions, attrp->u.str);
769 extensions = "";
770 }
771 if (attr_types_contains_default(attr_types, attr_position_radius, 0) && this_->meth.position_attr_get(this_->priv, attr_position_radius, &attr))
772 {
773 logstr = g_strconcat_printf(logstr, "%s\t\t<navit:radius>%.2f</navit:radius>\n", extensions, *attr.u.numd);
774 extensions = "";
775 }
776 if (!strcmp(extensions, ""))
777 {
778 logstr = g_strconcat_printf(logstr, "\t</extensions>\n");
779 }
780 logstr = g_strconcat_printf(logstr, "</trkpt>\n");
781 callback_list_call_attr_1(this_->cbl, attr_log_gpx, &logstr);
782 log_write(log, logstr, strlen(logstr), 0);
783 g_free(logstr);
784 }
785
786 /**
787 * Writes to a text log.
788 *
789 * @param this_ Pointer to the vehicle structure of the data source
790 * @param log Pointer to a log structure for the log file
791 */
792 static void vehicle_log_textfile(struct vehicle *this_, struct log *log)
793 {
794 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
795 dbg(0,"+#+:enter\n");
796 #endif
797 struct attr pos_attr, fix_attr;
798 char *logstr;
799 if (!this_->meth.position_attr_get)
800 return;
801 if (this_->meth.position_attr_get(this_->priv, attr_position_fix_type, &fix_attr))
802 {
803 if (fix_attr.u.num == 0)
804 return;
805 }
806 if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr))
807 return;
808 logstr = g_strdup_printf("%f %f type=trackpoint\n", pos_attr.u.coord_geo->lng, pos_attr.u.coord_geo->lat);
809 callback_list_call_attr_1(this_->cbl, attr_log_textfile, &logstr);
810 log_write(log, logstr, strlen(logstr), 0);
811 }
812
813 /**
814 * Writes to a binary log.
815 *
816 * @param this_ Pointer to the vehicle structure of the data source
817 * @param log Pointer to a log structure for the log file
818 */
819 static void vehicle_log_binfile(struct vehicle *this_, struct log *log)
820 {
821 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
822 dbg(0,"+#+:enter\n");
823 #endif
824 struct attr pos_attr, fix_attr;
825 int *buffer;
826 int *buffer_new;
827 int len, limit = 1024, done = 0, radius = 25;
828 struct coord c;
829 enum log_flags flags;
830
831 if (!this_->meth.position_attr_get)
832 return;
833 if (this_->meth.position_attr_get(this_->priv, attr_position_fix_type, &fix_attr))
834 {
835 if (fix_attr.u.num == 0)
836 return;
837 }
838 if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr))
839 return;
840 transform_from_geo(projection_mg, pos_attr.u.coord_geo, &c);
841 if (!c.x || !c.y)
842 return;
843 while (!done)
844 {
845 buffer = log_get_buffer(log, &len);
846 if (!buffer || !len)
847 {
848 buffer_new = g_malloc(5 * sizeof(int));
849 buffer_new[0] = 2;
850 buffer_new[1] = type_track;
851 buffer_new[2] = 0;
852 }
853 else
854 {
855 buffer_new = g_malloc((buffer[0] + 3) * sizeof(int));
856 memcpy(buffer_new, buffer, (buffer[0] + 1) * sizeof(int));
857 }
858 //// dbg(1, "c=0x%x,0x%x\n", c.x, c.y);
859 buffer_new[buffer_new[0] + 1] = c.x;
860 buffer_new[buffer_new[0] + 2] = c.y;
861 buffer_new[0] += 2;
862 buffer_new[2] += 2;
863 if (buffer_new[2] > limit)
864 {
865 int count = buffer_new[2] / 2;
866 struct coord *out = g_alloca(sizeof(struct coord) * (count));
867 struct coord *in = (struct coord *) (buffer_new + 3);
868 int count_out = transform_douglas_peucker(in, count, radius, out);
869 memcpy(in, out, count_out * 2 * sizeof(int));
870 buffer_new[0] += (count_out - count) * 2;
871 buffer_new[2] += (count_out - count) * 2;
872 flags = log_flag_replace_buffer | log_flag_force_flush | log_flag_truncate;
873 }
874 else
875 {
876 flags = log_flag_replace_buffer | log_flag_keep_pointer | log_flag_keep_buffer | log_flag_force_flush;
877 done = 1;
878 }
879 log_write(log, (char *) buffer_new, (buffer_new[0] + 1) * sizeof(int), flags);
880 }
881 }
882
883 /**
884 * Register a new log to receive data.
885 *
886 * @param this_ Pointer to the vehicle structure of the data source
887 * @param log Pointer to a log structure for the log file
888 */
889 static int vehicle_add_log(struct vehicle *this_, struct log *log)
890 {
891 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
892 dbg(0,"+#+:enter\n");
893 #endif
894 struct callback *cb;
895 struct attr type_attr;
896 if (!log_get_attr(log, attr_type, &type_attr, NULL))
897 return 1;
898
899 if (!strcmp(type_attr.u.str, "nmea"))
900 {
901 cb = callback_new_attr_2(callback_cast(vehicle_log_nmea), attr_position_coord_geo, this_, log);
902 }
903 else if (!strcmp(type_attr.u.str, "gpx"))
904 {
905 char *header = "<?xml version='1.0' encoding='UTF-8'?>\n"
906 "<gpx version='1.1' creator='Navit http://navit.sourceforge.net'\n"
907 " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"
908 " xmlns:navit='http://www.navit-project.org/schema/navit'\n"
909 " xmlns='http://www.topografix.com/GPX/1/1'\n"
910 " xsi:schemaLocation='http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'>\n"
911 "<trk>\n"
912 "<trkseg>\n";
913 char *trailer = "</trkseg>\n</trk>\n</gpx>\n";
914 log_set_header(log, header, strlen(header));
915 log_set_trailer(log, trailer, strlen(trailer));
916 cb = callback_new_attr_2(callback_cast(vehicle_log_gpx), attr_position_coord_geo, this_, log);
917 }
918 else if (!strcmp(type_attr.u.str, "textfile"))
919 {
920 char *header = "type=track\n";
921 log_set_header(log, header, strlen(header));
922 cb = callback_new_attr_2(callback_cast(vehicle_log_textfile), attr_position_coord_geo, this_, log);
923 }
924 else if (!strcmp(type_attr.u.str, "binfile"))
925 {
926 cb = callback_new_attr_2(callback_cast(vehicle_log_binfile), attr_position_coord_geo, this_, log);
927 }
928 else
929 return 1;
930 g_hash_table_insert(this_->log_to_cb, log, cb);
931 callback_list_add(this_->cbl, cb);
932 return 0;
933 }
934
935 void vehicle_update_(struct vehicle *this_, double lat, double lon, float speed, float direction, double height, float radius, long gpstime)
936 {
937 #ifdef HAVE_API_ANDROID
938 if (this_->meth.update_location_direct)
939 {
940 // dbg(0,"location=%p\n", location);
941 this_->meth.update_location_direct(lat, lon, speed, direction, height, radius, gpstime);
942 }
943 #endif
944 }
945
946

   
Visit the ZANavi Wiki