2

我有一个查询:(此查询使用 ST_Covers 函数的地理实现)

SELECT ST_Covers(ST_GeoGraphyFromText('MULTIPOLYGON(((179 -89,179 89,-179 89,-179 -89,179 -89)))'),ST_GeographyFromText('POINT(20 30)'));

当我运行此查询时,它应该返回 true,但它返回 false。我不知道 PostGIS(或此查询)有什么问题

当我用几何改变地理实现时,将查询重新排列如下:

SELECT ST_Covers(ST_ASTEXT(ST_GeoGraphyFromText('MULTIPOLYGON(((179 -89,179 89,-179 89,-179 -89,179 -89)))')),text('POINT(20 30)'));

它可以正常工作,返回true:

我可以使用下面的查询来满足,但问题是当数据库太大时,它需要太多时间

请有人告诉我

如何使查询 1 正常工作(按预期返回 true),或

如何使查询 2 在大表中快速工作

(请不要建议我应该删除 *ST_GeoGraphyFromText('MULTIPOLYGON(((179 -89,179 89,-179 89,-179 -89,179 -89)* ,因为它只表示将被来自列中的数据替换的地理数据桌子 )

查询 1 不起作用的其他值是 (5 5) (10 10) (-10 -10) 等等

4

1 回答 1

1

第一个查询失败,因为您使用的geography类型宽度 >180°。如果它是更真实的东西,例如'MULTIPOLYGON(((100 0,100 50,0 50,0 0,100 0)))',它将返回 TRUE。

没有直接的方法可以找到 MultiPolygon 地理类型的外环的最大直径,但是您可以尝试通过以下方式来寻找这些特殊情况:

SELECT ST_XMax(geog::geometry) - ST_XMin(geog::geometry) AS width,
       ST_YMax(geog::geometry) - ST_YMin(geog::geometry) AS height
FROM polygons

检查大于 180 的部分,并查看每个部分是否也大于 180。如果是,则应将这些视为无效地理。


第二个查询返回 TRUE 的唯一原因是因为 ST_AsText 转换为 WKT,然后将其重新解释回 WKB 作为geometry类型(并隐式调用ST_Covers(geometry, geometry),而不是ST_Covers(geography, geography))。这个查询很慢,因为它从 WKB 转换为 WKT 再到 WKB,在转换之间可能会丢失精度。一个更快的版本是使用 将地理列转换为几何::geometry,例如:

SELECT ST_Covers(geog::geometry, ST_SetSRID(ST_MakePoint(20, 30), 4326))
FROM polygons

几何类型对 ST_Covers 使用简单的“平地”笛卡尔逻辑,这就是为什么您会看到 TRUE 符合您的预期。地理类型使用不同的“圆形地球”逻辑,该逻辑使用更复杂的球形逻辑,但很容易看出您是否有手边的地球仪。

于 2013-01-20T23:16:55.167 回答