2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
4 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include <glib/gstdio.h>
29 #include <glib/gi18n.h>
34 #include "icons/icons.h"
36 VikLayerParam georef_layer_params[] = {
37 { "image", VIK_LAYER_PARAM_STRING, VIK_LAYER_NOT_IN_PROPERTIES },
38 { "corner_easting", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES },
39 { "corner_northing", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES },
40 { "mpp_easting", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES },
41 { "mpp_northing", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES },
44 enum { PARAM_IMAGE = 0, PARAM_CE, PARAM_CN, PARAM_ME, PARAM_MN, NUM_PARAMS };
46 static const gchar* georef_layer_tooltip ( VikGeorefLayer *vgl );
47 static void georef_layer_marshall( VikGeorefLayer *vgl, guint8 **data, gint *len );
48 static VikGeorefLayer *georef_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp );
49 static gboolean georef_layer_set_param ( VikGeorefLayer *vgl, guint16 id, VikLayerParamData data, VikViewport *vp, gboolean is_file_operation );
50 static VikLayerParamData georef_layer_get_param ( VikGeorefLayer *vgl, guint16 id, gboolean is_file_operation );
51 VikGeorefLayer *georef_layer_new ( );
52 VikGeorefLayer *georef_layer_create ( VikViewport *vp );
53 static void georef_layer_free ( VikGeorefLayer *vgl );
54 gboolean georef_layer_properties ( VikGeorefLayer *vgl, gpointer vp );
55 static void georef_layer_draw ( VikGeorefLayer *vgl, gpointer data );
56 static void georef_layer_add_menu_items ( VikGeorefLayer *vgl, GtkMenu *menu, gpointer vlp );
57 static void georef_layer_set_image ( VikGeorefLayer *vgl, const gchar *image );
58 static gboolean georef_layer_dialog ( VikGeorefLayer **vgl, gpointer vp, GtkWindow *w );
59 static void georef_layer_load_image ( VikGeorefLayer *vgl );
62 static gpointer georef_layer_move_create ( VikWindow *vw, VikViewport *vvp);
63 static gboolean georef_layer_move_release ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp );
64 static gboolean georef_layer_move_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp );
65 static gpointer georef_layer_zoom_create ( VikWindow *vw, VikViewport *vvp);
66 static gboolean georef_layer_zoom_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp );
68 static VikToolInterface georef_tools[] = {
69 { N_("Georef Move Map"), (VikToolConstructorFunc) georef_layer_move_create, NULL, NULL, NULL,
70 (VikToolMouseFunc) georef_layer_move_press, NULL, (VikToolMouseFunc) georef_layer_move_release,
71 (VikToolKeyFunc) NULL, GDK_CURSOR_IS_PIXMAP, &cursor_geomove_pixbuf },
73 { N_("Georef Zoom Tool"), (VikToolConstructorFunc) georef_layer_zoom_create, NULL, NULL, NULL,
74 (VikToolMouseFunc) georef_layer_zoom_press, NULL, NULL,
75 (VikToolKeyFunc) NULL, GDK_CURSOR_IS_PIXMAP, &cursor_geozoom_pixbuf },
78 VikLayerInterface vik_georef_layer_interface = {
80 &vikgeoreflayer_pixbuf, /*icon */
83 sizeof(georef_tools) / sizeof(VikToolInterface),
92 (VikLayerFuncCreate) georef_layer_create,
93 (VikLayerFuncRealize) NULL,
94 (VikLayerFuncPostRead) georef_layer_load_image,
95 (VikLayerFuncFree) georef_layer_free,
97 (VikLayerFuncProperties) georef_layer_properties,
98 (VikLayerFuncDraw) georef_layer_draw,
99 (VikLayerFuncChangeCoordMode) NULL,
101 (VikLayerFuncSetMenuItemsSelection) NULL,
102 (VikLayerFuncGetMenuItemsSelection) NULL,
104 (VikLayerFuncAddMenuItems) georef_layer_add_menu_items,
105 (VikLayerFuncSublayerAddMenuItems) NULL,
107 (VikLayerFuncSublayerRenameRequest) NULL,
108 (VikLayerFuncSublayerToggleVisible) NULL,
109 (VikLayerFuncSublayerTooltip) NULL,
110 (VikLayerFuncLayerTooltip) georef_layer_tooltip,
111 (VikLayerFuncLayerSelected) NULL,
113 (VikLayerFuncMarshall) georef_layer_marshall,
114 (VikLayerFuncUnmarshall) georef_layer_unmarshall,
116 (VikLayerFuncSetParam) georef_layer_set_param,
117 (VikLayerFuncGetParam) georef_layer_get_param,
119 (VikLayerFuncReadFileData) NULL,
120 (VikLayerFuncWriteFileData) NULL,
122 (VikLayerFuncDeleteItem) NULL,
123 (VikLayerFuncCutItem) NULL,
124 (VikLayerFuncCopyItem) NULL,
125 (VikLayerFuncPasteItem) NULL,
126 (VikLayerFuncFreeCopiedItem) NULL,
127 (VikLayerFuncDragDropRequest) NULL,
129 (VikLayerFuncSelectClick) NULL,
130 (VikLayerFuncSelectMove) NULL,
131 (VikLayerFuncSelectRelease) NULL,
132 (VikLayerFuncSelectedViewportMenu) NULL,
135 struct _VikGeorefLayer {
140 gdouble mpp_easting, mpp_northing;
144 guint32 scaled_width, scaled_height;
146 gint click_x, click_y;
151 GType vik_georef_layer_get_type ()
153 static GType vgl_type = 0;
157 static const GTypeInfo vgl_info =
159 sizeof (VikGeorefLayerClass),
160 NULL, /* base_init */
161 NULL, /* base_finalize */
162 NULL, /* class init */
163 NULL, /* class_finalize */
164 NULL, /* class_data */
165 sizeof (VikGeorefLayer),
167 NULL /* instance init */
169 vgl_type = g_type_register_static ( VIK_LAYER_TYPE, "VikGeorefLayer", &vgl_info, 0 );
175 static const gchar* georef_layer_tooltip ( VikGeorefLayer *vgl )
180 static void georef_layer_marshall( VikGeorefLayer *vgl, guint8 **data, gint *len )
182 vik_layer_marshall_params ( VIK_LAYER(vgl), data, len );
185 static VikGeorefLayer *georef_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp )
187 VikGeorefLayer *rv = georef_layer_new ();
188 vik_layer_unmarshall_params ( VIK_LAYER(rv), data, len, vvp );
190 georef_layer_load_image ( rv );
195 static gboolean georef_layer_set_param ( VikGeorefLayer *vgl, guint16 id, VikLayerParamData data, VikViewport *vp, gboolean is_file_operation )
199 case PARAM_IMAGE: georef_layer_set_image ( vgl, data.s ); break;
200 case PARAM_CN: vgl->corner.northing = data.d; break;
201 case PARAM_CE: vgl->corner.easting = data.d; break;
202 case PARAM_MN: vgl->mpp_northing = data.d; break;
203 case PARAM_ME: vgl->mpp_easting = data.d; break;
208 static VikLayerParamData georef_layer_get_param ( VikGeorefLayer *vgl, guint16 id, gboolean is_file_operation )
210 VikLayerParamData rv;
213 case PARAM_IMAGE: rv.s = vgl->image ? vgl->image : ""; break;
214 case PARAM_CN: rv.d = vgl->corner.northing; break;
215 case PARAM_CE: rv.d = vgl->corner.easting; break;
216 case PARAM_MN: rv.d = vgl->mpp_northing; break;
217 case PARAM_ME: rv.d = vgl->mpp_easting; break;
222 VikGeorefLayer *georef_layer_new ( )
224 VikGeorefLayer *vgl = VIK_GEOREF_LAYER ( g_object_new ( VIK_GEOREF_LAYER_TYPE, NULL ) );
225 vik_layer_init ( VIK_LAYER(vgl), VIK_LAYER_GEOREF );
232 vgl->scaled_width = 0;
233 vgl->scaled_height = 0;
237 static void georef_layer_draw ( VikGeorefLayer *vgl, gpointer data )
242 VikViewport *vp = VIK_VIEWPORT(data);
243 struct UTM utm_middle;
244 gdouble xmpp = vik_viewport_get_xmpp(vp), ympp = vik_viewport_get_ympp(vp);
245 GdkPixbuf *pixbuf = vgl->pixbuf;
246 guint layer_width = vgl->width;
247 guint layer_height = vgl->height;
249 vik_coord_to_utm ( vik_viewport_get_center ( vp ), &utm_middle );
251 /* scale the pixbuf if it doesn't match our dimensions */
252 if ( xmpp != vgl->mpp_easting || ympp != vgl->mpp_northing )
254 layer_width = round(vgl->width * vgl->mpp_easting / xmpp);
255 layer_height = round(vgl->height * vgl->mpp_northing / ympp);
257 /* rescale if necessary */
258 if (layer_width == vgl->scaled_width && layer_height == vgl->scaled_height && vgl->scaled != NULL)
259 pixbuf = vgl->scaled;
262 pixbuf = gdk_pixbuf_scale_simple(
269 if (vgl->scaled != NULL)
270 g_object_unref(vgl->scaled);
272 vgl->scaled = pixbuf;
273 vgl->scaled_width = layer_width;
274 vgl->scaled_height = layer_height;
278 guint width = vik_viewport_get_width(vp), height = vik_viewport_get_height(vp);
280 vgl->corner.zone = utm_middle.zone;
281 vgl->corner.letter = utm_middle.letter;
282 VikCoord corner_coord;
283 vik_coord_load_from_utm ( &corner_coord, vik_viewport_get_coord_mode(vp), &(vgl->corner) );
284 vik_viewport_coord_to_screen ( vp, &corner_coord, &x, &y );
285 if ( (x < 0 || x < width) && (y < 0 || y < height) && x+layer_width > 0 && y+layer_height > 0 )
286 vik_viewport_draw_pixbuf ( vp, pixbuf, 0, 0, x, y, layer_width, layer_height ); /* todo: draw only what we need to. */
290 static void georef_layer_free ( VikGeorefLayer *vgl )
292 if ( vgl->image != NULL )
293 g_free ( vgl->image );
294 if ( vgl->scaled != NULL )
295 g_object_unref ( vgl->scaled );
298 VikGeorefLayer *georef_layer_create ( VikViewport *vp )
300 return georef_layer_new ();
303 gboolean georef_layer_properties ( VikGeorefLayer *vgl, gpointer vp )
305 return georef_layer_dialog ( &vgl, vp, VIK_GTK_WINDOW_FROM_WIDGET(vp) );
308 static void georef_layer_load_image ( VikGeorefLayer *vgl )
311 if ( vgl->image == NULL )
315 g_object_unref ( G_OBJECT(vgl->pixbuf) );
318 g_object_unref ( G_OBJECT(vgl->scaled) );
322 vgl->pixbuf = gdk_pixbuf_new_from_file ( vgl->image, &gx );
326 g_warning ( _("Couldn't open image file: %s"), gx->message );
331 vgl->width = gdk_pixbuf_get_width ( vgl->pixbuf );
332 vgl->height = gdk_pixbuf_get_height ( vgl->pixbuf );
335 /* should find length and width here too */
338 static void georef_layer_set_image ( VikGeorefLayer *vgl, const gchar *image )
341 g_free ( vgl->image );
344 g_object_unref ( vgl->scaled );
349 vgl->image = g_strdup ( image );
352 static gboolean world_file_read_line ( gchar *buffer, gint size, FILE *f, GtkWidget *widget, gboolean use_value )
354 if (!fgets ( buffer, 1024, f ))
356 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(widget), _("Unexpected end of file reading World file.") );
364 gdouble val = g_strtod ( buffer, NULL );
365 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(widget), val > 0 ? val : -val );
370 static void georef_layer_dialog_load ( GtkWidget *pass_along[4] )
372 GtkWidget *file_selector = gtk_file_chooser_dialog_new (_("Choose World file"),
374 GTK_FILE_CHOOSER_ACTION_OPEN,
375 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
376 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
379 if ( gtk_dialog_run ( GTK_DIALOG ( file_selector ) ) == GTK_RESPONSE_ACCEPT )
381 FILE *f = g_fopen ( gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(file_selector) ), "r" );
382 gtk_widget_destroy ( file_selector );
385 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]), _("The World file you requested could not be opened for reading.") );
390 gchar *buffer = g_malloc ( 1024 * sizeof(gchar) );
391 if ( world_file_read_line ( buffer, 1024, f, pass_along[0], TRUE ) && world_file_read_line ( buffer, 1024, f, pass_along[0], FALSE)
392 && world_file_read_line ( buffer, 1024, f, pass_along[0], FALSE ) && world_file_read_line ( buffer, 1024, f, pass_along[1], TRUE)
393 && world_file_read_line ( buffer, 1024, f, pass_along[2], TRUE ) && world_file_read_line ( buffer, 1024, f, pass_along[3], TRUE ) )
402 gtk_widget_destroy ( file_selector );
405 file selection dialog
406 file opener for reading, if NULL, send error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]) )
407 does that catch directories too?
408 read lines -- if not enough lines, give error.
409 if anything outside, give error. define range with #define CONSTANTS
410 put 'em in thar widgets, and that's it.
414 static void georef_layer_export_params ( gpointer *pass_along[2] )
416 VikGeorefLayer *vgl = VIK_GEOREF_LAYER(pass_along[0]);
417 GtkWidget *file_selector = gtk_file_chooser_dialog_new (_("Choose World file"),
419 GTK_FILE_CHOOSER_ACTION_SAVE,
420 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
421 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
423 if ( gtk_dialog_run ( GTK_DIALOG ( file_selector ) ) == GTK_RESPONSE_ACCEPT )
425 FILE *f = g_fopen ( gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(file_selector) ), "w" );
427 gtk_widget_destroy ( file_selector );
430 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]), _("The file you requested could not be opened for writing.") );
435 fprintf ( f, "%f\n%f\n%f\n%f\n%f\n%f\n", vgl->mpp_easting, vgl->mpp_northing, 0.0, 0.0, vgl->corner.easting, vgl->corner.northing );
441 gtk_widget_destroy ( file_selector );
444 /* returns TRUE if OK was pressed. */
445 static gboolean georef_layer_dialog ( VikGeorefLayer **vgl, gpointer vp, GtkWindow *w )
447 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Layer Properties"),
449 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
455 /* Default to reject as user really needs to specify map file first */
456 gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
457 GtkWidget *response_w = NULL;
458 #if GTK_CHECK_VERSION (2, 20, 0)
459 response_w = gtk_dialog_get_widget_for_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
461 GtkWidget *table, *wfp_hbox, *wfp_label, *wfp_button, *ce_label, *ce_spin, *cn_label, *cn_spin, *xlabel, *xspin, *ylabel, *yspin, *imagelabel, *imageentry;
463 GtkWidget *pass_along[4];
465 table = gtk_table_new ( 6, 2, FALSE );
466 gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), table, TRUE, TRUE, 0 );
468 wfp_hbox = gtk_hbox_new ( FALSE, 0 );
469 wfp_label = gtk_label_new ( _("World File Parameters:") );
470 wfp_button = gtk_button_new_with_label ( _("Load From File...") );
472 gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_label, TRUE, TRUE, 0 );
473 gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_button, FALSE, FALSE, 3 );
475 ce_label = gtk_label_new ( _("Corner pixel easting:") );
476 ce_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 1500000.0, 1, 5, 0 ), 1, 4 );
477 gtk_widget_set_tooltip_text ( GTK_WIDGET(ce_spin), _("the UTM \"easting\" value of the upper-right corner pixel of the map") );
479 cn_label = gtk_label_new ( _("Corner pixel northing:") );
480 cn_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 9000000.0, 1, 5, 0 ), 1, 4 );
481 gtk_widget_set_tooltip_text ( GTK_WIDGET(cn_spin), _("the UTM \"northing\" value of the upper-right corner pixel of the map") );
483 xlabel = gtk_label_new ( _("X (easting) scale (mpp): "));
484 ylabel = gtk_label_new ( _("Y (northing) scale (mpp): "));
486 xspin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
487 gtk_widget_set_tooltip_text ( GTK_WIDGET(xspin), _("the scale of the map in the X direction (meters per pixel)") );
488 yspin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
489 gtk_widget_set_tooltip_text ( GTK_WIDGET(yspin), _("the scale of the map in the Y direction (meters per pixel)") );
491 imagelabel = gtk_label_new ( _("Map Image:") );
492 imageentry = vik_file_entry_new (GTK_FILE_CHOOSER_ACTION_OPEN);
496 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin), (*vgl)->corner.easting );
497 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin), (*vgl)->corner.northing );
498 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin), (*vgl)->mpp_easting );
499 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin), (*vgl)->mpp_northing );
501 vik_file_entry_set_filename ( VIK_FILE_ENTRY(imageentry), (*vgl)->image );
505 VikCoord corner_coord;
507 vik_viewport_screen_to_coord ( VIK_VIEWPORT(vp), 0, 0, &corner_coord );
508 vik_coord_to_utm ( &corner_coord, &utm );
509 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin), utm.easting );
510 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin), utm.northing );
511 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin), vik_viewport_get_xmpp ( VIK_VIEWPORT(vp) ) );
512 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin), vik_viewport_get_ympp ( VIK_VIEWPORT(vp) ) );
515 gtk_table_attach_defaults ( GTK_TABLE(table), imagelabel, 0, 1, 0, 1 );
516 gtk_table_attach_defaults ( GTK_TABLE(table), imageentry, 1, 2, 0, 1 );
517 gtk_table_attach_defaults ( GTK_TABLE(table), wfp_hbox, 0, 2, 1, 2 );
518 gtk_table_attach_defaults ( GTK_TABLE(table), xlabel, 0, 1, 2, 3 );
519 gtk_table_attach_defaults ( GTK_TABLE(table), xspin, 1, 2, 2, 3 );
520 gtk_table_attach_defaults ( GTK_TABLE(table), ylabel, 0, 1, 3, 4 );
521 gtk_table_attach_defaults ( GTK_TABLE(table), yspin, 1, 2, 3, 4 );
522 gtk_table_attach_defaults ( GTK_TABLE(table), ce_label, 0, 1, 4, 5 );
523 gtk_table_attach_defaults ( GTK_TABLE(table), ce_spin, 1, 2, 4, 5 );
524 gtk_table_attach_defaults ( GTK_TABLE(table), cn_label, 0, 1, 5, 6 );
525 gtk_table_attach_defaults ( GTK_TABLE(table), cn_spin, 1, 2, 5, 6 );
527 pass_along[0] = xspin;
528 pass_along[1] = yspin;
529 pass_along[2] = ce_spin;
530 pass_along[3] = cn_spin;
531 g_signal_connect_swapped ( G_OBJECT(wfp_button), "clicked", G_CALLBACK(georef_layer_dialog_load), pass_along );
534 gtk_widget_grab_focus ( response_w );
536 gtk_widget_show_all ( table );
538 if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
542 *vgl = georef_layer_new ();
543 vik_layer_rename ( VIK_LAYER(*vgl), vik_georef_layer_interface.name );
545 (*vgl)->corner.easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(ce_spin) );
546 (*vgl)->corner.northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(cn_spin) );
547 (*vgl)->mpp_easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(xspin) );
548 (*vgl)->mpp_northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(yspin) );
549 if ( (!(*vgl)->image) || strcmp( (*vgl)->image, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry)) ) != 0 )
551 georef_layer_set_image ( *vgl, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry)) );
552 georef_layer_load_image ( *vgl );
555 gtk_widget_destroy ( GTK_WIDGET(dialog) );
558 gtk_widget_destroy ( GTK_WIDGET(dialog) );
562 static void georef_layer_zoom_to_fit ( gpointer vgl_vlp[2] )
564 vik_viewport_set_xmpp ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1])), VIK_GEOREF_LAYER(vgl_vlp[0])->mpp_easting );
565 vik_viewport_set_ympp ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1])), VIK_GEOREF_LAYER(vgl_vlp[0])->mpp_northing );
566 vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vgl_vlp[1]) );
569 static void georef_layer_goto_center ( gpointer vgl_vlp[2] )
571 VikGeorefLayer *vgl = VIK_GEOREF_LAYER ( vgl_vlp[0] );
572 VikViewport *vp = vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1]));
576 vik_coord_to_utm ( vik_viewport_get_center ( vp ), &utm );
578 utm.easting = vgl->corner.easting + (vgl->width * vgl->mpp_easting / 2); /* only an approximation */
579 utm.northing = vgl->corner.northing - (vgl->height * vgl->mpp_northing / 2);
581 vik_coord_load_from_utm ( &coord, vik_viewport_get_coord_mode ( vp ), &utm );
582 vik_viewport_set_center_coord ( vp, &coord );
584 vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vgl_vlp[1]) );
587 static void georef_layer_add_menu_items ( VikGeorefLayer *vgl, GtkMenu *menu, gpointer vlp )
589 static gpointer pass_along[2];
594 item = gtk_menu_item_new();
595 gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
596 gtk_widget_show ( item );
598 item = gtk_menu_item_new_with_mnemonic ( _("_Zoom to Fit Map") );
599 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_zoom_to_fit), pass_along );
600 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
601 gtk_widget_show ( item );
603 item = gtk_menu_item_new_with_mnemonic ( _("_Goto Map Center") );
604 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_goto_center), pass_along );
605 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
606 gtk_widget_show ( item );
608 item = gtk_menu_item_new_with_mnemonic ( _("_Export to World File") );
609 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_export_params), pass_along );
610 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
611 gtk_widget_show ( item );
615 static gpointer georef_layer_move_create ( VikWindow *vw, VikViewport *vvp)
620 static gboolean georef_layer_move_release ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
622 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
625 if ( vgl->click_x != -1 )
627 vgl->corner.easting += (event->x - vgl->click_x) * vik_viewport_get_xmpp (vvp);
628 vgl->corner.northing -= (event->y - vgl->click_y) * vik_viewport_get_ympp (vvp);
629 vik_layer_emit_update ( VIK_LAYER(vgl) );
632 return FALSE; /* I didn't move anything on this layer! */
635 static gpointer georef_layer_zoom_create ( VikWindow *vw, VikViewport *vvp)
640 static gboolean georef_layer_zoom_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
642 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
644 if ( event->button == 1 )
646 if ( vgl->mpp_easting < (VIK_VIEWPORT_MAX_ZOOM / 1.05) && vgl->mpp_northing < (VIK_VIEWPORT_MAX_ZOOM / 1.05) )
648 vgl->mpp_easting *= 1.01;
649 vgl->mpp_northing *= 1.01;
654 if ( vgl->mpp_easting > (VIK_VIEWPORT_MIN_ZOOM * 1.05) && vgl->mpp_northing > (VIK_VIEWPORT_MIN_ZOOM * 1.05) )
656 vgl->mpp_easting /= 1.01;
657 vgl->mpp_northing /= 1.01;
660 vik_viewport_set_xmpp ( vvp, vgl->mpp_easting );
661 vik_viewport_set_ympp ( vvp, vgl->mpp_northing );
662 vik_layer_emit_update ( VIK_LAYER(vgl) );
666 static gboolean georef_layer_move_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
668 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
670 vgl->click_x = event->x;
671 vgl->click_y = event->y;