postgresql - 如何准确确定边界附近的点和地理的 ST_Intersects(ST_Intersects geography vs. Geometry diffrepancy)

标签 postgresql gis postgis

我有一个geography 多边形列。此列已被ST_Subdivided 用于多边形内点查找性能。

当我在距离 geography 类型的多边形边缘 < 10m 的点之间执行 ST_Intersects 时,我得到 false。但是在转换为geometry类型之后,我得到true:

SELECT
ST_Intersects(ST_GeogFromText('POINT(-118.46131 34.31171)'), latlong_shape) AS intersects_geog,
ST_Intersects(ST_GeogFromText('POINT(-118.46131 34.31171)')::geometry, latlong_shape::geometry) AS intersects_geom
FROM region_ids_for_latlong_shapes
WHERE ST_Distance(ST_GeogFromText('POINT(-118.46131 34.31171)'), latlong_shape) < 10;

| intersects_geog | intersects_geom |
| --------------- | --------------- |
| false           | true            |
| false           | false           |

我知道 ST_Intersects(geography, geography)ST_Intersects(geometry, Geometry) 之间存在预期差异,但我不明白为什么它们会在这种情况下会发生:

  • 几何形状有效
  • 即使存在一些很大的圆差异,我也希望该点与其中一个多边形相交,而不是在两个多边形之外。

确定该点与哪个多边形相交的最准确方法是什么?我知道我可以转换为几何类型,但我'令我惊讶的是,ST_Intersectgeography 支持在这里不起作用。是否可以在不进行强制转换的情况下准确地完成此操作?

这是该点和两个最接近的形状:

Overview image

Zoomed in to point and boundary

更多诊断:

SELECT
ST_Intersects(ST_GeogFromText('POINT(-118.46131 34.31171)'), latlong_shape) AS geogs_intersect,
ST_Intersects(ST_GeogFromText('POINT(-118.46131 34.31171)')::geometry, latlong_shape::geometry) AS geoms_intersect,
ST_IsValid(latlong_shape::geometry) AS geom_isvalid,
ST_Relate(ST_GeogFromText('POINT(-118.46131 34.31171)')::geometry, latlong_shape::geometry) AS relate_geoms,
ST_Distance(ST_GeogFromText('POINT(-118.46131 34.31171)'), latlong_shape) AS geogs_distance,
ST_Distance(ST_GeogFromText('POINT(-118.46131 34.31171)'), latlong_shape, false) AS geogs_no_spheroid_distance,
ST_Distance(ST_GeogFromText('POINT(-118.46131 34.31171)')::geometry, latlong_shape::geometry) AS geoms_distance,
ST_3DDistance(ST_GeogFromText('POINT(-118.46131 34.31171)')::geometry, latlong_shape::geometry) AS geoms_3d_distance
FROM region_ids_for_latlong_shapes
WHERE ST_Distance(ST_GeogFromText('POINT(-118.46131 34.31171)'), latlong_shape) < 10

| geogs_intersect | geoms_intersect | geom_isvalid | relate_geoms | geogs_distance | geogs_no_spheroid_distance | geoms_distance          | geoms_3d_distance       |
| --------------- | --------------- | ------------ | ------------ | -------------- | -------------------------- | ----------------------- | ----------------------- |
| false           | true            | true         | 0FFFFF212    | 3.4064663      | 3.4146671                  | 0                       | 0                       |
| false           | false           | true         | FF0FFF212    | 5.63478588     | 5.64835122                 | 0.000054321999996886916 | 0.000054321999996886916 |
SELECT VERSION()

| version                                                                                                           |
| ----------------------------------------------------------------------------------------------------------------- |
| PostgreSQL 13.9 on x86_64-apple-darwin19.6.0, compiled by Apple clang version 11.0.3 (clang-1103.0.32.62), 64-bit |
SELECT PostGIS_Version();

| postgis_version                       |
| ------------------------------------- |
| 3.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1 |

