基于周边点的多边形 - oracle spatial

时间:2013-06-15 12:13:48

标签: oracle spatial oracle-spatial grahams-scan

我有一张桌子。我想基于这些点创建多边形,然后只返回周边的这些点(不包括多边形内的点)。有没有简单的方法在数据库级别使用SDO GEOMETRY做到这一点?我发现它像GrahamScan,但我找不到像Spatial那样的东西

2 个答案:

答案 0 :(得分:2)

我无法想到Oracle提供的内置软件包的任何 easy 答案。如果要在Oracle中解决问题,可能必须考虑编写一些相当可怕的代码来执行此操作。

一个俗气的解决方案可能是将其分解为几个步骤:

  1. 在每组两点之间强行所有可能的线(选择点的笛卡尔积,将它们构造成线):
  2. 查找与任何其他线(最外边界)没有交叉点的所有线,并获取点值。
  3. 将点值连接回原始表格以检索任何数据(如有必要)。
  4. 这可能无法正常执行或扩展,但如果您的数据集不是很大,它应该可以正常工作。

    这是一个快速说明(未经测试的SQL)......

    <强>输入

    SELECT sdo_geometry(2001, NULL, sdo_point_type(tbl.x, tbl.y,  NULL), NULL, NULL)
    FROM my_table tbl
    

    Inputs to algorithm

    坐标转换为直线的笛卡尔积:

    WITH point_cartesian AS (
      SELECT 
        tbl.x x1
      , tbl.y y1
      , tbl2.x x2
      , tbl2.y y2
      FROM my_table tbl
      CROSS JOIN my_table tbl2
      WHERE tbl.x != tbl2.x 
      OR tbl.y != tbl2.y
    )
    SELECT sdo_geometry(
      2002
    , NULL
    , NULL
    , sdo_elem_info_array(1, 2, 1)
    , sdo_ordinate_array(x1, y1, x2, y2)
    )
    FROM point_cartesian
    

    Cartesian product of coordinates converted to lines

    确定所需的行:

    WITH point_cartesian AS (
      SELECT 
        tbl.x x1
      , tbl.y y1
      , tbl2.x x2
      , tbl2.y y2
      FROM my_table tbl
      CROSS JOIN my_table tbl2
      WHERE tbl.x != tbl2.x 
      OR tbl.y != tbl2.y
    )
    , lines AS (
      SELECT sdo_geometry(
        2002
      , NULL
      , NULL
      , sdo_elem_info_array(1, 2, 1)
      , sdo_ordinate_array(x1, y1, x2, y2)
      ) geom
      , ROWNUM line_id
      FROM point_cartesian
    )
    SELECT *
    FROM lines l1
    WHERE NOT EXISTS (
      SELECT 1
      FROM lines l2
      WHERE l2.line_id != l1.line_id
      AND sdo_geom.sdo_intersect (l1.geom, l2.geom, 0.05) IS NOT NULL
    )
    

    Identify lines

    请注意:SQL未经测试,但希望您明白这一点。

答案 1 :(得分:2)

如果数据确实如第一个答案中所描述的那样,那么最简单和最快速的方法就是在你的点集周围获得凸包。假设您的输入是表MY_TABLE,其中包含两列,X和Y代表经度和纬度(因此SRID为4326):

select sdo_aggr_convexhull (
         sdoaggrtype (
           sdo_geometry(2001, 4326, sdo_point_type(x, y,  NULL), NULL, NULL),
           0.5
         )
       )
from my_table;

结果是使用周边点构造的多边形。