根据 x 和 y 坐标列表从 Oracle 查询几何对象列表
Querying a list of geometry objects from Oracle based on list of x and y coordinates
我们正在使用具有 SDO_GEOMETRY
个对象的 Oracle 数据库 table。我想 return 具有几何对象的列包含某个 point
(x,y 坐标)的行。
我知道我可以使用这样的单点几何查询 table:
[..]
WHERE SDO_CONTAINS(D.D_SHAPE, SDO_GEOMETRY(
2001,
NULL,
SDO_POINT_TYPE(<myXCoordinate>, <myYCoordinate>, NULL),
NULL,
NULL)) = 'TRUE'
但是假设我有一个 list
坐标,并且我想要所有几何体 objects/rows,其中对象至少包含列表中的一个坐标。我该怎么做?
我知道我可以例如实现一个 OR
并做类似的事情:
WHERE SDO_CONTAINS(D.D_SHAPE, SDO_GEOMETRY(
2001,
NULL,
SDO_POINT_TYPE(<myXCoordinate1>, <myYCoordinate1>, NULL),
NULL,
NULL)) = 'TRUE'
OR SDO_CONTAINS(D.D_SHAPE, SDO_GEOMETRY(
2001,
NULL,
SDO_POINT_TYPE(<myXCoordinate2>, <myYCoordinate2>, NULL),
NULL,
NULL)) = 'TRUE'
但是当有一个列表时,这似乎不能很好地扩展。 1000个坐标对吧?
另外,我可能有一个带有 x 和 y 坐标的临时 table,并且想使用连接。不确定在这里该怎么做?
您可以使用 SDO_CONTAINS
函数将您的点“列表”与 table 形状连接起来。
如果此列表来自其他 table,您可以按原样应用连接(或通过构建 SDO_GEOMETRY
类型的点)。如果您需要“手动”传递它们,那么没有选择,因为我不知道 Oracle 中方便的行集生成函数(如其他 DBMS 中的 select ... from values ...
)。一些练习可以用 JSON 来完成,或者你可以使用集合类型作为记录的来源,它可以手动“输入”或从外部传递。
insert into poly
/*Growing squares centered in (0,0)*/
select
level
, sdo_geometry(
2003
, null, null
, SDO_ELEM_INFO_ARRAY(1, 1003, 3)
, SDO_ORDINATE_ARRAY(-level, -level, level, level)
)
from dual
connect by level < 6
insert into point
/*List of points (0, y)*/
select
level
, 0
, level
from dual
connect by level < 8
select
p.*
, pl.id as contained_in
, pl.poly.get_wkt() as contained_in_wkt
from point p
left join poly pl
/*You may construct point on-the-fly from its coordinates*/
on SDO_CONTAINS(pl.poly, sdo_geometry(
2001
, null
, sdo_point_type(p.x, p.y, null)
, null
, null
)) = 'TRUE'
where 1 = 1
order by
p.id
, pl.id
ID | X | Y | CONTAINED_IN | CONTAINED_IN_WKT
-: | -: | -: | -----------: | :------------------------------------------------------------
1 | 0 | 1 | 2 | POLYGON ((-2.0 -2.0, 2.0 -2.0, 2.0 2.0, -2.0 2.0, -2.0 -2.0))
1 | 0 | 1 | 3 | POLYGON ((-3.0 -3.0, 3.0 -3.0, 3.0 3.0, -3.0 3.0, -3.0 -3.0))
1 | 0 | 1 | 4 | POLYGON ((-4.0 -4.0, 4.0 -4.0, 4.0 4.0, -4.0 4.0, -4.0 -4.0))
1 | 0 | 1 | 5 | POLYGON ((-5.0 -5.0, 5.0 -5.0, 5.0 5.0, -5.0 5.0, -5.0 -5.0))
2 | 0 | 2 | 3 | POLYGON ((-3.0 -3.0, 3.0 -3.0, 3.0 3.0, -3.0 3.0, -3.0 -3.0))
2 | 0 | 2 | 4 | POLYGON ((-4.0 -4.0, 4.0 -4.0, 4.0 4.0, -4.0 4.0, -4.0 -4.0))
2 | 0 | 2 | 5 | POLYGON ((-5.0 -5.0, 5.0 -5.0, 5.0 5.0, -5.0 5.0, -5.0 -5.0))
3 | 0 | 3 | 4 | POLYGON ((-4.0 -4.0, 4.0 -4.0, 4.0 4.0, -4.0 4.0, -4.0 -4.0))
3 | 0 | 3 | 5 | POLYGON ((-5.0 -5.0, 5.0 -5.0, 5.0 5.0, -5.0 5.0, -5.0 -5.0))
4 | 0 | 4 | 5 | POLYGON ((-5.0 -5.0, 5.0 -5.0, 5.0 5.0, -5.0 5.0, -5.0 -5.0))
5 | 0 | 5 | null | null
6 | 0 | 6 | null | null
7 | 0 | 7 | null | null
下面是集合类型示例。
/*Object type to access instances as a single field*/
create type ts_sdo as object (
shape sdo_geometry
)
/*Table of SDO_GEOMETRY*/
create type tt_sdo as varray (1048576) of ts_sdo
select
p.shape.get_wkt() as point_wkt
, pl.id as contained_in
, pl.poly.get_wkt() as contained_in_wkt
from table(
/*Then we construct collection from list of points*/
tt_sdo(
/*Each member is constructed from SDO_GEOMETRY*/
ts_sdo(sdo_geometry('POINT(0 1)'))
, ts_sdo(sdo_geometry(
2001
, null
, sdo_point_type(0, 10, 0)
, null
, null
))
)) p
left join poly pl
on SDO_CONTAINS(pl.poly, p.shape) = 'TRUE'
where 1 = 1
order by
pl.id
POINT_WKT | CONTAINED_IN | CONTAINED_IN_WKT
:--------------- | -----------: | :------------------------------------------------------------
POINT (0.0 1.0) | 2 | POLYGON ((-2.0 -2.0, 2.0 -2.0, 2.0 2.0, -2.0 2.0, -2.0 -2.0))
POINT (0.0 1.0) | 3 | POLYGON ((-3.0 -3.0, 3.0 -3.0, 3.0 3.0, -3.0 3.0, -3.0 -3.0))
POINT (0.0 1.0) | 4 | POLYGON ((-4.0 -4.0, 4.0 -4.0, 4.0 4.0, -4.0 4.0, -4.0 -4.0))
POINT (0.0 1.0) | 5 | POLYGON ((-5.0 -5.0, 5.0 -5.0, 5.0 5.0, -5.0 5.0, -5.0 -5.0))
POINT (0.0 10.0) | null | null
db<>fiddle here
我们正在使用具有 SDO_GEOMETRY
个对象的 Oracle 数据库 table。我想 return 具有几何对象的列包含某个 point
(x,y 坐标)的行。
我知道我可以使用这样的单点几何查询 table:
[..]
WHERE SDO_CONTAINS(D.D_SHAPE, SDO_GEOMETRY(
2001,
NULL,
SDO_POINT_TYPE(<myXCoordinate>, <myYCoordinate>, NULL),
NULL,
NULL)) = 'TRUE'
但是假设我有一个 list
坐标,并且我想要所有几何体 objects/rows,其中对象至少包含列表中的一个坐标。我该怎么做?
我知道我可以例如实现一个 OR
并做类似的事情:
WHERE SDO_CONTAINS(D.D_SHAPE, SDO_GEOMETRY(
2001,
NULL,
SDO_POINT_TYPE(<myXCoordinate1>, <myYCoordinate1>, NULL),
NULL,
NULL)) = 'TRUE'
OR SDO_CONTAINS(D.D_SHAPE, SDO_GEOMETRY(
2001,
NULL,
SDO_POINT_TYPE(<myXCoordinate2>, <myYCoordinate2>, NULL),
NULL,
NULL)) = 'TRUE'
但是当有一个列表时,这似乎不能很好地扩展。 1000个坐标对吧?
另外,我可能有一个带有 x 和 y 坐标的临时 table,并且想使用连接。不确定在这里该怎么做?
您可以使用 SDO_CONTAINS
函数将您的点“列表”与 table 形状连接起来。
如果此列表来自其他 table,您可以按原样应用连接(或通过构建 SDO_GEOMETRY
类型的点)。如果您需要“手动”传递它们,那么没有选择,因为我不知道 Oracle 中方便的行集生成函数(如其他 DBMS 中的 select ... from values ...
)。一些练习可以用 JSON 来完成,或者你可以使用集合类型作为记录的来源,它可以手动“输入”或从外部传递。
insert into poly /*Growing squares centered in (0,0)*/ select level , sdo_geometry( 2003 , null, null , SDO_ELEM_INFO_ARRAY(1, 1003, 3) , SDO_ORDINATE_ARRAY(-level, -level, level, level) ) from dual connect by level < 6
insert into point /*List of points (0, y)*/ select level , 0 , level from dual connect by level < 8
select p.* , pl.id as contained_in , pl.poly.get_wkt() as contained_in_wkt from point p left join poly pl /*You may construct point on-the-fly from its coordinates*/ on SDO_CONTAINS(pl.poly, sdo_geometry( 2001 , null , sdo_point_type(p.x, p.y, null) , null , null )) = 'TRUE' where 1 = 1 order by p.id , pl.id
ID | X | Y | CONTAINED_IN | CONTAINED_IN_WKT -: | -: | -: | -----------: | :------------------------------------------------------------ 1 | 0 | 1 | 2 | POLYGON ((-2.0 -2.0, 2.0 -2.0, 2.0 2.0, -2.0 2.0, -2.0 -2.0)) 1 | 0 | 1 | 3 | POLYGON ((-3.0 -3.0, 3.0 -3.0, 3.0 3.0, -3.0 3.0, -3.0 -3.0)) 1 | 0 | 1 | 4 | POLYGON ((-4.0 -4.0, 4.0 -4.0, 4.0 4.0, -4.0 4.0, -4.0 -4.0)) 1 | 0 | 1 | 5 | POLYGON ((-5.0 -5.0, 5.0 -5.0, 5.0 5.0, -5.0 5.0, -5.0 -5.0)) 2 | 0 | 2 | 3 | POLYGON ((-3.0 -3.0, 3.0 -3.0, 3.0 3.0, -3.0 3.0, -3.0 -3.0)) 2 | 0 | 2 | 4 | POLYGON ((-4.0 -4.0, 4.0 -4.0, 4.0 4.0, -4.0 4.0, -4.0 -4.0)) 2 | 0 | 2 | 5 | POLYGON ((-5.0 -5.0, 5.0 -5.0, 5.0 5.0, -5.0 5.0, -5.0 -5.0)) 3 | 0 | 3 | 4 | POLYGON ((-4.0 -4.0, 4.0 -4.0, 4.0 4.0, -4.0 4.0, -4.0 -4.0)) 3 | 0 | 3 | 5 | POLYGON ((-5.0 -5.0, 5.0 -5.0, 5.0 5.0, -5.0 5.0, -5.0 -5.0)) 4 | 0 | 4 | 5 | POLYGON ((-5.0 -5.0, 5.0 -5.0, 5.0 5.0, -5.0 5.0, -5.0 -5.0)) 5 | 0 | 5 | null | null 6 | 0 | 6 | null | null 7 | 0 | 7 | null | null
下面是集合类型示例。
/*Object type to access instances as a single field*/ create type ts_sdo as object ( shape sdo_geometry )
/*Table of SDO_GEOMETRY*/ create type tt_sdo as varray (1048576) of ts_sdo
select p.shape.get_wkt() as point_wkt , pl.id as contained_in , pl.poly.get_wkt() as contained_in_wkt from table( /*Then we construct collection from list of points*/ tt_sdo( /*Each member is constructed from SDO_GEOMETRY*/ ts_sdo(sdo_geometry('POINT(0 1)')) , ts_sdo(sdo_geometry( 2001 , null , sdo_point_type(0, 10, 0) , null , null )) )) p left join poly pl on SDO_CONTAINS(pl.poly, p.shape) = 'TRUE' where 1 = 1 order by pl.id
POINT_WKT | CONTAINED_IN | CONTAINED_IN_WKT :--------------- | -----------: | :------------------------------------------------------------ POINT (0.0 1.0) | 2 | POLYGON ((-2.0 -2.0, 2.0 -2.0, 2.0 2.0, -2.0 2.0, -2.0 -2.0)) POINT (0.0 1.0) | 3 | POLYGON ((-3.0 -3.0, 3.0 -3.0, 3.0 3.0, -3.0 3.0, -3.0 -3.0)) POINT (0.0 1.0) | 4 | POLYGON ((-4.0 -4.0, 4.0 -4.0, 4.0 4.0, -4.0 4.0, -4.0 -4.0)) POINT (0.0 1.0) | 5 | POLYGON ((-5.0 -5.0, 5.0 -5.0, 5.0 5.0, -5.0 5.0, -5.0 -5.0)) POINT (0.0 10.0) | null | null
db<>fiddle here