What is the advantage of using
geom = link_feat.GetGeometryRef() newfeature.SetGeometry(geom.Clone()) # or newfeature.SetGeometry(geom) layer.CreateFeature(newfeature)
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It only takes a minute to sign up.Sign up to join this community
From my experience the difference is subtle in that GetGeometryRef() will store a reference to the geometry which will be removed when the underlying feature is destroyed. If you use Clone() when storing the geometry you can access it and its methods even after destroying the feature.
To highlight this, suppose you want to open a shapefile, read a feature geometry, and print its WKT string.
# Open shapefile for reading and get layer object import ogr pth = r"C:\points.shp" driver = ogr.GetDriverByName("ESRI Shapefile") ds = driver.Open(pth,0) lyr = ds.GetLayer() # Get the first feature and print its WKT string feat = lyr.GetNextFeature() geom = feat.GetGeometryRef() print geom.ExportToWkt() # Destroy the feature and print its WKT again feat.Destroy() print geom.ExportToWkt()
The first print statement will successfully print the geometry's WKT string. That feature is then destroyed and, as a result, the following print statement will not work and Python may crash.
Now suppose the geom variable is set as follows:
geom = feat.GetGeometryRef().Clone()
In this case both print statements will be successful as the geom variable is storing a copy of the geometry itself. You can therefore destroy the feature and you will still be able to work with its geometry.
In your particular case, SetGeometry(geom) and SetGeometry(geom.Clone()) do the same thing since you do not destroy your link_feat. That said, were you to destroy link_feat before setting the newfeature geometry, neither of your SetFeature() calls would work because they themselves reference geom, which references link_feat, which would no longer exist.
Hope that helps. It really comes down to whether or not you want to work with the geometry after the feature has been destroyed.
In addition to @Ali's answer...
My guess is the
Clone() method calls for a deep copy of the object. Where the other method provides a shallow copy. The differences come as one only copies the memory pointer while the other copies the entirety and stores it in another memory location. Since OGR is a C++ library, you can check out this tutorial on C++ shallow vs deep copying to get an idea. To go further, there may be some custom logic in the copy constructor defined for the OGR geometry class, which wouldn't be replicated in the shallow copy (probably using the default constructor).
In any case, when you're just copying the reference and the original object is destroyed, the deconstructor is called and that bit of memory gets wiped, so your other variable would come up as a
None type. Doing a deep copy would be more taxing on the system since it allocates more memory for your application and then needs to maintain another pointer, but it helps keep a clear separation of concerns. If you wanted to edit the geometry or otherwise modify it,
Clone() is the better idea.
According to the docs, it seems there is no difference.
SetGeometry "updates the features geometry ... and does not assume ownership of the passed geometry, but instead makes a copy of it."
so, in the case of SetGeometry, both
do the same thing.