【问题标题】:How do I select all points which are in a specific circle?如何选择特定圆圈中的所有点?
【发布时间】:2019-09-17 05:21:46
【问题描述】:

我有一个 oracle 数据库,其中有一个包含访问者及其位置的表。 现在我想选择所有在一个有位置和半径的圆中的点。

我对所有的空间函数都不太熟悉,但我尝试了 sdo_contains,第一个参数是访问者的位置。第二个是 SDO_GEOMETRY 类型的圆。我不知道我的选择应该是什么样子,因为我收到错误“没有空间索引不支持接口”。我是否错过了访问者中的一些索引?

我的选择如下所示:

SELECT * FROM visitors v
WHERE SDO_INSIDE(v.position,
SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1,1003,4), SDO_ORDINATE_ARRAY(8,7, 10,9, 8,11))) = 'TRUE';

【问题讨论】:

    标签: oracle spatial oracle-spatial


    【解决方案1】:

    您需要在position 列上定义空间索引。为此,您首先需要定义所需的空间元数据。像这样:

    insert into user_sdo_geom_metadata (table_name, column_name, dim info, srid)
    values (
      'visitors',
      'position',
      sdo_dim_array (
         sdo_dim_element ('x',-1000,1000,0.05),
         sdo_dim_element ('y',-1000,1000,0.05)
      ),
      null
    );
    commit;
    

    然后就可以创建空间索引了:

    create index visitors_sx on visitors(position)
      indextype is mdsys.spatial_index;
    

    然后您的查询将完成。

    注意事项

    (1) 以上假设您的空间数据(位置)处于抽象笛卡尔坐标中(即不包含任何明确的坐标参考系统 ID:SDO_SRIDNULL)。您的查询窗口也是如此。然而,在现实世界的应用程序中,您应该始终使用显式坐标参考系统,即始终填充 SDO_SRID。如果您的坐标是大地坐标(即经度/纬度),这一点尤其重要。以笛卡尔方式匹配它们将返回不正确的结果。此外,没有明确的 SRID 意味着您将无法进行任何测量或将数据与其他坐标系中的数据进行匹配。

    (2) 从 Oracle 12.2 开始,空间索引是可选的。由于您收到错误,我假设您正在运行 Oracle 数据库的旧(可能已过时)版本。最新版本是 Oracle 19c。 但是对于实际应用程序,您应该始终拥有空间索引 - 除非您的数据非常小:比如只有几个对象。任何 200 个或更多对象都需要空间索引才能获得适当的性能水平。

    【讨论】:

    • 非常感谢!是的,我的 Oracle 数据库在 11g 上运行,这就是我收到索引错误的原因。但是,我尝试在没有 sdo_contains 函数的情况下进行查询,并且只使用 sdo_distance 来计算点是否在圆中:SELECT v.id, v.name, t.x, t.y FROM visitors v, table(SDO_UTIL.GETVERTICES(v.position))t WHERE SDO_GEOM.SDO_DISTANCE(v.position, SDO_GEOMETRY(2001,NULL,SDO_POINT_TYPE(421,81,NULL), NULL, NULL), 0.005) < 50;
    • 这会给你正确的答案。但是,如果存在任何空间索引,它将使用。在现实生活中(包含数百万或仅数十万对象的表),它会非常慢:空间索引对于实现 ms 性能至关重要。更好的方法是使用SDO_WITHIN_DISTANCE 运算符,如下所示:SELECT v.id, v.name, v.position.sdo_point.x, v.position.sdo_point.y FROM visitors v WHERE SDO_WITHIN_DISTANCE(v.position, SDO_GEOMETRY(2001,NULL,SDO_POINT_TYPE(421,81,NULL), NULL, NULL), 'distance=50') = 'TRUE'
    • 再次注意,由于没有指定坐标系,距离将在笛卡尔空间中计算,距离(50)基于数据的单位。最好始终为所有空间数据指定正确的坐标系标识符,尤其是大地测量(经度/纬度)数据。
    猜你喜欢
    • 2017-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    相关资源
    最近更新 更多