如何用GeoAlchemy2计算ST_Union?

时间:2016-06-09 13:03:20

标签: python sqlalchemy postgis geoalchemy2

我有多对多的关系,OsmAdminUnit(多边形几何)的实例被分组到OsmAdminAgg实例中。

模型定义基本上是:

class OsmAdminUnit(db.Model):
    __tablename__ = 'osm_admin'

    id          = db.Column(db.Integer, primary_key=True)
    geometry    = db.Column(Geometry(
                    geometry_type='GEOMETRY', 
                    srid=3857), nullable=False)
    agg_units   = db.relationship('OsmAdminAgg',
                    secondary=aggregations,
                    backref=db.backref('osm_admin', lazy='dynamic'))

class OsmAdminAgg(db.Model):
    __tablename__ = 'admin_agg'

    id   = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), unique=True, nullable=False)

现在我正在努力做的是选择属于某个OsmAdminAgg的OsmAdminUnits并通过从GeoAlchemy应用ST_Union来合并polgyons。

选择所有属于admin agg且id = 1的管理单元:

units = OsmAdminUnit.query.filter(OsmAdminUnit.agg_units.any(id=1)).all()

但我不知道如何在该结果上应用ST_Union。 到目前为止我的方法是:

union = db.session.query(
        OsmAdminUnit.geometry.ST_Union().ST_AsGeoJSON().label('agg_union')
        ).filter(OsmAdminUnit.agg_units.any(id=1)).subquery()

那么如何获得这些几何的联合,并将其作为GeoJSON?

顺便说一下,我正在使用SQLAlchemy,Flask-SQLAlchemy,Geoalchemy2在Flask之上构建它。

2 个答案:

答案 0 :(得分:0)

试试这个:

from sqlalchemy.sql.functions import func

union = db.session.query(func.ST_AsGeoJSON(func.ST_Union(
    OsmAdminUnit.geometry)).label('agg_union')
    ).filter(OsmAdminUnit.agg_units.any(id=1)).subquery()

答案 1 :(得分:0)

您可以在 GeoAlchemy 2 docs 中看到一个基本模板。本质上,您需要将 func 传递给查询,而不是模型,以选择联合本身。

就您而言,例如:

import sqlalchemy

union = db.session.query(
    sqlalchemy.func.ST_AsGeoJSON(
        sqlalchemy.func.ST_Union(OsmAdminUnit.geometry)
    ).label('agg_union')
).filter(
    OsmAdminUnit.agg_units.any(id=1)
).all()

这会获取与过滤器匹配的 OsmAdminUnit 记录的 geometry 值的并集,并将其作为字符串化的 GeoJSON 返回。

接受的答案对我不起作用,我认为导入可能与我使用的 sqlalchemy 版本不同。