Updated Turkish translation
[navit-package] / navit / vehicle.c
1 /**
2  * Navit, a modular navigation system.
3  * Copyright (C) 2005-2008 Navit Team
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 #include <stdio.h>
21 #include <string.h>
22 #include <glib.h>
23 #include <time.h>
24 #include "config.h"
25 #include "debug.h"
26 #include "coord.h"
27 #include "item.h"
28 #include "log.h"
29 #include "callback.h"
30 #include "plugin.h"
31 #include "vehicle.h"
32 #include "util.h"
33
34 struct vehicle {
35         struct vehicle_priv *priv;
36         struct vehicle_methods meth;
37         struct callback_list *cbl;
38         struct log *nmea_log, *gpx_log;
39         struct attr **attrs;
40 };
41
42 static void
43 vehicle_log_nmea(struct vehicle *this_, struct log *log)
44 {
45         struct attr pos_attr;
46         if (!this_->meth.position_attr_get)
47                 return;
48         if (!this_->meth.position_attr_get(this_->priv, attr_position_nmea, &pos_attr))
49                 return;
50         log_write(log, pos_attr.u.str, strlen(pos_attr.u.str));
51 }
52
53 static void
54 vehicle_log_gpx(struct vehicle *this_, struct log *log)
55 {
56         struct attr pos_attr;
57         struct attr time_attr;
58         struct attr *profile_attr;
59         char *timep;
60         int free=0;
61
62         if (!this_->meth.position_attr_get)
63                 return;
64         if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr))
65                 return;
66         if (!this_->meth.position_attr_get(this_->priv, attr_position_time_iso8601, &time_attr)) {
67                 timep = current_to_iso8601();
68                 free=1;
69         } else {
70                 timep = time_attr.u.str;
71         }
72
73         // get the profile name attribute
74         profile_attr = attr_search(this_->attrs, NULL, attr_profilename);
75
76         log_printf(log,
77                         "<trkpt lat=\"%f\" lon=\"%f\">\n"
78                         "\t<time>%s</time>\n"
79                         "\t<extensions><navit:profilename>%s</navit:profilename></extensions>\n"
80                         "</trkpt>\n",
81                 pos_attr.u.coord_geo->lat,
82                 pos_attr.u.coord_geo->lng,
83                 timep,
84                 profile_attr->u.str
85         );
86
87         if (free)
88                 g_free(timep);
89 }
90
91 static void
92 vehicle_log_textfile(struct vehicle *this_, struct log *log)
93 {
94         struct attr pos_attr;
95         char buffer[256];
96         if (!this_->meth.position_attr_get)
97                 return;
98         if (!this_->meth.position_attr_get(this_->priv, attr_position_coord_geo, &pos_attr))
99                 return;
100         sprintf(buffer,"%f %f type=trackpoint\n", pos_attr.u.coord_geo->lng, pos_attr.u.coord_geo->lat);
101         log_write(log, buffer, strlen(buffer));
102 }
103
104 static int
105 vehicle_add_log(struct vehicle *this_, struct log *log)
106 {
107         struct callback *cb;
108         struct attr type_attr;
109         if (!log_get_attr(log, attr_type, &type_attr, NULL))
110                 return 1;
111
112         if (!strcmp(type_attr.u.str, "nmea")) {
113                 cb=callback_new_2(callback_cast(vehicle_log_nmea), this_, log);
114         } else if (!strcmp(type_attr.u.str, "gpx")) {
115                 char *header = "<?xml version='1.0' encoding='UTF-8'?>\n"
116                         "<gpx version='1.1' creator='Navit http://navit.sourceforge.net'\n"
117                         "     xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'\n"
118                         "     xmlns:navit='http://www.navit-project.org/schema/navit'\n"
119                         "     xmlns='http://www.topografix.com/GPX/1/1'\n"
120                         "     xsi:schemaLocation='http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd'>\n"
121                         "<trk>\n"
122                         "<trkseg>\n";
123                 char *trailer = "</trkseg>\n</trk>\n</gpx>\n";
124                 log_set_header(log, header, strlen(header));
125                 log_set_trailer(log, trailer, strlen(trailer));
126                 cb=callback_new_2(callback_cast(vehicle_log_gpx), this_, log);
127         } else if (!strcmp(type_attr.u.str, "textfile")) {
128                 char *header = "type=track\n";
129                 log_set_header(log, header, strlen(header));
130                 cb=callback_new_2(callback_cast(vehicle_log_textfile), this_, log);
131         } else
132                 return 1;
133         callback_list_add(this_->cbl, cb);
134         return 0;
135 }
136
137 struct vehicle *
138 vehicle_new(struct attr *parent, struct attr **attrs)
139 {
140         struct vehicle *this_;
141         struct attr *source;
142         struct vehicle_priv *(*vehicletype_new) (struct vehicle_methods *
143                                                  meth,
144                                                  struct callback_list *
145                                                  cbl,
146                                                  struct attr ** attrs);
147         char *type, *colon;
148
149         dbg(1, "enter\n");
150         source = attr_search(attrs, NULL, attr_source);
151         if (!source) {
152                 dbg(0, "no source\n");
153                 return NULL;
154         }
155
156         type = g_strdup(source->u.str);
157         colon = strchr(type, ':');
158         if (colon)
159                 *colon = '\0';
160         dbg(1, "source='%s' type='%s'\n", source->u.str, type);
161
162         vehicletype_new = plugin_get_vehicle_type(type);
163         if (!vehicletype_new) {
164                 dbg(0, "invalid type '%s'\n", type);
165                 return NULL;
166         }
167         this_ = g_new0(struct vehicle, 1);
168         this_->cbl = callback_list_new();
169         this_->priv = vehicletype_new(&this_->meth, this_->cbl, attrs);
170         if (!this_->priv) {
171                 dbg(0, "vehicletype_new failed\n");
172                 callback_list_destroy(this_->cbl);
173                 g_free(this_);
174                 return NULL;
175         }
176         this_->attrs=attr_list_dup(attrs);
177         dbg(1, "leave\n");
178
179         return this_;
180 }
181
182 int
183 vehicle_get_attr(struct vehicle *this_, enum attr_type type, struct attr *attr, struct attr_iter *iter)
184 {
185         int ret;
186         if (this_->meth.position_attr_get) {
187                 ret=this_->meth.position_attr_get(this_->priv, type, attr);
188                 if (ret)
189                         return ret;
190         }
191         return attr_generic_get_attr(this_->attrs, NULL, type, attr, iter);
192 }
193
194 int
195 vehicle_set_attr(struct vehicle *this_, struct attr *attr,
196                  struct attr **attrs)
197 {
198         int ret=1;
199         if (this_->meth.set_attr)
200                 ret=this_->meth.set_attr(this_->priv, attr, attrs);
201         if (ret == 1 && attr->type != attr_navit)
202                 this_->attrs=attr_generic_set_attr(this_->attrs, attr);
203         return ret != 0;
204 }
205
206 int
207 vehicle_add_attr(struct vehicle *this_, struct attr *attr)
208 {
209         int ret=1;
210         switch (attr->type) {
211         case attr_callback:
212                 callback_list_add(this_->cbl, attr->u.callback);
213                 break;
214         case attr_log:
215                 ret=vehicle_add_log(this_, attr->u.log);
216                 break;
217         default:
218                 break;
219         }
220         if (ret)
221                 this_->attrs=attr_generic_add_attr(this_->attrs, attr);
222         return ret;
223 }
224
225 int
226 vehicle_remove_attr(struct vehicle *this_, struct attr *attr)
227 {
228         switch (attr->type) {
229         case attr_callback:
230                 callback_list_remove(this_->cbl, attr->u.callback);
231                 break;
232         default:
233                 return 0;
234         }
235         return 1;
236 }
237
238 void
239 vehicle_destroy(struct vehicle *this_)
240 {
241         this_->meth.destroy(this_->priv);
242         callback_list_destroy(this_->cbl);
243         attr_list_free(this_->attrs);
244         g_free(this_);
245 }