Compare commits

...

2 Commits

  1. 14
      HexGrid.pm
  2. 65
      HexGrid/Path.pm
  3. 42
      tests/paths.pl
  4. 11
      wiki-map.pl

@ -90,7 +90,7 @@ sub get_tile_at($this, $nw, $sw)
{ {
return $this->{regions}{$region}{tiles}{$nw}{$sw} if exists $this->{regions}{$region}{tiles}{$nw}{$sw}; return $this->{regions}{$region}{tiles}{$nw}{$sw} if exists $this->{regions}{$region}{tiles}{$nw}{$sw};
} }
croak "No tile at $nw,$sw"; return;
} }
sub get_tile_and_region_at($this, $nw, $sw) sub get_tile_and_region_at($this, $nw, $sw)
{ {
@ -98,7 +98,7 @@ sub get_tile_and_region_at($this, $nw, $sw)
{ {
return ($region->{tiles}{$nw}{$sw}, $region) if exists $region->{tiles}{$nw}{$sw}; return ($region->{tiles}{$nw}{$sw}, $region) if exists $region->{tiles}{$nw}{$sw};
} }
croak "No tile at $nw,$sw"; return;
} }
# Clones settings # Clones settings
@ -138,6 +138,16 @@ sub subgrid_for_tiles($this, @coords_list)
foreach my $coords (@coords_list) foreach my $coords (@coords_list)
{ {
my ($tile, $region) = $this->get_tile_and_region_at($coords->{nw}, $coords->{sw}); my ($tile, $region) = $this->get_tile_and_region_at($coords->{nw}, $coords->{sw});
unless ($tile)
{
carp "No tile at " . $coords->{nw} . "," . $coords->{sw} . ", skipping.";
next;
}
unless ($region)
{
carp "No region at " . $coords->{nw} . "," . $coords->{sw} . ", skipping.";
next;
}
unless(exists $subgrid->{regions}{$region->{name}}) unless(exists $subgrid->{regions}{$region->{name}})
{ {
my $clone = $region->clone; my $clone = $region->clone;

@ -15,6 +15,8 @@ has id => (is => 'ro', required => 1);
has style => (is => 'rw', default => sub { {} }); has style => (is => 'rw', default => sub { {} });
has colour => (is => 'rw', alias => 'color', default => 'blue'); has colour => (is => 'rw', alias => 'color', default => 'blue');
has css_class => (is => 'rw'); has css_class => (is => 'rw');
has starts_from => (is => 'rw');
has ends_to => (is => 'rw');
# Class # Class
@ -48,24 +50,66 @@ sub render($this, $grid, $svg)
return unless @{$this->tiles}; return unless @{$this->tiles};
my $g = $svg->g(id => $this->id, class => $this->css_class); my $g = $svg->g(id => $this->id, class => $this->css_class);
my ($x0, $x, $y0, $y);
my $current_tile = shift @{$this->tiles}; my $current_tile = shift @{$this->tiles};
# Single tile
unless (@{$this->tiles}) unless (@{$this->tiles})
{ {
my ($cx, $cy) = $grid->coords_of_centre($current_tile->nw, $current_tile->sw); my ($cx, $cy) = $grid->coords_of_centre($current_tile->nw, $current_tile->sw);
if($this->starts_from)
{
my ($x1, $y1) = $grid->coords_of_edge($current_tile->nw, $current_tile->sw, $this->starts_from);
if($this->ends_to)
{
my ($x2, $y2) = $grid->coords_of_edge($current_tile->nw, $current_tile->sw, $this->ends_to);
# Curve from starts_from to ends_to with the centre as control point
$g->path(d => "M $x1,$y1 Q $cx,$cy $x2,$y2",
stroke => $this->colour, style => $this->style, class => $this->css_class);
}
else
{
# line from starts_from to the centre
$g->line(x1 => $x1, y1 => $y1, x2 => $cx, y2 => $cy,
stroke => $this->colour, style => $this->style, class => $this->css_class);
}
}
else
{
if($this->ends_to)
{
# line from the centre to ends_to
my ($x2, $y2) = $grid->coords_of_edge($current_tile->nw, $current_tile->sw, $this->ends_to);
$g->line(x1 => $cx, y1 => $cy, x2 => $x2, y2 => $y2,
stroke => $this->colour, style => $this->style, class => $this->css_class);
}
else
{
$g->circle(cx => $cx, cy => $cy, $g->circle(cx => $cx, cy => $cy,
r => $this->{style}{'stroke-width'} // $DEFAULT_WIDTH, r => $this->{style}{'stroke-width'} // $DEFAULT_WIDTH,
fill => $this->colour, style => $this->style, class => $this->css_class); fill => $this->colour, style => $this->style, class => $this->css_class);
return;
} }
}
return $g;
}
my ($x0, $x, $y0, $y);
my $path_spec; my $path_spec;
my $previous_tile = $current_tile; my $previous_tile = $current_tile;
$current_tile = shift @{$this->tiles}; $current_tile = shift @{$this->tiles};
my $next_edge = get_edge_direction($previous_tile, $current_tile); my $next_edge = get_edge_direction($previous_tile, $current_tile);
($x0, $y0) = $grid->coords_of_centre($previous_tile->nw, $previous_tile->sw);
($x, $y) = $grid->coords_of_edge($previous_tile->nw, $previous_tile->sw, $next_edge); ($x, $y) = $grid->coords_of_edge($previous_tile->nw, $previous_tile->sw, $next_edge);
if($this->starts_from)
{
($x0, $y0) = $grid->coords_of_edge($previous_tile->nw, $previous_tile->sw, $this->starts_from);
$path_spec .= "M $x0,$y0 ";
my ($cx, $cy) = $grid->coords_of_centre($previous_tile->nw, $previous_tile->sw);
$path_spec .= curve_to($cx, $cy, $x, $y);
}
else
{
($x0, $y0) = $grid->coords_of_centre($previous_tile->nw, $previous_tile->sw);
$path_spec .= "M $x0,$y0 L $x,$y"; $path_spec .= "M $x0,$y0 L $x,$y";
}
my $previous_edge; # not defined yet my $previous_edge; # not defined yet
my $next_tile; # not defined yet my $next_tile; # not defined yet
@ -84,12 +128,23 @@ sub render($this, $grid, $svg)
$current_tile = $next_tile; $current_tile = $next_tile;
} }
# When loop is done (or if it was empty) $current_tile is the last tile # When loop is done (or if it was empty) $current_tile is the last tile
# $next_edge will be the last used edge, so use it's opposite for the source of last line # $next_edge is the last used edge, so use it's opposite for the source of last line
if($this->ends_to)
{
($x, $y) = $grid->coords_of_centre($current_tile->nw, $current_tile->sw);
my ($xe, $ye) = $grid->coords_of_edge($current_tile->nw, $current_tile->sw, $this->ends_to);
$path_spec .= curve_to($x, $y, $xe, $ye);
}
else
{
($x, $y) = $grid->coords_of_centre($current_tile->nw, $current_tile->sw); ($x, $y) = $grid->coords_of_centre($current_tile->nw, $current_tile->sw);
$path_spec .= " L $x,$y"; $path_spec .= " L $x,$y";
}
$g->path(d => $path_spec, fill => 'transparent', $g->path(d => $path_spec, fill => 'transparent',
stroke => $this->colour, style => $this->style, class => $this->css_class stroke => $this->colour, style => $this->style, class => $this->css_class
); );
return $g;
} }
1; 1;

