3

I'm trying to perform a simple buffer on GeoJSNO file using python script. I am able to do it on shp file 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 gejson 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?

  • The error seems to be with creating the output file not reading the GeoJSON. I would check if in_lyr has a spatial ref – Ian Turton Sep 4 '17 at 7:48
  • 1
    What is GDAL version you are using? Only starting with GDAL 2.1.0, the GeoJSON driver supports updating existing GeoJSON files (gdal.org/drv_geojson.html). – Dmitry Baryshnikov Sep 4 '17 at 7:51
  • I use gdal 2.1.4 – user88484 Sep 4 '17 at 19:56
3

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')
  • Thanks gene, the geopandas solution works great. You just forgot to add the geojson driver in the last command: buffer.to_file('buffer.geojson', driver = 'GeoJSON'). Otherwise it will save it as shp file. – user88484 Sep 4 '17 at 19:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.