0

I have been experimenting with GeoAlchemy2, and I have some trouble with parsing its geom field.

I have tried to use the built-in to_shape function on a WKB element:

The example reads:

lake = Session.query(Lake).get(1)
polygon = to_shape(lake.geom)

I have used:

house = config.database.db_session.query(House)\
        .filter_by(house_id=1).first()
print "geom:", house.geom
01e90300009aea561e53634140ffb86b0da20a40400000000000000000

from geoalchemy2 import shape
print "to_shape:", shape.to_shape(house.geom)

to_shape:
Traceback (most recent call last):
  File "ranker_tester.py", line 40, in <module>
    print "to_shape:", shape.to_shape(house.geom)
  File ".../lib/python2.7/site-packages/GeoAlchemy2-0.2.4-py2.7.egg/geoalchemy2/shape.py", line 24, in to_shape
    return shapely.wkb.loads(bytes(element.data))
  File ".../lib/python2.7/site-packages/shapely/wkb.py", line 16, in loads
    return reader.read(data)
  File ".../lib/python2.7/site-packages/shapely/geos.py", line 361, in read
    raise ReadingError("Could not create geometry because of errors "
shapely.geos.ReadingError: Could not create geometry because of errors while reading input.

Any idea how can I parse this GeoAlchemy2 geom field? The database value is valid.

Community
  • 1
  • 1
Adam Matan
  • 128,757
  • 147
  • 397
  • 562

1 Answers1

1

I don't use GeoAlchemy2, so I can't comment on how it generates it's WKB, except to say that it is a different dialect than what Shapely/GEOS uses.

The WKB you provided is OGC/ISO (with PostGIS using encode(ST_AsBinary(geom), 'hex')):

01e90300009aea561e53634140ffb86b0da20a40400000000000000000

And here is the WKT equivalent (i.e. ST_AsText(geom)):

POINT Z (34.7759740757367 32.0830704475393 0)

However, Shapely and GEOS does not support OGC/ISO WKB for higher-dimension geometries. It only supports EWKB, which was specified for PostGIS (and pre-dates OGC/ISO specs), which looks like this (i.e. encode(ST_AsEWKB(geom), 'hex')):

01010000809aea561e53634140ffb86b0da20a40400000000000000000

So this works with Shapely,

from shapely.wkb import loads
pt = loads('01010000809aea561e53634140ffb86b0da20a40400000000000000000', hex=True)
pt.wkt  # 'POINT Z (34.77597407573667 32.08307044753928 0)'
pt.wkb_hex  # '01010000809AEA561E53634140FFB86B0DA20A40400000000000000000'

I'm not sure how this helps your problem, but might show some incite as to what is going on. If you aren't using the the Z-dimension, you can just stick to 2D geometries, where the WKB is identical for OGC/ISO WKB and EWKB specs.

Mike T
  • 41,085
  • 18
  • 152
  • 203