Gtk2-Ex-Geo-Graph
view release on metacpan or search on metacpan
lib/Gtk2/Ex/Geo/Graph.pm view on Meta::CPAN
125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
$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
238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362sub
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
372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
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
410411412413414415416417418419420421422423424425426427428429430
$u
=
$x
,
next
unless
$u
;
$v
=
$x
unless
$v
;
last
;
}
$self
->
select
();
return
unless
$u
and
$v
;
STDERR
"sp $u->$v\n"
;
my
@path
=
$self
->{graph}->SP_Dijkstra(
$u
,
$v
);
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];
456789101112131415161718192021222324use
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
=
@_
;
383940414243444546474849505152535455565758}
# 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.304 second using v1.01-cache-2.11-cpan-e5176c747c2 )