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