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

Contents of /navit/navit/vehicle.c

Parent Directory Parent Directory | Revision Log Revision Log


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

   
Visit the ZANavi Wiki