Esempio n. 1
0
/**
 * vik_viewport_compute_bearing:
 * @vp: self object
 * @x1: screen coord
 * @y1: screen coord
 * @x2: screen coord
 * @y2: screen coord
 * @angle: bearing in Radian (output)
 * @baseangle: UTM base angle in Radian (output)
 * 
 * Compute bearing.
 */
void vik_viewport_compute_bearing ( VikViewport *vp, gint x1, gint y1, gint x2, gint y2, gdouble *angle, gdouble *baseangle )
{
  gdouble len = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
  gdouble dx = (x2-x1)/len*10;
  gdouble dy = (y2-y1)/len*10;

  *angle = atan2(dy, dx) + M_PI_2;

  if ( vik_viewport_get_drawmode ( vp ) == VIK_VIEWPORT_DRAWMODE_UTM) {
    VikCoord test;
    struct LatLon ll;
    struct UTM u;
    gint tx, ty;

    vik_viewport_screen_to_coord ( vp, x1, y1, &test );
    vik_coord_to_latlon ( &test, &ll );
    ll.lat += vik_viewport_get_ympp ( vp ) * vik_viewport_get_height ( vp ) / 11000.0; // about 11km per degree latitude
    a_coords_latlon_to_utm ( &ll, &u );
    vik_coord_load_from_utm ( &test, VIK_VIEWPORT_DRAWMODE_UTM, &u );
    vik_viewport_coord_to_screen ( vp, &test, &tx, &ty );

    *baseangle = M_PI - atan2(tx-x1, ty-y1);
    *angle -= *baseangle;
  }

  if (*angle < 0)
    *angle += 2*M_PI;
  if (*angle > 2*M_PI)
    *angle -= 2*M_PI;
}
Esempio n. 2
0
static VikGeorefLayer *georef_layer_new ( VikViewport *vvp )
{
  VikGeorefLayer *vgl = VIK_GEOREF_LAYER ( g_object_new ( VIK_GEOREF_LAYER_TYPE, NULL ) );
  vik_layer_set_type ( VIK_LAYER(vgl), VIK_LAYER_GEOREF );

  // Since GeoRef layer doesn't use uibuilder
  //  initializing this way won't do anything yet..
  vik_layer_set_defaults ( VIK_LAYER(vgl), vvp );

  // Make these defaults based on the current view
  vgl->mpp_northing = vik_viewport_get_ympp ( vvp );
  vgl->mpp_easting = vik_viewport_get_xmpp ( vvp );
  vik_coord_to_utm ( vik_viewport_get_center ( vvp ), &(vgl->corner) );

  vgl->image = NULL;
  vgl->pixbuf = NULL;
  vgl->click_x = -1;
  vgl->click_y = -1;
  vgl->scaled = NULL;
  vgl->scaled_width = 0;
  vgl->scaled_height = 0;
  vgl->ll_br.lat = 0.0;
  vgl->ll_br.lon = 0.0;
  vgl->alpha = 255;
  return vgl;
}
Esempio n. 3
0
static void georef_layer_draw ( VikGeorefLayer *vgl, VikViewport *vp )
{
  if ( vik_viewport_get_drawmode(vp) != VIK_VIEWPORT_DRAWMODE_UTM )
    return;

  if ( vgl->pixbuf )
  {
    struct UTM utm_middle;
    gdouble xmpp = vik_viewport_get_xmpp(vp), ympp = vik_viewport_get_ympp(vp);
    GdkPixbuf *pixbuf = vgl->pixbuf;
    guint layer_width = vgl->width;
    guint layer_height = vgl->height;

    vik_coord_to_utm ( vik_viewport_get_center ( vp ), &utm_middle );

    /* scale the pixbuf if it doesn't match our dimensions */
    if ( xmpp != vgl->mpp_easting || ympp != vgl->mpp_northing )
    {
      layer_width = round(vgl->width * vgl->mpp_easting / xmpp);
      layer_height = round(vgl->height * vgl->mpp_northing / ympp);

      /* rescale if necessary */
      if (layer_width == vgl->scaled_width && layer_height == vgl->scaled_height && vgl->scaled != NULL)
        pixbuf = vgl->scaled;
      else
      {
        pixbuf = gdk_pixbuf_scale_simple(
          vgl->pixbuf, 
          layer_width,
          layer_height,
          GDK_INTERP_BILINEAR
        );

        if (vgl->scaled != NULL)
          g_object_unref(vgl->scaled);

        vgl->scaled = pixbuf;
        vgl->scaled_width = layer_width;
        vgl->scaled_height = layer_height;
      }
    }

    guint width = vik_viewport_get_width(vp), height = vik_viewport_get_height(vp);
    gint32 x, y;
    vgl->corner.zone = utm_middle.zone;
    vgl->corner.letter = utm_middle.letter;
    VikCoord corner_coord;
    vik_coord_load_from_utm ( &corner_coord, vik_viewport_get_coord_mode(vp), &(vgl->corner) );
    vik_viewport_coord_to_screen ( vp, &corner_coord, &x, &y );
    if ( (x < 0 || x < width) && (y < 0 || y < height) && x+layer_width > 0 && y+layer_height > 0 )
      vik_viewport_draw_pixbuf ( vp, pixbuf, 0, 0, x, y, layer_width, layer_height ); /* todo: draw only what we need to. */
  }
}
Esempio n. 4
0
static void georef_layer_draw ( VikGeorefLayer *vgl, VikViewport *vp )
{
  if ( vgl->pixbuf )
  {
    gdouble xmpp = vik_viewport_get_xmpp(vp), ympp = vik_viewport_get_ympp(vp);
    GdkPixbuf *pixbuf = vgl->pixbuf;
    guint layer_width = vgl->width;
    guint layer_height = vgl->height;

    guint width = vik_viewport_get_width(vp), height = vik_viewport_get_height(vp);
    gint32 x, y;
    VikCoord corner_coord;
    vik_coord_load_from_utm ( &corner_coord, vik_viewport_get_coord_mode(vp), &(vgl->corner) );
    vik_viewport_coord_to_screen ( vp, &corner_coord, &x, &y );

    /* mark to scale the pixbuf if it doesn't match our dimensions */
    gboolean scale = FALSE;
    if ( xmpp != vgl->mpp_easting || ympp != vgl->mpp_northing )
    {
      scale = TRUE;
      layer_width = round(vgl->width * vgl->mpp_easting / xmpp);
      layer_height = round(vgl->height * vgl->mpp_northing / ympp);
    }

    // If image not in viewport bounds - no need to draw it (or bother with any scaling)
    if ( (x < 0 || x < width) && (y < 0 || y < height) && x+layer_width > 0 && y+layer_height > 0 ) {

      if ( scale )
      {
        /* rescale if necessary */
        if (layer_width == vgl->scaled_width && layer_height == vgl->scaled_height && vgl->scaled != NULL)
          pixbuf = vgl->scaled;
        else
        {
          pixbuf = gdk_pixbuf_scale_simple(
            vgl->pixbuf,
            layer_width,
            layer_height,
            GDK_INTERP_BILINEAR
          );

          if (vgl->scaled != NULL)
            g_object_unref(vgl->scaled);

          vgl->scaled = pixbuf;
          vgl->scaled_width = layer_width;
          vgl->scaled_height = layer_height;
        }
      }
      vik_viewport_draw_pixbuf ( vp, pixbuf, 0, 0, x, y, layer_width, layer_height ); /* todo: draw only what we need to. */
    }
  }
}
Esempio n. 5
0
File: print.c Progetto: gdt/viking
void a_print(VikWindow *vw, VikViewport *vvp)
{
  /* TODO: make print_settings non-static when saving_settings_to_file is
   * implemented. Keep it static for now to retain settings for each
   * viking session
   */
  static GtkPrintSettings *print_settings = NULL;

  GtkPrintOperation *print_oper;
  GtkPrintOperationResult res;
  PrintData data;

  print_oper = gtk_print_operation_new ();

  data.num_pages     = 1;
  data.vw            = vw;
  data.vvp           = vvp;
  data.offset_x      = 0;
  data.offset_y      = 0;
  data.center        = VIK_PRINT_CENTER_BOTH;
  data.use_full_page = FALSE;
  data.operation     = print_oper;

  data.xmpp          = vik_viewport_get_xmpp(vvp);
  data.ympp          = vik_viewport_get_ympp(vvp);
  data.width         = vik_viewport_get_width(vvp);
  data.height        = vik_viewport_get_height(vvp);

  data.xres = data.yres = 230;   /* FIXME */

  if (print_settings != NULL) 
    gtk_print_operation_set_print_settings (print_oper, print_settings);

  g_signal_connect (print_oper, "begin_print", G_CALLBACK (begin_print), &data);
  g_signal_connect (print_oper, "draw_page", G_CALLBACK (draw_page), &data);
  g_signal_connect (print_oper, "end-print", G_CALLBACK (end_print), &data);
  g_signal_connect (print_oper, "create-custom-widget", G_CALLBACK (create_custom_widget_cb), &data);

  gtk_print_operation_set_custom_tab_label (print_oper, _("Image Settings"));

  res = gtk_print_operation_run (print_oper,
                                 GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
                                 GTK_WINDOW (vw), NULL);

  if (res == GTK_PRINT_OPERATION_RESULT_APPLY) {
    if (print_settings != NULL)
      g_object_unref (print_settings);
    print_settings = g_object_ref (gtk_print_operation_get_print_settings (print_oper));
  }

  g_object_unref (print_oper);
}
Esempio n. 6
0
static gboolean georef_layer_move_release ( VikGeorefLayer *vgl, GdkEventButton *event, VikViewport *vvp )
{
  if (!vgl || vgl->vl.type != VIK_LAYER_GEOREF)
    return FALSE;

  if ( vgl->click_x != -1 )
  {
    vgl->corner.easting += (event->x - vgl->click_x) * vik_viewport_get_xmpp (vvp);
    vgl->corner.northing -= (event->y - vgl->click_y) * vik_viewport_get_ympp (vvp);
    vik_layer_emit_update ( VIK_LAYER(vgl) );
    return TRUE;
  }
  return FALSE; /* I didn't move anything on this layer! */
}
Esempio n. 7
0
File: file.c Progetto: gapato/viking
static void file_write ( VikAggregateLayer *top, FILE *f, gpointer vp )
{
  Stack *stack = NULL;
  VikLayer *current_layer;
  struct LatLon ll;
  VikViewportDrawMode mode;
  gchar *modestring = NULL;

  push(&stack);
  stack->data = (gpointer) vik_aggregate_layer_get_children(VIK_AGGREGATE_LAYER(top));
  stack->under = NULL;

  /* crazhy CRAZHY */
  vik_coord_to_latlon ( vik_viewport_get_center ( VIK_VIEWPORT(vp) ), &ll );

  mode = vik_viewport_get_drawmode ( VIK_VIEWPORT(vp) );
  switch ( mode ) {
    case VIK_VIEWPORT_DRAWMODE_UTM: modestring = "utm"; break;
    case VIK_VIEWPORT_DRAWMODE_EXPEDIA: modestring = "expedia"; break;
    case VIK_VIEWPORT_DRAWMODE_MERCATOR: modestring = "mercator"; break;
    case VIK_VIEWPORT_DRAWMODE_LATLON: modestring = "latlon"; break;
    default:
      g_critical("Houston, we've had a problem. mode=%d", mode);
  }

  fprintf ( f, "#VIKING GPS Data file " VIKING_URL "\n" );
  fprintf ( f, "FILE_VERSION=%d\n", VIKING_FILE_VERSION );
  fprintf ( f, "\nxmpp=%f\nympp=%f\nlat=%f\nlon=%f\nmode=%s\ncolor=%s\nhighlightcolor=%s\ndrawscale=%s\ndrawcentermark=%s\ndrawhighlight=%s\n",
      vik_viewport_get_xmpp ( VIK_VIEWPORT(vp) ), vik_viewport_get_ympp ( VIK_VIEWPORT(vp) ), ll.lat, ll.lon,
      modestring, vik_viewport_get_background_color(VIK_VIEWPORT(vp)),
      vik_viewport_get_highlight_color(VIK_VIEWPORT(vp)),
      vik_viewport_get_draw_scale(VIK_VIEWPORT(vp)) ? "t" : "f",
      vik_viewport_get_draw_centermark(VIK_VIEWPORT(vp)) ? "t" : "f",
      vik_viewport_get_draw_highlight(VIK_VIEWPORT(vp)) ? "t" : "f" );

  if ( ! VIK_LAYER(top)->visible )
    fprintf ( f, "visible=f\n" );

  while (stack && stack->data)
  {
    current_layer = VIK_LAYER(((GList *)stack->data)->data);
    fprintf ( f, "\n~Layer %s\n", vik_layer_get_interface(current_layer->type)->fixed_layer_name );
    write_layer_params_and_data ( current_layer, f );
    if ( current_layer->type == VIK_LAYER_AGGREGATE && !vik_aggregate_layer_is_empty(VIK_AGGREGATE_LAYER(current_layer)) )
    {
      push(&stack);
      stack->data = (gpointer) vik_aggregate_layer_get_children(VIK_AGGREGATE_LAYER(current_layer));
    }
    else if ( current_layer->type == VIK_LAYER_GPS && !vik_gps_layer_is_empty(VIK_GPS_LAYER(current_layer)) )
    {
      push(&stack);
      stack->data = (gpointer) vik_gps_layer_get_children(VIK_GPS_LAYER(current_layer));
    }
    else
    {
      stack->data = (gpointer) ((GList *)stack->data)->next;
      fprintf ( f, "~EndLayer\n\n" );
      while ( stack && (!stack->data) )
      {
        pop(&stack);
        if ( stack )
        {
          stack->data = (gpointer) ((GList *)stack->data)->next;
          fprintf ( f, "~EndLayer\n\n" );
        }
      }
    }
  }
/*
  get vikaggregatelayer's children (?)
  foreach write ALL params,
  then layer data (IF function exists)
  then endlayer

  impl:
  stack of layers (LIST) we are working on
  when layer->next == NULL ...
  we move on.
*/
}
Esempio n. 8
0
void vik_coord_layer_draw ( VikCoordLayer *vcl, gpointer data )
{
  VikViewport *vp = (VikViewport *) data;

  if ( !vcl->gc ) {
    return;
  }

  if ( vik_viewport_get_coord_mode(vp) != VIK_COORD_UTM ) 
  {
    VikCoord left, right, left2, right2;
    gdouble l, r, i, j;
    gint x1, y1, x2, y2, smod = 1, mmod = 1;
    gboolean mins = FALSE, secs = FALSE;
    GdkGC *dgc = vik_viewport_new_gc_from_color(vp, vcl->color, vcl->line_thickness);
    GdkGC *mgc = vik_viewport_new_gc_from_color(vp, vcl->color, MAX(vcl->line_thickness/2, 1));
    GdkGC *sgc = vik_viewport_new_gc_from_color(vp, vcl->color, MAX(vcl->line_thickness/5, 1));

    vik_viewport_screen_to_coord ( vp, 0, 0, &left );
    vik_viewport_screen_to_coord ( vp, vik_viewport_get_width(vp), 0, &right );
    vik_viewport_screen_to_coord ( vp, 0, vik_viewport_get_height(vp), &left2 );
    vik_viewport_screen_to_coord ( vp, vik_viewport_get_width(vp), vik_viewport_get_height(vp), &right2 );

#define CLINE(gc, c1, c2) { \
	  vik_viewport_coord_to_screen(vp, (c1), &x1, &y1);  \
	  vik_viewport_coord_to_screen(vp, (c2), &x2, &y2);  \
	  vik_viewport_draw_line (vp, (gc), x1, y1, x2, y2); \
	}

    l = left.east_west;
    r = right.east_west;
    if (60*fabs(l-r) < 4) {
      secs = TRUE;
      smod = MIN(6, (int)ceil(3600*fabs(l-r)/30.0));
    }
    if (fabs(l-r) < 4) {
      mins = TRUE;
      mmod = MIN(6, (int)ceil(60*fabs(l-r)/30.0));
    }
    for (i=floor(l*60); i<ceil(r*60); i+=1.0) {
      if (secs) {
	for (j=i*60+1; j<(i+1)*60; j+=1.0) {
	  left.east_west = j/3600.0;
	  left2.east_west = j/3600.0;
	  if ((int)j % smod == 0) CLINE(sgc, &left, &left2);
	}
      }
      if (mins) {
	left.east_west = i/60.0;
	left2.east_west = i/60.0;
	if ((int)i % mmod == 0) CLINE(mgc, &left, &left2);
      }
      if ((int)i % 60 == 0) {
	left.east_west = i/60.0;
	left2.east_west = i/60.0;
	CLINE(dgc, &left, &left2);
      }
    }

    vik_viewport_screen_to_coord ( vp, 0, 0, &left );
    l = left2.north_south;
    r = left.north_south;
    for (i=floor(l*60); i<ceil(r*60); i+=1.0) {
      if (secs) {
	for (j=i*60+1; j<(i+1)*60; j+=1.0) {
	  left.north_south = j/3600.0;
	  right.north_south = j/3600.0;
	  if ((int)j % smod == 0) CLINE(sgc, &left, &right);
	}
      }
      if (mins) {
	left.north_south = i/60.0;
	right.north_south = i/60.0;
	if ((int)i % mmod == 0) CLINE(mgc, &left, &right);
      }
      if ((int)i % 60 == 0) {
	left.north_south = i/60.0;
	right.north_south = i/60.0;
	CLINE(dgc, &left, &right);
      }
    }
#undef CLINE
    g_object_unref(dgc);
    g_object_unref(sgc);
    g_object_unref(mgc);
    return;
  }

  if ( vik_viewport_get_coord_mode(vp) == VIK_COORD_UTM ) 
  {
    const struct UTM *center = (const struct UTM *)vik_viewport_get_center ( vp );
    gdouble xmpp = vik_viewport_get_xmpp ( vp ), ympp = vik_viewport_get_ympp ( vp );
    guint16 width = vik_viewport_get_width ( vp ), height = vik_viewport_get_height ( vp );
    struct LatLon ll, ll2, min, max;
    double lon;
    int x1, x2;
    struct UTM utm;

    utm = *center;
    utm.northing = center->northing - ( ympp * height / 2 );

    a_coords_utm_to_latlon ( &utm, &ll );

    utm.northing = center->northing + ( ympp * height / 2 );

    a_coords_utm_to_latlon ( &utm, &ll2 );

    {
      /* find corner coords in lat/lon.
        start at whichever is less: top or bottom left lon. goto whichever more: top or bottom right lon
      */
      struct LatLon topleft, topright, bottomleft, bottomright;
      struct UTM temp_utm;
      temp_utm = *center;
      temp_utm.easting -= (width/2)*xmpp;
      temp_utm.northing += (height/2)*ympp;
      a_coords_utm_to_latlon ( &temp_utm, &topleft );
      temp_utm.easting += (width*xmpp);
      a_coords_utm_to_latlon ( &temp_utm, &topright );
      temp_utm.northing -= (height*ympp);
      a_coords_utm_to_latlon ( &temp_utm, &bottomright );
      temp_utm.easting -= (width*xmpp);
      a_coords_utm_to_latlon ( &temp_utm, &bottomleft );
      min.lon = (topleft.lon < bottomleft.lon) ? topleft.lon : bottomleft.lon;
      max.lon = (topright.lon > bottomright.lon) ? topright.lon : bottomright.lon;
      min.lat = (bottomleft.lat < bottomright.lat) ? bottomleft.lat : bottomright.lat;
      max.lat = (topleft.lat > topright.lat) ? topleft.lat : topright.lat;
    }

    lon = ((double) ((long) ((min.lon)/ vcl->deg_inc))) * vcl->deg_inc;
    ll.lon = ll2.lon = lon;

    for (; ll.lon <= max.lon; ll.lon+=vcl->deg_inc, ll2.lon+=vcl->deg_inc )
    {
      a_coords_latlon_to_utm ( &ll, &utm );
      x1 = ( (utm.easting - center->easting) / xmpp ) + (width / 2);
      a_coords_latlon_to_utm ( &ll2, &utm );
      x2 = ( (utm.easting - center->easting) / xmpp ) + (width / 2);
      vik_viewport_draw_line (vp, vcl->gc, x1, height, x2, 0);
    }

    utm = *center;
    utm.easting = center->easting - ( xmpp * width / 2 );

    a_coords_utm_to_latlon ( &utm, &ll );

    utm.easting = center->easting + ( xmpp * width / 2 );

    a_coords_utm_to_latlon ( &utm, &ll2 );

    /* really lat, just reusing a variable */
    lon = ((double) ((long) ((min.lat)/ vcl->deg_inc))) * vcl->deg_inc;
    ll.lat = ll2.lat = lon;

    for (; ll.lat <= max.lat ; ll.lat+=vcl->deg_inc, ll2.lat+=vcl->deg_inc )
    {
      a_coords_latlon_to_utm ( &ll, &utm );
      x1 = (height / 2) - ( (utm.northing - center->northing) / ympp );
      a_coords_latlon_to_utm ( &ll2, &utm );
      x2 = (height / 2) - ( (utm.northing - center->northing) / ympp );
      vik_viewport_draw_line (vp, vcl->gc, width, x2, 0, x1);
    }
  }
}
Esempio n. 9
0
/* returns TRUE if OK was pressed. */
static gboolean georef_layer_dialog ( VikGeorefLayer **vgl, gpointer vp, GtkWindow *w )
{
  GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Layer Properties"),
                                                  w,
                                                  GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
                                                  GTK_STOCK_CANCEL,
                                                  GTK_RESPONSE_REJECT,
                                                  GTK_STOCK_OK,
                                                  GTK_RESPONSE_ACCEPT,
                                                  NULL );
  /* Default to reject as user really needs to specify map file first */
  gtk_dialog_set_default_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
  GtkWidget *response_w = NULL;
