#!/usr/bin/perl -w
use v5.12;
use Data::Dumper;
use strict;
use warnings;
use Graphics::ColorObject;
use Math::Trig;
use SVG::Parser;
use CSS;
use constant DATE_MIN => 1795;
use constant DATE_MAX => 2000;
use constant HUE_START => -60;
use constant HUE_LENGTH => 240;
use constant SATURATION => 0.7;
use constant LIGHTNESS => 0.6;
use constant LEGEND_XLABEL_SIZE => 60;
use constant LEGEND_XPOS => 245;
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' ],
'1816' => [ 'nl', 'be', 'lu' ],
'1840' => [ 'sn', 'dz' ],
'1849' => [ 'es' ],
'1852' => [ 'pt' ],
'1853' => [ 'co', 'mc' ],
'1857' => [ 'mx', 've' ],
'1858' => [ 'cu' ],
'1861' => [ 'it' ],
'1862' => [ 'pe', 'uy', 'br' ],
'1864' => [ 'ro' ],
'1865' => [ 'ec', 'cl' ],
'1867' => [ 'do' ],
'1868' => [ 'de' , 'bo' ],
'1869' => [ 'tr' ],
'1871' => [ 'sr', 'at', 'cz', 'sk', 'hr', 'li', 'si', 'me' ],
'1873' => [ 'rs' ],
'1874' => [ 'hu', 'se' ],
'1875' => [ 'ch' ],
'1876' => [ 'mu' ],
'1877' => [ 'ar' ],
'1878' => [ 'ba', 'sc' ],
'1881' => [ 'cr' ],
'1882' => [ 'no' ],
'1884' => [ 'cg', 'ci', 'bj', 'mr', 'ne', 'td' ],
'1885' => [ 'sv' ],
'1886' => [ 'fi' ],
'1888' => [ 'bg', 'mk' ],
'1891' => [ 'st' ],
'1893' => [ 'tn', 'ni' ],
'1895' => [ 'hn' ],
'1898' => [ 'dj' ],
'1899' => [ 'py', 'pr' ],
'1900' => [ 'gq', 'is' ],
'1901' => [ 'gn' ],
'1905' => [ 'mz', 'ao' , 'gw', 'cv' ],
'1906' => [ 'ph' ],
'1907' => [ 'dk', 'sm', 'gl', 'fo' ], # GL and FO as part of DK
'1910' => [ 'gt', 'mt', 'bz', 'bi', 'rw', 'cd' ],
'1911' => [ 'vn' ],
'1912' => [ 'th' ],
'1913' => [ 'cnx' ],
'1914' => [ 'km' ],
'1915' => [ 'pa' ],
'1916' => [ 'mn' ],
'1918' => [ 'ru' ],
'1919' => [ 'pl' ],
'1920' => [ 'ht' ],
'1922' => [ 'kh', 'ma', 'eh', 'kz', 'kg', 'tj', 'tm', 'uz', 'am', 'az', 'by', 'ee', 'ge', 'lv', 'lt', 'md', 'ua' ],
'1923' => [ 'ly', 'id', 'af' ],
'1924' => [ 'tg' ],
'1927' => [ 'ir' ],
'1930' => [ 'iq' ],
'1934' => [ 'sy', 'ad', 'lb' ],
'1947' => [ 'il' ],
'1948' => [ 'kp', 'al' ],
'1949' => [ 'kr' ],
'1951' => [ 'eg', 'bt', 'jp' ],
'1952' => [ 'jo', 'tw' ],
'1954' => [ 'sd', 'ss', 'in' ], # SS was part of SD
'1957' => [ 'gr', 'mo', 'tl', 'mg' ],
'1959' => [ 'mv' ],
'1960' => [ 'so', 'ga', 'bf', 'ml', 'cf' ],
'1961' => [ 'kw', 'cm', 'ae' ],
'1962' => [ 'et', 'er', 'ng' ],
'1963' => [ 'np', 'la' ],
'1964' => [ 'sa' ],
'1965' => [ 'gb' ],
'1967' => [ 'na', 'ie', 'za', 'ke', 'ug', 'tz', 'pk' ], # NA was part of ZA
'1968' => [ 'sg'],
'1969' => [ 'au', 'nz', 'bs', 'zw', 'bw', 'sz', 'bh', 'gd', 'dm', 'vc', 'kn' ],
'1970' => [ 'ca', 'lk', 'tt', 'zm', 'ls', 'pg', 'sb' ],
'1971' => [ 'bm', 'gy', 'my'], # BM is grouped with GY and MY on the NIST list on p.244
'1972' => [ 'gh', 'cy', 'fj', 'qa' ],
'1973' => [ 'bb', 'jm', 'nr' ],
'1974' => [ 'om', 'ag' ],
'1975' => [ 'to' ],
'1976' => [ 'sl', 'mw', 'gm'],
'1978' => [ 'tv' ],
'1981' => [ 'ye' ],
'1982' => [ 'bd' ],
'1984' => [ 'ki' ],
'1985' => [ 'bn' ],
'1988' => [ 'vu' ],
'2000' => [ 'lc' ]
};
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');
my $css_data = $css_container->{-cdata};
$css_data =~ s!/\*.*?\*\/!!gs;
$css->read_string( $css_data );
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 } " );
# say($css->output());
$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( '.oceanxx' )->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.') scale(0.8)'
);
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: #d0d0d0; 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();