I have a need for a utility to translate shapefiles to SVG images, and I’m thinking of writing my own.  I’m aware of the one at carto.net.  I don’t like that it requires shp2pgsql, though; there are native Perl modules for parsing shapefiles so there should be no need for external executables with their own prerequisites.  Also, if I write my own I can put into it whatever features that I want… if they are within my capabilities.

If anyone stumbles across this post and has something that they’d like to see in such a utility, please leave a comment.

Update: Success!

Initial success came more easily than I anticipated, in only 90 lines of code using the Geo::Shapefile and SVG modules from CPAN.  Here is a map showing the Ozark Trail in Missouri that was generated from three separate shapefiles with a single run of the new program.  (The colors were modified after the fact with Inkscape.)  This exercised the handling of the three basic data types in shapefiles: points, polylines, and polygons.

Ozark Trail in Missouri; initial results from a new SVG generator

Ozark Trail in Missouri; initial results from a new SVG generator

To do list:

  • Accept source SRS specs on the command line, allowing multiple input files to have disparate coordinate systems.  DONE
  • Generate the results to an arbitrary SRS using Geo::Proj4.  That will be necessary to support the first item.  The initial test worked only because all 3 datasets use the same UTM zone as their coordinate system, and that same coordinate system was used as the basis for the rendering.  DONE
  • Support some specification of color and other rendering options, per source, on the command line.  (I anticipate that in most cases some post-processing with Inkscape will still be necessary, though.)  DONE
  • Optionally select subset of shapes by regex on arbitrary data fields.  DONEish
  • Support coloring of shapes by value of arbitrary data field.  DONE
  • Allow specification of a shapefile to use in scaling but not in rendering.  That would support independent production of layers to be later combined in Inkscape; they could all be scaled and translated according to the geometry of the base/largest layer to aid layering after the fact.  DONE
  • Include value from some data field in the SVG objects, either in the object ID or in another suitable field.
  • Specify a background color.
  • Take a name from a field to print in the output.  Getting labels to print in a legible manner that doesn’t interfere with the other items on a map is very problematical.  But if they’re already in the image as an output option, it’s easier to move them around in Inkscape than if you had to type them in by hand to boot.

Update 2:

The utility is coming along better that I anticipated, as testified to by the “DONE” tags in the to-do list.  After I tie up a few loose ends I’ll start another post to document what I have and how to use it.  I’ll post the code after I have a chance to tidy it up.

Final update:

As mentioned in the comments, I’ve posted this utility on GitHub.  All further development and documentation will be done there, but feel free to use this page for comments and suggestions.

One thing that I will note here is that the dependencies may not be quite as simple as I thought.  I import four Perl modules to use in the utlity, but they have some subdependencies that I wasn’t aware of.  I already had those on my system, so they weren’t flagged when I installed these other packages specifically for this project.  I’m installing a fresh testbed on a clean VM, and I’m starting to run into dependency hell.  I hate that.  I will try to carefully document at GitHub all the dependencies, once I have the testbed fully operational.

5 Responses to “Shapefile to SVG translator project”

  1. Alla Rob says:

    usually I do not postanything on sites. but I would love to tell all that this post extremely forced me to try and do therefore! really good post

  2. hgavin says:

    I’ve just used your script from github to generate SVGs from Tele Atlas shapefiles – it works great! Thanks very much for all your efforts.

  3. egb13 says:

    Okay, now I recall that git is what Linus wrote to replace that bitthingy.

    I’ve created a github account called “kbh3rd” with a repository called “shptosvg”. The perl script and an example shellscript that invokes it are the two files currently in the repository. Running “shptosvg.pl -h” gives a fairly lenghty usage summary.

    The perl script requires two modules from CPAN to run: Geo::Shapefile and SVG. No other external dependencies exist.

  4. egb13 says:

    It’s very close to ready for prime time. I just posted a map on Wikipedia that I made with it. I had to do very little tweaking after the fact. It will require some documentation about how to specify all those options on the command line; there’s quite a lot there, and I’ve found it easier to put it into a shell script where I can easily edit and tweak the parameters for successive runs until I’m happy with the result.

    I was considering creating a project on SourceForge. It would be my first, so I’m not bound to that site. I’m not familiar with GitHub. Why would I want to use that instead?

    BTW, the new map is at http://commons.wikimedia.org/wiki/File:Ogallala_saturated_thickness_1997-sattk97-v2.svg and is used in the Ogallala Aquifer article. (There, I’ve gone and blown my cover and linked this site to another of my online identities. Out of one closet and into another. ;)

  5. This would be extremely handy, would you mind throwing it up on GitHub, even un-tidied? I’m about ready to write my own Ruby version, but I’d rather hack yours.

Leave a Reply