【问题标题】:CosmosDB ST_WITHIN and ST_INTERSECTS give different results than using explicit latitude / longitude valuesCosmosDB ST_WITHIN 和 ST_INTERSECTS 给出的结果与使用显式纬度/经度值不同
【发布时间】:2021-10-04 19:06:25
【问题描述】:

我有一个包含 10000 个文档的 CosmosDB 容器。每个文档都包含一个在特定范围内的随机(地理)点。

我正在使用 CosmosDB 模拟器和 Azure Cosmos DB .NET SDK (v3) 来执行一些地理空间查询。但是,使用 ST_INTERSECTS 和 ST_WITHIN 的查询与使用纬度和经度最小值/最大值的查询给出的结果不同,如下所示:

1 - 使用明确的纬度/经度最小值和最大值进行查询 - 给出正确的结果:

SELECT r.id FROM testcontainer r 
 WHERE r.lat >= 53.393183 AND r.lat <= 53.657421
   AND r.lon >= -113.733431 AND r.lon <= -113.247049

Query Total time: 00:00:00.1293465
Total Request Units consumed: 244.15
Documents found: 10000

2 - 使用 ST_INTERSECTS 查询 - 应该与查询 #1 具有相同的结果?

SELECT r.id FROM testcontainer r 
 WHERE ST_INTERSECTS( r.geopoint, {'type':'Polygon','coordinates':[[[-113.247049,53.657421],[-113.733431,53.657421],[-113.733431,53.393183],[-113.247049,53.393183],[-113.247049,53.657421]]]})

Query Total time: 00:00:00.3134729
Total Request Units consumed: 226.17000000000002
Documents found: 9994

3 - 使用 ST_WITHIN 查询 - 应该与查询 #1 具有相同的结果?

SELECT r.id FROM testcontainer r 
 WHERE ST_WITHIN( r.geopoint, {'type':'Polygon','coordinates':[[[-113.247049,53.657421],[-113.733431,53.657421],[-113.733431,53.393183],[-113.247049,53.393183],[-113.247049,53.657421]]]})

Query Total time: 00:00:00.3107136
Total Request Units consumed: 962.91
Documents found: 9994

上述所有查询应该返回了 10000 个文档——但 ST_INTERSECTS 和 ST_WITHIN 似乎不足,只有查询 #1 给出了正确的结果——我无法解释原因。

有没有人知道为什么 ST_WITHIN 和 ST_INTERSECTS 不会给出与具有明确纬度/经度值的查询相同的结果?

其他信息:

当我执行以下查询时:

SELECT r.id, r.geopoint FROM testcontainer r 
 WHERE NOT ST_INTERSECTS( r.geopoint, {'type':'Polygon','coordinates':[[[-113.247049,53.657421],[-113.733431,53.657421],[-113.733431,53.393183],[-113.247049,53.393183],[-113.247049,53.657421]]]})

查询结果是缺少 6 个文档 - 但查看结果,只有一个经度值为 -113.247049 的结果与边界中指定的经度值匹配。

[
    {
        "id": "6892de3d-4b8a-42c6-8421-18b65a70146f",
        "geopoint": {
            "type": "Point",
            "coordinates": [
                -113.465305,
                53.393386
            ]
        }
    },
    {
        "id": "6b89e0fc-7f65-4f75-90db-63dc599b98dd",
        "geopoint": {
            "type": "Point",
            "coordinates": [
                -113.247049,
                53.623584
            ]
        }
    },
    {
        "id": "467a388a-f0fd-4717-9eb5-3a8f538df38b",
        "geopoint": {
            "type": "Point",
            "coordinates": [
                -113.302698,
                53.393212
            ]
        }
    },
    {
        "id": "ada61462-5131-4e25-b0be-3bee42fcde05",
        "geopoint": {
            "type": "Point",
            "coordinates": [
                -113.362105,
                53.393276
            ]
        }
    },
    {
        "id": "3bfd30a7-abcd-4216-905f-5a3831869626",
        "geopoint": {
            "type": "Point",
            "coordinates": [
                -113.340676,
                53.393227
            ]
        }
    },
    {
        "id": "c259a408-e6f0-4050-b7ad-6f55d9a614da",
        "geopoint": {
            "type": "Point",
            "coordinates": [
                -113.400457,
                53.393275
            ]
        }
    }
]

下面是一个 Excel(屏幕快照),它显示了边界纬度/经度值与“缺失”文档中的值之间的差异(差异):

查看差异,根据 Michael Entin 给出的答案,使用 ST_WITHIN / ST_INTERSECTS 时,一个小的偏差将排除一些点。

谢谢。

【问题讨论】:

  • 丢失的 6 个文档是否都非常靠近该区域的边缘?不知道是不是球形测地线比较和平面比较的差异造成的
  • @Schepo - 使用 ST_WITHIN 和 ST_INTERSECTS 时从搜索结果中排除的 6 个文档更新了我的问题。

标签: azure-cosmosdb geospatial spatial-query


【解决方案1】:

这就是geography(具有测地线边缘的球体上的形状)和geometry(平面地图上的形状,其边缘在该地图上看起来是直的)之间的区别。

如果您使用地理,GeoJson“矩形”的“水平”边缘会遵循测地线,因此会向两极弯曲。因此,矩形描述的形状与您所期望的略有不同。

如果您的第一个查询中的最小/最大结果是您想要的 - 切换到 geometry

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    相关资源
    最近更新 更多