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>
32 #include "icons/icons.h"
34 VikLayerParam georef_layer_params
[] = {
35 { "image", VIK_LAYER_PARAM_STRING
, VIK_LAYER_NOT_IN_PROPERTIES
},
36 { "corner_easting", VIK_LAYER_PARAM_DOUBLE
, VIK_LAYER_NOT_IN_PROPERTIES
},
37 { "corner_northing", VIK_LAYER_PARAM_DOUBLE
, VIK_LAYER_NOT_IN_PROPERTIES
},
38 { "mpp_easting", VIK_LAYER_PARAM_DOUBLE
, VIK_LAYER_NOT_IN_PROPERTIES
},
39 { "mpp_northing", VIK_LAYER_PARAM_DOUBLE
, VIK_LAYER_NOT_IN_PROPERTIES
},
42 enum { PARAM_IMAGE
= 0, PARAM_CE
, PARAM_CN
, PARAM_ME
, PARAM_MN
, NUM_PARAMS
};
44 static void georef_layer_marshall( VikGeorefLayer
*vgl
, guint8
**data
, gint
*len
);
45 static VikGeorefLayer
*georef_layer_unmarshall( guint8
*data
, gint len
, VikViewport
*vvp
);
46 static gboolean
georef_layer_set_param ( VikGeorefLayer
*vgl
, guint16 id
, VikLayerParamData data
, VikViewport
*vp
);
47 static VikLayerParamData
georef_layer_get_param ( VikGeorefLayer
*vgl
, guint16 id
);
48 VikGeorefLayer
*georef_layer_new ( );
49 VikGeorefLayer
*georef_layer_create ( VikViewport
*vp
);
50 static void georef_layer_free ( VikGeorefLayer
*vgl
);
51 gboolean
georef_layer_properties ( VikGeorefLayer
*vgl
, gpointer vp
);
52 static void georef_layer_draw ( VikGeorefLayer
*vgl
, gpointer data
);
53 static void georef_layer_add_menu_items ( VikGeorefLayer
*vgl
, GtkMenu
*menu
, gpointer vlp
);
54 static void georef_layer_set_image ( VikGeorefLayer
*vgl
, const gchar
*image
);
55 static gboolean
georef_layer_dialog ( VikGeorefLayer
**vgl
, gpointer vp
, GtkWindow
*w
);
56 static void georef_layer_load_image ( VikGeorefLayer
*vgl
);
59 static gpointer
georef_layer_move_create ( VikWindow
*vw
, VikViewport
*vvp
);
60 static gboolean
georef_layer_move_release ( VikGeorefLayer
*vgl
, GdkEventButton
*event
, VikViewport
*vvp
);
61 static gboolean
georef_layer_move_press ( VikGeorefLayer
*vgl
, GdkEventButton
*event
, VikViewport
*vvp
);
62 static gpointer
georef_layer_zoom_create ( VikWindow
*vw
, VikViewport
*vvp
);
63 static gboolean
georef_layer_zoom_press ( VikGeorefLayer
*vgl
, GdkEventButton
*event
, VikViewport
*vvp
);
65 static VikToolInterface georef_tools
[] = {
66 { N_("Georef Move Map"), (VikToolConstructorFunc
) georef_layer_move_create
, NULL
, NULL
, NULL
,
67 (VikToolMouseFunc
) georef_layer_move_press
, NULL
, (VikToolMouseFunc
) georef_layer_move_release
,
68 (VikToolKeyFunc
) NULL
, GDK_CURSOR_IS_PIXMAP
, &cursor_geomove_pixbuf
},
70 { N_("Georef Zoom Tool"), (VikToolConstructorFunc
) georef_layer_zoom_create
, NULL
, NULL
, NULL
,
71 (VikToolMouseFunc
) georef_layer_zoom_press
, NULL
, NULL
,
72 (VikToolKeyFunc
) NULL
, GDK_CURSOR_IS_PIXMAP
, &cursor_geozoom_pixbuf
},
75 VikLayerInterface vik_georef_layer_interface
= {
77 &vikgeoreflayer_pixbuf
, /*icon */
80 sizeof(georef_tools
) / sizeof(VikToolInterface
),
89 (VikLayerFuncCreate
) georef_layer_create
,
90 (VikLayerFuncRealize
) NULL
,
91 (VikLayerFuncPostRead
) georef_layer_load_image
,
92 (VikLayerFuncFree
) georef_layer_free
,
94 (VikLayerFuncProperties
) georef_layer_properties
,
95 (VikLayerFuncDraw
) georef_layer_draw
,
96 (VikLayerFuncChangeCoordMode
) NULL
,
98 (VikLayerFuncSetMenuItemsSelection
) NULL
,
99 (VikLayerFuncGetMenuItemsSelection
) NULL
,
101 (VikLayerFuncAddMenuItems
) georef_layer_add_menu_items
,
102 (VikLayerFuncSublayerAddMenuItems
) NULL
,
104 (VikLayerFuncSublayerRenameRequest
) NULL
,
105 (VikLayerFuncSublayerToggleVisible
) NULL
,
107 (VikLayerFuncMarshall
) georef_layer_marshall
,
108 (VikLayerFuncUnmarshall
) georef_layer_unmarshall
,
110 (VikLayerFuncSetParam
) georef_layer_set_param
,
111 (VikLayerFuncGetParam
) georef_layer_get_param
,
113 (VikLayerFuncReadFileData
) NULL
,
114 (VikLayerFuncWriteFileData
) NULL
,
116 (VikLayerFuncDeleteItem
) NULL
,
117 (VikLayerFuncCopyItem
) NULL
,
118 (VikLayerFuncPasteItem
) NULL
,
119 (VikLayerFuncFreeCopiedItem
) NULL
,
120 (VikLayerFuncDragDropRequest
) NULL
,
123 struct _VikGeorefLayer
{
128 gdouble mpp_easting
, mpp_northing
;
131 gint click_x
, click_y
;
136 GType
vik_georef_layer_get_type ()
138 static GType vgl_type
= 0;
142 static const GTypeInfo vgl_info
=
144 sizeof (VikGeorefLayerClass
),
145 NULL
, /* base_init */
146 NULL
, /* base_finalize */
147 NULL
, /* class init */
148 NULL
, /* class_finalize */
149 NULL
, /* class_data */
150 sizeof (VikGeorefLayer
),
152 NULL
/* instance init */
154 vgl_type
= g_type_register_static ( VIK_LAYER_TYPE
, "VikGeorefLayer", &vgl_info
, 0 );
160 static void georef_layer_marshall( VikGeorefLayer
*vgl
, guint8
**data
, gint
*len
)
162 vik_layer_marshall_params ( VIK_LAYER(vgl
), data
, len
);
165 static VikGeorefLayer
*georef_layer_unmarshall( guint8
*data
, gint len
, VikViewport
*vvp
)
167 VikGeorefLayer
*rv
= georef_layer_new ( vvp
);
168 vik_layer_unmarshall_params ( VIK_LAYER(rv
), data
, len
, vvp
);
170 georef_layer_load_image ( rv
);
175 static gboolean
georef_layer_set_param ( VikGeorefLayer
*vgl
, guint16 id
, VikLayerParamData data
, VikViewport
*vp
)
179 case PARAM_IMAGE
: georef_layer_set_image ( vgl
, data
.s
); break;
180 case PARAM_CN
: vgl
->corner
.northing
= data
.d
; break;
181 case PARAM_CE
: vgl
->corner
.easting
= data
.d
; break;
182 case PARAM_MN
: vgl
->mpp_northing
= data
.d
; break;
183 case PARAM_ME
: vgl
->mpp_easting
= data
.d
; break;
188 static VikLayerParamData
georef_layer_get_param ( VikGeorefLayer
*vgl
, guint16 id
)
190 VikLayerParamData rv
;
193 case PARAM_IMAGE
: rv
.s
= vgl
->image
? vgl
->image
: ""; break;
194 case PARAM_CN
: rv
.d
= vgl
->corner
.northing
; break;
195 case PARAM_CE
: rv
.d
= vgl
->corner
.easting
; break;
196 case PARAM_MN
: rv
.d
= vgl
->mpp_northing
; break;
197 case PARAM_ME
: rv
.d
= vgl
->mpp_easting
; break;
202 VikGeorefLayer
*georef_layer_new ( )
204 VikGeorefLayer
*vgl
= VIK_GEOREF_LAYER ( g_object_new ( VIK_GEOREF_LAYER_TYPE
, NULL
) );
205 vik_layer_init ( VIK_LAYER(vgl
), VIK_LAYER_GEOREF
);
214 static void georef_layer_draw ( VikGeorefLayer
*vgl
, gpointer data
)
219 VikViewport
*vp
= VIK_VIEWPORT(data
);
220 struct UTM utm_middle
;
221 gdouble xmpp
= vik_viewport_get_xmpp(vp
), ympp
= vik_viewport_get_ympp(vp
);
222 vik_coord_to_utm ( vik_viewport_get_center ( vp
), &utm_middle
);
224 if ( xmpp
== vgl
->mpp_easting
&& ympp
== vgl
->mpp_northing
)
226 guint width
= vik_viewport_get_width(vp
), height
= vik_viewport_get_height(vp
);
228 vgl
->corner
.zone
= utm_middle
.zone
;
229 vgl
->corner
.letter
= utm_middle
.letter
;
230 VikCoord corner_coord
;
231 vik_coord_load_from_utm ( &corner_coord
, vik_viewport_get_coord_mode(vp
), &(vgl
->corner
) );
232 vik_viewport_coord_to_screen ( vp
, &corner_coord
, &x
, &y
);
233 if ( (x
< 0 || x
< width
) && (y
< 0 || y
< height
) && x
+vgl
->width
> 0 && y
+vgl
->height
> 0 )
234 vik_viewport_draw_pixbuf ( vp
, vgl
->pixbuf
, 0, 0, x
, y
, vgl
->width
, vgl
->height
); /* todo: draw only what we need to. */
239 static void georef_layer_free ( VikGeorefLayer
*vgl
)
241 if ( vgl
->image
!= NULL
)
242 g_free ( vgl
->image
);
245 VikGeorefLayer
*georef_layer_create ( VikViewport
*vp
)
247 return georef_layer_new ();
250 gboolean
georef_layer_properties ( VikGeorefLayer
*vgl
, gpointer vp
)
252 return georef_layer_dialog ( &vgl
, vp
, VIK_GTK_WINDOW_FROM_WIDGET(vp
) );
255 static void georef_layer_load_image ( VikGeorefLayer
*vgl
)
258 if ( vgl
->image
== NULL
)
262 g_object_unref ( G_OBJECT(vgl
->pixbuf
) );
264 vgl
->pixbuf
= gdk_pixbuf_new_from_file ( vgl
->image
, &gx
);
268 g_warning ( _("Couldn't open image file: %s"), gx
->message
);
273 vgl
->width
= gdk_pixbuf_get_width ( vgl
->pixbuf
);
274 vgl
->height
= gdk_pixbuf_get_height ( vgl
->pixbuf
);
277 /* should find length and width here too */
280 static void georef_layer_set_image ( VikGeorefLayer
*vgl
, const gchar
*image
)
283 g_free ( vgl
->image
);
286 vgl
->image
= g_strdup ( image
);
289 static gboolean
world_file_read_line ( gchar
*buffer
, gint size
, FILE *f
, GtkWidget
*widget
, gboolean use_value
)
291 if (!fgets ( buffer
, 1024, f
))
293 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(widget
), _("Unexpected end of file reading World file.") );
301 gdouble val
= g_strtod ( buffer
, NULL
);
302 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(widget
), val
> 0 ? val
: -val
);
307 static void georef_layer_dialog_load ( GtkWidget
*pass_along
[4] )
309 GtkWidget
*file_selector
= gtk_file_chooser_dialog_new (_("Choose World file"),
311 GTK_FILE_CHOOSER_ACTION_OPEN
,
312 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
313 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
316 if ( gtk_dialog_run ( GTK_DIALOG ( file_selector
) ) == GTK_RESPONSE_ACCEPT
)
318 FILE *f
= g_fopen ( gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(file_selector
) ), "r" );
319 gtk_widget_destroy ( file_selector
);
322 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along
[0]), _("The World file you requested could not be opened for reading.") );
327 gchar
*buffer
= g_malloc ( 1024 * sizeof(gchar
) );
328 if ( world_file_read_line ( buffer
, 1024, f
, pass_along
[0], TRUE
) && world_file_read_line ( buffer
, 1024, f
, pass_along
[1], TRUE
)
329 && world_file_read_line ( buffer
, 1024, f
, pass_along
[0], FALSE
) && world_file_read_line ( buffer
, 1024, f
, pass_along
[0], FALSE
)
330 && world_file_read_line ( buffer
, 1024, f
, pass_along
[2], TRUE
) && world_file_read_line ( buffer
, 1024, f
, pass_along
[3], TRUE
) )
339 gtk_widget_destroy ( file_selector
);
342 file selection dialog
343 file opener for reading, if NULL, send error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along[0]) )
344 does that catch directories too?
345 read lines -- if not enough lines, give error.
346 if anything outside, give error. define range with #define CONSTANTS
347 put 'em in thar widgets, and that's it.
351 static void georef_layer_export_params ( gpointer
*pass_along
[2] )
353 VikGeorefLayer
*vgl
= VIK_GEOREF_LAYER(pass_along
[0]);
354 GtkWidget
*file_selector
= gtk_file_chooser_dialog_new (_("Choose World file"),
356 GTK_FILE_CHOOSER_ACTION_SAVE
,
357 GTK_STOCK_CANCEL
, GTK_RESPONSE_CANCEL
,
358 GTK_STOCK_OPEN
, GTK_RESPONSE_ACCEPT
,
360 if ( gtk_dialog_run ( GTK_DIALOG ( file_selector
) ) == GTK_RESPONSE_ACCEPT
)
362 FILE *f
= g_fopen ( gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER(file_selector
) ), "w" );
364 gtk_widget_destroy ( file_selector
);
367 a_dialog_error_msg ( VIK_GTK_WINDOW_FROM_WIDGET(pass_along
[0]), _("The file you requested could not be opened for writing.") );
372 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
);
378 gtk_widget_destroy ( file_selector
);
381 /* returns TRUE if OK was pressed. */
382 static gboolean
georef_layer_dialog ( VikGeorefLayer
**vgl
, gpointer vp
, GtkWindow
*w
)
384 GtkWidget
*dialog
= gtk_dialog_new_with_buttons (_("Layer Properties"),
386 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
392 GtkWidget
*table
, *wfp_hbox
, *wfp_label
, *wfp_button
, *ce_label
, *ce_spin
, *cn_label
, *cn_spin
, *xlabel
, *xspin
, *ylabel
, *yspin
, *imagelabel
, *imageentry
;
394 GtkWidget
*pass_along
[4];
396 table
= gtk_table_new ( 6, 2, FALSE
);
397 gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog
)->vbox
), table
, TRUE
, TRUE
, 0 );
399 wfp_hbox
= gtk_hbox_new ( FALSE
, 0 );
400 wfp_label
= gtk_label_new ( _("World File Parameters:") );
401 wfp_button
= gtk_button_new_with_label ( _("Load From File...") );
403 gtk_box_pack_start ( GTK_BOX(wfp_hbox
), wfp_label
, TRUE
, TRUE
, 0 );
404 gtk_box_pack_start ( GTK_BOX(wfp_hbox
), wfp_button
, FALSE
, FALSE
, 3 );
406 ce_label
= gtk_label_new ( _("Corner pixel easting:") );
407 ce_spin
= gtk_spin_button_new ( (GtkAdjustment
*) gtk_adjustment_new ( 4, 0.0, 1500000.0, 1, 5, 5 ), 1, 4 );
409 cn_label
= gtk_label_new ( _("Corner pixel northing:") );
410 cn_spin
= gtk_spin_button_new ( (GtkAdjustment
*) gtk_adjustment_new ( 4, 0.0, 9000000.0, 1, 5, 5 ), 1, 4 );
412 xlabel
= gtk_label_new ( _("X (easting) scale (mpp): "));
413 ylabel
= gtk_label_new ( _("Y (northing) scale (mpp): "));
415 xspin
= gtk_spin_button_new ( (GtkAdjustment
*) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM
, VIK_VIEWPORT_MAX_ZOOM
, 1, 5, 5 ), 1, 8 );
416 yspin
= gtk_spin_button_new ( (GtkAdjustment
*) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM
, VIK_VIEWPORT_MAX_ZOOM
, 1, 5, 5 ), 1, 8 );
418 imagelabel
= gtk_label_new ( _("Map Image:") );
419 imageentry
= vik_file_entry_new ();
423 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin
), (*vgl
)->corner
.easting
);
424 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin
), (*vgl
)->corner
.northing
);
425 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin
), (*vgl
)->mpp_easting
);
426 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin
), (*vgl
)->mpp_northing
);
428 vik_file_entry_set_filename ( VIK_FILE_ENTRY(imageentry
), (*vgl
)->image
);
432 VikCoord corner_coord
;
434 vik_viewport_screen_to_coord ( VIK_VIEWPORT(vp
), 0, 0, &corner_coord
);
435 vik_coord_to_utm ( &corner_coord
, &utm
);
436 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin
), utm
.easting
);
437 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin
), utm
.northing
);
438 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin
), vik_viewport_get_xmpp ( VIK_VIEWPORT(vp
) ) );
439 gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin
), vik_viewport_get_ympp ( VIK_VIEWPORT(vp
) ) );
442 gtk_table_attach_defaults ( GTK_TABLE(table
), imagelabel
, 0, 1, 0, 1 );
443 gtk_table_attach_defaults ( GTK_TABLE(table
), imageentry
, 1, 2, 0, 1 );
444 gtk_table_attach_defaults ( GTK_TABLE(table
), wfp_hbox
, 0, 2, 1, 2 );
445 gtk_table_attach_defaults ( GTK_TABLE(table
), xlabel
, 0, 1, 2, 3 );
446 gtk_table_attach_defaults ( GTK_TABLE(table
), xspin
, 1, 2, 2, 3 );
447 gtk_table_attach_defaults ( GTK_TABLE(table
), ylabel
, 0, 1, 3, 4 );
448 gtk_table_attach_defaults ( GTK_TABLE(table
), yspin
, 1, 2, 3, 4 );
449 gtk_table_attach_defaults ( GTK_TABLE(table
), ce_label
, 0, 1, 4, 5 );
450 gtk_table_attach_defaults ( GTK_TABLE(table
), ce_spin
, 1, 2, 4, 5 );
451 gtk_table_attach_defaults ( GTK_TABLE(table
), cn_label
, 0, 1, 5, 6 );
452 gtk_table_attach_defaults ( GTK_TABLE(table
), cn_spin
, 1, 2, 5, 6 );
454 pass_along
[0] = xspin
;
455 pass_along
[1] = yspin
;
456 pass_along
[2] = ce_spin
;
457 pass_along
[3] = cn_spin
;
458 g_signal_connect_swapped ( G_OBJECT(wfp_button
), "clicked", G_CALLBACK(georef_layer_dialog_load
), pass_along
);
460 gtk_widget_show_all ( table
);
462 if ( gtk_dialog_run ( GTK_DIALOG(dialog
) ) == GTK_RESPONSE_ACCEPT
)
466 *vgl
= georef_layer_new ();
467 vik_layer_rename ( VIK_LAYER(*vgl
), vik_georef_layer_interface
.name
);
469 (*vgl
)->corner
.easting
= gtk_spin_button_get_value ( GTK_SPIN_BUTTON(ce_spin
) );
470 (*vgl
)->corner
.northing
= gtk_spin_button_get_value ( GTK_SPIN_BUTTON(cn_spin
) );
471 (*vgl
)->mpp_easting
= gtk_spin_button_get_value ( GTK_SPIN_BUTTON(xspin
) );
472 (*vgl
)->mpp_northing
= gtk_spin_button_get_value ( GTK_SPIN_BUTTON(yspin
) );
473 if ( (!(*vgl
)->image
) || strcmp( (*vgl
)->image
, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry
)) ) != 0 )
475 georef_layer_set_image ( *vgl
, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry
)) );
476 georef_layer_load_image ( *vgl
);
479 gtk_widget_destroy ( GTK_WIDGET(dialog
) );
482 gtk_widget_destroy ( GTK_WIDGET(dialog
) );
486 static void georef_layer_zoom_to_fit ( gpointer vgl_vlp
[2] )
488 vik_viewport_set_xmpp ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp
[1])), VIK_GEOREF_LAYER(vgl_vlp
[0])->mpp_easting
);
489 vik_viewport_set_ympp ( vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp
[1])), VIK_GEOREF_LAYER(vgl_vlp
[0])->mpp_northing
);
490 vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vgl_vlp
[1]) );
493 static void georef_layer_goto_center ( gpointer vgl_vlp
[2] )
495 VikGeorefLayer
*vgl
= VIK_GEOREF_LAYER ( vgl_vlp
[0] );
496 VikViewport
*vp
= vik_layers_panel_get_viewport(VIK_LAYERS_PANEL(vgl_vlp
[1]));
500 vik_coord_to_utm ( vik_viewport_get_center ( vp
), &utm
);
502 utm
.easting
= vgl
->corner
.easting
+ (vgl
->width
* vgl
->mpp_easting
/ 2); /* only an approximation */
503 utm
.northing
= vgl
->corner
.northing
- (vgl
->height
* vgl
->mpp_northing
/ 2);
505 vik_coord_load_from_utm ( &coord
, vik_viewport_get_coord_mode ( vp
), &utm
);
506 vik_viewport_set_center_coord ( vp
, &coord
);
508 vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(vgl_vlp
[1]) );
511 static void georef_layer_add_menu_items ( VikGeorefLayer
*vgl
, GtkMenu
*menu
, gpointer vlp
)
513 static gpointer pass_along
[2];
518 item
= gtk_menu_item_new();
519 gtk_menu_shell_append ( GTK_MENU_SHELL(menu
), item
);
520 gtk_widget_show ( item
);
522 item
= gtk_menu_item_new_with_label ( _("Zoom to Fit Map") );
523 g_signal_connect_swapped ( G_OBJECT(item
), "activate", G_CALLBACK(georef_layer_zoom_to_fit
), pass_along
);
524 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
525 gtk_widget_show ( item
);
527 item
= gtk_menu_item_new_with_label ( _("Goto Map Center") );
528 g_signal_connect_swapped ( G_OBJECT(item
), "activate", G_CALLBACK(georef_layer_goto_center
), pass_along
);
529 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
530 gtk_widget_show ( item
);
532 item
= gtk_menu_item_new_with_label ( _("Export to World File") );
533 g_signal_connect_swapped ( G_OBJECT(item
), "activate", G_CALLBACK(georef_layer_export_params
), pass_along
);
534 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
535 gtk_widget_show ( item
);
539 static gpointer
georef_layer_move_create ( VikWindow
*vw
, VikViewport
*vvp
)
544 static gboolean
georef_layer_move_release ( VikGeorefLayer
*vgl
, GdkEventButton
*event
, VikViewport
*vvp
)
546 if (!vgl
|| vgl
->vl
.type
!= VIK_LAYER_GEOREF
)
549 if ( vgl
->click_x
!= -1 )
551 vgl
->corner
.easting
+= (event
->x
- vgl
->click_x
) * vik_viewport_get_xmpp (vvp
);
552 vgl
->corner
.northing
-= (event
->y
- vgl
->click_y
) * vik_viewport_get_ympp (vvp
);
553 vik_layer_emit_update ( VIK_LAYER(vgl
) );
556 return FALSE
; /* I didn't move anything on this layer! */
559 static gpointer
georef_layer_zoom_create ( VikWindow
*vw
, VikViewport
*vvp
)
564 static gboolean
georef_layer_zoom_press ( VikGeorefLayer
*vgl
, GdkEventButton
*event
, VikViewport
*vvp
)
566 if (!vgl
|| vgl
->vl
.type
!= VIK_LAYER_GEOREF
)
568 if ( event
->button
== 1 )
570 if ( vgl
->mpp_easting
< (VIK_VIEWPORT_MAX_ZOOM
/ 1.05) && vgl
->mpp_northing
< (VIK_VIEWPORT_MAX_ZOOM
/ 1.05) )
572 vgl
->mpp_easting
*= 1.01;
573 vgl
->mpp_northing
*= 1.01;
578 if ( vgl
->mpp_easting
> (VIK_VIEWPORT_MIN_ZOOM
* 1.05) && vgl
->mpp_northing
> (VIK_VIEWPORT_MIN_ZOOM
* 1.05) )
580 vgl
->mpp_easting
/= 1.01;
581 vgl
->mpp_northing
/= 1.01;
584 vik_viewport_set_xmpp ( vvp
, vgl
->mpp_easting
);
585 vik_viewport_set_ympp ( vvp
, vgl
->mpp_northing
);
586 vik_layer_emit_update ( VIK_LAYER(vgl
) );
590 static gboolean
georef_layer_move_press ( VikGeorefLayer
*vgl
, GdkEventButton
*event
, VikViewport
*vvp
)
592 if (!vgl
|| vgl
->vl
.type
!= VIK_LAYER_GEOREF
)
594 vgl
->click_x
= event
->x
;
595 vgl
->click_y
= event
->y
;