]>
Commit | Line | Data |
---|---|---|
1b236385 EB |
1 | /* |
2 | * viking -- GPS Data and Topo Analyzer, Explorer, and Manager | |
3 | * | |
4 | * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License as published by | |
8 | * the Free Software Foundation; either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, write to the Free Software | |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | * | |
20 | */ | |
21 | #include <math.h> | |
22 | #include <gps.h> | |
23 | ||
50a54941 EB |
24 | #include "globals.h" |
25 | #include "dialog.h" | |
1b236385 EB |
26 | #include "vikgpsdlayer.h" |
27 | #include "viklayer.h" | |
28 | #include "vikgpsdlayer_pixmap.h" | |
29 | ||
30 | static void gpsd_layer_marshall( VikGpsdLayer *vgl, guint8 **data, gint *len ); | |
31 | static VikGpsdLayer *gpsd_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp ); | |
32 | static gboolean gpsd_layer_set_param ( VikGpsdLayer *vgl, guint16 id, VikLayerParamData data, VikViewport *vp ); | |
33 | static VikLayerParamData gpsd_layer_get_param ( VikGpsdLayer *vgl, guint16 id ); | |
34 | static VikGpsdLayer *vik_gpsd_layer_new ( VikViewport *vp ); | |
35 | static void vik_gpsd_layer_free ( VikGpsdLayer *vgl ); | |
36 | static void vik_gpsd_layer_draw ( VikGpsdLayer *vgl, gpointer data ); | |
37 | ||
38 | ||
39 | static VikLayerParam gpsd_layer_params[] = { | |
40 | }; | |
41 | ||
42 | ||
43 | enum { NUM_PARAMS=0 }; | |
44 | ||
45 | VikLayerInterface vik_gpsd_layer_interface = { | |
46 | "Gpsd", | |
47 | &gpsdlayer_pixbuf, | |
48 | ||
49 | NULL, | |
50 | 0, | |
51 | ||
52 | // gpsd_layer_params, | |
53 | NULL, | |
54 | NUM_PARAMS, | |
55 | NULL, | |
56 | 0, | |
57 | ||
58 | VIK_MENU_ITEM_ALL, | |
59 | ||
60 | (VikLayerFuncCreate) vik_gpsd_layer_new, | |
61 | (VikLayerFuncRealize) NULL, | |
62 | NULL, | |
63 | (VikLayerFuncFree) vik_gpsd_layer_free, | |
64 | ||
65 | (VikLayerFuncProperties) NULL, | |
66 | (VikLayerFuncDraw) vik_gpsd_layer_draw, | |
67 | (VikLayerFuncChangeCoordMode) NULL, | |
68 | ||
69 | (VikLayerFuncSetMenuItemsSelection) NULL, | |
70 | (VikLayerFuncGetMenuItemsSelection) NULL, | |
71 | ||
72 | (VikLayerFuncAddMenuItems) NULL, | |
73 | (VikLayerFuncSublayerAddMenuItems) NULL, | |
74 | ||
75 | (VikLayerFuncSublayerRenameRequest) NULL, | |
76 | (VikLayerFuncSublayerToggleVisible) NULL, | |
77 | ||
78 | (VikLayerFuncMarshall) gpsd_layer_marshall, | |
79 | (VikLayerFuncUnmarshall) gpsd_layer_unmarshall, | |
80 | ||
81 | (VikLayerFuncSetParam) gpsd_layer_set_param, | |
82 | (VikLayerFuncGetParam) gpsd_layer_get_param, | |
83 | ||
84 | (VikLayerFuncReadFileData) NULL, | |
85 | (VikLayerFuncWriteFileData) NULL, | |
86 | ||
87 | (VikLayerFuncDeleteItem) NULL, | |
88 | (VikLayerFuncCopyItem) NULL, | |
89 | (VikLayerFuncPasteItem) NULL, | |
90 | (VikLayerFuncFreeCopiedItem) NULL, | |
91 | (VikLayerFuncDragDropRequest) NULL, | |
92 | }; | |
93 | ||
94 | typedef struct { | |
95 | struct gps_data_t data; | |
96 | VikGpsdLayer *vgl; | |
97 | } FakeGpsData; | |
98 | ||
99 | struct _VikGpsdLayer { | |
100 | VikLayer vl; | |
415302f4 | 101 | GdkGC *gc, *pt_gc; |
1b236385 EB |
102 | struct LatLon ll; |
103 | gdouble course; | |
50a54941 | 104 | FakeGpsData *fgd; |
1b236385 EB |
105 | gint timeout; |
106 | }; | |
107 | ||
108 | GType vik_gpsd_layer_get_type () | |
109 | { | |
110 | static GType vgl_type = 0; | |
111 | ||
112 | if (!vgl_type) | |
113 | { | |
114 | static const GTypeInfo vgl_info = | |
115 | { | |
116 | sizeof (VikGpsdLayerClass), | |
117 | NULL, /* base_init */ | |
118 | NULL, /* base_finalize */ | |
119 | NULL, /* class init */ | |
120 | NULL, /* class_finalize */ | |
121 | NULL, /* class_data */ | |
122 | sizeof (VikGpsdLayer), | |
123 | 0, | |
124 | NULL /* instance init */ | |
125 | }; | |
126 | vgl_type = g_type_register_static ( VIK_LAYER_TYPE, "VikGpsdLayer", &vgl_info, 0 ); | |
127 | } | |
128 | ||
129 | return vgl_type; | |
130 | } | |
131 | ||
132 | static void gpsd_layer_marshall( VikGpsdLayer *vgl, guint8 **data, gint *len ) | |
133 | { | |
134 | vik_layer_marshall_params ( VIK_LAYER(vgl), data, len ); | |
135 | } | |
136 | ||
137 | static VikGpsdLayer *gpsd_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp ) | |
138 | { | |
139 | VikGpsdLayer *rv = vik_gpsd_layer_new ( vvp ); | |
140 | vik_layer_unmarshall_params ( VIK_LAYER(rv), data, len, vvp ); | |
141 | return rv; | |
142 | } | |
143 | ||
144 | gboolean gpsd_layer_set_param ( VikGpsdLayer *vgl, guint16 id, VikLayerParamData data, VikViewport *vp ) | |
145 | { | |
146 | switch ( id ) | |
147 | { | |
148 | ||
149 | } | |
150 | return TRUE; | |
151 | } | |
152 | ||
153 | static VikLayerParamData gpsd_layer_get_param ( VikGpsdLayer *vgl, guint16 id ) | |
154 | { | |
155 | VikLayerParamData rv; | |
156 | switch ( id ) | |
157 | { | |
158 | // case PARAM_COLOR: rv.s = vgl->color ? vgl->color : ""; break; | |
159 | } | |
160 | return rv; | |
161 | } | |
162 | ||
163 | static void vik_gpsd_layer_draw ( VikGpsdLayer *vgl, gpointer data ) | |
164 | { | |
165 | VikViewport *vp = (VikViewport *) data; | |
166 | VikCoord nw, se; | |
167 | struct LatLon lnw, lse; | |
168 | vik_viewport_screen_to_coord ( vp, -20, -20, &nw ); | |
169 | vik_viewport_screen_to_coord ( vp, vik_viewport_get_width(vp)+20, vik_viewport_get_width(vp)+20, &se ); | |
170 | vik_coord_to_latlon ( &nw, &lnw ); | |
171 | vik_coord_to_latlon ( &se, &lse ); | |
172 | if ( vgl->ll.lat > lse.lat && | |
173 | vgl->ll.lat < lnw.lat && | |
174 | vgl->ll.lon > lnw.lon && | |
175 | vgl->ll.lon < lse.lon ) { | |
176 | VikCoord gps; | |
177 | gint x, y; | |
415302f4 | 178 | gint half_back_x, half_back_y; |
1b236385 | 179 | gint pt_x, pt_y; |
415302f4 | 180 | gint side1_x, side1_y, side2_x, side2_y; |
1b236385 EB |
181 | |
182 | vik_coord_load_from_latlon ( &gps, vik_viewport_get_coord_mode(vp), &(vgl->ll) ); | |
183 | vik_viewport_coord_to_screen ( vp, &gps, &x, &y ); | |
1b236385 | 184 | |
415302f4 EB |
185 | half_back_y = y+8*cos(M_PI/180*vgl->course); |
186 | half_back_x = x-8*sin(M_PI/180*vgl->course); | |
187 | ||
188 | pt_y = half_back_y-24*cos(M_PI/180*vgl->course); | |
189 | pt_x = half_back_x+24*sin(M_PI/180*vgl->course); | |
190 | ||
191 | side1_y = half_back_y+9*sin(M_PI/180*vgl->course); | |
192 | side1_x = half_back_x+9*cos(M_PI/180*vgl->course); | |
193 | ||
194 | side2_y = half_back_y-9*sin(M_PI/180*vgl->course); | |
195 | side2_x = half_back_x-9*cos(M_PI/180*vgl->course); | |
196 | ||
197 | GdkPoint trian[3] = { { pt_x, pt_y }, {side1_x, side1_y}, {side2_x, side2_y} }; | |
1b236385 EB |
198 | |
199 | g_print("%d %d %d %d\n", x, y, pt_x, pt_y); | |
415302f4 EB |
200 | vik_viewport_draw_polygon ( vp, vgl->gc, TRUE, trian, 3 ); |
201 | vik_viewport_draw_rectangle ( vp, vgl->pt_gc, TRUE, x-2, y-2, 4, 4 ); | |
1b236385 EB |
202 | } |
203 | } | |
204 | ||
205 | static void vik_gpsd_layer_free ( VikGpsdLayer *vgl ) | |
206 | { | |
50a54941 EB |
207 | /* we already free'd the original gps_data, |
208 | * and the current one lives in the VikGpsdLayer and would be freed twice. | |
209 | * so we malloc one, copy the data, and close/free it. | |
210 | */ | |
211 | if ( vgl->fgd ) { | |
212 | gps_close ( (struct gps_data_t *) vgl->fgd ); | |
213 | gtk_timeout_remove ( vgl->timeout ); | |
214 | } | |
215 | ||
1b236385 EB |
216 | if ( vgl->gc != NULL ) |
217 | g_object_unref ( G_OBJECT(vgl->gc) ); | |
415302f4 EB |
218 | if ( vgl->pt_gc != NULL ) |
219 | g_object_unref ( G_OBJECT(vgl->pt_gc) ); | |
1b236385 EB |
220 | } |
221 | ||
415302f4 | 222 | void gpsd_hook(struct gps_data_t *gps_data, char *data) |
1b236385 | 223 | { |
415302f4 | 224 | FakeGpsData *fgd = (FakeGpsData *) gps_data; |
1b236385 EB |
225 | gdouble lat, lon, alt, herror, verror, course, speed; |
226 | /* skip thru three spaces */ | |
227 | while (*data && *data != ' ') data++; if (*data) data++; | |
228 | while (*data && *data != ' ') data++; if (*data) data++; | |
229 | while (*data && *data != ' ') data++; if (*data) data++; | |
230 | if ( sscanf(data, "%lf %lf %lf %lf %lf %lf %lf", &lat, &lon, | |
231 | &alt, &herror, &verror, &course, &speed) ) { | |
232 | VikGpsdLayer *vgl = fgd->vgl; | |
233 | vgl->ll.lat = lat; | |
234 | vgl->ll.lon = lon; | |
235 | vgl->course = course; | |
236 | /* could/should emit update here. */ | |
237 | } | |
238 | } | |
239 | ||
240 | static gboolean gpsd_timeout(VikGpsdLayer *vgl) | |
241 | { | |
50a54941 EB |
242 | if ( vgl->fgd ) { |
243 | gps_query( (struct gps_data_t *) vgl->fgd, "o"); | |
244 | vik_layer_emit_update ( VIK_LAYER(vgl) ); | |
245 | } | |
1b236385 EB |
246 | return TRUE; |
247 | } | |
248 | ||
249 | static VikGpsdLayer *vik_gpsd_layer_new ( VikViewport *vp ) | |
250 | { | |
251 | VikGpsdLayer *vgl = VIK_GPSD_LAYER ( g_object_new ( VIK_GPSD_LAYER_TYPE, NULL ) ); | |
252 | ||
253 | vik_layer_init ( VIK_LAYER(vgl), VIK_LAYER_GPSD ); | |
254 | ||
255 | struct gps_data_t *orig_data = gps_open ("localhost", DEFAULT_GPSD_PORT); | |
50a54941 EB |
256 | if ( orig_data ) { |
257 | vgl->fgd = g_realloc ( orig_data, sizeof(FakeGpsData) ); | |
258 | vgl->fgd->vgl = vgl; | |
259 | ||
260 | gps_set_raw_hook( (struct gps_data_t *) vgl->fgd, gpsd_hook ); /* pass along vgl in fgd */ | |
261 | ||
262 | vgl->timeout = gtk_timeout_add ( 1000, (GtkFunction)gpsd_timeout, vgl); | |
263 | } else { | |
264 | a_dialog_warning_msg(VIK_GTK_WINDOW_FROM_WIDGET(vp), "No Gpsd found! Right-click layer and click 'Enable GPSD' (not yet implemented) once daemon is started."); | |
265 | } | |
1b236385 | 266 | |
415302f4 EB |
267 | vgl->gc = vik_viewport_new_gc ( vp, "#203070", 2 ); |
268 | vgl->pt_gc = vik_viewport_new_gc ( vp, "red", 2 ); | |
1b236385 EB |
269 | vgl->ll.lat = vgl->ll.lon = vgl->course = 0; |
270 | ||
1b236385 EB |
271 | return vgl; |
272 | } | |
273 |