]> git.street.me.uk Git - andy/viking.git/blob - src/datasource_bfilter.c
[QA] Reusable function for freeing the waypoint image cache.
[andy/viking.git] / src / datasource_bfilter.c
1 /*
2  * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3  *
4  * Copyright (C) 2003-2007, Evan Battaglia <gtoevan@gmx.net>
5  * Copyright (C) 2014-2015, 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  * See: http://www.gpsbabel.org/htmldoc-development/Data_Filters.html
22  */
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26 #include <string.h>
27 #include <glib/gi18n.h>
28
29 #include "viking.h"
30 #include "babel.h"
31 #include "gpx.h"
32 #include "acquire.h"
33 #include "settings.h"
34
35 /************************************ Simplify (Count) *****************************/
36
37 /* spin button scales */
38 VikLayerParamScale simplify_params_scales[] = {
39   {1, 10000, 10, 0},
40 };
41
42 VikLayerParam bfilter_simplify_params[] = {
43   { VIK_LAYER_NUM_TYPES, "numberofpoints", VIK_LAYER_PARAM_UINT, VIK_LAYER_GROUP_NONE, N_("Max number of points:"), VIK_LAYER_WIDGET_SPINBUTTON, simplify_params_scales, NULL, NULL, NULL, NULL, NULL },
44 };
45
46 VikLayerParamData bfilter_simplify_params_defaults[] = {
47   /* Annoyingly 'C' cannot initialize unions properly */
48   /* It's dependent on the standard used or the compiler support... */
49 #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L || __GNUC__
50   { .u = 100 },
51 #else
52   { 100 },
53 #endif
54 };
55
56 static void datasource_bfilter_simplify_get_process_options ( VikLayerParamData *paramdatas, ProcessOptions *po, gpointer not_used, const gchar *input_filename, const gchar *not_used3 )
57 {
58   po->babelargs = g_strdup ( "-i gpx" );
59   po->filename = g_strdup ( input_filename );
60   po->babel_filters = g_strdup_printf ( "-x simplify,count=%d", paramdatas[0].u );
61
62   // Store for subsequent default use
63   bfilter_simplify_params_defaults[0].u = paramdatas[0].u;
64 }
65
66 #define VIK_SETTINGS_BFILTER_SIMPLIFY "bfilter_simplify"
67 static gboolean bfilter_simplify_default_set = FALSE;
68
69 static gpointer datasource_bfilter_simplify_init ( acq_vik_t *not_used )
70 {
71   if ( !bfilter_simplify_default_set ) {
72     gint tmp;
73     if ( !a_settings_get_integer ( VIK_SETTINGS_BFILTER_SIMPLIFY, &tmp ) )
74       tmp = 100;
75
76     bfilter_simplify_params_defaults[0].u = tmp;
77     bfilter_simplify_default_set = TRUE;
78   }
79
80   return NULL;
81 }
82
83 VikDataSourceInterface vik_datasource_bfilter_simplify_interface = {
84   N_("Simplify All Tracks..."),
85   N_("Simplified Tracks"),
86   VIK_DATASOURCE_CREATENEWLAYER,
87   VIK_DATASOURCE_INPUTTYPE_TRWLAYER,
88   TRUE,
89   FALSE, /* keep dialog open after success */
90   TRUE,
91   (VikDataSourceInitFunc)              datasource_bfilter_simplify_init,
92   NULL, NULL,
93   (VikDataSourceGetProcessOptionsFunc) datasource_bfilter_simplify_get_process_options,
94   (VikDataSourceProcessFunc)           a_babel_convert_from,
95   NULL, NULL, NULL,
96   (VikDataSourceOffFunc) NULL,
97
98   bfilter_simplify_params,
99   sizeof(bfilter_simplify_params)/sizeof(bfilter_simplify_params[0]),
100   bfilter_simplify_params_defaults,
101   NULL,
102   0
103 };
104
105 /**************************** Compress (Simplify by Error Factor Method) *****************************/
106
107 static VikLayerParamScale compress_spin_scales[] = { {0.0, 1.000, 0.001, 3} };
108
109 VikLayerParam bfilter_compress_params[] = {
110   //{ VIK_LAYER_NUM_TYPES, "compressmethod", VIK_LAYER_PARAM_UINT, VIK_LAYER_GROUP_NONE, N_("Simplify Method:"), VIK_LAYER_WIDGET_COMBOBOX, compress_method, NULL, NULL, NULL, NULL, NULL },
111   { VIK_LAYER_NUM_TYPES, "compressfactor", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_GROUP_NONE, N_("Error Factor:"), VIK_LAYER_WIDGET_SPINBUTTON, compress_spin_scales, NULL,
112       N_("Specifies the maximum allowable error that may be introduced by removing a single point by the crosstrack method. See the manual or GPSBabel Simplify Filter documentation for more detail."), NULL, NULL, NULL },
113 };
114
115 VikLayerParamData bfilter_compress_params_defaults[] = {
116   /* Annoyingly 'C' cannot initialize unions properly */
117   /* It's dependent on the standard used or the compiler support... */
118 #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L || __GNUC__
119   { .d = 0.001 },
120 #else
121   { 0.001 },
122 #endif
123 };
124
125 /**
126  * http://www.gpsbabel.org/htmldoc-development/filter_simplify.html
127  */
128 static void datasource_bfilter_compress_get_process_options ( VikLayerParamData *paramdatas, ProcessOptions *po, gpointer not_used, const gchar *input_filename, const gchar *not_used3 )
129 {
130   gchar units = a_vik_get_units_distance() == VIK_UNITS_DISTANCE_KILOMETRES ? 'k' : ' ';
131   // I toyed with making the length,crosstrack or relative methods selectable
132   // However several things:
133   // - mainly that typical values to use for the error relate to method being used - so hard to explain and then give a default sensible value in the UI
134   // - also using relative method fails when track doesn't have HDOP info - error reported to stderr - which we don't capture ATM
135   // - options make this more complicated to use - is even that useful to be allowed to change the error value?
136   // NB units not applicable if relative method used - defaults to Miles when not specified
137   po->babelargs = g_strdup ( "-i gpx" );
138   po->filename = g_strdup ( input_filename );
139   po->babel_filters = g_strdup_printf ( "-x simplify,crosstrack,error=%-.5f%c", paramdatas[0].d, units );
140
141   // Store for subsequent default use
142   bfilter_compress_params_defaults[0].d = paramdatas[0].d;
143 }
144
145 #define VIK_SETTINGS_BFILTER_COMPRESS "bfilter_compress"
146 static gboolean bfilter_compress_default_set = FALSE;
147
148 static gpointer datasource_bfilter_compress_init ( acq_vik_t *not_used )
149 {
150   if ( !bfilter_compress_default_set ) {
151     gdouble tmp;
152     if ( !a_settings_get_double ( VIK_SETTINGS_BFILTER_COMPRESS, &tmp ) )
153       tmp = 0.001;
154
155     bfilter_compress_params_defaults[0].d = tmp;
156     bfilter_compress_default_set = TRUE;
157   }
158
159   return NULL;
160 }
161
162 /**
163  * Allow 'compressing' tracks/routes using the Simplify by Error Factor method
164  */
165 VikDataSourceInterface vik_datasource_bfilter_compress_interface = {
166   N_("Compress Tracks..."),
167   N_("Compressed Tracks"),
168   VIK_DATASOURCE_CREATENEWLAYER,
169   VIK_DATASOURCE_INPUTTYPE_TRWLAYER,
170   TRUE,
171   FALSE, // Close the dialog after successful operation
172   TRUE,
173   (VikDataSourceInitFunc)              datasource_bfilter_compress_init,
174   NULL, NULL,
175   (VikDataSourceGetProcessOptionsFunc) datasource_bfilter_compress_get_process_options,
176   (VikDataSourceProcessFunc)           a_babel_convert_from,
177   NULL, NULL, NULL,
178   (VikDataSourceOffFunc) NULL,
179
180   bfilter_compress_params,
181   sizeof(bfilter_compress_params)/sizeof(bfilter_compress_params[0]),
182   bfilter_compress_params_defaults,
183   NULL,
184   0
185 };
186
187 /************************************ Duplicate Location ***********************************/
188
189 static void datasource_bfilter_dup_get_process_options ( VikLayerParamData *paramdatas, ProcessOptions *po, gpointer not_used, const gchar *input_filename, const gchar *not_used3 )
190 {
191   po->babelargs = g_strdup ( "-i gpx" );
192   po->filename = g_strdup ( input_filename );
193   po->babel_filters = g_strdup ( "-x duplicate,location" );
194 }
195
196 VikDataSourceInterface vik_datasource_bfilter_dup_interface = {
197   N_("Remove Duplicate Waypoints"),
198   N_("Remove Duplicate Waypoints"),
199   VIK_DATASOURCE_CREATENEWLAYER,
200   VIK_DATASOURCE_INPUTTYPE_TRWLAYER,
201   TRUE,
202   FALSE, /* keep dialog open after success */
203   TRUE,
204   NULL, NULL, NULL,
205   (VikDataSourceGetProcessOptionsFunc) datasource_bfilter_dup_get_process_options,
206   (VikDataSourceProcessFunc)           a_babel_convert_from,
207   NULL, NULL, NULL,
208   (VikDataSourceOffFunc) NULL,
209
210   NULL, 0, NULL, NULL, 0
211 };
212
213
214 /************************************ Swap Lat<->Lon ***********************************/
215
216 VikLayerParamData bfilter_manual_params_defaults[] = {
217   { .s = NULL },
218 };
219
220 VikLayerParam bfilter_manual_params[] = {
221   { VIK_LAYER_NUM_TYPES, "manual", VIK_LAYER_PARAM_STRING, VIK_LAYER_GROUP_NONE, N_("Manual filter:"), VIK_LAYER_WIDGET_ENTRY, NULL, NULL,
222       N_("Manual filter command: e.g. 'swap'."), NULL, NULL, NULL },
223 };
224
225 static void datasource_bfilter_manual_get_process_options ( VikLayerParamData *paramdatas, ProcessOptions *po, gpointer not_used, const gchar *input_filename, const gchar *not_used3 )
226 {
227   po->babelargs = g_strdup ( "-i gpx" );
228   po->filename = g_strdup ( input_filename );
229   po->babel_filters = g_strconcat ( "-x ", paramdatas[0].s, NULL );
230 }
231
232 VikDataSourceInterface vik_datasource_bfilter_manual_interface = {
233   N_("Manual filter"),
234   N_("Manual filter"),
235   VIK_DATASOURCE_CREATENEWLAYER,
236   VIK_DATASOURCE_INPUTTYPE_TRWLAYER,
237   TRUE,
238   FALSE, /* keep dialog open after success */
239   TRUE,
240   NULL, NULL, NULL,
241   (VikDataSourceGetProcessOptionsFunc) datasource_bfilter_manual_get_process_options,
242   (VikDataSourceProcessFunc)           a_babel_convert_from,
243   NULL, NULL, NULL,
244   (VikDataSourceOffFunc) NULL,
245
246   bfilter_manual_params,
247   sizeof(bfilter_manual_params)/sizeof(bfilter_manual_params[0]),
248   bfilter_manual_params_defaults,
249   NULL,
250   0
251 };
252
253 /************************************ Polygon ***********************************/
254
255 static void datasource_bfilter_polygon_get_process_options ( VikLayerParamData *paramdatas, ProcessOptions *po, gpointer not_used, const gchar *input_filename, const gchar *input_track_filename )
256 {
257   po->shell_command = g_strdup_printf ( "gpsbabel -i gpx -f %s -o arc -F - | gpsbabel -i gpx -f %s -x polygon,file=- -o gpx -F -", input_track_filename, input_filename );
258 }
259 /* TODO: shell_escape stuff */
260
261 VikDataSourceInterface vik_datasource_bfilter_polygon_interface = {
262   N_("Waypoints Inside This"),
263   N_("Polygonized Layer"),
264   VIK_DATASOURCE_CREATENEWLAYER,
265   VIK_DATASOURCE_INPUTTYPE_TRWLAYER_TRACK,
266   TRUE,
267   FALSE, /* keep dialog open after success */
268   TRUE,
269   NULL, NULL, NULL,
270   (VikDataSourceGetProcessOptionsFunc) datasource_bfilter_polygon_get_process_options,
271   (VikDataSourceProcessFunc)           a_babel_convert_from,
272   NULL, NULL, NULL,
273   (VikDataSourceOffFunc) NULL,
274
275   NULL,
276   0,
277   NULL,
278   NULL,
279   0
280 };
281
282 /************************************ Exclude Polygon ***********************************/
283
284 static void datasource_bfilter_exclude_polygon_get_process_options ( VikLayerParamData *paramdatas, ProcessOptions *po, gpointer not_used, const gchar *input_filename, const gchar *input_track_filename )
285 {
286   po->shell_command = g_strdup_printf ( "gpsbabel -i gpx -f %s -o arc -F - | gpsbabel -i gpx -f %s -x polygon,exclude,file=- -o gpx -F -", input_track_filename, input_filename );
287 }
288 /* TODO: shell_escape stuff */
289
290 VikDataSourceInterface vik_datasource_bfilter_exclude_polygon_interface = {
291   N_("Waypoints Outside This"),
292   N_("Polygonzied Layer"),
293   VIK_DATASOURCE_CREATENEWLAYER,
294   VIK_DATASOURCE_INPUTTYPE_TRWLAYER_TRACK,
295   TRUE,
296   FALSE, /* keep dialog open after success */
297   TRUE,
298   NULL, NULL, NULL,
299   (VikDataSourceGetProcessOptionsFunc) datasource_bfilter_exclude_polygon_get_process_options,
300   (VikDataSourceProcessFunc)           a_babel_convert_from,
301   NULL, NULL, NULL,
302   (VikDataSourceOffFunc) NULL,
303
304   NULL,
305   0,
306   NULL,
307   NULL,
308   0
309 };