@ -8,11 +8,11 @@ use Carp;
use Data::Dumper; use Data::Dumper;
my $MAP_SIZE = 3; my $MAP_SIZE = 5;
my $grid = HexGrid->new(defaults => { my $grid = HexGrid->new(defaults => {
style => { 'stroke-width' => 1, stroke => 'white' }, style => { 'stroke-width' => 1, stroke => 'white' },
show_coords => 0}); show_coords => 1});
my $region = $grid->make_region("TEST"); my $region = $grid->make_region("TEST");
for (my $nw=-$MAP_SIZE; $nw <= $MAP_SIZE; $nw++) for (my $nw=-$MAP_SIZE; $nw <= $MAP_SIZE; $nw++)
@ -23,13 +23,51 @@ for (my $nw=-$MAP_SIZE; $nw <= $MAP_SIZE; $nw++)
} }
} }
# generic "standard" path
$grid->make_path_from('test-id', $grid->make_path_from('test-id',
[[0,0], [1,0], [1,1], [2,0], [2,-1], [2,-2], [1,-2], [1,-1], [2,-1], [3,-1]], [[0,0], [1,0], [1,1], [2,0], [2,-1], [2,-2], [1,-2], [1,-1], [2,-1], [3,-1]],
colour => 'lime', css_class => 'path', style => { 'stroke-width' => 5 } colour => 'lime', css_class => 'path', style => { 'stroke-width' => 5 }
); );
# Single tile paths
$grid->make_path_from('point-id', [[-1,1]], $grid->make_path_from('point-id', [[-1,1]],
colour => 'cyan', css_class => 'path', style => { 'stroke-width' => 5 } colour => 'cyan', css_class => 'path', style => { 'stroke-width' => 5 }
); );
$grid->add_path(HexGrid::Path->new(id => 'point-starts', tiles => [$grid->get_tile_at(-2,2)],
starts_from => $HexGrid::DIR{n},
colour => 'yellow', css_class => 'path', style => { 'stroke-width' => 5 }));
$grid->add_path(HexGrid::Path->new(id => 'point-ends', tiles => [$grid->get_tile_at(-3,3)],
ends_to => $HexGrid::DIR{nw},
colour => 'blue', css_class => 'path', style => { 'stroke-width' => 5 }));
$grid->add_path(HexGrid::Path->new(id => 'point-starts-ends-1', tiles => [$grid->get_tile_at(-2,3)],
starts_from => $HexGrid::DIR{sw}, ends_to => $HexGrid::DIR{ne},
colour => 'magenta', css_class => 'path', style => { 'stroke-width' => 5 }));
$grid->add_path(HexGrid::Path->new(id => 'point-starts-ends-2', tiles => [$grid->get_tile_at(-1,2)],
starts_from => $HexGrid::DIR{sw}, ends_to => $HexGrid::DIR{n},
colour => 'orange', css_class => 'path', style => { 'stroke-width' => 5 }));
# starts_from/ends_to paths
$grid->add_path(HexGrid::Path->new(id => 'starts', starts_from => $HexGrid::DIR{ne},
tiles => [$grid->get_tile_at(4,-1), $grid->get_tile_at(5,-1), $grid->get_tile_at(5,0)],
colour => 'yellow', css_class => 'path', style => { 'stroke-width' => 5 }));
$grid->add_path(HexGrid::Path->new(id => 'ends', ends_to => $HexGrid::DIR{nw},
tiles => [$grid->get_tile_at(4,1), $grid->get_tile_at(4,0), $grid->get_tile_at(3,1)],
colour => 'blue', css_class => 'path', style => { 'stroke-width' => 5 }));
$grid->add_path(HexGrid::Path->new(id => 'starts-ends',
starts_from => $HexGrid::DIR{sw}, ends_to => $HexGrid::DIR{s},
tiles => [$grid->get_tile_at(2,3), $grid->get_tile_at(3,3), $grid->get_tile_at(4,3)],
colour => 'magenta', css_class => 'path', style => { 'stroke-width' => 5 }));
#loop
$grid->make_path_from('loop-id', $grid->make_path_from('loop-id',
[[-2,0], [-1,0], [-1,-1], [-2,-1], [-2,0]], [[-2,0], [-1,0], [-1,-1], [-2,-1], [-2,0]],
colour => 'red', css_class => 'path', style => { 'stroke-width' => 5 } colour => 'red', css_class => 'path', style => { 'stroke-width' => 5 }

@ -177,7 +177,6 @@ foreach my $page (values %{$location_query_results->{query}{pages}})
foreach my $coords (split /;/, $parsed_template->{named_params}{context_tiles}) foreach my $coords (split /;/, $parsed_template->{named_params}{context_tiles})
{ {
do { carp "Skipping bad spec: $coords"; next; } unless $coords =~ $coords_regex; do { carp "Skipping bad spec: $coords"; next; } unless $coords =~ $coords_regex;
# $location_with_context->add_tile($grid->get_tile_at($1, $2));
push @coords_list, { nw => $1, sw => $2 }; push @coords_list, { nw => $1, sw => $2 };
} }
my $location_grid = $grid->subgrid_for_tiles(@coords_list); my $location_grid = $grid->subgrid_for_tiles(@coords_list);
@ -197,8 +196,6 @@ foreach my $page (values %{$location_query_results->{query}{pages}})
# HexGrid::Image::DEBUG();
say STDERR "Getting Background image pages"; say STDERR "Getting Background image pages";
my $background_query_results = $mw->api({ action => 'query', my $background_query_results = $mw->api({ action => 'query',
prop => 'imageinfo', prop => 'imageinfo',
@ -286,6 +283,12 @@ foreach my $site_page_ref (values %{$site_query_results->{query}{pages}})
my $parsed_template = MWTemplate::Parse($site_content, $site_template_name); my $parsed_template = MWTemplate::Parse($site_content, $site_template_name);
next unless $parsed_template; next unless $parsed_template;
my ($nw,$sw) = split /,/, $parsed_template->{named_params}{coords}; my ($nw,$sw) = split /,/, $parsed_template->{named_params}{coords};
my $tile = $grid->get_tile_at($nw, $sw);
unless($tile)
{
carp "Coordinates of Site $site_name do not appear in the grid, skipping.";
next;
}
my $imageinfo_query_results = $mw->api({ action => 'query', my $imageinfo_query_results = $mw->api({ action => 'query',
prop => 'imageinfo', prop => 'imageinfo',
@ -304,7 +307,7 @@ foreach my $site_page_ref (values %{$site_query_results->{query}{pages}})
link => $site_url, link => $site_url,
description => $parsed_template->{named_params}{abstract} description => $parsed_template->{named_params}{abstract}
); );
$grid->get_tile_at($nw, $sw)->pin($pin); $tile->pin($pin);
} }
my (%path_specs); my (%path_specs);

Loading…
Cancel
Save