7

I have thousands of polygons in a layer. I am using following code to delete one of two intersecting polygons from a layer by checking geometry intersection of each polygon with all others. But it results in deleting both the intersecting polygons. How to delete only one instead of both? Also, this code is taking too long as there are many features in the layer. Is there any way to speed it up?

features=[f for f in layer.getFeatures()]
layer.startEditing()
for n in features:
    geom = n.geometry()
    if any(geom.intersects(init.geometry())==True for init in features if n.id()!=init.id()):
        layer.deleteFeature(n.id())
layer.commitChanges()
0

1 Answer 1

10

If you use != (in n.id()!=init.id()) inside the "if" statement, you compare the items (ex: comparing 2 to 1) you've compared before (ex: comparing 1 to 2). In this case, both items are deleted.

Use <= for id in the if statement like if n.id() <= init.id()). That also gives you a bit of speed. And using any in a such way is not reasonable. You probably will always get a True in your case.

One critical suggestion: Don't use layer.deleteFeature in editing mode, especially (1) in a for loop while comparing the features' ids in the same layer, especially (2) for a large dataset. That slows you down, and you may get unexpected results. Instead, use layer.dataProvider().deleteFeatures as below:

to_be_deleted = []
for n in layer.getFeatures():
    for init in layer.getFeatures():
        if n.id() <= init.id():
            g1 = n.geometry()
            g2 = init.geometry()           

            if g1.intersects(g2):
                to_be_deleted.append(n.id()) # or init.id()

layer.dataProvider().deleteFeatures(to_be_deleted)

Your question is not clear to me. But I think this answer gives you a hint.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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