#!/usr/bin/perl -w
use strict;
use warnings;
use Graphics::ColorObject;
use Math::Trig;
use SVG::Parser;
use CSS;
use constant DATE_MIN => 1795;
use constant DATE_MAX => 1998;
use constant HUE_START => 0;
use constant HUE_LENGTH => 120;
use constant SATURATION => 0.7;
use constant LIGHTNESS => 0.6;
use constant LEGEND_XLABEL_SIZE => 60;
use constant LEGEND_XPOS => 0;
use constant LEGEND_YPOS => 1250;
use constant LEGEND_XOFF => 100;
use constant LEGEND_YOFF => 50;
use constant LEGEND_WIDTH => 2752.766;
use constant LEGEND_HEIGHT => 250;
my $dates = {
'1795' => [ 'fr' ],
'1820' => [ 'nl', 'be', 'lu' ],
'1840' => [ 'dz' ],
'1853' => [ 'co', 'mc' ],
'1858' => [ 'cu', 'es' ],
'1862' => [ 'br', 'mx' ],
'1863' => [ 'it', 'uy' ],
'1865' => [ 'cl', 'ec' ],
'1868' => [ 'pe', 'pr' ],
'1871' => [ 'at', 'li' ],
'1872' => [ 'de', 'pt' ],
'1875' => [ 'no', 'cz', 'sk' ],
'1876' => [ 'se', 'ch', 'hu', 'mk' ],
'1878' => [ 'mu', 'sc' ],
'1884' => [ 'sv', 'ro' ],
'1886' => [ 'ar', 'fi' ],
'1891' => [ 'bo', 'bg' ],
'1893' => [ 'ni', 'tn' ],
'1900' => [ 'is', 'py' ],
'1908' => [ 'dk', 'cr' ],
'1910' => [ 'bi', 'rw', 'cd' ],
'1911' => [ 'hn' ],
'1912' => [ 'dm' ],
'1915' => [ 'gt', 'sm', 'pa', 've' ],
'1916' => [ 'ph', 'sr' ],
'1918' => [ 'pl', 'mn' ],
'1920' => [ 'ht', 'mt' ],
'1922' => [ 'kh', 'ma' ],
'1923' => [ 'af', 'ly' ],
'1925' => [ 'ru', 'cn' ],
'1927' => [ 'ir' ],
'1930' => [ 'iq', 'tr' ],
'1934' => [ 'lb', 'sy' ],
'1946' => [ 'id', 'th' ],
'1948' => [ 'al', 'kr', 'il' ],
'1952' => [ 'jo', 'tw' ],
'1954' => [ 'in', 'sd' ],
'1957' => [ 'jp', 'gr' ],
'1959' => [ 'ci', 'gn' ],
'1960' => [ 'cg', 'ne', 'sn', 'tg', 'td', 'ga', 'bj', 'mr', 'ml', 'mg', 'cf', 'bf', 'so' ],
'1961' => [ 'cm', 'eg' ],
'1962' => [ 'et', 'ng' ],
'1963' => [ 'la', 'vn' ],
'1964' => [ 'sa' ],
'1965' => [ 'gb' ],
'1967' => [ 'ke', 'ug', 'tz', 'ie', 'pk' ],
'1968' => [ 'na', 'za' ],
'1969' => [ 'au', 'nz' ],
'1970' => [ 'ca' ],
'1990' => [ 'bd' ],
'1998' => [ 'jm' ]
};
my $css = new CSS( { 'parser' => 'CSS::Parse::Lite', 'adaptor' => 'CSS::Adaptor::Pretty' } );
my $svg=SVG::Parser->new()->parsefile($ARGV[0]);
my $css_container = $svg->getElementbyID('style_css_sheet');
$css->read_string( $css_container->{-CDATA} );
my $hue_start = deg2rad(HUE_START);
my $hue_length = deg2rad(HUE_LENGTH, 1);
foreach my $date( sort keys %$dates ) {
my $hue = $hue_start + (1-(DATE_MAX - $date)/(DATE_MAX - DATE_MIN)) * $hue_length;
$css->read_string( sprintf
"%s {\n\tfill: #%s;\n}\n",
join (', ', map { ".$_" } @{$dates->{$date}}),
Graphics::ColorObject->new_HSL([rad2deg($hue), SATURATION, LIGHTNESS])->as_RGBhex()
);
}
$css->read_string( ".us, .mm, .lr { fill: #333333 } " );
$css->get_style_by_selector( '.landxx' )->get_property_by_name( 'stroke' )->{values} = [new CSS::Value({value => 'black'})];
$css->get_style_by_selector( '.landxx' )->get_property_by_name( 'fill' )->{values} = [new CSS::Value({value => '#FFFFD0'})];
$css->get_style_by_selector( '.lake' )->get_property_by_name( 'stroke' )->{values} = [new CSS::Value({value => '#1821DE'})];
$css->get_style_by_selector( '.ocean' )->get_property_by_name( 'fill' )->{values} = [new CSS::Value({value => '#9ec7f3'})];
my $coastxx = $css->get_style_by_selector( '.coastxx' );
$coastxx->add_property( new CSS::Property( { property => 'stroke', value => '#1821DE' } ) );
$coastxx->add_property( new CSS::Property( { property => 'stroke-opacity', value => '1.0' } ) );
$coastxx->add_property( new CSS::Property( { property => 'stroke-width', value => '0.5' } ) );
my $legend = $svg->group(
id => 'legend',
transform => 'translate('.LEGEND_XPOS.','.LEGEND_YPOS.')'
);
my $gradient = $legend->gradient(
-type => "linear",
id => "legend_gradient"
);
my $legend_box = $legend->rectangle(
x => 0, y => 0,
width => LEGEND_WIDTH, height => LEGEND_HEIGHT,
rx => 10, ry => 10,
id => 'legend_box'
);
my $gradbox = $legend->rectangle(
x => LEGEND_XOFF, y => LEGEND_YOFF,
width => LEGEND_WIDTH - LEGEND_XOFF * 2, height => 100,
id => 'legend_grad'
);
{
my $span = scalar keys %$dates;
my $counter = 0;
foreach my $date( sort keys %$dates ) {
my $hue = $hue_start + (1-(DATE_MAX - $date)/(DATE_MAX - DATE_MIN)) * $hue_length;
$gradient->stop(
offset => sprintf( "%d%%", $counter / $span * 100 ),
'stop-color' => '#'.Graphics::ColorObject->new_HSL([rad2deg($hue), SATURATION, LIGHTNESS])->as_RGBhex(),
);
++$counter;
}
my $datespan = DATE_MAX - DATE_MIN;
foreach my $id(0..10) {
my $xpos = LEGEND_XOFF + $id / 10 * (LEGEND_WIDTH - LEGEND_XOFF * 2);
$legend->line(
x1 => $xpos - 2,
x2 => $xpos - 2,
y1 => LEGEND_YOFF,
y2 => 170,
'stroke-width' => '4',
);
$legend->text(
x => $xpos - LEGEND_XLABEL_SIZE,
y => 220,
fill => 'black',
'font-family' => 'sans-serif',
'fill-opacity' => 1,
'font-size' => LEGEND_XLABEL_SIZE,
'stroke' => 'none',
)->cdata(DATE_MIN + int($id/10 * $datespan) );
}
}
$css->read_string( "#legend { fill: blue; fill-opacity: .3; stroke: black; stroke-width: 10; } " );
$css->read_string( "#legend_grad { fill: url(#legend_gradient); fill-opacity: 1; stroke: black; stroke-width: 1; } " );
$css_container->CDATA( "\n".$css->output() );
print $svg->xmlify();