如何在Oracle空间数据库中插入来自子查询的点作为SDO_GEOMETRY的对象?

时间:2015-12-13 19:49:27

标签: oracle11g geospatial spatial-query oracle-spatial

说,我有一个名为buildings的表,可以通过以下查询创建:

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的对象。以下两点直接插入上述查询中:

  1. 24.916312,91.832393
  2. 24.916392,91.832678
  3. 现在,我想从两个不同的子查询中插入这两个点。

    子查询如下:

    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
    

    我有谷歌它并探索了几个博客,但没有运气。

    N.B:

    标题似乎不合适,但子查询的简单版本返回SDO_GEOMETRY的对象。如果你研究了oracle空间查询,那么你很清楚我只是从返回的对象中检索X和Y的值。

2 个答案:

答案 0 :(得分:0)

SDO_CENTROID()函数返回一个SDO_GEOMETRY对象,然后您可以将其用于插入结果表。

假设这是你的结果表

List<MyMarker> markers = new ArrayList<>();
MyMarker myMarker = new MyMarker(
    new LatLng(1.123456, -2.123456), 
    BitmapDescriptorFactory.fromResource(R.drawable.icon2)),
    "title1",
    "snippet1");
markers.add(myMarker);

然后以下内容将填充所有建筑物的质心

create table building_centroids (
  building_id number primary key,
  centroid sdo_geometry
);

我不明白为什么你需要改变坐标(180 + x,180-y)。这毫无意义。

无论如何,你说以上不是你想要的。我将继续猜测,并假设您要构建一个矩形,其中两个角被计算为两个建筑物中的质心。这需要一些PL / SQL,如下所示:

首先定义一个从两个输入点构建矩形的函数

insert into building_centroids (building_id, centroid)
select building_id, sdo_geom.sdo_centroid(shape, 0.05)
from buildings;

现在,像这样使用它:

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;
/

如果这不符合您的预期,请重新提出问题(并澄清您要解决的实际业务问题)

答案 1 :(得分:0)

我发现了一种插入方式。可能存在有效的方法,但这个工作正常。

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
 )
);