Geo-Vector

 view release on metacpan or  search on metacpan

lib/Geo/Vector/Layer/Dialogs/Vertices.pm  view on Meta::CPAN

package Geo::Vector::Layer::Dialogs::Vertices;
# @brief 

use strict;
use warnings;
use Carp;
use Geo::Vector::Layer::Dialogs qw/:all/;

## @ignore
# vertices dialog
sub open {
    my($self, $gui) = @_;
    
    # bootstrap:
    my($dialog, $boot) = $self->bootstrap_dialog
	($gui, 'vertices_dialog', "Vertices from ".$self->name,
	 {
	     vertices_dialog => [delete_event => \&close_vertices_dialog, [$self, $gui]],
	     vertices_from_spinbutton => [value_changed => \&fill_vtv, [$self, $gui]],
	     vertices_max_spinbutton => [value_changed => \&fill_vtv, [$self, $gui]],	
	     vertices_close_button => [clicked => \&close_vertices_dialog, [$self, $gui]],
	 });
    
    if ($boot) {
	my $selection = $dialog->get_widget('vertices_treeview')->get_selection;
	$selection->set_mode('multiple');
	$selection->signal_connect(changed => \&vertices_activated, [$self, $gui]);
    }
	
    my $tv = $dialog->get_widget('vertices_treeview');
    my @c = $tv->get_columns;
    for (@c) {
	$tv->remove_column($_);
    }

    my $model = Gtk2::TreeStore->new(qw/Glib::String/);
    my $cell = Gtk2::CellRendererText->new;
    my $col = Gtk2::TreeViewColumn->new_with_attributes('Vertices', $cell, text => 0);
    $tv->append_column($col);
    $tv->set_model($model);

    fill_vtv(undef, [$self, $gui]);
}

##@ignore
sub close_vertices_dialog {
    my($self, $gui);
    for (@_) {
	next unless ref eq 'ARRAY';
	($self, $gui) = @{$_};
    }
    $self->hide_dialog('vertices_dialog');
    1;
}

##@ignore
sub fill_vtv {
    my($self, $gui) = @{$_[1]};

    my $overlay = $gui->{overlay};
    my $dialog = $self->{vertices_dialog};
    
    my $from = $dialog->get_widget('vertices_from_spinbutton')->get_value_as_int;
    my $count = $dialog->get_widget('vertices_max_spinbutton')->get_value_as_int;
    my $tv = $dialog->get_widget('vertices_treeview');
    my $model = $tv->get_model;
    $model->clear;

    delete $self->{GIDS};    
    my @data;
    my $vertex = 0;
    my $vertices = 0;
	
    my $features = $self->selected_features;
    for my $f (@$features) {
	my $geom = $f->Geometry();
	my $fid = $f->GetFID;
	my $name = $geom->GetGeometryName;
	my $vertices2 = $vertices;
	my $d = get_geom_data($self, $gui, $geom, \$vertex, \$vertices2, $from, $count);
	push @data,["Feature (fid=$fid) ($name)",$d,$fid] if $vertices2 > $vertices;
	$vertices = $vertices2;
	last if $vertices >= $count;
    }

    my $i = 0;
    for my $d (@data) {
	set_geom_data($self, $d, $i, $d->[2], $model);
	$i++;
    }
}

##@ignore
sub set_geom_data {
    my($self, $data, $path, $gid, $tree_store, $iter) = @_;
    
    my $iter2 = $tree_store->append($iter);
    $tree_store->set($iter2, 0 => $data->[0]);
    
    if ($data->[1]) {

	my $i = 0;
	for my $d (@{$data->[1]}) {
	    set_geom_data($self, $d, "$path:$i", "$gid:$d->[2]", $tree_store, $iter2);
	    $i++;
	}

    } else {

	$self->{GIDS}->{$path} = $gid;

    }
}

##@ignore
sub get_geom_data {
    my($self, $gui, $geom, $vertex, $vertices, $from, $count) = @_;

    return if $$vertices >= $count;
    
    if ($geom->GetGeometryCount) {
	
	my @d;
	for my $i2 (0..$geom->GetGeometryCount-1) {
	    
	    my $geom2 = $geom->GetGeometryRef($i2);
	    my $name = $geom2->GetGeometryName;
	    
	    my $vertices2 = $$vertices;
	    my $data = get_geom_data($self, $gui, $geom2, $vertex, \$vertices2, $from, $count);
	    push @d, [($i2+1).'. '.$name, $data, $i2] if $vertices2 > $$vertices;
	    $$vertices = $vertices2;
	    last if $$vertices >= $count;
	    
	}
	return \@d if @d;
	
    } else {

	my @rect = $gui->{overlay}->get_viewport; #_of_selection;
	#@rect = $gui->{overlay}->get_viewport unless @rect;
	my $s = $gui->{overlay}->{selection};
	my $a = ($s and $s->isa('Geo::OGR::Geometry'));
	my @d;
	for my $i (0..$geom->GetPointCount-1) {	    
	    my $x = $geom->GetX($i);
	    next if $x < $rect[0] or $x > $rect[2];
	    my $y = $geom->GetY($i);
	    next if $y < $rect[1] or $y > $rect[3];
	    if ($a) {
		my $point = Geo::OGR::Geometry->create('Point');
		$point->ACQUIRE;
		$point->AddPoint($x, $y);
		next unless $point->Within($s);
	    }
	    my $z = $geom->GetZ($i);
	    $$vertex++;
	    if ($$vertex >= $from) {
		push @d, [($i+1).": $x $y $z", undef, $i];
		$$vertices++;
	    }
	    last if $$vertices >= $count;
	}
	
	return \@d;
	
    }

    return undef;

}

##@ignore
sub vertices_activated {
    my $selection = $_[0];
    my($self, $gui) = @{$_[1]};

    $self->{SELECTED_GIDS} = [];
    for my $row ($selection->get_selected_rows) {
	push @{$self->{SELECTED_GIDS}}, $row->to_string;
    }

    $gui->{overlay}->update_image(\&show_vertices, $self) if @{$self->{SELECTED_GIDS}};
}

sub show_vertices {
    my($overlay, $pixmap, $gc, $layer) = @_;
    $gc->set_rgb_fg_color(Gtk2::Gdk::Color->new(65535, 0, 0));
    for my $selected (@{$layer->{SELECTED_GIDS}}) {
	next unless exists $layer->{GIDS}->{$selected};
	my @path = split(/:/, $layer->{GIDS}->{$selected});
	my $fid = shift @path;
	my $f = $layer->feature($fid);
	next unless $f;
	my $p = $f->Geometry()->Points;
	for (@path) {
	    $p = $p->[$_];
	}
	my @p = $overlay->point2pixmap_pixel(@$p);
	$pixmap->draw_line($gc, $p[0]-4, $p[1], $p[0]+4, $p[1]);
	$pixmap->draw_line($gc, $p[0], $p[1]-4, $p[0], $p[1]+4);
    }
}

1;



( run in 0.646 second using v1.01-cache-2.11-cpan-39bf76dae61 )