Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 106 lines (78 sloc) 3.41 KB
#!/usr/bin/env python3
# Display multiple polygons from a GeoJSON or Shapefile on a slippy map.
# Uses folium, which isn't available as a Debian package, so use pip.
import folium
# import shapefile # This nonobviously comes from the pyshp module
import gdal
from json import dumps
import random
import sys
def shapefile2geojson(infile, outfile, fieldname):
'''Translate a shapefile to GEOJSON.
Similar to: ogr2ogr -t_srs EPSG:4326 -f GeoJSON file.json file.shp
options = gdal.VectorTranslateOptions(format="GeoJSON",
gdal.VectorTranslate(outfile, infile, options=options)
print("Translated GEOJSON file", outfile)
def random_html_color():
r = random.randint(0,256)
g = random.randint(0,256)
b = random.randint(0,256)
return '#%02x%02x%02x' % (r, g, b)
def create_map(lat, lon, label, infile, fieldname):
'''Create a map and write it to index.html
jsonfile = infile
m = folium.Map(location=[lat, lon], zoom_start=7)
# Add some alternate tile layers
folium.TileLayer('Stamen Terrain').add_to(m)
folium.TileLayer('Stamen Toner').add_to(m)
def style_fcn(x):
'''The style function can key off x['properties']['NAME10']
which will be strings like 'Senate District 42'
but for now, let's just return random colors.
return { 'fillColor': random_html_color() }
def highlight_fcn(x):
return { 'fillColor': '#ff0000' }
gj = folium.GeoJson(jsonfile,
name="State %s Boundaries" % label,
# Don't include the field name in the tooltip.
# There doesn't seem to be a way to map to
# to '10' rather than ' Senate District 10';
# all folium allows is aliasing the field name
# and it will add a space even if the alias
# is empty.
# Optionally can pass a style
# style="font-family: serif;",
# Here's how to add a popup to the whole GeoJSON object.
# gj.add_child(folium.Popup('outline Popup on GeoJSON'))
# But it doesn't help in adding a popup that shows the current polygon.
# The only way seems to be to add each polygon as a separate feature:
# There may eventually be a way to do this:
print("Saved to index.html")
if __name__ == '__main__':
# Usage: polidistmap senate_districts.json Senate 34.3 -105.96 NAME
infile = sys.argv[1]
label = sys.argv[2]
lat = float(sys.argv[3])
lon = float(sys.argv[4])
fieldname = sys.argv[5]
if not infile.lower().endswith('json'):
jsonfile = '%s.json' % label
shapefile2geojson(infile, jsonfile, fieldname)
infile = jsonfile
create_map(lat, lon, label, infile, fieldname)
You can’t perform that action at this time.