我需要找到不同道路的交叉点,但每条道路分为多个区段,因此一条道路有很多记录。我有这个查询,我可以用来查找几何,但每个显示为null。我需要有一个几何体,以便我可以将其插入一个记录中。
SELECT SDO_GEOM.SDO_INTERSECTION(coll_a.GEOMETRY, coll_b.GEOMETRY, 0.05)
FROM OTTAWACOLLECTORS coll_a, OTTAWACOLLECTORS coll_b
WHERE coll_a.ROAD_NAME = 'KENT' AND coll_b.ROAD_NAME = 'METCALFE';
答案 0 :(得分:0)
解决此类问题的最有效方法是使用SDO_JOIN()过滤器。它旨在使用空间索引有效地将许多其他对象与空间索引进行匹配。
我假设你的桌子看起来像这样:
create table ottawacollectors (
road_id number,
segment_id number,
road_name varchar2(30),
geometry sdo_geometry,
primary key (road_id, segment_id)
);
它包含路段。每个道路段由道路标识符和段标识符标识。
以下内容创建了新表INTERSECTIONS,每个交叉点包含一行,即每当两个路段相互作用时。交点计算为几何点。每行包含每个段的标识符(道路标识符和段标识符)以及每条道路的名称。
create table intersections as
select a.road_id road_id_1, a.segment_id segment_id_1, a.road_name road_name_1,
b.road_id road_id_2, b.segment_id segment_id_2, b.road_name road_name_2,
sdo_geom.sdo_intersection (
a.geometry, b.geometry, 0.05
) intersection_point
from ottawacollectors a,
ottawacollectors b,
table (
sdo_join(
'OTTAWACOLLECTORS','GEOMETRY',
'OTTAWACOLLECTORS','GEOMETRY',
'MASK=ANYINTERACT'
)
) j
where a.rowid = j.rowid1
and b.rowid = j.rowid2
and j.rowid1 > j.rowid2;
一些解释:
SDO_JOIN()
是"表"功能。它采用两个输入表的名称(表名和几何列的名称)和匹配条件 - 这里" ANYINTERACT",意味着任何类型的互动:片段可能交叉或只是相互接触。TABLE()
构造函数强制转换该数组,以使其看起来像常规表,从而可以轻松地将其嵌入到关系查询中。那"虚拟" table在查询中称为J. OTTAWACOLLECTORS
表(如示例所示)。它使用TABLE()
结果J.ROWID1=A.ROWID AND J.ROWID2=B.ROWID
J.ROWID1>J.ROWID2
过滤器用于消除不需要的结果。假设路段A和B相交。 SDO_JOIN将返回4个组合:(A,B),还有(B,A)以及(A,A)和(B,B),因为一个段明显与自身相交!比较rowid的目的是仅保留(A,B)或(B,A)中的一个。SDO_GEOM.SDO_INTERSECTION()
计算,如示例所示)。请注意,此查询不会立即返回结果:可能需要几分钟才能完成,具体取决于您需要处理的路段数量,当然还有您运行它的硬件。如果您在Oracle 12c(12.1.0.1或12.1.0.2)上运行它并拥有适用于Oracle Spatial的正确许可,请确保已启用Vector Performance Accelerator选项。