为了方便起见,这是我在上面可视化的 GeoJSON。它包含查找点和两个最近的多边形(由 ST_AsGeoJSON 返回):

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Point",
        "coordinates": [
          -118.46131,
          34.31171
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -118.590173754,
              34.818203384
            ],
            [
              -118.554669477,
              34.818248424
            ],
            [
              -118.519233938,
              34.81833323
            ],
            [
              -118.500917157,
              34.818263939
            ],
            [
              -118.484492998,
              34.818255519
            ],
            [
              -118.466714818,
              34.818356235
            ],
            [
              -118.431575103,
              34.818707983
            ],
            [
              -118.413900556,
              34.818924424
            ],
            [
              -118.396521556,
              34.819207589
            ],
            [
              -118.375913258,
              34.819322959
            ],
            [
              -118.326206757,
              34.819675701
            ],
            [
              -118.298911338,
              34.819887117
            ],
            [
              -118.298911338,
              34.747356668
            ],
            [
              -118.30726467,
              34.747324674
            ],
            [
              -118.311221449,
              34.747259523
            ],
            [
              -118.315177432,
              34.747194256
            ],
            [
              -118.316156934,
              34.747178062
            ],
            [
              -118.31616929,
              34.747315306
            ],
            [
              -118.316271488,
              34.752065567
            ],
            [
              -118.312325229,
              34.752140489
            ],
            [
              -118.312326535,
              34.75219544
            ],
            [
              -118.312531114,
              34.760874375
            ],
            [
              -118.311419271,
              34.760887938
            ],
            [
              -118.311447254,
              34.761794819
            ],
            [
              -118.307547133,
              34.761876226
            ],
            [
              -118.307688072,
              34.76914709
            ],
            [
              -118.312139537,
              34.769051848
            ],
            [
              -118.312013231,
              34.761782985
            ],
            [
              -118.320871559,
              34.761596736
            ],
            [
              -118.320643006,
              34.751982309
            ],
            [
              -118.32518382,
              34.751892427
            ],
            [
              -118.325146684,
              34.750645594
            ],
            [
              -118.320698938,
              34.750725582
            ],
            [
              -118.320619613,
              34.747238796
            ],
            [
              -118.320621472,
              34.74711144
            ],
            [
              -118.319132498,
              34.74712522
            ],
            [
              -118.31912928,
              34.746989586
            ],
            [
              -118.318963759,
              34.742294886
            ],
            [
              -118.324094459,
              34.742214348
            ],
            [
              -118.324100254,
              34.742351721
            ],
            [
              -118.324765599,
              34.742340771
            ],
            [
              -118.324902701,
              34.742340774
            ],
            [
              -118.324782787,
              34.739791629
            ],
            [
              -118.324656399,
              34.739792562
            ],
            [
              -118.321818215,
              34.73983491
            ],
            [
              -118.321723743,
              34.737421328
            ],
            [
              -118.318794936,
              34.737463571
            ],
            [
              -118.318943061,
              34.741690458
            ],
            [
              -118.315014788,
              34.741751738
            ],
            [
              -118.314961133,
              34.739937086
            ],
            [
              -118.311042888,
              34.739996866
            ],
            [
              -118.311131734,
              34.743628911
            ],
            [
              -118.307195019,
              34.743692679
            ],
            [
              -118.307022176,
              34.73292151
            ],
            [
              -118.307017236,
              34.732701729
            ],
            [
              -118.306961869,
              34.729197417
            ],
            [
              -118.311327393,
              34.729174956
            ],
            [
              -118.311346965,
              34.732617423
            ],
            [
              -118.3113478,
              34.732644898
            ],
            [
              -118.311351901,
              34.732727164
            ],
            [
              -118.315711282,
              34.73267014
            ],
            [
              -118.315713308,
              34.732587934
            ],
            [
              -118.315701602,
              34.729152316
            ],
            [
              -118.320071884,
              34.729129528
            ],
            [
              -118.320062563,
              34.725505708
            ],
            [
              -118.315688277,
              34.725527134
            ],
            [
              -118.315674941,
              34.721907411
            ],
            [
              -118.320054027,
              34.721894246
            ],
            [
              -118.320044883,
              34.718366592
            ],
            [
              -118.320044698,
              34.71828416
            ],
            [
              -118.318949128,
              34.718285882
            ],
            [
              -118.317852726,
              34.718287568
            ],
            [
              -118.316757189,
              34.718289242
            ],
            [
              -118.315661616,
              34.718290466
            ],
            [
              -118.315591765,
              34.711052422
            ],
            [
              -118.31177053,
              34.711045178
            ],
            [
              -118.306851348,
              34.711035697
            ],
            [
              -118.306807821,
              34.703851184
            ],
            [
              -118.306807578,
              34.703768345
            ],
            [
              -118.311163994,
              34.703793557
            ],
            [
              -118.311164549,
              34.703710593
            ],
            [
              -118.311153205,
              34.700151308
            ],
            [
              -118.315521476,
              34.700168694
            ],
            [
              -118.315520836,
              34.698345595
            ],
            [
              -118.315520196,
              34.696522689
            ],
            [
              -118.315519752,
              34.694760206
            ],
            [
              -118.315519343,
              34.69294554
            ],
            [
              -118.315518911,
              34.691133595
            ],
            [
              -118.315518483,
              34.689349154
            ],
            [
              -118.315518511,
              34.689321676
            ],
            [
              -118.315518613,
              34.689225465
            ],
            [
              -118.324240593,
              34.6892215
            ],
            [
              -118.324199826,
              34.681929424
            ],
            [
              -118.324181765,
              34.678286336
            ],
            [
              -118.324013286,
              34.678286206
            ],
            [
              -118.321990626,
              34.678294268
            ],
            [
              -118.319802221,
              34.678302293
            ],
            [
              -118.319789286,
              34.676482105
            ],
            [
              -118.319776231,
              34.674800764
            ],
            [
              -118.319777068,
              34.674668997
            ],
            [
              -118.324156113,
              34.674640133
            ],
            [
              -118.324305833,
              34.667353292
            ],
            [
              -118.324299819,
              34.665534142
            ],
            [
              -118.324196404,
              34.665535338
            ],
            [
              -118.319819256,
              34.66554772
            ],
            [
              -118.319836703,
              34.661900053
            ],
            [
              -118.321427846,
              34.661592475
            ],
            [
              -118.322854394,
              34.661224449
            ],
            [
              -118.324355708,
              34.661602373
            ],
            [
              -118.324379145,
              34.660067608
            ],
            [
              -118.322436434,
              34.660073928
            ],
            [
              -118.320078162,
              34.66007227
            ],
            [
              -118.319016614,
              34.659630555
            ],
            [
              -118.318265028,
              34.659228426
            ],
            [
              -118.317204016,
              34.65892139
            ],
            [
              -118.316696353,
              34.658343507
            ],
            [
              -118.316433733,
              34.657886214
            ],
            [
              -118.316399174,
              34.657374451
            ],
            [
              -118.316233563,
              34.656701388
            ],
            [
              -118.315872914,
              34.656190468
            ],
            [
              -118.315317537,
              34.655922512
            ],
            [
              -118.314716272,
              34.655843026
            ],
            [
              -118.314152005,
              34.656042868
            ],
            [
              -118.313658715,
              34.656335886
            ],
            [
              -118.31325996,
              34.656463014
            ],
            [
              -118.312825923,
              34.656501405
            ],
            [
              -118.312240655,
              34.656360416
            ],
            [
              -118.311823758,
              34.656137014
            ],
            [
              -118.311295459,
              34.655640322
            ],
            [
              -118.310486705,
              34.655074199
            ],
            [
              -118.309612031,
              34.654525776
            ],
            [
              -118.308409437,
              34.654003693
            ],
            [
              -118.307518342,
              34.653679193
            ],
            [
              -118.306495295,
              34.653471832
            ],
            [
              -118.306491282,
              34.652731529
            ],
            [
              -118.306449169,
              34.645426711
            ],
            [
              -118.304251649,
              34.645432722
            ],
            [
              -118.302054126,
              34.645438694
            ],
            [
              -118.299868246,
              34.645445971
            ],
            [
              -118.298911338,
              34.645448524
            ],
            [
              -118.298911338,
              34.311655678
            ],
            [
              -118.590173754,
              34.311655678
            ],
            [
              -118.590173754,
              34.818203384
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -118.625390854,
              34.05061708
            ],
            [
              -118.625390854,
              34.311655678
            ],
            [
              -118.456022326,
              34.311655678
            ],
            [
              -118.456022326,
              34.05061708
            ],
            [
              -118.625390854,
              34.05061708
            ]
          ]
        ]
      }
    }
  ]
}

