如何在 Oracle 空间数据库中插入来自 sub-query 的点作为 SDO_GEOMETRY 的 object?
How to insert points coming from sub-query as an object of SDO_GEOMETRY in Oracle spatial database?
说,我有一个名为 buildings
的 table,可以通过以下查询创建:
create table buildings(
building_id number primary key,
building_name varchar2(32),
shape sdo_geometry
);
我可以通过以下查询向其中插入一个矩形:
insert into buildings values(
4, -- index
'Reading Room', -- building_name
sdo_geometry(
2003, --SDO_GTYPE: dltt - 2(2D)0(linear referencing)03(polygon)
8307, --SDO_SRID: coordinate system
null, --SDO_POINT: it is for point inserting, if the next two field = null, then it could not be null.
sdo_elem_info_array( --SDO_ELEM_INFO:
1, --SDO_STARTING_OFFSET: indicates from which index of the next param of SDO_GEOMETRY would be considered, starts from 1.
1003, --SDO_ETYPE: 1(exterior, interior - 2)003(this digits usually comes from SDO_GTYPE)
3), --SDO_INTERPRETATION: 1 - simple polygon, 2 - polygon connecting arcs, 3 - rectangle, 4 - circle etc.
sdo_ordinate_array(
24.916312, 91.832393,
24.916392, 91.832678
) --SDO_ORDINATES: co-ordinates of the geometry
-- two corner points of the main diagonal
)
);
这里,两个大地测量点来自真实数据,作为 sdo_ordinate_array
的 object。在上面的查询中直接插入了以下两点:
- 24.916312, 91.832393
- 24.916392, 91.832678
现在,我想插入来自两个不同 sub-query 的这两点。
Sub-queries 会像下面这样:
SELECT 180+SDO_GEOM.SDO_CENTROID(c.shape, m.diminfo).SDO_POINT.X,
180-SDO_GEOM.SDO_CENTROID(c.shape, m.diminfo).SDO_POINT.Y
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT';
因此,查询结果如下:
X Y
---------- ----------
24.9181097 91.83097409
如何将此结果转换为逗号分隔值,例如:24.9181097, 91.83097409
?
这样我就可以替换下面的代码:
sdo_ordinate_array(
24.916312, 91.832393,
24.916392, 91.832678
) --SDO_ORDINATES: co-ordinates of the geometry
与:
sdo_ordinate_array(
(/*sub-query*/),
(/*another-subquery*/)
) --SDO_ORDINATES: co-ordinates of the geometry
我有 google 它并浏览了几个博客,但没有运气。
N.B.:
标题似乎不合适,但是 sub-queries return SDO_GEOMETRY
的 object 的直接版本。如果您探索过 oracle 空间查询,那么您很清楚我只是从 returned object.
中检索 X 和 Y 的值
SDO_CENTROID() 函数 returns 一个 SDO_GEOMETRY 对象,然后您可以将其用于插入结果 table.
假设这是你的结果table
create table building_centroids (
building_id number primary key,
centroid sdo_geometry
);
然后下面将用你所有建筑物的质心填充它
insert into building_centroids (building_id, centroid)
select building_id, sdo_geom.sdo_centroid(shape, 0.05)
from buildings;
我不明白你为什么要改变坐标(180+x,180-y)。这毫无意义。
反正你说上面的不是你想要的。我将继续猜测并假设您想构建一个矩形,其中两个角被计算为您的两个建筑物的质心。这需要一点 PL/SQL,像这样:
首先定义一个从两个输入点构建矩形的函数
create or replace function rectangle_from_points (
point_1 sdo_geometry,
point_2 sdo_geometry
)
return sdo_geometry
as
rectangle sdo_geometry;
begin
-- Initialize resulting rectangle
rectangle := sdo_geometry (2003, point_1.sdo_srid, null,
sdo_elem_info_array (1,1003,3),
sdo_ordinate_array()
);
-- Fill it with the two point points
rectangle.sdo_ordinates.extend(4);
rectangle.sdo_ordinates(1) := point_1.sdo_point.x;
rectangle.sdo_ordinates(2) := point_1.sdo_point.y;
rectangle.sdo_ordinates(3) := point_2.sdo_point.x;
rectangle.sdo_ordinates(4) := point_2.sdo_point.y;
-- Return it
return rectangle;
end;
/
现在,像这样使用它:
select rectangle_from_points (
(
select sdo_geom.sdo_centroid(shape, 0.05)
from buildings
building_id = 42
),
(
select sdo_geom.sdo_centroid(shape, 0.05)
from buildings
building_id = 564
)
)
from dual;
如果这不是您所期望的,那么请重新表述问题(并阐明您要解决的实际业务问题)
我找到了插入的方法。可能存在有效的方法,但这个方法很好用。
sdo_ordinate_array(
--this sub-query returns the Longitude of the first point
(SELECT SDO_GEOM.SDO_CENTROID(c.shape, m.diminfo).SDO_POINT.X X
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT'),
--this sub-query returns the Latitude of the first point
(SELECT SDO_GEOM.SDO_CENTROID(c.shape, m.diminfo).SDO_POINT.Y Y
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT'),
--this sub-query returns the Longitude of the second point
(SELECT SDO_GEOM.SDO_POINTONSURFACE(c.shape, m.diminfo).SDO_POINT.X X
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT'),
--this sub-query returns the Latitude of the second point
(SELECT SDO_GEOM.SDO_POINTONSURFACE(c.shape, m.diminfo).SDO_POINT.Y Y
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT')
) --SDO_ORDINATES: co-ordinates of the geomentry
sdo_ordinate_array
只拿分,不拿sdo_geometry
的对象。所以,我必须分别获取经度和纬度。
因此,完整的插入查询如下所示:
insert into buildings values(
4, -- index
'Reading Room', -- building_name
sdo_geometry(
2003, --SDO_GTYPE: dltt - 2(2D)0(linear referencing)03(polygon)
8307, --SDO_SRID: coordinate system
null, --SDO_POINT: it is for point inserting, if the next two field = null, then it could not be null.
sdo_elem_info_array( --SDO_ELEM_INFO:
1, --SDO_STARTING_OFFSET: indicates from which index of the next param of SDO_GEOMETRY would be considered, starts from 1.
1003, --SDO_ETYPE: 1(exterior, interior - 2)003(this digits usually comes from SDO_GTYPE)
3), --SDO_INTERPRETATION: 1 - simple polygon, 2 - polygon connecting arcs, 3 - rectangle, 4 - circle etc.
sdo_ordinate_array(
--this sub-query returns the Longitude of the first point
(SELECT SDO_GEOM.SDO_CENTROID(c.shape, m.diminfo).SDO_POINT.X X
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT'),
--this sub-query returns the Latitude of the first point
(SELECT SDO_GEOM.SDO_CENTROID(c.shape, m.diminfo).SDO_POINT.Y Y
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT'),
--this sub-query returns the Longitude of the second point
(SELECT SDO_GEOM.SDO_POINTONSURFACE(c.shape, m.diminfo).SDO_POINT.X X
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT'),
--this sub-query returns the Latitude of the second point
(SELECT SDO_GEOM.SDO_POINTONSURFACE(c.shape, m.diminfo).SDO_POINT.Y Y
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT')
) --SDO_ORDINATES: co-ordinates of the geomentry
)
);
说,我有一个名为 buildings
的 table,可以通过以下查询创建:
create table buildings(
building_id number primary key,
building_name varchar2(32),
shape sdo_geometry
);
我可以通过以下查询向其中插入一个矩形:
insert into buildings values(
4, -- index
'Reading Room', -- building_name
sdo_geometry(
2003, --SDO_GTYPE: dltt - 2(2D)0(linear referencing)03(polygon)
8307, --SDO_SRID: coordinate system
null, --SDO_POINT: it is for point inserting, if the next two field = null, then it could not be null.
sdo_elem_info_array( --SDO_ELEM_INFO:
1, --SDO_STARTING_OFFSET: indicates from which index of the next param of SDO_GEOMETRY would be considered, starts from 1.
1003, --SDO_ETYPE: 1(exterior, interior - 2)003(this digits usually comes from SDO_GTYPE)
3), --SDO_INTERPRETATION: 1 - simple polygon, 2 - polygon connecting arcs, 3 - rectangle, 4 - circle etc.
sdo_ordinate_array(
24.916312, 91.832393,
24.916392, 91.832678
) --SDO_ORDINATES: co-ordinates of the geometry
-- two corner points of the main diagonal
)
);
这里,两个大地测量点来自真实数据,作为 sdo_ordinate_array
的 object。在上面的查询中直接插入了以下两点:
- 24.916312, 91.832393
- 24.916392, 91.832678
现在,我想插入来自两个不同 sub-query 的这两点。
Sub-queries 会像下面这样:
SELECT 180+SDO_GEOM.SDO_CENTROID(c.shape, m.diminfo).SDO_POINT.X,
180-SDO_GEOM.SDO_CENTROID(c.shape, m.diminfo).SDO_POINT.Y
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT';
因此,查询结果如下:
X Y
---------- ----------
24.9181097 91.83097409
如何将此结果转换为逗号分隔值,例如:24.9181097, 91.83097409
?
这样我就可以替换下面的代码:
sdo_ordinate_array(
24.916312, 91.832393,
24.916392, 91.832678
) --SDO_ORDINATES: co-ordinates of the geometry
与:
sdo_ordinate_array(
(/*sub-query*/),
(/*another-subquery*/)
) --SDO_ORDINATES: co-ordinates of the geometry
我有 google 它并浏览了几个博客,但没有运气。
N.B.:
标题似乎不合适,但是 sub-queries return SDO_GEOMETRY
的 object 的直接版本。如果您探索过 oracle 空间查询,那么您很清楚我只是从 returned object.
SDO_CENTROID() 函数 returns 一个 SDO_GEOMETRY 对象,然后您可以将其用于插入结果 table.
假设这是你的结果table
create table building_centroids (
building_id number primary key,
centroid sdo_geometry
);
然后下面将用你所有建筑物的质心填充它
insert into building_centroids (building_id, centroid)
select building_id, sdo_geom.sdo_centroid(shape, 0.05)
from buildings;
我不明白你为什么要改变坐标(180+x,180-y)。这毫无意义。
反正你说上面的不是你想要的。我将继续猜测并假设您想构建一个矩形,其中两个角被计算为您的两个建筑物的质心。这需要一点 PL/SQL,像这样:
首先定义一个从两个输入点构建矩形的函数
create or replace function rectangle_from_points (
point_1 sdo_geometry,
point_2 sdo_geometry
)
return sdo_geometry
as
rectangle sdo_geometry;
begin
-- Initialize resulting rectangle
rectangle := sdo_geometry (2003, point_1.sdo_srid, null,
sdo_elem_info_array (1,1003,3),
sdo_ordinate_array()
);
-- Fill it with the two point points
rectangle.sdo_ordinates.extend(4);
rectangle.sdo_ordinates(1) := point_1.sdo_point.x;
rectangle.sdo_ordinates(2) := point_1.sdo_point.y;
rectangle.sdo_ordinates(3) := point_2.sdo_point.x;
rectangle.sdo_ordinates(4) := point_2.sdo_point.y;
-- Return it
return rectangle;
end;
/
现在,像这样使用它:
select rectangle_from_points (
(
select sdo_geom.sdo_centroid(shape, 0.05)
from buildings
building_id = 42
),
(
select sdo_geom.sdo_centroid(shape, 0.05)
from buildings
building_id = 564
)
)
from dual;
如果这不是您所期望的,那么请重新表述问题(并阐明您要解决的实际业务问题)
我找到了插入的方法。可能存在有效的方法,但这个方法很好用。
sdo_ordinate_array(
--this sub-query returns the Longitude of the first point
(SELECT SDO_GEOM.SDO_CENTROID(c.shape, m.diminfo).SDO_POINT.X X
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT'),
--this sub-query returns the Latitude of the first point
(SELECT SDO_GEOM.SDO_CENTROID(c.shape, m.diminfo).SDO_POINT.Y Y
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT'),
--this sub-query returns the Longitude of the second point
(SELECT SDO_GEOM.SDO_POINTONSURFACE(c.shape, m.diminfo).SDO_POINT.X X
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT'),
--this sub-query returns the Latitude of the second point
(SELECT SDO_GEOM.SDO_POINTONSURFACE(c.shape, m.diminfo).SDO_POINT.Y Y
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT')
) --SDO_ORDINATES: co-ordinates of the geomentry
sdo_ordinate_array
只拿分,不拿sdo_geometry
的对象。所以,我必须分别获取经度和纬度。
因此,完整的插入查询如下所示:
insert into buildings values(
4, -- index
'Reading Room', -- building_name
sdo_geometry(
2003, --SDO_GTYPE: dltt - 2(2D)0(linear referencing)03(polygon)
8307, --SDO_SRID: coordinate system
null, --SDO_POINT: it is for point inserting, if the next two field = null, then it could not be null.
sdo_elem_info_array( --SDO_ELEM_INFO:
1, --SDO_STARTING_OFFSET: indicates from which index of the next param of SDO_GEOMETRY would be considered, starts from 1.
1003, --SDO_ETYPE: 1(exterior, interior - 2)003(this digits usually comes from SDO_GTYPE)
3), --SDO_INTERPRETATION: 1 - simple polygon, 2 - polygon connecting arcs, 3 - rectangle, 4 - circle etc.
sdo_ordinate_array(
--this sub-query returns the Longitude of the first point
(SELECT SDO_GEOM.SDO_CENTROID(c.shape, m.diminfo).SDO_POINT.X X
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT'),
--this sub-query returns the Latitude of the first point
(SELECT SDO_GEOM.SDO_CENTROID(c.shape, m.diminfo).SDO_POINT.Y Y
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT'),
--this sub-query returns the Longitude of the second point
(SELECT SDO_GEOM.SDO_POINTONSURFACE(c.shape, m.diminfo).SDO_POINT.X X
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT'),
--this sub-query returns the Latitude of the second point
(SELECT SDO_GEOM.SDO_POINTONSURFACE(c.shape, m.diminfo).SDO_POINT.Y Y
FROM buildings c, user_sdo_geom_metadata m
WHERE m.table_name = 'BUILDINGS' AND m.column_name = 'SHAPE'
AND c.building_name = 'IICT')
) --SDO_ORDINATES: co-ordinates of the geomentry
)
);