Wednesday 30 May 2018

shapefile - Buffering GeoJSON file using Python?


I'm trying to perform a simple buffer on GeoJSON file using Python script. I am able to do it on a shapefile using Python script and on GeoJSON using QGIS fix distance buffer tool but I can't figure out how to do it on GeoJSON using Python script. I read many posts on it but none of them include working solely on GeoJSON. I also know that it is possible to convert GeoJSON to .shp but I need to work only with GeoJSON files.


My code that works for .shp file:


from osgeo import ogr

ds = ogr.Open(r'C:\vector files\tryyy.shp', 1)

in_lyr = ds.GetLayer()
out_lyr = ds.CreateLayer('new_buff44',in_lyr.GetSpatialRef(),ogr.wkbPolygon)
out_lyr.CreateFields(in_lyr.schema)
out_defn = out_lyr.GetLayerDefn()
out_feat = ogr.Feature(out_defn)
bufferDist = -0.00015075

for in_feat in in_lyr:

geom = in_feat.geometry()

out_feat.SetGeometry(geom)
for in_feat in in_lyr:

geom = in_feat.geometry().Buffer(bufferDist)
out_feat.SetGeometry(geom)
for i in range(in_feat.GetFieldCount()):
value = in_feat.GetField(i)
out_feat.SetField(i, value)
out_lyr.CreateFeature(out_feat)


del ds
print "finish"

When I change the file from shp to geojson in the org.Open line I get:



NoneType' object has no attribute 'CreateFields'



I thought that if I read vector file as OGR datasource object then it doesn't matter which format is the original vector file.


Can someone help me understand what I should change so that the code will work on GeoJSON files?



Answer




You don't need ogr here, nor PyQGIS. GeoJSON is a text format and you can use Shapely for buffering


Read the GeoJSON file


import json
from shapely.geometry import shape
with open('test.geojson') as geojson_file:
data = json.load(geojson_file)

Now data is a Python dictionary


print data.keys()
[u'crs', u'type', u'features']

# number of features in the GeoJSON file
print len(data['features'])
12

Buffer the features geometry with Shapely


for feat in features:
# transform to Shapely geometry (shape) and buffer
result = shape(feat['geometry']).buffer(10))

And you can save the result. But the easiest solution is to use GeoPandas



Read the GeoJSON file


import geopandas as gpd
test = gpd.read_file('G:/test.geojson')
test.head()
geometry id prof
0 LINESTRING (98343.63152166376 127733.349299224... 0 -300
1 LINESTRING (102765.6654736941 129425.499969790... 1 -350
2 LINESTRING (102462.0707786608 129444.182720253... 2 -300
3 LINESTRING (108072.8138189411 127543.072867221... 3 -300
4 LINESTRING (98944.76521158419 128898.571228531... 4 -300


Create the buffer file


buffer = test.copy()
buffer.geometry = buffer['geometry'].buffer(10)
buffer.head()
geometry id prof
0 POLYGON ((98338.20413879973 127724.9644054933,... 0 -300
1 POLYGON ((102768.850749055 129434.9713033329, ... 1 -350
2 POLYGON ((102322.0772607171 129216.1646869608,... 2 -300
3 POLYGON ((108079.2937964466 127533.9139139283,... 3 -300

4 POLYGON ((99110.01696110952 129288.1265286858,... 4 -300

Save the result


buffer.to_file('buffer.geojson')

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...