44 |
struct { |
struct { |
45 |
GtkWidget *widget; |
GtkWidget *widget; |
46 |
GtkWidget *zoomin, *zoomout; |
GtkWidget *zoomin, *zoomout; |
47 |
|
gboolean needs_redraw; |
48 |
} map; |
} map; |
49 |
|
|
50 |
} context_t; |
} context_t; |
65 |
} |
} |
66 |
} |
} |
67 |
|
|
68 |
#define log2(x) (log(x) / log(2)) |
#define LOG2(x) (log(x) / log(2)) |
69 |
|
|
70 |
void get_zoom(context_t *context) { |
/* the contents of the map tab have been changed */ |
71 |
pos_float_t center_lat = (context->max.lat + context->min.lat)/2; |
static void map_update(context_t *context, gboolean forced) { |
|
|
|
|
/* we know pixel size, we know the real size, we want the zoom! */ |
|
|
|
|
|
printf("map_update: %d x %d\n", |
|
|
context->map.widget->allocation.width, |
|
|
context->map.widget->allocation.height); |
|
|
|
|
|
double vscale = DEG2RAD(POS_EQ_RADIUS); |
|
|
double hscale = DEG2RAD(cos(DEG2RAD(center_lat)) * POS_EQ_RADIUS); |
|
|
|
|
|
printf("scale: %f m/pix %f m/pix\n", hscale*256, vscale*256); |
|
|
|
|
|
// double height = 8 * (1<<zoom) / vscale; // 2^zoom ln2(zoom) |
|
|
// double hzoom = log2(context->map.widget->allocation.height * vscale / 8); |
|
|
// double width = 16 * (1<<zoom) / hscale; |
|
|
// double vzoom = log2(context->map.widget->allocation.width * hscale / 8); |
|
72 |
|
|
73 |
// printf("zoom: %f %f\n", hzoom, vzoom); |
/* map is first tab (page 0) */ |
74 |
} |
if(!forced && gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 0) { |
75 |
|
context->map.needs_redraw = TRUE; |
76 |
|
return; |
77 |
|
} |
78 |
|
|
|
/* the contents of the map tab have been changed */ |
|
|
static void map_update(context_t *context) { |
|
79 |
pos_float_t center_lat = (context->max.lat + context->min.lat)/2; |
pos_float_t center_lat = (context->max.lat + context->min.lat)/2; |
80 |
pos_float_t center_lon = (context->max.lon + context->min.lon)/2; |
pos_float_t center_lon = (context->max.lon + context->min.lon)/2; |
81 |
|
|
82 |
get_zoom(context); |
/* we know the widgets pixel size, we know the required real size, we want the zoom! */ |
83 |
|
double vzoom = LOG2((45.0 * context->map.widget->allocation.height)/ |
84 |
|
((context->max.lat - context->min.lat)*32.0)); |
85 |
|
|
86 |
|
double hzoom = LOG2((45.0 * context->map.widget->allocation.width)/ |
87 |
|
((context->max.lon - context->min.lon)*32.0)); |
88 |
|
|
89 |
osm_gps_map_set_center(OSM_GPS_MAP(context->map.widget), |
osm_gps_map_set_center(OSM_GPS_MAP(context->map.widget), |
90 |
center_lat, center_lon); |
center_lat, center_lon); |
91 |
|
|
92 |
osm_gps_map_set_zoom(OSM_GPS_MAP(context->map.widget), 14); |
osm_gps_map_set_zoom(OSM_GPS_MAP(context->map.widget), (hzoom+vzoom+0.5)/2); |
93 |
|
|
94 |
|
context->map.needs_redraw = FALSE; |
95 |
} |
} |
96 |
|
|
97 |
static gboolean on_map_configure(GtkWidget *widget, |
static gboolean on_map_configure(GtkWidget *widget, |
98 |
GdkEventConfigure *event, |
GdkEventConfigure *event, |
99 |
context_t *context) { |
context_t *context) { |
100 |
|
map_update(context, FALSE); |
|
map_update(context); |
|
101 |
return FALSE; |
return FALSE; |
102 |
} |
} |
103 |
|
|
130 |
static void callback_modified_direct(GtkWidget *widget, gpointer data) { |
static void callback_modified_direct(GtkWidget *widget, gpointer data) { |
131 |
context_t *context = (context_t*)data; |
context_t *context = (context_t*)data; |
132 |
|
|
133 |
/* direct is first tab (page 0) */ |
/* direct is second tab (page 1) */ |
134 |
if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 0) |
if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 1) |
135 |
return; |
return; |
136 |
|
|
137 |
/* parse the fields from the direct entry pad */ |
/* parse the fields from the direct entry pad */ |
147 |
static void callback_modified_extent(GtkWidget *widget, gpointer data) { |
static void callback_modified_extent(GtkWidget *widget, gpointer data) { |
148 |
context_t *context = (context_t*)data; |
context_t *context = (context_t*)data; |
149 |
|
|
150 |
/* extent is second tab (page 1) */ |
/* extent is third tab (page 2) */ |
151 |
if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 1) |
if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 2) |
152 |
return; |
return; |
153 |
|
|
154 |
pos_float_t center_lat = pos_lat_get(context->extent.lat); |
pos_float_t center_lat = pos_lat_get(context->extent.lat); |
177 |
|
|
178 |
/* also update other tabs */ |
/* also update other tabs */ |
179 |
direct_update(context); |
direct_update(context); |
180 |
map_update(context); |
map_update(context, FALSE); |
181 |
} |
} |
182 |
|
|
183 |
static void callback_modified_unit(GtkWidget *widget, gpointer data) { |
static void callback_modified_unit(GtkWidget *widget, gpointer data) { |
219 |
return; |
return; |
220 |
} |
} |
221 |
|
|
222 |
/* maemo mapper is third tab (page 2) */ |
/* maemo mapper is fourth tab (page 3) */ |
223 |
if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 2) |
if(gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 3) |
224 |
return; |
return; |
225 |
|
|
226 |
/* maemo mapper pos data ... */ |
/* maemo mapper pos data ... */ |
248 |
/* also update other tabs */ |
/* also update other tabs */ |
249 |
direct_update(context); |
direct_update(context); |
250 |
extent_update(context); |
extent_update(context); |
251 |
map_update(context); |
map_update(context, FALSE); |
252 |
} |
} |
253 |
#endif |
#endif |
254 |
|
|
255 |
|
/* the user has changed the map view, update other views accordingly */ |
256 |
|
static void map_has_changed(context_t *context) { |
257 |
|
coord_t pt1, pt2; |
258 |
|
|
259 |
|
/* get maps bounding box */ |
260 |
|
osm_gps_map_get_bbox(OSM_GPS_MAP(context->map.widget), &pt1, &pt2); |
261 |
|
|
262 |
|
context->min.lat = RAD2DEG(pt2.rlat); |
263 |
|
pos_lat_label_set(context->minlat, context->min.lat); |
264 |
|
context->max.lat = RAD2DEG(pt1.rlat); |
265 |
|
pos_lat_label_set(context->maxlat, context->max.lat); |
266 |
|
|
267 |
|
context->min.lon = RAD2DEG(pt1.rlon); |
268 |
|
pos_lon_label_set(context->minlon, context->min.lon); |
269 |
|
context->max.lon = RAD2DEG(pt2.rlon); |
270 |
|
pos_lon_label_set(context->maxlon, context->max.lon); |
271 |
|
|
272 |
|
direct_update(context); |
273 |
|
extent_update(context); |
274 |
|
} |
275 |
|
|
276 |
|
static gboolean |
277 |
|
on_map_button_release_event(GtkWidget *widget, |
278 |
|
GdkEventButton *event, context_t *context) { |
279 |
|
map_has_changed(context); |
280 |
|
return FALSE; |
281 |
|
} |
282 |
|
|
283 |
static void map_zoom(context_t *context, int step) { |
static void map_zoom(context_t *context, int step) { |
284 |
int zoom; |
int zoom; |
285 |
OsmGpsMap *map = OSM_GPS_MAP(context->map.widget); |
OsmGpsMap *map = OSM_GPS_MAP(context->map.widget); |
286 |
g_object_get(map, "zoom", &zoom, NULL); |
g_object_get(map, "zoom", &zoom, NULL); |
287 |
zoom = osm_gps_map_set_zoom(map, zoom+step); |
zoom = osm_gps_map_set_zoom(map, zoom+step); |
288 |
|
|
|
get_zoom(context); |
|
|
|
|
289 |
/* enable/disable zoom buttons as required */ |
/* enable/disable zoom buttons as required */ |
290 |
gtk_widget_set_sensitive(context->map.zoomin, zoom<17); |
gtk_widget_set_sensitive(context->map.zoomin, zoom<17); |
291 |
gtk_widget_set_sensitive(context->map.zoomout, zoom>1); |
gtk_widget_set_sensitive(context->map.zoomout, zoom>1); |
292 |
|
|
293 |
|
map_has_changed(context); |
294 |
} |
} |
295 |
|
|
296 |
static gboolean |
static gboolean |
305 |
return FALSE; |
return FALSE; |
306 |
} |
} |
307 |
|
|
308 |
|
static void on_page_switch(GtkNotebook *notebook, GtkNotebookPage *page, |
309 |
|
guint page_num, context_t *context) { |
310 |
|
|
311 |
|
/* updating the map while the user manually changes some coordinates */ |
312 |
|
/* may confuse the map. so we delay those updates until the map tab */ |
313 |
|
/* is becoming visible */ |
314 |
|
if((page_num == 0) && context->map.needs_redraw) |
315 |
|
map_update(context, TRUE); |
316 |
|
} |
317 |
|
|
318 |
gboolean area_edit(area_edit_t *area) { |
gboolean area_edit(area_edit_t *area) { |
319 |
gboolean ok = FALSE; |
gboolean ok = FALSE; |
320 |
|
|
362 |
|
|
363 |
GtkWidget *hbox = gtk_hbox_new(FALSE, 0); |
GtkWidget *hbox = gtk_hbox_new(FALSE, 0); |
364 |
|
|
365 |
|
context.map.needs_redraw = FALSE; |
366 |
context.map.widget = g_object_new(OSM_TYPE_GPS_MAP, |
context.map.widget = g_object_new(OSM_TYPE_GPS_MAP, |
367 |
"repo-uri", MAP_SOURCE_OPENSTREETMAP, |
"repo-uri", MAP_SOURCE_OPENSTREETMAP, |
368 |
"proxy-uri", misc_get_proxy_uri(area->settings), |
"proxy-uri", misc_get_proxy_uri(area->settings), |
369 |
NULL); |
NULL); |
370 |
|
|
371 |
g_signal_connect(G_OBJECT(context.map.widget), "configure-event", |
g_signal_connect(G_OBJECT(context.map.widget), "configure-event", |
372 |
G_CALLBACK(on_map_configure), &context); |
G_CALLBACK(on_map_configure), &context); |
373 |
|
g_signal_connect(G_OBJECT(context.map.widget), "button-release-event", |
374 |
|
G_CALLBACK(on_map_button_release_event), &context); |
375 |
|
|
376 |
gtk_box_pack_start_defaults(GTK_BOX(hbox), context.map.widget); |
gtk_box_pack_start_defaults(GTK_BOX(hbox), context.map.widget); |
377 |
|
|
401 |
|
|
402 |
vbox = gtk_vbox_new(FALSE, 10); |
vbox = gtk_vbox_new(FALSE, 10); |
403 |
table = gtk_table_new(3, 3, FALSE); // x, y |
table = gtk_table_new(3, 3, FALSE); // x, y |
404 |
|
gtk_table_set_col_spacings(GTK_TABLE(table), 10); |
405 |
|
gtk_table_set_row_spacings(GTK_TABLE(table), 5); |
406 |
|
|
407 |
context.direct.minlat = pos_lat_entry_new(0.0); |
context.direct.minlat = pos_lat_entry_new(0.0); |
408 |
misc_table_attach(table, context.direct.minlat, 0, 0); |
misc_table_attach(table, context.direct.minlat, 0, 0); |
443 |
|
|
444 |
vbox = gtk_vbox_new(FALSE, 10); |
vbox = gtk_vbox_new(FALSE, 10); |
445 |
table = gtk_table_new(3, 4, FALSE); // x, y |
table = gtk_table_new(3, 4, FALSE); // x, y |
446 |
|
gtk_table_set_col_spacings(GTK_TABLE(table), 10); |
447 |
|
gtk_table_set_row_spacings(GTK_TABLE(table), 5); |
448 |
|
|
449 |
label = gtk_label_new(_("Center:")); |
label = gtk_label_new(_("Center:")); |
450 |
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f); |
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f); |
454 |
context.extent.lon = pos_lon_entry_new(0.0); |
context.extent.lon = pos_lon_entry_new(0.0); |
455 |
gtk_table_attach_defaults(GTK_TABLE(table), context.extent.lon, 2, 3, 0, 1); |
gtk_table_attach_defaults(GTK_TABLE(table), context.extent.lon, 2, 3, 0, 1); |
456 |
|
|
457 |
gtk_table_set_row_spacing(GTK_TABLE(table), 0, 8); |
gtk_table_set_row_spacing(GTK_TABLE(table), 0, 10); |
458 |
|
|
459 |
label = gtk_label_new(_("Width:")); |
label = gtk_label_new(_("Width:")); |
460 |
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f); |
gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f); |
524 |
gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context.dialog)->vbox), |
gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(context.dialog)->vbox), |
525 |
context.notebook); |
context.notebook); |
526 |
|
|
527 |
|
g_signal_connect(G_OBJECT(context.notebook), "switch-page", |
528 |
|
G_CALLBACK(on_page_switch), &context); |
529 |
|
|
530 |
gtk_widget_show_all(context.dialog); |
gtk_widget_show_all(context.dialog); |
531 |
|
|