diff options
Diffstat (limited to 'navit/vehicle.c')
-rw-r--r-- | navit/vehicle.c | 1015 |
1 files changed, 503 insertions, 512 deletions
diff --git a/navit/vehicle.c b/navit/vehicle.c index 61ada2059..b63d08a15 100644 --- a/navit/vehicle.c +++ b/navit/vehicle.c @@ -16,12 +16,12 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ - + /** @file vehicle.c * @defgroup vehicle-plugins vehicle plugins * @ingroup plugins * @brief Generic components of the vehicle object. - * + * * This file implements the generic vehicle interface, i.e. everything which is * not specific to a single data source. * @@ -56,26 +56,26 @@ struct vehicle { - NAVIT_OBJECT - struct vehicle_methods meth; - struct vehicle_priv *priv; - struct callback_list *cbl; - struct log *nmea_log, *gpx_log; - char *gpx_desc; - - // cursor - struct cursor *cursor; - int cursor_fixed; - struct callback *animate_callback; - struct event_timeout *animate_timer; - struct point cursor_pnt; - struct graphics *gra; - struct graphics_gc *bg; - struct transformation *trans; - int angle; - int speed; - int sequence; - GHashTable *log_to_cb; + NAVIT_OBJECT + struct vehicle_methods meth; + struct vehicle_priv *priv; + struct callback_list *cbl; + struct log *nmea_log, *gpx_log; + char *gpx_desc; + + // cursor + struct cursor *cursor; + int cursor_fixed; + struct callback *animate_callback; + struct event_timeout *animate_timer; + struct point cursor_pnt; + struct graphics *gra; + struct graphics_gc *bg; + struct transformation *trans; + int angle; + int speed; + int sequence; + GHashTable *log_to_cb; }; struct object_func vehicle_func; @@ -100,93 +100,90 @@ static int vehicle_add_log(struct vehicle *this_, struct log *log); * @return The newly created vehicle object */ struct vehicle * -vehicle_new(struct attr *parent, struct attr **attrs) -{ - struct vehicle *this_; - struct attr *source; - struct vehicle_priv *(*vehicletype_new) (struct vehicle_methods * - meth, - struct callback_list * - cbl, - struct attr ** attrs); - char *type, *colon; - struct pcoord center; - - dbg(lvl_debug, "enter"); - source = attr_search(attrs, NULL, attr_source); - if (!source) { - dbg(lvl_error, "incomplete vehicle definition: missing attribute 'source'"); - return NULL; - } - - type = g_strdup(source->u.str); - colon = strchr(type, ':'); - if (colon) - *colon = '\0'; - dbg(lvl_debug, "source='%s' type='%s'", source->u.str, type); - - vehicletype_new = plugin_get_category_vehicle(type); - if (!vehicletype_new) { - dbg(lvl_error, "invalid source '%s': unknown type '%s'", source->u.str, type); - g_free(type); - return NULL; - } - g_free(type); - this_ = g_new0(struct vehicle, 1); - this_->func=&vehicle_func; - navit_object_ref((struct navit_object *)this_); - this_->cbl = callback_list_new(); - this_->priv = vehicletype_new(&this_->meth, this_->cbl, attrs); - if (!this_->priv) { - dbg(lvl_error, "vehicletype_new failed"); - callback_list_destroy(this_->cbl); - g_free(this_); - return NULL; - } - this_->attrs=attr_list_dup(attrs); - - center.pro=projection_screen; - center.x=0; - center.y=0; - this_->trans=transform_new(¢er, 16, 0); - vehicle_set_default_name(this_); - - dbg(lvl_debug, "leave"); - this_->log_to_cb=g_hash_table_new(NULL,NULL); - return this_; +vehicle_new(struct attr *parent, struct attr **attrs) { + struct vehicle *this_; + struct attr *source; + struct vehicle_priv *(*vehicletype_new) (struct vehicle_methods * + meth, + struct callback_list * + cbl, + struct attr ** attrs); + char *type, *colon; + struct pcoord center; + + dbg(lvl_debug, "enter"); + source = attr_search(attrs, NULL, attr_source); + if (!source) { + dbg(lvl_error, "incomplete vehicle definition: missing attribute 'source'"); + return NULL; + } + + type = g_strdup(source->u.str); + colon = strchr(type, ':'); + if (colon) + *colon = '\0'; + dbg(lvl_debug, "source='%s' type='%s'", source->u.str, type); + + vehicletype_new = plugin_get_category_vehicle(type); + if (!vehicletype_new) { + dbg(lvl_error, "invalid source '%s': unknown type '%s'", source->u.str, type); + g_free(type); + return NULL; + } + g_free(type); + this_ = g_new0(struct vehicle, 1); + this_->func=&vehicle_func; + navit_object_ref((struct navit_object *)this_); + this_->cbl = callback_list_new(); + this_->priv = vehicletype_new(&this_->meth, this_->cbl, attrs); + if (!this_->priv) { + dbg(lvl_error, "vehicletype_new failed"); + callback_list_destroy(this_->cbl); + g_free(this_); + return NULL; + } + this_->attrs=attr_list_dup(attrs); + + center.pro=projection_screen; + center.x=0; + center.y=0; + this_->trans=transform_new(¢er, 16, 0); + vehicle_set_default_name(this_); + + dbg(lvl_debug, "leave"); + this_->log_to_cb=g_hash_table_new(NULL,NULL); + return this_; } /** * @brief Destroys a vehicle - * + * * @param this_ The vehicle to destroy */ void -vehicle_destroy(struct vehicle *this_) -{ - dbg(lvl_debug,"enter"); - if (this_->animate_callback) { - callback_destroy(this_->animate_callback); - event_remove_timeout(this_->animate_timer); - } - transform_destroy(this_->trans); - this_->meth.destroy(this_->priv); - callback_list_destroy(this_->cbl); - attr_list_free(this_->attrs); - if (this_->bg) - graphics_gc_destroy(this_->bg); - if (this_->gra) - graphics_free(this_->gra); - g_free(this_); +vehicle_destroy(struct vehicle *this_) { + dbg(lvl_debug,"enter"); + if (this_->animate_callback) { + callback_destroy(this_->animate_callback); + event_remove_timeout(this_->animate_timer); + } + transform_destroy(this_->trans); + this_->meth.destroy(this_->priv); + callback_list_destroy(this_->cbl); + attr_list_free(this_->attrs); + if (this_->bg) + graphics_gc_destroy(this_->bg); + if (this_->gra) + graphics_free(this_->gra); + g_free(this_); } /** * Creates an attribute iterator to be used with vehicles */ struct attr_iter * -vehicle_attr_iter_new(void) -{ - return (struct attr_iter *)g_new0(void *,1); +vehicle_attr_iter_new(void) { + return (struct attr_iter *)g_new0(void *,1); } /** @@ -195,9 +192,8 @@ vehicle_attr_iter_new(void) * @param iter a vehicle attr_iter */ void -vehicle_attr_iter_destroy(struct attr_iter *iter) -{ - g_free(iter); +vehicle_attr_iter_destroy(struct attr_iter *iter) { + g_free(iter); } @@ -212,19 +208,18 @@ vehicle_attr_iter_destroy(struct attr_iter *iter) * @return True for success, false for failure */ int -vehicle_get_attr(struct vehicle *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter) -{ - int ret; - if (type == attr_log_gpx_desc) { - attr->u.str = this_->gpx_desc; - return 1; - } - if (this_->meth.position_attr_get) { - ret=this_->meth.position_attr_get(this_->priv, type, attr); - if (ret) - return ret; - } - return attr_generic_get_attr(this_->attrs, NULL, type, attr, iter); +vehicle_get_attr(struct vehicle *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter) { + int ret; + if (type == attr_log_gpx_desc) { + attr->u.str = this_->gpx_desc; + return 1; + } + if (this_->meth.position_attr_get) { + ret=this_->meth.position_attr_get(this_->priv, type, attr); + if (ret) + return ret; + } + return attr_generic_get_attr(this_->attrs, NULL, type, attr, iter); } /** @@ -235,21 +230,20 @@ vehicle_get_attr(struct vehicle *this_, enum attr_type type, struct attr *attr, * @return False on success, true on failure */ int -vehicle_set_attr(struct vehicle *this_, struct attr *attr) -{ - int ret=1; - if (attr->type == attr_log_gpx_desc) { - g_free(this_->gpx_desc); - this_->gpx_desc = g_strdup(attr->u.str); - } else if (this_->meth.set_attr) - ret=this_->meth.set_attr(this_->priv, attr); - /* attr_profilename probably is never used by vehicle itself but it's used to control the - routing engine. So any vehicle should allow to set and read it. */ - if(attr->type == attr_profilename) - ret=1; - if (ret == 1 && attr->type != attr_navit && attr->type != attr_pdl_gps_update) - this_->attrs=attr_generic_set_attr(this_->attrs, attr); - return ret != 0; +vehicle_set_attr(struct vehicle *this_, struct attr *attr) { + int ret=1; + if (attr->type == attr_log_gpx_desc) { + g_free(this_->gpx_desc); + this_->gpx_desc = g_strdup(attr->u.str); + } else if (this_->meth.set_attr) + ret=this_->meth.set_attr(this_->priv, attr); + /* attr_profilename probably is never used by vehicle itself but it's used to control the + routing engine. So any vehicle should allow to set and read it. */ + if(attr->type == attr_profilename) + ret=1; + if (ret == 1 && attr->type != attr_navit && attr->type != attr_pdl_gps_update) + this_->attrs=attr_generic_set_attr(this_->attrs, attr); + return ret != 0; } /** @@ -261,27 +255,26 @@ vehicle_set_attr(struct vehicle *this_, struct attr *attr) * @return true if the attribute was added, false if not. */ int -vehicle_add_attr(struct vehicle *this_, struct attr *attr) -{ - int ret=1; - switch (attr->type) { - case attr_callback: - callback_list_add(this_->cbl, attr->u.callback); - break; - case attr_log: - ret=vehicle_add_log(this_, attr->u.log); - break; - // currently supporting oldstyle cursor config. - case attr_cursor: - this_->cursor_fixed=1; - vehicle_set_cursor(this_, attr->u.cursor, 1); - break; - default: - break; - } - if (ret) - this_->attrs=attr_generic_add_attr(this_->attrs, attr); - return ret; +vehicle_add_attr(struct vehicle *this_, struct attr *attr) { + int ret=1; + switch (attr->type) { + case attr_callback: + callback_list_add(this_->cbl, attr->u.callback); + break; + case attr_log: + ret=vehicle_add_log(this_, attr->u.log); + break; + // currently supporting oldstyle cursor config. + case attr_cursor: + this_->cursor_fixed=1; + vehicle_set_cursor(this_, attr->u.cursor, 1); + break; + default: + break; + } + if (ret) + this_->attrs=attr_generic_add_attr(this_->attrs, attr); + return ret; } /** @@ -292,25 +285,24 @@ vehicle_add_attr(struct vehicle *this_, struct attr *attr) * @param attr */ int -vehicle_remove_attr(struct vehicle *this_, struct attr *attr) -{ - struct callback *cb; - switch (attr->type) { - case attr_callback: - callback_list_remove(this_->cbl, attr->u.callback); - break; - case attr_log: - cb=g_hash_table_lookup(this_->log_to_cb, attr->u.log); - if (!cb) - return 0; - g_hash_table_remove(this_->log_to_cb, attr->u.log); - callback_list_remove(this_->cbl, cb); - break; - default: - this_->attrs=attr_generic_remove_attr(this_->attrs, attr); - return 0; - } - return 1; +vehicle_remove_attr(struct vehicle *this_, struct attr *attr) { + struct callback *cb; + switch (attr->type) { + case attr_callback: + callback_list_remove(this_->cbl, attr->u.callback); + break; + case attr_log: + cb=g_hash_table_lookup(this_->log_to_cb, attr->u.log); + if (!cb) + return 0; + g_hash_table_remove(this_->log_to_cb, attr->u.log); + callback_list_remove(this_->cbl, cb); + break; + default: + this_->attrs=attr_generic_remove_attr(this_->attrs, attr); + return 0; + } + return 1; } @@ -321,43 +313,42 @@ vehicle_remove_attr(struct vehicle *this_, struct attr *attr) * @param this_ A vehicle * @param cursor A cursor * @author Ralph Sennhauser (10/2009) - */ + */ void -vehicle_set_cursor(struct vehicle *this_, struct cursor *cursor, int overwrite) -{ - struct point sc; - if (this_->cursor_fixed && !overwrite) - return; - if (this_->animate_callback) { - event_remove_timeout(this_->animate_timer); - this_->animate_timer=NULL; // dangling pointer! prevent double freeing. - callback_destroy(this_->animate_callback); - this_->animate_callback=NULL; // dangling pointer! prevent double freeing. - } - if (cursor && cursor->interval) { - this_->animate_callback=callback_new_2(callback_cast(vehicle_draw_do), this_, 0); - this_->animate_timer=event_add_timeout(cursor->interval, 1, this_->animate_callback); - } - - if (cursor && this_->gra && this_->cursor) { - this_->cursor_pnt.x+=(this_->cursor->w - cursor->w)/2; - this_->cursor_pnt.y+=(this_->cursor->h - cursor->h)/2; - graphics_overlay_resize(this_->gra, &this_->cursor_pnt, cursor->w, cursor->h, 0); - } - - if (cursor) { - sc.x=cursor->w/2; - sc.y=cursor->h/2; - if (!this_->cursor && this_->gra) - graphics_overlay_disable(this_->gra, 0); - } else { - sc.x=sc.y=0; - if (this_->cursor && this_->gra) - graphics_overlay_disable(this_->gra, 1); - } - transform_set_screen_center(this_->trans, &sc); - - this_->cursor=cursor; +vehicle_set_cursor(struct vehicle *this_, struct cursor *cursor, int overwrite) { + struct point sc; + if (this_->cursor_fixed && !overwrite) + return; + if (this_->animate_callback) { + event_remove_timeout(this_->animate_timer); + this_->animate_timer=NULL; // dangling pointer! prevent double freeing. + callback_destroy(this_->animate_callback); + this_->animate_callback=NULL; // dangling pointer! prevent double freeing. + } + if (cursor && cursor->interval) { + this_->animate_callback=callback_new_2(callback_cast(vehicle_draw_do), this_, 0); + this_->animate_timer=event_add_timeout(cursor->interval, 1, this_->animate_callback); + } + + if (cursor && this_->gra && this_->cursor) { + this_->cursor_pnt.x+=(this_->cursor->w - cursor->w)/2; + this_->cursor_pnt.y+=(this_->cursor->h - cursor->h)/2; + graphics_overlay_resize(this_->gra, &this_->cursor_pnt, cursor->w, cursor->h, 0); + } + + if (cursor) { + sc.x=cursor->w/2; + sc.y=cursor->h/2; + if (!this_->cursor && this_->gra) + graphics_overlay_disable(this_->gra, 0); + } else { + sc.x=sc.y=0; + if (this_->cursor && this_->gra) + graphics_overlay_disable(this_->gra, 1); + } + transform_set_screen_center(this_->trans, &sc); + + this_->cursor=cursor; } /** @@ -370,105 +361,104 @@ vehicle_set_cursor(struct vehicle *this_, struct cursor *cursor, int overwrite) * @param speed The speed of the vehicle. */ void -vehicle_draw(struct vehicle *this_, struct graphics *gra, struct point *pnt, int angle, int speed) -{ - if (angle < 0) - angle+=360; - dbg(lvl_debug,"enter this=%p gra=%p pnt=%p dir=%d speed=%d", this_, gra, pnt, angle, speed); - dbg(lvl_debug,"point %d,%d", pnt->x, pnt->y); - this_->cursor_pnt=*pnt; - this_->angle=angle; - this_->speed=speed; - if (!this_->cursor) - return; - this_->cursor_pnt.x-=this_->cursor->w/2; - this_->cursor_pnt.y-=this_->cursor->h/2; - if (!this_->gra) { - struct color c; - this_->gra=graphics_overlay_new(gra, &this_->cursor_pnt, this_->cursor->w, this_->cursor->h, 0); - if (this_->gra) { - graphics_init(this_->gra); - this_->bg=graphics_gc_new(this_->gra); - c.r=0; c.g=0; c.b=0; c.a=0; - graphics_gc_set_foreground(this_->bg, &c); - graphics_background_gc(this_->gra, this_->bg); - } - } - vehicle_draw_do(this_); +vehicle_draw(struct vehicle *this_, struct graphics *gra, struct point *pnt, int angle, int speed) { + if (angle < 0) + angle+=360; + dbg(lvl_debug,"enter this=%p gra=%p pnt=%p dir=%d speed=%d", this_, gra, pnt, angle, speed); + dbg(lvl_debug,"point %d,%d", pnt->x, pnt->y); + this_->cursor_pnt=*pnt; + this_->angle=angle; + this_->speed=speed; + if (!this_->cursor) + return; + this_->cursor_pnt.x-=this_->cursor->w/2; + this_->cursor_pnt.y-=this_->cursor->h/2; + if (!this_->gra) { + struct color c; + this_->gra=graphics_overlay_new(gra, &this_->cursor_pnt, this_->cursor->w, this_->cursor->h, 0); + if (this_->gra) { + graphics_init(this_->gra); + this_->bg=graphics_gc_new(this_->gra); + c.r=0; + c.g=0; + c.b=0; + c.a=0; + graphics_gc_set_foreground(this_->bg, &c); + graphics_background_gc(this_->gra, this_->bg); + } + } + vehicle_draw_do(this_); } int -vehicle_get_cursor_data(struct vehicle *this, struct point *pnt, int *angle, int *speed) -{ - *pnt=this->cursor_pnt; - *angle=this->angle; - *speed=this->speed; - return 1; +vehicle_get_cursor_data(struct vehicle *this, struct point *pnt, int *angle, int *speed) { + *pnt=this->cursor_pnt; + *angle=this->angle; + *speed=this->speed; + return 1; } -static void vehicle_set_default_name(struct vehicle *this_) -{ - struct attr default_name; - if (!attr_search(this_->attrs, NULL, attr_name)) { - default_name.type=attr_name; - // Safe cast: attr_generic_set_attr does not modify its parameter. - default_name.u.str=(char*)_("Unnamed vehicle"); - this_->attrs=attr_generic_set_attr(this_->attrs, &default_name); - dbg(lvl_error, "Incomplete vehicle definition: missing attribute 'name'. Default name set."); - } +static void vehicle_set_default_name(struct vehicle *this_) { + struct attr default_name; + if (!attr_search(this_->attrs, NULL, attr_name)) { + default_name.type=attr_name; + // Safe cast: attr_generic_set_attr does not modify its parameter. + default_name.u.str=(char*)_("Unnamed vehicle"); + this_->attrs=attr_generic_set_attr(this_->attrs, &default_name); + dbg(lvl_error, "Incomplete vehicle definition: missing attribute 'name'. Default name set."); + } } static void -vehicle_draw_do(struct vehicle *this_) -{ - struct point p; - struct cursor *cursor=this_->cursor; - int speed=this_->speed; - int angle=this_->angle; - int sequence=this_->sequence; - struct attr **attr; - char *label=NULL; - int match=0; - - if (!this_->cursor || !this_->cursor->attrs || !this_->gra) - return; - - attr=this_->attrs; - while (attr && *attr) { - if ((*attr)->type == attr_name) - label=(*attr)->u.str; - attr++; - } - transform_set_yaw(this_->trans, -this_->angle); - graphics_draw_mode(this_->gra, draw_mode_begin); - p.x=0; - p.y=0; - graphics_draw_rectangle(this_->gra, this_->bg, &p, cursor->w, cursor->h); - attr=cursor->attrs; - while (*attr) { - if ((*attr)->type == attr_itemgra) { - struct itemgra *itm=(*attr)->u.itemgra; - dbg(lvl_debug,"speed %d-%d %d", itm->speed_range.min, itm->speed_range.max, speed); - 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) { - graphics_draw_itemgra(this_->gra, itm, this_->trans, label); - } - if (sequence < itm->sequence_range.max) - match=1; - } - ++attr; - } - graphics_draw_drag(this_->gra, &this_->cursor_pnt); - graphics_draw_mode(this_->gra, draw_mode_end); - if (this_->animate_callback) { - ++this_->sequence; - if (cursor->sequence_range && cursor->sequence_range->max < this_->sequence) - this_->sequence=cursor->sequence_range->min; - if (! match && ! cursor->sequence_range) - this_->sequence=0; - } +vehicle_draw_do(struct vehicle *this_) { + struct point p; + struct cursor *cursor=this_->cursor; + int speed=this_->speed; + int angle=this_->angle; + int sequence=this_->sequence; + struct attr **attr; + char *label=NULL; + int match=0; + + if (!this_->cursor || !this_->cursor->attrs || !this_->gra) + return; + + attr=this_->attrs; + while (attr && *attr) { + if ((*attr)->type == attr_name) + label=(*attr)->u.str; + attr++; + } + transform_set_yaw(this_->trans, -this_->angle); + graphics_draw_mode(this_->gra, draw_mode_begin); + p.x=0; + p.y=0; + graphics_draw_rectangle(this_->gra, this_->bg, &p, cursor->w, cursor->h); + attr=cursor->attrs; + while (*attr) { + if ((*attr)->type == attr_itemgra) { + struct itemgra *itm=(*attr)->u.itemgra; + dbg(lvl_debug,"speed %d-%d %d", itm->speed_range.min, itm->speed_range.max, speed); + 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) { + graphics_draw_itemgra(this_->gra, itm, this_->trans, label); + } + if (sequence < itm->sequence_range.max) + match=1; + } + ++attr; + } + graphics_draw_drag(this_->gra, &this_->cursor_pnt); + graphics_draw_mode(this_->gra, draw_mode_end); + if (this_->animate_callback) { + ++this_->sequence; + if (cursor->sequence_range && cursor->sequence_range->max < this_->sequence) + this_->sequence=cursor->sequence_range->min; + if (! match && ! cursor->sequence_range) + this_->sequence=0; + } } /** @@ -478,14 +468,13 @@ vehicle_draw_do(struct vehicle *this_) * @param log The log to write to */ static void -vehicle_log_nmea(struct vehicle *this_, struct log *log) -{ - struct attr pos_attr; - if (!this_->meth.position_attr_get) - return; - if (!this_->meth.position_attr_get(this_->priv, attr_position_nmea, &pos_attr)) - return; - log_write(log, pos_attr.u.str, strlen(pos_attr.u.str), 0); +vehicle_log_nmea(struct vehicle *this_, struct log *log) { + struct attr pos_attr; + if (!this_->meth.position_attr_get) + return; + if (!this_->meth.position_attr_get(this_->priv, attr_position_nmea, &pos_attr)) + return; + log_write(log, pos_attr.u.str, strlen(pos_attr.u.str), 0); } /** @@ -498,36 +487,35 @@ vehicle_log_nmea(struct vehicle *this_, struct log *log) * Upon returning, {@code *logstr} will point to the new string with the additional tag inserted. */ void -vehicle_log_gpx_add_tag(char *tag, char **logstr) -{ - char *ext_start="\t<extensions>\n"; - char *ext_end="\t</extensions>\n"; - char *trkpt_end="</trkpt>"; - char *start=NULL,*end=NULL; - if (!*logstr) { - start=g_strdup(ext_start); - end=g_strdup(ext_end); - } else { - char *str=strstr(*logstr, ext_start); - int len; - if (str) { - len=str-*logstr+strlen(ext_start); - start=g_strdup(*logstr); - start[len]='\0'; - end=g_strdup(str+strlen(ext_start)); - } else { - str=strstr(*logstr, trkpt_end); - len=str-*logstr; - end=g_strdup_printf("%s%s",ext_end,str); - str=g_strdup(*logstr); - str[len]='\0'; - start=g_strdup_printf("%s%s",str,ext_start); - g_free(str); - } - } - *logstr=g_strdup_printf("%s%s%s",start,tag,end); - g_free(start); - g_free(end); +vehicle_log_gpx_add_tag(char *tag, char **logstr) { + char *ext_start="\t<extensions>\n"; + char *ext_end="\t</extensions>\n"; + char *trkpt_end="</trkpt>"; + char *start=NULL,*end=NULL; + if (!*logstr) { + start=g_strdup(ext_start); + end=g_strdup(ext_end); + } else { + char *str=strstr(*logstr, ext_start); + int len; + if (str) { + len=str-*logstr+strlen(ext_start); + start=g_strdup(*logstr); + start[len]='\0'; + end=g_strdup(str+strlen(ext_start)); + } else { + str=strstr(*logstr, trkpt_end); + len=str-*logstr; + end=g_strdup_printf("%s%s",ext_end,str); + str=g_strdup(*logstr); + str[len]='\0'; + start=g_strdup_printf("%s%s",str,ext_start); + g_free(str); + } + } + *logstr=g_strdup_printf("%s%s%s",start,tag,end); + g_free(start); + g_free(end); } /** @@ -537,75 +525,81 @@ vehicle_log_gpx_add_tag(char *tag, char **logstr) * @param log The log to write to */ static void -vehicle_log_gpx(struct vehicle *this_, struct log *log) -{ - struct attr attr,*attrp, fix_attr; - enum attr_type *attr_types; - char *logstr; - char *extensions="\t<extensions>\n"; - - if (!this_->meth.position_attr_get) - return; - if (log_get_attr(log, attr_attr_types, &attr, NULL)) - attr_types=attr.u.attr_types; - else - attr_types=NULL; - if (this_->meth.position_attr_get(this_->priv, attr_position_fix_type, &fix_attr)) { - if ( fix_attr.u.num == 0 ) - return; - } - if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &attr)) - return; - logstr=g_strdup_printf("<trkpt lat=\"%f\" lon=\"%f\">\n",attr.u.coord_geo->lat,attr.u.coord_geo->lng); - if (attr_types && attr_types_contains_default(attr_types, attr_position_time_iso8601, 0)) { - if (this_->meth.position_attr_get(this_->priv, attr_position_time_iso8601, &attr)) { - logstr=g_strconcat_printf(logstr,"\t<time>%s</time>\n",attr.u.str); - } else { - char *timep = current_to_iso8601(); - logstr=g_strconcat_printf(logstr,"\t<time>%s</time>\n",timep); - g_free(timep); - } - } - if (this_->gpx_desc) { - logstr=g_strconcat_printf(logstr,"\t<desc>%s</desc>\n",this_->gpx_desc); - g_free(this_->gpx_desc); - this_->gpx_desc = NULL; - } - if (attr_types_contains_default(attr_types, attr_position_height,0) && this_->meth.position_attr_get(this_->priv, attr_position_height, &attr)) - logstr=g_strconcat_printf(logstr,"\t<ele>%.6f</ele>\n",*attr.u.numd); - // <magvar> magnetic variation in degrees; we might use position_magnetic_direction and position_direction to figure it out - // <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) - // <name> GPS name (arbitrary) - // <cmt> comment - // <src> Source of data - // <link> Link to additional information (URL) - // <sym> Text of GPS symbol name - // <type> Type (classification) - // <fix> Type of GPS fix {'none'|'2d'|'3d'|'dgps'|'pps'}, leave out if unknown. Similar to position_fix_type but more detailed. - if (attr_types_contains_default(attr_types, attr_position_sats_used,0) && this_->meth.position_attr_get(this_->priv, attr_position_sats_used, &attr)) - logstr=g_strconcat_printf(logstr,"\t<sat>%d</sat>\n",attr.u.num); - if (attr_types_contains_default(attr_types, attr_position_hdop,0) && this_->meth.position_attr_get(this_->priv, attr_position_hdop, &attr)) - logstr=g_strconcat_printf(logstr,"\t<hdop>%.6f</hdop>\n",*attr.u.numd); - // <vdop>, <pdop> Vertical and position dilution of precision, no corresponding attribute - if (attr_types_contains_default(attr_types, attr_position_direction,0) && this_->meth.position_attr_get(this_->priv, attr_position_direction, &attr)) - logstr=g_strconcat_printf(logstr,"\t<course>%.1f</course>\n",*attr.u.numd); - if (attr_types_contains_default(attr_types, attr_position_speed, 0) && this_->meth.position_attr_get(this_->priv, attr_position_speed, &attr)) - logstr=g_strconcat_printf(logstr,"\t<speed>%.2f</speed>\n",(*attr.u.numd / 3.6)); - if (attr_types_contains_default(attr_types, attr_profilename, 0) && (attrp=attr_search(this_->attrs, NULL, attr_profilename))) { - logstr=g_strconcat_printf(logstr,"%s\t\t<navit:profilename>%s</navit:profilename>\n",extensions,attrp->u.str); - extensions=""; - } - if (attr_types_contains_default(attr_types, attr_position_radius, 0) && this_->meth.position_attr_get(this_->priv, attr_position_radius, &attr)) { - logstr=g_strconcat_printf(logstr,"%s\t\t<navit:radius>%.2f</navit:radius>\n",extensions,*attr.u.numd); - extensions=""; - } - if (!strcmp(extensions,"")) { - logstr=g_strconcat_printf(logstr,"\t</extensions>\n"); - } - logstr=g_strconcat_printf(logstr,"</trkpt>\n"); - callback_list_call_attr_1(this_->cbl, attr_log_gpx, &logstr); - log_write(log, logstr, strlen(logstr), 0); - g_free(logstr); +vehicle_log_gpx(struct vehicle *this_, struct log *log) { + struct attr attr,*attrp, fix_attr; + enum attr_type *attr_types; + char *logstr; + char *extensions="\t<extensions>\n"; + + if (!this_->meth.position_attr_get) + return; + if (log_get_attr(log, attr_attr_types, &attr, NULL)) + attr_types=attr.u.attr_types; + else + attr_types=NULL; + if (this_->meth.position_attr_get(this_->priv, attr_position_fix_type, &fix_attr)) { + if ( fix_attr.u.num == 0 ) + return; + } + if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &attr)) + return; + logstr=g_strdup_printf("<trkpt lat=\"%f\" lon=\"%f\">\n",attr.u.coord_geo->lat,attr.u.coord_geo->lng); + if (attr_types && attr_types_contains_default(attr_types, attr_position_time_iso8601, 0)) { + if (this_->meth.position_attr_get(this_->priv, attr_position_time_iso8601, &attr)) { + logstr=g_strconcat_printf(logstr,"\t<time>%s</time>\n",attr.u.str); + } else { + char *timep = current_to_iso8601(); + logstr=g_strconcat_printf(logstr,"\t<time>%s</time>\n",timep); + g_free(timep); + } + } + if (this_->gpx_desc) { + logstr=g_strconcat_printf(logstr,"\t<desc>%s</desc>\n",this_->gpx_desc); + g_free(this_->gpx_desc); + this_->gpx_desc = NULL; + } + if (attr_types_contains_default(attr_types, attr_position_height,0) + && this_->meth.position_attr_get(this_->priv, attr_position_height, &attr)) + logstr=g_strconcat_printf(logstr,"\t<ele>%.6f</ele>\n",*attr.u.numd); + // <magvar> magnetic variation in degrees; we might use position_magnetic_direction and position_direction to figure it out + // <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) + // <name> GPS name (arbitrary) + // <cmt> comment + // <src> Source of data + // <link> Link to additional information (URL) + // <sym> Text of GPS symbol name + // <type> Type (classification) + // <fix> Type of GPS fix {'none'|'2d'|'3d'|'dgps'|'pps'}, leave out if unknown. Similar to position_fix_type but more detailed. + if (attr_types_contains_default(attr_types, attr_position_sats_used,0) + && this_->meth.position_attr_get(this_->priv, attr_position_sats_used, &attr)) + logstr=g_strconcat_printf(logstr,"\t<sat>%d</sat>\n",attr.u.num); + if (attr_types_contains_default(attr_types, attr_position_hdop,0) + && this_->meth.position_attr_get(this_->priv, attr_position_hdop, &attr)) + logstr=g_strconcat_printf(logstr,"\t<hdop>%.6f</hdop>\n",*attr.u.numd); + // <vdop>, <pdop> Vertical and position dilution of precision, no corresponding attribute + if (attr_types_contains_default(attr_types, attr_position_direction,0) + && this_->meth.position_attr_get(this_->priv, attr_position_direction, &attr)) + logstr=g_strconcat_printf(logstr,"\t<course>%.1f</course>\n",*attr.u.numd); + if (attr_types_contains_default(attr_types, attr_position_speed, 0) + && this_->meth.position_attr_get(this_->priv, attr_position_speed, &attr)) + logstr=g_strconcat_printf(logstr,"\t<speed>%.2f</speed>\n",(*attr.u.numd / 3.6)); + if (attr_types_contains_default(attr_types, attr_profilename, 0) + && (attrp=attr_search(this_->attrs, NULL, attr_profilename))) { + logstr=g_strconcat_printf(logstr,"%s\t\t<navit:profilename>%s</navit:profilename>\n",extensions,attrp->u.str); + extensions=""; + } + if (attr_types_contains_default(attr_types, attr_position_radius, 0) + && this_->meth.position_attr_get(this_->priv, attr_position_radius, &attr)) { + logstr=g_strconcat_printf(logstr,"%s\t\t<navit:radius>%.2f</navit:radius>\n",extensions,*attr.u.numd); + extensions=""; + } + if (!strcmp(extensions,"")) { + logstr=g_strconcat_printf(logstr,"\t</extensions>\n"); + } + logstr=g_strconcat_printf(logstr,"</trkpt>\n"); + callback_list_call_attr_1(this_->cbl, attr_log_gpx, &logstr); + log_write(log, logstr, strlen(logstr), 0); + g_free(logstr); } /** @@ -615,21 +609,20 @@ vehicle_log_gpx(struct vehicle *this_, struct log *log) * @param log The log to write to */ static void -vehicle_log_textfile(struct vehicle *this_, struct log *log) -{ - struct attr pos_attr,fix_attr; - char *logstr; - if (!this_->meth.position_attr_get) - return; - if (this_->meth.position_attr_get(this_->priv, attr_position_fix_type, &fix_attr)) { - if (fix_attr.u.num == 0) - return; - } - if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr)) - return; - logstr=g_strdup_printf("%f %f type=trackpoint\n", pos_attr.u.coord_geo->lng, pos_attr.u.coord_geo->lat); - callback_list_call_attr_1(this_->cbl, attr_log_textfile, &logstr); - log_write(log, logstr, strlen(logstr), 0); +vehicle_log_textfile(struct vehicle *this_, struct log *log) { + struct attr pos_attr,fix_attr; + char *logstr; + if (!this_->meth.position_attr_get) + return; + if (this_->meth.position_attr_get(this_->priv, attr_position_fix_type, &fix_attr)) { + if (fix_attr.u.num == 0) + return; + } + if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr)) + return; + logstr=g_strdup_printf("%f %f type=trackpoint\n", pos_attr.u.coord_geo->lng, pos_attr.u.coord_geo->lat); + callback_list_call_attr_1(this_->cbl, attr_log_textfile, &logstr); + log_write(log, logstr, strlen(logstr), 0); } /** @@ -639,57 +632,56 @@ vehicle_log_textfile(struct vehicle *this_, struct log *log) * @param log The log to write to */ static void -vehicle_log_binfile(struct vehicle *this_, struct log *log) -{ - struct attr pos_attr, fix_attr; - int *buffer; - int *buffer_new; - int len,limit=1024,done=0,radius=25; - struct coord c; - enum log_flags flags; - - if (!this_->meth.position_attr_get) - return; - if (this_->meth.position_attr_get(this_->priv, attr_position_fix_type, &fix_attr)) { - if (fix_attr.u.num == 0) - return; - } - if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr)) - return; - transform_from_geo(projection_mg, pos_attr.u.coord_geo, &c); - if (!c.x || !c.y) - return; - while (!done) { - buffer=log_get_buffer(log, &len); - if (! buffer || !len) { - buffer_new=g_malloc(5*sizeof(int)); - buffer_new[0]=2; - buffer_new[1]=type_track; - buffer_new[2]=0; - } else { - buffer_new=g_malloc((buffer[0]+3)*sizeof(int)); - memcpy(buffer_new, buffer, (buffer[0]+1)*sizeof(int)); - } - dbg(lvl_debug,"c=0x%x,0x%x",c.x,c.y); - buffer_new[buffer_new[0]+1]=c.x; - buffer_new[buffer_new[0]+2]=c.y; - buffer_new[0]+=2; - buffer_new[2]+=2; - if (buffer_new[2] > limit) { - int count=buffer_new[2]/2; - struct coord *out=g_alloca(sizeof(struct coord)*(count)); - struct coord *in=(struct coord *)(buffer_new+3); - int count_out=transform_douglas_peucker(in, count, radius, out); - memcpy(in, out, count_out*2*sizeof(int)); - buffer_new[0]+=(count_out-count)*2; - buffer_new[2]+=(count_out-count)*2; - flags=log_flag_replace_buffer|log_flag_force_flush|log_flag_truncate; - } else { - flags=log_flag_replace_buffer|log_flag_keep_pointer|log_flag_keep_buffer|log_flag_force_flush; - done=1; - } - log_write(log, (char *)buffer_new, (buffer_new[0]+1)*sizeof(int), flags); - } +vehicle_log_binfile(struct vehicle *this_, struct log *log) { + struct attr pos_attr, fix_attr; + int *buffer; + int *buffer_new; + int len,limit=1024,done=0,radius=25; + struct coord c; + enum log_flags flags; + + if (!this_->meth.position_attr_get) + return; + if (this_->meth.position_attr_get(this_->priv, attr_position_fix_type, &fix_attr)) { + if (fix_attr.u.num == 0) + return; + } + if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr)) + return; + transform_from_geo(projection_mg, pos_attr.u.coord_geo, &c); + if (!c.x || !c.y) + return; + while (!done) { + buffer=log_get_buffer(log, &len); + if (! buffer || !len) { + buffer_new=g_malloc(5*sizeof(int)); + buffer_new[0]=2; + buffer_new[1]=type_track; + buffer_new[2]=0; + } else { + buffer_new=g_malloc((buffer[0]+3)*sizeof(int)); + memcpy(buffer_new, buffer, (buffer[0]+1)*sizeof(int)); + } + dbg(lvl_debug,"c=0x%x,0x%x",c.x,c.y); + buffer_new[buffer_new[0]+1]=c.x; + buffer_new[buffer_new[0]+2]=c.y; + buffer_new[0]+=2; + buffer_new[2]+=2; + if (buffer_new[2] > limit) { + int count=buffer_new[2]/2; + struct coord *out=g_alloca(sizeof(struct coord)*(count)); + struct coord *in=(struct coord *)(buffer_new+3); + int count_out=transform_douglas_peucker(in, count, radius, out); + memcpy(in, out, count_out*2*sizeof(int)); + buffer_new[0]+=(count_out-count)*2; + buffer_new[2]+=(count_out-count)*2; + flags=log_flag_replace_buffer|log_flag_force_flush|log_flag_truncate; + } else { + flags=log_flag_replace_buffer|log_flag_keep_pointer|log_flag_keep_buffer|log_flag_force_flush; + done=1; + } + log_write(log, (char *)buffer_new, (buffer_new[0]+1)*sizeof(int), flags); + } } /** @@ -701,53 +693,52 @@ vehicle_log_binfile(struct vehicle *this_, struct log *log) * @return False if the log is of an unknown type, true otherwise (including when {@code attr_type} is missing). */ static int -vehicle_add_log(struct vehicle *this_, struct log *log) -{ - struct callback *cb; - struct attr type_attr; - if (!log_get_attr(log, attr_type, &type_attr, NULL)) - return 1; - - if (!strcmp(type_attr.u.str, "nmea")) { - cb=callback_new_attr_2(callback_cast(vehicle_log_nmea), attr_position_coord_geo, this_, log); - } else if (!strcmp(type_attr.u.str, "gpx")) { - char *header = "<?xml version='1.0' encoding='UTF-8'?>\n" - "<gpx version='1.1' creator='Navit http://navit.sourceforge.net'\n" - " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n" - " xmlns:navit='http://www.navit-project.org/schema/navit'\n" - " xmlns='http://www.topografix.com/GPX/1/1'\n" - " xsi:schemaLocation='http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'>\n" - "<trk>\n" - "<trkseg>\n"; - char *trailer = "</trkseg>\n</trk>\n</gpx>\n"; - log_set_header(log, header, strlen(header)); - log_set_trailer(log, trailer, strlen(trailer)); - cb=callback_new_attr_2(callback_cast(vehicle_log_gpx), attr_position_coord_geo, this_, log); - } else if (!strcmp(type_attr.u.str, "textfile")) { - char *header = "type=track\n"; - log_set_header(log, header, strlen(header)); - cb=callback_new_attr_2(callback_cast(vehicle_log_textfile), attr_position_coord_geo, this_, log); - } else if (!strcmp(type_attr.u.str, "binfile")) { - cb=callback_new_attr_2(callback_cast(vehicle_log_binfile), attr_position_coord_geo, this_, log); - } else - return 0; - g_hash_table_insert(this_->log_to_cb, log, cb); - callback_list_add(this_->cbl, cb); - return 1; +vehicle_add_log(struct vehicle *this_, struct log *log) { + struct callback *cb; + struct attr type_attr; + if (!log_get_attr(log, attr_type, &type_attr, NULL)) + return 1; + + if (!strcmp(type_attr.u.str, "nmea")) { + cb=callback_new_attr_2(callback_cast(vehicle_log_nmea), attr_position_coord_geo, this_, log); + } else if (!strcmp(type_attr.u.str, "gpx")) { + char *header = "<?xml version='1.0' encoding='UTF-8'?>\n" + "<gpx version='1.1' creator='Navit http://navit.sourceforge.net'\n" + " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n" + " xmlns:navit='http://www.navit-project.org/schema/navit'\n" + " xmlns='http://www.topografix.com/GPX/1/1'\n" + " xsi:schemaLocation='http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'>\n" + "<trk>\n" + "<trkseg>\n"; + char *trailer = "</trkseg>\n</trk>\n</gpx>\n"; + log_set_header(log, header, strlen(header)); + log_set_trailer(log, trailer, strlen(trailer)); + cb=callback_new_attr_2(callback_cast(vehicle_log_gpx), attr_position_coord_geo, this_, log); + } else if (!strcmp(type_attr.u.str, "textfile")) { + char *header = "type=track\n"; + log_set_header(log, header, strlen(header)); + cb=callback_new_attr_2(callback_cast(vehicle_log_textfile), attr_position_coord_geo, this_, log); + } else if (!strcmp(type_attr.u.str, "binfile")) { + cb=callback_new_attr_2(callback_cast(vehicle_log_binfile), attr_position_coord_geo, this_, log); + } else + return 0; + g_hash_table_insert(this_->log_to_cb, log, cb); + callback_list_add(this_->cbl, cb); + return 1; } struct object_func vehicle_func = { - attr_vehicle, - (object_func_new)vehicle_new, - (object_func_get_attr)vehicle_get_attr, - (object_func_iter_new)vehicle_attr_iter_new, - (object_func_iter_destroy)vehicle_attr_iter_destroy, - (object_func_set_attr)vehicle_set_attr, - (object_func_add_attr)vehicle_add_attr, - (object_func_remove_attr)vehicle_remove_attr, - (object_func_init)NULL, - (object_func_destroy)vehicle_destroy, - (object_func_dup)NULL, - (object_func_ref)navit_object_ref, - (object_func_unref)navit_object_unref, + attr_vehicle, + (object_func_new)vehicle_new, + (object_func_get_attr)vehicle_get_attr, + (object_func_iter_new)vehicle_attr_iter_new, + (object_func_iter_destroy)vehicle_attr_iter_destroy, + (object_func_set_attr)vehicle_set_attr, + (object_func_add_attr)vehicle_add_attr, + (object_func_remove_attr)vehicle_remove_attr, + (object_func_init)NULL, + (object_func_destroy)vehicle_destroy, + (object_func_dup)NULL, + (object_func_ref)navit_object_ref, + (object_func_unref)navit_object_unref, }; |