From: Thierry Parmentelat Date: Sat, 22 Mar 2008 15:15:24 +0000 (+0000) Subject: restoring plot-latlong X-Git-Tag: PLEWWW-PLE.5.0-0~23 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=a292f1eb12522c91c71b1d7ab08fc29050cdb630;p=plewww.git restoring plot-latlong --- diff --git a/plot-latlong/.mapimages/Africa.png b/plot-latlong/.mapimages/Africa.png new file mode 100755 index 0000000..cd4cfea Binary files /dev/null and b/plot-latlong/.mapimages/Africa.png differ diff --git a/plot-latlong/.mapimages/Australia.png b/plot-latlong/.mapimages/Australia.png new file mode 100755 index 0000000..c0f6b04 Binary files /dev/null and b/plot-latlong/.mapimages/Australia.png differ diff --git a/plot-latlong/.mapimages/Belgium.png b/plot-latlong/.mapimages/Belgium.png new file mode 100755 index 0000000..335faca Binary files /dev/null and b/plot-latlong/.mapimages/Belgium.png differ diff --git a/plot-latlong/.mapimages/Canada.png b/plot-latlong/.mapimages/Canada.png new file mode 100755 index 0000000..b782efb Binary files /dev/null and b/plot-latlong/.mapimages/Canada.png differ diff --git a/plot-latlong/.mapimages/Caribbean.png b/plot-latlong/.mapimages/Caribbean.png new file mode 100755 index 0000000..3d37287 Binary files /dev/null and b/plot-latlong/.mapimages/Caribbean.png differ diff --git a/plot-latlong/.mapimages/CentralAmerica.png b/plot-latlong/.mapimages/CentralAmerica.png new file mode 100755 index 0000000..67ae790 Binary files /dev/null and b/plot-latlong/.mapimages/CentralAmerica.png differ diff --git a/plot-latlong/.mapimages/China.png b/plot-latlong/.mapimages/China.png new file mode 100755 index 0000000..c825fc0 Binary files /dev/null and b/plot-latlong/.mapimages/China.png differ diff --git a/plot-latlong/.mapimages/Europe.png b/plot-latlong/.mapimages/Europe.png new file mode 100755 index 0000000..c5728cb Binary files /dev/null and b/plot-latlong/.mapimages/Europe.png differ diff --git a/plot-latlong/.mapimages/France.png b/plot-latlong/.mapimages/France.png new file mode 100755 index 0000000..a1f3b2d Binary files /dev/null and b/plot-latlong/.mapimages/France.png differ diff --git a/plot-latlong/.mapimages/Germany.png b/plot-latlong/.mapimages/Germany.png new file mode 100755 index 0000000..a8bfa4b Binary files /dev/null and b/plot-latlong/.mapimages/Germany.png differ diff --git a/plot-latlong/.mapimages/Hawaii.png b/plot-latlong/.mapimages/Hawaii.png new file mode 100755 index 0000000..fa417f8 Binary files /dev/null and b/plot-latlong/.mapimages/Hawaii.png differ diff --git a/plot-latlong/.mapimages/India.png b/plot-latlong/.mapimages/India.png new file mode 100755 index 0000000..3c609dd Binary files /dev/null and b/plot-latlong/.mapimages/India.png differ diff --git a/plot-latlong/.mapimages/Italy.png b/plot-latlong/.mapimages/Italy.png new file mode 100755 index 0000000..2f7ba30 Binary files /dev/null and b/plot-latlong/.mapimages/Italy.png differ diff --git a/plot-latlong/.mapimages/Japan.png b/plot-latlong/.mapimages/Japan.png new file mode 100755 index 0000000..b4997d5 Binary files /dev/null and b/plot-latlong/.mapimages/Japan.png differ diff --git a/plot-latlong/.mapimages/Korea.png b/plot-latlong/.mapimages/Korea.png new file mode 100755 index 0000000..d2e3af3 Binary files /dev/null and b/plot-latlong/.mapimages/Korea.png differ diff --git a/plot-latlong/.mapimages/MalaysiaIndonesia.png b/plot-latlong/.mapimages/MalaysiaIndonesia.png new file mode 100755 index 0000000..3d8c0a0 Binary files /dev/null and b/plot-latlong/.mapimages/MalaysiaIndonesia.png differ diff --git a/plot-latlong/.mapimages/MiddleEast.png b/plot-latlong/.mapimages/MiddleEast.png new file mode 100755 index 0000000..eb8847f Binary files /dev/null and b/plot-latlong/.mapimages/MiddleEast.png differ diff --git a/plot-latlong/.mapimages/NOSEFI.png b/plot-latlong/.mapimages/NOSEFI.png new file mode 100755 index 0000000..a5c1de2 Binary files /dev/null and b/plot-latlong/.mapimages/NOSEFI.png differ diff --git a/plot-latlong/.mapimages/Netherlands.png b/plot-latlong/.mapimages/Netherlands.png new file mode 100755 index 0000000..1e87009 Binary files /dev/null and b/plot-latlong/.mapimages/Netherlands.png differ diff --git a/plot-latlong/.mapimages/NewZealand.png b/plot-latlong/.mapimages/NewZealand.png new file mode 100755 index 0000000..3750a0f Binary files /dev/null and b/plot-latlong/.mapimages/NewZealand.png differ diff --git a/plot-latlong/.mapimages/Philippines.png b/plot-latlong/.mapimages/Philippines.png new file mode 100755 index 0000000..18c0a3f Binary files /dev/null and b/plot-latlong/.mapimages/Philippines.png differ diff --git a/plot-latlong/.mapimages/SouthAmerica.png b/plot-latlong/.mapimages/SouthAmerica.png new file mode 100755 index 0000000..763db3f Binary files /dev/null and b/plot-latlong/.mapimages/SouthAmerica.png differ diff --git a/plot-latlong/.mapimages/UK.png b/plot-latlong/.mapimages/UK.png new file mode 100755 index 0000000..71dd394 Binary files /dev/null and b/plot-latlong/.mapimages/UK.png differ diff --git a/plot-latlong/.mapimages/USA100.png b/plot-latlong/.mapimages/USA100.png new file mode 100755 index 0000000..542c8b3 Binary files /dev/null and b/plot-latlong/.mapimages/USA100.png differ diff --git a/plot-latlong/.mapimages/USA200.png b/plot-latlong/.mapimages/USA200.png new file mode 100755 index 0000000..8dbafae Binary files /dev/null and b/plot-latlong/.mapimages/USA200.png differ diff --git a/plot-latlong/.mapimages/USA50-new.png b/plot-latlong/.mapimages/USA50-new.png new file mode 100755 index 0000000..1833e27 Binary files /dev/null and b/plot-latlong/.mapimages/USA50-new.png differ diff --git a/plot-latlong/.mapimages/World100.png b/plot-latlong/.mapimages/World100.png new file mode 100755 index 0000000..82b65a4 Binary files /dev/null and b/plot-latlong/.mapimages/World100.png differ diff --git a/plot-latlong/.mapimages/World50-new.png b/plot-latlong/.mapimages/World50-new.png new file mode 100755 index 0000000..99af593 Binary files /dev/null and b/plot-latlong/.mapimages/World50-new.png differ diff --git a/plot-latlong/.mapinfo b/plot-latlong/.mapinfo new file mode 100755 index 0000000..0e32ee5 --- /dev/null +++ b/plot-latlong/.mapinfo @@ -0,0 +1,35 @@ +MAP World World100.png 90 -170 -90 190 +MAP USA USA100.png 50 -125 24 -66 +MAP World50 World50-new.png 90 -170 -90 190 +MAP World100 World100.png 90 -170 -90 190 +MAP Africa Africa.png 38 -18 -35 52 +MAP Australia Australia.png -10 110 -45 155 +MAP Canada Canada.png 75 -142 41 -50 +MAP Caribbean Caribbean.png 27 -85 10 -59 +MAP CentralAmerica CentralAmerica.png 19 -93 5 -77 +MAP China China.png 54 73 18 135 +MAP Europe Europe.png 60 -15 35 30 +MAP Hawaii Hawaii.png 23 -161 18 -154 +MAP India India.png 36 68 5 110 +MAP Japan Japan.png 42 125 30 149 +MAP Korea Korea.png 44 124 34 131 +MAP MalaysiaIndonesia MalaysiaIndonesia.png 8 95 -11 135 +MAP MiddleEast MiddleEast.png 43 25 12 78 +MAP NewZealand NewZealand.png -34 166 -48 180 +MAP NOSEFI NOSEFI.png 72 4 55 32 +MAP Philippines Philippines.png 19 117 5 127 +MAP USA50 USA50-new.png 50 -125 24 -66 +MAP USA100 USA100.png 50 -125 24 -66 +MAP USA200 USA200.png 50 -125 24 -66 +MAP SouthAmerica SouthAmerica.png 13 -82 -56 -34 +MAP Belgium Belgium.png 51.6 2.5 49.4 6.6 +MAP France France.png 52 -5 42 9 +MAP Germany Germany.png 56 5 47 16 +MAP Italy Italy.png 48 6 35 19 +MAP Netherlands Netherlands.png 53.6 3.3 50.7 7.3 +MAP UK UK.png 59 -11 49 2 +# Calculated via trial and error. +PROJECTION USA50 ALBER 703.18 30.8 45.5 21.7 -99.9 232 390 +PROJECTION USA100 ALBER 1406.35 30.8 45.5 21.7 -99.9 464 781 +PROJECTION USA ALBER 1406.35 30.8 45.5 21.7 -99.9 464 781 +PROJECTION USA200 ALBER 2812.7 30.8 45.5 21.7 -99.9 929 1561 diff --git a/plot-latlong/CONFIG b/plot-latlong/CONFIG new file mode 100755 index 0000000..367c7fd --- /dev/null +++ b/plot-latlong/CONFIG @@ -0,0 +1,135 @@ +OVERVIEW + +This document describes the format of the .mapinfo configuration file, +which specifies the maps (and their projection parameters) available to +users of plot-latlong. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +SYNTAX + +The .mapinfo file has a simple line-oriented syntax. Each line +independently specifies some piece of information, and the order of the +lines is unimportant. Blank lines and lines starting with '#', which +may be preceded by whitespace, are ignored. All other lines must have +the syntax described below. + +We use a few conventions in the following description of the syntax. +Placeholders are denoted by words enclosed in angle brackets (e.g., +). All other words are literals that should be included +verbatim. The order of the words on each line is significant. One or +more whitespace characters should separate the individual words on each line. + +1) map definitions: + + MAP + + MAP World World100.png 90 -170 -90 190 + +These lines specify a map that is available to the user and supply some +basic attributes. + +The values are + + -- the name of the map; this is the name used for the '-m' + command line argument; the name must consist of letters, + digits, and underscores--no spaces are allowed + + -- the name of the PNG file containing the map image; the + path is relative to the location of the .mapimages directory, + so in most cases, the path can be a simple filename such as + "World100.png" + + + -- the lat/long of the top-left corner of the map image in + decimal degrees + + + -- the lat/long of the bottom-right corner of the map image in + decimal degrees + + +2) map projection parameters: + + PROJECTION + + PROJECTION USA50 ALBER 704.0 30.8 45.5 21.86 -99.9 232 388 + +These lines specify the parameters for nonlinear map projections. In +contrast, the values given in MAP lines are sufficient for linear map +projections. + +The values are + + -- the name of the map; this value should match the name used + in the corresponding MAP line + + -- the name of the nonlinear projection that will be + applied to the map; currently, if maps are not linear, they may + have one nonlinear projection specified for them; multiple + nonlinear projections for the same map are not allowed + + -- a variable set of values that provides the + actual parameters for the map projection; see below for details + + +The following describes the supported projections and their parameters. +Only one projection is currently supported: + + ALBER -- an Alber/Lambert projection; this is used by the USA maps + included in the distribution + + See the publication "Map Projections Used by the U.S. Geological + Survey Bulletin 1532" for details about this projection. + + parameters: + + + + where + + -- radius of sphere + -- standard parallel (lower) + -- standard parallel (upper) + -- origin latitude + -- origin longitude + -- the false easting amount + -- the false northing amount + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +TIPS & TRICKS + +Creating maps at different scales is both useful and relatively easy. +The following describes the steps for creating maps at different scales +using existing maps: + + 1) Use an image editing tool/package like ImageMagick or NetPBM to create + a map image at a different size; e.g., + + convert -scale '50%' .mapimages/World100.png .mapimages/World50.png + + would create a half-sized image using the 'convert' tool of ImageMagick. + + 2) Add a MAP line to .mapinfo; specifically, copy the MAP line of the + source map and change the map name and image path--don't change the + lat/long parameters; e.g., + + MAP World100 World100.png 90 -170 -90 190 + => MAP World50 World50.png 90 -170 -90 190 + + 3) For maps created with nonlinear projections, add a PROJECTION line to + .mapinfo; again, you may simply copy and tweak the PROJECTION line of + the source map; e.g., + + PROJECTION USA50 ALBER 704.0 30.8 45.5 21.86 -99.9 232 388 + PROJECTION USA100 ALBER 1408.0 30.8 45.5 21.86 -99.9 464 776 + PROJECTION USA200 ALBER 2816.0 30.8 45.5 21.86 -99.9 928 1552 + + For the Alber/Lambert projection, you need only change the , + , and parameters. These values change + in direct proportion to the change in size of the image itself. For + example, if the size is halved, then these parameter values should be + halved; if the size is doubled, then the values should be doubled. + In the above example, USA100 is the USA map at 100%; USA50 and USA200 + represent images at 50% and 200%, respectively. diff --git a/plot-latlong/README b/plot-latlong/README new file mode 100755 index 0000000..961224e --- /dev/null +++ b/plot-latlong/README @@ -0,0 +1,236 @@ + plot-latlong + + version 0.3 + + Jun 10, 2005 + + (c) 2003,2004,2005 CAIDA/UCSD + + (http://www.caida.org/tools/visualization/plot-latlong/index.xml) + + plot-latlong-info@caida.org + plot-latlong-bugs@caida.org + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +CHANGES + + * v0.3 released Jun 10, 2005 + + - added -i option to specify location of mapinfo file. + + * v0.2 released Apr 6, 2004 + + - added test-gd script for testing the GD installation + + * v0.1 released Oct 3, 2003 -- initial release + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +DESCRIPTION + +plot-latlong is a small command line tool written in perl for plotting +points on geographic maps given a list of latitude/longitude (lat/long) +pairs. This is aimed at situations in which + + * a moderate amount of accuracy and precision is sufficient + * a large number of locations need to be plotted (tens of thousands of + locations can be easily handled) + * the plotting needs to be automatable (from a shell script, for example) + * a lightweight tool (both small and with few dependencies) that just plots + points is sufficient + * ease of modification is important (so that special requirements can be + met) + +plot-latlong can handle nonlinear map projections (currently the +Alber/Lambert projection) and is intentionally minimalistic so that it can +serve as a building block. Users can build upon it in three ways: (1) add +new maps, (2) run the output images through packages like NetPBM to add +titles, etc., and (3) modify the source to change how points are drawn, to +add labels, etc. plot-latlong can also be used to simply compute the +mapping from lat/long to pixel coordinates (for a given map). These pixel +coordinates can then be fed to other programs to draw more elaborate +pictures. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +IMPLEMENTED FEATURES + +The list of implemented features is intentionally short: + + * drawing points at a user-specified size + * printing out just the pixel coordinates of input lat/long pairs + * support for linear projections (the relationship between pixels + and lat/long values is linear) + * support for the Alber/Lambert nonlinear projection + +The distribution includes over two dozen maps, covering the continents +and several country groups. Users can also supply maps to use, so +long as the projection type is supported and the projection parameters +are known. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +CAVEATS + +plot-latlong is unsuitable for applications demanding high accuracy. +Accuracy is likely no better than 5-10 miles--and even this is merely a +shot in the dark, since we're not in a position to rigorously determine the +accuracy of the generated plots. The following factors contribute to +increased inaccuracy: + + * the relative coarseness of the supplied maps + * unverified projection parameters for the supplied maps + * the USA maps, which use the Alber/Lambert projection, have parameters + calibrated by eye + * the geodetic datum assumed by the supplied maps is unknown to us + (http://www.colorado.edu/geography/gcraft/notes/datum/datum_f.html) + + + lat/long coordinate values are not universal; values are always + specified in some system, the datum, and mismatches in the assumed + datum can lead to the specification of physical locations that are + separated by as much as 1km + + + to assess whether plot-latlong will be sufficient for your needs, + you might try comparing the results with those from the + Tiger Map Server (http://tiger.census.gov/cgi-bin/mapbrowse-tbl/) + and MapQuest (http://www.mapquest.com/maps/latlong.adp). + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +REQUIREMENTS + +The requirements for running plot-latlong are: + + * UNIX-like operating system + * perl (http://www.perl.com) + * GD.pm (http://stein.cshl.org/WWW/software/GD/), which in turn requires + (see the README of GD.pm): + + + the gd graphics library (http://www.boutell.com/gd/) + + the PNG graphics library (http://www.libpng.org/pub/png/libpng.html) + + the zlib compression library (http://www.gzip.org/zlib/) + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +INSTALLATION + +No installation, per se, is required, but for the greatest convenience, +it is best to copy some files to your home directory, as in the following: + + cp plot-latlong $HOME/bin + cp -R .mapinfo .mapimages $HOME + +Assuming $HOME/bin is in your PATH, you can now run plot-latlong from +anywhere. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +USAGE + +plot-latlong reads lat/long values from stdin and writes a PNG to +stdout. The input should contain one pair of lat/long values per line +with the values separated by whitespace. Each coordinate should be a +decimal value, with negative values indicating south or west. Blank lines +and lines starting with the pound character ('#') are ignored. + +Command line options are + + -m specifies the name of a map to use (default: the first + map listed in .mapinfo: 'World'); see .mapinfo for the valid map names; + see the file CONFIG for a description of the .mapinfo format + + -s specifies the size of the points to draw (default: 1); + points are filled squares, and the size is the width in pixels + + (NOTE: Points drawn at the default size of 1 pixel may be hard to see + when only a few points are plotted. Use '-s 10' when plotting + a small number of points.) + + -c causes the pixel coordinates of each lat/long to be printed to stderr; + the coordinates (0, 0) are at the upper left corner, and values increase + to the right and down + + -i specifies an alternate location for .mapinfo (other + than in the current directory or $HOME). + +Examples: + +$ cat locations.txt | ./plot-latlong >plot.png + +$ ./plot-latlong -m USA -s 10 >plot.png </dev/null 2>xy.txt +$ head xy.txt +33.58 -86.52 250.44 168.946555555556 +33.59 -86.96 249.12 168.916611111111 +... + + +NOTE: You may safely ignore the following warning: + + gd-png warning: alpha channel not supported + + This warning says that the input map image had transparency information, + which some GD versions don't support. None of the map images included + in the distribution have transparency, but maps of your own may. + In such cases, use an image editing tool to remove the transparency + information. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +ACKNOWLEDGMENTS + +The code for handling the Alber/Lambert map projection is derived from +GTrace v1.0.0beta (http://www.caida.org/tools/visualization/gtrace), +which was written by Ram Periakaruppan. The included set of maps are also +derived from the GTrace distribution. GTrace redistributed these maps +with the permission of VisualRoute (http://www.visualroute.com), +the original source of the maps. + + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +LICENSE + +Copyright (C) 2003,2004,2005 The Regents of the University of California. +All Rights Reserved. + +Permission to use, copy, modify and distribute any part of this +plot-latlong software package for educational, research and non-profit +purposes, without fee, and without a written agreement is hereby +granted, provided that the above copyright notice, this paragraph +and the following paragraphs appear in all copies. + +Those desiring to incorporate this into commercial products or use +for commercial purposes should contact the Technology Transfer +Office, University of California, San Diego, 9500 Gilman Drive, La +Jolla, CA 92093-0910, Ph: (858) 534-5815, FAX: (858) 534-7345. + +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY +PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS +SOFTWARE, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. + +THE SOFTWARE PROVIDED HEREIN IS ON AN "AS IS" BASIS, AND THE +UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, +SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. THE UNIVERSITY +OF CALIFORNIA MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES +OF ANY KIND, EITHER IMPLIED OR EXPRESS, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A +PARTICULAR PURPOSE, OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE +ANY PATENT, TRADEMARK OR OTHER RIGHTS. + +The plot-latlong software is developed by the plot-latlong Team at the +University of California, San Diego under the Cooperative Association +for Internet Data Analysis (CAIDA) Program. Support for this work is +provided by the National Communications System (NCS) via NSF grant +ANI-0221172, entitled "Routing and Peering Analysis for Enhancing +Internet Performance and Security." diff --git a/plot-latlong/plot-latlong b/plot-latlong/plot-latlong new file mode 100755 index 0000000..d1f574e --- /dev/null +++ b/plot-latlong/plot-latlong @@ -0,0 +1,390 @@ +#!/usr/bin/perl -w + +############################################################################## +## Plots user supplied lat/longs on a user chosen map. +## +## plot-latlong reads lat/long values from stdin and writes a PNG to +## stdout. The input should contain one pair of lat/long values per line, +## with the values separated by whitespace. Blank lines and lines starting +## with the pound character ('#') are ignored. +## +## Command line options are +## +## -m specifies the name of a map to use (default: the first +## map listed in .mapinfo: 'World'); see .mapinfo for the valid map names; +## see the file CONFIG for a description of the .mapinfo format +## +## -s specifies the size of the points to draw (default: 1); +## points are filled squares, and the size is the width in pixels +## +## -c causes the pixel coordinates of each lat/long to be printed to stderr; +## the coordinates (0, 0) are at the upper left corner, and values increase +## to the right and down +## +## -i specifies an alternate location for .mapinfo (other +## than in the current directory or $HOME). +## +##---------------------------------------------------------------------------- +## +## The code for handling the Alber/Lambert map projection is derived from +## GTrace v1.0.0beta (http://www.caida.org/tools/visualization/gtrace), +## which was written by Ram Periakaruppan. The included set of maps are also +## derived from the GTrace distribution. GTrace redistributed these maps +## with the permission of VisualRoute (http://www.visualroute.com), +## the original source of the maps. +## +##---------------------------------------------------------------------------- +## +## Copyright (C) 2003,2004,2005 The Regents of the University of California. +## All Rights Reserved. +## +## Permission to use, copy, modify and distribute any part of this +## plot-latlong software package for educational, research and non-profit +## purposes, without fee, and without a written agreement is hereby +## granted, provided that the above copyright notice, this paragraph +## and the following paragraphs appear in all copies. +## +## Those desiring to incorporate this into commercial products or use +## for commercial purposes should contact the Technology Transfer +## Office, University of California, San Diego, 9500 Gilman Drive, La +## Jolla, CA 92093-0910, Ph: (858) 534-5815, FAX: (858) 534-7345. +## +## IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY +## PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +## DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS +## SOFTWARE, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF +## THE POSSIBILITY OF SUCH DAMAGE. +## +## THE SOFTWARE PROVIDED HEREIN IS ON AN "AS IS" BASIS, AND THE +## UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, +## SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. THE UNIVERSITY +## OF CALIFORNIA MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES +## OF ANY KIND, EITHER IMPLIED OR EXPRESS, INCLUDING, BUT NOT LIMITED +## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A +## PARTICULAR PURPOSE, OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE +## ANY PATENT, TRADEMARK OR OTHER RIGHTS. +## +## The plot-latlong software is developed by the plot-latlong Team at the +## University of California, San Diego under the Cooperative Association +## for Internet Data Analysis (CAIDA) Program. Support for this work is +## provided by the National Communications System (NCS) via NSF grant +## ANI-0221172, entitled "Routing and Peering Analysis for Enhancing +## Internet Performance and Security." +## +############################################################################## + +use strict; +use File::Basename; +use GD; +use Getopt::Std; +use vars qw($opt_m $opt_s $opt_c $opt_i); + +sub usage +{ + die "usage: cat datapoints | plot-latlong [-m ] [-s ] [-c] [-i ] >output.png\n"; +} + +if (not getopts('m:s:ci:')) +{ + usage(); +} + +my $DEBUG = 0; +my $PI = 3.141592654; + +my $point_size = $opt_s || 1; + +my $first_map; +my $map_directory; # directory containing map images +my %configuration; +my @mapinfo_locations = (".mapinfo", "$ENV{HOME}/.mapinfo"); +if ($opt_i) { + unshift @mapinfo_locations, $opt_i; +} +load_configuration(@mapinfo_locations); + +my $selected_map = $opt_m || $first_map; + +# lat/long of the upper-left and lower-right corners of the map image +my $map_top_lat; +my $map_top_long; +my $map_bottom_lat; +my $map_bottom_long; + +# parameters for linear projection: pixels per degree +my $map_lat_scale; +my $map_long_scale; + +# parameters for Alber projection (supplied by user): +# (in degrees) +my $R; # radius of sphere +#my $phi_1; # standard parallel +#my $phi_2; # standard parallel +#my $phi_0; # origin latitude +#my $lambda_0; # origin longitude +my $false_easting; # the false easting amount +my $false_northing; # the false northing amount + +# values for Alber projection calculated from user parameters: +# (in radians) +my $PHI_1; +my $PHI_2; +my $PHI_0; +my $LAMBDA_0; +my $N; +my $C; + +my $conversion_fn; # pointer to function for converting lat/long to (x, y) + +my $map = load_map($selected_map); + +############################################################################# + +my $green = $map->colorAllocate(64, 192, 64); +my $red = $map->colorAllocate(220, 64, 64); + +while (<>) +{ + chomp; + next if /^\s*$/; + next if /^\s*#/; + + # REQUIRE: -90 <= $lat <= 90 + my ($lat, $long) = split /\s+/; + my $adjusted_long = $long; + if ($long < $map_top_long) { + $adjusted_long += 360; + } elsif ($long > $map_bottom_long) { + $adjusted_long -= 360; + } + my ($x, $y) = &$conversion_fn($lat, $adjusted_long); + + print STDERR "$lat $long $x $y\n" if $DEBUG || $opt_c; + + if ($point_size == 1) + { + $map->setPixel($x, $y, $red); + } + else + { + my $half = int($point_size / 2); + my $left_x = $x - $half; + my $top_y = $y - $half; + $map->filledRectangle($left_x, $top_y, + $left_x + $point_size - 1, $top_y + $point_size - 1, + $red); + } +} + +print $map->png if not $DEBUG; + +############################################################################# +############################################################################# + +sub convert_latlong_to_xy_linear +{ + my ($lat, $long) = @_; + + my $lat_rel = $map_top_lat - $lat; + my $long_rel = $long - $map_top_long; + + return ($long_rel * $map_long_scale, $lat_rel * $map_lat_scale); +} + +############################################################################# + + +# See the publication "Map Projections Used by the U.S. Geological +# Survey Bulletin 1532" for details about this projection. +# +# However, the present coder does not know exactly which projection this +# function corresponds to in the USGS Bulletin. + +sub round { + my ($number) = @_; + return int($number + .5 * ($number <=> 0)); +} + +sub convert_latlong_to_xy_alber +{ + my ($lat, $long) = @_; + + my $phi = ($lat * $PI) / 180.0; + my $lambda = ($long * $PI) / 180.0; + + my $p = ($R * sqrt($C - 2.0 * $N * sin($phi))) / $N; + my $p_0 = ($R * sqrt($C - 2.0 * $N * sin($PHI_0))) / $N; + my $theta = $N * ($lambda - $LAMBDA_0); + + my $x = $false_easting + round($p * sin($theta)); + my $y = $false_northing - round($p_0 - $p * cos($theta)); + + return ($x, $y); +} + +############################################################################ + +sub load_map +{ + my ($name) = @_; + + if (not exists $configuration{"MAP $name"}) + { + die "ERROR: Map '$name' not found in map configuration file.\n"; + } + + print("OPEN: $name ", $configuration{"MAP $name"}, "\n") if $DEBUG; + + my $filename; + ($filename, $map_top_lat, $map_top_long, $map_bottom_lat, $map_bottom_long) + = split(/\s+/, $configuration{"MAP $name"}); + + my $path = "$map_directory/$filename"; + my $retval = new GD::Image($path) + or die "ERROR: Couldn't open map image '$path': $!\n"; + + my ($map_width, $map_height) = $retval->getBounds(); + + print("DIM: $map_width $map_height\n") if $DEBUG; + + $map_lat_scale = $map_height / ($map_top_lat - $map_bottom_lat); + $map_long_scale = $map_width / ($map_bottom_long - $map_top_long); + + print("SCALE: $map_lat_scale $map_long_scale\n") if $DEBUG; + + # -- projections -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + + if (not exists $configuration{"PROJECTION $name"}) + { + $conversion_fn = \&convert_latlong_to_xy_linear; + } + else + { + my @F = split(/\s+/, $configuration{"PROJECTION $name"}); + if ($F[0] eq "ALBER") + { + ($R, $false_easting, $false_northing) = @F[1,6,7]; + my ($phi_1, $phi_2, $phi_0, $lambda_0) = @F[2..5]; + + $PHI_1 = ($phi_1 * $PI) / 180.0; + $PHI_2 = ($phi_2 * $PI) / 180.0; + $PHI_0 = ($phi_0 * $PI) / 180.0; + $LAMBDA_0 = ($lambda_0 * $PI) / 180.0; + + $N = (sin($PHI_1) + sin($PHI_2)) / 2.0; + $C = cos($PHI_1) ** 2 + 2.0 * $N * sin($PHI_1); + + $conversion_fn = \&convert_latlong_to_xy_alber; + } + else + { + die "INTERNAL ERROR: unknown projection '$F[0]'\n"; + } + } + + return $retval; +} + +############################################################################# + +sub load_configuration +{ + foreach my $filename (@_) + { + if (-f $filename) + { + $map_directory = dirname($filename) . "/.mapimages"; + load_configuration_aux($filename); + return; + } + } + + die "ERROR: Couldn't find map configuration file; looked for: @_\n"; +} + +sub load_configuration_aux +{ + my ($filename) = @_; + + open CONFIG, "$filename" + or die "ERROR: Couldn't open map configuration file '$filename': $!\n"; + while () + { + chomp; + next if /^\s*$/; + next if /^\s*#/; + + my @F = split /\s+/; + if ($F[0] eq "MAP") + { + if ($#F == 6) + { + my ($top_lat, $top_long, $bot_lat, $bot_long) = @F[3..6]; + if (!check_coordinate($top_lat) + || !check_coordinate($top_long) + || !check_coordinate($bot_lat) + || !check_coordinate($bot_long)) + { + die "ERROR: Line $.: boundary coordinates are malformed in map configuration file.\n"; + } + + if ($top_lat < $bot_lat || $top_long > $bot_long) + { + die "ERROR: Line $.: boundary coordinates have wrong relations in map configuration file.\n"; + } + + $first_map = $F[1] if not defined $first_map; + $configuration{"MAP $F[1]"} = join(" ", @F[2..6]); + next; + } + } + elsif ($F[0] eq "PROJECTION") + { + if ($#F >= 2) + { + if ($F[2] eq "ALBER") + { + if ($#F == 9) + { + foreach my $x (@F[3..9]) + { + if (not check_number($x)) + { + die "ERROR: Line $.: projection parameters are malformed in map configuration file.\n"; + } + } + + $configuration{"PROJECTION $F[1]"} = join(" ", @F[2..9]); + next; + } + } + else + { + die "ERROR: Line $.: unknown map projection '$F[2]' in map configuration file.\n"; + } + } + } + else + { + die "ERROR: Line $.: unknown key '$F[0]' in map configuration file.\n"; + } + + die "ERROR: Line $. of map configuration file is malformed.\n"; + } + close CONFIG; +} + +############################################################################# + +sub check_coordinate +{ + my ($x) = @_; + + return $x =~ /^(\-?)\d+(\.\d+)?$/; +} + + +sub check_number +{ + return check_coordinate(@_); +}