A while back, I worked on a project with a company I’m working for and it eventually evolved into something I released to Perl’s open archive network, CPAN and chatted about for my first SPUG talk. Naturally, as the Conwaytistical Perl programmer I am, I figured why not write about it one more time for old times sakes. Generally speaking, Google has already found the documentation for the module which is all I really figure is necessary to explain it. The crazy thing is that people seem to be using this… a lot. Likely for the same reason I made it: there are no programmatic alternatives that I could find. With this unfortune comes the destruction of my inbox with questions and curiosities ranging from examples to the process I took for making this module in the first place. All things considered, I’m happy to see people using the module but it turns out I’m a little lazy and don’t like responding to strangers’ questions all that much. Born from that comes this page. When the forces of this are combined with the perldoc, I’m no longer needed and can feel much more at ease with the temperature of my shoulder as I ignore the trickle of emails that come to me. Lucky for you, I am a personal fan of direct examples that can be followed without the needless bloat of words, and this is what I’m going to (try to) do. The only predicate to this instruction set is that we will assume you are going to map the US. It’s possible to map the entire world, but we will only work with the US for now. Go USA!
Install It
Download Images
First, we need to download some images. I won’t explain how they are used as you can find all that info in the slide deck for the talk I gave but you do need them, trust me.
And should look like this (just bigger):

Configure It
‘width’ => 1600,
‘height’ => 1000,
‘x_adjust’ => -1605,
‘y_adjust’ => -1515,
‘processes’ => 1,
‘zoom’ => 6.405,
‘plot_size’ => 64,
‘transparent_bg’ => 1,
‘map’ => ‘/INPUT_DIR/usa-1650×875-mod.png’,
‘output’ => ‘/OUTPUT_DIR/heatmap-64px.gif’,
‘thumbnail’ => ‘/THUMB_DIR/heatmap-64px_thumb.gif’,
‘thumbnail_scale’ => .3,
# One method is to pass a statement handle
# (with appropriately named columns) to use
# use your database directly when generating images
’statement’ => DBI->connect(
qw(
dsn
user
pass
),
)->prepare( q{
SELECT latitude, longitude
FROM some_table_with_that_info_in_it
} ),
# Alternatively (and new), you can pass a
# reference of an array of hashes
# that represents the appropriate geo-data
# you wish to map.
‘geo_data’ => [
{
‘latitude’ => ‘0.0000′,
‘longitude’ => ‘0.000′,
},
],
};
This is the configuration I’ve used to make most of the examples I’ve given over time. For more information on the keys, RTFM.
Other things to keep in mind are
- The thumbnail scale is a percentage of the full output which is the size of the USA image you’ve downloaded.
- DBI is the only method you have (at this point) to get your lat/long data into the module. Only have a file? Then either your screwed (for now) or put it into SQLite or something similar.
- Update: The interface now supports the passing of an array of hashes.
- The options lacking format were meticulously derrived. Feel free to change them but I all but guarantee your image will end up looking like crap.
Run It
$map->$_( $config->{$_} ) foreach ( keys %$config );
$map->process();
View It
You should get a heat map image saved as defined by the output option and a thumbnail to the thumbnail option (if defined). You should expect something like this:

Pat yourself on the back, your done. Have fun.
See it in Action
Here are some of the places and resources that are available for further reading, some are simply links to people who have used this on a live, public site:
And if you have data in CSV, you can use DBD::CSV as DBI driver.
There is also a new version being indexed as this comment is written that will allow for array references to be passed. I’ll update this post eventually with that new information.
A FreeBSD port of the module was just made available as well.
http://www.freebsd.org/cgi/cvsweb.cgi/ports/graphics/p5-Image-Heatmap/
Is anyone using these maps to generate Google Maps tilesets ? If so I’d be interested in hearing about your experience.
I get this error when trying to run it, any ideas?
Image::Heatmap :: Map image (map) must be defined and have accomidating file permissions. at /usr/local/share/perl/5.10.0/Image/Heatmap.pm line 409.
Take a look at this link:
http://search.cpan.org/~wazzuteke/Image-Heatmap-0.557/lib/Image/Heatmap.pm#map
You must define where the original map image is (the image the plots will be set upon).
If you don’t already have a map, the examples from above use this one (of the US only):
http://internetsamhard.com/wp-content/uploads/2009/07/usa-1650×875-mod.png
Otherwise, the API for the current version is public here:
http://search.cpan.org/~wazzuteke/Image-Heatmap
And working examples are in this post as well.
The only thing is not clear at all is how to use other map images than the one provided. Lets say I want to do a city in Canada. How would this be done?
The short answer is this:
* The map attribute can be used to set the image of your preference.
* By default, using 0 for zoom, x_adjust and y_adjust will assume the map is of the entire world.
* Adjusting these three attributes respectively will let you pan and zoom into any particular country you wish to map, including Canada
* The examples in this article are examples of the US, which I tediously found the best combination of the three attributes for the particular map I used (and linked). As with any other map, simple adjustments can be made to find the right fit.
I would recommend starting with all the defaults of ‘0′ for the noted attributes. Zooming in a little here, a little there; adjusting the x and y coordinates a little here, a little there; eventually you will be able to find the precise location you are looking for with respect to the size, proportion and perspective of your map. Remember that the map must be of true scale of the geographical location you are looking to map as the coordinates are calculated from lat/long values and are immutable in terms of their location on the plane.
Good luck!