20 |
#include "appdata.h" |
#include "appdata.h" |
21 |
#include "osm-gps-map.h" |
#include "osm-gps-map.h" |
22 |
|
|
23 |
|
/* limit of square kilometers above the warning is enabled */ |
24 |
|
#define WARN_OVER 5.0 |
25 |
|
|
26 |
typedef struct { |
typedef struct { |
27 |
GtkWidget *dialog, *notebook; |
GtkWidget *dialog, *notebook; |
28 |
area_edit_t *area; |
area_edit_t *area; |
29 |
pos_t min, max; /* local copy to work on */ |
pos_t min, max; /* local copy to work on */ |
30 |
GtkWidget *minlat, *maxlat, *minlon, *maxlon; |
GtkWidget *minlat, *maxlat, *minlon, *maxlon; |
31 |
|
GtkWidget *warning; |
32 |
|
|
33 |
struct { |
struct { |
34 |
GtkWidget *minlat, *maxlat, *minlon, *maxlon; |
GtkWidget *minlat, *maxlat, *minlon, *maxlon; |
53 |
|
|
54 |
} context_t; |
} context_t; |
55 |
|
|
56 |
static void parse_and_set_lat(GtkWidget *src, GtkWidget *dst, pos_float_t *store) { |
static void parse_and_set_lat(GtkWidget *src, pos_float_t *store) { |
57 |
pos_float_t i = pos_parse_lat((char*)gtk_entry_get_text(GTK_ENTRY(src))); |
pos_float_t i = pos_parse_lat((char*)gtk_entry_get_text(GTK_ENTRY(src))); |
58 |
if(pos_lat_valid(i)) { |
if(pos_lat_valid(i)) |
59 |
*store = i; |
*store = i; |
|
pos_lat_label_set(dst, i); |
|
|
} |
|
60 |
} |
} |
61 |
|
|
62 |
static void parse_and_set_lon(GtkWidget *src, GtkWidget *dst, pos_float_t *store) { |
static void parse_and_set_lon(GtkWidget *src, pos_float_t *store) { |
63 |
pos_float_t i = pos_parse_lon((char*)gtk_entry_get_text(GTK_ENTRY(src))); |
pos_float_t i = pos_parse_lon((char*)gtk_entry_get_text(GTK_ENTRY(src))); |
64 |
if(pos_lon_valid(i)) { |
if(pos_lon_valid(i)) |
65 |
*store = i; |
*store = i; |
|
pos_lon_label_set(dst, i); |
|
|
} |
|
66 |
} |
} |
67 |
|
|
68 |
#define LOG2(x) (log(x) / log(2)) |
#define LOG2(x) (log(x) / log(2)) |
69 |
|
|
70 |
|
static void on_area_warning_clicked(GtkButton *button, gpointer data) { |
71 |
|
context_t *context = (context_t*)data; |
72 |
|
|
73 |
|
/* compute area size */ |
74 |
|
pos_float_t center_lat = (context->max.lat + context->min.lat)/2; |
75 |
|
double vscale = DEG2RAD(POS_EQ_RADIUS / 1000.0); |
76 |
|
double hscale = DEG2RAD(cos(DEG2RAD(center_lat)) * POS_EQ_RADIUS / 1000.0); |
77 |
|
|
78 |
|
double area = vscale * (context->max.lat - context->min.lat) * |
79 |
|
hscale * (context->max.lon - context->min.lon); |
80 |
|
|
81 |
|
messagef(context->dialog, _("Area size warning"), |
82 |
|
_("The currently selected area is %.02f km² (%.02f mil²) in size. " |
83 |
|
"This is more than the recommended %.02f km² (%.02f mil²). " |
84 |
|
"This may result in a big download and slow mapping performance " |
85 |
|
"in a densly mapped area (e.g. cities)!"), |
86 |
|
area, area/(KMPMIL*KMPMIL), |
87 |
|
WARN_OVER, WARN_OVER/(KMPMIL*KMPMIL) |
88 |
|
); |
89 |
|
|
90 |
|
} |
91 |
|
|
92 |
|
static void area_main_update(context_t *context) { |
93 |
|
pos_lat_label_set(context->minlat, context->min.lat); |
94 |
|
pos_lat_label_set(context->maxlat, context->max.lat); |
95 |
|
pos_lon_label_set(context->minlon, context->min.lon); |
96 |
|
pos_lon_label_set(context->maxlon, context->max.lon); |
97 |
|
|
98 |
|
/* check if area size exceeds recommended values */ |
99 |
|
pos_float_t center_lat = (context->max.lat + context->min.lat)/2; |
100 |
|
double vscale = DEG2RAD(POS_EQ_RADIUS / 1000.0); |
101 |
|
double hscale = DEG2RAD(cos(DEG2RAD(center_lat)) * POS_EQ_RADIUS / 1000.0); |
102 |
|
|
103 |
|
double area = vscale * (context->max.lat - context->min.lat) * |
104 |
|
hscale * (context->max.lon - context->min.lon); |
105 |
|
|
106 |
|
if(area > WARN_OVER) |
107 |
|
gtk_widget_show(context->warning); |
108 |
|
else |
109 |
|
gtk_widget_hide(context->warning); |
110 |
|
} |
111 |
|
|
112 |
/* the contents of the map tab have been changed */ |
/* the contents of the map tab have been changed */ |
113 |
static void map_update(context_t *context, gboolean forced) { |
static void map_update(context_t *context, gboolean forced) { |
114 |
|
|
115 |
/* map is first tab (page 0) */ |
/* map is first tab (page 0) */ |
116 |
if(!forced && gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 0) { |
if(!forced && |
117 |
|
gtk_notebook_get_current_page(GTK_NOTEBOOK(context->notebook)) != 0) { |
118 |
context->map.needs_redraw = TRUE; |
context->map.needs_redraw = TRUE; |
119 |
return; |
return; |
120 |
} |
} |
122 |
pos_float_t center_lat = (context->max.lat + context->min.lat)/2; |
pos_float_t center_lat = (context->max.lat + context->min.lat)/2; |
123 |
pos_float_t center_lon = (context->max.lon + context->min.lon)/2; |
pos_float_t center_lon = (context->max.lon + context->min.lon)/2; |
124 |
|
|
125 |
/* we know the widgets pixel size, we know the required real size, we want the zoom! */ |
/* we know the widgets pixel size, we know the required real size, */ |
126 |
|
/* we want the zoom! */ |
127 |
double vzoom = LOG2((45.0 * context->map.widget->allocation.height)/ |
double vzoom = LOG2((45.0 * context->map.widget->allocation.height)/ |
128 |
((context->max.lat - context->min.lat)*32.0)); |
((context->max.lat - context->min.lat)*32.0)); |
129 |
|
|
179 |
return; |
return; |
180 |
|
|
181 |
/* parse the fields from the direct entry pad */ |
/* parse the fields from the direct entry pad */ |
182 |
parse_and_set_lat(context->direct.minlat, context->minlat, &context->min.lat); |
parse_and_set_lat(context->direct.minlat, &context->min.lat); |
183 |
parse_and_set_lon(context->direct.minlon, context->minlon, &context->min.lon); |
parse_and_set_lon(context->direct.minlon, &context->min.lon); |
184 |
parse_and_set_lat(context->direct.maxlat, context->maxlat, &context->max.lat); |
parse_and_set_lat(context->direct.maxlat, &context->max.lat); |
185 |
parse_and_set_lon(context->direct.maxlon, context->maxlon, &context->max.lon); |
parse_and_set_lon(context->direct.maxlon, &context->max.lon); |
186 |
|
|
187 |
|
area_main_update(context); |
188 |
|
|
189 |
/* also adjust other views */ |
/* also adjust other views */ |
190 |
extent_update(context); |
extent_update(context); |
211 |
|
|
212 |
height /= 2 * vscale; |
height /= 2 * vscale; |
213 |
context->min.lat = center_lat - height; |
context->min.lat = center_lat - height; |
|
pos_lat_label_set(context->minlat, context->min.lat); |
|
214 |
context->max.lat = center_lat + height; |
context->max.lat = center_lat + height; |
215 |
pos_lat_label_set(context->maxlat, context->max.lat); |
|
|
|
|
216 |
width /= 2 * hscale; |
width /= 2 * hscale; |
217 |
context->min.lon = center_lon - width; |
context->min.lon = center_lon - width; |
|
pos_lon_label_set(context->minlon, context->min.lon); |
|
218 |
context->max.lon = center_lon + width; |
context->max.lon = center_lon + width; |
219 |
pos_lon_label_set(context->maxlon, context->max.lon); |
|
220 |
|
area_main_update(context); |
221 |
|
|
222 |
/* also update other tabs */ |
/* also update other tabs */ |
223 |
direct_update(context); |
direct_update(context); |
278 |
double vscale = DEG2RAD(POS_EQ_RADIUS); |
double vscale = DEG2RAD(POS_EQ_RADIUS); |
279 |
double height = 8 * (1<<zoom) / vscale; |
double height = 8 * (1<<zoom) / vscale; |
280 |
context->min.lat = center_lat - height; |
context->min.lat = center_lat - height; |
|
pos_lat_label_set(context->minlat, context->min.lat); |
|
281 |
context->max.lat = center_lat + height; |
context->max.lat = center_lat + height; |
|
pos_lat_label_set(context->maxlat, context->max.lat); |
|
282 |
|
|
283 |
double hscale = DEG2RAD(cos(DEG2RAD(center_lat)) * POS_EQ_RADIUS); |
double hscale = DEG2RAD(cos(DEG2RAD(center_lat)) * POS_EQ_RADIUS); |
284 |
double width = 16 * (1<<zoom) / hscale; |
double width = 16 * (1<<zoom) / hscale; |
285 |
context->min.lon = center_lon - width; |
context->min.lon = center_lon - width; |
|
pos_lon_label_set(context->minlon, context->min.lon); |
|
286 |
context->max.lon = center_lon + width; |
context->max.lon = center_lon + width; |
287 |
pos_lon_label_set(context->maxlon, context->max.lon); |
|
288 |
|
area_main_update(context); |
289 |
|
|
290 |
/* also update other tabs */ |
/* also update other tabs */ |
291 |
direct_update(context); |
direct_update(context); |
302 |
osm_gps_map_get_bbox(OSM_GPS_MAP(context->map.widget), &pt1, &pt2); |
osm_gps_map_get_bbox(OSM_GPS_MAP(context->map.widget), &pt1, &pt2); |
303 |
|
|
304 |
context->min.lat = RAD2DEG(pt2.rlat); |
context->min.lat = RAD2DEG(pt2.rlat); |
|
pos_lat_label_set(context->minlat, context->min.lat); |
|
305 |
context->max.lat = RAD2DEG(pt1.rlat); |
context->max.lat = RAD2DEG(pt1.rlat); |
|
pos_lat_label_set(context->maxlat, context->max.lat); |
|
306 |
|
|
307 |
context->min.lon = RAD2DEG(pt1.rlon); |
context->min.lon = RAD2DEG(pt1.rlon); |
|
pos_lon_label_set(context->minlon, context->min.lon); |
|
308 |
context->max.lon = RAD2DEG(pt2.rlon); |
context->max.lon = RAD2DEG(pt2.rlon); |
|
pos_lon_label_set(context->maxlon, context->max.lon); |
|
309 |
|
|
310 |
|
area_main_update(context); |
311 |
direct_update(context); |
direct_update(context); |
312 |
extent_update(context); |
extent_update(context); |
313 |
} |
} |
372 |
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, |
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, |
373 |
NULL); |
NULL); |
374 |
|
|
375 |
GtkWidget *table = gtk_table_new(4, 2, FALSE); // x, y |
GtkWidget *table = gtk_table_new(5, 2, FALSE); // x, y |
376 |
|
|
377 |
GtkWidget *label = gtk_label_new(_("Latitude:")); |
GtkWidget *label = gtk_label_new(_("Latitude:")); |
378 |
misc_table_attach(table, label, 0, 0); |
misc_table_attach(table, label, 0, 0); |
392 |
context.maxlon = pos_lon_label_new(area->max->lon); |
context.maxlon = pos_lon_label_new(area->max->lon); |
393 |
misc_table_attach(table, context.maxlon, 3, 1); |
misc_table_attach(table, context.maxlon, 3, 1); |
394 |
|
|
395 |
|
context.warning = gtk_button_new(); |
396 |
|
gtk_button_set_image(GTK_BUTTON(context.warning), |
397 |
|
gtk_image_new_from_stock(GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_MENU)); |
398 |
|
g_signal_connect(context.warning, "clicked", |
399 |
|
G_CALLBACK(on_area_warning_clicked), &context); |
400 |
|
gtk_table_attach_defaults(GTK_TABLE(table), context.warning, 4, 5, 0, 2); |
401 |
|
|
402 |
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context.dialog)->vbox), |
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(context.dialog)->vbox), |
403 |
table, FALSE, FALSE, 0); |
table, FALSE, FALSE, 0); |
404 |
|
|
575 |
|
|
576 |
gtk_widget_show_all(context.dialog); |
gtk_widget_show_all(context.dialog); |
577 |
|
|
578 |
|
area_main_update(&context); |
579 |
|
|
580 |
if(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(context.dialog))) { |
if(GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(context.dialog))) { |
581 |
/* copy modified values back to given storage */ |
/* copy modified values back to given storage */ |
582 |
area->min->lat = context.min.lat; |
area->min->lat = context.min.lat; |