http://www.perlmonks.org?node_id=163021

Baz has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I want to produce a map of a particular state, with each of the counties shaded with a color representing a certain statistic, such as rain fall and climate. Thing is I cant find a perl module relating to this. I guess the best way perl would achieve this is to produce a gif of the map and spit it to the client each time a request is made for a different stat. But maybe Javascipt could do this more effienctly by spitting the data to the client and then produce the map at the client side. ANyway perhaps if someone has experience at doing this they could advise me, Thanks.

Replies are listed 'Best First'.
Re: Generating a map using perl
by OeufMayo (Curate) on Apr 30, 2002 at 11:54 UTC

    I did a similar application a while ago and gave a Lightning Talk about it at YAPC::Eu 2001. I mainly used Image::Magick an GD to produce the maps, along with DBI to fetch the datas. You can find the presentation here.

    (the - rather badly written - code is available at the end of the presentation)

    -- 
    briac
Re: Generating a map using perl
by vroom (His Eminence) on Apr 30, 2002 at 14:06 UTC
    I'm guessing this isn't an approach you're likely to take unless it is for a major project, however I'll throw my 2 cents in.

    esri offers a product called IMS which is an internet map server. The communication between the client and server can occur through a servlet connector in which XML requests are passed back and forth, or an Active X connector. The product ships with an HTML client which is basically a whole lot of Javascript which builds and parses the XML requests and responses. The requests are then sent via javascript by submitting a form in a hidden frame. If the request is to generate an image the response contains the URL of the generated map. The client then replaces the map with the new map. This allows for dynamic things like zooming and panning to occur. For instance you select a bounding box within the client. It calculates the bounding box and sends the request to the map service which then generates the image. I've done a lot of things using LWP, HTML::Template for XML templating, and XML::Parser to read the resulting response.

    This reference to ArcXML might give you a feeling for its capabilities as well as some ideas for approaches you might want to use in your project.

      ArcIMS is indeed nice, but I find the javascript client hard to customize. I wrote some perl to generate ArcXML requests and parse the responses; then just linked to the URL of the generated image. Then I found an easier approach if I just wanted the image: ArcIMS supports the OpenGIS Web Map Server specification which let me specify everything I needed in the URL and returned the image. Simple, but it is not enabled by default.

      A cheaper solution with the 60% of the features that are needed by 90% of the people is the UMN MapServer. It is free, works well, and supports perl out of the box.

Re: Generating a map using perl
by delegatrix (Scribe) on Apr 30, 2002 at 13:07 UTC
    See MapStats. We use GD to generate these maps. As there are only 350 or so maps, they are not produced on the fly for each request.

      Where'd you get the source images (and whatever related positioning data)? I've been wanting to get somthing similar working for network monitoring (we've got several machines all over the country and it'd be a handy indicator to colour a state red or yellow to indicate problems).

        You might want to look at Big Brother, which has a mapping facility built in to its monitoring software.
        The source images were created in house, from TIGER, btw.
Re: Generating a map using perl
by mattr (Curate) on Apr 30, 2002 at 13:37 UTC
    another way to do it might be to use the gimp and perl-fu. Your program can call gimp commands programmatically and ought to be able to fill a region if you can give it a point inside each county. Though SVG or some postscript or pdf thing might look prettier.

    Just a wild guess but you might be able to even make a PDF template of the map and then replace colors at appropriate places in the program, if you are feeling adventurous.

Re: Generating a map using perl
by particle (Vicar) on Apr 30, 2002 at 12:22 UTC
    i suggest you contact hackmare in reference to svg. cool stuff.

    ~Particle *accelerates*

Re: Generating a map using perl
by Anonymous Monk on Apr 30, 2002 at 21:25 UTC
    The fedtstats.gov/thememaps example previously mentioned is your best direct example, since they're doing the same thing, with publicly available data: TIGER. Since they're a federal project, they might even be able to release their code. See the module Geo::TigerLine for how to handle (and get) the county border data. Although you can get county outlines as lat-long point pairs from other sources, TIGER is the new standard.

    My Perl generated state maps aren't area maps (yet), only point-plots from a flat-file database. I used GD.pm with basemaps from Color Landform Atlas by permission. My maps are online at EMAARES (points) (and with lines too).

    For those plotting points and wanting nice state basemaps see Sterner's Color Landform Atlas of the States <A HREF="http://fermi.jhuapl.edu/states/about.html#use">Rights and terms of use</A> and Birrell's tesselation of Sterner's mark 1 <A HREF="http://birrell.org/andrew/copyright.html">Rights and use</A> for the source of my basemaps.

    My other dataset is, like yours, weather related, although specifically related to radio propagation, and prognostic & diagnostic rather than climatalogical; I'm currently working from soundings, so also a point-plot situation. When I get it rich enough to be worth plotting areas instead of point values (from model grid fields), it will be contoured and not thematic (county based). For that one, I'm currently using as basemaps a radar plot, Sterner's B&w states, and Birrell's tiling of Sterner's previous maps.

    For Thematic work, GD.pm should be adequate. GD.pm has a limitation of 256 colors, a bit awkward with detailed basemaps, but that's enough for thematic work. Recent versions of GD.pm support PNG and JPEG, older versions support GIF and JPEG. For thematic, you'd probably prefer PNG. GD.pm can overlay data onto a basemap read from disk, or generate the whole map, on the fly in a CGI or mod_perl module just fine, as it can write the resulting PNG to STDOUT if instructed to do so. (Just be sure to provide the HTTP header first, and binmode if on WIntel. ActiveState has GD.pm.) I'd recommend saving the basemap(s) and overlaying data on the fly, as the state outlines are often large and nasty chains, while county outlines are more often internally simple -- but your state and server situation may vary, generating the whole thing on the fly may be logical for you. And as the fedstat Monk said, if there are few enough variants, pre-generating them all to disk trades space for time.

    bill -- n1vux at arrl.net

      Correction to my own comment -- GD.pm has a default of 256 colors, but latest versions have TrueColor 24bit palette option. -- bill / n1vux at arrl dot net