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 (VikLayerFuncSelectedViewportMenu) NULL,
133 struct _VikGeorefLayer {
138 gdouble mpp_easting, mpp_northing;
142 guint32 scaled_width, scaled_height;
144 gint click_x, click_y;
149 GType vik_georef_layer_get_type ()
151 static GType vgl_type = 0;
155 static const GTypeInfo vgl_info =
157 sizeof (VikGeorefLayerClass),
158 NULL, /* base_init */
159 NULL, /* base_finalize */
160 NULL, /* class init */
161 NULL, /* class_finalize */
162 NULL, /* class_data */
163 sizeof (VikGeorefLayer),
165 NULL /* instance init */
167 vgl_type = g_type_register_static ( VIK_LAYER_TYPE, "VikGeorefLayer", &vgl_info, 0 );
173 static const gchar* georef_layer_tooltip ( VikGeorefLayer *vgl )
178 static void georef_layer_marshall( VikGeorefLayer *vgl, guint8 **data, gint *len )
180 vik_layer_marshall_params ( VIK_LAYER(vgl), data, len );
183 static VikGeorefLayer *georef_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp )
185 VikGeorefLayer *rv = georef_layer_new ();
186 vik_layer_unmarshall_params ( VIK_LAYER(rv), data, len, vvp );
188 georef_layer_load_image ( rv );
193 static gboolean georef_layer_set_param ( VikGeorefLayer *vgl, guint16 id, VikLayerParamData data, VikViewport *vp, gboolean is_file_operation )
197 case PARAM_IMAGE: georef_layer_set_image ( vgl, data.s ); break;
198 case PARAM_CN: vgl->corner.northing = data.d; break;
199 case PARAM_CE: vgl->corner.easting = data.d; break;
200 case PARAM_MN: vgl->mpp_northing = data.d; break;
201 case PARAM_ME: vgl->mpp_easting = data.d; break;
206 static VikLayerParamData georef_layer_get_param ( VikGeorefLayer *vgl, guint16 id, gboolean is_file_operation )
208 VikLayerParamData rv;
211 case PARAM_IMAGE: rv.s = vgl->image ? vgl->image : ""; break;
212 case PARAM_CN: rv.d = vgl->corner.northing; break;
213 case PARAM_CE: rv.d = vgl->corner.easting; break;
214 case PARAM_MN: rv.d = vgl->mpp_northing; break;
215 case PARAM_ME: rv.d = vgl->mpp_easting; break;
220 VikGeorefLayer *georef_layer_new ( )
222 VikGeorefLayer *vgl = VIK_GEOREF_LAYER ( g_object_new ( VIK_GEOREF_LAYER_TYPE, NULL ) );
223 vik_layer_init ( VIK_LAYER(vgl), VIK_LAYER_GEOREF );
230 vgl->scaled_width = 0;
231 vgl->scaled_height = 0;
235 static void georef_layer_draw ( VikGeorefLayer *vgl, gpointer data )
240 VikViewport *vp = VIK_VIEWPORT(data);
241 struct UTM utm_middle;
242 gdouble xmpp = vik_viewport_get_xmpp(vp), ympp = vik_viewport_get_ympp(vp);
243 GdkPixbuf *pixbuf = vgl->pixbuf;
244 guint layer_width = vgl->width;
245 guint layer_height = vgl->height;
247 vik_coord_to_utm ( vik_viewport_get_center ( vp ), &utm_middle );
249 /* scale the pixbuf if it doesn't match our dimensions */
250 if ( xmpp != vgl->mpp_easting || ympp != vgl->mpp_northing )
252 layer_width = round(vgl->width * vgl->mpp_easting / xmpp);
253 layer_height = round(vgl->height * vgl->mpp_northing / ympp);
255 /* rescale if necessary */
256 if (layer_width == vgl->scaled_width && layer_height == vgl->scaled_height && vgl->scaled != NULL)
257 pixbuf = vgl->scaled;
260 pixbuf = gdk_pixbuf_scale_simple(
267 if (vgl->scaled != NULL)
268 g_object_unref(vgl->scaled);
270 vgl->scaled = pixbuf;
271 vgl->scaled_width = layer_width;
272 vgl->scaled_height = layer_height;
276 guint width = vik_viewport_get_width(vp), height = vik_viewport_get_height(vp);
278 vgl->corner.zone = utm_middle.zone;
279 vgl->corner.letter = utm_middle.letter;
280 VikCoord corner_coord;
281 vik_coord_load_from_utm ( &corner_coord, vik_viewport_get_coord_mode(vp), &(vgl->corner) );
282 vik_viewport_coord_to_screen ( vp, &corner_coord, &x, &y );
283 if ( (x < 0 || x < width) && (y < 0 || y < height) && x+layer_width > 0 && y+layer_height > 0 )
284 vik_viewport_draw_pixbuf ( vp, pixbuf, 0, 0, x, y, layer_width, layer_height ); /* todo: draw only what we need to. */
288 static void georef_layer_free ( VikGeorefLayer *vgl )
290 if ( vgl->image != NULL )
291 g_free ( vgl->image );
292 if ( vgl->scaled != NULL )
293 g_object_unref ( vgl->scaled );
296 VikGeorefLayer *georef_layer_create ( VikViewport *vp )
298 return georef_layer_new ();
301 gboolean georef_layer_properties ( VikGeorefLayer *vgl, gpointer vp )
303 return georef_layer_dialog ( &vgl, vp, VIK_GTK_WINDOW_FROM_WIDGET(vp) );
306 static void georef_layer_load_image ( VikGeorefLayer *vgl )
309 if ( vgl->image == NULL )
313 g_object_unref ( G_OBJECT(vgl->pixbuf) );
316 g_object_unref ( G_OBJECT(vgl->scaled) );
320 vgl->pixbuf = gdk_pixbuf_new_from_file ( vgl->image, &gx );
324 g_warning ( _("Couldn't open image file: %s"), gx->message );
329 vgl->width = gdk_pixbuf_get_width ( vgl->pixbuf );
330 vgl->height = gdk_pixbuf_get_height ( vgl->pixbuf );
333 /* should find length and width here too */
336 static void georef_layer_set_image ( VikGeorefLayer *vgl, const gchar *image )
339 g_free ( vgl->image );
342 g_object_unref ( vgl->scaled );
347 vgl->image = g_strdup ( image );
350 static gboolean world_file_read_line ( gchar *buffer, gint size, FILE *f, GtkWidget *widget, gboolean use_value )
352 if (!fgets ( buffer, 1024, f ))
354 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(widget), _("Unexpected end of file reading World file.") );
362 gdouble val = g_strtod ( buffer, NULL );
363 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(widget), val > 0 ? val : -val );
368 static void georef_layer_dialog_load ( GtkWidget *pass_along[4] )
370 GtkWidget *file_selector = gtk_file_chooser_dialog_new (_("Choose World file"),
372 GTK_FILE_CHOOSER_ACTION_OPEN,
373 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
374 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
377 if ( gtk_dialog_run ( GTK_DIALOG ( file_selector ) ) == GTK_RESPONSE_ACCEPT )
379 FILE *f = g_fopen ( gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(file_selector) ), "r" );
380 gtk_widget_destroy ( file_selector );
383 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]), _("The World file you requested could not be opened for reading.") );
388 gchar *buffer = g_malloc ( 1024 * sizeof(gchar) );
389 if ( world_file_read_line ( buffer, 1024, f, pass_along[0], TRUE ) && world_file_read_line ( buffer, 1024, f, pass_along[0], FALSE)
390 && world_file_read_line ( buffer, 1024, f, pass_along[0], FALSE ) && world_file_read_line ( buffer, 1024, f, pass_along[1], TRUE)
391 && world_file_read_line ( buffer, 1024, f, pass_along[2], TRUE ) && world_file_read_line ( buffer, 1024, f, pass_along[3], TRUE ) )
400 gtk_widget_destroy ( file_selector );
403 file selection dialog
404 file opener for reading, if NULL, send error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]) )
405 does that catch directories too?
406 read lines -- if not enough lines, give error.
407 if anything outside, give error. define range with #define CONSTANTS
408 put 'em in thar widgets, and that's it.
412 static void georef_layer_export_params ( gpointer *pass_along[2] )
414 VikGeorefLayer *vgl = VIK_GEOREF_LAYER(pass_along[0]);
415 GtkWidget *file_selector = gtk_file_chooser_dialog_new (_("Choose World file"),
417 GTK_FILE_CHOOSER_ACTION_SAVE,
418 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
419 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
421 if ( gtk_dialog_run ( GTK_DIALOG ( file_selector ) ) == GTK_RESPONSE_ACCEPT )
423 FILE *f = g_fopen ( gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(file_selector) ), "w" );
425 gtk_widget_destroy ( file_selector );
428 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]), _("The file you requested could not be opened for writing.") );
433 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 );
439 gtk_widget_destroy ( file_selector );
442 /* returns TRUE if OK was pressed. */
443 static gboolean georef_layer_dialog ( VikGeorefLayer **vgl, gpointer vp, GtkWindow *w )
445 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Layer Properties"),
447 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
453 /* Default to reject as user really needs to specify map file first */
454 gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
455 GtkWidget *response_w = NULL;
456 #if GTK_CHECK_VERSION (2, 20, 0)
457 response_w = gtk_dialog_get_widget_for_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
459 GtkWidget *table, *wfp_hbox, *wfp_label, *wfp_button, *ce_label, *ce_spin, *cn_label, *cn_spin, *xlabel, *xspin, *ylabel, *yspin, *imagelabel, *imageentry;
461 GtkWidget *pass_along[4];
463 table = gtk_table_new ( 6, 2, FALSE );
464 gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), table, TRUE, TRUE, 0 );
466 wfp_hbox = gtk_hbox_new ( FALSE, 0 );
467 wfp_label = gtk_label_new ( _("World File Parameters:") );
468 wfp_button = gtk_button_new_with_label ( _("Load From File...") );
470 gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_label, TRUE, TRUE, 0 );
471 gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_button, FALSE, FALSE, 3 );
473 ce_label = gtk_label_new ( _("Corner pixel easting:") );
474 ce_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 1500000.0, 1, 5, 0 ), 1, 4 );
475 gtk_widget_set_tooltip_text ( GTK_WIDGET(ce_spin), _("the UTM \"easting\" value of the upper-right corner pixel of the map") );
477 cn_label = gtk_label_new ( _("Corner pixel northing:") );
478 cn_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 9000000.0, 1, 5, 0 ), 1, 4 );
479 gtk_widget_set_tooltip_text ( GTK_WIDGET(cn_spin), _("the UTM \"northing\" value of the upper-right corner pixel of the map") );
481 xlabel = gtk_label_new ( _("X (easting) scale (mpp): "));
482 ylabel = gtk_label_new ( _("Y (northing) scale (mpp): "));
484 xspin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
485 gtk_widget_set_tooltip_text ( GTK_WIDGET(xspin), _("the scale of the map in the X direction (meters per pixel)") );
486 yspin = 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(yspin), _("the scale of the map in the Y direction (meters per pixel)") );
489 imagelabel = gtk_label_new ( _("Map Image:") );
490 imageentry = vik_file_entry_new (GTK_FILE_CHOOSER_ACTION_OPEN);
494 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin), (*vgl)->corner.easting );
495 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin), (*vgl)->corner.northing );
496 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin), (*vgl)->mpp_easting );
497 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin), (*vgl)->mpp_northing );
499 vik_file_entry_set_filename ( VIK_FILE_ENTRY(imageentry), (*vgl)->image );
503 VikCoord corner_coord;
505 vik_viewport_screen_to_coord ( VIK_VIEWPORT(vp), 0, 0, &corner_coord );
506 vik_coord_to_utm ( &corner_coord, &utm );
507 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin), utm.easting );
508 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin), utm.northing );
509 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin), vik_viewport_get_xmpp ( VIK_VIEWPORT(vp) ) );
510 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin), vik_viewport_get_ympp ( VIK_VIEWPORT(vp) ) );
513 gtk_table_attach_defaults ( GTK_TABLE(table), imagelabel, 0, 1, 0, 1 );
514 gtk_table_attach_defaults ( GTK_TABLE(table), imageentry, 1, 2, 0, 1 );
515 gtk_table_attach_defaults ( GTK_TABLE(table), wfp_hbox, 0, 2, 1, 2 );
516 gtk_table_attach_defaults ( GTK_TABLE(table), xlabel, 0, 1, 2, 3 );
517 gtk_table_attach_defaults ( GTK_TABLE(table), xspin, 1, 2, 2, 3 );
518 gtk_table_attach_defaults ( GTK_TABLE(table), ylabel, 0, 1, 3, 4 );
519 gtk_table_attach_defaults ( GTK_TABLE(table), yspin, 1, 2, 3, 4 );
520 gtk_table_attach_defaults ( GTK_TABLE(table), ce_label, 0, 1, 4, 5 );
521 gtk_table_attach_defaults ( GTK_TABLE(table), ce_spin, 1, 2, 4, 5 );
522 gtk_table_attach_defaults ( GTK_TABLE(table), cn_label, 0, 1, 5, 6 );
523 gtk_table_attach_defaults ( GTK_TABLE(table), cn_spin, 1, 2, 5, 6 );
525 pass_along[0] = xspin;
526 pass_along[1] = yspin;
527 pass_along[2] = ce_spin;
528 pass_along[3] = cn_spin;
529 g_signal_connect_swapped ( G_OBJECT(wfp_button), "clicked", G_CALLBACK(georef_layer_dialog_load), pass_along );
532 gtk_widget_grab_focus ( response_w );
534 gtk_widget_show_all ( table );
536 if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
540 *vgl = georef_layer_new ();
541 vik_layer_rename ( VIK_LAYER(*vgl), vik_georef_layer_interface.name );
543 (*vgl)->corner.easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(ce_spin) );
544 (*vgl)->corner.northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(cn_spin) );
545 (*vgl)->mpp_easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(xspin) );
546 (*vgl)->mpp_northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(yspin) );
547 if ( (!(*vgl)->image) || strcmp( (*vgl)->image, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry)) ) != 0 )
549 georef_layer_set_image ( *vgl, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry)) );
550 georef_layer_load_image ( *vgl );
553 gtk_widget_destroy ( GTK_WIDGET(dialog) );
556 gtk_widget_destroy ( GTK_WIDGET(dialog) );
560 static void georef_layer_zoom_to_fit ( gpointer vgl_vlp[2] )
562 vik_viewport_set_xmpp ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1])), VIK_GEOREF_LAYER(vgl_vlp[0])->mpp_easting );
563 vik_viewport_set_ympp ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1])), VIK_GEOREF_LAYER(vgl_vlp[0])->mpp_northing );
564 vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vgl_vlp[1]) );
567 static void georef_layer_goto_center ( gpointer vgl_vlp[2] )
569 VikGeorefLayer *vgl = VIK_GEOREF_LAYER ( vgl_vlp[0] );
570 VikViewport *vp = vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1]));
574 vik_coord_to_utm ( vik_viewport_get_center ( vp ), &utm );
576 utm.easting = vgl->corner.easting + (vgl->width * vgl->mpp_easting / 2); /* only an approximation */
577 utm.northing = vgl->corner.northing - (vgl->height * vgl->mpp_northing / 2);
579 vik_coord_load_from_utm ( &coord, vik_viewport_get_coord_mode ( vp ), &utm );
580 vik_viewport_set_center_coord ( vp, &coord );
582 vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vgl_vlp[1]) );
585 static void georef_layer_add_menu_items ( VikGeorefLayer *vgl, GtkMenu *menu, gpointer vlp )
587 static gpointer pass_along[2];
592 item = gtk_menu_item_new();
593 gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
594 gtk_widget_show ( item );
596 item = gtk_menu_item_new_with_mnemonic ( _("_Zoom to Fit Map") );
597 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_zoom_to_fit), pass_along );
598 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
599 gtk_widget_show ( item );
601 item = gtk_menu_item_new_with_mnemonic ( _("_Goto Map Center") );
602 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_goto_center), pass_along );
603 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
604 gtk_widget_show ( item );
606 item = gtk_menu_item_new_with_mnemonic ( _("_Export to World File") );
607 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_export_params), pass_along );
608 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
609 gtk_widget_show ( item );
613 static gpointer georef_layer_move_create ( VikWindow *vw, VikViewport *vvp)
618 static gboolean georef_layer_move_release ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
620 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
623 if ( vgl->click_x != -1 )
625 vgl->corner.easting += (event->x - vgl->click_x) * vik_viewport_get_xmpp (vvp);
626 vgl->corner.northing -= (event->y - vgl->click_y) * vik_viewport_get_ympp (vvp);
627 vik_layer_emit_update ( VIK_LAYER(vgl) );
630 return FALSE; /* I didn't move anything on this layer! */
633 static gpointer georef_layer_zoom_create ( VikWindow *vw, VikViewport *vvp)
638 static gboolean georef_layer_zoom_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
640 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
642 if ( event->button == 1 )
644 if ( vgl->mpp_easting < (VIK_VIEWPORT_MAX_ZOOM / 1.05) && vgl->mpp_northing < (VIK_VIEWPORT_MAX_ZOOM / 1.05) )
646 vgl->mpp_easting *= 1.01;
647 vgl->mpp_northing *= 1.01;
652 if ( vgl->mpp_easting > (VIK_VIEWPORT_MIN_ZOOM * 1.05) && vgl->mpp_northing > (VIK_VIEWPORT_MIN_ZOOM * 1.05) )
654 vgl->mpp_easting /= 1.01;
655 vgl->mpp_northing /= 1.01;
658 vik_viewport_set_xmpp ( vvp, vgl->mpp_easting );
659 vik_viewport_set_ympp ( vvp, vgl->mpp_northing );
660 vik_layer_emit_update ( VIK_LAYER(vgl) );
664 static gboolean georef_layer_move_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
666 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
668 vgl->click_x = event->x;
669 vgl->click_y = event->y;