Skip to content

Instantly share code, notes, and snippets.

@perrygeo

perrygeo/topo2geojson.py

Last active Sep 17, 2020
Embed
What would you like to do?
TopoJSON to GeoJSON converter
"""
topo2geojson.py
Convert topojson to geojson
Example Usage:
python topo2geojson.py data.topojson data.geojson
The topojson tested here was created using the mbostock topojson CLI
created with --spherical coords and --properties turned on
Author: Matthew Perry (http://github.com/perrygeo)
Thanks to @sgillies for the topojson geometry logic
requires:
https://github.com/sgillies/topojson/blob/master/topojson.py
Next steps: how can this be generalized to a robust CLI converter?
"""
import json
import sys
from topojson import geometry
from shapely.geometry import asShape
topojson_path = sys.argv[1]
geojson_path = sys.argv[2]
with open(topojson_path, 'r') as fh:
f = fh.read()
topology = json.loads(f)
# file can be renamed, the first 'object' is more reliable
layername = topology['objects'].keys()[0]
features = topology['objects'][layername]['geometries']
scale = topology['transform']['scale']
trans = topology['transform']['translate']
with open(geojson_path, 'w') as dest:
fc = {'type': "FeatureCollection", 'features': []}
for id, tf in enumerate(features):
f = {'id': id, 'type': "Feature"}
f['properties'] = tf['properties'].copy()
geommap = geometry(tf, topology['arcs'], scale, trans)
geom = asShape(geommap).buffer(0)
assert geom.is_valid
f['geometry'] = geom.__geo_interface__
fc['features'].append(f)
dest.write(json.dumps(fc))
!#/bin/bash
echo "Convert ESRI File Geodatabase to a shapefile in Plate Carre/WGS84 (EPSG:4326)"
ogr2ogr -t_srs epsg:4326 -f "ESRI Shapefile" \
ecoregions_original.shp EcoregionSummaries3.gdb.zip EcoSums_ForMatt
echo "Convert shapefile to topojson with simplification"
# -s <tolerance> measured in steridians
# see http://en.wikipedia.org/wiki/Steradian#SI_multiples
# alternatively, can specify proportion of points kept
# e.g. --simplify-proportion 0.1 \
# rm temp*
for tolerance in 1E-7 1E-8 1E-9 1E-10
do
topojson --spherical \
--properties \
-s $tolerance \
-q 1E6 \
-o temp_$tolerance.topojson \
ecoregions_original.shp &&
# Convert it to GeoJSON
python topo2geojson.py temp_$tolerance.topojson temp_$tolerance.geojson &&
# Optionally, convert GeoJSON to any OGR data source
ogr2ogr -f "ESRI Shapefile" ecoregions_$tolerance.shp temp_$tolerance.geojson OGRGeoJson &
done
wait
@kadereub

This comment has been minimized.

Copy link

@kadereub kadereub commented Mar 23, 2020

This was really useful! Used it to plot some covid-19 data across South Africa

@kylepollina

This comment has been minimized.

Copy link

@kylepollina kylepollina commented Apr 9, 2020

5 years later I made a CLI from this to convert topojson to geojson. Check it out here: https://github.com/kylepollina/topo2geo
Thank you!

@EverWinter23

This comment has been minimized.

Copy link

@EverWinter23 EverWinter23 commented Apr 22, 2020

@kylepollina Yesss!!!!

@fferrin

This comment has been minimized.

Copy link

@fferrin fferrin commented Apr 27, 2020

I'm porting the whole TopoJSON suit from Mike Bostock. You can install it running:

pip install pytopojson

You can convert from TopoJSON either with the command-line tool:

python bin/topo2geo.py aruba=- < topojson.json

Or inside a script:

from pytopojson import feature

topojson = {
  "type": "Topology",
  "transform": {
    "scale": [0.036003600360036005, 0.017361589674592462],
    "translate": [-180, -89.99892578124998]
  },
  "objects": {
    "aruba": {
      "type": "Polygon",
      "arcs": [[0]],
      "id": 533
    }
  },
  "arcs": [
    [[3058, 5901], [0, -2], [-2, 1], [-1, 3], [-2, 3], [0, 3], [1, 1],
     [1, -3], [2, -5], [1, -1]]
  ]
}

feature_ = feature.Feature()
geojson = feature_(topojson, 'aruba')
@chitgoks

This comment has been minimized.

Copy link

@chitgoks chitgoks commented Sep 17, 2020

thank you. (off topic) also planning to use this in another platform. any chance you guys know java? there is no lib to convert topojson to geojson in java, sadly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.