]> git.street.me.uk Git - andy/viking.git/blame - src/vikcoordlayer.c
Fix mapcache stuff
[andy/viking.git] / src / vikcoordlayer.c
CommitLineData
50a14534
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
22#include "viking.h"
23#include "vikcoordlayer_pixmap.h"
24
25static VikCoordLayer *coord_layer_copy ( VikCoordLayer *vcl, gpointer vp );
26static gboolean coord_layer_set_param ( VikCoordLayer *vcl, guint16 id, VikLayerParamData data, VikViewport *vp );
27static VikLayerParamData coord_layer_get_param ( VikCoordLayer *vcl, guint16 id );
28static void coord_layer_update_gc ( VikCoordLayer *vcl, VikViewport *vp, const gchar *color );
29static void coord_layer_post_read ( VikCoordLayer *vcl, VikViewport *vp );
30
31VikLayerParamScale param_scales[] = {
32 { 0.05, 60.0, 0.25, 10 },
33 { 1, 10, 1, 0 },
34};
35
36VikLayerParam coord_layer_params[] = {
37 { "color", VIK_LAYER_PARAM_STRING, VIK_LAYER_GROUP_NONE, "Color:", VIK_LAYER_WIDGET_ENTRY },
38 { "min_inc", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_GROUP_NONE, "Minutes Width:", VIK_LAYER_WIDGET_SPINBUTTON, param_scales + 0 },
39 { "line_thickness", VIK_LAYER_PARAM_UINT, VIK_LAYER_GROUP_NONE, "Line Thickness:", VIK_LAYER_WIDGET_SPINBUTTON, param_scales + 1 },
40};
41
42
43enum { PARAM_COLOR = 0, PARAM_MIN_INC, PARAM_LINE_THICKNESS, NUM_PARAMS };
44
45VikLayerInterface vik_coord_layer_interface = {
46 "Coord",
47 &coordlayer_pixbuf,
48
49 NULL,
50 0,
51
52 coord_layer_params,
53 NUM_PARAMS,
54 NULL,
55 0,
56
57 (VikLayerFuncCreate) vik_coord_layer_create,
58 (VikLayerFuncRealize) NULL,
59 (VikLayerFuncPostRead) coord_layer_post_read,
60 (VikLayerFuncFree) vik_coord_layer_free,
61
62 (VikLayerFuncProperties) NULL,
63 (VikLayerFuncDraw) vik_coord_layer_draw,
64 (VikLayerFuncChangeCoordMode) NULL,
65
66 (VikLayerFuncAddMenuItems) NULL,
67 (VikLayerFuncSublayerAddMenuItems) NULL,
68
69 (VikLayerFuncSublayerRenameRequest) NULL,
70 (VikLayerFuncSublayerToggleVisible) NULL,
71
72 (VikLayerFuncCopy) coord_layer_copy,
73
74 (VikLayerFuncSetParam) coord_layer_set_param,
75 (VikLayerFuncGetParam) coord_layer_get_param,
76
77 (VikLayerFuncReadFileData) NULL,
78 (VikLayerFuncWriteFileData) NULL,
79
80 (VikLayerFuncCopyItem) NULL,
81 (VikLayerFuncPasteItem) NULL,
82 (VikLayerFuncFreeCopiedItem) NULL,
83};
84
85struct _VikCoordLayer {
86 VikLayer vl;
87 GdkGC *gc;
88 gdouble deg_inc;
89 guint8 line_thickness;
90 gchar *color;
91};
92
93GType vik_coord_layer_get_type ()
94{
95 static GType vcl_type = 0;
96
97 if (!vcl_type)
98 {
99 static const GTypeInfo vcl_info =
100 {
101 sizeof (VikCoordLayerClass),
102 NULL, /* base_init */
103 NULL, /* base_finalize */
104 NULL, /* class init */
105 NULL, /* class_finalize */
106 NULL, /* class_data */
107 sizeof (VikCoordLayer),
108 0,
109 NULL /* instance init */
110 };
111 vcl_type = g_type_register_static ( VIK_LAYER_TYPE, "VikCoordLayer", &vcl_info, 0 );
112 }
113
114 return vcl_type;
115}
116
117static VikCoordLayer *coord_layer_copy ( VikCoordLayer *vcl, gpointer vp )
118{
119 VikCoordLayer *rv = vik_coord_layer_new ( );
120
121 rv->color = g_strdup ( vcl->color );
122 rv->deg_inc = vcl->deg_inc;
123 rv->line_thickness = vcl->line_thickness;
124 rv->gc = vcl->gc;
125 g_object_ref ( rv->gc );
126 return rv;
127}
128
129gboolean coord_layer_set_param ( VikCoordLayer *vcl, guint16 id, VikLayerParamData data, VikViewport *vp )
130{
131 switch ( id )
132 {
133 case PARAM_COLOR: if ( vcl->color ) g_free ( vcl->color ); vcl->color = g_strdup ( data.s ); break;
134 case PARAM_MIN_INC: vcl->deg_inc = data.d / 60.0; break;
135 case PARAM_LINE_THICKNESS: if ( data.u >= 1 && data.u <= 15 ) vcl->line_thickness = data.u; break;
136 }
137 return TRUE;
138}
139
140static VikLayerParamData coord_layer_get_param ( VikCoordLayer *vcl, guint16 id )
141{
142 VikLayerParamData rv;
143 switch ( id )
144 {
145 case PARAM_COLOR: rv.s = vcl->color ? vcl->color : ""; break;
146 case PARAM_MIN_INC: rv.d = vcl->deg_inc * 60.0; break;
147 case PARAM_LINE_THICKNESS: rv.i = vcl->line_thickness; break;
148 }
149 return rv;
150}
151
152static void coord_layer_post_read ( VikCoordLayer *vcl, VikViewport *vp )
153{
154 if ( vcl->gc )
155 g_object_unref ( G_OBJECT(vcl->gc) );
156
157 vcl->gc = vik_viewport_new_gc ( vp, vcl->color, vcl->line_thickness );
158}
159
160VikCoordLayer *vik_coord_layer_new ( )
161{
162 VikCoordLayer *vcl = VIK_COORD_LAYER ( g_object_new ( VIK_COORD_LAYER_TYPE, NULL ) );
163 vik_layer_init ( VIK_LAYER(vcl), VIK_LAYER_COORD );
164
165 vcl->gc = NULL;
166 vcl->deg_inc = 1.0/60.0;
167 vcl->line_thickness = 3;
168 vcl->color = NULL;
169 return vcl;
170}
171
172void vik_coord_layer_draw ( VikCoordLayer *vcl, gpointer data )
173{
174 VikViewport *vp = (VikViewport *) data;
175 if ( vik_viewport_get_coord_mode(vp) != VIK_COORD_UTM )
176 return;
177 if ( vcl->gc != NULL)
178 {
179 const struct UTM *center = (const struct UTM *)vik_viewport_get_center ( vp );
180 gdouble xmpp = vik_viewport_get_xmpp ( vp ), ympp = vik_viewport_get_ympp ( vp );
181 guint16 width = vik_viewport_get_width ( vp ), height = vik_viewport_get_height ( vp );
182 struct LatLon ll, ll2, min, max;
183 double lon;
184 int x1, x2;
185 struct UTM utm;
186
187 utm = *center;
188 utm.northing = center->northing - ( ympp * height / 2 );
189
190 a_coords_utm_to_latlon ( &utm, &ll );
191
192 utm.northing = center->northing + ( ympp * height / 2 );
193
194 a_coords_utm_to_latlon ( &utm, &ll2 );
195
196 {
197 /* find corner coords in lat/lon.
198 start at whichever is less: top or bottom left lon. goto whichever more: top or bottom right lon
199 */
200 struct LatLon topleft, topright, bottomleft, bottomright;
201 struct UTM temp_utm;
202 temp_utm = *center;
203 temp_utm.easting -= (width/2)*xmpp;
204 temp_utm.northing += (height/2)*ympp;
205 a_coords_utm_to_latlon ( &temp_utm, &topleft );
206 temp_utm.easting += (width*xmpp);
207 a_coords_utm_to_latlon ( &temp_utm, &topright );
208 temp_utm.northing -= (height*ympp);
209 a_coords_utm_to_latlon ( &temp_utm, &bottomright );
210 temp_utm.easting -= (width*xmpp);
211 a_coords_utm_to_latlon ( &temp_utm, &bottomleft );
212 min.lon = (topleft.lon < bottomleft.lon) ? topleft.lon : bottomleft.lon;
213 max.lon = (topright.lon > bottomright.lon) ? topright.lon : bottomright.lon;
214 min.lat = (bottomleft.lat < bottomright.lat) ? bottomleft.lat : bottomright.lat;
215 max.lat = (topleft.lat > topright.lat) ? topleft.lat : topright.lat;
216 }
217
218 lon = ((double) ((long) ((min.lon)/ vcl->deg_inc))) * vcl->deg_inc;
219 ll.lon = ll2.lon = lon;
220
221 for (; ll.lon <= max.lon; ll.lon+=vcl->deg_inc, ll2.lon+=vcl->deg_inc )
222 {
223 a_coords_latlon_to_utm ( &ll, &utm );
224 x1 = ( (utm.easting - center->easting) / xmpp ) + (width / 2);
225 a_coords_latlon_to_utm ( &ll2, &utm );
226 x2 = ( (utm.easting - center->easting) / xmpp ) + (width / 2);
227 vik_viewport_draw_line (vp, vcl->gc, x1, height, x2, 0);
228 }
229
230 utm = *center;
231 utm.easting = center->easting - ( xmpp * width / 2 );
232
233 a_coords_utm_to_latlon ( &utm, &ll );
234
235 utm.easting = center->easting + ( xmpp * width / 2 );
236
237 a_coords_utm_to_latlon ( &utm, &ll2 );
238
239 /* really lat, just reusing a variable */
240 lon = ((double) ((long) ((min.lat)/ vcl->deg_inc))) * vcl->deg_inc;
241 ll.lat = ll2.lat = lon;
242
243 for (; ll.lat <= max.lat ; ll.lat+=vcl->deg_inc, ll2.lat+=vcl->deg_inc )
244 {
245 a_coords_latlon_to_utm ( &ll, &utm );
246 x1 = (height / 2) - ( (utm.northing - center->northing) / ympp );
247 a_coords_latlon_to_utm ( &ll2, &utm );
248 x2 = (height / 2) - ( (utm.northing - center->northing) / ympp );
249 vik_viewport_draw_line (vp, vcl->gc, width, x2, 0, x1);
250 }
251 }
252}
253
254void vik_coord_layer_free ( VikCoordLayer *vcl )
255{
256 if ( vcl->gc != NULL )
257 g_object_unref ( G_OBJECT(vcl->gc) );
258
259 if ( vcl->color != NULL )
260 g_free ( vcl->color );
261}
262
263static void coord_layer_update_gc ( VikCoordLayer *vcl, VikViewport *vp, const gchar *color )
264{
265 if ( vcl->color )
266 g_free ( vcl->color );
267
268 vcl->color = g_strdup ( color );
269
270 if ( vcl->gc )
271 g_object_unref ( G_OBJECT(vcl->gc) );
272
273 vcl->gc = vik_viewport_new_gc ( vp, vcl->color, vcl->line_thickness );
274}
275
276VikCoordLayer *vik_coord_layer_create ( VikViewport *vp )
277{
278 VikCoordLayer *vcl = vik_coord_layer_new ();
279 coord_layer_update_gc ( vcl, vp, "red" );
280 return vcl;
281}
282