[QGIS-Developer] Geometry data model logic?

Raymond Nijssen r.nijssen at terglobo.nl
Wed Aug 22 07:47:19 PDT 2018



On 22-08-18 14:51, Denis Rouzaud wrote:
> Hi Raymond,
> 
> Le mer. 22 août 2018 à 15:30, Raymond Nijssen <r.nijssen at terglobo.nl 
> <mailto:r.nijssen at terglobo.nl>> a écrit :
> 
>     Hopefully it is just a misconception on my side, but I really don't get
>     the logic in the qgis geometry data model.
> 
>     I tried the following script (sorry, some lines are wrapped by my email
>     client):
> 
>     ---
> 
>     #points
> 
>     p1 = QgsGeometry().fromWkt('point(0 0)')
>     print(p1) # <QgsGeometry: Point (0 0)>
>     print(p1.asPoint()) # <QgsPointXY: POINT(0 0)>
>     print(p1.centroid()) # <QgsGeometry: Point (0 0)>
>     print(p1.buffer(1, 1)) # <QgsGeometry: Polygon ((1 0, 0 -1, -1 0, 0
>     1, 1
>     0))>
> 
>     p2 = QgsPoint(1,2)
>     print(p2) # <QgsPoint: Point (1 2)>
>     p2g = QgsGeometry(p2)
>     print(p2g) # <QgsGeometry: Point (1 2)>
>     print(p2) # <QgsPoint: Point (1 2)>
>     print(p2.centroid()) # <QgsPoint: Point (1 2)>
>     print(QgsPointXY(p2.x(), p2.y())) # <QgsPointXY: POINT(1 2)>
>     # The next line makes qgis crash after running it 2x !!
>     #print(QgsGeometry(p2)) # <QgsGeometry: Point (1 2)>
> 
>     p3 = QgsPointXY(2, 0)
>     print(p3) # <QgsPointXY: POINT(2 0)>
>     print(QgsGeometry.fromPointXY(p3)) # <QgsGeometry: Point (2 0)>
>     print(QgsPoint(p3.x(), p3.y())) # <QgsPoint: Point (2 0)>
> 
>     # lines
> 
>     l1 = QgsGeometry().fromWkt('linestring((0 0, 1 1, 1 2))')
>     print(l1) # <QgsGeometry: LineString (0 0, 1 1, 1 2)>
>     print(l1.buffer(1, 1).asPolygon())
>     print(l1.asPolyline()) # [<QgsPointXY: POINT(0 0)>, <QgsPointXY:
>     POINT(1
>     1)>, <QgsPointXY: POINT(1 0)>]
>     print(QgsLineString(l1.asPolyline())) # TypeError: index 0 has type
>     'QgsPointXY' but 'QgsPoint' is expected
> 
> 
>     ---
> 
>     My questions are:
> 
>     - How is the relation between QgsGeometry, QgsPoint, QgsPoitXY, etc
>     meant to be? Is there documentation? Maybe even a schema?
> 
> 
> QgsGeometry contains a QgsAbstractGeometry which is the base class of 
> all geometry classes.
> You can get the abstract geometry using get and constGet methods.
> 
> The documentation partially mentions this
> https://qgis.org/pyqgis/master/core/Geometry/QgsGeometry.html
> 
> 
>     - Having QgsPoint and QgsPointXY etc is not handy, but I understand
>     they
>     are necessary for efficiency reasons. However, shouldn't they all have
>     easy typecasting functions? For example:
>     QgsGeometry.asPoint()
>     QgsGeometry.asPointXY()
>     QgsGeometry.asLineString()
>     QgsGeometry.asLineStringXY()
>     QgsGeometry.asPolygon()
>     QgsGeometry.asPolygonXY()
>     QgsGeometry.asMultiLineString()
>     QgsGeometry.asMultiLineStringXY()
>     etc..
> 
>     QgsPoint.asGeometry()
>     QgsPoint.asPointXY()
> 
>     QgsLineString.asGeometry()
>     QgsLineString.asPointXY()
> 
>     etc..
> 
> 
> I was also asking my self the same thing.
> I am not really sure if there is a reason or not that they were not 
> implemented.
> The main issue to me is the difficulty to get the geometries as points 
> with their Z/M values.
> The workaround I am using is looping along vertices using
> 
> geometry.get()->nextVertex( vertexId, pt );
> 
> You will the list of QgsPoint with Z/M values.
> 
> 
>     - Why don't all geometry types inherit from QgsGeometry, making all the
>     geometry operators work? For example:
>     QgsPoint(1,2).buffer(3,5)
> 
> 
> as said before, all geometry classes inherit from QgsAbstractGeometry. 
> You can use set method (setGeometry in 2.x) on QgsGeometry to create the 
> geometry from the any subclass of abstract geometry.
> 
> 
> 
> 
> 
>     Some, IMHO, really odd things are:
> 
>     - QgsGeometry.asPoint() returns a QgsPointXY
> 
> 
> I guess that's historical (QgsPoint in 2.x became QgsPointXY in 3, while 
> QgsPointZ became QgsPoint).
> 
> 
>     - QgsGeometry.asLineString() does not exist
> 
>     - QgsGeometry.asPolyLine() returns an array of QgsPointXY's (besides,
>     polyline is a strange geometry type in this model)
> 
>     - QgsLineString([qgsPointXY, qgsPointXY, qgsPointXY, ...]) results
>     in an
>     error, while the documentation states:
>          QgsLineString(points: Iterable[QgsPointXY]) Construct a linestring
>          from list of points. This constructor is more efficient then
>     calling
>          setPoints() or repeatedly calling addVertex()
> 
> 
> ls = QgsLineString([QgsPoint(10, 2), QgsPoint(10, 1), QgsPoint(5, 1)])
> 
> this does work for me (and for Travis ;) )

True, but the docs say these should be QgsPointXY's, not QgsPoint's. So 
maybe the docs are wrong here, but still this is annoying because 
asPolyLine() returns a list of QgsPointXY's. Only writing your own loop 
can convert those.

> 
> 
>     - QgsGeometry(QgsPoint) does work, but destroys my QgsPoint (and makes
>     qgis instable)
> 
> 
> look at QgsGeometry::set method

Thanks, I got this working:


pg1 = QgsGeometry().fromWkt('polygon((0 0, 0 1, 1 1, 1 0, 0 0))')
print(pg1) # <QgsGeometry: Polygon ((0 0, 0 1, 1 1, 1 0, 0 0))>

pg2 = pg1.get()
print(pg2) # <QgsPolygon: Polygon ((0 0, 0 1, 1 1, 1 0, 0 0))>

g = QgsGeometry()
g.set(pg2)
print(g) # <QgsGeometry: Polygon ((0 0, 0 1, 1 1, 1 0, 0 0))>


So, now I can convert both ways between QgsGeometry and 
QgsPoint/QgsLineString/QgsPolygon. But this script makes qgis crash 
after running it 2 times. It has to do with the set() method. This could 
also be a bug of course. Should I file it?

> 
> 
> 
> 
>     Hopefully somebody can explain, making this more sense to me. And I'd
>     like to contribute to improving this, though I'm not a cpp programmer.
> 
> 
> This is indeed a bit obscure at first and it took me a bit of time to 
> see the logic here.
> 
> The gurus might arrive with a more precise explanation but I hope it's a 
> good start!

Still waiting for the guru's! :)
> 
> Best wishes,
> Denis
> -- 
> 
> Denis Rouzaud
> denis at opengis.ch <mailto:denis at opengis.ch>
> +41 76 370 21 22
> 
> 



More information about the QGIS-Developer mailing list