假设有表记录点坐标信息如下
create table tbl_point(
PointID varchar(10),  --点坐标编号
X numeric(8,2),    --X坐标
Y numeric(8,2)     --Y坐标
);现在要求查询出表中属于某个任意多变形区域内的数据点记录;各位达人有什么高招没?
我采用的方法是,写一个函数,判断点point(x,y)是否在任意多边形区域polygon内。
create type point as object(
X numeric(8,2),    --X坐标
Y numeric(8,2)     --Y坐标 
);create type polygon as table of point;create function pointinpolygon(Apolygon polygon,Apoint point)
return boolean
as
begin
  ...
end;然后在查询的时候使用语句
select * from tbl_point
where pointinpolygon(Apolygon,point(x,y)) ;但这种方案明显效率偏低;
有没有更好的解决方式?

解决方案 »

  1.   

    /*第一步,使用MDSYS.SDO_GEOMETRY类型标识控制点的坐标*/
    create table tbl_point(
      ID varchar(10),
      Name varchar2(10),
      XY MDSYS.SDO_GEOMETRY);/第二步,填写xy坐标范围与精度/
    insert into user_sdo_geom_metadata
    values('tbl_point',
    'xy',
    MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',-1000,1000,0.01),
                        MDSYS.SDO_DIM_ELEMENT('Y',-1000,1000,0.01)),
    null
    );
    /*第三步,在xy字段上创建空间索引辅助对数据查询执行*/
    create index tbl_point_index on tbl_point(xy) 
    indextype is MDSYS.SPATIAL_INDEX;/*第四步,插入空间数据*/
    insert into tbl_point(ID,name,XY)
    select 'KZD7101901','控制点01',
    MDSYS.SDO_GEOMETRY(2001,null,MDSYS.SDO_POINT_TYPE(1,1,null),null,null) from dual union all
    select 'KZD7101902','控制点02',
    MDSYS.SDO_GEOMETRY(2001,null,MDSYS.SDO_POINT_TYPE(1,2,null),null,null) from dual union all
    select 'KZD7101903','控制点03',
    MDSYS.SDO_GEOMETRY(2001,null,MDSYS.SDO_POINT_TYPE(1,3,null),null,null) from dual union all
    select 'KZD7101904','控制点04',
    MDSYS.SDO_GEOMETRY(2001,null,MDSYS.SDO_POINT_TYPE(1,1,null),null,null) from dual union all
    select 'KZD7101905','控制点05',
    MDSYS.SDO_GEOMETRY(2001,null,MDSYS.SDO_POINT_TYPE(0,1,null),null,null) from dual;/* 查询在多边形内的控制点数据并展示*/
    declare
      ARolygon MDSYS.SDO_GeomeTRY;  --创建多边形
    begin
      AROLYGON := new MDSYS.SDO_GeomeTRY(2003,null,null,
                                  MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1),
                                  MDSYS.SDO_ORDINATE_ARRAY(0,0,0,1.5,2,1.5,2,0));
      
      for myrecord in (
                    select a.ID,a.name,a.xy.SDO_POINT.x x坐标, a.xy.SDO_POINT.y Y坐标 
                    from tbl_point a
                    where  MDSYS.SDO_RELATE(a.xy,AROLYGON,'mask=anyinteract querytype=window') = 'TRUE' ) 
      loop
        dbms_output.put_line(myrecord.ID||','||myrecord.name||','||myrecord.X坐标||','||myrecord.Y坐标);
      end loop;  
    end;--执行结果
    KZD7101904,控制点04,1,1
    KZD7101905,控制点05,0,1
    KZD7101901,控制点01,1,1