Diff of /trunk/src/area_edit.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 204 by harbaum, Fri Jul 10 07:36:19 2009 UTC revision 205 by harbaum, Fri Jul 10 08:37:43 2009 UTC
# Line 20  Line 20 
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;
# Line 49  typedef struct { Line 53  typedef struct {
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    }    }
# Line 79  static void map_update(context_t *contex Line 122  static void map_update(context_t *contex
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    
# Line 135  static void callback_modified_direct(Gtk Line 179  static void callback_modified_direct(Gtk
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);
# Line 165  static void callback_modified_extent(Gtk Line 211  static void callback_modified_extent(Gtk
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);
# Line 234  static void callback_fetch_mm_clicked(Gt Line 278  static void callback_fetch_mm_clicked(Gt
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);
# Line 260  static void map_has_changed(context_t *c Line 302  static void map_has_changed(context_t *c
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  }  }
# Line 333  gboolean area_edit(area_edit_t *area) { Line 372  gboolean area_edit(area_edit_t *area) {
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);
# Line 353  gboolean area_edit(area_edit_t *area) { Line 392  gboolean area_edit(area_edit_t *area) {
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    
# Line 529  gboolean area_edit(area_edit_t *area) { Line 575  gboolean area_edit(area_edit_t *area) {
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;

Legend:
Removed from v.204  
changed lines
  Added in v.205