GD::Map - Perl extension for creating geographic map files with GD


  use GD::Map;
  my $m = GD::Map:new(
        basemap_path => "[required]",
        output_path => "[required]",
        verbose => 1,
  $m->add_object(id => "route", type => "line", color => "255,0,0");
        id => "route",
        start_long => 123.1,
        end_long => 124.7,
        start_lat => 49.3,
        end_lat => 37.5,

  my $filename = "$m->{filename}.png";
  my $w = $m->{map_width};
  my $h = $m->{map_height};


  Perl extension for creating geographic map files with GD


This library came out of work I did/do for In our systems we have lots of information about customers that come to our website. If they provide us with a zip/postal code, we have database lookup tables that can translate that into a lattitude and longitude value. We use this data for supplier selection logic, but it could also be used for other interesting things. We also have lookup tables that give approximate lattitude and longitude values for network subnets.

Anyway, we had a wealth of data, but I had never gotten around to putting any of this data on a map. I had done a lot of dynamic graphing, and drawing with GD, but Mapping seemed to be too hard, or at least I thought so.

I looked into GIS type things, and map projection logic, which all became waaay to complicated. I wasn't that interested in map projections, I just wanted to have a flat grid, that raw lattitude and longitude values translated easily onto.

The thing I had a problem with was where to get the basemap. Then I came across: - CIA World DataBank II

The files that Dave Pape created gave me exactly what I needed. These files are also needed to make this module work.



The first thing you need to do is download the WDB files and unzip them somewhere. For example /usr/local/wdb/. There should be a number of large text files (11 I think).

Then you need to create one (or multiple), basemaps.

 use GD::Map;

 my $m = GD::Map::new(
        basemap_path => "/data/basemaps",
        output_path => "/data/maps",

        map_name => "testing",
        data_path => "/usr/local/wdb",
        scale => 8,
        max_long => 162,
        min_long => 65,
        max_lat => 70,
        min_lat => 14,

This will create a testing.png file in /data/basemaps.

Making scale bigger will zoom in, smaller will zoom out.

A mapdata.conf file will also be created in /data/basemaps. This is crutial for GD::Map to function. The create_basemap function modifies this file.

NOTE!!!. Once the basemap file has been created, you need to scale it down 25%. You can do this in whatever editor you want, but the initial drawing is a little crunchy, so I usually use gimp or something to smooth things out. This seemed better than trying to incorporate Image::Magick in here, which sometimes gets cranky. Plus, basemaps do not get created very often so it is not much work. Maybe in the future I will add an option to do this for you if you have Image::Magick installed.


 my $m = GD::Map::new(
        basemap_path => "/data/basemaps",
        output_path => "/data/maps",

To create maps, after getting your map object, you need to define object types. They can be thought of as groups of similar objects and the order in which they are defined, determines the order in which they are drawn.

 $m->add_object(id => "travel", type => "line", color => "128,128,128");
 $m->add_object(id => "source", type => "dot", color => "0,0,0");
 $m->add_object(id => "dest", type => "dot", color => "255,0,0");

This will setup 3 different things. First we draw all the "travel" lines, then we draw the "source" dots, and finally the "dest" dots. This will make sure that the "source" dots are over top of the lines, and that the "dest" dots are on top of everything else, just in case there is some overlapping.

Finally we add the actual data. The order in which the data is drawn depends on the order of the objects, and then the order in which the data was added.

 $m->add_data(id => "travel", 
        start_long => 125, end_long => 90,
        start_lat => 62, end_lat => 55);
 $m->add_data(id => "travel", 
        start_long => 85, end_long => 90,
        start_lat => 30, end_lat => 55);

Since the travel objects are of type line, they need a start and end lat and long.

 $m->add_data(id => "source", start_long => 125, start_lat => 62);
 $m->add_data(id => "source", start_long => 85, start_lat => 30);
 $m->add_data(id => "dest", start_long => 90, start_lat => 55);

And since the source and dest objects are of type dot, they only need start lat and long.

Then we need to set our basemap.


And finally we draw!


GD::Map creates a unique filename using the data provided. Draw writes the file into the output_path you specified (in our example /data/maps).

Once draw() is done, you can find the filename, and height and width of the image in the map object.

 my $filename = "$m->{filename}.png";
 my $w = $m->{map_width};
 my $h = $m->{map_height};

If you have any questions or suggestions about this module please feel free to send me an email.


        id => whatever you want,
        type => line|dot|circle|image
        color => "r,g,b",


        id => should match add object id otherwise it will not draw,
        start_long => required,
        start_lat => required,
        end_long => required for line type things,
        end_lat => required for line type things,
        size => size (diameter) of circle or dot in pixels (default 4),
        image_path => path to image file if object type is "image",
        image_width => width of image at image_path,
        image_height => width of image at image_path,


None by default.

SEE ALSO - CIA World DataBank II


Chris Sutton, <>


Copyright 2006 by Chris Sutton

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.