#if GTK_CHECK_VERSION (2, 20, 0)
  response_w = gtk_dialog_get_widget_for_response ( GTK_DIALOG(dialog), GTK_RESPONSE_REJECT );
#endif
  GtkWidget *table, *wfp_hbox, *wfp_label, *wfp_button, *ce_label, *ce_spin, *cn_label, *cn_spin, *xlabel, *xspin, *ylabel, *yspin, *imagelabel, *imageentry;

  GtkWidget *pass_along[4];

  table = gtk_table_new ( 6, 2, FALSE );
  gtk_box_pack_start ( GTK_BOX(GTK_DIALOG(dialog)->vbox), table, TRUE, TRUE, 0 );

  wfp_hbox = gtk_hbox_new ( FALSE, 0 );
  wfp_label = gtk_label_new ( _("World File Parameters:") );
  wfp_button = gtk_button_new_with_label ( _("Load From File...") );

  gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_label, TRUE, TRUE, 0 );
  gtk_box_pack_start ( GTK_BOX(wfp_hbox), wfp_button, FALSE, FALSE, 3 );

  ce_label = gtk_label_new ( _("Corner pixel easting:") );
  ce_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 1500000.0, 1, 5, 0 ), 1, 4 );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(ce_spin), _("the UTM \"easting\" value of the upper-left corner pixel of the map") );

  cn_label = gtk_label_new ( _("Corner pixel northing:") );
  cn_spin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, 0.0, 9000000.0, 1, 5, 0 ), 1, 4 );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(cn_spin), _("the UTM \"northing\" value of the upper-left corner pixel of the map") );

  xlabel = gtk_label_new ( _("X (easting) scale (mpp): "));
  ylabel = gtk_label_new ( _("Y (northing) scale (mpp): "));

  xspin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(xspin), _("the scale of the map in the X direction (meters per pixel)") );
  yspin = gtk_spin_button_new ( (GtkAdjustment *) gtk_adjustment_new ( 4, VIK_VIEWPORT_MIN_ZOOM, VIK_VIEWPORT_MAX_ZOOM, 1, 5, 0 ), 1, 8 );
  gtk_widget_set_tooltip_text ( GTK_WIDGET(yspin), _("the scale of the map in the Y direction (meters per pixel)") );

  imagelabel = gtk_label_new ( _("Map Image:") );
  imageentry = vik_file_entry_new (GTK_FILE_CHOOSER_ACTION_OPEN);

  if (*vgl)
  {
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin), (*vgl)->corner.easting );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin), (*vgl)->corner.northing );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin), (*vgl)->mpp_easting );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin), (*vgl)->mpp_northing );
    if ( (*vgl)->image )
    vik_file_entry_set_filename ( VIK_FILE_ENTRY(imageentry), (*vgl)->image );
  }
  else
  {
    VikCoord corner_coord;
    struct UTM utm;
    vik_viewport_screen_to_coord ( VIK_VIEWPORT(vp), 0, 0, &corner_coord );
    vik_coord_to_utm ( &corner_coord, &utm );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(ce_spin), utm.easting );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(cn_spin), utm.northing );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(xspin), vik_viewport_get_xmpp ( VIK_VIEWPORT(vp) ) );
    gtk_spin_button_set_value ( GTK_SPIN_BUTTON(yspin), vik_viewport_get_ympp ( VIK_VIEWPORT(vp) ) );
  }

  gtk_table_attach_defaults ( GTK_TABLE(table), imagelabel, 0, 1, 0, 1 );
  gtk_table_attach_defaults ( GTK_TABLE(table), imageentry, 1, 2, 0, 1 );
  gtk_table_attach_defaults ( GTK_TABLE(table), wfp_hbox, 0, 2, 1, 2 );
  gtk_table_attach_defaults ( GTK_TABLE(table), xlabel, 0, 1, 2, 3 );
  gtk_table_attach_defaults ( GTK_TABLE(table), xspin, 1, 2, 2, 3 );
  gtk_table_attach_defaults ( GTK_TABLE(table), ylabel, 0, 1, 3, 4 );
  gtk_table_attach_defaults ( GTK_TABLE(table), yspin, 1, 2, 3, 4 );
  gtk_table_attach_defaults ( GTK_TABLE(table), ce_label, 0, 1, 4, 5 );
  gtk_table_attach_defaults ( GTK_TABLE(table), ce_spin, 1, 2, 4, 5 );
  gtk_table_attach_defaults ( GTK_TABLE(table), cn_label, 0, 1, 5, 6 );
  gtk_table_attach_defaults ( GTK_TABLE(table), cn_spin, 1, 2, 5, 6 );

  pass_along[0] = xspin;
  pass_along[1] = yspin;
  pass_along[2] = ce_spin;
  pass_along[3] = cn_spin;
  g_signal_connect_swapped ( G_OBJECT(wfp_button), "clicked", G_CALLBACK(georef_layer_dialog_load), pass_along );

  if ( response_w )
    gtk_widget_grab_focus ( response_w );

  gtk_widget_show_all ( table );

  if ( gtk_dialog_run ( GTK_DIALOG(dialog) ) == GTK_RESPONSE_ACCEPT )
  {
    if (! *vgl)
    {
      *vgl = georef_layer_new ( VIK_VIEWPORT(vp) );
       vik_layer_rename ( VIK_LAYER(*vgl), vik_georef_layer_interface.name );
    }
    (*vgl)->corner.easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(ce_spin) );
    (*vgl)->corner.northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(cn_spin) );
    (*vgl)->mpp_easting = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(xspin) );
    (*vgl)->mpp_northing = gtk_spin_button_get_value ( GTK_SPIN_BUTTON(yspin) );
    if ( (!(*vgl)->image) || strcmp( (*vgl)->image, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry)) ) != 0 )
    {
      georef_layer_set_image ( *vgl, vik_file_entry_get_filename(VIK_FILE_ENTRY(imageentry)) );
      georef_layer_load_image ( *vgl, VIK_VIEWPORT(vp), FALSE );
    }

    gtk_widget_destroy ( GTK_WIDGET(dialog) );
    return TRUE;
  }
  gtk_widget_destroy ( GTK_WIDGET(dialog) );
  return FALSE;
}