Join GitHub today
shptosvg.pl is a command-line utility written in Perl to render projected maps in SVG format from GIS data in one or more shapefiles . SVG is the technically superior format preferred for many kinds of maps on Wikipedia, which is my intended use.
I wanted a quick, easy way to render shapefiles in SVG format, and a quick google turned up shp2svg at carto:net. That looks interesting, but I did’t like that it requires shp2pgsql, an external executable from another project. Feeling up to a little programming challenge and figuring that if I wrote my own utility I could more easily add whatever features I wanted, I created is this project.
Note: I’m new to git, so proper versioning might be a little while in coming.
The earliest version posted here, used to create the map shown on the right, was posted on 2009-07-30. There’s still much to be done, but you can see that it already has some good basic functionality.
- Accepts source SRS specs on the command line, allowing multiple input files to have disparate coordinate systems.
- Generates the results projected to any SRS using Geo::Proj4.
- Works on multiple shapefiles at a single invocation, layering them in order into the SVG map.
- Supports specification of color and other rendering options, per source file, on the command line.
- Optionally select subset of shapes by regex on arbitrary attribute fields.
- Support coloring of shapes by value of an attribute field.
- Allow specification of a shapefile to use in scaling but not in rendering. That supports independent production of layers to be later combined in an SVG editor; they can all be scaled and translated according to the geometry of the base/largest layer to aid layering after the fact.
The FEATURES file in the repository may be more up-to-date than this page.
This list is a moving target, growing as more ideas occur:
- 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.
- Trace the outline of a group of shapes. This one won’t be trivial!
- Drawing piont shapes with more than just circles by addeing more built-in shapes to select from in the inputspec
- Support some way of importing shapes from external SVG files
- Depict a polygon shape with a point symbol located at the center of the polygon. E.g.: Show a campground icon for a state or national park instead of the outline of the park.
- Crop the results to a user-specified bounding-box in target coordinates.
The TODO file in the repository may be more up-to-date than this page.
The tool exists as a single Perl program (script, whatever) that relies on some third-party Perl modules to be installed, but it requires no external executables. All the modules are easily installed from CPAN, and if you use the cpan shell, those modules’ dependencies will be installed also.
There is one external library required that is not part of CPAN. The Geo::Proj4 module requires that the Proj4 library be pre-installed on the system before CPAN can build your local copy of the Perl module. That libary can be downloaded from trac.osgeo.org.
These four Perl modules are used directly by shptosvg.pl:
If you have the cpan utility installed on your system you will not have to download, build, and install those manually. A simple “cpan Geo::ShapeFile”, e.g., will install that module and any dependencies for you. (You may need to do that as root or Administrator to install in a global location.)
If you install manually, you may need to first download and install other dependencies that those modules themselves have. The ones that I am aware of are:
This utility seems to work perfectly for me on an up-tod-date Ubuntu 8.4 system with Perl version 5.8.8, but when the Perl interpreter itself exits, it spews a list of errors of the form:
Attempt to free unreferenced scalar: SV 0×85a03f4, Perl interpreter: 0×8153008 during global destruction.
As far as I can tell from searching for that on the intertubes, it is an error internal to the Perl interpreter and not an error per se in the Perl script. I’ve tried various means to narrow down what is causing the error, and it appears to be related to the SVG module. The shape objects I create with the SVG module go unreferenced in my code. I don’t think that should be a problem. If I assign the objects to a scalar on creation ($var = $g→polygon(…);) instead of leaving it unreferenced ($g→polygon(…);), the number of errors printed usually decreases, but they don’t totally disappear.
As a test, I downloaded and built the latest 5.10.0 version of Perl, and I installed the modules needed by this script. The error messages still occur with this version. Unfortunately, the SVG rendering is incorrect in some, but not all, of my test cases. That is indeed bothersome.
The XML being generated for these SVG renderings is not very complicated. I’m considering dispensing with the SVG module altogether and spitting out the SVG text on my own.
In the meantime, I’d be very interested if anyone can offer any insight or advice. Use the the GitHub messaging system if you have an account here, or leave a comment on my blog.