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