Как рассчитать ST_Union с 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)

Теперь я пытаюсь выбрать OsmAdminUnits, которые принадлежат определенному OsmAdminAgg, и объединить полигоны, применяя ST_Union из GeoAlchemy.

Выбор всех административных единиц, которые принадлежат 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?

Кстати, я строю это поверх Flask, используя SQLAlchemy, Flask-SQLAlchemy, Geoalchemy2.

2 ответа

Попробуй это:

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()

Вы можете увидеть базовый шаблон для этого в документации GeoAlchemy 2 .

В вашем случае что-то вроде:

      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()
Другие вопросы по тегам