[GIS] How to copy a geometry with Python OGR

ogrpython

I want to copy a geometry with Python OGR within a loop:

I tried the following, but I get ERROR 1: Empty geometries cannot be constructed

import ogr
import copy

d = ogr.Open('sampleData.geojson')
l = d.GetLayer()

for f in l: 
     gCurrent = f.GetGeometryRef()
     gPrevious = copy.copy(gCurrent)

I know I can't just assign gPrevious = gCurrent since it only references the geometry. But why is it trying to construct an empty geometry?

Best Answer

Don't expect OGR to be Pythonic. In fact, there is a large list of gotchas documented to describe these. Essentially, all of the variables are references to objects described in C++, so they often don't make sense with workflows in Python. Modules like copy only work on Python objects, which is why your example doesn't work as expected. You need to keep references to the features and the geometries alive, not just the geometry, otherwise it will crash.

For example, here is something that will calculate the union of current and previous features, showing the area of all three geometries:

l = d.GetLayer()

fPrevious = None
for fid in range(l.GetFeatureCount()):
    fCurrent = l.GetFeature(fid)
    if fPrevious:
        gCurrent = fCurrent.GetGeometryRef()
        gPrevious = fPrevious.GetGeometryRef()
        # Do something with the two geometries
        gNew = gCurrent.Union(gPrevious)
        print("Areas: %d vs %d vs %d" % (gPrevious.GetArea(), gCurrent.GetArea(), gNew.GetArea()))
    fPrevious = fCurrent

But if, for example, outside the loop did gNew = gCurrent.Union(gPrevious) it will crash since the references to the features have changed.