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.
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.
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.
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.
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.