#!/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();