Generating GeoJSON with Python
If you've got an GDAL/OGR dev environment (headers, libs), you could radically simplify your code by using Fiona. To read features from a shapefile, add new attributes, and write them out as GeoJSON is just a handful of lines:
import fiona
import json
features = []
crs = None
with fiona.collection("docs/data/test_uk.shp", "r") as source:
for feat in source:
feat['properties'].update(...) # with your attributes
features.append(feat)
crs = " ".join("+%s=%s" % (k,v) for k,v in source.crs.items())
my_layer = {
"type": "FeatureCollection",
"features": features,
"crs": {
"type": "link",
"properties": {"href": "my_layer.crs", "type": "proj4"} }}
with open("my_layer.json", "w") as f:
f.write(json.dumps(my_layer))
with open("my_layer.crs", "w") as f:
f.write(crs)
Happily OGR can do this for you as both ogr.Feature
and ogr.Geometry
objects have ExportToJson()
methods. In your code;
fe.ExportToJson()
And since geojson FeatureCollection objects are simply dictionaries with a type
of FeatureCollection
and a features
object containing a list of Feature objects.
feature_collection = {"type": "FeatureCollection",
"features": []
}
feature_collection["features"].append(fe.ExportToJson())
The CRS object in a feature collection can be one of two types:
- A named CRS (e.g. an OGC URN or an EPSG code)
- A link object with a URI and a type such as "proj4"
Depending on your data format it's quite likely that the name is going to be a pain to get from OGR. Instead if we write the projection to a file on disk which we can reference with the URI. We can grab the projection from the layer object (which has several Export functions)
spatial_reference = dl.GetSpatialRef()
with open("data.crs", "wb") as f:
f.write(spatial_reference.ExportToProj4())
feature_collection["crs"] = {"type": "link",
"properties": {
"href": "data.crs",
"type": "proj4"
}
}
This is the simplest and easiest one in Fiona. you can set the SRS for output GeoJSON.
import fiona
from fiona.crs import from_epsg
source= fiona.open('shp/second_shp.shp', 'r', encoding = 'utf-8')
with fiona.open('tool_shp_geojson/geojson_fiona.json','w', driver ="GeoJSON", schema=source.schema, encoding = 'utf-8', crs=fiona.crs.from_epsg(4326)) as geojson:
geojson.write(feat)