Skip to content

add deleteVertices to QgsAbstractGeometry#63257

Open
ViperMiniQ wants to merge 15 commits intoqgis:masterfrom
ViperMiniQ:add-deletevertices
Open

add deleteVertices to QgsAbstractGeometry#63257
ViperMiniQ wants to merge 15 commits intoqgis:masterfrom
ViperMiniQ:add-deletevertices

Conversation

@ViperMiniQ
Copy link
Contributor

This PR implements deleteVertices for QgsAbstractGeometry classes and is the first part of #62669.
Unfortunately, some types of geometries can hold other types of geometries, so the method in QgsGeometry as tried in #62669 cannot properly handle all and that is why I decided for this approach.

Follow up PR will modify the QgsVertexTool to use the newly created functions which will avoid constant calls to detach and speed up vertices deletion on complex geometries as well as simplify the vertex tool delete function.

I need to add more tests for CoumpundCurve and CurvePolygon types before setting this PR as ready. Suggestions are welcome.

Even the special case of a "middle vertex" of a circularstring as added in #53960 is checked for.

(ping @uclaros and @3nids)

@github-actions github-actions bot added this to the 4.0.0 milestone Sep 18, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Sep 18, 2025

🪟 Windows Qt6 builds

Download Windows Qt6 builds of this PR for testing.
(Built from commit b1ad58b)

🍎 MacOS Qt6 builds

Download MacOS Qt6 builds of this PR for testing.
This installer is not signed, control+click > open the app to avoid the warning
(Built from commit b1ad58b)

@github-actions github-actions bot added the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label Oct 4, 2025
@qgis qgis deleted a comment from github-actions bot Oct 8, 2025
@github-actions github-actions bot removed the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label Oct 8, 2025
@github-actions github-actions bot added the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label Oct 23, 2025
@ViperMiniQ
Copy link
Contributor Author

I'll check on this shortly. I believe only some test cases need to be covered and apart from formatting issues, the rest should be good.

@github-actions github-actions bot removed the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label Oct 23, 2025
@qgis qgis deleted a comment from github-actions bot Oct 23, 2025
@ViperMiniQ
Copy link
Contributor Author

ViperMiniQ commented Nov 2, 2025

The purpose of this PR is to clearly define the behavior when multiple vertices are deleted from a geometry, since not all geometries can be modified as easily, there are some rules we need/want to follow.

This change also provides much better result when multiple vertices are deleted through the vertex tool. Currently, the vertex tool filters out the start and end points of polygons and removes selected points if the geometry would otherwise be deleted before reaching them.
None of that is needed as deleteVertices method handles all.

Another important aspect is the detach() call, which is now executed only once within this method. This results in a noticeable performance improvement.

To test the vertex tool modifications, you will need the following commit (you can also review the parts of the code that will become obsolete in the vertex tool, as they will no longer be needed):
ViperMiniQ@9380b8b

If this PR is accepted and merged, that commit will also become a PR.

With the vertex tool updated to use the deleteVertices method, we get a significant performance increase when deleting geometry vertices.


Testing dataset: ne_10m_land.zip

Test 1:
entire map would be selected (all features, all vertices) with the vertex tool and delete key would be pressed.

Time:
deleteVertices – ~15 seconds
deleteVertex – didn’t finish after 40 minutes, filled up the entire RAM and crashed the system (no other apps were running while the deletion was ongoing)


Test 2:
roughly half of Antarctica would be selected with the vertex tool and delete key pressed

Time:
deleteVertices – ~1.5 seconds
deleteVertex - ~25 seconds

Apart from speed, we will save enough energy to train better AIs to replace us :)


Creating a geometry in Python without registering it (this is important because this just modifies the geometry in place, so functions should have similar times).

QgsGeometry.fromWkt() and iterating deleteVertex vs a single call to deleteVertices (same dataset as above):

No of vertices deleted Time deleteVertex (s) Time deleteVertices (s)
270415 0.818599 0.598984
35369 3.966918 4.188773
31693 0.917808 0.90572
26548 0.316232 0.292192
26035 1.785067 1.838909
19457 0.084182 0.06668
12458 0.270085 0.265986
11639 0.201289 0.200791
7448 0.034886 0.028464
4998 0.014339 0.010227

Creating a layer and iterating its features calling deleteVertex and deleteVertices on feature.geometry():

No of vertices deleted Time deleteVertex (s) Time deleteVertices (s)
270415 26.589434 0.590351
35369 70.662433 3.793866
31693 17.344827 0.878986
26548 5.149592 0.282969
26035 34.360964 1.739295
19457 1.021254 0.065217
12458 4.921302 0.256777
11639 3.676333 0.188385
7448 0.438811 0.027785
4998 0.111671 0.009919

In current master, using the vertex tool is best being done on a single vertex, otherwise the tool might end up deleting more vertices than selected, there is no support for multiple vertices deletion on CompoundCurve geometries, for example (till now).

Here is how the tool behaves on master vs the behavior with deleteVertices:

Screencast_20251102_203328.webm
What is that? Notice how the first vertex behaves vs all the others, how many more vertices are being deleted than are being selected and how I am unable to delete vertices if I select the entire bottom part or if I select the entire left part.

Screencast_20251102_202711.webm
Here, for all mentioned cases, we end up with a much more expected result.

That weird geometry if you want to play with it:
CurvePolygon (CompoundCurve (CircularString (3 19, 0 22, 3 25, 6 28, 9 25),( 9 25, 14 20, 19 25 ),CircularString (19 25, 22 28, 25 25, 28 22, 25 19),(25 19, 20 14, 25 9),CircularString (25 9, 28 6, 25 3, 22 0, 19 3),(19 3, 14 8, 9 3),CircularString (9 3, 6 0, 3 3, 0 6, 3 9),(3 9, 8 14, 3 19) ))))

