deadpickle has asked for the wisdom of the Perl Monks concerning the following question:

Trying to build the frame work for a geoTiff Gtk2 app. so far it loads a pre-defined geoTiff(or Tiff) prints the meta-data and captures a mouse click. On the todo list is to have:
1. On mouse click an icon is placed at that position on the tiff. I'm going to guess this has to do with a drawing area but which one? How should it be packed?
2. Convert the window coords from the above mouse click into lat and long of the actual image projection. What governs the $event->x call? I cant seem to find it. Is the geoTiff data printing the whole data?

As always, thanks for the Help.

Here is the code I have so far. To test you would need libgeotiff, a geoTiff and the Image::ExifTool module:
#!/usr/bin/perl use warnings; use strict; use Glib qw/TRUE FALSE/; use Gtk2 -init; use Image::ExifTool; use Geo::Coordinates::UTM; #geoTiff File (static) my $filename = 'q3639_DRG24k-c.tif'; #geostats my $ellipsoid = 23; #static WSG83 my $zone; my @mtp; my @ps; my @cs; #Create Window my $window = new Gtk2::Window ( "toplevel" ); $window->signal_connect ("delete_event", sub { Gtk2->main_quit; }); $window->set_border_width (10); $window->set_size_request(640,480); $window->set_position('center'); #create Table my $table = Gtk2::Table->new(1, 1, FALSE); #Create Scrolled Window my $scwin = Gtk2::ScrolledWindow->new(); $scwin->set_policy('always','always'); #Create Viewport my $vp = Gtk2::Viewport->new (undef,undef); #add GeoTiff my $exifTool = new Image::ExifTool; my $info = $exifTool->ImageInfo($filename); foreach (sort keys %$info) { print "$_ => $$info{$_}\n"; #Find the right keys(data) if ($_ eq "ModelTiePoint"){ @mtp = split(/ /,$$info{$_}); } if ($_ eq "PixelScale"){ @ps = split(/ /,$$info{$_}); } if ($_ eq "ProjectedCSType"){ @cs = split(/ /,$$info{$_}); $zone = $cs[3]; } } my $pixbuf = Gtk2::Gdk::Pixbuf->new_from_file ($filename); my $widget = Gtk2::Image->new_from_pixbuf ($pixbuf); #Create Eventbox and Pack mouse signal my $ebox = Gtk2::EventBox->new; $ebox->set_events( 'button_press_mask' ); $ebox->signal_connect( button_press_event => sub { my ($widget, $event) = @_; my ($x, $y) = ($event->x, $event->y); #convert UTM to Lat and Long my $easting = $ps[0] * $x + 0.0 * $y + $mtp[3]; my $northing = (-$ps[1]) * $y + 0.0 * $x + $mtp[4]; my ($latitude,$longitude)=utm_to_latlon($ellipsoid,$zone,$easting, +$northing); print "$x, $y, ($latitude, $longitude)\n"; }); #Pack $ebox->add($widget); $vp->add($ebox); $window->add($table); $scwin->add($vp); $table->attach_defaults($scwin, 0, 1, 0, 1); #change the cursor over image $ebox->realize; $ebox->window->set_cursor(Gtk2::Gdk::Cursor->new ('hand2')); $window->show_all; Gtk2->main;

Update1: It seems to get the correct lat and long you can use Geo::Coordinates::UTM but I need the northing and easting of the image.
Update2: I found out that the output loop given before does not give all of the data so I changed it, The new script is above. So far this script is very static and seems to grab the correct coordinates using a formula from the .tfw file. This still leaves the drawing part open. I could use some help on that.

Replies are listed 'Best First'.
Re: geoTiff Application Building
by zentara (Cardinal) on May 29, 2008 at 11:24 UTC
    That's alot of stuff we need to get to just to try your script.... too lazy. But if I was to do it, I would put it on a Gnome2::Canvas ( or Goo::Canvas). Why? The canvas has persistence of objects, so you can put your tiff on the canvas, have easy access to canvas mouse coordinates, and can easily drop little icons on top of the tiff..... it would all be
    my $image = Gnome2::Canvas::Item->new ($root, 'Gnome2::Canvas::Pixbuf', pixbuf => $im, x => 75.0, y => 75.0, width => $im->get_width, height => $im->get_height, anchor => 'center', );
    Just keep dropping your images on the canvas, and the canvas will remember it.

    With the event box and a drawing area, it is not-persistent..... and you will need to go thru a bunch of extra work to constantly rebuild on every expose event.

    See Gtk2-annotate-draggable texts on image for an example which you can easily adapt.... I add text to an image on a canvas, but all you need to do is add images in a layer.


    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      Thanks for the reply that works well and it also allows me to zoom and pan the image. Does Gnome2::Canvas capture mouse clicks or do I still have to add an event box to grab this?
        The cool thing about Gtk2 is it is designed properly.... most widgets have an eventbox built-in. A word of caution about pixel-zooming...... it will not save as zoomed, unless you grab a screenshot.
        #!/usr/bin/perl use warnings; use strict; use Gtk2 '-init'; use Gnome2::Canvas; my $window = Gtk2::Window->new; $window ->signal_connect( 'destroy' => \&delete_event ); my $canvas = Gnome2::Canvas->new(); $canvas->set_size_request(256,256); $canvas->set_scroll_region(0,0,256,256); my $root = $canvas->root(); my $item = Gnome2::Canvas::Item->new($root, "Gnome2::Canvas::Ellipse", x1 => 0, y1 => 0, x2 => 200, y2 => 180, fill_color=>"red", outline_color=>"black" ); $item->signal_connect(event=>sub {print "I got an event!\n"; }); $canvas->signal_connect (event => \&event_handler); $window->add ($canvas); $window->show_all; Gtk2->main; ###########################################################3 sub event_handler{ my ( $widget, $event ) = @_; print $widget ,' ',$event->type,"\n"; if ( $event->type eq "button-press" ) { print 'x->',$event->x,' ','y->',$event->y,"\n"; } } sub delete_event { Gtk2->main_quit; return 0; }

        I'm not really a human, but I play one on earth CandyGram for Mongo