对于 Oracle 提供的内置软件包,我想不出任何简单的答案。如果你想在 Oracle 中解决这个问题,你可能不得不考虑编写一些相当糟糕的代码来做到这一点。
一个俗气的解决方案可能是将其分解为几个步骤:
- 暴力破解每组两点之间的所有可能线(选择点的笛卡尔积,将它们构造成线):
- 查找与任何其他线(最外周)不相交的所有线并获取点值。
- 将点值连接回原始表以检索任何数据(如有必要)。
这可能不会很好地执行或扩展,但如果您的数据集不是很大,它应该可以工作。
这是一个简单的说明(未经测试的 SQL)...
输入:
SELECT sdo_geometry(2001, NULL, sdo_point_type(tbl.x, tbl.y, NULL), NULL, NULL)
FROM my_table tbl
坐标的笛卡尔积转换为线:
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
确定所需的行:
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
)
请注意:SQL 未经测试,但希望您能理解。