当一个点在多边形之外时,ST_Within错误地返回true

Rhi*_*ino 2 gis postgis google-bigquery

此查询用于确定某个点是否在多边形内...

SELECT ST_Within
(
    ST_GeogPoint(69.6, 21.1),
    ST_GeogFromText('POLYGON((67.8 23.4, 69 17, 72.8 16.9, 67.8 23.4))')
)
Run Code Online (Sandbox Code Playgroud)

...在BigQuery中返回TRUE.这是一个不正确的结果.

同样的查询......

SELECT ST_Within
(
    ST_MakePoint(69.6, 21.1),
    'POLYGON((67.8 23.4, 69 17, 72.8 16.9, 67.8 23.4))'
)
Run Code Online (Sandbox Code Playgroud)

...在PostGIS中返回FALSE.这是正确的结果.

Fel*_*ffa 8

此查询为您提供您false要查找的回复:

SELECT ST_WITHIN(
  ST_GeogPoint(69.6, 21.1)
  , ST_GeogFromGeoJSON(
    '{"type": "Polygon", "coordinates": [[[67.8, 23.4], [69, 17], [72.8, 16.9], [67.8, 23.4]]]}'
))
Run Code Online (Sandbox Code Playgroud)

有什么不同?

我们来看看文档:

BigQuery GEOGRAPHY具有球形测地边,而GeoJSON Geometry对象明确具有平面边.要在这两种类型的边缘之间进行转换,BigQuery会在必要时向线条添加额外的点,以便生成的边缘序列保持在原始边缘的10米范围内.

事实上,在两个系统之间进行转换时,会发生一个非常有趣的曲面细分:

 SELECT ST_GeogFromGeoJSON(
   '{"type": "Polygon", "coordinates": [[[67.8, 23.4], [69, 17], [72.8, 16.9], [67.8, 23.4]]]}'
 )

 POLYGON((67.8 23.4, 67.875 23, 67.95 22.6, 68.025 22.2, 68.1 21.8, 68.175 21.4, 68.25 21, 68.325 20.6, 68.4 20.2, 68.475 19.8, 68.55 19.4, 68.625 19, 68.7 18.6, 68.775 18.2, 68.85 17.8, 68.925 17.4, 69 17, 69.2375 16.99375, 69.475 16.9875, 69.7125 16.98125, 69.95 16.975, 70.1875 16.96875, 70.425 16.9625, 70.6625 16.95625, 70.9 16.95, 71.1375 16.94375, 71.375 16.9375, 71.6125 16.93125, 71.85 16.925, 72.0875 16.91875, 72.325 16.9125, 72.5625 16.90625, 72.8 16.9, 72.64375 17.103125, 72.4875 17.30625, 72.33125 17.509375, 72.175 17.7125, 72.01875 17.915625, 71.8625 18.11875, 71.70625 18.321875, 71.55 18.525, 71.39375 18.728125, 71.2375 18.93125, 71.08125 19.134375, 70.925 19.3375, 70.76875 19.540625, 70.6125 19.74375, 70.45625 19.946875, 70.3 20.15, 70.14375 20.353125, 69.9875 20.55625, 69.83125 20.759375, 69.675 20.9625, 69.51875 21.165625, 69.3625 21.36875, 69.20625 21.571875, 69.05 21.775, 68.89375 21.978125, 68.7375 22.18125, 68.58125 22.384375, 68.425 22.5875, 68.26875 22.790625, 68.1125 22.99375, 67.95625 23.196875, 67.8 23.4))   
Run Code Online (Sandbox Code Playgroud)

顺便说一句,来自Earth Engine的文档:

在地球引擎中创建的几何体是测地线(即边缘是球体表面上的最短路径)或平面(即边缘是二维笛卡尔平面中的最短路径).没有一个平面坐标系适用于全局特征集合,因此Earth Engine的几何构造函数默认构建测地几何.

在此输入图像描述


现在让我们检查一下PostGIS - 它可以用于Geometries和Geographies.

SELECT ST_CoveredBy (
    ST_MakePoint(69.6, 21.1),
    'POLYGON((67.8 23.4, 69 17, 72.8 16.9, 67.8 23.4))'
)    
false

SELECT ST_CoveredBy(
    ST_MakePoint(69.6, 21.1)::geography,
    'POLYGON((67.8 23.4, 69 17, 72.8 16.9, 67.8 23.4))'
)
true
Run Code Online (Sandbox Code Playgroud)

(在这个多边形的大陆范围内:你真的想在几何上使用地理位置 - 即使PostGIS中的性能会慢一些)


回到BigQuery:巴黎和洛杉矶之间的距离是多少?

SELECT ROUND(ST_Length(line)/1000,2) km
FROM (
  SELECT [
    ST_GeogFromGeoJSON('{"type": "LineString", "coordinates": [[-118.4079, 33.9434], [2.5559, 49.0083]]}')
    , ST_GEOGFROMTEXT('LINESTRING(-118.4079 33.9434, 2.5559 49.0083)')
  ] lines
), UNNEST(lines) line


km
10187.92     
9103.09
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我刚刚使用测地线为你节省了1084公里的行程.