Oracle11g 如何将子查询中的点作为SDO_几何体的对象插入到Oracle空间数据库中?

Oracle11g 如何将子查询中的点作为SDO_几何体的对象插入到Oracle空间数据库中?,oracle11g,geospatial,spatial-query,oracle-spatial,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( 20

比如说,我有一个名为
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
  )
);
我可以通过以下查询将矩形插入其中:

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\u坐标阵列的对象。以下两点直接插入到上述查询中:

  • 24.916312、91.832393
  • 24.916392,91.832678
  • 现在,我想插入来自两个不同子查询的这两点

    子查询如下所示:

    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';
    
    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
     )
    );
    
    因此,查询的结果如下所示:

             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_GEOMETRY
    的对象。如果您对oracle spatial查询进行了研究,那么很明显,我只是从返回的对象中检索X和Y的值。

    SDO_CENTROID()函数返回一个SDO_几何体对象,然后您可以使用该对象插入到结果表中

    假设这是您的结果表

    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,如下所示:

    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;
    
    首先定义一个从两个输入点构建矩形的函数

    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_坐标_数组
    仅获取点,而不获取
    sdo_几何体的对象
    。所以,我必须分别得到经度和纬度

    因此,完整的insert查询如下所示:

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

    看起来你们试图用所有建筑物的质心制作另一张桌子,但这不是我的需要,我也没有要求。但你是对的。从某物上加或减x或y是没有意义的。我这样做是因为一些问题,但我从中恢复过来了。我不明白。在您的问题中,您询问了如何插入子查询的结果,这正是我所展示的。但是,你可以对函数的结果做任何你想做的事情:将它插入到某个表中,用它更新某个表,将它保存在变量中,在另一个查询中使用它,在另一个函数调用中使用它。。。你们需要重新表述你们的问题,并澄清你们想要达到的目标。若你们不明白,那个么你们应该先在评论中提问以澄清,我认为。然而,考虑这个查询:<代码>选择SdoyGeOM.SdoyCytoCobe(C.形状,M.DIFFO).SdokPoT从建筑物C,UsRySdodoGeMoMe元数据M,其中M.TabLE.NoNe= =“建筑物”和M.CulnNoNosie=“形状”和C.BuffugIn Nosie=“ICT”;
    返回一个
    SDO\u几何体的对象
    。我想把它添加到我问题的最后一个代码块中,比如
    /*sub query*/
    。但它不起作用。我的问题是如何让它工作?还不清楚。你的意思是想通过将质心函数得到的点附加到现有的直线几何体上来构造直线-有点像从单个点构造GPS轨迹?或者你想用两个质心作为角来构造一个形状(一个矩形?)?这需要一些PL/SQL。在我的回答中看到一个补充。此外,解释您需要解决的原始业务问题以及您一直试图解决的方式总是有帮助的。在我问题中的insert查询中,很明显我试图添加一个矩形。矩形的角点将来自子查询。子查询将返回一个点作为
    SDO\u GEOMETRY
    的对象。但是
    SDO_-ordination_数组
    函数只取点。所以,我在问题中问到,如何解决这个问题?你不能像你那样使用SDO_坐标_数组类型。它仅设计用于SDO_几何图形类型内。您不能使用此类型执行任何操作:特别是,您不能在其上创建任何空间索引,不能查询它,不能使用它执行任何处理。您也无法查看它。只存储四个数字列会更有意义。同样,我不确定您想要实现什么。有一个包含三个几何图形列的建筑表是有意义的:一个用于建筑迹线,一个用于质心,另一个用于“表面上的点”。填充质心和曲面上的点是通过一个简单的更新语句来实现的。@AlbertGodfrind哦,对不起,复制粘贴时我错过了一些代码。谢谢。好的,这有点清楚了。您要寻找的是一种构建矩形的方法,给定两个点(都是SDO_几何体对象)。虽然您使用的代码可能会工作,但它并不是非常有效,因为它涉及多次调用生成点的函数。我建议使用我发布的简单矩形函数。另外一点:几何矩形是纯人工构造的。它们永远不会出现在现实世界中。该形状的唯一用途是用作矩形,用于获取表格以供查看(缩放和平移操作)。您还可以将它们视为SDO_MBR()函数返回的MBR(最小边界矩形)。但你永远不会看到现实生活中的物体(如建筑物)以这种方式建模。