]> git.street.me.uk Git - andy/viking.git/blob - src/vikgpsdlayer.c
Experimental VikGpsdLayer
[andy/viking.git] / src / vikgpsdlayer.c
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