2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
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.
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.
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.
32 #include "transform.h"
36 struct vehicle_priv *priv;
37 struct vehicle_methods meth;
38 struct callback_list *cbl;
39 struct log *nmea_log, *gpx_log;
44 vehicle_log_nmea(struct vehicle *this_, struct log *log)
47 if (!this_->meth.position_attr_get)
49 if (!this_->meth.position_attr_get(this_->priv, attr_position_nmea, &pos_attr))
51 log_write(log, pos_attr.u.str, strlen(pos_attr.u.str), 0);
55 vehicle_log_gpx(struct vehicle *this_, struct log *log)
57 struct attr attr,*attrp;
58 enum attr_type *attr_types;
60 char *extensions="\t<extensions>\n";
62 if (!this_->meth.position_attr_get)
64 if (log_get_attr(log, attr_attr_types, &attr, NULL))
65 attr_types=attr.u.attr_types;
68 if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &attr))
70 logstr=g_strdup_printf("<trkpt lat=\"%f\" lon=\"%f\">\n",attr.u.coord_geo->lat,attr.u.coord_geo->lng);
71 if (attr_types && attr_types_contains_default(attr_types, attr_position_time_iso8601, 0)) {
72 if (this_->meth.position_attr_get(this_->priv, attr_position_time_iso8601, &attr)) {
73 logstr=g_strconcat_printf(logstr,"\t<time>%s</time>\n",attr.u.str);
75 char *timep = current_to_iso8601();
76 logstr=g_strconcat_printf(logstr,"\t<time>%s</time>\n",timep);
80 if (attr_types_contains_default(attr_types, attr_position_direction,0) && this_->meth.position_attr_get(this_->priv, attr_position_direction, &attr))
81 logstr=g_strconcat_printf(logstr,"\t<course>%.1f</course>\n",*attr.u.numd);
82 if (attr_types_contains_default(attr_types, attr_position_speed, 0) && this_->meth.position_attr_get(this_->priv, attr_position_speed, &attr))
83 logstr=g_strconcat_printf(logstr,"\t<speed>%.2f</speed>\n",*attr.u.numd);
84 if (attr_types_contains_default(attr_types, attr_profilename, 0) && (attrp=attr_search(this_->attrs, NULL, attr_profilename))) {
85 logstr=g_strconcat_printf(logstr,"%s\t\t<navit:profilename>%s</navit:profilename>\n",extensions,attrp->u.str);
88 if (attr_types_contains_default(attr_types, attr_position_radius, 0) && this_->meth.position_attr_get(this_->priv, attr_position_radius, &attr)) {
89 logstr=g_strconcat_printf(logstr,"%s\t\t<navit:radius>%.2f</navit:radius>\n",extensions,*attr.u.numd);
92 if (!strcmp(extensions,"")) {
93 logstr=g_strconcat_printf(logstr,"\t</extensions>\n");
95 logstr=g_strconcat_printf(logstr,"</trkpt>\n");
96 callback_list_call_attr_1(this_->cbl, attr_log_gpx, &logstr);
97 log_write(log, logstr, strlen(logstr), 0);
102 vehicle_log_textfile(struct vehicle *this_, struct log *log)
104 struct attr pos_attr;
106 if (!this_->meth.position_attr_get)
108 if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr))
110 logstr=g_strdup_printf("%f %f type=trackpoint\n", pos_attr.u.coord_geo->lng, pos_attr.u.coord_geo->lat);
111 callback_list_call_attr_1(this_->cbl, attr_log_textfile, &logstr);
112 log_write(log, logstr, strlen(logstr), 0);
116 vehicle_log_binfile(struct vehicle *this_, struct log *log)
118 struct attr pos_attr;
121 int len,limit=1024,done=0,radius=25;
123 enum log_flags flags;
125 if (!this_->meth.position_attr_get)
127 if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr))
129 transform_from_geo(projection_mg, pos_attr.u.coord_geo, &c);
133 buffer=log_get_buffer(log, &len);
134 if (! buffer || !len) {
135 buffer_new=g_malloc(5*sizeof(int));
137 buffer_new[1]=type_track;
140 buffer_new=g_malloc((buffer[0]+3)*sizeof(int));
141 memcpy(buffer_new, buffer, (buffer[0]+1)*sizeof(int));
143 dbg(1,"c=0x%x,0x%x\n",c.x,c.y);
144 buffer_new[buffer_new[0]+1]=c.x;
145 buffer_new[buffer_new[0]+2]=c.y;
148 if (buffer_new[2] > limit) {
149 int count=buffer_new[2]/2;
150 struct coord out[count];
151 struct coord *in=(struct coord *)(buffer_new+3);
152 int count_out=transform_douglas_peucker(in, count, radius, out);
153 memcpy(in, out, count_out*2*sizeof(int));
154 buffer_new[0]+=(count_out-count)*2;
155 buffer_new[2]+=(count_out-count)*2;
156 flags=log_flag_replace_buffer|log_flag_force_flush|log_flag_truncate;
158 flags=log_flag_replace_buffer|log_flag_keep_pointer|log_flag_keep_buffer|log_flag_force_flush;
161 log_write(log, (char *)buffer_new, (buffer_new[0]+1)*sizeof(int), flags);
166 vehicle_add_log(struct vehicle *this_, struct log *log)
169 struct attr type_attr;
170 if (!log_get_attr(log, attr_type, &type_attr, NULL))
173 if (!strcmp(type_attr.u.str, "nmea")) {
174 cb=callback_new_attr_2(callback_cast(vehicle_log_nmea), attr_position_coord_geo, this_, log);
175 } else if (!strcmp(type_attr.u.str, "gpx")) {
176 char *header = "<?xml version='1.0' encoding='UTF-8'?>\n"
177 "<gpx version='1.1' creator='Navit http://navit.sourceforge.net'\n"
178 " xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"
179 " xmlns:navit='http://www.navit-project.org/schema/navit'\n"
180 " xmlns='http://www.topografix.com/GPX/1/1'\n"
181 " xsi:schemaLocation='http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'>\n"
184 char *trailer = "</trkseg>\n</trk>\n</gpx>\n";
185 log_set_header(log, header, strlen(header));
186 log_set_trailer(log, trailer, strlen(trailer));
187 cb=callback_new_attr_2(callback_cast(vehicle_log_gpx), attr_position_coord_geo, this_, log);
188 } else if (!strcmp(type_attr.u.str, "textfile")) {
189 char *header = "type=track\n";
190 log_set_header(log, header, strlen(header));
191 cb=callback_new_attr_2(callback_cast(vehicle_log_textfile), attr_position_coord_geo, this_, log);
192 } else if (!strcmp(type_attr.u.str, "binfile")) {
193 cb=callback_new_attr_2(callback_cast(vehicle_log_binfile), attr_position_coord_geo, this_, log);
196 callback_list_add(this_->cbl, cb);
201 vehicle_new(struct attr *parent, struct attr **attrs)
203 struct vehicle *this_;
205 struct vehicle_priv *(*vehicletype_new) (struct vehicle_methods *
207 struct callback_list *
209 struct attr ** attrs);
213 source = attr_search(attrs, NULL, attr_source);
215 dbg(0, "no source\n");
219 type = g_strdup(source->u.str);
220 colon = strchr(type, ':');
223 dbg(1, "source='%s' type='%s'\n", source->u.str, type);
225 vehicletype_new = plugin_get_vehicle_type(type);
226 if (!vehicletype_new) {
227 dbg(0, "invalid type '%s'\n", type);
230 this_ = g_new0(struct vehicle, 1);
231 this_->cbl = callback_list_new();
232 this_->priv = vehicletype_new(&this_->meth, this_->cbl, attrs);
234 dbg(0, "vehicletype_new failed\n");
235 callback_list_destroy(this_->cbl);
239 this_->attrs=attr_list_dup(attrs);
246 vehicle_attr_iter_new(void)
248 return g_new0(struct attr_iter,1);
252 vehicle_attr_iter_destroy(struct attr_iter *iter)
259 vehicle_get_attr(struct vehicle *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
262 if (this_->meth.position_attr_get) {
263 ret=this_->meth.position_attr_get(this_->priv, type, attr);
267 return attr_generic_get_attr(this_->attrs, NULL, type, attr, iter);
271 vehicle_set_attr(struct vehicle *this_, struct attr *attr,
275 if (this_->meth.set_attr)
276 ret=this_->meth.set_attr(this_->priv, attr, attrs);
277 if (ret == 1 && attr->type != attr_navit)
278 this_->attrs=attr_generic_set_attr(this_->attrs, attr);
283 vehicle_add_attr(struct vehicle *this_, struct attr *attr)
286 switch (attr->type) {
288 callback_list_add(this_->cbl, attr->u.callback);
291 ret=vehicle_add_log(this_, attr->u.log);
297 this_->attrs=attr_generic_add_attr(this_->attrs, attr);
302 vehicle_remove_attr(struct vehicle *this_, struct attr *attr)
304 switch (attr->type) {
306 callback_list_remove(this_->cbl, attr->u.callback);
315 vehicle_destroy(struct vehicle *this_)
317 this_->meth.destroy(this_->priv);
318 callback_list_destroy(this_->cbl);
319 attr_list_free(this_->attrs);