:)

@ViperMiniQ ViperMiniQ marked this pull request as ready for review November 2, 2025 20:06
@github-actions github-actions bot added stale Uh oh! Seems this work is abandoned, and the PR is about to close. and removed stale Uh oh! Seems this work is abandoned, and the PR is about to close. labels Nov 18, 2025
@qgis qgis deleted a comment from github-actions bot Nov 19, 2025
@github-actions github-actions bot added stale Uh oh! Seems this work is abandoned, and the PR is about to close. and removed stale Uh oh! Seems this work is abandoned, and the PR is about to close. labels Dec 4, 2025
@ViperMiniQ
Copy link
Contributor Author

ViperMiniQ commented Dec 4, 2025

Waiting for review.

I see merge conflicts, but those are in auto generated .py files.
As this is completely new code and some other PRs may also add new methods to classes, I will fix them after a review :)

@qgis qgis deleted a comment from github-actions bot Dec 4, 2025
@github-actions github-actions bot added the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label Dec 19, 2025
@ViperMiniQ
Copy link
Contributor Author

Woah, we're halfway there...

@github-actions github-actions bot removed the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label Dec 19, 2025
@qgis qgis deleted a comment from github-actions bot Dec 19, 2025
Copy link
Contributor

@uclaros uclaros left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a partial review, only for QgsAbstractGeometry, QgsGeometry and QgsLinestring.

Let's first decide on the final behavior regarding passing invalid vertex ids and what happens when a degenerate geometry is produced after a vertex deletion (fail vs clear geom).

/**
* Deletes vertices within the geometry
* \param positions list of vertex ids for vertices to delete
* \returns TRUE if delete was successful
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify what makes a successful delete?
How are invalid vertex ids handled?
How are degenerate geometry results handled (ie deleting one vertex of a 2 vertex linestring will result in an empty geometry or will return false?

Also needs \since QGIS 4.0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A successful deletion is when all the requested vertices are actually deleted (maybe some extra as well, to keep the geometry valid), but there is a difference between QgsAbstractGeometry and QgsGeometry.

If we reach a state where less than required vertices are present to form a valid geometry (linestring with less than 2 vertices, a polygon with less than 3), we clear the geometry at that point and return TRUE, same as in deleteVertex.

If any of the QgsAbstractGeometry vertices fails to be deleted, the method should return FALSE. This can potentially leave the geometry in an invalid state.

Invalid VertexIds are not handled at all in QgsAbstractGeometry, the same way they are not handled in the deleteVertex method. Were you thinking of a check to see if the requested VertexIds actually belong to the the geometry? For example, right now, neither deleteVertex or deleteVertices care for the part_id or ring_id in case of linestring, they only use the vertex bit of the VertexId.

Calling deleteVertices on a QgsGeometry should always produce a valid geometry – it internally calls the QgsAbstractGeometry::deleteVertices and if it gets a FALSE from it, it resets the geometry to whatever it was before the call (in QgsGeomtry::deleteVertices, we copy the geometry so we can reset to it if the deletion of any vertices fails).

@ViperMiniQ ViperMiniQ closed this Jan 12, 2026
@ViperMiniQ ViperMiniQ reopened this Jan 12, 2026
@ViperMiniQ ViperMiniQ closed this Jan 12, 2026
@ViperMiniQ ViperMiniQ reopened this Jan 12, 2026
@github-actions github-actions bot added the stale Uh oh! Seems this work is abandoned, and the PR is about to close. label Jan 27, 2026
@nyalldawson nyalldawson added API API improvement only, no visible user interface changes and removed stale Uh oh! Seems this work is abandoned, and the PR is about to close. labels Jan 27, 2026
@github-actions github-actions bot added stale Uh oh! Seems this work is abandoned, and the PR is about to close. and removed stale Uh oh! Seems this work is abandoned, and the PR is about to close. labels Feb 11, 2026
@qgis qgis deleted a comment from github-actions bot Feb 13, 2026
@qgis qgis deleted a comment from github-actions bot Feb 13, 2026
@github-actions
Copy link
Contributor

The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check

  • that all unit tests are passing

  • that all comments by reviewers have been addressed

  • that there is enough information for reviewers, in particular

    • link to any issues which this pull request fixes

    • add a description of workflows which this pull request fixes

    • add screenshots if applicable

  • that you have written unit tests where possible
    In case you should have any uncertainty, please leave a comment and we will be happy to help you proceed with this pull request.
    If there is no further activity on this pull request, it will be closed in a week.

@github-actions github-actions bot added stale Uh oh! Seems this work is abandoned, and the PR is about to close. and removed stale Uh oh! Seems this work is abandoned, and the PR is about to close. labels Feb 28, 2026
@github-actions
Copy link
Contributor

The QGIS project highly values your contribution and would love to see this work merged! Unfortunately this PR has not had any activity in the last 14 days and is being automatically marked as "stale". If you think this pull request should be merged, please check

  • that all unit tests are passing

  • that all comments by reviewers have been addressed

  • that there is enough information for reviewers, in particular

    • link to any issues which this pull request fixes

    • add a description of workflows which this pull request fixes

    • add screenshots if applicable

  • that you have written unit tests where possible
    In case you should have any uncertainty, please leave a comment and we will be happy to help you proceed with this pull request.
    If there is no further activity on this pull request, it will be closed in a week.

@github-actions github-actions bot added stale Uh oh! Seems this work is abandoned, and the PR is about to close. and removed stale Uh oh! Seems this work is abandoned, and the PR is about to close. labels Mar 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API API improvement only, no visible user interface changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants