google-bigquery - 当点在多边形之外时,ST_Within 错误地返回 true
问题描述
此查询确定一个点是否在多边形内...
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))')
)
...在 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))'
)
...在 PostGIS 中返回 FALSE。这是一个正确的结果。
解决方案
此查询为您提供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]]]}'
))
有什么不同?
让我们检查一下文档:
- https://cloud.google.com/bigquery/docs/reference/standard-sql/geography_functions#st_geogfromgeojson
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))
顺便说一句,来自地球引擎文档:
在 Earth Engine 中创建的几何图形要么是测地线的(即边是球体表面上的最短路径),要么是平面的(即边是二维笛卡尔平面中的最短路径)。没有一个平面坐标系适用于全局要素集合,因此 Earth Engine 的几何构造函数默认构建测地线几何。
现在让我们检查一下 PostGIS - 它可以与几何和地理一起使用。
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
(在这个多边形的大陆范围内:你真的想在几何上使用地理 - 即使 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
我刚刚使用测地线为您节省了 1084 公里的行程。
推荐阅读
- javascript - MongoDB:更新后返回修改后的文档会影响性能吗?
- node.js - 如何更改网站主题并保存此主题,使其在重新加载时不会更改?
- javascript - 返回所有排列的 JavaScript 函数
- python-3.x - 没有为 intel-numpy 找到匹配的分布
- arrays - 从数组中删除重复项,但按频率排序
- python - AWS S3从excel CSV中删除带有脚本的文件
- excel - 如何删除表中具有值的最后一行
- html - HTML表格对齐
- c# - 如何从另一个类/通过在 WPF 中的函数中传递它来更新按钮的颜色
- node.js - 需要 JSON 作为深拷贝