#include <stdlib.h>
#include <ctype.h>
+#include "ui_util.h"
#include "preferences.h"
#include "icons/icons.h"
+#include "vikmapslayer.h"
+
/*
static VikLayerParamData image_default ( void )
{
{ VIK_LAYER_GEOREF, "mpp_northing", VIK_LAYER_PARAM_DOUBLE, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL },
{ VIK_LAYER_GEOREF, "corner_zone", VIK_LAYER_PARAM_UINT, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL },
{ VIK_LAYER_GEOREF, "corner_letter_as_int", VIK_LAYER_PARAM_UINT, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL },
+ { VIK_LAYER_GEOREF, "alpha", VIK_LAYER_PARAM_UINT, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL },
};
enum {
PARAM_MN,
PARAM_CZ,
PARAM_CL,
+ PARAM_AA,
NUM_PARAMS };
static const gchar* georef_layer_tooltip ( VikGeorefLayer *vgl );
(VikLayerFuncDraw) georef_layer_draw,
(VikLayerFuncChangeCoordMode) NULL,
+ (VikLayerFuncGetTimestamp) NULL,
+
(VikLayerFuncSetMenuItemsSelection) NULL,
(VikLayerFuncGetMenuItemsSelection) NULL,
VikLayer vl;
gchar *image;
GdkPixbuf *pixbuf;
+ guint8 alpha;
+
struct UTM corner; // Top Left
gdouble mpp_easting, mpp_northing;
struct LatLon ll_br; // Bottom Right
case PARAM_ME: vgl->mpp_easting = data.d; break;
case PARAM_CZ: if ( data.u <= 60 ) vgl->corner.zone = data.u; break;
case PARAM_CL: if ( data.u >= 65 || data.u <= 90 ) vgl->corner.letter = data.u; break;
+ case PARAM_AA: if ( data.u <= 255 ) vgl->alpha = data.u; break;
default: break;
}
return TRUE;
}
+static void create_image_file ( VikGeorefLayer *vgl )
+{
+ // Create in .viking-maps
+ gchar *filename = g_strconcat ( maps_layer_default_dir(), vik_layer_get_name(VIK_LAYER(vgl)), ".jpg", NULL );
+ GError *error = NULL;
+ gdk_pixbuf_save ( vgl->pixbuf, filename, "jpeg", &error, NULL );
+ if ( error ) {
+ g_warning ( "%s", error->message );
+ g_error_free ( error );
+ }
+ else
+ vgl->image = g_strdup ( filename );
+
+ g_free ( filename );
+}
+
static VikLayerParamData georef_layer_get_param ( VikGeorefLayer *vgl, guint16 id, gboolean is_file_operation )
{
VikLayerParamData rv;
case PARAM_IMAGE: {
gboolean set = FALSE;
if ( is_file_operation ) {
+ if ( vgl->pixbuf && !vgl->image ) {
+ // Force creation of image file
+ create_image_file ( vgl );
+ }
if ( a_vik_get_file_ref_format() == VIK_FILE_REF_FORMAT_RELATIVE ) {
gchar *cwd = g_get_current_dir();
if ( cwd ) {
rv.s = file_GetRelativeFilename ( cwd, vgl->image );
- if ( !rv.s ) rv.s = "";
- set = TRUE;
- }
- }
+ if ( !rv.s ) rv.s = "";
+ set = TRUE;
+ }
+ }
}
if ( !set )
rv.s = vgl->image ? vgl->image : "";
case PARAM_ME: rv.d = vgl->mpp_easting; break;
case PARAM_CZ: rv.u = vgl->corner.zone; break;
case PARAM_CL: rv.u = vgl->corner.letter; break;
+ case PARAM_AA: rv.u = vgl->alpha; break;
default: break;
}
return rv;
vgl->scaled_height = 0;
vgl->ll_br.lat = 0.0;
vgl->ll_br.lon = 0.0;
+ vgl->alpha = 255;
return vgl;
}
+/**
+ * Return mpp for the given coords, coord mode and image size.
+ */
+static void georef_layer_mpp_from_coords ( VikCoordMode mode, struct LatLon ll_tl, struct LatLon ll_br, guint width, guint height, gdouble *xmpp, gdouble *ympp )
+{
+ struct LatLon ll_tr;
+ ll_tr.lat = ll_tl.lat;
+ ll_tr.lon = ll_br.lon;
+
+ struct LatLon ll_bl;
+ ll_bl.lat = ll_br.lat;
+ ll_bl.lon = ll_tl.lon;
+
+ // UTM mode should be exact MPP
+ gdouble factor = 1.0;
+ if ( mode == VIK_COORD_LATLON ) {
+ // NB the 1.193 - is at the Equator.
+ // http://wiki.openstreetmap.org/wiki/Zoom_levels
+
+ // Convert from actual image MPP to Viking 'pixelfact'
+ gdouble mid_lat = (ll_bl.lat + ll_tr.lat ) / 2.0;
+ // Protect against div by zero (but shouldn't have 90 degrees for mid latitude...)
+ if ( fabs(mid_lat) < 89.9 )
+ factor = cos(DEG2RAD(mid_lat)) * 1.193;
+ }
+
+ gdouble diffx = a_coords_latlon_diff ( &ll_tl, &ll_tr );
+ *xmpp = (diffx / width) / factor;
+
+ gdouble diffy = a_coords_latlon_diff ( &ll_tl, &ll_bl );
+ *ympp = (diffy / height) / factor;
+}
+
static void georef_layer_draw ( VikGeorefLayer *vgl, VikViewport *vp )
{
if ( vgl->pixbuf )
{
vgl->width = gdk_pixbuf_get_width ( vgl->pixbuf );
vgl->height = gdk_pixbuf_get_height ( vgl->pixbuf );
+
+ if ( vgl->pixbuf && vgl->alpha <= 255 )
+ vgl->pixbuf = ui_pixbuf_set_alpha ( vgl->pixbuf, vgl->alpha );
}
/* should find length and width here too */
}
struct LatLon ll_tl = get_ll_tl (vgl);
struct LatLon ll_br = get_ll_br (vgl);
- struct LatLon ll_tr;
- ll_tr.lat = ll_tl.lat;
- ll_tr.lon = ll_br.lon;
-
- struct LatLon ll_bl;
- ll_bl.lat = ll_br.lat;
- ll_bl.lon = ll_tl.lon;
-
- gdouble diffx = a_coords_latlon_diff ( &ll_tl, &ll_tr );
- gdouble xmpp = diffx / width;
-
- gdouble diffy = a_coords_latlon_diff ( &ll_tl, &ll_bl );
- gdouble ympp = diffy / height;
+ gdouble xmpp, ympp;
+ georef_layer_mpp_from_coords ( VIK_COORD_LATLON, ll_tl, ll_br, width, height, &xmpp, &ympp );
gtk_spin_button_set_value ( GTK_SPIN_BUTTON(vgl->cw.x_spin), xmpp );
gtk_spin_button_set_value ( GTK_SPIN_BUTTON(vgl->cw.y_spin), ympp );
gtk_notebook_append_page(GTK_NOTEBOOK(cw.tabs), GTK_WIDGET(table_ll), gtk_label_new(_("Latitude/Longitude")));
gtk_box_pack_start ( dgbox, cw.tabs, TRUE, TRUE, 0 );
+ GtkWidget *alpha_hbox = gtk_hbox_new ( FALSE, 0 );
+ // GTK3 => GtkWidget *alpha_scale = gtk_scale_new_with_range ( GTK_ORIENTATION_HORIZONTAL, 0, 255, 1 );
+ GtkWidget *alpha_scale = gtk_hscale_new_with_range ( 0, 255, 1 );
+ gtk_scale_set_digits ( GTK_SCALE(alpha_scale), 0 );
+ gtk_range_set_value ( GTK_RANGE(alpha_scale), vgl->alpha );
+ gtk_box_pack_start ( GTK_BOX(alpha_hbox), gtk_label_new(_("Alpha:")), TRUE, TRUE, 0 );
+ gtk_box_pack_start ( GTK_BOX(alpha_hbox), alpha_scale, TRUE, TRUE, 0 );
+ gtk_box_pack_start ( dgbox, alpha_hbox, TRUE, TRUE, 0 );
+
vgl->cw = cw;
g_signal_connect ( G_OBJECT(vgl->cw.tabs), "switch-page", G_CALLBACK(switch_tab), vgl );
vgl->mpp_northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(cw.y_spin) );
vgl->ll_br = get_ll_br (vgl);
check_br_is_good_or_msg_user ( vgl );
- if ( g_strcmp0 (vgl->image, vik_file_entry_get_filename(VIK_FILE_ENTRY(cw.imageentry)) ) != 0 )
+ // TODO check if image has changed otherwise no need to regenerate pixbuf
+ if ( !vgl->pixbuf )
{
- georef_layer_set_image ( vgl, vik_file_entry_get_filename(VIK_FILE_ENTRY(cw.imageentry)) );
- georef_layer_load_image ( vgl, VIK_VIEWPORT(vp), FALSE );
+ if ( g_strcmp0 (vgl->image, vik_file_entry_get_filename(VIK_FILE_ENTRY(cw.imageentry)) ) != 0 )
+ {
+ georef_layer_set_image ( vgl, vik_file_entry_get_filename(VIK_FILE_ENTRY(cw.imageentry)) );
+ georef_layer_load_image ( vgl, VIK_VIEWPORT(vp), FALSE );
+ }
}
+ vgl->alpha = (guint8) gtk_range_get_value ( GTK_RANGE(alpha_scale) );
+ if ( vgl->pixbuf && vgl->alpha <= 255 )
+ vgl->pixbuf = ui_pixbuf_set_alpha ( vgl->pixbuf, vgl->alpha );
+ if ( vgl->scaled && vgl->alpha <= 255 )
+ vgl->scaled = ui_pixbuf_set_alpha ( vgl->scaled, vgl->alpha );
+
a_settings_set_integer ( VIK_SETTINGS_GEOREF_TAB, gtk_notebook_get_current_page(GTK_NOTEBOOK(cw.tabs)) );
gtk_widget_destroy ( GTK_WIDGET(dialog) );
vgl->click_y = event->y;
return TRUE;
}
+
+static void goto_center_ll ( VikViewport *vp,
+ struct LatLon ll_tl,
+ struct LatLon ll_br )
+{
+ VikCoord vc_center;
+ struct LatLon ll_center;
+
+ ll_center.lat = (ll_tl.lat + ll_br.lat) / 2.0;
+ ll_center.lon = (ll_tl.lon + ll_br.lon) / 2.0;
+
+ vik_coord_load_from_latlon ( &vc_center, vik_viewport_get_coord_mode (vp), &ll_center );
+ vik_viewport_set_center_coord ( vp, &vc_center, TRUE );
+}
+
+/**
+ *
+ */
+VikGeorefLayer *vik_georef_layer_create ( VikViewport *vp,
+ VikLayersPanel *vlp,
+ const gchar *name,
+ GdkPixbuf *pixbuf,
+ VikCoord *coord_tl,
+ VikCoord *coord_br )
+{
+ VikGeorefLayer *vgl = georef_layer_new ( vp );
+ vik_layer_rename ( VIK_LAYER(vgl), name );
+
+ vgl->pixbuf = pixbuf;
+
+ vik_coord_to_utm ( coord_tl, &(vgl->corner) );
+ vik_coord_to_latlon ( coord_br, &(vgl->ll_br) );
+
+ if ( vgl->pixbuf ) {
+ vgl->width = gdk_pixbuf_get_width ( vgl->pixbuf );
+ vgl->height = gdk_pixbuf_get_height ( vgl->pixbuf );
+
+ if ( vgl->width > 0 && vgl->height > 0 ) {
+
+ struct LatLon ll_tl;
+ vik_coord_to_latlon ( coord_tl, &ll_tl);
+ struct LatLon ll_br;
+ vik_coord_to_latlon ( coord_br, &ll_br);
+
+ VikCoordMode mode = vik_viewport_get_coord_mode (vp);
+
+ gdouble xmpp, ympp;
+ georef_layer_mpp_from_coords ( mode, ll_tl, ll_br, vgl->width, vgl->height, &xmpp, &ympp );
+ vgl->mpp_easting = xmpp;
+ vgl->mpp_northing = ympp;
+
+ goto_center_ll ( vp, ll_tl, ll_br);
+ // Set best zoom level
+ struct LatLon maxmin[2] = { ll_tl, ll_br };
+ vu_zoom_to_show_latlons ( vik_viewport_get_coord_mode(vp), vp, maxmin );
+
+ return vgl;
+ }
+ }
+
+ // Bad image
+ georef_layer_free ( vgl );
+ return NULL;
+}