FastAPI+GeoAlchemy2:如何用矩形两点筛选含Point的数据库行?
基于GeoAlchemy2和FastAPI实现矩形范围的点筛选
1. 推导矩形的四个顶点
已知矩形的左下点(min_lon, min_lat,即经度最小、纬度最小的点)和右上点(max_lon, max_lat,即经度最大、纬度最大的点),另外两个顶点可直接推导:
- 左上点:(
min_lon,max_lat) → 复用左下点的经度、右上点的纬度 - 右下点:(
max_lon,min_lat) → 复用右上点的经度、左下点的纬度
2. 构造闭合的Polygon
Polygon需要是闭合的环,坐标需按顺时针或逆时针顺序排列,最后回到起始点(左下点),WKT格式示例如下:
POLYGON((min_lon min_lat, min_lon max_lat, max_lon max_lat, max_lon min_lat, min_lon min_lat))
3. 完整实现代码
依赖导入与数据库配置
from fastapi import FastAPI from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from geoalchemy2 import functions from geoalchemy2.elements import WKTElement # 替换为你的模型类 from your_app.models import LocationTable app = FastAPI() # 替换为你的数据库连接信息 DB_URL = "postgresql://username:password@localhost:5432/your_db" engine = create_engine(DB_URL) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
FastAPI路由实现
@app.get("/filter-points-in-rect/") def filter_points(min_lon: float, min_lat: float, max_lon: float, max_lat: float): # 构造矩形Polygon的WKT字符串 polygon_wkt = f"POLYGON(({min_lon} {min_lat}, {min_lon} {max_lat}, {max_lon} {max_lat}, {max_lon} {min_lat}, {min_lon} {min_lat}))" # 绑定SRID为4326,与数据库列的坐标系保持一致 polygon = WKTElement(polygon_wkt, srid=4326) db = SessionLocal() try: # 使用ST_Contains筛选位于矩形内(含边界)的点 query_result = db.query(LocationTable).filter( functions.ST_Contains(polygon, LocationTable.coordinates) ).all() # 格式化返回结果(按需调整) return [ { "id": item.id, "coordinates": item.coordinates.wkt # 将Point转为WKT字符串 } for item in query_result ] finally: db.close()
补充说明
- 坐标系一致性:必须保证构造的Polygon SRID与数据库
coordinates列的4326一致,否则会出现坐标匹配错误。 - 边界控制:如果需要排除边界上的点,可将
ST_Contains替换为ST_ContainsProperly。 - 等价写法:
functions.ST_Within(LocationTable.coordinates, polygon)与ST_Contains效果完全一致,可根据习惯选择。
内容的提问来源于stack exchange,提问作者Dmitriy Lunev
相关产品推荐
相关产品推荐

