Bug report #20661

QgsPoint.clone() not fully reliable? It's original QgsFeature may get corrupted?

Added by Juan Manuel Perez 11 months ago. Updated 8 months ago.

Status:Closed
Priority:Normal
Assignee:-
Category:Python bindings / sipify
Affected QGIS version:3.5(master) Regression?:Yes
Operating System:Windows 7 64 bits Easy fix?:No
Pull Request or Patch supplied:No Resolution:up/downstream
Crashes QGIS or corrupts data:No Copied to github as #:28481

Description

We have stumbled upon an strange problem and reproducible problem. We attach a plugin to reproduce it.

The problem arises in this circumstances:
  • We have a layer. We iterate over all its features, then over all their geometries, then all of their nodes (QgsPoints). To reproduce the problem, we use a layer with only a single polygon.
  • For each node, we create a new QgsFeature (in memory), and we assign it a new geometry initialized with a clone of the node (QgsPoint)
  • The original layer is not modified in any way, nor its features.
  • We then repeat the above steps. We may repeat it successfully but only for a limited and variable number of iterations.
  • Eventually, the process will break with an unexpected exception.

  • More precisely, the exception raises because eventually we get a PolygonGeometry QgsGeometry (as expected), but its actual geometry (geom.constGet()) is reported as a QgsPoint. Debugging, it looks as "<QgsPoint: MultiPolygon (...)>", as shown in the attached screenshots.

How to reproduce it

We have prepared a plugin to easily reproduce the issue. We have attached as 'issuePlugin.zip' to this bug report.
You only need to install it in QGis. Then, a toolbar with a spider will appear (see above screenshots). You only need to click this icon. A dialog will open, showing how the test iterates until the unexpected exception is raised.

We have tested it in Qgis 3.5 MASTER and 3.4.1.

iteration_screenshot.png (82.5 KB) Juan Manuel Perez, 2018-11-28 03:41 PM

debugging_screenshot.png (116 KB) Juan Manuel Perez, 2018-11-28 03:41 PM

issuePlugin.zip (487 KB) Juan Manuel Perez, 2018-11-28 03:44 PM

History

#1 Updated by Juan Manuel Perez 11 months ago

For now, we use a simple workaround: not using QgsPoint.clone(), but creating a brand new QgsPoint (QgsPoint(nodo.x(), nodo.y()).
But we think such a strange behavior should need be reviewed, as it may lead to unexpected or unreliable results...

#2 Updated by Martin Dobias 11 months ago

I can replicate on linux too.

Simplified code to reproduce the issue:

import sip
for i in range(50):
    geom = QgsGeometry.fromWkt("MULTIPOLYGON(((1 1, 1 2, 2 2, 2 1, 1 1)))")
    geomV2 = geom.constGet()
    if isinstance(geomV2, QgsPoint):
        print("WHAT??????!!!!!  " + hex(sip.unwrapinstance(geomV2)))

    pt = QgsGeometry.fromWkt("POINT( 3 4 )")
    pt_g = pt.constGet()
    pt_clone = pt_g.clone()
    pt_x = QgsGeometry(pt_clone)
    print("new pt  " + hex(sip.unwrapinstance(pt_clone)))
print("-----")

#3 Updated by Matthias Kuhn 8 months ago

  • Resolution set to up/downstream
  • Status changed from Open to Closed

Issue fixed upstream with upcoming sip version 4.19.14.

Also available in: Atom PDF