In an ORM I would expect to be able to do this:
session.add(Lake("hello",Polygon([(0,0),(1,0),(1,1)]))) lake = session.get(Lake).first() assert isinstance(lake.geometry, Polygon) assert isinstance(lake.geometry.get_exterior_ring().get_points()[0], Point) print(lake.geometry.get_exterior_ring().get_points()[0].x)
Instead the only way I see to access the Points of my lake is through a rather complex monster of code:
ring = func.ST_ExteriorRing(func.ST_GeomFromWKB(Lake.geometry)) node_count = func.ST_NPoints(ring) node_series = func.generate_series(1, node_count) node_n = func.ST_PointN(ring, node_series) node_n_x = func.ST_X(node_n) node_n_y = func.ST_Y(node_n) rows = session.query(Lake, node_n_x, node_n_y).all() lake_coasts = {} for row in rows: lake = row[0] if not lake in lake_coasts: lake_coasts[lake] = [] lake_coast = lake_coasts[lake] lake_coast.append((row[1], row[2])) for lake in lake_coasts: lake_coast = lake_coasts[lake] print("Lake #{0}: \"{1}\" has its coasts at {2}" .format(lake.id, lake.name, lake_coast))
and while this loop gets me the coordinates I want, I'm lost figuring out how to implement some Lake.get_coast() that returns this instance's coast.
Also I gave up on implementing the same for ""Lake""s with MULTIPOLYGONs as the nesting to get down to the points was too much for postgis (at least that's how I read the Error message)
I'm new to postgis, gis, python and sqla but in two days of googling I could not find anything that looks like an ORM within SQL-Alchemy 2 but only some SQL-helper functions (postgis) to parse the WKB but only within the database. Do I need some additional framework? I saw gdal, ogr, fiona but I feel like looking in the wrong direction. Is there some open source project using SQL-Alchemy2 with a nice structure? Entities, DAOs, whatever? How do you actually use this monster beyond this minimalist example?
You may use GeoAlchemy2 and Shapely: