2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
4 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
5 * Copyright (c) 2014, Rob Norris <rw_norris@hotmail.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #include <glib/gstdio.h>
31 #include <glib/gi18n.h>
38 #include "preferences.h"
39 #include "icons/icons.h"
41 static VikLayerParamData image_default ( void )
43 VikLayerParamData data;
44 data.s = g_strdup ("");
49 VikLayerParam georef_layer_params[] = {
50 { VIK_LAYER_GEOREF, "image", VIK_LAYER_PARAM_STRING, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL },
51 { VIK_LAYER_GEOREF, "corner_easting", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL },
52 { VIK_LAYER_GEOREF, "corner_northing", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL },
53 { VIK_LAYER_GEOREF, "mpp_easting", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL },
54 { VIK_LAYER_GEOREF, "mpp_northing", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL },
55 { VIK_LAYER_GEOREF, "corner_zone", VIK_LAYER_PARAM_UINT, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL },
56 { VIK_LAYER_GEOREF, "corner_letter_as_int", VIK_LAYER_PARAM_UINT, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL },
57 { VIK_LAYER_GEOREF, "alpha", VIK_LAYER_PARAM_UINT, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL },
71 static const gchar* georef_layer_tooltip ( VikGeorefLayer *vgl );
72 static void georef_layer_marshall( VikGeorefLayer *vgl, guint8 **data, gint *len );
73 static VikGeorefLayer *georef_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp );
74 static gboolean georef_layer_set_param ( VikGeorefLayer *vgl, guint16 id, VikLayerParamData data, VikViewport *vp, gboolean is_file_operation );
75 static VikLayerParamData georef_layer_get_param ( VikGeorefLayer *vgl, guint16 id, gboolean is_file_operation );
76 static VikGeorefLayer *georef_layer_new ( VikViewport *vvp );
77 static VikGeorefLayer *georef_layer_create ( VikViewport *vp );
78 static void georef_layer_free ( VikGeorefLayer *vgl );
79 static gboolean georef_layer_properties ( VikGeorefLayer *vgl, gpointer vp );
80 static void georef_layer_draw ( VikGeorefLayer *vgl, VikViewport *vp );
81 static void georef_layer_add_menu_items ( VikGeorefLayer *vgl, GtkMenu *menu, gpointer vlp );
82 static void georef_layer_set_image ( VikGeorefLayer *vgl, const gchar *image );
83 static gboolean georef_layer_dialog ( VikGeorefLayer *vgl, gpointer vp, GtkWindow *w );
84 static void georef_layer_load_image ( VikGeorefLayer *vgl, VikViewport *vp, gboolean from_file );
87 static gpointer georef_layer_move_create ( VikWindow *vw, VikViewport *vvp);
88 static gboolean georef_layer_move_release ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp );
89 static gboolean georef_layer_move_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp );
90 static gpointer georef_layer_zoom_create ( VikWindow *vw, VikViewport *vvp);
91 static gboolean georef_layer_zoom_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp );
93 // See comment in viktrwlayer.c for advice on values used
94 static VikToolInterface georef_tools[] = {
95 { { "GeorefMoveMap", "vik-icon-Georef Move Map", N_("_Georef Move Map"), NULL, N_("Georef Move Map"), 0 },
96 (VikToolConstructorFunc) georef_layer_move_create, NULL, NULL, NULL,
97 (VikToolMouseFunc) georef_layer_move_press, NULL, (VikToolMouseFunc) georef_layer_move_release,
98 (VikToolKeyFunc) NULL,
100 GDK_CURSOR_IS_PIXMAP, &cursor_geomove_pixbuf, NULL },
102 { { "GeorefZoomTool", "vik-icon-Georef Zoom Tool", N_("Georef Z_oom Tool"), NULL, N_("Georef Zoom Tool"), 0 },
103 (VikToolConstructorFunc) georef_layer_zoom_create, NULL, NULL, NULL,
104 (VikToolMouseFunc) georef_layer_zoom_press, NULL, NULL,
105 (VikToolKeyFunc) NULL,
107 GDK_CURSOR_IS_PIXMAP, &cursor_geozoom_pixbuf, NULL },
110 VikLayerInterface vik_georef_layer_interface = {
114 &vikgeoreflayer_pixbuf, /*icon */
117 sizeof(georef_tools) / sizeof(VikToolInterface),
126 (VikLayerFuncCreate) georef_layer_create,
127 (VikLayerFuncRealize) NULL,
128 (VikLayerFuncPostRead) georef_layer_load_image,
129 (VikLayerFuncFree) georef_layer_free,
131 (VikLayerFuncProperties) georef_layer_properties,
132 (VikLayerFuncDraw) georef_layer_draw,
133 (VikLayerFuncChangeCoordMode) NULL,
135 (VikLayerFuncSetMenuItemsSelection) NULL,
136 (VikLayerFuncGetMenuItemsSelection) NULL,
138 (VikLayerFuncAddMenuItems) georef_layer_add_menu_items,
139 (VikLayerFuncSublayerAddMenuItems) NULL,
141 (VikLayerFuncSublayerRenameRequest) NULL,
142 (VikLayerFuncSublayerToggleVisible) NULL,
143 (VikLayerFuncSublayerTooltip) NULL,
144 (VikLayerFuncLayerTooltip) georef_layer_tooltip,
145 (VikLayerFuncLayerSelected) NULL,
147 (VikLayerFuncMarshall) georef_layer_marshall,
148 (VikLayerFuncUnmarshall) georef_layer_unmarshall,
150 (VikLayerFuncSetParam) georef_layer_set_param,
151 (VikLayerFuncGetParam) georef_layer_get_param,
152 (VikLayerFuncChangeParam) NULL,
154 (VikLayerFuncReadFileData) NULL,
155 (VikLayerFuncWriteFileData) NULL,
157 (VikLayerFuncDeleteItem) NULL,
158 (VikLayerFuncCutItem) NULL,
159 (VikLayerFuncCopyItem) NULL,
160 (VikLayerFuncPasteItem) NULL,
161 (VikLayerFuncFreeCopiedItem) NULL,
162 (VikLayerFuncDragDropRequest) NULL,
164 (VikLayerFuncSelectClick) NULL,
165 (VikLayerFuncSelectMove) NULL,
166 (VikLayerFuncSelectRelease) NULL,
167 (VikLayerFuncSelectedViewportMenu) NULL,
174 GtkWidget *ce_spin; // top left
175 GtkWidget *cn_spin; // "
176 GtkWidget *utm_zone_spin;
177 GtkWidget *utm_letter_entry;
179 GtkWidget *lat_tl_spin;
180 GtkWidget *lon_tl_spin;
181 GtkWidget *lat_br_spin;
182 GtkWidget *lon_br_spin;
185 GtkWidget *imageentry;
186 } changeable_widgets;
188 struct _VikGeorefLayer {
194 struct UTM corner; // Top Left
195 gdouble mpp_easting, mpp_northing;
196 struct LatLon ll_br; // Bottom Right
200 guint32 scaled_width, scaled_height;
202 gint click_x, click_y;
203 changeable_widgets cw;
206 static VikLayerParam io_prefs[] = {
207 { VIK_LAYER_NUM_TYPES, VIKING_PREFERENCES_IO_NAMESPACE "georef_auto_read_world_file", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_GROUP_NONE, N_("Auto Read World Files:"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL,
208 N_("Automatically attempt to read associated world file of a new image for a GeoRef layer"), NULL, NULL, NULL}
211 void vik_georef_layer_init (void)
213 VikLayerParamData tmp;
215 a_preferences_register(&io_prefs[0], tmp, VIKING_PREFERENCES_IO_GROUP_KEY);
218 GType vik_georef_layer_get_type ()
220 static GType vgl_type = 0;
224 static const GTypeInfo vgl_info =
226 sizeof (VikGeorefLayerClass),
227 NULL, /* base_init */
228 NULL, /* base_finalize */
229 NULL, /* class init */
230 NULL, /* class_finalize */
231 NULL, /* class_data */
232 sizeof (VikGeorefLayer),
234 NULL /* instance init */
236 vgl_type = g_type_register_static ( VIK_LAYER_TYPE, "VikGeorefLayer", &vgl_info, 0 );
242 static const gchar* georef_layer_tooltip ( VikGeorefLayer *vgl )
247 static void georef_layer_marshall( VikGeorefLayer *vgl, guint8 **data, gint *len )
249 vik_layer_marshall_params ( VIK_LAYER(vgl), data, len );
252 static VikGeorefLayer *georef_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp )
254 VikGeorefLayer *rv = georef_layer_new ( vvp );
255 vik_layer_unmarshall_params ( VIK_LAYER(rv), data, len, vvp );
257 georef_layer_load_image ( rv, vvp, TRUE );
262 static gboolean georef_layer_set_param ( VikGeorefLayer *vgl, guint16 id, VikLayerParamData data, VikViewport *vp, gboolean is_file_operation )
266 case PARAM_IMAGE: georef_layer_set_image ( vgl, data.s ); break;
267 case PARAM_CN: vgl->corner.northing = data.d; break;
268 case PARAM_CE: vgl->corner.easting = data.d; break;
269 case PARAM_MN: vgl->mpp_northing = data.d; break;
270 case PARAM_ME: vgl->mpp_easting = data.d; break;
271 case PARAM_CZ: if ( data.u <= 60 ) vgl->corner.zone = data.u; break;
272 case PARAM_CL: if ( data.u >= 65 || data.u <= 90 ) vgl->corner.letter = data.u; break;
273 case PARAM_AA: if ( data.u <= 255 ) vgl->alpha = data.u; break;
279 static VikLayerParamData georef_layer_get_param ( VikGeorefLayer *vgl, guint16 id, gboolean is_file_operation )
281 VikLayerParamData rv;
285 gboolean set = FALSE;
286 if ( is_file_operation ) {
287 if ( a_vik_get_file_ref_format() == VIK_FILE_REF_FORMAT_RELATIVE ) {
288 gchar *cwd = g_get_current_dir();
290 rv.s = file_GetRelativeFilename ( cwd, vgl->image );
291 if ( !rv.s ) rv.s = "";
297 rv.s = vgl->image ? vgl->image : "";
300 case PARAM_CN: rv.d = vgl->corner.northing; break;
301 case PARAM_CE: rv.d = vgl->corner.easting; break;
302 case PARAM_MN: rv.d = vgl->mpp_northing; break;
303 case PARAM_ME: rv.d = vgl->mpp_easting; break;
304 case PARAM_CZ: rv.u = vgl->corner.zone; break;
305 case PARAM_CL: rv.u = vgl->corner.letter; break;
306 case PARAM_AA: rv.u = vgl->alpha; break;
312 static VikGeorefLayer *georef_layer_new ( VikViewport *vvp )
314 VikGeorefLayer *vgl = VIK_GEOREF_LAYER ( g_object_new ( VIK_GEOREF_LAYER_TYPE, NULL ) );
315 vik_layer_set_type ( VIK_LAYER(vgl), VIK_LAYER_GEOREF );
317 // Since GeoRef layer doesn't use uibuilder
318 // initializing this way won't do anything yet..
319 vik_layer_set_defaults ( VIK_LAYER(vgl), vvp );
321 // Make these defaults based on the current view
322 vgl->mpp_northing = vik_viewport_get_ympp ( vvp );
323 vgl->mpp_easting = vik_viewport_get_xmpp ( vvp );
324 vik_coord_to_utm ( vik_viewport_get_center ( vvp ), &(vgl->corner) );
331 vgl->scaled_width = 0;
332 vgl->scaled_height = 0;
333 vgl->ll_br.lat = 0.0;
334 vgl->ll_br.lon = 0.0;
339 static void georef_layer_draw ( VikGeorefLayer *vgl, VikViewport *vp )
343 gdouble xmpp = vik_viewport_get_xmpp(vp), ympp = vik_viewport_get_ympp(vp);
344 GdkPixbuf *pixbuf = vgl->pixbuf;
345 guint layer_width = vgl->width;
346 guint layer_height = vgl->height;
348 guint width = vik_viewport_get_width(vp), height = vik_viewport_get_height(vp);
350 VikCoord corner_coord;
351 vik_coord_load_from_utm ( &corner_coord, vik_viewport_get_coord_mode(vp), &(vgl->corner) );
352 vik_viewport_coord_to_screen ( vp, &corner_coord, &x, &y );
354 /* mark to scale the pixbuf if it doesn't match our dimensions */
355 gboolean scale = FALSE;
356 if ( xmpp != vgl->mpp_easting || ympp != vgl->mpp_northing )
359 layer_width = round(vgl->width * vgl->mpp_easting / xmpp);
360 layer_height = round(vgl->height * vgl->mpp_northing / ympp);
363 // If image not in viewport bounds - no need to draw it (or bother with any scaling)
364 if ( (x < 0 || x < width) && (y < 0 || y < height) && x+layer_width > 0 && y+layer_height > 0 ) {
368 /* rescale if necessary */
369 if (layer_width == vgl->scaled_width && layer_height == vgl->scaled_height && vgl->scaled != NULL)
370 pixbuf = vgl->scaled;
373 pixbuf = gdk_pixbuf_scale_simple(
380 if (vgl->scaled != NULL)
381 g_object_unref(vgl->scaled);
383 vgl->scaled = pixbuf;
384 vgl->scaled_width = layer_width;
385 vgl->scaled_height = layer_height;
388 vik_viewport_draw_pixbuf ( vp, pixbuf, 0, 0, x, y, layer_width, layer_height ); /* todo: draw only what we need to. */
393 static void georef_layer_free ( VikGeorefLayer *vgl )
395 if ( vgl->image != NULL )
396 g_free ( vgl->image );
397 if ( vgl->scaled != NULL )
398 g_object_unref ( vgl->scaled );
401 static VikGeorefLayer *georef_layer_create ( VikViewport *vp )
403 return georef_layer_new ( vp );
406 static gboolean georef_layer_properties ( VikGeorefLayer *vgl, gpointer vp )
408 return georef_layer_dialog ( vgl, vp, VIK_GTK_WINDOW_FROM_WIDGET(vp) );
411 static void georef_layer_load_image ( VikGeorefLayer *vgl, VikViewport *vp, gboolean from_file )
414 if ( vgl->image == NULL )
418 g_object_unref ( G_OBJECT(vgl->pixbuf) );
421 g_object_unref ( G_OBJECT(vgl->scaled) );
425 vgl->pixbuf = gdk_pixbuf_new_from_file ( vgl->image, &gx );
430 a_dialog_error_msg_extra ( VIK_GTK_WINDOW_FROM_WIDGET(vp), _("Couldn't open image file: %s"), gx->message );
435 vgl->width = gdk_pixbuf_get_width ( vgl->pixbuf );
436 vgl->height = gdk_pixbuf_get_height ( vgl->pixbuf );
438 if ( vgl->pixbuf && vgl->alpha < 255 )
439 vgl->pixbuf = ui_pixbuf_set_alpha ( vgl->pixbuf, vgl->alpha );
441 /* should find length and width here too */
444 static void georef_layer_set_image ( VikGeorefLayer *vgl, const gchar *image )
447 g_free ( vgl->image );
450 g_object_unref ( vgl->scaled );
456 if ( g_strcmp0 (image, "") != 0 )
457 vgl->image = vu_get_canonical_filename ( VIK_LAYER(vgl), image );
459 vgl->image = g_strdup (image);
462 // Only positive values allowed here
463 static void gdouble2spinwidget ( GtkWidget *widget, gdouble val )
465 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(widget), val > 0 ? val : -val );
468 static void set_widget_values ( changeable_widgets *cw, gdouble values[4] )
470 gdouble2spinwidget ( cw->x_spin, values[0] );
471 gdouble2spinwidget ( cw->y_spin, values[1] );
472 gdouble2spinwidget ( cw->ce_spin, values[2] );
473 gdouble2spinwidget ( cw->cn_spin, values[3] );
476 static gboolean world_file_read_line ( FILE *ff, gdouble *value, gboolean use_value )
478 gboolean answer = TRUE; // Success
480 if ( !fgets ( buffer, 1024, ff ) ) {
483 if ( answer && use_value )
484 *value = g_strtod ( buffer, NULL );
490 * http://en.wikipedia.org/wiki/World_file
492 * Note world files do not define the units and nor are the units standardized :(
493 * Currently Viking only supports:
494 * x&y scale as meters per pixel
495 * x&y coords as UTM eastings and northings respectively
497 static gint world_file_read_file ( const gchar* filename, gdouble values[4] )
499 g_debug ("%s - trying world file %s", __FUNCTION__, filename);
501 FILE *f = g_fopen ( filename, "r" );
505 gint answer = 2; // Not enough info read yet
506 // **We do not handle 'skew' values ATM - normally they are a value of 0 anyway to align with the UTM grid
507 if ( world_file_read_line ( f, &values[0], TRUE ) // x scale
508 && world_file_read_line ( f, NULL, FALSE ) // Ignore value in y-skew line**
509 && world_file_read_line ( f, NULL, FALSE ) // Ignore value in x-skew line**
510 && world_file_read_line ( f, &values[1], TRUE ) // y scale
511 && world_file_read_line ( f, &values[2], TRUE ) // x-coordinate of the upper left pixel
512 && world_file_read_line ( f, &values[3], TRUE ) // y-coordinate of the upper left pixel
516 g_debug ("%s - %s - world file read success", __FUNCTION__, filename);
524 static void georef_layer_dialog_load ( changeable_widgets *cw )
526 GtkWidget *file_selector = gtk_file_chooser_dialog_new (_("Choose World file"),
528 GTK_FILE_CHOOSER_ACTION_OPEN,
529 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
530 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
533 if ( gtk_dialog_run ( GTK_DIALOG ( file_selector ) ) == GTK_RESPONSE_ACCEPT )
536 gint answer = world_file_read_file ( gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(file_selector)), values );
538 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(cw->x_spin), _("The World file you requested could not be opened for reading.") );
539 else if ( answer == 2 )
540 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(cw->x_spin), _("Unexpected end of file reading World file.") );
542 // NB answer should == 0 for success
543 set_widget_values ( cw, values );
546 gtk_widget_destroy ( file_selector );
549 static void georef_layer_export_params ( gpointer *pass_along[2] )
551 VikGeorefLayer *vgl = VIK_GEOREF_LAYER(pass_along[0]);
552 GtkWidget *file_selector = gtk_file_chooser_dialog_new (_("Choose World file"),
554 GTK_FILE_CHOOSER_ACTION_SAVE,
555 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
556 GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
558 if ( gtk_dialog_run ( GTK_DIALOG ( file_selector ) ) == GTK_RESPONSE_ACCEPT )
560 FILE *f = g_fopen ( gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(file_selector) ), "w" );
562 gtk_widget_destroy ( file_selector );
565 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]), _("The file you requested could not be opened for writing.") );
570 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 );
576 gtk_widget_destroy ( file_selector );
580 * Auto attempt to read the world file associated with the image used for the georef
581 * Based on simple file name conventions
582 * Only attempted if the preference is on.
584 static void maybe_read_world_file ( VikFileEntry *vfe, gpointer user_data )
586 if ( a_preferences_get (VIKING_PREFERENCES_IO_NAMESPACE "georef_auto_read_world_file")->b ) {
587 const gchar* filename = vik_file_entry_get_filename(VIK_FILE_ENTRY(vfe));
589 if ( filename && user_data ) {
591 changeable_widgets *cw = user_data;
593 gboolean upper = g_ascii_isupper (filename[strlen(filename)-1]);
594 gchar* filew = g_strconcat ( filename, (upper ? "W" : "w") , NULL );
596 if ( world_file_read_file ( filew, values ) == 0 ) {
597 set_widget_values ( cw, values );
600 if ( strlen(filename) > 3 ) {
601 gchar* file0 = g_strndup ( filename, strlen(filename)-2 );
602 gchar* file1 = g_strdup_printf ( "%s%c%c", file0, filename[strlen(filename)-1], (upper ? 'W' : 'w') );
603 if ( world_file_read_file ( file1, values ) == 0 ) {
604 set_widget_values ( cw, values );
615 static struct LatLon get_ll_tl (VikGeorefLayer *vgl)
618 ll_tl.lat = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vgl->cw.lat_tl_spin) );
619 ll_tl.lon = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vgl->cw.lon_tl_spin) );
623 static struct LatLon get_ll_br (VikGeorefLayer *vgl)
626 ll_br.lat = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vgl->cw.lat_br_spin) );
627 ll_br.lon = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vgl->cw.lon_br_spin) );
631 // Align displayed UTM values with displayed Lat/Lon values
632 static void align_utm2ll (VikGeorefLayer *vgl)
634 struct LatLon ll_tl = get_ll_tl (vgl);
637 a_coords_latlon_to_utm ( &ll_tl, &utm );
638 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(vgl->cw.ce_spin), utm.easting );
639 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(vgl->cw.cn_spin), utm.northing );
642 tmp_letter[0] = utm.letter;
643 tmp_letter[1] = '\0';
644 gtk_entry_set_text ( GTK_ENTRY(vgl->cw.utm_letter_entry), tmp_letter );
646 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(vgl->cw.utm_zone_spin), utm.zone );
649 // Align displayed Lat/Lon values with displayed UTM values
650 static void align_ll2utm (VikGeorefLayer *vgl)
653 const gchar *letter = gtk_entry_get_text ( GTK_ENTRY(vgl->cw.utm_letter_entry) );
655 corner.letter = toupper(*letter);
656 corner.zone = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(vgl->cw.utm_zone_spin) );
657 corner.easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vgl->cw.ce_spin) );
658 corner.northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(vgl->cw.cn_spin) );
661 a_coords_utm_to_latlon ( &corner, &ll );
662 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(vgl->cw.lat_tl_spin), ll.lat );
663 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(vgl->cw.lon_tl_spin), ll.lon );
667 * Align coordinates between tabs as the user may have changed the values
668 * Use this before acting on the user input
669 * This is easier then trying to use the 'value-changed' signal for each individual coordinate
670 * especiallly since it tends to end up in an infinite loop continually updating each other.
672 static void align_coords ( VikGeorefLayer *vgl )
674 if (gtk_notebook_get_current_page(GTK_NOTEBOOK(vgl->cw.tabs)) == 0)
675 align_ll2utm ( vgl );
677 align_utm2ll ( vgl );
680 static void switch_tab (GtkNotebook *notebook, gpointer tab, guint tab_num, gpointer user_data)
682 VikGeorefLayer *vgl = user_data;
692 static void check_br_is_good_or_msg_user ( VikGeorefLayer *vgl )
694 // if a 'blank' ll value that's alright
695 if ( vgl->ll_br.lat == 0.0 && vgl->ll_br.lon == 0.0 )
698 struct LatLon ll_tl = get_ll_tl (vgl);
699 if ( ll_tl.lat < vgl->ll_br.lat || ll_tl.lon > vgl->ll_br.lon )
700 a_dialog_warning_msg ( VIK_GTK_WINDOW_FROM_LAYER(vgl), _("Lower right corner values may not be consistent with upper right values") );
706 static void calculate_mpp_from_coords ( GtkWidget *ww, VikGeorefLayer *vgl )
708 const gchar* filename = vik_file_entry_get_filename(VIK_FILE_ENTRY(vgl->cw.imageentry));
713 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file ( filename, &gx );
715 a_dialog_error_msg_extra ( VIK_GTK_WINDOW_FROM_WIDGET(ww), _("Couldn't open image file: %s"), gx->message );
720 guint width = gdk_pixbuf_get_width ( pixbuf );
721 guint height = gdk_pixbuf_get_height ( pixbuf );
723 if ( width == 0 || height == 0 ) {
724 a_dialog_error_msg_extra ( VIK_GTK_WINDOW_FROM_WIDGET(ww), _("Invalid image size: %s"), filename);
727 align_coords ( vgl );
729 struct LatLon ll_tl = get_ll_tl (vgl);
730 struct LatLon ll_br = get_ll_br (vgl);
733 ll_tr.lat = ll_tl.lat;
734 ll_tr.lon = ll_br.lon;
737 ll_bl.lat = ll_br.lat;
738 ll_bl.lon = ll_tl.lon;
740 gdouble diffx = a_coords_latlon_diff ( &ll_tl, &ll_tr );
741 gdouble xmpp = diffx / width;
743 gdouble diffy = a_coords_latlon_diff ( &ll_tl, &ll_bl );
744 gdouble ympp = diffy / height;
746 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(vgl->cw.x_spin), xmpp );
747 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(vgl->cw.y_spin), ympp );
749 check_br_is_good_or_msg_user ( vgl );
752 g_object_unref ( G_OBJECT(pixbuf) );
755 #define VIK_SETTINGS_GEOREF_TAB "georef_coordinate_tab"
757 /* returns TRUE if OK was pressed. */
758 static gboolean georef_layer_dialog ( VikGeorefLayer *vgl, gpointer vp, GtkWindow *w )
760 GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Layer Properties"),
762 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
768 /* Default to reject as user really needs to specify map file first */
769 gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
770 GtkWidget *response_w = NULL;
771 #if GTK_CHECK_VERSION (2, 20, 0)
772 response_w = gtk_dialog_get_widget_for_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
774 GtkWidget *table, *wfp_hbox, *wfp_label, *wfp_button, *ce_label, *cn_label, *xlabel, *ylabel, *imagelabel;
775 changeable_widgets cw;
777 GtkBox *dgbox = GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog)));
778 table = gtk_table_new ( 4, 2, FALSE );
779 gtk_box_pack_start ( dgbox, table, TRUE, TRUE, 0 );
781 wfp_hbox = gtk_hbox_new ( FALSE, 0 );
782 wfp_label = gtk_label_new ( _("World File Parameters:") );
783 wfp_button = gtk_button_new_with_label ( _("Load From File...") );
785 gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_label, TRUE, TRUE, 0 );
786 gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_button, FALSE, FALSE, 3 );
788 ce_label = gtk_label_new ( _("Corner pixel easting:") );
789 cw.ce_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 1500000.0, 1, 5, 0 ), 1, 4 );
790 gtk_widget_set_tooltip_text ( GTK_WIDGET(cw.ce_spin), _("the UTM \"easting\" value of the upper-left corner pixel of the map") );
792 cn_label = gtk_label_new ( _("Corner pixel northing:") );
793 cw.cn_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 9000000.0, 1, 5, 0 ), 1, 4 );
794 gtk_widget_set_tooltip_text ( GTK_WIDGET(cw.cn_spin), _("the UTM \"northing\" value of the upper-left corner pixel of the map") );
796 xlabel = gtk_label_new ( _("X (easting) scale (mpp): "));
797 ylabel = gtk_label_new ( _("Y (northing) scale (mpp): "));
799 cw.x_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
800 gtk_widget_set_tooltip_text ( GTK_WIDGET(cw.x_spin), _("the scale of the map in the X direction (meters per pixel)") );
801 cw.y_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
802 gtk_widget_set_tooltip_text ( GTK_WIDGET(cw.y_spin), _("the scale of the map in the Y direction (meters per pixel)") );
804 imagelabel = gtk_label_new ( _("Map Image:") );
805 cw.imageentry = vik_file_entry_new (GTK_FILE_CHOOSER_ACTION_OPEN, VF_FILTER_IMAGE, maybe_read_world_file, &cw);
807 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cw.ce_spin), vgl->corner.easting );
808 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cw.cn_spin), vgl->corner.northing );
809 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cw.x_spin), vgl->mpp_easting );
810 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cw.y_spin), vgl->mpp_northing );
812 vik_file_entry_set_filename ( VIK_FILE_ENTRY(cw.imageentry), vgl->image );
814 gtk_table_attach_defaults ( GTK_TABLE(table), imagelabel, 0, 1, 0, 1 );
815 gtk_table_attach_defaults ( GTK_TABLE(table), cw.imageentry, 1, 2, 0, 1 );
816 gtk_table_attach_defaults ( GTK_TABLE(table), wfp_hbox, 0, 2, 1, 2 );
817 gtk_table_attach_defaults ( GTK_TABLE(table), xlabel, 0, 1, 2, 3 );
818 gtk_table_attach_defaults ( GTK_TABLE(table), cw.x_spin, 1, 2, 2, 3 );
819 gtk_table_attach_defaults ( GTK_TABLE(table), ylabel, 0, 1, 3, 4 );
820 gtk_table_attach_defaults ( GTK_TABLE(table), cw.y_spin, 1, 2, 3, 4 );
822 cw.tabs = gtk_notebook_new();
823 GtkWidget *table_utm = gtk_table_new ( 3, 2, FALSE );
825 gtk_table_attach_defaults ( GTK_TABLE(table_utm), ce_label, 0, 1, 0, 1 );
826 gtk_table_attach_defaults ( GTK_TABLE(table_utm), cw.ce_spin, 1, 2, 0, 1 );
827 gtk_table_attach_defaults ( GTK_TABLE(table_utm), cn_label, 0, 1, 1, 2 );
828 gtk_table_attach_defaults ( GTK_TABLE(table_utm), cw.cn_spin, 1, 2, 1, 2 );
830 GtkWidget *utm_hbox = gtk_hbox_new ( FALSE, 0 );
831 cw.utm_zone_spin = gtk_spin_button_new ((GtkAdjustment*)gtk_adjustment_new( vgl->corner.zone, 1, 60, 1, 5, 0 ), 1, 0 );
832 gtk_box_pack_start ( GTK_BOX(utm_hbox), gtk_label_new(_("Zone:")), TRUE, TRUE, 0 );
833 gtk_box_pack_start ( GTK_BOX(utm_hbox), cw.utm_zone_spin, TRUE, TRUE, 0 );
834 gtk_box_pack_start ( GTK_BOX(utm_hbox), gtk_label_new(_("Letter:")), TRUE, TRUE, 0 );
835 cw.utm_letter_entry = gtk_entry_new ();
836 gtk_entry_set_max_length ( GTK_ENTRY(cw.utm_letter_entry), 1 );
837 gtk_entry_set_width_chars ( GTK_ENTRY(cw.utm_letter_entry), 2 );
839 tmp_letter[0] = vgl->corner.letter;
840 tmp_letter[1] = '\0';
841 gtk_entry_set_text ( GTK_ENTRY(cw.utm_letter_entry), tmp_letter );
842 gtk_box_pack_start ( GTK_BOX(utm_hbox), cw.utm_letter_entry, TRUE, TRUE, 0 );
844 gtk_table_attach_defaults ( GTK_TABLE(table_utm), utm_hbox, 0, 2, 2, 3 );
847 GtkWidget *table_ll = gtk_table_new ( 5, 2, FALSE );
849 GtkWidget *lat_tl_label = gtk_label_new ( _("Upper left latitude:") );
850 cw.lat_tl_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new (0.0,-90,90.0,0.05,0.1,0), 0.1, 6 );
851 GtkWidget *lon_tl_label = gtk_label_new ( _("Upper left longitude:") );
852 cw.lon_tl_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new (0.0,-180,180.0,0.05,0.1,0), 0.1, 6 );
853 GtkWidget *lat_br_label = gtk_label_new ( _("Lower right latitude:") );
854 cw.lat_br_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new (0.0,-90,90.0,0.05,0.1,0), 0.1, 6 );
855 GtkWidget *lon_br_label = gtk_label_new ( _("Lower right longitude:") );
856 cw.lon_br_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new (0.0,-180.0,180.0,0.05,0.1,0), 0.1, 6 );
858 gtk_table_attach_defaults ( GTK_TABLE(table_ll), lat_tl_label, 0, 1, 0, 1 );
859 gtk_table_attach_defaults ( GTK_TABLE(table_ll), cw.lat_tl_spin, 1, 2, 0, 1 );
860 gtk_table_attach_defaults ( GTK_TABLE(table_ll), lon_tl_label, 0, 1, 1, 2 );
861 gtk_table_attach_defaults ( GTK_TABLE(table_ll), cw.lon_tl_spin, 1, 2, 1, 2 );
862 gtk_table_attach_defaults ( GTK_TABLE(table_ll), lat_br_label, 0, 1, 2, 3 );
863 gtk_table_attach_defaults ( GTK_TABLE(table_ll), cw.lat_br_spin, 1, 2, 2, 3 );
864 gtk_table_attach_defaults ( GTK_TABLE(table_ll), lon_br_label, 0, 1, 3, 4 );
865 gtk_table_attach_defaults ( GTK_TABLE(table_ll), cw.lon_br_spin, 1, 2, 3, 4 );
867 GtkWidget *calc_mpp_button = gtk_button_new_with_label ( _("Calculate MPP values from coordinates") );
868 gtk_widget_set_tooltip_text ( calc_mpp_button, _("Enter all corner coordinates before calculating the MPP values from the image size") );
869 gtk_table_attach_defaults ( GTK_TABLE(table_ll), calc_mpp_button, 0, 2, 4, 5 );
872 vik_coord_load_from_utm (&vc, VIK_COORD_LATLON, &(vgl->corner));
873 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cw.lat_tl_spin), vc.north_south );
874 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cw.lon_tl_spin), vc.east_west );
875 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cw.lat_br_spin), vgl->ll_br.lat );
876 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cw.lon_br_spin), vgl->ll_br.lon );
878 gtk_notebook_append_page(GTK_NOTEBOOK(cw.tabs), GTK_WIDGET(table_utm), gtk_label_new(_("UTM")));
879 gtk_notebook_append_page(GTK_NOTEBOOK(cw.tabs), GTK_WIDGET(table_ll), gtk_label_new(_("Latitude/Longitude")));
880 gtk_box_pack_start ( dgbox, cw.tabs, TRUE, TRUE, 0 );
882 GtkWidget *alpha_hbox = gtk_hbox_new ( FALSE, 0 );
883 // GTK3 => GtkWidget *alpha_scale = gtk_scale_new_with_range ( GTK_ORIENTATION_HORIZONTAL, 0, 255, 1 );
884 GtkWidget *alpha_scale = gtk_hscale_new_with_range ( 0, 255, 1 );
885 gtk_scale_set_digits ( GTK_SCALE(alpha_scale), 0 );
886 gtk_range_set_value ( GTK_RANGE(alpha_scale), vgl->alpha );
887 gtk_box_pack_start ( GTK_BOX(alpha_hbox), gtk_label_new(_("Alpha:")), TRUE, TRUE, 0 );
888 gtk_box_pack_start ( GTK_BOX(alpha_hbox), alpha_scale, TRUE, TRUE, 0 );
889 gtk_box_pack_start ( dgbox, alpha_hbox, TRUE, TRUE, 0 );
893 g_signal_connect ( G_OBJECT(vgl->cw.tabs), "switch-page", G_CALLBACK(switch_tab), vgl );
894 g_signal_connect ( G_OBJECT(calc_mpp_button), "clicked", G_CALLBACK(calculate_mpp_from_coords), vgl );
896 g_signal_connect_swapped ( G_OBJECT(wfp_button), "clicked", G_CALLBACK(georef_layer_dialog_load), &cw );
899 gtk_widget_grab_focus ( response_w );
901 gtk_widget_show_all ( dialog );
903 // Remember setting the notebook page must be done after the widget is visible.
905 if ( a_settings_get_integer ( VIK_SETTINGS_GEOREF_TAB, &page_num ) )
906 if ( page_num < 0 || page_num > 1 )
908 gtk_notebook_set_current_page ( GTK_NOTEBOOK(cw.tabs), page_num );
910 if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
912 align_coords ( vgl );
914 vgl->corner.easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(cw.ce_spin) );
915 vgl->corner.northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(cw.cn_spin) );
916 vgl->corner.zone = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON(cw.utm_zone_spin) );
917 const gchar *letter = gtk_entry_get_text ( GTK_ENTRY(cw.utm_letter_entry) );
919 vgl->corner.letter = toupper(*letter);
920 vgl->mpp_easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(cw.x_spin) );
921 vgl->mpp_northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(cw.y_spin) );
922 vgl->ll_br = get_ll_br (vgl);
923 check_br_is_good_or_msg_user ( vgl );
924 if ( g_strcmp0 (vgl->image, vik_file_entry_get_filename(VIK_FILE_ENTRY(cw.imageentry)) ) != 0 )
926 georef_layer_set_image ( vgl, vik_file_entry_get_filename(VIK_FILE_ENTRY(cw.imageentry)) );
927 georef_layer_load_image ( vgl, VIK_VIEWPORT(vp), FALSE );
930 vgl->alpha = (guint8) gtk_range_get_value ( GTK_RANGE(alpha_scale) );
931 if ( vgl->pixbuf && vgl->alpha < 255 )
932 vgl->pixbuf = ui_pixbuf_set_alpha ( vgl->pixbuf, vgl->alpha );
933 if ( vgl->scaled && vgl->alpha < 255 )
934 vgl->scaled = ui_pixbuf_set_alpha ( vgl->scaled, vgl->alpha );
936 a_settings_set_integer ( VIK_SETTINGS_GEOREF_TAB, gtk_notebook_get_current_page(GTK_NOTEBOOK(cw.tabs)) );
938 gtk_widget_destroy ( GTK_WIDGET(dialog) );
941 gtk_widget_destroy ( GTK_WIDGET(dialog) );
945 static void georef_layer_zoom_to_fit ( gpointer vgl_vlp[2] )
947 vik_viewport_set_xmpp ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1])), VIK_GEOREF_LAYER(vgl_vlp[0])->mpp_easting );
948 vik_viewport_set_ympp ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1])), VIK_GEOREF_LAYER(vgl_vlp[0])->mpp_northing );
949 vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vgl_vlp[1]) );
952 static void georef_layer_goto_center ( gpointer vgl_vlp[2] )
954 VikGeorefLayer *vgl = VIK_GEOREF_LAYER ( vgl_vlp[0] );
955 VikViewport *vp = vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp[1]));
959 vik_coord_to_utm ( vik_viewport_get_center ( vp ), &utm );
961 utm.easting = vgl->corner.easting + (vgl->width * vgl->mpp_easting / 2); /* only an approximation */
962 utm.northing = vgl->corner.northing - (vgl->height * vgl->mpp_northing / 2);
964 vik_coord_load_from_utm ( &coord, vik_viewport_get_coord_mode ( vp ), &utm );
965 vik_viewport_set_center_coord ( vp, &coord, TRUE );
967 vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vgl_vlp[1]) );
970 static void georef_layer_add_menu_items ( VikGeorefLayer *vgl, GtkMenu *menu, gpointer vlp )
972 static gpointer pass_along[2];
977 item = gtk_menu_item_new();
978 gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
979 gtk_widget_show ( item );
982 item = gtk_image_menu_item_new_with_mnemonic ( _("_Zoom to Fit Map") );
983 gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_FIT, GTK_ICON_SIZE_MENU) );
984 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_zoom_to_fit), pass_along );
985 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
986 gtk_widget_show ( item );
988 item = gtk_image_menu_item_new_with_mnemonic ( _("_Goto Map Center") );
989 gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU) );
990 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_goto_center), pass_along );
991 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
992 gtk_widget_show ( item );
994 item = gtk_image_menu_item_new_with_mnemonic ( _("_Export to World File") );
995 gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_HARDDISK, GTK_ICON_SIZE_MENU) );
996 g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(georef_layer_export_params), pass_along );
997 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
998 gtk_widget_show ( item );
1002 static gpointer georef_layer_move_create ( VikWindow *vw, VikViewport *vvp)
1007 static gboolean georef_layer_move_release ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
1009 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
1012 if ( vgl->click_x != -1 )
1014 vgl->corner.easting += (event->x - vgl->click_x) * vik_viewport_get_xmpp (vvp);
1015 vgl->corner.northing -= (event->y - vgl->click_y) * vik_viewport_get_ympp (vvp);
1016 vik_layer_emit_update ( VIK_LAYER(vgl) );
1019 return FALSE; /* I didn't move anything on this layer! */
1022 static gpointer georef_layer_zoom_create ( VikWindow *vw, VikViewport *vvp)
1027 static gboolean georef_layer_zoom_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
1029 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
1031 if ( event->button == 1 )
1033 if ( vgl->mpp_easting < (VIK_VIEWPORT_MAX_ZOOM / 1.05) && vgl->mpp_northing < (VIK_VIEWPORT_MAX_ZOOM / 1.05) )
1035 vgl->mpp_easting *= 1.01;
1036 vgl->mpp_northing *= 1.01;
1041 if ( vgl->mpp_easting > (VIK_VIEWPORT_MIN_ZOOM * 1.05) && vgl->mpp_northing > (VIK_VIEWPORT_MIN_ZOOM * 1.05) )
1043 vgl->mpp_easting /= 1.01;
1044 vgl->mpp_northing /= 1.01;
1047 vik_viewport_set_xmpp ( vvp, vgl->mpp_easting );
1048 vik_viewport_set_ympp ( vvp, vgl->mpp_northing );
1049 vik_layer_emit_update ( VIK_LAYER(vgl) );
1053 static gboolean georef_layer_move_press ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
1055 if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
1057 vgl->click_x = event->x;
1058 vgl->click_y = event->y;