最佳答案

Even if it were some great circle discrepancy, I'd expect the point to be intersecting one of the polygons, not outside both of them.

这并不总是一个有效的假设。如果多边形具有相同的边和完全相同的端点,则这将起作用。但事实并非如此,所以每个人都遵循自己的大循环。这是这里可能发生的情况的夸张版本,使用两个完全对齐为几何图形的地理(我使用 BigQuery GeoViz 来绘制它):

select 1 x, st_geogfromtext('polygon((20 20, 40 20, 40 40, 20 40, 20 20))') g1
union all
select 2, st_geogfromtext('polygon((25 40, 50 40, 50 60, 25 60, 25 40))') 

正如您所看到的,当边缘遵循大圆时,两个“矩形”之间既存在重叠又存在孔。

two near-rectangle as geographies

基本上,您需要使用真正代表您所拥有的形状的类型(几何与地理)。 PostGIS 会进行正确的计算,但是当您转换为不同的类型时,可能会得到错误的结果。

如果您使用 Geometry 的原因是缺少 Geography 类型的 PostGIS ST_Subdivide,请考虑制作自己的。我已经为 BigQuery 创建了一个 ST_Subdivide 版本,可以与地理一起使用(BigQuery 缺少几何类型) - 应该可以将其移植到 PostGIS https://mentin.medium.com/subdivide-and-conquer-any-geometry-ca4f0a4b8491 .

关于postgresql - 如何准确确定边界附近的点和地理的 ST_Intersects(ST_Intersects geography vs. Geometry diffrepancy),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76665124/

相关文章:

sql - 授予对 PostgreSQL 中 future 表的特权?

gis - Openlayers 3 WKT writeFeatures rightHanded 不起作用

arrays - 尝试查找任何 int 数组时出错

postgresql - 如何删除 aws redshift 中的 NaN

java - JPA、Wildfly 14 和 PostgreSQL

javascript - 删除传单 map 上的图例

gis - QGIS 在 Ubuntu Precise 上缺少 libjvm.so

postgresql - 如何从 PostGIS 获取地球上两点之间的距离?

python - GeoAlchemy ST_DWithin 实现

python - psycopg2.InternalError : parse error - invalid geometry