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

Contents of /navit/navit/vehicle.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 27 - (hide annotations) (download)
Mon Apr 9 21:27:36 2012 UTC (12 years ago) by zoff99
File MIME type: text/plain
File size: 22947 byte(s)
lots of new stuff, tranlsations, bug fixes ...
1 zoff99 2 /**
2 zoff99 27 * 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 zoff99 2 * 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 "transform.h"
54     #include "projection.h"
55     #include "point.h"
56     #include "graphics.h"
57     #include "callback.h"
58     #include "color.h"
59     #include "layout.h"
60     #include "vehicle.h"
61    
62 zoff99 27 struct vehicle
63     {
64 zoff99 2 struct vehicle_methods meth;
65     struct vehicle_priv *priv;
66     struct callback_list *cbl;
67     struct log *nmea_log, *gpx_log;
68     char *gpx_desc;
69     struct attr **attrs;
70    
71     // cursor
72     struct cursor *cursor;
73     int cursor_fixed;
74     struct callback *animate_callback;
75     struct event_timeout *animate_timer;
76     struct point cursor_pnt;
77     struct graphics *gra;
78     struct graphics_gc *bg;
79     struct transformation *trans;
80     int angle;
81     int speed;
82     int sequence;
83     GHashTable *log_to_cb;
84     };
85    
86     static void vehicle_draw_do(struct vehicle *this_, int lazy);
87     static void vehicle_log_nmea(struct vehicle *this_, struct log *log);
88     static void vehicle_log_gpx(struct vehicle *this_, struct log *log);
89     static void vehicle_log_textfile(struct vehicle *this_, struct log *log);
90     static void vehicle_log_binfile(struct vehicle *this_, struct log *log);
91     static int vehicle_add_log(struct vehicle *this_, struct log *log);
92 zoff99 27 void vehicle_remove_cursor(struct vehicle *this_);
93 zoff99 2
94     /**
95     * Creates a new vehicle
96     */
97     struct vehicle *
98     vehicle_new(struct attr *parent, struct attr **attrs)
99     {
100     struct vehicle *this_;
101     struct attr *source;
102 zoff99 27 struct vehicle_priv *(*vehicletype_new)(struct vehicle_methods * meth, struct callback_list * cbl, struct attr ** attrs);
103 zoff99 2 char *type, *colon;
104     struct pcoord center;
105    
106 zoff99 27 //DBG dbg(0, "enter\n");
107 zoff99 2 source = attr_search(attrs, NULL, attr_source);
108 zoff99 27 if (!source)
109     {
110     //DBG dbg(0, "no source\n");
111 zoff99 2 return NULL;
112     }
113    
114     type = g_strdup(source->u.str);
115     colon = strchr(type, ':');
116     if (colon)
117 zoff99 27 {
118 zoff99 2 *colon = '\0';
119 zoff99 27 }
120     ////DBG dbg(0, "source='%s' type='%s'\n", source->u.str, type);
121 zoff99 2
122     vehicletype_new = plugin_get_vehicle_type(type);
123 zoff99 27 if (!vehicletype_new)
124     {
125     //DBG dbg(0, "invalid type '%s'\n", type);
126 zoff99 2 g_free(type);
127     return NULL;
128     }
129     g_free(type);
130     this_ = g_new0(struct vehicle, 1);
131     this_->cbl = callback_list_new();
132     this_->priv = vehicletype_new(&this_->meth, this_->cbl, attrs);
133 zoff99 27 //DBG dbg(0, "veh new 2\n");
134     if (!this_->priv)
135     {
136     //DBG dbg(0, "vehicletype_new failed\n");
137 zoff99 2 callback_list_destroy(this_->cbl);
138     g_free(this_);
139     return NULL;
140     }
141 zoff99 27 //DBG dbg(0, "veh new 3\n");
142     this_->attrs = attr_list_dup(attrs);
143     //DBG dbg(0, "veh new 4\n");
144     this_->trans = transform_new();
145 zoff99 2
146     // set bad 0/0 location ??? i dont know really
147     /*
148 zoff99 27 struct coord_geo g;
149     struct coord co;
150     enum projection pro=projection_mg;
151     g.lat=53.13;
152     g.lng=11.70;
153     transform_from_geo(pro, &g, &co);
154     center.x=co.x;
155     center.y=co.y;
156     center.pro = pro;
157     */
158 zoff99 2
159 zoff99 27 center.pro = projection_screen;
160     center.x = 0;
161     center.y = 0;
162     //DBG dbg(0, "veh new 5\n");
163 zoff99 2 transform_setup(this_->trans, &center, 16, 0);
164 zoff99 27 //DBG dbg(0, "veh new 6\n");
165 zoff99 2
166 zoff99 27 this_->log_to_cb = g_hash_table_new(NULL, NULL);
167     //DBG dbg(0, "leave\n");
168 zoff99 2 return this_;
169     }
170    
171     /**
172     * Destroys a vehicle
173     *
174     * @param this_ The vehicle to destroy
175     */
176 zoff99 27 void vehicle_destroy(struct vehicle *this_)
177 zoff99 2 {
178 zoff99 27 if (this_->animate_callback)
179     {
180 zoff99 2 callback_destroy(this_->animate_callback);
181     event_remove_timeout(this_->animate_timer);
182     }
183     transform_destroy(this_->trans);
184     this_->meth.destroy(this_->priv);
185     callback_list_destroy(this_->cbl);
186     attr_list_free(this_->attrs);
187     if (this_->bg)
188     graphics_gc_destroy(this_->bg);
189     if (this_->gra)
190     graphics_free(this_->gra);
191     g_free(this_);
192     }
193    
194     /**
195     * Creates an attribute iterator to be used with vehicles
196     */
197     struct attr_iter *
198     vehicle_attr_iter_new(void)
199     {
200 zoff99 27 return (struct attr_iter *)g_new0(void *,1);
201 zoff99 2 }
202    
203     /**
204     * Destroys a vehicle attribute iterator
205     *
206     * @param iter a vehicle attr_iter
207     */
208 zoff99 27 void vehicle_attr_iter_destroy(struct attr_iter *iter)
209 zoff99 2 {
210     g_free(iter);
211     }
212    
213     /**
214     * Generic get function
215     *
216     * @param this_ Pointer to a vehicle structure
217     * @param type The attribute type to look for
218     * @param attr Pointer to an attr structure to store the attribute
219     * @param iter A vehicle attr_iter
220     */
221 zoff99 27 int vehicle_get_attr(struct vehicle *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
222 zoff99 2 {
223 zoff99 27 ////DBG dbg(0,"enter\n");
224 zoff99 2 int ret;
225 zoff99 27 if (this_->meth.position_attr_get)
226     {
227     ret = this_->meth.position_attr_get(this_->priv, type, attr);
228 zoff99 2 if (ret)
229     return ret;
230     }
231 zoff99 27 if (type == attr_log_gpx_desc)
232     {
233 zoff99 2 attr->u.str = this_->gpx_desc;
234     return 1;
235     }
236 zoff99 27 ////DBG dbg(0,"before return\n");
237 zoff99 2 return attr_generic_get_attr(this_->attrs, NULL, type, attr, iter);
238     }
239    
240     /**
241     * Generic set function
242     *
243     * @param this_ Pointer to a vehicle structure
244     * @param attr Pointer to an attr structure for the attribute to be set
245     * @return nonzero on success, zero on failure
246     */
247 zoff99 27 int vehicle_set_attr(struct vehicle *this_, struct attr *attr)
248 zoff99 2 {
249 zoff99 27 int ret = 1;
250 zoff99 2 if (this_->meth.set_attr)
251 zoff99 27 ret = this_->meth.set_attr(this_->priv, attr);
252     if (ret == 1 && attr->type == attr_log_gpx_desc)
253     {
254 zoff99 2 g_free(this_->gpx_desc);
255     this_->gpx_desc = attr->u.str;
256     }
257     if (ret == 1 && attr->type != attr_navit && attr->type != attr_pdl_gps_update)
258 zoff99 27 this_->attrs = attr_generic_set_attr(this_->attrs, attr);
259 zoff99 2 return ret != 0;
260     }
261    
262     /**
263     * Generic add function
264     *
265     * @param this_ A vehicle
266     * @param attr A struct attr
267     */
268 zoff99 27 int vehicle_add_attr(struct vehicle *this_, struct attr *attr)
269 zoff99 2 {
270 zoff99 27 int ret = 1;
271     switch (attr->type)
272     {
273     case attr_callback:
274     callback_list_add(this_->cbl, attr->u.callback);
275     break;
276     case attr_log:
277     ret = vehicle_add_log(this_, attr->u.log);
278     break;
279     // currently supporting oldstyle cursor config.
280     case attr_cursor:
281     this_->cursor_fixed = 1;
282     vehicle_set_cursor(this_, attr->u.cursor, 1);
283     break;
284     default:
285     break;
286 zoff99 2 }
287     if (ret)
288 zoff99 27 this_->attrs = attr_generic_add_attr(this_->attrs, attr);
289 zoff99 2 return ret;
290     }
291    
292     /**
293     * @brief Generic remove function.
294     *
295     * Used to remove a callback from the vehicle.
296     * @param this_ A vehicle
297     * @param attr
298     */
299 zoff99 27 int vehicle_remove_attr(struct vehicle *this_, struct attr *attr)
300 zoff99 2 {
301     struct callback *cb;
302 zoff99 27 switch (attr->type)
303     {
304     case attr_callback:
305     callback_list_remove(this_->cbl, attr->u.callback);
306     break;
307     case attr_log:
308     cb = g_hash_table_lookup(this_->log_to_cb, attr->u.log);
309     if (!cb)
310     return 0;
311     g_hash_table_remove(this_->log_to_cb, attr->u.log);
312     callback_list_remove(this_->cbl, cb);
313     break;
314     case attr_cursor:
315     vehicle_remove_cursor(this_);
316     break;
317     default:
318     this_->attrs = attr_generic_remove_attr(this_->attrs, attr);
319 zoff99 2 return 0;
320     }
321     return 1;
322     }
323    
324     /**
325     * Sets the cursor of a vehicle.
326     *
327     * @param this_ A vehicle
328     * @param cursor A cursor
329     * @author Ralph Sennhauser (10/2009)
330 zoff99 27 */
331     void vehicle_set_cursor(struct vehicle *this_, struct cursor *cursor, int overwrite)
332 zoff99 2 {
333     struct point sc;
334     if (this_->cursor_fixed && !overwrite)
335 zoff99 27 {
336 zoff99 2 return;
337 zoff99 27 }
338     if (this_->animate_callback)
339     {
340 zoff99 2 event_remove_timeout(this_->animate_timer);
341 zoff99 27 this_->animate_timer = NULL; // dangling pointer! prevent double freeing.
342 zoff99 2 callback_destroy(this_->animate_callback);
343 zoff99 27 this_->animate_callback = NULL; // dangling pointer! prevent double freeing.
344 zoff99 2 }
345 zoff99 27 if (cursor && cursor->interval)
346     {
347     this_->animate_callback = callback_new_2(callback_cast(vehicle_draw_do), this_, 0);
348     dbg(0, "event_add_timeout %d,%d,%p", cursor->interval, 1, this_->animate_callback);
349     this_->animate_timer = event_add_timeout(cursor->interval, 1, this_->animate_callback);
350 zoff99 2 }
351    
352 zoff99 27 if (cursor && this_->gra && this_->cursor)
353     {
354     this_->cursor_pnt.x += (this_->cursor->w - cursor->w) / 2;
355     this_->cursor_pnt.y += (this_->cursor->h - cursor->h) / 2;
356 zoff99 2 graphics_overlay_resize(this_->gra, &this_->cursor_pnt, cursor->w, cursor->h, 65535, 0);
357     }
358    
359 zoff99 27 if (cursor)
360     {
361     sc.x = cursor->w / 2;
362     sc.y = cursor->h / 2;
363 zoff99 2 if (!this_->cursor && this_->gra)
364     graphics_overlay_disable(this_->gra, 0);
365 zoff99 27 }
366     else
367     {
368     sc.x = sc.y = 0;
369 zoff99 2 if (this_->cursor && this_->gra)
370     graphics_overlay_disable(this_->gra, 1);
371     }
372     transform_set_screen_center(this_->trans, &sc);
373    
374 zoff99 27 this_->cursor = cursor;
375 zoff99 2 }
376    
377 zoff99 27 void vehicle_remove_cursor(struct vehicle *this_)
378     {
379     struct point sc;
380    
381     if (this_->animate_callback)
382     {
383     event_remove_timeout(this_->animate_timer);
384     this_->animate_timer = NULL; // dangling pointer! prevent double freeing.
385     callback_destroy(this_->animate_callback);
386     this_->animate_callback = NULL; // dangling pointer! prevent double freeing.
387     }
388    
389     if (this_->cursor && this_->gra)
390     {
391     }
392    
393     if (this_->cursor && this_->gra)
394     {
395     graphics_overlay_disable(this_->gra, 1);
396     }
397    
398     this_->cursor = NULL;
399     }
400    
401 zoff99 2 /**
402     * Draws a vehicle on top of a graphics.
403     *
404     * @param this_ The vehicle
405     * @param gra The graphics
406     * @param pnt Screen coordinates of the vehicle.
407     * @param lazy use lazy draw mode.
408     * @param angle The angle relative to the map.
409     * @param speed The speed of the vehicle.
410     */
411 zoff99 27 void vehicle_draw(struct vehicle *this_, struct graphics *gra, struct point *pnt, int lazy, int angle, int speed)
412 zoff99 2 {
413     if (angle < 0)
414 zoff99 27 angle += 360;
415     //// dbg(1, "enter this=%p gra=%p pnt=%p lazy=%d dir=%d speed=%d\n", this_, gra,
416     // pnt, lazy, angle, speed);
417     //// dbg(1, "point %d,%d\n", pnt->x, pnt->y);
418     this_->cursor_pnt = *pnt;
419     this_->angle = angle;
420     this_->speed = speed;
421 zoff99 2 if (!this_->cursor)
422     return;
423 zoff99 27 this_->cursor_pnt.x -= this_->cursor->w / 2;
424     this_->cursor_pnt.y -= this_->cursor->h / 2;
425     if (!this_->gra)
426     {
427 zoff99 2 struct color c;
428 zoff99 27 this_->gra = graphics_overlay_new(gra, &this_->cursor_pnt, this_->cursor->w, this_->cursor->h, 65535, 0);
429     if (this_->gra)
430     {
431     this_->bg = graphics_gc_new(this_->gra);
432     c.r = 0;
433     c.g = 0;
434     c.b = 0;
435     c.a = 0;
436 zoff99 2 graphics_gc_set_foreground(this_->bg, &c);
437     graphics_background_gc(this_->gra, this_->bg);
438     }
439     }
440     vehicle_draw_do(this_, lazy);
441     }
442    
443 zoff99 27 int vehicle_get_cursor_data(struct vehicle *this, struct point *pnt, int *angle, int *speed)
444 zoff99 2 {
445 zoff99 27 *pnt = this->cursor_pnt;
446     *angle = this->angle;
447     *speed = this->speed;
448 zoff99 2 return 1;
449     }
450    
451 zoff99 27 static void vehicle_draw_do(struct vehicle *this_, int lazy)
452 zoff99 2 {
453     struct point p;
454 zoff99 27 struct cursor *cursor = this_->cursor;
455     int speed = this_->speed;
456     int angle = this_->angle;
457     int sequence = this_->sequence;
458 zoff99 2 struct attr **attr;
459 zoff99 27 char *label = NULL;
460     int match = 0;
461 zoff99 2
462     if (!this_->cursor || !this_->cursor->attrs || !this_->gra)
463     return;
464    
465 zoff99 27 attr = this_->attrs;
466     while (attr && *attr)
467     {
468     if ((*attr)->type == attr_name)
469     label = (*attr)->u.str;
470 zoff99 2 attr++;
471     }
472     transform_set_yaw(this_->trans, -this_->angle);
473     graphics_draw_mode(this_->gra, draw_mode_begin);
474 zoff99 27 p.x = 0;
475     p.y = 0;
476 zoff99 2 graphics_draw_rectangle(this_->gra, this_->bg, &p, cursor->w, cursor->h);
477 zoff99 27 attr = cursor->attrs;
478     while (*attr)
479     {
480     if ((*attr)->type == attr_itemgra)
481     {
482     struct itemgra *itm = (*attr)->u.itemgra;
483     //// dbg(1, "speed %d-%d %d\n", itm->speed_range.min,
484     // itm->speed_range.max, speed);
485     if (speed >= itm->speed_range.min && speed <= itm->speed_range.max && angle >= itm->angle_range.min && angle <= itm->angle_range.max && sequence >= itm->sequence_range.min && sequence <= itm->sequence_range.max)
486     {
487 zoff99 2 graphics_draw_itemgra(this_->gra, itm, this_->trans, label);
488     }
489     if (sequence < itm->sequence_range.max)
490 zoff99 27 match = 1;
491 zoff99 2 }
492     ++attr;
493     }
494     graphics_draw_drag(this_->gra, &this_->cursor_pnt);
495     graphics_draw_mode(this_->gra, lazy ? draw_mode_end_lazy : draw_mode_end);
496 zoff99 27 if (this_->animate_callback)
497     {
498 zoff99 2 ++this_->sequence;
499     if (cursor->sequence_range && cursor->sequence_range->max < this_->sequence)
500 zoff99 27 this_->sequence = cursor->sequence_range->min;
501     if (!match && !cursor->sequence_range)
502     this_->sequence = 0;
503 zoff99 2 }
504     }
505    
506     /**
507     * Writes to an NMEA log.
508     *
509     * @param this_ Pointer to the vehicle structure of the data source
510     * @param log Pointer to a log structure for the log file
511     */
512 zoff99 27 static void vehicle_log_nmea(struct vehicle *this_, struct log *log)
513 zoff99 2 {
514     struct attr pos_attr;
515     if (!this_->meth.position_attr_get)
516     return;
517     if (!this_->meth.position_attr_get(this_->priv, attr_position_nmea, &pos_attr))
518     return;
519     log_write(log, pos_attr.u.str, strlen(pos_attr.u.str), 0);
520     }
521    
522 zoff99 27 void vehicle_log_gpx_add_tag(char *tag, char **logstr)
523 zoff99 2 {
524 zoff99 27 char *ext_start = "\t<extensions>\n";
525     char *ext_end = "\t</extensions>\n";
526     char *trkpt_end = "</trkpt>";
527     char *start = NULL, *end = NULL;
528     if (!*logstr)
529     {
530     start = g_strdup(ext_start);
531     end = g_strdup(ext_end);
532     }
533     else
534     {
535     char *str = strstr(*logstr, ext_start);
536 zoff99 2 int len;
537 zoff99 27 if (str)
538     {
539     len = str - *logstr + strlen(ext_start);
540     start = g_strdup(*logstr);
541     start[len] = '\0';
542     end = g_strdup(str + strlen(ext_start));
543     }
544     else
545     {
546     str = strstr(*logstr, trkpt_end);
547     len = str - *logstr;
548     end = g_strdup_printf("%s%s", ext_end, str);
549     str = g_strdup(*logstr);
550     str[len] = '\0';
551     start = g_strdup_printf("%s%s", str, ext_start);
552 zoff99 2 g_free(str);
553     }
554     }
555 zoff99 27 *logstr = g_strdup_printf("%s%s%s", start, tag, end);
556 zoff99 2 g_free(start);
557     g_free(end);
558     }
559    
560     /**
561     * Writes to a GPX log.
562     *
563     * @param this_ Pointer to the vehicle structure of the data source
564     * @param log Pointer to a log structure for the log file
565     */
566 zoff99 27 static void vehicle_log_gpx(struct vehicle *this_, struct log *log)
567 zoff99 2 {
568 zoff99 27 struct attr attr, *attrp, fix_attr;
569 zoff99 2 enum attr_type *attr_types;
570     char *logstr;
571 zoff99 27 char *extensions = "\t<extensions>\n";
572 zoff99 2
573     if (!this_->meth.position_attr_get)
574     return;
575     if (log_get_attr(log, attr_attr_types, &attr, NULL))
576 zoff99 27 attr_types = attr.u.attr_types;
577 zoff99 2 else
578 zoff99 27 attr_types = NULL;
579     if (this_->meth.position_attr_get(this_->priv, attr_position_fix_type, &fix_attr))
580     {
581     if (fix_attr.u.num == 0)
582     return;
583 zoff99 2 }
584     if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &attr))
585     return;
586 zoff99 27 logstr = g_strdup_printf("<trkpt lat=\"%f\" lon=\"%f\">\n", attr.u.coord_geo->lat, attr.u.coord_geo->lng);
587     if (attr_types && attr_types_contains_default(attr_types, attr_position_time_iso8601, 0))
588     {
589     if (this_->meth.position_attr_get(this_->priv, attr_position_time_iso8601, &attr))
590     {
591     logstr = g_strconcat_printf(logstr, "\t<time>%s</time>\n", attr.u.str);
592     }
593     else
594     {
595 zoff99 2 char *timep = current_to_iso8601();
596 zoff99 27 logstr = g_strconcat_printf(logstr, "\t<time>%s</time>\n", timep);
597 zoff99 2 g_free(timep);
598     }
599     }
600 zoff99 27 if (this_->gpx_desc)
601     {
602     logstr = g_strconcat_printf(logstr, "\t<desc>%s</desc>\n", this_->gpx_desc);
603 zoff99 2 g_free(this_->gpx_desc);
604     this_->gpx_desc = NULL;
605     }
606 zoff99 27 if (attr_types_contains_default(attr_types, attr_position_height, 0) && this_->meth.position_attr_get(this_->priv, attr_position_height, &attr))
607     logstr = g_strconcat_printf(logstr, "\t<ele>%.6f</ele>\n", *attr.u.numd);
608 zoff99 2 // <magvar> magnetic variation in degrees; we might use position_magnetic_direction and position_direction to figure it out
609     // <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)
610     // <name> GPS name (arbitrary)
611     // <cmt> comment
612     // <src> Source of data
613     // <link> Link to additional information (URL)
614     // <sym> Text of GPS symbol name
615     // <type> Type (classification)
616     // <fix> Type of GPS fix {'none'|'2d'|'3d'|'dgps'|'pps'}, leave out if unknown. Similar to position_fix_type but more detailed.
617 zoff99 27 if (attr_types_contains_default(attr_types, attr_position_sats_used, 0) && this_->meth.position_attr_get(this_->priv, attr_position_sats_used, &attr))
618     logstr = g_strconcat_printf(logstr, "\t<sat>%d</sat>\n", attr.u.num);
619     if (attr_types_contains_default(attr_types, attr_position_hdop, 0) && this_->meth.position_attr_get(this_->priv, attr_position_hdop, &attr))
620     logstr = g_strconcat_printf(logstr, "\t<hdop>%.6f</hdop>\n", *attr.u.numd);
621 zoff99 2 // <vdop>, <pdop> Vertical and position dilution of precision, no corresponding attribute
622 zoff99 27 if (attr_types_contains_default(attr_types, attr_position_direction, 0) && this_->meth.position_attr_get(this_->priv, attr_position_direction, &attr))
623     logstr = g_strconcat_printf(logstr, "\t<course>%.1f</course>\n", *attr.u.numd);
624 zoff99 2 if (attr_types_contains_default(attr_types, attr_position_speed, 0) && this_->meth.position_attr_get(this_->priv, attr_position_speed, &attr))
625 zoff99 27 logstr = g_strconcat_printf(logstr, "\t<speed>%.2f</speed>\n", (*attr.u.numd / 3.6));
626     if (attr_types_contains_default(attr_types, attr_profilename, 0) && (attrp = attr_search(this_->attrs, NULL, attr_profilename)))
627     {
628     logstr = g_strconcat_printf(logstr, "%s\t\t<navit:profilename>%s</navit:profilename>\n", extensions, attrp->u.str);
629     extensions = "";
630 zoff99 2 }
631 zoff99 27 if (attr_types_contains_default(attr_types, attr_position_radius, 0) && this_->meth.position_attr_get(this_->priv, attr_position_radius, &attr))
632     {
633     logstr = g_strconcat_printf(logstr, "%s\t\t<navit:radius>%.2f</navit:radius>\n", extensions, *attr.u.numd);
634     extensions = "";
635 zoff99 2 }
636 zoff99 27 if (!strcmp(extensions, ""))
637     {
638     logstr = g_strconcat_printf(logstr, "\t</extensions>\n");
639 zoff99 2 }
640 zoff99 27 logstr = g_strconcat_printf(logstr, "</trkpt>\n");
641 zoff99 2 callback_list_call_attr_1(this_->cbl, attr_log_gpx, &logstr);
642     log_write(log, logstr, strlen(logstr), 0);
643     g_free(logstr);
644     }
645    
646     /**
647     * Writes to a text log.
648     *
649     * @param this_ Pointer to the vehicle structure of the data source
650     * @param log Pointer to a log structure for the log file
651     */
652 zoff99 27 static void vehicle_log_textfile(struct vehicle *this_, struct log *log)
653 zoff99 2 {
654 zoff99 27 struct attr pos_attr, fix_attr;
655 zoff99 2 char *logstr;
656     if (!this_->meth.position_attr_get)
657     return;
658 zoff99 27 if (this_->meth.position_attr_get(this_->priv, attr_position_fix_type, &fix_attr))
659     {
660     if (fix_attr.u.num == 0)
661     return;
662 zoff99 2 }
663     if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr))
664     return;
665 zoff99 27 logstr = g_strdup_printf("%f %f type=trackpoint\n", pos_attr.u.coord_geo->lng, pos_attr.u.coord_geo->lat);
666 zoff99 2 callback_list_call_attr_1(this_->cbl, attr_log_textfile, &logstr);
667     log_write(log, logstr, strlen(logstr), 0);
668     }
669    
670     /**
671     * Writes to a binary log.
672     *
673     * @param this_ Pointer to the vehicle structure of the data source
674     * @param log Pointer to a log structure for the log file
675     */
676 zoff99 27 static void vehicle_log_binfile(struct vehicle *this_, struct log *log)
677 zoff99 2 {
678     struct attr pos_attr, fix_attr;
679     int *buffer;
680     int *buffer_new;
681 zoff99 27 int len, limit = 1024, done = 0, radius = 25;
682 zoff99 2 struct coord c;
683     enum log_flags flags;
684    
685     if (!this_->meth.position_attr_get)
686     return;
687 zoff99 27 if (this_->meth.position_attr_get(this_->priv, attr_position_fix_type, &fix_attr))
688     {
689     if (fix_attr.u.num == 0)
690     return;
691 zoff99 2 }
692     if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr))
693     return;
694     transform_from_geo(projection_mg, pos_attr.u.coord_geo, &c);
695     if (!c.x || !c.y)
696     return;
697 zoff99 27 while (!done)
698     {
699     buffer = log_get_buffer(log, &len);
700     if (!buffer || !len)
701     {
702     buffer_new = g_malloc(5 * sizeof(int));
703     buffer_new[0] = 2;
704     buffer_new[1] = type_track;
705     buffer_new[2] = 0;
706 zoff99 2 }
707 zoff99 27 else
708     {
709     buffer_new = g_malloc((buffer[0] + 3) * sizeof(int));
710     memcpy(buffer_new, buffer, (buffer[0] + 1) * sizeof(int));
711 zoff99 2 }
712 zoff99 27 //// dbg(1, "c=0x%x,0x%x\n", c.x, c.y);
713     buffer_new[buffer_new[0] + 1] = c.x;
714     buffer_new[buffer_new[0] + 2] = c.y;
715     buffer_new[0] += 2;
716     buffer_new[2] += 2;
717     if (buffer_new[2] > limit)
718     {
719     int count = buffer_new[2] / 2;
720     struct coord *out = g_alloca(sizeof(struct coord) * (count));
721     struct coord *in = (struct coord *) (buffer_new + 3);
722     int count_out = transform_douglas_peucker(in, count, radius, out);
723     memcpy(in, out, count_out * 2 * sizeof(int));
724     buffer_new[0] += (count_out - count) * 2;
725     buffer_new[2] += (count_out - count) * 2;
726     flags = log_flag_replace_buffer | log_flag_force_flush | log_flag_truncate;
727     }
728     else
729     {
730     flags = log_flag_replace_buffer | log_flag_keep_pointer | log_flag_keep_buffer | log_flag_force_flush;
731     done = 1;
732     }
733     log_write(log, (char *) buffer_new, (buffer_new[0] + 1) * sizeof(int), flags);
734 zoff99 2 }
735     }
736    
737     /**
738     * Register a new log to receive data.
739     *
740     * @param this_ Pointer to the vehicle structure of the data source
741     * @param log Pointer to a log structure for the log file
742     */
743 zoff99 27 static int vehicle_add_log(struct vehicle *this_, struct log *log)
744 zoff99 2 {
745     struct callback *cb;
746     struct attr type_attr;
747     if (!log_get_attr(log, attr_type, &type_attr, NULL))
748 zoff99 27 return 1;
749 zoff99 2
750 zoff99 27 if (!strcmp(type_attr.u.str, "nmea"))
751     {
752     cb = callback_new_attr_2(callback_cast(vehicle_log_nmea), attr_position_coord_geo, this_, log);
753     }
754     else if (!strcmp(type_attr.u.str, "gpx"))
755     {
756 zoff99 2 char *header = "<?xml version='1.0' encoding='UTF-8'?>\n"
757     "<gpx version='1.1' creator='Navit http://navit.sourceforge.net'\n"
758     " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"
759     " xmlns:navit='http://www.navit-project.org/schema/navit'\n"
760     " xmlns='http://www.topografix.com/GPX/1/1'\n"
761     " xsi:schemaLocation='http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'>\n"
762     "<trk>\n"
763     "<trkseg>\n";
764     char *trailer = "</trkseg>\n</trk>\n</gpx>\n";
765     log_set_header(log, header, strlen(header));
766     log_set_trailer(log, trailer, strlen(trailer));
767 zoff99 27 cb = callback_new_attr_2(callback_cast(vehicle_log_gpx), attr_position_coord_geo, this_, log);
768     }
769     else if (!strcmp(type_attr.u.str, "textfile"))
770     {
771 zoff99 2 char *header = "type=track\n";
772     log_set_header(log, header, strlen(header));
773 zoff99 27 cb = callback_new_attr_2(callback_cast(vehicle_log_textfile), attr_position_coord_geo, this_, log);
774     }
775     else if (!strcmp(type_attr.u.str, "binfile"))
776     {
777     cb = callback_new_attr_2(callback_cast(vehicle_log_binfile), attr_position_coord_geo, this_, log);
778     }
779     else
780 zoff99 2 return 1;
781     g_hash_table_insert(this_->log_to_cb, log, cb);
782     callback_list_add(this_->cbl, cb);
783     return 0;
784     }
785    

   
Visit the ZANavi Wiki