#!/usr/bin/perl use strict; use warnings; use File::Slurp; use GD; GD::Image->trueColor( 1 ); use Image::Size; use LWP::Simple; use Readonly; Readonly::Scalar my $LIST_URL => 'http://data.giss.nasa.gov/gistemp/station_data/station_list.txt'; Readonly::Scalar my $LIST_FILE => 'station_list.txt'; # Map: http://www.evl.uic.edu/pape/data/Earth/ Readonly::Scalar my $MAP_TEMPLATE => 'etopo-landmask.png'; Readonly::Scalar my $MAP_OUTPUT => 'giss-stations-map.png'; unless ( -e $LIST_FILE ) { my $station_list = get $LIST_URL; unless ( (defined $station_list) and length $station_list ) { die "Cannot retrieve station list\n" } write_file $LIST_FILE, \$station_list; } my $gd = GD::Image->new( $MAP_TEMPLATE ) or die "Cannot load map template: '$MAP_TEMPLATE'\n"; my ($lon_mapper, $lat_mapper); { my ($w, $h) = imgsize $MAP_TEMPLATE; $lon_mapper = sub ($) { ( $w / 2 ) + $_[0] * ( $w / 360 ) } ; $lat_mapper = sub ($) { ( $h / 2 ) - $_[0] * ( $h / 180 ) } ; } my $marker_color = $gd->colorAllocate( 0xff, 0x00, 0x00 ); my $circle_color = $gd->colorAllocate( 0xff, 0xff, 0x00 ); open my $list_fh, '<', $LIST_FILE or die "Cannot open '$LIST_FILE': $!"; while ( <$list_fh> ) { # next unless /cc=425/; # use only U.S. stations my $coord_str = substr $_, 58, 12; if ( $coord_str =~ /(-?\d+)\s+(-?\d+)/ ) { my ($lat, $lon) = ($1, $2); $_ /= 10 for $lat, $lon; my $x = $lon_mapper->( $lon ); my $y = $lat_mapper->( $lat ); $gd->ellipse( $x, $y, 4, 4, $circle_color ); $gd->line( $x, $y - 2, $x, $y + 2, $marker_color ); $gd->line( $x - 2, $y, $x + 2, $y, $marker_color ); } } close $list_fh; write_file $MAP_OUTPUT, { binmode => ':raw' }, \$gd->png; __END__