diff --git a/HexGrid.pm b/HexGrid.pm index 2204850..a86fff4 100644 --- a/HexGrid.pm +++ b/HexGrid.pm @@ -64,9 +64,18 @@ sub get_tile_at($this, $nw, $sw) } croak "No tile at $nw,$sw"; } +sub get_tile_and_region_at($this, $nw, $sw) +{ + foreach my $region (values $this->{regions}->%*) + { + return ($region->{tiles}{$nw}{$sw}, $region) if exists $region->{tiles}{$nw}{$sw}; + } + croak "No tile at $nw,$sw"; +} -# Clones basic settings -# Grid defaults and regions (and by extension tiles) are tied to $this +# Clones settings +# Regions (and by extension tiles) are tied to $this +# Images are not imported sub subgrid_for_regions($this, @region_names) { my $subgrid = HexGrid->new @@ -74,7 +83,7 @@ sub subgrid_for_regions($this, @region_names) sideLength => $this->{sideLength}, width => $this->{width}, height => $this->{height}, - defaults => $this->{defaults}, + defaults => merge($this->{defaults}, {}), make_popups => $this->{make_popups}, popup_class => $this->{popup_class}, hidden_popups => $this->{hidden_popups}, @@ -85,8 +94,30 @@ sub subgrid_for_regions($this, @region_names) return $subgrid; } -sub subgrid_for_tiles($this, @coords) +sub subgrid_for_tiles($this, @coords_list) { + my $subgrid = HexGrid->new + ( + sideLength => $this->{sideLength}, + width => $this->{width}, + height => $this->{height}, + defaults => $this->{defaults}, + make_popups => $this->{make_popups}, + popup_class => $this->{popup_class}, + hidden_popups => $this->{hidden_popups}, + embed_images => $this->{embed_images} + ); + foreach my $coords (@coords_list) + { + my ($tile, $region) = $this->get_tile_and_region_at($coords->{nw}, $coords->{sw}); + unless(exists $subgrid->{regions}{$region->{name}}) + { + my $clone = $region->clone; + $subgrid->add_region($clone); + } + $subgrid->{regions}{$region->{name}}->add_tile($tile); + } + return $subgrid; } sub render($this) diff --git a/HexGrid/Region.pm b/HexGrid/Region.pm index 584fd73..64cce21 100644 --- a/HexGrid/Region.pm +++ b/HexGrid/Region.pm @@ -17,6 +17,16 @@ has name => (is => 'rw', required => 1); has defaults => (is => 'rw', default => sub { {} }); has id_suffix => (is => 'rw', default => '_region'); +sub clone($this) +{ + return HexGrid::Region->new + ( + name => $this->{name}, + defaults => merge($this->{defaults},{}), + id_suffix => $this->{id_suffix} + ); +} + sub add_tile($this, $tile) { $this->{tiles}{$tile->{nw}}{$tile->{sw}} = $tile; } sub make_tile_at($this, $nw, $sw, %tile_settings) { diff --git a/wiki-map.pl b/wiki-map.pl index efdf7e9..6dd1e07 100644 --- a/wiki-map.pl +++ b/wiki-map.pl @@ -56,8 +56,12 @@ $api_url // croak "Base API URL is required! Use --api-url to set"; my $grid = HexGrid->new(embed_images => $embed_images, defaults => { style => { 'stroke-width' => $border_width, stroke => $border_colour }, show_coords => $show_coords}); -my %region_grids; -my %region_grids_by_subregion; + +# my %region_grids; +my %regions_by_subregion; +my %region_grid_listings; +my %images_for_region_grids; + my $mw = MediaWiki::API->new(); $mw->{config}->{api_url} = $api_url; @@ -86,18 +90,8 @@ foreach my $page (values %{$region_query_results->{query}{pages}}) $region->{defaults}{colour} = $parsed_template->{named_params}{colour}; if($regiondir) { - $region_grids{$page->{title}} = HexGrid->new - ( - defaults => - { - style => { 'stroke-width' => $border_width, stroke => $border_colour }, - show_coords => $show_coords - }, - height => 300, - width => 300, - embed_images => $embed_images - ); - $region_grids{$page->{title}}->add_region($region); + # $region_grid_listings{$region->{name}} = [$region->{name}]; + $regions_by_subregion{$region->{name}} = $region->{name}; } push @tile_pages, "$page->{title}/Tiles"; @@ -129,8 +123,7 @@ foreach my $page (values %{$subregion_query_results->{query}{pages}}) if($regiondir) { my $region_name = $parsed_template->{positional_params}[0]; - $region_grids{$region_name}->add_region($subregion); - $region_grids_by_subregion{$subregion->{name}} = $region_grids{$region_name}; + $regions_by_subregion{$subregion->{name}} = $region_name; } push @tile_pages, "$page->{title}/Tiles"; @@ -157,37 +150,41 @@ foreach my $page (values %{$location_query_results->{query}{pages}}) next if $page->{title} =~ /^Category:/; my $parsed_template = MWTemplate::Parse($page->{revisions}[0]{'*'}, $location_template_name); next unless $parsed_template; + say STDERR "Processing location: $page->{title}"; + my $location = $grid->make_region($page->{title}); $location->{defaults}{colour} = $parsed_template->{named_params}{colour}; push @{$background_pages{"File:$parsed_template->{named_params}{background}"}}, $location; + my $region_name = $parsed_template->{positional_params}[1]; + $regions_by_subregion{$location->{name}} = $region_name; + push @location_continuations, sub { return unless $parsed_template->{positional_params}[0] =~ $coords_regex; my ($nw, $sw) = ($1, $2); $location->make_tile_at($nw, $sw); - my $region_name = $parsed_template->{positional_params}[1]; if($regiondir) { - $region_grids{$region_name}->add_region($location); - - $region_grids{$location->{name}} = HexGrid->new - ( - defaults => - { - style => { 'stroke-width' => $border_width, stroke => $border_colour }, - show_coords => $show_coords - }, - height => 300, - width => 300 - ); - my $location_with_context = $region_grids{$location->{name}}->make_region($location->{name}); - $location_with_context->add_tile($grid->get_tile_at($nw, $sw)); - foreach my $coords (split /;/, $parsed_template->{named_params}{context_tiles}) - { - do { carp "Skipping bad spec: $coords"; next; } unless $coords =~ $coords_regex; - $location_with_context->add_tile($grid->get_tile_at($1, $2)); - } + # $region_grids{$region_name}->add_region($location); + + # $region_grids{$location->{name}} = HexGrid->new + # ( + # defaults => + # { + # style => { 'stroke-width' => $border_width, stroke => $border_colour }, + # show_coords => $show_coords + # }, + # height => 300, + # width => 300 + # ); + # my $location_with_context = $region_grids{$location->{name}}->make_region($location->{name}); + # $location_with_context->add_tile($grid->get_tile_at($nw, $sw)); + # foreach my $coords (split /;/, $parsed_template->{named_params}{context_tiles}) + # { + # do { carp "Skipping bad spec: $coords"; next; } unless $coords =~ $coords_regex; + # $location_with_context->add_tile($grid->get_tile_at($1, $2)); + # } } }; } @@ -203,32 +200,34 @@ my $background_query_results = $mw->api({ action => 'query', iiprop => 'url' }) || carp $mw->{error}->{code} . ': ' . $mw->{error}->{details}; -# say STDERR Dumper(\%region_grids); +# say STDERR Dumper(\%background_pages); foreach my $page (values %{$background_query_results->{query}{pages}}) { if($page->{imageinfo}) { say STDERR "Processing image: $page->{title}"; $grid->add_image(HexGrid::to_id($page->{title}), $page->{imageinfo}[0]{url}); - foreach my $region (@{$background_pages{$page->{title}}}) + foreach my $subregion (@{$background_pages{$page->{title}}}) { - $region->{defaults}{image} = HexGrid::to_id($page->{title}); + $subregion->{defaults}{image} = HexGrid::to_id($page->{title}); if($regiondir) { - # say STDERR $region->{name}; - if(exists $region_grids{$region->{name}}) + my $region_name = $regions_by_subregion{$subregion->{name}}; + # say STDERR $page->{title} unless $region_name; + # say STDERR "$region_name"; + push @{$images_for_region_grids{$region_name}}, { - $region_grids{$region->{name}}->add_image(HexGrid::to_id($page->{title}), $page->{imageinfo}[0]{url}); - } - elsif(exists $region_grids_by_subregion{$region->{name}}) - { - $region_grids_by_subregion{$region->{name}}->add_image(HexGrid::to_id($page->{title}), $page->{imageinfo}[0]{url}); - } + name => HexGrid::to_id($page->{title}), + source => $page->{imageinfo}[0]{url} + }; } } } } +# say STDERR Dumper($grid->{images}); +# say STDERR Dumper(\%images_for_region_grids); + say STDERR "Getting Tile pages"; @@ -313,8 +312,24 @@ if($regiondir) { chdir $regiondir || croak "Couldn't chdir to $regiondir: $!"; my $extension = $html_document ? 'html' : 'svg'; - while(my ($region, $region_grid) = each %region_grids) + my %region_grid_listings; + while(my ($subregion, $region) = each %regions_by_subregion) { + push @{$region_grid_listings{$region}}, $subregion; + } + while(my ($region, $subregions) = each %region_grid_listings) + { + my $region_grid = $grid->subgrid_for_regions(@$subregions); + # say STDERR Dumper($images_for_region_grids{$region}); + if(exists $images_for_region_grids{$region}) + { + foreach my $image (@{$images_for_region_grids{$region}}) + { + # say STDERR Dumper($image); + $region_grid->add_image($image->{name}, $image->{source}); + } + } + open (my $region_fh, "> $region.$extension") or croak "Couldn't open $region.extension for writing: $!"; say $region_fh ($html_document ? wrap_in_html($region_grid) : $region_grid->render); @@ -325,12 +340,24 @@ if($regiondir) ### Subgrid testing -HexGrid::DEBUG(); -my $subgrid = $grid->subgrid_for_regions("Midhills", "Minev's Forest", "Naurardhon"); -my $svg = $subgrid->render; -open SUBGRID, ">subgrid_test.svg"; -say SUBGRID $svg; -close SUBGRID; +# HexGrid::DEBUG(); +# my $subgrid = $grid->subgrid_for_regions("Midhills", "Minev's Forest", "Naurardhon"); +# my $subgrid = $grid->subgrid_for_tiles +# ( +# { nw => 0, sw => 0 }, +# { nw => 1, sw => 0 }, +# { nw => 0, sw => 1 }, +# # { nw => 1, sw => 1 }, +# { nw => -1, sw => 0 }, +# { nw => -1, sw => 1 }, +# { nw => 1, sw => -1 } +# # { nw => 0, sw => -1 }, +# # { nw => -1, sw => -1 } +# ); +# my $svg = $subgrid->render; +# open SUBGRID, ">subgrid_test.svg"; +# say SUBGRID $svg; +# close SUBGRID; ###