]>
Commit | Line | Data |
---|---|---|
3333c069 EB |
1 | /* |
2 | * viking -- GPS Data and Topo Analyzer, Explorer, and Manager | |
3 | * | |
a482007a | 4 | * Copyright (C) 2003-2007, Evan Battaglia <gtoevan@gmx.net> |
17acdaec | 5 | * Copyright (C) 2015, Rob Norris <rw_norris@hotmail.com> |
3333c069 EB |
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 | */ | |
8aad4ca3 | 22 | #ifdef HAVE_CONFIG_H |
08a1fa12 | 23 | #include "config.h" |
8aad4ca3 | 24 | #endif |
1ef9e637 | 25 | #ifdef VIK_CONFIG_GEOCACHES |
3333c069 EB |
26 | #include <string.h> |
27 | ||
4c77d5e0 | 28 | #include <glib/gi18n.h> |
28c82d8b | 29 | |
3333c069 EB |
30 | #include "viking.h" |
31 | #include "babel.h" | |
32 | #include "gpx.h" | |
33 | #include "acquire.h" | |
a5c8699d EB |
34 | #include "preferences.h" |
35 | ||
5f96aa1a RN |
36 | // Could have an array of programs instead... |
37 | #define GC_PROGRAM1 "geo-nearest" | |
38 | #define GC_PROGRAM2 "geo-html2gpx" | |
39 | ||
a5c8699d EB |
40 | /* params will be geocaching.username, geocaching.password */ |
41 | /* we have to make sure these don't collide. */ | |
42 | #define VIKING_GC_PARAMS_GROUP_KEY "geocaching" | |
43 | #define VIKING_GC_PARAMS_NAMESPACE "geocaching." | |
44 | ||
3333c069 EB |
45 | |
46 | typedef struct { | |
47 | GtkWidget *num_spin; | |
5f96aa1a | 48 | GtkWidget *center_entry; // TODO make separate widgets for lat/lon |
28c82d8b EB |
49 | GtkWidget *miles_radius_spin; |
50 | ||
51 | GdkGC *circle_gc; | |
52 | VikViewport *vvp; | |
53 | gboolean circle_onscreen; | |
54 | gint circle_x, circle_y, circle_width; | |
3333c069 EB |
55 | } datasource_gc_widgets_t; |
56 | ||
57 | ||
307abf54 | 58 | static gpointer datasource_gc_init ( acq_vik_t *avt ); |
65f0ccab | 59 | static void datasource_gc_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data ); |
17acdaec | 60 | static void datasource_gc_get_process_options ( datasource_gc_widgets_t *widgets, ProcessOptions *po, gpointer not_used, const gchar *not_used2, const gchar *not_used3 ); |
28c82d8b | 61 | static void datasource_gc_cleanup ( datasource_gc_widgets_t *widgets ); |
92255687 | 62 | static gchar *datasource_gc_check_existence (); |
3333c069 | 63 | |
28c82d8b EB |
64 | #define METERSPERMILE 1609.344 |
65 | ||
3333c069 | 66 | VikDataSourceInterface vik_datasource_gc_interface = { |
4c77d5e0 GB |
67 | N_("Download Geocaches"), |
68 | N_("Geocaching.com Caches"), | |
9cc13848 | 69 | VIK_DATASOURCE_AUTO_LAYER_MANAGEMENT, |
28c82d8b | 70 | VIK_DATASOURCE_INPUTTYPE_NONE, |
5f96aa1a | 71 | TRUE, // Yes automatically update the display - otherwise we won't see the geocache waypoints! |
28c82d8b | 72 | TRUE, |
b623177a | 73 | TRUE, |
65f0ccab | 74 | (VikDataSourceInitFunc) datasource_gc_init, |
92255687 | 75 | (VikDataSourceCheckExistenceFunc) datasource_gc_check_existence, |
65f0ccab | 76 | (VikDataSourceAddSetupWidgetsFunc) datasource_gc_add_setup_widgets, |
17acdaec RN |
77 | (VikDataSourceGetProcessOptionsFunc) datasource_gc_get_process_options, |
78 | (VikDataSourceProcessFunc) a_babel_convert_from, | |
3333c069 EB |
79 | (VikDataSourceProgressFunc) NULL, |
80 | (VikDataSourceAddProgressWidgetsFunc) NULL, | |
2b756ea0 RN |
81 | (VikDataSourceCleanupFunc) datasource_gc_cleanup, |
82 | (VikDataSourceOffFunc) NULL, | |
3333c069 EB |
83 | }; |
84 | ||
a5c8699d | 85 | static VikLayerParam prefs[] = { |
a87f8fa1 RN |
86 | { VIK_LAYER_NUM_TYPES, VIKING_GC_PARAMS_NAMESPACE "username", VIK_LAYER_PARAM_STRING, VIK_LAYER_GROUP_NONE, N_("geocaching.com username:"), VIK_LAYER_WIDGET_ENTRY, NULL, NULL, NULL, NULL, NULL }, |
87 | { VIK_LAYER_NUM_TYPES, VIKING_GC_PARAMS_NAMESPACE "password", VIK_LAYER_PARAM_STRING, VIK_LAYER_GROUP_NONE, N_("geocaching.com password:"), VIK_LAYER_WIDGET_ENTRY, NULL, NULL, NULL, NULL, NULL }, | |
a5c8699d EB |
88 | }; |
89 | ||
90 | void a_datasource_gc_init() | |
91 | { | |
92 | a_preferences_register_group ( VIKING_GC_PARAMS_GROUP_KEY, "Geocaching" ); | |
93 | ||
94 | VikLayerParamData tmp; | |
95 | tmp.s = "username"; | |
96 | a_preferences_register(prefs, tmp, VIKING_GC_PARAMS_GROUP_KEY); | |
97 | tmp.s = "password"; | |
98 | a_preferences_register(prefs+1, tmp, VIKING_GC_PARAMS_GROUP_KEY); | |
99 | } | |
100 | ||
101 | ||
307abf54 | 102 | static gpointer datasource_gc_init ( acq_vik_t *avt ) |
65f0ccab AF |
103 | { |
104 | datasource_gc_widgets_t *widgets = g_malloc(sizeof(*widgets)); | |
105 | return widgets; | |
106 | } | |
107 | ||
92255687 EB |
108 | static gchar *datasource_gc_check_existence () |
109 | { | |
5f96aa1a RN |
110 | gboolean OK1 = FALSE; |
111 | gboolean OK2 = FALSE; | |
112 | ||
113 | gchar *location1 = g_find_program_in_path(GC_PROGRAM1); | |
114 | if ( location1 ) { | |
115 | g_free(location1); | |
116 | OK1 = TRUE; | |
92255687 | 117 | } |
5f96aa1a RN |
118 | |
119 | gchar *location2 = g_find_program_in_path(GC_PROGRAM2); | |
120 | if ( location2 ) { | |
121 | g_free(location2); | |
122 | OK2 = TRUE; | |
123 | } | |
124 | ||
125 | if ( OK1 && OK2 ) | |
126 | return NULL; | |
127 | ||
128 | return g_strdup_printf(_("Can't find %s or %s in path! Check that you have installed it correctly."), GC_PROGRAM1, GC_PROGRAM2); | |
92255687 | 129 | } |
3333c069 | 130 | |
28c82d8b EB |
131 | static void datasource_gc_draw_circle ( datasource_gc_widgets_t *widgets ) |
132 | { | |
133 | gdouble lat, lon; | |
134 | if ( widgets->circle_onscreen ) { | |
135 | vik_viewport_draw_arc ( widgets->vvp, widgets->circle_gc, FALSE, | |
136 | widgets->circle_x - widgets->circle_width/2, | |
137 | widgets->circle_y - widgets->circle_width/2, | |
138 | widgets->circle_width, widgets->circle_width, 0, 360*64 ); | |
139 | } | |
140 | /* calculate widgets circle_x and circle_y */ | |
141 | /* split up lat,lon into lat and lon */ | |
142 | if ( 2 == sscanf ( gtk_entry_get_text ( GTK_ENTRY(widgets->center_entry) ), "%lf,%lf", &lat, &lon ) ) { | |
143 | struct LatLon ll; | |
144 | VikCoord c; | |
145 | gint x, y; | |
146 | ||
147 | ll.lat = lat; ll.lon = lon; | |
148 | vik_coord_load_from_latlon ( &c, vik_viewport_get_coord_mode ( widgets->vvp ), &ll ); | |
149 | vik_viewport_coord_to_screen ( widgets->vvp, &c, &x, &y ); | |
150 | /* TODO: real calculation */ | |
151 | if ( x > -1000 && y > -1000 && x < (vik_viewport_get_width(widgets->vvp) + 1000) && | |
152 | y < (vik_viewport_get_width(widgets->vvp) + 1000) ) { | |
153 | VikCoord c1, c2; | |
154 | gdouble pixels_per_meter; | |
155 | ||
156 | widgets->circle_x = x; | |
157 | widgets->circle_y = y; | |
158 | ||
159 | /* determine miles per pixel */ | |
160 | vik_viewport_screen_to_coord ( widgets->vvp, 0, vik_viewport_get_height(widgets->vvp)/2, &c1 ); | |
161 | vik_viewport_screen_to_coord ( widgets->vvp, vik_viewport_get_width(widgets->vvp), vik_viewport_get_height(widgets->vvp)/2, &c2 ); | |
162 | pixels_per_meter = ((gdouble)vik_viewport_get_width(widgets->vvp)) / vik_coord_diff(&c1, &c2); | |
163 | ||
164 | /* this is approximate */ | |
165 | widgets->circle_width = gtk_spin_button_get_value_as_float ( GTK_SPIN_BUTTON(widgets->miles_radius_spin) ) | |
166 | * METERSPERMILE * pixels_per_meter * 2; | |
167 | ||
168 | vik_viewport_draw_arc ( widgets->vvp, widgets->circle_gc, FALSE, | |
169 | widgets->circle_x - widgets->circle_width/2, | |
170 | widgets->circle_y - widgets->circle_width/2, | |
171 | widgets->circle_width, widgets->circle_width, 0, 360*64 ); | |
172 | ||
173 | widgets->circle_onscreen = TRUE; | |
174 | } else | |
175 | widgets->circle_onscreen = FALSE; | |
176 | } | |
177 | ||
178 | /* see if onscreen */ | |
179 | /* okay */ | |
180 | vik_viewport_sync ( widgets->vvp ); | |
181 | } | |
182 | ||
65f0ccab | 183 | static void datasource_gc_add_setup_widgets ( GtkWidget *dialog, VikViewport *vvp, gpointer user_data ) |
3333c069 | 184 | { |
65f0ccab | 185 | datasource_gc_widgets_t *widgets = (datasource_gc_widgets_t *)user_data; |
28c82d8b | 186 | GtkWidget *num_label, *center_label, *miles_radius_label; |
3333c069 EB |
187 | struct LatLon ll; |
188 | gchar *s_ll; | |
189 | ||
4c77d5e0 | 190 | num_label = gtk_label_new (_("Number geocaches:")); |
5f96aa1a | 191 | widgets->num_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new( 20, 1, 1000, 10, 20, 0 )), 10, 0 ); |
4c77d5e0 | 192 | center_label = gtk_label_new (_("Centered around:")); |
3333c069 | 193 | widgets->center_entry = gtk_entry_new(); |
28c82d8b | 194 | miles_radius_label = gtk_label_new ("Miles Radius:"); |
5f96aa1a | 195 | widgets->miles_radius_spin = gtk_spin_button_new ( GTK_ADJUSTMENT(gtk_adjustment_new( 5, 1, 1000, 1, 20, 0 )), 25, 1 ); |
3333c069 EB |
196 | |
197 | vik_coord_to_latlon ( vik_viewport_get_center(vvp), &ll ); | |
198 | s_ll = g_strdup_printf("%f,%f", ll.lat, ll.lon ); | |
199 | gtk_entry_set_text ( GTK_ENTRY(widgets->center_entry), s_ll ); | |
200 | g_free ( s_ll ); | |
201 | ||
28c82d8b EB |
202 | |
203 | widgets->vvp = vvp; | |
204 | widgets->circle_gc = vik_viewport_new_gc ( vvp, "#000000", 3 ); | |
205 | gdk_gc_set_function ( widgets->circle_gc, GDK_INVERT ); | |
5f96aa1a | 206 | widgets->circle_onscreen = TRUE; |
28c82d8b EB |
207 | datasource_gc_draw_circle ( widgets ); |
208 | ||
209 | g_signal_connect_swapped ( G_OBJECT(widgets->center_entry), "changed", G_CALLBACK(datasource_gc_draw_circle), widgets ); | |
210 | g_signal_connect_swapped ( G_OBJECT(widgets->miles_radius_spin), "value-changed", G_CALLBACK(datasource_gc_draw_circle), widgets ); | |
211 | ||
0328eaf5 GB |
212 | /* Packing all these widgets */ |
213 | GtkBox *box = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))); | |
214 | gtk_box_pack_start ( box, num_label, FALSE, FALSE, 5 ); | |
215 | gtk_box_pack_start ( box, widgets->num_spin, FALSE, FALSE, 5 ); | |
216 | gtk_box_pack_start ( box, center_label, FALSE, FALSE, 5 ); | |
217 | gtk_box_pack_start ( box, widgets->center_entry, FALSE, FALSE, 5 ); | |
218 | gtk_box_pack_start ( box, miles_radius_label, FALSE, FALSE, 5 ); | |
219 | gtk_box_pack_start ( box, widgets->miles_radius_spin, FALSE, FALSE, 5 ); | |
3333c069 | 220 | gtk_widget_show_all(dialog); |
3333c069 EB |
221 | } |
222 | ||
17acdaec | 223 | static void datasource_gc_get_process_options ( datasource_gc_widgets_t *widgets, ProcessOptions *po, gpointer not_used, const gchar *not_used2, const gchar *not_used3 ) |
3333c069 | 224 | { |
5f96aa1a | 225 | //gchar *safe_string = g_shell_quote ( gtk_entry_get_text ( GTK_ENTRY(widgets->center_entry) ) ); |
a5c8699d EB |
226 | gchar *safe_user = g_shell_quote ( a_preferences_get ( VIKING_GC_PARAMS_NAMESPACE "username")->s ); |
227 | gchar *safe_pass = g_shell_quote ( a_preferences_get ( VIKING_GC_PARAMS_NAMESPACE "password")->s ); | |
5dc7ffd5 | 228 | gchar *slat, *slon; |
5f96aa1a RN |
229 | gdouble lat, lon; |
230 | if ( 2 != sscanf ( gtk_entry_get_text ( GTK_ENTRY(widgets->center_entry) ), "%lf,%lf", &lat, &lon ) ) { | |
231 | g_warning (_("Broken input - using some defaults")); | |
232 | lat = a_vik_get_default_lat(); | |
233 | lon = a_vik_get_default_long(); | |
234 | } | |
5dc7ffd5 GB |
235 | // Convert double as string in C locale |
236 | slat = a_coords_dtostr ( lat ); | |
237 | slon = a_coords_dtostr ( lon ); | |
5f96aa1a RN |
238 | |
239 | // Unix specific shell commands | |
240 | // 1. Remove geocache webpages (maybe be from different location) | |
241 | // 2, Gets upto n geocaches as webpages for the specified user in radius r Miles | |
242 | // 3. Converts webpages into a single waypoint file, ignoring zero location waypoints '-z' | |
243 | // Probably as they are premium member only geocaches and user is only a basic member | |
244 | // Final output is piped into GPSbabel - hence removal of *html is done at beginning of the command sequence | |
8d2d169f | 245 | po->shell_command = g_strdup_printf( "rm -f ~/.geo/caches/*.html ; %s -H ~/.geo/caches -P -n%d -r%.1fM -u %s -p %s %s %s ; %s -z ~/.geo/caches/*.html ", |
5f96aa1a RN |
246 | GC_PROGRAM1, |
247 | gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(widgets->num_spin) ), | |
248 | gtk_spin_button_get_value_as_float ( GTK_SPIN_BUTTON(widgets->miles_radius_spin) ), | |
249 | safe_user, | |
250 | safe_pass, | |
5dc7ffd5 | 251 | slat, slon, |
5f96aa1a | 252 | GC_PROGRAM2 ); |
5f96aa1a | 253 | //g_free ( safe_string ); |
a5c8699d EB |
254 | g_free ( safe_user ); |
255 | g_free ( safe_pass ); | |
5dc7ffd5 GB |
256 | g_free ( slat ); |
257 | g_free ( slon ); | |
3333c069 EB |
258 | } |
259 | ||
28c82d8b | 260 | static void datasource_gc_cleanup ( datasource_gc_widgets_t *widgets ) |
3333c069 | 261 | { |
28c82d8b EB |
262 | if ( widgets->circle_onscreen ) { |
263 | vik_viewport_draw_arc ( widgets->vvp, widgets->circle_gc, FALSE, | |
264 | widgets->circle_x - widgets->circle_width/2, | |
265 | widgets->circle_y - widgets->circle_width/2, | |
266 | widgets->circle_width, widgets->circle_width, 0, 360*64 ); | |
267 | vik_viewport_sync( widgets->vvp ); | |
268 | } | |
269 | g_free ( widgets ); | |
3333c069 | 270 | } |
1ef9e637 | 271 | #endif /* VIK_CONFIG_GEOCACHES */ |