More

Methods to Convert .SVG File to GeoJSON

Methods to Convert .SVG File to GeoJSON


Question

How do I convert an SVG file to GeoJSON format?

Desired Outcome:

I want to make a choropleth map using something like D3.js, or any of the other libraries out there.

Challenge:

I have an SVG file that I was able to obtain from public domain of the administrative regions for a particular province of a particular country. I believe I need to convert that to GeoJSON before being able to use it in the libraries that I am aware of.


I just wrote a library that converts an SVG image to a (slightly-incorrect) GeoJSON.

Svg2geojson

It requires that you hand-edit your SVG to add two XML tags that associate an SVG location with a lat/long, and it provides a command-line tool to convert the file. It will even, if you like, take all the top-level groups (which is what Illustrator exports its layers as) and export them as separate files.

Usage

# First, install Node.js $ npm install svg2geojson -g # install globally for easy access to executable $ svg2geojson -h Usage: svg2geojson [options] file.svg Options: -t, --tolerance=0.1 Distance (world meters) to sample curves to. (default: 0.1) -l, --layers Split top-level groups into separate files. (default: one file) -o, --stdout Output GeoJSON to stdout. (default: write files with names based on the SVG/layer) -m, --minimal Make the GeoJSON as small as possible (not pretty). -p, --precision Number of decimal places to format JSON numbers to. (default:6, as GeoJSON recommends) -d, --debug Include ids for each SVG element in the features. (default: no properties) -v, --version Output the version of svg2geojson as the first line on stdout (0.7.0). -h, --help Show this help message. $ svg2geojson my.svg Wrote my.geojson

Limitations

  • Uses a naive/incorrect un-projection technique that assumes that a rectangular region of the image corresponds to a rectangular lat/long region. For example, on a rectangle about 1 mile wide by half a mile tall near San Francisco, the bottom edge is about 4 inches longer than the top edge. This was close enough for my needs.

  • Currently does not support SVG that uses paths with quadratic Bézier or elliptical arc commands. (I'm working on adding these.)


There is a command-line tool by Phrogz mentioned below that I have not checked out:

https://gis.stackexchange.com/a/245085/35596


To anyone that comes here, the answer is: "it is quite difficult (at least for an experienced programmer but inexperienced cartographer)." It requires a more-than-superficial understanding of how the Spacial Reference Systems (SRS) work. You more or less need to geocode your .SVG using something like QGIS. How that is done? Still no clue. But the answer is:

"You cannot simply convert SVG to GeoJSON, as SVG is missing the fundamental geo references."

If you would like to proceed, begin searching on how to georeference a DXF file.

How to compute parameters for QGIS Affine transformation?

Germán Carrillo's answer there is very useful.


You don't need to convert from SVG to GeoJSON to use the image for a choropleth in d3, although it may be necessary for other libraries.

The path information on the SVG file (there must be at least one path for each state/country/state/subdivision in your map) is enough to map data to your SVG image in d3.

Let me put it in another way: if you can do a d3.select on your original svg that will return just one path per state/country/region then you can use d3 to build a choropleth. This is usually the case when you have a map in SVG. It is actually simpler than using a GeoJSON file as you don't need to worry about space location, projection etc. You may even want to tweak the original SVG to add missing information (like state names, that you can add as DOM IDs or Classes) before using it with D3 but that's usually not necessary.

On the other hand, as it was said before, SVG have just path/lines information, not geographic/spatial information, so if you want to convert from SVG to GeoJSON then you need to ADD/MAP geolocation information to your SVG image. For example, you can convert from svg to JSON first, then calculate/add geolocation information (this will depend on the region you are mapping) and generate a GeoJSON from that. As far as I know there is no out of the box tool to do this job for you though.


I would try source the shapefile format instead of SVG for the province you're looking for. Since the data are public domain chances are good you can find it. Try http://www.naturalearthdata.com/ or ask a question here. Then convert from Shapefile to GeoJSON or TopoJSON; MapShaper is your friend. From this point D3 should be in reach (excellent tutorial Let's Make a Map)