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 // 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 = {
88 &vikgeoreflayer_pixbuf, /*icon */
91 sizeof(georef_tools) / sizeof(VikToolInterface),
100 (VikLayerFuncCreate) georef_layer_create,
101 (VikLayerFuncRealize) NULL,
102 (VikLayerFuncPostRead) georef_layer_load_image,
103 (VikLayerFuncFree) georef_layer_free,
105 (VikLayerFuncProperties) georef_layer_properties,
106 (VikLayerFuncDraw) georef_layer_draw,
107 (VikLayerFuncChangeCoordMode) NULL,
109 (VikLayerFuncSetMenuItemsSelection) NULL,
110 (VikLayerFuncGetMenuItemsSelection) NULL,
112 (VikLayerFuncAddMenuItems) georef_layer_add_menu_items,
113 (VikLayerFuncSublayerAddMenuItems) NULL,
115 (VikLayerFuncSublayerRenameRequest) NULL,
116 (VikLayerFuncSublayerToggleVisible) NULL,
117 (VikLayerFuncSublayerTooltip) NULL,
118 (VikLayerFuncLayerTooltip) georef_layer_tooltip,
119 (VikLayerFuncLayerSelected) NULL,
121 (VikLayerFuncMarshall) georef_layer_marshall,
122 (VikLayerFuncUnmarshall) georef_layer_unmarshall,
124 (VikLayerFuncSetParam) georef_layer_set_param,
125 (VikLayerFuncGetParam) georef_layer_get_param,
127 (VikLayerFuncReadFileData) NULL,
128 (VikLayerFuncWriteFileData) NULL,
130 (VikLayerFuncDeleteItem) NULL,
131 (VikLayerFuncCutItem) NULL,
132 (VikLayerFuncCopyItem) NULL,
133 (VikLayerFuncPasteItem) NULL,
134 (VikLayerFuncFreeCopiedItem) NULL,
135 (VikLayerFuncDragDropRequest) NULL,
137 (VikLayerFuncSelectClick) NULL,
138 (VikLayerFuncSelectMove) NULL,
139 (VikLayerFuncSelectRelease) NULL,
140 (VikLayerFuncSelectedViewportMenu) NULL,
143 struct _VikGeorefLayer {
148 gdouble mpp_easting, mpp_northing;
152 guint32 scaled_width, scaled_height;
154 gint click_x, click_y;
159 GType vik_georef_layer_get_type ()
161 static GType vgl_type = 0;
165 static const GTypeInfo vgl_info =
167 sizeof (VikGeorefLayerClass),
168 NULL, /* base_init */
169 NULL, /* base_finalize */
170 NULL, /* class init */
171 NULL, /* class_finalize */
172 NULL, /* class_data */
173 sizeof (VikGeorefLayer),
175 NULL /* instance init */
177 vgl_type = g_type_register_static ( VIK_LAYER_TYPE, "VikGeorefLayer", &vgl_info, 0 );
183 static const gchar* georef_layer_tooltip ( VikGeorefLayer *vgl )
188 static void georef_layer_marshall( VikGeorefLayer *vgl, guint8 **data, gint *len )
190 vik_layer_marshall_params ( VIK_LAYER(vgl), data, len );
193 static VikGeorefLayer *georef_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp )
195 VikGeorefLayer *rv = georef_layer_new ();
196 vik_layer_unmarshall_params ( VIK_LAYER(rv), data, len, vvp );
198 georef_layer_load_image ( rv );
203 static gboolean georef_layer_set_param ( VikGeorefLayer *vgl, guint16 id, VikLayerParamData data, VikViewport *vp, gboolean is_file_operation )
207 case PARAM_IMAGE: georef_layer_set_image ( vgl, data.s ); break;
208 case PARAM_CN: vgl->corner.northing = data.d; break;
209 case PARAM_CE: vgl->corner.easting = data.d; break;
210 case PARAM_MN: vgl->mpp_northing = data.d; break;
211 case PARAM_ME: vgl->mpp_easting = data.d; break;
216 static VikLayerParamData georef_layer_get_param ( VikGeorefLayer *vgl, guint16 id, gboolean is_file_operation )
218 VikLayerParamData rv;
221 case PARAM_IMAGE: rv.s = vgl->image ? vgl->image : ""; break;
222 case PARAM_CN: rv.d = vgl->corner.northing; break;
223 case PARAM_CE: rv.d = vgl->corner.easting; break;
224 case PARAM_MN: rv.d = vgl->mpp_northing; break;
225 case PARAM_ME: rv.d = vgl->mpp_easting; break;
230 VikGeorefLayer *georef_layer_new ( )
232 VikGeorefLayer *vgl = VIK_GEOREF_LAYER ( g_object_new ( VIK_GEOREF_LAYER_TYPE, NULL ) );
233 vik_layer_init ( VIK_LAYER(vgl), VIK_LAYER_GEOREF );
240 vgl->scaled_width = 0;
241 vgl->scaled_height = 0;
245 static void georef_layer_draw ( VikGeorefLayer *vgl, gpointer data )
250 VikViewport *vp = VIK_VIEWPORT(data);
251 struct UTM utm_middle;
252 gdouble xmpp = vik_viewport_get_xmpp(vp), ympp = vik_viewport_get_ympp(vp);
253 GdkPixbuf *pixbuf = vgl->pixbuf;
254 guint layer_width = vgl->width;
255 guint layer_height = vgl->height;
257 vik_coord_to_utm ( vik_viewport_get_center ( vp ), &utm_middle );
259 /* scale the pixbuf if it doesn't match our dimensions */
260 if ( xmpp != vgl->mpp_easting || ympp != vgl->mpp_northing )
262 layer_width = round(vgl->width * vgl->mpp_easting / xmpp);
263 layer_height = round(vgl->height * vgl->mpp_northing / ympp);
265 /* rescale if necessary */
266 if (layer_width == vgl->scaled_width && layer_height == vgl->scaled_height && vgl->scaled != NULL)
267 pixbuf = vgl->scaled;
270 pixbuf = gdk_pixbuf_scale_simple(
277 if (vgl->scaled != NULL)
278 g_object_unref(vgl->scaled);
280 vgl->scaled = pixbuf;
281 vgl->scaled_width = layer_width;
282 vgl->scaled_height = layer_height;
286 guint width = vik_viewport_get_width(vp), height = vik_viewport_get_height(vp);
288 vgl->corner.zone = utm_middle.zone;
289 vgl->corner.letter = utm_middle.letter;
290 VikCoord corner_coord;
291 vik_coord_load_from_utm ( &corner_coord, vik_viewport_get_coord_mode(vp), &(vgl->corner) );
292 vik_viewport_coord_to_screen ( vp, &corner_coord, &x, &y );
293 if ( (x < 0 || x < width) && (y < 0 || y < height) && x+layer_width > 0 && y+layer_height > 0 )
294 vik_viewport_draw_pixbuf ( vp, pixbuf, 0, 0, x, y, layer_width, layer_height ); /* todo: draw only what we need to. */
298 static void georef_layer_free ( VikGeorefLayer *vgl )
300 if ( vgl->image != NULL )
301 g_free ( vgl->image );
302 if ( vgl->scaled != NULL )
303 g_object_unref ( vgl->scaled );
306 VikGeorefLayer *georef_layer_create ( VikViewport *vp )
308 return georef_layer_new ();
311 gboolean georef_layer_properties ( VikGeorefLayer *vgl, gpointer vp )
313 return georef_layer_dialog ( &vgl, vp, VIK_GTK_WINDOW_FROM_WIDGET(vp) );
316 static void georef_layer_load_image ( VikGeorefLayer *vgl )
319 if ( vgl->image == NULL )
323 g_object_unref ( G_OBJECT(vgl->pixbuf) );
326 g_object_unref ( G_OBJECT(vgl->scaled) );
330 vgl->pixbuf = gdk_pixbuf_new_from_file ( vgl->image, &gx );
334 g_warning ( _("Couldn't open image file: %s"), gx->message );
339 vgl->width = gdk_pixbuf_get_width ( vgl->pixbuf );
340 vgl->height = gdk_pixbuf_get_height ( vgl->pixbuf );
343 /* should find length and width here too */
346 static void georef_layer_set_image ( VikGeorefLayer *vgl, const gchar *image )
349 g_free ( vgl->image );
352 g_object_unref ( vgl->scaled );
357 vgl->image = g_strdup ( image );
360 static gboolean world_file_read_line ( gchar *buffer, gint size, FILE *f, GtkWidget *widget, gboolean use_value )
362 if (!fgets ( buffer, 1024, f ))
364 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(widget), _("Unexpected end of file reading World file.") );
372 gdouble val = g_strtod ( buffer, NULL );
373 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(widget), val > 0 ? val : -val );
378 static void georef_layer_dialog_load ( GtkWidget *pass_along[4] )
380 GtkWidget *file_selector = gtk_file_chooser_dialog_new (_("Choose World file"),
382 GTK_FILE_CHOOSER_ACTION_OPEN,
383 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
384 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
387 if ( gtk_dialog_run ( GTK_DIALOG ( file_selector ) ) == GTK_RESPONSE_ACCEPT )
389 FILE *f = g_fopen ( gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(file_selector) ), "r" );
390 gtk_widget_destroy ( file_selector );
393 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]), _("The World file you requested could not be opened for reading.") );
398 gchar *buffer = g_malloc ( 1024 * sizeof(gchar) );
399 if ( world_file_read_line ( buffer, 1024, f, pass_along[0], TRUE ) && world_file_read_line ( buffer, 1024, f, pass_along[0], FALSE)
400 && world_file_read_line ( buffer, 1024, f, pass_along[0], FALSE ) && world_file_read_line ( buffer, 1024, f, pass_along[1], TRUE)
401 && world_file_read_line ( buffer, 1024, f, pass_along[2], TRUE ) && world_file_read_line ( buffer, 1024, f, pass_along[3], TRUE ) )
410 gtk_widget_destroy ( file_selector );
413 file selection dialog
414 file opener for reading, if NULL, send error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]) )
415 does that catch directories too?
416 read lines -- if not enough lines, give error.
417 if anything outside, give error. define range with #define CONSTANTS
418 put 'em in thar widgets, and that's it.
422 static void georef_layer_export_params ( gpointer *pass_along[2] )
424 VikGeorefLayer *vgl = VIK_GEOREF_LAYER(pass_along[0]);
425 GtkWidget *file_selector = gtk_file_chooser_dialog_new (_("Choose World file"),
427 GTK_FILE_CHOOSER_ACTION_SAVE,
428 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
429 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
431 if ( gtk_dialog_run ( GTK_DIALOG ( file_selector ) ) == GTK_RESPONSE_ACCEPT )
433 FILE *f = g_fopen ( gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(file_selector) ), "w" );
435 gtk_widget_destroy ( file_selector );
438 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]), _("The file you requested could not be opened for writing.") );
443 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 );
449 gtk_widget_destroy ( file_selector );
452 /* returns TRUE if OK was pressed. */
453 static gboolean georef_layer_dialog ( VikGeorefLayer **vgl, gpointer vp, GtkWindow *w )
455 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Layer Properties"),
457 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
463 /* Default to reject as user really needs to specify map file first */
464 gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
465 GtkWidget *response_w = NULL;
466 #if GTK_CHECK_VERSION (2, 20, 0)
467 response_w = gtk_dialog_get_widget_for_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
469 GtkWidget *table, *wfp_hbox, *wfp_label, *wfp_button, *ce_label, *ce_spin, *cn_label, *cn_spin, *xlabel, *xspin, *ylabel, *yspin, *imagelabel, *imageentry;
471 GtkWidget *pass_along[4];
473 table = gtk_table_new ( 6, 2, FALSE );
474 gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), table, TRUE, TRUE, 0 );
476 wfp_hbox = gtk_hbox_new ( FALSE, 0 );
477 wfp_label = gtk_label_new ( _("World File Parameters:") );
478 wfp_button = gtk_button_new_with_label ( _("Load From File...") );
480 gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_label, TRUE, TRUE, 0 );
481 gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_button, FALSE, FALSE, 3 );
483 ce_label = gtk_label_new ( _("Corner pixel easting:") );
484 ce_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 1500000.0, 1, 5, 0 ), 1, 4 );
485 gtk_widget_set_tooltip_text ( GTK_WIDGET(ce_spin), _("the UTM \"easting\" value of the upper-right corner pixel of the map") );
487 cn_label = gtk_label_new ( _("Corner pixel northing:") );
488 cn_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 9000000.0, 1, 5, 0 ), 1, 4 );
489 gtk_widget_set_tooltip_text ( GTK_WIDGET(cn_spin), _("the UTM \"northing\" value of the upper-right corner pixel of the map") );
491 xlabel = gtk_label_new ( _("X (easting) scale (mpp): "));
492 ylabel = gtk_label_new ( _("Y (northing) scale (mpp): "));
494 xspin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
495 gtk_widget_set_tooltip_text ( GTK_WIDGET(xspin), _("the scale of the map in the X direction (meters per pixel)") );
496 yspin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
497 gtk_widget_set_tooltip_text ( GTK_WIDGET(yspin), _("the scale of the map in the Y direction (meters per pixel)") );
499 imagelabel = gtk_label_new ( _("Map Image:") );
500 imageentry = vik_file_entry_new (GTK_FILE_CHOOSER_ACTION_OPEN);
504 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin), (*vgl)->corner.easting );
505 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin), (*vgl)->corner.northing );
506 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin), (*vgl)->mpp_easting );
507 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin), (*vgl)->mpp_northing );
509 vik_file_entry_set_filename ( VIK_FILE_ENTRY(imageentry), (*vgl)->image );
513 VikCoord corner_coord;
515 vik_viewport_screen_to_coord ( VIK_VIEWPORT(vp), 0, 0, &corner_coord );
516 vik_coord_to_utm ( &corner_coord, &utm );
517 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin), utm.easting );
518 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin), utm.northing );
519 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin), vik_viewport_get_xmpp ( VIK_VIEWPORT(vp) ) );
520 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin), vik_viewport_get_ympp ( VIK_VIEWPORT(vp) ) );
523 gtk_table_attach_defaults ( GTK_TABLE(table), imagelabel, 0, 1, 0, 1 );
524 gtk_table_attach_defaults ( GTK_TABLE(table), imageentry, 1, 2, 0, 1 );
525 gtk_table_attach_defaults ( GTK_TABLE(table), wfp_hbox, 0, 2, 1, 2 );
526 gtk_table_attach_defaults ( GTK_TABLE(table), xlabel, 0, 1, 2, 3 );
527 gtk_table_attach_defaults ( GTK_TABLE(table), xspin, 1, 2, 2, 3 );
528 gtk_table_attach_defaults ( GTK_TABLE(table), ylabel, 0, 1, 3, 4 );
529 gtk_table_attach_defaults ( GTK_TABLE(table), yspin, 1, 2, 3, 4 );
530 gtk_table_attach_defaults ( GTK_TABLE(table), ce_label, 0, 1, 4, 5 );
531 gtk_table_attach_defaults ( GTK_TABLE(table), ce_spin, 1, 2, 4, 5 );
532 gtk_table_attach_defaults ( GTK_TABLE(table), cn_label, 0, 1, 5, 6 );
533 gtk_table_attach_defaults ( GTK_TABLE(table), cn_spin, 1, 2, 5, 6 );
535 pass_along[0] = xspin;
536 pass_along[1] = yspin;
537 pass_along[2] = ce_spin;
538 pass_along[3] = cn_spin;
539 g_signal_connect_swapped ( G_OBJECT(wfp_button), "clicked", G_CALLBACK(georef_layer_dialog_load), pass_along );
542 gtk_widget_grab_focus ( response_w );
544 gtk_widget_show_all ( table );
546 if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
550 *vgl = georef_layer_new ();
551 vik_layer_rename ( VIK_LAYER(*vgl), vik_georef_layer_interface.name );
553 (*vgl)->corner.easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(ce_spin) );
554 (*vgl)->corner.northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(cn_spin) );
555 (*vgl)->mpp_easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(xspin) );
556 (*vgl)->mpp_northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(yspin) );
557 if ( (!(*vgl)->image) || strcmp( (*vgl)->image, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry)) ) != 0 )
559 georef_layer_set_image ( *vgl, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry)) );
560 georef_layer_load_image ( *vgl );
563 gtk_widget_destroy ( GTK_WIDGET(dialog) );
566 gtk_widget_destroy ( GTK_WIDGET(dialog) );
570 static void georef_layer_zoom_to_fit ( gpointer vgl_vlp[2] )
572 vik_viewport_set_xmpp ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1])), VIK_GEOREF_LAYER(vgl_vlp[0])->mpp_easting );
573 vik_viewport_set_ympp ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1])), VIK_GEOREF_LAYER(vgl_vlp[0])->mpp_northing );
574 vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vgl_vlp[1]) );
577 static void georef_layer_goto_center ( gpointer vgl_vlp[2] )
579 VikGeorefLayer *vgl = VIK_GEOREF_LAYER ( vgl_vlp[0] );
580 VikViewport *vp = vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1]));
584 vik_coord_to_utm ( vik_viewport_get_center ( vp ), &utm );
586 utm.easting = vgl->corner.easting + (vgl->width * vgl->mpp_easting / 2); /* only an approximation */
587 utm.northing = vgl->corner.northing - (vgl->height * vgl->mpp_northing / 2);
589 vik_coord_load_from_utm ( &coord, vik_viewport_get_coord_mode ( vp ), &utm );
590 vik_viewport_set_center_coord ( vp, &coord );
592 vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vgl_vlp[1]) );
595 static void georef_layer_add_menu_items ( VikGeorefLayer *vgl, GtkMenu *menu, gpointer vlp )
597 static gpointer pass_along[2];
602 item = gtk_menu_item_new();
603 gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
604 gtk_widget_show ( item );
607 item = gtk_image_menu_item_new_with_mnemonic ( _("_Zoom to Fit Map") );
608 gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_FIT, GTK_ICON_SIZE_MENU) );
609 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_zoom_to_fit), pass_along );
610 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
611 gtk_widget_show ( item );
613 item = gtk_image_menu_item_new_with_mnemonic ( _("_Goto Map Center") );
614 gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU) );
615 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_goto_center), pass_along );
616 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
617 gtk_widget_show ( item );
619 item = gtk_image_menu_item_new_with_mnemonic ( _("_Export to World File") );
620 gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_HARDDISK, GTK_ICON_SIZE_MENU) );
621 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_export_params), pass_along );
622 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
623 gtk_widget_show ( item );
627 static gpointer georef_layer_move_create ( VikWindow *vw, VikViewport *vvp)
632 static gboolean georef_layer_move_release ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
634 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
637 if ( vgl->click_x != -1 )
639 vgl->corner.easting += (event->x - vgl->click_x) * vik_viewport_get_xmpp (vvp);
640 vgl->corner.northing -= (event->y - vgl->click_y) * vik_viewport_get_ympp (vvp);
641 vik_layer_emit_update ( VIK_LAYER(vgl), FALSE );
644 return FALSE; /* I didn't move anything on this layer! */
647 static gpointer georef_layer_zoom_create ( VikWindow *vw, VikViewport *vvp)
652 static gboolean georef_layer_zoom_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
654 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
656 if ( event->button == 1 )
658 if ( vgl->mpp_easting < (VIK_VIEWPORT_MAX_ZOOM / 1.05) && vgl->mpp_northing < (VIK_VIEWPORT_MAX_ZOOM / 1.05) )
660 vgl->mpp_easting *= 1.01;
661 vgl->mpp_northing *= 1.01;
666 if ( vgl->mpp_easting > (VIK_VIEWPORT_MIN_ZOOM * 1.05) && vgl->mpp_northing > (VIK_VIEWPORT_MIN_ZOOM * 1.05) )
668 vgl->mpp_easting /= 1.01;
669 vgl->mpp_northing /= 1.01;
672 vik_viewport_set_xmpp ( vvp, vgl->mpp_easting );
673 vik_viewport_set_ympp ( vvp, vgl->mpp_northing );
674 vik_layer_emit_update ( VIK_LAYER(vgl), FALSE );
678 static gboolean georef_layer_move_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
680 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
682 vgl->click_x = event->x;
683 vgl->click_y = event->y;