使用GeoAlchemy2与Spatialite时ST_Contains/ST_Within返回-1的问题
问题解决步骤
1. 修正空间函数参数顺序
ST_Within和ST_Contains的参数逻辑必须对应:
ST_Within(点, 多边形):判断点是否落在多边形内部ST_Contains(多边形, 点):判断多边形是否包含点
你当前代码的参数顺序完全颠倒,这是核心问题之一。
2. 正确解析EWKT字符串为空间对象
直接传入字符串无法被Spatialite正确识别,需要通过ST_GeomFromText解析,同时用ST_SetSRID指定空间参考(GeoJSON默认采用EPSG:4326)。
修正后的代码示例:
from geoalchemy2.functions import ST_Within, ST_GeomFromText, ST_SetSRID from sqlalchemy import select from app import app, db from app.models import Neighbourhood # 定义点并绑定空间参考(与GeoJSON一致的EPSG:4326) point_wkt = 'Point (-79.3438 43.7377)' point_geom = ST_SetSRID(ST_GeomFromText(point_wkt), 4326) with app.app_context(): # 正确参数顺序:点在前,社区多边形在后 query = select(Neighbourhood.name).where(ST_Within(point_geom, Neighbourhood.geometry)) results = db.session.scalars(query).all()
3. 确保空间参考(SRID)一致性
检查社区数据的geometry字段与传入点的SRID是否完全一致:
- 确认Neighbourhood模型中geometry字段定义是否设置了
srid=4326 - 可通过查询验证现有数据的SRID:
query = select(Neighbourhood.name, ST_SRID(Neighbourhood.geometry)).limit(5).all()
4. 关于ST_Contains返回-1的说明
Spatialite中布尔值以整数返回:1为真,0为假,-1表示空间操作失败(常见原因是SRID不匹配、几何对象无效),解决上述参数和SRID问题后该异常会消失。
5. 验证并修复几何对象有效性
若仍无结果,检查社区多边形是否有效:
# 查询无效几何对象 query = select(Neighbourhood.name).where(ST_IsValid(Neighbourhood.geometry) == 0).all()
存在无效几何时,可执行SQL修复:
UPDATE neighbourhood SET geometry = ST_MakeValid(geometry) WHERE ST_IsValid(geometry) = 0;
内容的提问来源于stack exchange,提问作者user3772884
相关产品推荐
相关产品推荐

