## @namespace Gtk2::Ex::Geo # @brief A framework of widgets for geospatial applications package Gtk2::Ex::Geo; # @brief A framework of widgets for geospatial applications # @author Copyright (c) Ari Jolma # @author This library is free software; you can redistribute it and/or modify # it under the same terms as Perl itself, either Perl version 5.8.5 or, # at your option, any later version of Perl 5 you may have available. =pod =head1 NAME Gtk2::Ex::Geo - The main module to use for geospatial applications Gtk2::Ex::Geo is a namespace for modules, classes, and widgets for geospatial applications. This package contains the modules: =head2 Gtk2::Ex::Geo The main module to 'use'. Contains also function 'simple', which constructs a simple geospatial desktop application. =head2 Gtk2::Ex::Geo::Canvas A subclass of Gtk2::Gdk::Pixbuf. Constructs a pixbuf from a stack of geospatial layer objects by calling the 'render' method for each $layer. Embedded in Gtk2::Ex::Geo::Overlay. =head2 Gtk2::Ex::Geo::Overlay A subclass of Gtk2::ScrolledWindow. A canvas in a scrolled window. Contains a list of layer objects. Functionality includes redraw, support for selections (point, line, path, rectangle, polygon, or many of them), zoom, pan, and conversion between event and world (layer) coordinates. =head2 Gtk2::Ex::Geo::Layer The root class for geospatial layers. A geospatial layer is a typically a subclass of a geospatial data (raster, vector features, or something else) and of this class. The idea is that this class contains visualization information (transparency, palette, colors, symbology, label placement, etc) for the data. Contains many callbacks that are fired as a result of user using context menu, making a selection, etc. Uses layer dialogs. =head2 Gtk2::Ex::Geo::DialogMaster A class which maintains a set of Glade dialogs taken from XML in DATA section. =head2 Gtk2::Ex::Geo::Dialogs A subclass of Gtk2::Ex::Geo::DialogMaster. Contains dialogs for Gtk2::Ex::Geo::Layer. =head2 Gtk2::Ex::Geo::Glue Typically a singleton class for an object, which manages a Gtk2::Ex::Geo::Overlay widget, a Gtk2::TreeView widgets, and other widgets of a geospatial application. The object also takes care of popping up context menus and other things. =head2 Gtk2::Ex::Geo::History Embedded in Gtk2::Ex::Geo::Glue. Input history a'la (at least attempting) GNU history that is used by Glue object with Gtk2::Entry. =head2 Gtk2::Ex::Geo::TreeDumper From http://www.asofyet.org/muppet/software/gtk2-perl/treedumper.pl-txt For inspecting layer and other objects. =head1 USAGE # these two geospatial layer classes are not included: use Geo::Raster; use Geo::Vector; use Gtk2::Ex::Geo; use Gtk2 '-init'; Glib->install_exception_handler(\&Gtk2::Ex::Geo::exception_handler); my($window, $gis) = Gtk2::Ex::Geo::simple (classes => [qw/Gtk2::Ex::Geo::Layer Geo::Vector::Layer Geo::Raster::Layer/]); Gtk2->main; =head1 DOCUMENTATION The documentation of Gtk2::Ex::Geo is included into the source code in doxygen format. The documentation can be generated in HTML, LaTeX, and other formats using the doxygen executable and the perl doxygen filter. The documentation is of this framework is available as a part of the documentation for Geoinformatica. =cut use strict; use warnings; use XSLoader; use Carp; use Glib qw/TRUE FALSE/; use Gtk2; use Gtk2::Gdk::Keysyms; # in Overlay use Gtk2::GladeXML; use Gtk2::Ex::Geo::DialogMaster; use Gtk2::Ex::Geo::Glue; BEGIN { use Exporter 'import'; our %EXPORT_TAGS = ( 'all' => [ qw( ) ] ); our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); our @EXPORT = qw( ); our $VERSION = '0.60'; XSLoader::load( 'Gtk2::Ex::Geo', $VERSION ); } ## @cmethod list simple(%params) # @brief Construct a simple GIS # # @param params named parameters: # - classes an anonymous list of layer classes # @return a list of window and a Glue object sub simple{ my %params = @_; my $home = Gtk2::Ex::Geo::homedir(); my $window = Gtk2::Window->new; $params{title} = 'Geoinformatica' unless $params{title}; $window->set_title($params{title}); $window->set_default_icon_from_file($params{icon}) if $params{icon} and -f $params{icon}; my $gis = Gtk2::Ex::Geo::Glue->new ( history => "$home.rash_history", resources => "$home.rashrc", main_window => $window ); if ($params{classes}) { for (@{$params{classes}}) { $gis->register_class($_); } } else { croak "usage: simple(classes => [qw/Gtk2::Ex::Geo::Layer ...other layer classes.../])"; } my $vbox = Gtk2::VBox->new (FALSE, 0); $vbox->pack_start ($gis->{toolbar}, FALSE, FALSE, 0); my $hbox = Gtk2::HBox->new (FALSE, 0); my $w = Gtk2::ScrolledWindow->new(); $w->set_policy("never", "automatic"); $hbox->pack_start ($w, FALSE, FALSE, 0); $w->add ($gis->{tree_view}); $hbox->pack_start ($gis->{overlay}, TRUE, TRUE, 0); $vbox->add ($hbox); $vbox->pack_start ($gis->{entry}, FALSE, FALSE, 0); $vbox->pack_start ($gis->{statusbar}, FALSE, FALSE, 0); $window->add ($vbox); $window->signal_connect("destroy", \&close_the_app, [$window, $gis]); $window->set_default_size(600,600); $window->show_all; return ($window, $gis); } ## @ignore sub exception_handler { if ($_[0] =~ /\@INC contains/) { $_[0] =~ s/\(\@INC contains.*?\)//; } my $dialog = Gtk2::MessageDialog->new(undef,'destroy-with-parent','info','close',$_[0]); $dialog->signal_connect(response => \&destroy_dialog); $dialog->show_all; return 1; } ## @ignore sub destroy_dialog { my($dialog) = @_; $dialog->destroy; } ## @ignore sub close_the_app { my($window, $gis) = @{$_[1]}; $gis->close(); Gtk2->main_quit; exit(0); } ## @ignore sub homedir { require Config; my $OS = $Config::Config{'osname'}; if ($OS eq 'MSWin32') { require Win32::Registry; my $Register = "Volatile Environment"; my $hkey = $::HKEY_CURRENT_USER; # assignment is just to get rid of a "used only once" warning $::HKEY_CURRENT_USER->Open($Register,$hkey); my %values; $hkey->GetValues(\%values); $hkey->Close; return "$values{HOMEDRIVE}->[2]$values{HOMEPATH}->[2]\\"; } else { return "$ENV{HOME}/"; } } 1;