On 22-08-18 14:51, Denis Rouzaud wrote:
Hi Raymond,

Le mer. 22 août 2018 à 15:30, Raymond Nijssen <r.nijs...@terglobo.nl <mailto:r.nijs...@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
de...@opengis.ch <mailto:de...@opengis.ch>
+41 76 370 21 22



_______________________________________________
QGIS-Developer mailing list
QGIS-Developer@lists.osgeo.org
List info: https://lists.osgeo.org/mailman/listinfo/qgis-developer
Unsubscribe: https://lists.osgeo.org/mailman/listinfo/qgis-developer

Reply via email to