- SEE ALSO
- AUTHOR, COPYRIGHT AND LICENSE
GD::Map::Mercator - Create Mercator projected map images using GD
use GD::Map::Mercator; # # create a new basemap # my $newmap = GD::Map::Mercator->new( basemap_path => './basemaps', basemap_name => 'namer.gif', data_path => './WDB', min_lat => 15.5, min_long => -50, max_lat => 49.5, max_long => -26, width => 800, height => 500, background => '#FF0023', foreground => 'black', thickness => 3, silent => 1, ); # # or load an existing one # my $oldmap = GD::Map::Mercator->new( basemap_path => './basemaps', basemap_name => 'namer.gif' ); # # grab the image as an GD object # my $imager = $newmap->image(); # # draw some stuff on it # $imager->lineTo($here, $there); # # compute some pixels from lat/long # my ($x,$y) = $newmap->project($lat, $long); # # or compute lat/long from pixels # my ($lat, $long) = $newmap->translate($x, $y); # # carve out a section of the map # my $submap = $newmap->extract($minlat, $minlong, $maxlat, $maxlong); # # create a 1/2 size map # my $scaledmap = $newmap->scale(0.5); # # and save it # $scaledmap->save('scaledmap.gif');
Perl module for creating geographic map files with GD using a Mercator Projection.
Originally inspired by GD::Map, but significantly modified to
support the Mercator projection
optimize for performance (theres a lot of data to convert)
expose the map image for direct manipulation by the application
The geospatial data is sourced from the CIA World DataBank II repository at http://www.evl.uic.edu/pape/data/WDB/. Note that this database was created in the mid 1980's, so some of the political boundries are not current.
You'll need to download the WDB files and unpack them somewhere. The following files are contained in the archive:
africa-bdy.txt africa-cil.txt africa-riv.txt asia-bdy.txt asia-cil.txt asia-riv.txt europe-bdy.txt europe-cil.txt europe-riv.txt namer-bdy.txt namer-cil.txt namer-pby.txt namer-riv.txt samer-bdy.txt samer-cil.txt samer-riv.txt
Once unpacked, the files need to be filtered and converted via the wdb2merc script included in this bundle. wdb2merc
filters out some noisy data
converts the latitude/longitude coordinates into Mercator projected distances (for faster loading/computation)
writes the results out as binary records which can be loaded much faster, and compresses the data approx. 35%
Map images are rendered by specifying a bounding box defined by minimum and maximum latitude and longitudes, and the output image dimensions. The resulting image and associated configuration data can be saved for future use, avoiding the overhead of re-rendering by reloading the basemap image and its data.
To create a new basemap:
use GD::Map::Mercator; my $map = GD::Map::Mercator->new( basemap_path => "/data/basemaps", basemap_name => "testing", data_path => "/usr/local/wdb", width => $width, height => $height, max_long => 162, min_long => 65, max_lat => 70, min_lat => 14, background => '#FF0023', foreground => 'black', thickness => 3, );
This will create testing.png and testing.conf files in /data/basemaps containing a map of the area bounded by 14 deg latitude, 65 deg longitude, and 70 deg latitude, 162 deg longitude. The resulting image will attempt a best fit for the specified $width and $height, but will adjust dimensions as needed to preserve the Mercator scaling. Note that negative latitude values are south of the equator, and negative longitude is west of the meridian (Greenwich, GB). If the maximum longitude is negative and the minimum is positive, the map is assumed to cross the antipodal meridian.
The testing.conf file contains the relevant data for the created map image.
The created base map can be reused later by using the alternate constructor:
use GD::Map::Mercator; my $map = GD::Map::Mercator->new( basemap_path => "/data/basemaps", basemap_name => "testing", );
This constructor will attempt to initialize itself from the specified basemap file.
After creating or loading a basemap image, you can extract portions of the image, rescale the image, or decorate the image directly by getting the GD::Image object (or rather, a copy of the basemap image):
my $img = $map->image();
To compute pixel coordinates from latitude/longitude pairs:
my ($x,$y) = $map->project($lat, $long);
If the specified latitude or longitude is outside the range of the map, it returns undef values. Otherwise, the results are a pixel coordinate.
As a shortcut, multiple sets of lat/long points may be specified:
my @coords = $map->project($lat1, $long1, $lat2, $long2, $lat3, $long3, .. );
Once you have the map image, and coordinates, the usual GD methods can be used to manipulate the image.
Conversely, you can get the latitude/longitude and Mercator projected distances for given pixel coordinates:
my ($lat,$long, $merclat, $merclong) = $map->translate($x, $y);
This might be useful for interactive mapping applications.
The basemap configuration data, including hte bounding box latitude/longitude coordiates, the Mercator projected lat/long distance (in meters), and the image dimensions can also be retrieved:
my ($minlat, $minlong, $maxlat, $maxlong, $minmerclat, $minmerclong, $maxmerclat, $maxmerclong, $width, $height) = $map->config();
The basemap can also be rescaled:
my $newmap = $map->scale($scale);
This will create a new GD::Map::Mercator object zoomed in/out as needed, with updated configuration data.
Submaps can be extracted (and optionally scaled):
my $newmap = $map->extract($minlat, $minlong, $maxlat, $maxlong [, $scale ]);
Once you've created a new map via
extract you can save it as a basemap using
Refer to the classdoc output for detailed method descriptions.
EXAMPLESSome example maps can be viewed here.
This package was inspired by GD::Map, but this package uses a significantly different rendering technique, and exposes a different interface.
Geo::Mercator is used to compute the projections.
CIA World DataBank II datasets are at http://www.evl.uic.edu/pape/data/WDB/
US Zip Code Database: http://zips.sourceforge.net/
US Census TIGER/Line Data: http://www.census.gov/geo/www/tiger/
Geo::Coder::US and the several other Geo::Coder packages
Dean Arnold mailto:firstname.lastname@example.org
Copyright(C) 2008, Dean Arnold, Presicient Corp., USA
Permission is granted to use, copy, modify, and redistribute this software under the terms of the Perl Artistic license.