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, NULL, 0, NULL, NULL, },
38 { "corner_easting", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL },
39 { "corner_northing", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL },
40 { "mpp_easting", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL },
41 { "mpp_northing", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL },
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 // See comment in viktrwlayer.c for advice on values used
69 static VikToolInterface georef_tools[] = {
70 { { "GeorefMoveMap", "vik-icon-Georef Move Map", N_("_Georef Move Map"), NULL, N_("Georef Move Map"), 0 },
71 (VikToolConstructorFunc) georef_layer_move_create, NULL, NULL, NULL,
72 (VikToolMouseFunc) georef_layer_move_press, NULL, (VikToolMouseFunc) georef_layer_move_release,
73 (VikToolKeyFunc) NULL,
75 GDK_CURSOR_IS_PIXMAP, &cursor_geomove_pixbuf },
77 { { "GeorefZoomTool", "vik-icon-Georef Zoom Tool", N_("Georef Z_oom Tool"), NULL, N_("Georef Zoom Tool"), 0 },
78 (VikToolConstructorFunc) georef_layer_zoom_create, NULL, NULL, NULL,
79 (VikToolMouseFunc) georef_layer_zoom_press, NULL, NULL,
80 (VikToolKeyFunc) NULL,
82 GDK_CURSOR_IS_PIXMAP, &cursor_geozoom_pixbuf },
85 VikLayerInterface vik_georef_layer_interface = {
89 &vikgeoreflayer_pixbuf, /*icon */
92 sizeof(georef_tools) / sizeof(VikToolInterface),
101 (VikLayerFuncCreate) georef_layer_create,
102 (VikLayerFuncRealize) NULL,
103 (VikLayerFuncPostRead) georef_layer_load_image,
104 (VikLayerFuncFree) georef_layer_free,
106 (VikLayerFuncProperties) georef_layer_properties,
107 (VikLayerFuncDraw) georef_layer_draw,
108 (VikLayerFuncChangeCoordMode) NULL,
110 (VikLayerFuncSetMenuItemsSelection) NULL,
111 (VikLayerFuncGetMenuItemsSelection) NULL,
113 (VikLayerFuncAddMenuItems) georef_layer_add_menu_items,
114 (VikLayerFuncSublayerAddMenuItems) NULL,
116 (VikLayerFuncSublayerRenameRequest) NULL,
117 (VikLayerFuncSublayerToggleVisible) NULL,
118 (VikLayerFuncSublayerTooltip) NULL,
119 (VikLayerFuncLayerTooltip) georef_layer_tooltip,
120 (VikLayerFuncLayerSelected) NULL,
122 (VikLayerFuncMarshall) georef_layer_marshall,
123 (VikLayerFuncUnmarshall) georef_layer_unmarshall,
125 (VikLayerFuncSetParam) georef_layer_set_param,
126 (VikLayerFuncGetParam) georef_layer_get_param,
128 (VikLayerFuncReadFileData) NULL,
129 (VikLayerFuncWriteFileData) NULL,
131 (VikLayerFuncDeleteItem) NULL,
132 (VikLayerFuncCutItem) NULL,
133 (VikLayerFuncCopyItem) NULL,
134 (VikLayerFuncPasteItem) NULL,
135 (VikLayerFuncFreeCopiedItem) NULL,
136 (VikLayerFuncDragDropRequest) NULL,
138 (VikLayerFuncSelectClick) NULL,
139 (VikLayerFuncSelectMove) NULL,
140 (VikLayerFuncSelectRelease) NULL,
141 (VikLayerFuncSelectedViewportMenu) NULL,
144 struct _VikGeorefLayer {
149 gdouble mpp_easting, mpp_northing;
153 guint32 scaled_width, scaled_height;
155 gint click_x, click_y;
160 GType vik_georef_layer_get_type ()
162 static GType vgl_type = 0;
166 static const GTypeInfo vgl_info =
168 sizeof (VikGeorefLayerClass),
169 NULL, /* base_init */
170 NULL, /* base_finalize */
171 NULL, /* class init */
172 NULL, /* class_finalize */
173 NULL, /* class_data */
174 sizeof (VikGeorefLayer),
176 NULL /* instance init */
178 vgl_type = g_type_register_static ( VIK_LAYER_TYPE, "VikGeorefLayer", &vgl_info, 0 );
184 static const gchar* georef_layer_tooltip ( VikGeorefLayer *vgl )
189 static void georef_layer_marshall( VikGeorefLayer *vgl, guint8 **data, gint *len )
191 vik_layer_marshall_params ( VIK_LAYER(vgl), data, len );
194 static VikGeorefLayer *georef_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp )
196 VikGeorefLayer *rv = georef_layer_new ();
197 vik_layer_unmarshall_params ( VIK_LAYER(rv), data, len, vvp );
199 georef_layer_load_image ( rv );
204 static gboolean georef_layer_set_param ( VikGeorefLayer *vgl, guint16 id, VikLayerParamData data, VikViewport *vp, gboolean is_file_operation )
208 case PARAM_IMAGE: georef_layer_set_image ( vgl, data.s ); break;
209 case PARAM_CN: vgl->corner.northing = data.d; break;
210 case PARAM_CE: vgl->corner.easting = data.d; break;
211 case PARAM_MN: vgl->mpp_northing = data.d; break;
212 case PARAM_ME: vgl->mpp_easting = data.d; break;
217 static VikLayerParamData georef_layer_get_param ( VikGeorefLayer *vgl, guint16 id, gboolean is_file_operation )
219 VikLayerParamData rv;
222 case PARAM_IMAGE: rv.s = vgl->image ? vgl->image : ""; break;
223 case PARAM_CN: rv.d = vgl->corner.northing; break;
224 case PARAM_CE: rv.d = vgl->corner.easting; break;
225 case PARAM_MN: rv.d = vgl->mpp_northing; break;
226 case PARAM_ME: rv.d = vgl->mpp_easting; break;
231 VikGeorefLayer *georef_layer_new ( )
233 VikGeorefLayer *vgl = VIK_GEOREF_LAYER ( g_object_new ( VIK_GEOREF_LAYER_TYPE, NULL ) );
234 vik_layer_set_type ( VIK_LAYER(vgl), VIK_LAYER_GEOREF );
241 vgl->scaled_width = 0;
242 vgl->scaled_height = 0;
246 static void georef_layer_draw ( VikGeorefLayer *vgl, gpointer data )
251 VikViewport *vp = VIK_VIEWPORT(data);
252 struct UTM utm_middle;
253 gdouble xmpp = vik_viewport_get_xmpp(vp), ympp = vik_viewport_get_ympp(vp);
254 GdkPixbuf *pixbuf = vgl->pixbuf;
255 guint layer_width = vgl->width;
256 guint layer_height = vgl->height;
258 vik_coord_to_utm ( vik_viewport_get_center ( vp ), &utm_middle );
260 /* scale the pixbuf if it doesn't match our dimensions */
261 if ( xmpp != vgl->mpp_easting || ympp != vgl->mpp_northing )
263 layer_width = round(vgl->width * vgl->mpp_easting / xmpp);
264 layer_height = round(vgl->height * vgl->mpp_northing / ympp);
266 /* rescale if necessary */
267 if (layer_width == vgl->scaled_width && layer_height == vgl->scaled_height && vgl->scaled != NULL)
268 pixbuf = vgl->scaled;
271 pixbuf = gdk_pixbuf_scale_simple(
278 if (vgl->scaled != NULL)
279 g_object_unref(vgl->scaled);
281 vgl->scaled = pixbuf;
282 vgl->scaled_width = layer_width;
283 vgl->scaled_height = layer_height;
287 guint width = vik_viewport_get_width(vp), height = vik_viewport_get_height(vp);
289 vgl->corner.zone = utm_middle.zone;
290 vgl->corner.letter = utm_middle.letter;
291 VikCoord corner_coord;
292 vik_coord_load_from_utm ( &corner_coord, vik_viewport_get_coord_mode(vp), &(vgl->corner) );
293 vik_viewport_coord_to_screen ( vp, &corner_coord, &x, &y );
294 if ( (x < 0 || x < width) && (y < 0 || y < height) && x+layer_width > 0 && y+layer_height > 0 )
295 vik_viewport_draw_pixbuf ( vp, pixbuf, 0, 0, x, y, layer_width, layer_height ); /* todo: draw only what we need to. */
299 static void georef_layer_free ( VikGeorefLayer *vgl )
301 if ( vgl->image != NULL )
302 g_free ( vgl->image );
303 if ( vgl->scaled != NULL )
304 g_object_unref ( vgl->scaled );
307 VikGeorefLayer *georef_layer_create ( VikViewport *vp )
309 return georef_layer_new ();
312 gboolean georef_layer_properties ( VikGeorefLayer *vgl, gpointer vp )
314 return georef_layer_dialog ( &vgl, vp, VIK_GTK_WINDOW_FROM_WIDGET(vp) );
317 static void georef_layer_load_image ( VikGeorefLayer *vgl )
320 if ( vgl->image == NULL )
324 g_object_unref ( G_OBJECT(vgl->pixbuf) );
327 g_object_unref ( G_OBJECT(vgl->scaled) );
331 vgl->pixbuf = gdk_pixbuf_new_from_file ( vgl->image, &gx );
335 g_warning ( _("Couldn't open image file: %s"), gx->message );
340 vgl->width = gdk_pixbuf_get_width ( vgl->pixbuf );
341 vgl->height = gdk_pixbuf_get_height ( vgl->pixbuf );
344 /* should find length and width here too */
347 static void georef_layer_set_image ( VikGeorefLayer *vgl, const gchar *image )
350 g_free ( vgl->image );
353 g_object_unref ( vgl->scaled );
358 vgl->image = g_strdup ( image );
361 static gboolean world_file_read_line ( gchar *buffer, gint size, FILE *f, GtkWidget *widget, gboolean use_value )
363 if (!fgets ( buffer, 1024, f ))
365 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(widget), _("Unexpected end of file reading World file.") );
373 gdouble val = g_strtod ( buffer, NULL );
374 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(widget), val > 0 ? val : -val );
379 static void georef_layer_dialog_load ( GtkWidget *pass_along[4] )
381 GtkWidget *file_selector = gtk_file_chooser_dialog_new (_("Choose World file"),
383 GTK_FILE_CHOOSER_ACTION_OPEN,
384 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
385 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
388 if ( gtk_dialog_run ( GTK_DIALOG ( file_selector ) ) == GTK_RESPONSE_ACCEPT )
390 FILE *f = g_fopen ( gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(file_selector) ), "r" );
391 gtk_widget_destroy ( file_selector );
394 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]), _("The World file you requested could not be opened for reading.") );
399 gchar *buffer = g_malloc ( 1024 * sizeof(gchar) );
400 if ( world_file_read_line ( buffer, 1024, f, pass_along[0], TRUE ) && world_file_read_line ( buffer, 1024, f, pass_along[0], FALSE)
401 && world_file_read_line ( buffer, 1024, f, pass_along[0], FALSE ) && world_file_read_line ( buffer, 1024, f, pass_along[1], TRUE)
402 && world_file_read_line ( buffer, 1024, f, pass_along[2], TRUE ) && world_file_read_line ( buffer, 1024, f, pass_along[3], TRUE ) )
411 gtk_widget_destroy ( file_selector );
414 file selection dialog
415 file opener for reading, if NULL, send error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]) )
416 does that catch directories too?
417 read lines -- if not enough lines, give error.
418 if anything outside, give error. define range with #define CONSTANTS
419 put 'em in thar widgets, and that's it.
423 static void georef_layer_export_params ( gpointer *pass_along[2] )
425 VikGeorefLayer *vgl = VIK_GEOREF_LAYER(pass_along[0]);
426 GtkWidget *file_selector = gtk_file_chooser_dialog_new (_("Choose World file"),
428 GTK_FILE_CHOOSER_ACTION_SAVE,
429 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
430 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
432 if ( gtk_dialog_run ( GTK_DIALOG ( file_selector ) ) == GTK_RESPONSE_ACCEPT )
434 FILE *f = g_fopen ( gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(file_selector) ), "w" );
436 gtk_widget_destroy ( file_selector );
439 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]), _("The file you requested could not be opened for writing.") );
444 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 );
450 gtk_widget_destroy ( file_selector );
453 /* returns TRUE if OK was pressed. */
454 static gboolean georef_layer_dialog ( VikGeorefLayer **vgl, gpointer vp, GtkWindow *w )
456 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Layer Properties"),
458 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
464 /* Default to reject as user really needs to specify map file first */
465 gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
466 GtkWidget *response_w = NULL;
467 #if GTK_CHECK_VERSION (2, 20, 0)
468 response_w = gtk_dialog_get_widget_for_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
470 GtkWidget *table, *wfp_hbox, *wfp_label, *wfp_button, *ce_label, *ce_spin, *cn_label, *cn_spin, *xlabel, *xspin, *ylabel, *yspin, *imagelabel, *imageentry;
472 GtkWidget *pass_along[4];
474 table = gtk_table_new ( 6, 2, FALSE );
475 gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), table, TRUE, TRUE, 0 );
477 wfp_hbox = gtk_hbox_new ( FALSE, 0 );
478 wfp_label = gtk_label_new ( _("World File Parameters:") );
479 wfp_button = gtk_button_new_with_label ( _("Load From File...") );
481 gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_label, TRUE, TRUE, 0 );
482 gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_button, FALSE, FALSE, 3 );
484 ce_label = gtk_label_new ( _("Corner pixel easting:") );
485 ce_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 1500000.0, 1, 5, 0 ), 1, 4 );
486 gtk_widget_set_tooltip_text ( GTK_WIDGET(ce_spin), _("the UTM \"easting\" value of the upper-right corner pixel of the map") );
488 cn_label = gtk_label_new ( _("Corner pixel northing:") );
489 cn_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 9000000.0, 1, 5, 0 ), 1, 4 );
490 gtk_widget_set_tooltip_text ( GTK_WIDGET(cn_spin), _("the UTM \"northing\" value of the upper-right corner pixel of the map") );
492 xlabel = gtk_label_new ( _("X (easting) scale (mpp): "));
493 ylabel = gtk_label_new ( _("Y (northing) scale (mpp): "));
495 xspin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
496 gtk_widget_set_tooltip_text ( GTK_WIDGET(xspin), _("the scale of the map in the X direction (meters per pixel)") );
497 yspin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
498 gtk_widget_set_tooltip_text ( GTK_WIDGET(yspin), _("the scale of the map in the Y direction (meters per pixel)") );
500 imagelabel = gtk_label_new ( _("Map Image:") );
501 imageentry = vik_file_entry_new (GTK_FILE_CHOOSER_ACTION_OPEN);
505 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin), (*vgl)->corner.easting );
506 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin), (*vgl)->corner.northing );
507 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin), (*vgl)->mpp_easting );
508 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin), (*vgl)->mpp_northing );
510 vik_file_entry_set_filename ( VIK_FILE_ENTRY(imageentry), (*vgl)->image );
514 VikCoord corner_coord;
516 vik_viewport_screen_to_coord ( VIK_VIEWPORT(vp), 0, 0, &corner_coord );
517 vik_coord_to_utm ( &corner_coord, &utm );
518 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin), utm.easting );
519 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin), utm.northing );
520 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin), vik_viewport_get_xmpp ( VIK_VIEWPORT(vp) ) );
521 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin), vik_viewport_get_ympp ( VIK_VIEWPORT(vp) ) );
524 gtk_table_attach_defaults ( GTK_TABLE(table), imagelabel, 0, 1, 0, 1 );
525 gtk_table_attach_defaults ( GTK_TABLE(table), imageentry, 1, 2, 0, 1 );
526 gtk_table_attach_defaults ( GTK_TABLE(table), wfp_hbox, 0, 2, 1, 2 );
527 gtk_table_attach_defaults ( GTK_TABLE(table), xlabel, 0, 1, 2, 3 );
528 gtk_table_attach_defaults ( GTK_TABLE(table), xspin, 1, 2, 2, 3 );
529 gtk_table_attach_defaults ( GTK_TABLE(table), ylabel, 0, 1, 3, 4 );
530 gtk_table_attach_defaults ( GTK_TABLE(table), yspin, 1, 2, 3, 4 );
531 gtk_table_attach_defaults ( GTK_TABLE(table), ce_label, 0, 1, 4, 5 );
532 gtk_table_attach_defaults ( GTK_TABLE(table), ce_spin, 1, 2, 4, 5 );
533 gtk_table_attach_defaults ( GTK_TABLE(table), cn_label, 0, 1, 5, 6 );
534 gtk_table_attach_defaults ( GTK_TABLE(table), cn_spin, 1, 2, 5, 6 );
536 pass_along[0] = xspin;
537 pass_along[1] = yspin;
538 pass_along[2] = ce_spin;
539 pass_along[3] = cn_spin;
540 g_signal_connect_swapped ( G_OBJECT(wfp_button), "clicked", G_CALLBACK(georef_layer_dialog_load), pass_along );
543 gtk_widget_grab_focus ( response_w );
545 gtk_widget_show_all ( table );
547 if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
551 *vgl = georef_layer_new ();
552 vik_layer_rename ( VIK_LAYER(*vgl), vik_georef_layer_interface.name );
554 (*vgl)->corner.easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(ce_spin) );
555 (*vgl)->corner.northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(cn_spin) );
556 (*vgl)->mpp_easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(xspin) );
557 (*vgl)->mpp_northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(yspin) );
558 if ( (!(*vgl)->image) || strcmp( (*vgl)->image, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry)) ) != 0 )
560 georef_layer_set_image ( *vgl, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry)) );
561 georef_layer_load_image ( *vgl );
564 gtk_widget_destroy ( GTK_WIDGET(dialog) );
567 gtk_widget_destroy ( GTK_WIDGET(dialog) );
571 static void georef_layer_zoom_to_fit ( gpointer vgl_vlp[2] )
573 vik_viewport_set_xmpp ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1])), VIK_GEOREF_LAYER(vgl_vlp[0])->mpp_easting );
574 vik_viewport_set_ympp ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1])), VIK_GEOREF_LAYER(vgl_vlp[0])->mpp_northing );
575 vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vgl_vlp[1]) );
578 static void georef_layer_goto_center ( gpointer vgl_vlp[2] )
580 VikGeorefLayer *vgl = VIK_GEOREF_LAYER ( vgl_vlp[0] );
581 VikViewport *vp = vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1]));
585 vik_coord_to_utm ( vik_viewport_get_center ( vp ), &utm );
587 utm.easting = vgl->corner.easting + (vgl->width * vgl->mpp_easting / 2); /* only an approximation */
588 utm.northing = vgl->corner.northing - (vgl->height * vgl->mpp_northing / 2);
590 vik_coord_load_from_utm ( &coord, vik_viewport_get_coord_mode ( vp ), &utm );
591 vik_viewport_set_center_coord ( vp, &coord );
593 vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vgl_vlp[1]) );
596 static void georef_layer_add_menu_items ( VikGeorefLayer *vgl, GtkMenu *menu, gpointer vlp )
598 static gpointer pass_along[2];
603 item = gtk_menu_item_new();
604 gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
605 gtk_widget_show ( item );
608 item = gtk_image_menu_item_new_with_mnemonic ( _("_Zoom to Fit Map") );
609 gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_FIT, GTK_ICON_SIZE_MENU) );
610 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_zoom_to_fit), pass_along );
611 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
612 gtk_widget_show ( item );
614 item = gtk_image_menu_item_new_with_mnemonic ( _("_Goto Map Center") );
615 gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU) );
616 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_goto_center), pass_along );
617 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
618 gtk_widget_show ( item );
620 item = gtk_image_menu_item_new_with_mnemonic ( _("_Export to World File") );
621 gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_HARDDISK, GTK_ICON_SIZE_MENU) );
622 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_export_params), pass_along );
623 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
624 gtk_widget_show ( item );
628 static gpointer georef_layer_move_create ( VikWindow *vw, VikViewport *vvp)
633 static gboolean georef_layer_move_release ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
635 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
638 if ( vgl->click_x != -1 )
640 vgl->corner.easting += (event->x - vgl->click_x) * vik_viewport_get_xmpp (vvp);
641 vgl->corner.northing -= (event->y - vgl->click_y) * vik_viewport_get_ympp (vvp);
642 vik_layer_emit_update ( VIK_LAYER(vgl) );
645 return FALSE; /* I didn't move anything on this layer! */
648 static gpointer georef_layer_zoom_create ( VikWindow *vw, VikViewport *vvp)
653 static gboolean georef_layer_zoom_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
655 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
657 if ( event->button == 1 )
659 if ( vgl->mpp_easting < (VIK_VIEWPORT_MAX_ZOOM / 1.05) && vgl->mpp_northing < (VIK_VIEWPORT_MAX_ZOOM / 1.05) )
661 vgl->mpp_easting *= 1.01;
662 vgl->mpp_northing *= 1.01;
667 if ( vgl->mpp_easting > (VIK_VIEWPORT_MIN_ZOOM * 1.05) && vgl->mpp_northing > (VIK_VIEWPORT_MIN_ZOOM * 1.05) )
669 vgl->mpp_easting /= 1.01;
670 vgl->mpp_northing /= 1.01;
673 vik_viewport_set_xmpp ( vvp, vgl->mpp_easting );
674 vik_viewport_set_ympp ( vvp, vgl->mpp_northing );
675 vik_layer_emit_update ( VIK_LAYER(vgl) );
679 static gboolean georef_layer_move_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
681 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
683 vgl->click_x = event->x;
684 vgl->click_y = event->y;