5

Creating a QgsGeometry using a WKT/WKB string is a fairly standard procedure using pyqgis:

wkt = 'MULTIPOLYGON (((0 0, 1 1, 1 0, 0 0)))'
wkb = '0106000000010000000103000000010000000400000000000000000000000000000000000000000000000000f03f000000000000f03f000000000000f03f000000000000000000000000000000000000000000000000'

geometry_wkt = QgsGeometry.fromWkt(wkt)
print(geometry_wkt) # <QgsGeometry: MultiPolygon (((0 0, 1 1, 1 0, 0 0)))>

geometry_wkb = QgsGeometry()
geometry_wkb.fromWkb(bytes.fromhex(wkb))
print(geometry_wkb) # <QgsGeometry: MultiPolygon (((0 0, 1 1, 1 0, 0 0)))>

But now I have data in the extended WKT/WKB format which also embeds a spatial reference identifier. I could't find a way to create a QgsGeometry from such a string. If I just use the same as above I always get <QgsGeometry: null> as result.

ewkt = 'SRID=4326;POLYGON((0 0,1 0,1,0 1,0 0))'
ewkb = '0103000020E6100000010000000500000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F000000000000F03F0000000000000000000000000000F03F00000000000000000000000000000000'

geometry_ewkt = QgsGeometry.fromWkt(ewkt)
print(geometry_ewkt) # <QgsGeometry: null>

geometry_ewkb = QgsGeometry()
geometry_ewkb.fromWkb(bytes.fromhex(ewkb))
print(geometry_ewkb) # <QgsGeometry: null>

Is there any way to create those geometries using pyqgis API?

If not, I probably could extract the relevant wkt/wkb parts from the extended representation. I guess for EWKT it would be just dropping everything until the ;. But what do I do to convert EWKB string to WKB string?

1 Answer 1

1

I had the same problem and found a solution, though it uses an additional PostGis function on the EWKB before working with python:

i added ST_AsBinary to my query converting the EWKB to a WKB.
The result of psycopg2 cursor.fetchone()[0] is then of type memoryview, i convert it using the tobytes method then feeds it to the fromWkb method of QgsGeometry.

Example:

def function(connection):
    try:
        cursor = connection.cursor()
        req = "SELECT ST_AsBinary( myPostGisRequest(%s) );"
        parameters = (myParameter,)

        cursor.execute(req, parameters)
        memoryview_wkb = cursor.fetchone()[0]
        connection.commit()
    finally:
        cursor.close()

    if memoryview_wkb is None:
            return

    qgs_geometry = QgsGeometry()
    qgs_geometry.fromWkb(memoryview_wkb.tobytes())
    return qgs_geometry
1
  • PostGIS wasn't an option in my particular use case, but thanks for your answer anyway!
    – CodeBard
    Commented Mar 22 at 16:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.