zoukankan      html  css  js  c++  java
  • Oracle查询多边形对象SDO_GEOMETRY并转换为java对象举例

      最近实现了一个判断点是否与多边形交互的功能,这里的点是一个经纬度,多边形是一个区域,包含多个经纬度,最后看下这个点是否在这个区域内。就好比你打开百度地图,然后看你自己的位置(点)是不是在某个小区(多边形)里。在Oracle里几何对象用的是MDSYS的SDO_GEOMETRY类型,第一次碰到这种数据类型,先看下定义

    SQL> desc MDSYS.SDO_GEOMETRY;
    Element       Type                      
    ------------- ------------------------- 
    SDO_GTYPE     NUMBER                    
    SDO_SRID      NUMBER                    
    SDO_POINT     MDSYS.SDO_POINT_TYPE      
    SDO_ELEM_INFO MDSYS.SDO_ELEM_INFO_ARRAY 
    SDO_ORDINATES MDSYS.SDO_ORDINATE_ARRAY  
    GET_GTYPE     FUNCTION                  
    GET_DIMS      FUNCTION                  
    GET_LRS_DIM   FUNCTION                  
    GET_WKB       FUNCTION                  
    GET_WKT       FUNCTION                  
    ST_COORDDIM   FUNCTION                  
    ST_ISVALID    FUNCTION                  
    SDO_GEOMETRY  FUNCTION 

      这里不细讲这个数据类型,我们只需要知道我这里有张表里包含了这种类型的字段

    create table GRID
    (
      ID           VARCHAR2(32),
      NAME       VARCHAR2(64),
      INSERT_TIME   DATE,
      LOCA_TION     MDSYS.SDO_GEOMETRY
    )

      现在我需要查loca_tiom字段值,得到多边形的数据,我们试试直接查这个字段

    SQL> select loca_tion from grid where rownum < 10;
     
    LOCA_TION
    ---------
    <Object>
    <Object>
    <Object>
    <Object>
    <Object>
    <Object>
    <Object>
    <Object>
    <Object>
     
    9 rows selected

      查不到,因为SDO_GEOMETRY是一种定义出来的数据类型,所以是一个对象。再试试用oracle自带的工具包方法

    SQL> select to_char(sdo_util.to_gmlgeometry(loca_tion)) from i2_grid_info_cur where rownum < 10;
     
    TO_CHAR(SDO_UTIL.TO_GMLGEOMETR
    --------------------------------------------------------------------------------
    <gml:Polygon srsName="SDO:8307" xmlns:gml="http://www.opengis.net/gml"><gml:oute
    <gml:Polygon srsName="SDO:8307" xmlns:gml="http://www.opengis.net/gml"><gml:oute
    <gml:Polygon srsName="SDO:8307" xmlns:gml="http://www.opengis.net/gml"><gml:oute
    <gml:Polygon srsName="SDO:8307" xmlns:gml="http://www.opengis.net/gml"><gml:oute
    <gml:Polygon srsName="SDO:8307" xmlns:gml="http://www.opengis.net/gml"><gml:oute
    <gml:Polygon srsName="SDO:8307" xmlns:gml="http://www.opengis.net/gml"><gml:oute
    <gml:Polygon srsName="SDO:8307" xmlns:gml="http://www.opengis.net/gml"><gml:oute
    <gml:Polygon srsName="SDO:8307" xmlns:gml="http://www.opengis.net/gml"><gml:oute
    <gml:Polygon srsName="SDO:8307" xmlns:gml="http://www.opengis.net/gml"><gml:oute
     
    9 rows selected

      这时可以查到了,但得到的是一个定义元数据的类似xml文本,这种格式叫GML。我们需要解析这个文本才行,这也不是我们想要的。接着用另一个工具方法

    SQL> select ID, t.x LONGITUDE, t.y LATITUDE from I2_GRID_INFO_CUR,table (sdo_util.getvertices(LOCA_TION)) t where rownum < 10;
     
    ID                               LONGITUDE   LATITUDE
    -------------------------------- ---------- ----------
    W_12101_1267                     120.020046 30.0552959
    W_12101_1267                     120.025472 30.0546780
    W_12101_1267                     120.037507 30.0530230
    W_12101_1267                     120.033047 30.0475079
    W_12101_1267                     120.032709 30.0457979
    W_12101_1267                     120.020461 30.0510129
    W_12101_1267                     120.020046 30.0552959
    W_12101_1269                     120.371666 30.3074470
    W_12101_1269                     120.371691 30.3048049
     
    9 rows selected

      这次我们查到了数据,得到的是对象的点坐标,同一个ID存在多个经纬度点,我们的数据是分开的,这种情况我们可以在代码里处理一下进行合并。但其实是可以直接得到我们想要的数据的,最终方法

    SQL> select ID,to_char(sdo_util.to_wktgeometry(loca_tion)) as LOACTION from i2_grid_info_cur where rownum < 10;
     
    ID                              LOACTION
    -------------------------------- --------------------------------------------------------------------------------
    W_12101_1267                     POLYGON ((120.02004612 30.0552959680001, 120.02547204 30.054678073, 120.03750792
    W_12101_1269                     POLYGON ((120.37166604 30.307447059, 120.37169196 30.3048049230001, 120.36850092
    W_12101_1270                     POLYGON ((120.17660796 30.3214770650001, 120.178233 30.3194360100001, 120.178289
    W_12101_1272                     POLYGON ((120.19454784 30.1169789890001, 120.19940208 30.117213007, 120.19855212
    W_12101_1273                     POLYGON ((119.93450904 30.273637046, 119.93518188 30.2715850450001, 119.93440284
    W_12101_1792                     POLYGON ((120.29597712 30.4123550300001, 120.29666004 30.411310928, 120.29740704
    W_12101_1797                     POLYGON ((120.38929884 30.3079359440001, 120.38813208 30.3047020450001, 120.3824
    W_12101_1801                     POLYGON ((120.174912 30.1599599400001, 120.17404008 30.158240961, 120.17396988 3
    W_12101_1804                     POLYGON ((120.29777388 30.43979804, 120.29884488 30.4400100280001, 120.29911308
     
    9 rows selected

      它已经帮我们格式化成wkt文本了,可以直接拿去转换成java的Geometry对象

            GeometryFactory geometryFactory = new GeometryFactory();
            
            WKTReader wktReader = new WKTReader(geometryFactory);
    
            Geometry circleG = wktReader.read(circleRule);

      这里需要注意下,如果POLYGON里第一个点和最后一个点不相等,那么说明这个多边形不是闭环,数据是有问题的,上面的read方法将抛出IllegalArgumentException异常。

  • 相关阅读:
    注解-案例
    注解(Annotation)
    适合新手看的超详细CentOS Linux 7 安装Tomcat8过程
    CentOS Linux 7 提示 lsof: 未找到命令
    解决MySql报错:1130
    Spring Boot 创建自定义的properties文件
    spring boot 使用Schedule创建轻量级定时任务
    4.Java数组模块
    3.IDEA开发工具
    2.java基础语法
  • 原文地址:https://www.cnblogs.com/wuxun1997/p/8418952.html
Copyright © 2011-2022 走看看