Gtk2-Ex-Geo-Graph

 view release on metacpan or  search on metacpan

lib/Gtk2/Ex/Geo/Graph.pm  view on Meta::CPAN

	    $miny = min($miny, $v->{point}->{Y});
	    $maxx = max($maxx, $v->{point}->{X});
	    $maxy = max($maxy, $v->{point}->{Y});
	}
    }
    return ($minx, $miny, $maxx, $maxy) if defined $minx;
    return ();
}

sub render {
    my($self, $pb, $cr, $overlay, $viewport) = @_;

    my @s = @{$self->selected_features()};
    my %selected = map { (ref($_) eq 'HASH' ? $_ : $_->[0].$_->[1] ) => 1 } @s;

    my $a = $self->alpha/255.0;
    my @color = $self->single_color;
    for (@color) {
	$_ /= 255.0;
	$_ *= $a;
    }

    $cr->set_line_width(1);
    $cr->set_source_rgba(@color);
    
    for my $v ($self->{graph}->vertices) {
	my @p = $overlay->point2surface($v->{point}->{X}, $v->{point}->{Y});
	for (@p) {
	    $_ = bounds($_, -10000, 10000);
	}
	$cr->arc(@p, $NODE_RAY, 0, 2*3.1415927);
	$cr->fill_preserve if $selected{$v};
	$cr->stroke;
    }
    for my $e ($self->{graph}->edges) {
	my($u, $v) = @$e;
	my @p = $overlay->point2surface($u->{point}->{X}, $u->{point}->{Y});
	my @q = $overlay->point2surface($v->{point}->{X}, $v->{point}->{Y});
	for (@p, @q) {
	    $_ = bounds($_, -10000, 10000);
	}
	$cr->move_to(@p);
	$cr->line_to(@q);
	$cr->set_line_width(3) if $selected{$u.$v};
	$cr->stroke;
	$cr->set_line_width(1) if $selected{$u.$v};
    }
    

lib/Gtk2/Ex/Geo/Graph.pm  view on Meta::CPAN


sub nodes_selected {
    my($selection) = @_;
    my($self, $gui) = @{pop()};
    return if $self->{ignore_cursor_change};
    my $selected = get_selected_from_selection($selection);
    $self->select();
    for my $v ($self->{graph}->vertices) {
	push @{$self->selected_features}, $v if $selected->{$v->{index}};
    }
    $gui->{overlay}->render;
}

sub open_links_dialog {
    my($self, $gui) = @{pop()};
    my $dialog = Gtk2::Dialog->new('Nodes of '.$self->name, undef, [], 'gtk-close' => 'close');
    $dialog->set_default_size(600, 500);
    $dialog->set_transient_for(undef);
    $dialog->signal_connect(response => sub { $_[0]->destroy });
    $dialog->show_all;
}

sub bounds {
    $_[0] < $_[1] ? $_[1] : ($_[0] > $_[2] ? $_[2] : $_[0]);
}

sub got_focus {
    my($self, $gui) = @_;
    my $o = $gui->{overlay};
    $self->{_tag1} = $o->signal_connect(
	drawing_changed => \&drawing_changed, [$self, $gui]);
    $self->{_tag2} = $o->signal_connect(
	new_selection => \&new_selection, [$self, $gui]);
    $self->{_tag3} = $o->signal_connect(
	key_press_event => \&key_pressed, [$self, $gui]);
    $gui->set_interaction_mode('Draw');
    $gui->set_interaction_geometry('Line');
    $o->{show_selection} = 0;
}

sub lost_focus {
    my($self, $gui) = @_;
    for (qw/_tag1 _tag2 _tag3/) {
	$gui->{overlay}->signal_handler_disconnect($self->{$_}) if $self->{$_};
	delete $self->{$_};
    }
}

sub drawing_changed {
    my($self, $gui) = @{$_[1]};
    my $drawing = $gui->{overlay}->{drawing};
    if ($drawing->isa('Geo::OGC::LineString') and $drawing->NumPoints == 2) {
	my $v1 = $self->find_vertex($gui, $drawing->StartPoint);
	my $v2 = $self->find_vertex($gui, $drawing->EndPoint);
	unless ($v1) {
	    $v1 = { point => $drawing->StartPoint->Clone };
	    $v1->{index} = $self->{index}++;
	    $self->{graph}->add_vertex($v1);
	}
	unless ($v2) {
	    $v2 = { point => $drawing->EndPoint->Clone };
	    $v2->{index} = $self->{index}++;
	    $self->{graph}->add_vertex($v2);
	}
	my $w = $drawing->Length;
	$self->{graph}->add_weighted_edge($v1, $v2, $w);
    }
    delete $gui->{overlay}->{drawing};
    $gui->{overlay}->render;
}

sub find_vertex {
    my($self, $gui, $point) = @_;
    my $d = -1;
    my $c;
    for my $v ($self->{graph}->vertices) {
	my $e = $point->Distance($v->{point});
	($c, $d) = ($v, $e) if $d < 0 or $e < $d;
    }
    return $c if $d/$gui->{overlay}->{pixel_size} < $NODE_RAY;
}

sub find_edge {
    my($self, $gui, $point) = @_;
    my $d = -1;
    my $c;
    for my $e ($self->{graph}->edges) {
	my $e2 = Geo::OGC::LineString->new;
	$e2->AddPoint($e->[0]->{point});
	$e2->AddPoint($e->[1]->{point});
	my $d2 = $point->Distance($e2);
	($c, $d) = ($e, $d2) if $d < 0 or $d2 < $d;
    }
    return $c if $d/$gui->{overlay}->{pixel_size} < $NODE_RAY;
}

sub new_selection {
    my($self, $gui) = @{$_[1]};
    my $selection = $gui->{overlay}->{selection};
    $self->select();
    $self->_select($gui, $selection);
    if ($self->{nodes_dialog}) {
	my $view = $self->{nodes_view};
	my $model = $view->get_model;
	my $selection = $view->get_selection;
	$self->{ignore_cursor_change} = 1;
	$selection->unselect_all;
	for my $v (@{$self->selected_features}) {
	    next if ref($v) eq 'ARRAY';
	    $model->foreach( \&select_in_selection, [$selection, $v->{index}]);
	    
	}
	delete $self->{ignore_cursor_change};
    }
    $gui->{overlay}->render;
}

sub select_in_selection {
    my($selection, $index) = @{pop()};
    my($model, $path, $iter) = @_;
    my($x) = $model->get($iter);
    if ($x == $index) {
	$selection->select_iter($iter);
	return 1;
    }

lib/Gtk2/Ex/Geo/Graph.pm  view on Meta::CPAN

	my $v = $self->find_vertex($gui, $selection);
	push @{$self->selected_features}, $v if $v;
	unless ($v) {
	    my $e = $self->find_edge($gui, $selection);
	    push @{$self->selected_features}, $e if $e;
	}
    }
}

