]>
Commit | Line | Data |
---|---|---|
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 | ||
24 | #include "vikgpsdlayer.h" | |
25 | #include "viklayer.h" | |
26 | #include "vikgpsdlayer_pixmap.h" | |
27 | ||
28 | static void gpsd_layer_marshall( VikGpsdLayer *vgl, guint8 **data, gint *len ); | |
29 | static VikGpsdLayer *gpsd_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp ); | |
30 | static gboolean gpsd_layer_set_param ( VikGpsdLayer *vgl, guint16 id, VikLayerParamData data, VikViewport *vp ); | |
31 | static VikLayerParamData gpsd_layer_get_param ( VikGpsdLayer *vgl, guint16 id ); | |
32 | static VikGpsdLayer *vik_gpsd_layer_new ( VikViewport *vp ); | |
33 | static void vik_gpsd_layer_free ( VikGpsdLayer *vgl ); | |
34 | static void vik_gpsd_layer_draw ( VikGpsdLayer *vgl, gpointer data ); | |
35 | ||
36 | ||
37 | static VikLayerParam gpsd_layer_params[] = { | |
38 | }; | |
39 | ||
40 | ||
41 | enum { NUM_PARAMS=0 }; | |
42 | ||
43 | VikLayerInterface vik_gpsd_layer_interface = { | |
44 | "Gpsd", | |
45 | &gpsdlayer_pixbuf, | |
46 | ||
47 | NULL, | |
48 | 0, | |
49 | ||
50 | // gpsd_layer_params, | |
51 | NULL, | |
52 | NUM_PARAMS, | |
53 | NULL, | |
54 | 0, | |
55 | ||
56 | VIK_MENU_ITEM_ALL, | |
57 | ||
58 | (VikLayerFuncCreate) vik_gpsd_layer_new, | |
59 | (VikLayerFuncRealize) NULL, | |
60 | NULL, | |
61 | (VikLayerFuncFree) vik_gpsd_layer_free, | |
62 | ||
63 | (VikLayerFuncProperties) NULL, | |
64 | (VikLayerFuncDraw) vik_gpsd_layer_draw, | |
65 | (VikLayerFuncChangeCoordMode) NULL, | |
66 | ||
67 | (VikLayerFuncSetMenuItemsSelection) NULL, | |
68 | (VikLayerFuncGetMenuItemsSelection) NULL, | |
69 | ||
70 | (VikLayerFuncAddMenuItems) NULL, | |
71 | (VikLayerFuncSublayerAddMenuItems) NULL, | |
72 | ||
73 | (VikLayerFuncSublayerRenameRequest) NULL, | |
74 | (VikLayerFuncSublayerToggleVisible) NULL, | |
75 | ||
76 | (VikLayerFuncMarshall) gpsd_layer_marshall, | |
77 | (VikLayerFuncUnmarshall) gpsd_layer_unmarshall, | |
78 | ||
79 | (VikLayerFuncSetParam) gpsd_layer_set_param, | |
80 | (VikLayerFuncGetParam) gpsd_layer_get_param, | |
81 | ||
82 | (VikLayerFuncReadFileData) NULL, | |
83 | (VikLayerFuncWriteFileData) NULL, | |
84 | ||
85 | (VikLayerFuncDeleteItem) NULL, | |
86 | (VikLayerFuncCopyItem) NULL, | |
87 | (VikLayerFuncPasteItem) NULL, | |
88 | (VikLayerFuncFreeCopiedItem) NULL, | |
89 | (VikLayerFuncDragDropRequest) NULL, | |
90 | }; | |
91 | ||
92 | typedef struct { | |
93 | struct gps_data_t data; | |
94 | VikGpsdLayer *vgl; | |
95 | } FakeGpsData; | |
96 | ||
97 | struct _VikGpsdLayer { | |
98 | VikLayer vl; | |
99 | GdkGC *gc; | |
100 | struct LatLon ll; | |
101 | gdouble course; | |
102 | FakeGpsData fgd; | |
103 | gint timeout; | |
104 | }; | |
105 | ||
106 | GType vik_gpsd_layer_get_type () | |
107 | { | |
108 | static GType vgl_type = 0; | |
109 | ||
110 | if (!vgl_type) | |
111 | { | |
112 | static const GTypeInfo vgl_info = | |
113 | { | |
114 | sizeof (VikGpsdLayerClass), | |
115 | NULL, /* base_init */ | |
116 | NULL, /* base_finalize */ | |
117 | NULL, /* class init */ | |
118 | NULL, /* class_finalize */ | |
119 | NULL, /* class_data */ | |
120 | sizeof (VikGpsdLayer), | |
121 | 0, | |
122 | NULL /* instance init */ | |
123 | }; | |
124 | vgl_type = g_type_register_static ( VIK_LAYER_TYPE, "VikGpsdLayer", &vgl_info, 0 ); | |
125 | } | |
126 | ||
127 | return vgl_type; | |
128 | } | |
129 | ||
130 | static void gpsd_layer_marshall( VikGpsdLayer *vgl, guint8 **data, gint *len ) | |
131 | { | |
132 | vik_layer_marshall_params ( VIK_LAYER(vgl), data, len ); | |
133 | } | |
134 | ||
135 | static VikGpsdLayer *gpsd_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp ) | |
136 | { | |
137 | VikGpsdLayer *rv = vik_gpsd_layer_new ( vvp ); | |
138 | vik_layer_unmarshall_params ( VIK_LAYER(rv), data, len, vvp ); | |
139 | return rv; | |
140 | } | |
141 | ||
142 | gboolean gpsd_layer_set_param ( VikGpsdLayer *vgl, guint16 id, VikLayerParamData data, VikViewport *vp ) | |
143 | { | |
144 | switch ( id ) | |
145 | { | |
146 | ||
147 | } | |
148 | return TRUE; | |
149 | } | |
150 | ||
151 | static VikLayerParamData gpsd_layer_get_param ( VikGpsdLayer *vgl, guint16 id ) | |
152 | { | |
153 | VikLayerParamData rv; | |
154 | switch ( id ) | |
155 | { | |
156 | // case PARAM_COLOR: rv.s = vgl->color ? vgl->color : ""; break; | |
157 | } | |
158 | return rv; | |
159 | } | |
160 | ||
161 | static void vik_gpsd_layer_draw ( VikGpsdLayer *vgl, gpointer data ) | |
162 | { | |
163 | VikViewport *vp = (VikViewport *) data; | |
164 | VikCoord nw, se; | |
165 | struct LatLon lnw, lse; | |
166 | vik_viewport_screen_to_coord ( vp, -20, -20, &nw ); | |
167 | vik_viewport_screen_to_coord ( vp, vik_viewport_get_width(vp)+20, vik_viewport_get_width(vp)+20, &se ); | |
168 | vik_coord_to_latlon ( &nw, &lnw ); | |
169 | vik_coord_to_latlon ( &se, &lse ); | |
170 | if ( vgl->ll.lat > lse.lat && | |
171 | vgl->ll.lat < lnw.lat && | |
172 | vgl->ll.lon > lnw.lon && | |
173 | vgl->ll.lon < lse.lon ) { | |
174 | VikCoord gps; | |
175 | gint x, y; | |
176 | gint pt_x, pt_y; | |
177 | ||
178 | vik_coord_load_from_latlon ( &gps, vik_viewport_get_coord_mode(vp), &(vgl->ll) ); | |
179 | vik_viewport_coord_to_screen ( vp, &gps, &x, &y ); | |
180 | vik_viewport_draw_rectangle ( vp, vgl->gc, TRUE, x-2, y-2, 4, 4 ); | |
181 | ||
182 | pt_y = y-20*cos(M_PI/180*vgl->course); | |
183 | pt_x = x+20*sin(M_PI/180*vgl->course); | |
184 | ||
185 | g_print("%d %d %d %d\n", x, y, pt_x, pt_y); | |
186 | vik_viewport_draw_line ( vp, vgl->gc, x, y, pt_x, pt_y ); | |
187 | } | |
188 | } | |
189 | ||
190 | static void vik_gpsd_layer_free ( VikGpsdLayer *vgl ) | |
191 | { | |
192 | if ( vgl->gc != NULL ) | |
193 | g_object_unref ( G_OBJECT(vgl->gc) ); | |
194 | gtk_timeout_remove ( vgl->timeout ); | |
195 | } | |
196 | ||
197 | void gpsd_hook(FakeGpsData *fgd, gchar *data) | |
198 | { | |
199 | gdouble lat, lon, alt, herror, verror, course, speed; | |
200 | /* skip thru three spaces */ | |
201 | while (*data && *data != ' ') data++; if (*data) data++; | |
202 | while (*data && *data != ' ') data++; if (*data) data++; | |
203 | while (*data && *data != ' ') data++; if (*data) data++; | |
204 | if ( sscanf(data, "%lf %lf %lf %lf %lf %lf %lf", &lat, &lon, | |
205 | &alt, &herror, &verror, &course, &speed) ) { | |
206 | VikGpsdLayer *vgl = fgd->vgl; | |
207 | vgl->ll.lat = lat; | |
208 | vgl->ll.lon = lon; | |
209 | vgl->course = course; | |
210 | /* could/should emit update here. */ | |
211 | } | |
212 | } | |
213 | ||
214 | static gboolean gpsd_timeout(VikGpsdLayer *vgl) | |
215 | { | |
216 | gps_query(&(vgl->fgd), "o"); | |
217 | vik_layer_emit_update ( VIK_LAYER(vgl) ); | |
218 | return TRUE; | |
219 | } | |
220 | ||
221 | static VikGpsdLayer *vik_gpsd_layer_new ( VikViewport *vp ) | |
222 | { | |
223 | VikGpsdLayer *vgl = VIK_GPSD_LAYER ( g_object_new ( VIK_GPSD_LAYER_TYPE, NULL ) ); | |
224 | ||
225 | vik_layer_init ( VIK_LAYER(vgl), VIK_LAYER_GPSD ); | |
226 | ||
227 | struct gps_data_t *orig_data = gps_open ("localhost", DEFAULT_GPSD_PORT); | |
228 | vgl->fgd.data = *orig_data; | |
229 | vgl->fgd.vgl = vgl; | |
230 | g_free ( orig_data ); | |
231 | gps_set_raw_hook(&(vgl->fgd), gpsd_hook); /* pass along vgl in fgd */ | |
232 | ||
233 | vgl->gc = vik_viewport_new_gc ( vp, "red", 2 ); | |
234 | vgl->ll.lat = vgl->ll.lon = vgl->course = 0; | |
235 | ||
236 | gtk_timeout_add ( 1000, (GtkFunction)gpsd_timeout, vgl); | |
237 | ||
238 | return vgl; | |
239 | } | |
240 |