]> git.street.me.uk Git - andy/viking.git/blame - src/vikwebtool_datasource.c
Refactor: TrackWaypoint sublayer menu callback functions.
[andy/viking.git] / src / vikwebtool_datasource.c
CommitLineData
82993cc7
RN
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2/*
3 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
4 *
5 * Copyright (C) 2013, Rob Norris <rw_norris@hotmail.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "vikwebtool_datasource.h"
28
29#include <string.h>
30
31#include <glib.h>
32#include <glib/gi18n.h>
33
34#include "globals.h"
35#include "acquire.h"
3957ef85 36#include "maputils.h"
82993cc7
RN
37
38static GObjectClass *parent_class;
39
40static void webtool_datasource_finalize ( GObject *gob );
41
42static gchar *webtool_datasource_get_url ( VikWebtool *self, VikWindow *vw );
43
44typedef struct _VikWebtoolDatasourcePrivate VikWebtoolDatasourcePrivate;
45
46struct _VikWebtoolDatasourcePrivate
47{
48 gchar *url;
49 gchar *url_format_code;
50 gchar *file_type;
51};
52
53#define WEBTOOL_DATASOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
54 VIK_WEBTOOL_DATASOURCE_TYPE, \
55 VikWebtoolDatasourcePrivate))
56
57G_DEFINE_TYPE (VikWebtoolDatasource, vik_webtool_datasource, VIK_WEBTOOL_TYPE)
58
59enum
60{
61 PROP_0,
62 PROP_URL,
63 PROP_URL_FORMAT_CODE,
64 PROP_FILE_TYPE,
65};
66
67static void webtool_datasource_set_property (GObject *object,
68 guint property_id,
69 const GValue *value,
70 GParamSpec *pspec)
71{
72 VikWebtoolDatasource *self = VIK_WEBTOOL_DATASOURCE ( object );
73 VikWebtoolDatasourcePrivate *priv = WEBTOOL_DATASOURCE_GET_PRIVATE ( self );
74
75 switch ( property_id ) {
76 case PROP_URL:
77 g_free ( priv->url );
78 priv->url = g_value_dup_string ( value );
79 g_debug ( "VikWebtoolDatasource.url: %s", priv->url );
80 break;
81
82 case PROP_URL_FORMAT_CODE:
83 g_free ( priv->url_format_code );
84 priv->url_format_code = g_value_dup_string ( value );
85 g_debug ( "VikWebtoolDatasource.url_format_code: %s", priv->url_format_code );
86 break;
87
88 case PROP_FILE_TYPE:
89 g_free ( priv->file_type );
90 priv->file_type = g_value_dup_string ( value );
91 g_debug ( "VikWebtoolDatasource.file_type: %s", priv->url_format_code );
92 break;
93
94 default:
95 /* We don't have any other property... */
96 G_OBJECT_WARN_INVALID_PROPERTY_ID ( object, property_id, pspec );
97 break;
98 }
99}
100
101static void webtool_datasource_get_property (GObject *object,
102 guint property_id,
103 GValue *value,
104 GParamSpec *pspec)
105{
106 VikWebtoolDatasource *self = VIK_WEBTOOL_DATASOURCE ( object );
107 VikWebtoolDatasourcePrivate *priv = WEBTOOL_DATASOURCE_GET_PRIVATE ( self );
108
109 switch ( property_id ) {
110
111 case PROP_URL: g_value_set_string ( value, priv->url ); break;
112 case PROP_URL_FORMAT_CODE: g_value_set_string ( value, priv->url_format_code ); break;
113 case PROP_FILE_TYPE: g_value_set_string ( value, priv->url ); break;
114
115 default:
116 /* We don't have any other property... */
117 G_OBJECT_WARN_INVALID_PROPERTY_ID ( object, property_id, pspec );
118 break;
119 }
120}
121
122typedef struct {
123 VikExtTool *self;
124 VikWindow *vw;
125 VikViewport *vvp;
126} datasource_t;
127
128static gpointer datasource_init ( acq_vik_t *avt )
129{
130 datasource_t *data = g_malloc(sizeof(*data));
131 data->self = avt->userdata;
132 data->vw = avt->vw;
133 data->vvp = avt->vvp;
134 return data;
135}
136
137static void datasource_get_cmd_string ( gpointer user_data, gchar **cmd, gchar **extra, DownloadMapOptions *options )
138{
139 datasource_t *data = (datasource_t*) user_data;
140
141 VikWebtool *vwd = VIK_WEBTOOL ( data->self );
142 gchar *url = vik_webtool_get_url ( vwd, data->vw );
143 g_debug ("%s: %s", __FUNCTION__, url );
144
1aefc7eb 145 *cmd = g_strdup ( url );
82993cc7
RN
146
147 // Only use first section of the file_type string
148 // One can't use values like 'kml -x transform,rte=wpt' in order to do fancy things
149 // since it won't be in the right order for the overall GPSBabel command
150 // So prevent any potentially dangerous behaviour
151 VikWebtoolDatasourcePrivate *priv = WEBTOOL_DATASOURCE_GET_PRIVATE ( data->self );
152 gchar **parts = NULL;
153 if ( priv->file_type )
154 parts = g_strsplit ( priv->file_type, " ", 0);
155 if ( parts )
156 *extra = g_strdup ( parts[0] );
157 else
158 *extra = NULL;
159 g_strfreev ( parts );
160
161 options = NULL;
162}
163
164static gboolean datasource_process ( VikTrwLayer *vtl, const gchar *cmd, const gchar *extra, BabelStatusFunc status_cb, acq_dialog_widgets_t *adw, DownloadMapOptions *options )
165{
166 //datasource_t *data = (datasource_t *)adw->user_data;
167 // Dependent on the ExtTool / what extra has been set to...
168 // When extra is NULL - then it interprets results as a GPX
169 gboolean result = a_babel_convert_from_url ( vtl, cmd, extra, status_cb, adw, options);
170 return result;
171}
172
173static void cleanup ( gpointer data )
174{
175 g_free ( data );
176}
177
178static void webtool_datasource_open ( VikExtTool *self, VikWindow *vw )
179{
180 // Use VikDataSourceInterface to give thready goodness controls of downloading stuff (i.e. can cancel the request)
181
182 // Can now create a 'VikDataSourceInterface' on the fly...
183 VikDataSourceInterface *vik_datasource_interface = g_malloc(sizeof(VikDataSourceInterface));
184
185 // An 'easy' way of assigning values
186 VikDataSourceInterface data = {
187 vik_ext_tool_get_label (self),
188 vik_ext_tool_get_label (self),
189 VIK_DATASOURCE_ADDTOLAYER,
190 VIK_DATASOURCE_INPUTTYPE_NONE,
191 FALSE, // Maintain current view - rather than setting it to the acquired points
192 TRUE,
193 TRUE,
194 (VikDataSourceInitFunc) datasource_init,
195 (VikDataSourceCheckExistenceFunc) NULL,
196 (VikDataSourceAddSetupWidgetsFunc) NULL,
197 (VikDataSourceGetCmdStringFunc) datasource_get_cmd_string,
198 (VikDataSourceProcessFunc) datasource_process,
199 (VikDataSourceProgressFunc) NULL,
200 (VikDataSourceAddProgressWidgetsFunc) NULL,
201 (VikDataSourceCleanupFunc) cleanup,
202 (VikDataSourceOffFunc) NULL,
203 NULL,
204 0,
205 NULL,
206 NULL,
207 0
208 };
209 memcpy ( vik_datasource_interface, &data, sizeof(VikDataSourceInterface) );
210
211 a_acquire ( vw, vik_window_layers_panel(vw), vik_window_viewport (vw), vik_datasource_interface, self, cleanup );
212}
213
214static void vik_webtool_datasource_class_init ( VikWebtoolDatasourceClass *klass )
215{
216 GObjectClass *gobject_class;
217 VikWebtoolClass *base_class;
218 GParamSpec *pspec;
219
220 gobject_class = G_OBJECT_CLASS (klass);
221
222 gobject_class->finalize = webtool_datasource_finalize;
223 gobject_class->set_property = webtool_datasource_set_property;
224 gobject_class->get_property = webtool_datasource_get_property;
225
226 pspec = g_param_spec_string ("url",
227 "Template URL",
228 "Set the template URL",
229 VIKING_URL /* default value */,
230 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
231 g_object_class_install_property (gobject_class,
232 PROP_URL,
233 pspec);
234
235 pspec = g_param_spec_string ("url_format_code",
236 "Template URL Format Code",
237 "Set the template URL format code",
238 "LRBT", // default value
239 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
240 g_object_class_install_property (gobject_class,
241 PROP_URL_FORMAT_CODE,
242 pspec);
243
244 pspec = g_param_spec_string ("file_type",
245 "The file type expected",
246 "Set the file type",
247 NULL, // default value ~ equates to internal GPX reading
248 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
249 g_object_class_install_property (gobject_class,
250 PROP_FILE_TYPE,
251 pspec);
252
253 parent_class = g_type_class_peek_parent (klass);
254
255 base_class = VIK_WEBTOOL_CLASS ( klass );
256 base_class->get_url = webtool_datasource_get_url;
257
258 // Override default open function here:
259 VikExtToolClass *ext_tool_class = VIK_EXT_TOOL_CLASS ( klass );
260 ext_tool_class->open = webtool_datasource_open;
261
262 g_type_class_add_private (klass, sizeof (VikWebtoolDatasourcePrivate));
263}
264
265VikWebtoolDatasource *vik_webtool_datasource_new ()
266{
267 return VIK_WEBTOOL_DATASOURCE ( g_object_new ( VIK_WEBTOOL_DATASOURCE_TYPE, NULL ) );
268}
269
270VikWebtoolDatasource *vik_webtool_datasource_new_with_members ( const gchar *label,
271 const gchar *url,
272 const gchar *url_format_code,
273 const gchar *file_type )
274{
275 VikWebtoolDatasource *result = VIK_WEBTOOL_DATASOURCE ( g_object_new ( VIK_WEBTOOL_DATASOURCE_TYPE,
276 "label", label,
277 "url", url,
278 "url_format_code", url_format_code,
279 "file_type", file_type,
280 NULL ) );
281
282 return result;
283}
284
285static void vik_webtool_datasource_init ( VikWebtoolDatasource *self )
286{
287 VikWebtoolDatasourcePrivate *priv = WEBTOOL_DATASOURCE_GET_PRIVATE (self);
288 priv->url = NULL;
289 priv->url_format_code = NULL;
290 priv->file_type = NULL;
291}
292
293static void webtool_datasource_finalize ( GObject *gob )
294{
295 VikWebtoolDatasourcePrivate *priv = WEBTOOL_DATASOURCE_GET_PRIVATE ( gob );
296 g_free ( priv->url ); priv->url = NULL;
297 g_free ( priv->url_format_code ); priv->url_format_code = NULL;
298 g_free ( priv->file_type ); priv->file_type = NULL;
299 G_OBJECT_CLASS(parent_class)->finalize(gob);
300}
301
302#define MAX_NUMBER_CODES 7
303
304/**
305 * Calculate individual elements (similarly to the VikWebtool Bounds & Center) for *all* potential values
306 * Then only values specified by the URL format are used in parameterizing the URL
307 */
308static gchar *webtool_datasource_get_url ( VikWebtool *self, VikWindow *vw )
309{
310 VikWebtoolDatasourcePrivate *priv = WEBTOOL_DATASOURCE_GET_PRIVATE ( self );
311 VikViewport *viewport = vik_window_viewport ( vw );
312
313 // Get top left and bottom right lat/lon pairs from the viewport
314 gdouble min_lat, max_lat, min_lon, max_lon;
315 gchar sminlon[G_ASCII_DTOSTR_BUF_SIZE];
316 gchar smaxlon[G_ASCII_DTOSTR_BUF_SIZE];
317 gchar sminlat[G_ASCII_DTOSTR_BUF_SIZE];
318 gchar smaxlat[G_ASCII_DTOSTR_BUF_SIZE];
319 vik_viewport_get_min_max_lat_lon ( viewport, &min_lat, &max_lat, &min_lon, &max_lon );
320
321 // Cannot simply use g_strdup_printf and gdouble due to locale.
322 // As we compute an URL, we have to think in C locale.
323 g_ascii_dtostr (sminlon, G_ASCII_DTOSTR_BUF_SIZE, min_lon);
324 g_ascii_dtostr (smaxlon, G_ASCII_DTOSTR_BUF_SIZE, max_lon);
325 g_ascii_dtostr (sminlat, G_ASCII_DTOSTR_BUF_SIZE, min_lat);
326 g_ascii_dtostr (smaxlat, G_ASCII_DTOSTR_BUF_SIZE, max_lat);
327
328 // Center values
329 const VikCoord *coord = vik_viewport_get_center ( viewport );
330 struct LatLon ll;
331 vik_coord_to_latlon ( coord, &ll );
332
333 gchar scenterlat[G_ASCII_DTOSTR_BUF_SIZE];
334 gchar scenterlon[G_ASCII_DTOSTR_BUF_SIZE];
335 g_ascii_dtostr (scenterlat, G_ASCII_DTOSTR_BUF_SIZE, ll.lat);
336 g_ascii_dtostr (scenterlon, G_ASCII_DTOSTR_BUF_SIZE, ll.lon);
337
338 guint8 zoom = 17; // A zoomed in default
339 // zoom - ideally x & y factors need to be the same otherwise use the default
340 if ( vik_viewport_get_xmpp ( viewport ) == vik_viewport_get_ympp ( viewport ) )
3957ef85 341 zoom = map_utils_mpp_to_zoom_level ( vik_viewport_get_zoom ( viewport ) );
82993cc7
RN
342
343 gchar szoom[G_ASCII_DTOSTR_BUF_SIZE];
344 g_snprintf ( szoom, G_ASCII_DTOSTR_BUF_SIZE, "%d", zoom );
345
346 gint len = 0;
347 if ( priv->url_format_code )
348 len = strlen ( priv->url_format_code );
349 if ( len > MAX_NUMBER_CODES )
350 len = MAX_NUMBER_CODES;
351
352 gchar* values[MAX_NUMBER_CODES];
353 int i;
354 for ( i = 0; i < MAX_NUMBER_CODES; i++ ) {
644eea0e 355 values[i] = '\0';
82993cc7
RN
356 }
357
358 for ( i = 0; i < len; i++ ) {
359 switch ( g_ascii_toupper ( priv->url_format_code[i] ) ) {
360 case 'L': values[i] = g_strdup ( sminlon ); break;
361 case 'R': values[i] = g_strdup ( smaxlon ); break;
362 case 'B': values[i] = g_strdup ( sminlat ); break;
363 case 'T': values[i] = g_strdup ( smaxlat ); break;
364 case 'A': values[i] = g_strdup ( scenterlat ); break;
365 case 'O': values[i] = g_strdup ( scenterlon ); break;
366 case 'Z': values[i] = g_strdup ( szoom ); break;
367 default: break;
368 }
369 }
370
371 gchar *url = g_strdup_printf ( priv->url, values[0], values[1], values[2], values[3], values[4], values[5], values[6] );
372
373 for ( i = 0; i < MAX_NUMBER_CODES; i++ ) {
644eea0e
RN
374 if ( values[i] != '\0' )
375 g_free ( values[i] );
82993cc7
RN
376 }
377
378 return url;
379}