sub key_pressed {
    my($overlay, $event, $user) = @_;
    my $key = $event->keyval;
    return unless $key == $Gtk2::Gdk::Keysyms{Delete};
    my($self, $gui) = @{$user};
    my @v;
    my @e;
    for my $v (@{$self->selected_features()}) {
	if (ref $v eq 'HASH') {
	    push @v, $v;
	} else {
	    push @e, ($v->[0], $v->[1]);
	}
    }
    $self->{graph}->delete_vertices(@v);
    $self->{graph}->delete_edges(@e);
    $self->select();
    $gui->{overlay}->render;
}

sub open_properties_dialog {
    my($self, $gui) = @_;
}

sub shortest_path {
    my($self) = @_;
    my($u, $v);
    for my $x (@{$self->selected_features()}) {

lib/Gtk2/Ex/Geo/Graph.pm  view on Meta::CPAN

	$u = $x,next unless $u;
	$v = $x unless $v;
	last;
    }
    $self->select();
    return unless $u and $v;
    print STDERR "sp $u->$v\n";
    my @path = $self->{graph}->SP_Dijkstra($u, $v);
    print STDERR "sp @path\n";
    $self->selected_features(\@path);
    #$gui->{overlay}->render;
}

## @ignore
sub min {
    $_[0] > $_[1] ? $_[1] : $_[0];
}

## @ignore
sub max {
    $_[0] > $_[1] ? $_[0] : $_[1];

t/00.t  view on Meta::CPAN

use Gtk2::Ex::Geo;

BEGIN { 
    use_ok('Gtk2::Ex::Geo::Graph');
};

Gtk2->init;

my($window, $gis) = setup (classes => [qw/Gtk2::Ex::Geo::Layer Gtk2::Ex::Geo::Graph/]);

$gis->{overlay}->signal_connect(update_layers => 
	sub {
	#print STDERR "in callback: @_\n";
	});

exit unless $ENV{GUI};

Gtk2->main;

sub setup{
    my %params = @_;

t/00.t  view on Meta::CPAN

    }

    # layer list
    my $list = Gtk2::ScrolledWindow->new();
    $list->set_policy("never", "automatic");
    $list->add($gis->{tree_view});
    
    # layer list and the map
    my $hbox = Gtk2::HBox->new(FALSE, 0);
    $hbox->pack_start($list, FALSE, FALSE, 0);
    $hbox->pack_start($gis->{overlay}, TRUE, TRUE, 0);
    
    # the stack
    my $vbox = Gtk2::VBox->new(FALSE, 0);
    $vbox->pack_start($gis->{toolbar}, FALSE, FALSE, 0);
    #$vbox->add($hbox);
    $vbox->pack_start($hbox, TRUE, TRUE, 0);
    $vbox->pack_start($gis->{entry}, FALSE, FALSE, 0);
    $vbox->pack_start($gis->{statusbar}, FALSE, FALSE, 0);

    $window->add($vbox);



( run in 0.380 second using v1.01-cache-2.11-cpan-cba739cd03b )