Geography类型查询多边形内数据返回异常行问题咨询
问题描述
我们有一张存储约200万条英国经纬度数据的表,已将经纬度转换为Geography类型,用于查询谷歌地图绘制的多边形范围内的参考编号。使用的SQL查询代码如下:
DECLARE @PolygonWKT VARCHAR(MAX) = 'POLYGON((-2.8940874872629085 53.18998211235127, -2.8929395018045345 53.19014603440105, -2.892751747173492 53.1898953298359, -2.8939641056482235 53.18979890461282, -2.8940874872629085 53.18998211235127))' DECLARE @Polygon GEOGRAPHY = geography::STGeomFromText(@PolygonWKT, 4326).MakeValid() SELECT ref_number FROM MyTable WITH (INDEX(SI_GeoLocation)) WHERE GeoLocation.STIntersects(@Polygon) = 1
该查询多数时候能返回正确结果,但存在异常情况:查询一个位于英国切斯特的小型多边形(首尾点一致)时,返回了近全部数据(2020398条,总数据2020451条)。请问此实现方式是否正确?
问题分析与结论
你的实现逻辑存在多边形顶点顺序导致的"反多边形"问题,并非正确的实现方式:
- SQL Server的
Geography类型遵循OGC规范,多边形顶点的顺时针/逆时针顺序直接决定覆盖范围。在WGS84(4326)坐标系下,系统默认认为逆时针顶点围成的是你预期的小区域,而顺时针顶点则会被解析为"覆盖除小区域外的整个地球"。 - 你调用的
MakeValid()方法仅用于修复几何结构错误(如自相交),无法自动修正顶点顺序导致的反多边形问题,这就是为什么查询返回了几乎全部数据——你实际匹配的是整个地球除目标小区域外的所有点。
修正方案
方案1:手动调整顶点为逆时针顺序
将WKT中的顶点按逆时针重新排列,示例调整后的WKT:
DECLARE @PolygonWKT VARCHAR(MAX) = 'POLYGON((-2.8940874872629085 53.18998211235127, -2.8939641056482235 53.18979890461282, -2.892751747173492 53.1898953298359, -2.8929395018045345 53.19014603440105, -2.8940874872629085 53.18998211235127))'
方案2:使用ReorientObject()自动修正方向
在创建多边形后调用ReorientObject()方法,翻转多边形的内部/外部区域,无需手动调整顶点:
DECLARE @PolygonWKT VARCHAR(MAX) = 'POLYGON((-2.8940874872629085 53.18998211235127, -2.8929395018045345 53.19014603440105, -2.892751747173492 53.1898953298359, -2.8939641056482235 53.18979890461282, -2.8940874872629085 53.18998211235127))' DECLARE @Polygon GEOGRAPHY = geography::STGeomFromText(@PolygonWKT, 4326).MakeValid().ReorientObject() SELECT ref_number FROM MyTable WITH (INDEX(SI_GeoLocation)) WHERE GeoLocation.STIntersects(@Polygon) = 1
验证方法
可以通过STArea()检查多边形面积:
- 正确的小型多边形面积数值极小(对应城市区域的实际面积)
- 若面积接近地球表面积(约5.1亿平方公里),则说明是反多边形,需修正
内容的提问来源于stack exchange,提问作者Andy Murphy
相关产品推荐
相关产品推荐

