欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用Java替换GET_WKT函数转换SDO_GEOMETRY

程序员文章站 2022-04-14 07:49:38
...

用Java替换GET_WKT函数转换SDO_GEOMETRY

在用 SQL 查询 Oracle Spatial 空间表的数据时,如果使用 Oracle Spatial 自带的函数GET_WKT 对 SDO_GEOMETRY类型字段进行转换,效率极低,SQL 如下:

SELECT * FROM (
	SELECT ROWNUM AS rowno,t.* FROM (
		SELECT T.FID,T.T.SHAPE.GET_WKT(),T.AREA,T.NAME,T.GB1999 FROM CKQ_SQDJ T
	) t
) table_alias WHERE table_alias.rowno between 70000 and 70100

表里面有70000多条数据,用该分页语句查询10条,需要3分钟才能将数据查出来。
如果选择不用 GET_WKT,GET_WKT 函数去掉,先将数据查询出来,然后用 Java 代码对 SHAPE 字段进行转换,效率则会提升很多,只需要不到300ms

SQL:

SELECT * FROM (
	SELECT ROWNUM AS rowno,t.* FROM (
		SELECT T.FID,T.T.SHAPE,T.AREA,T.NAME,T.GB1999 FROM CKQ_SQDJ T
	) t
) table_alias WHERE table_alias.rowno between 70000 and 70100

Java 代码:

	/**
     * 将Oracle中的SDO_GEOMETRY字段转换为WKT(Well-Know Text)
     * @param geometryObj
     * @return
     */
    public static String getGeometryWkt(Object geometryObj) throws Throwable {
        boolean isStruct = geometryObj instanceof oracle.sql.STRUCT;
        if (!isStruct) {
            log.warn("【getGeometryWkt】处理对象不是结构体,将返回对象字符串");
            return geometryObj + "";
        }
        // SDO_GEOMETRY 为 STRUCT类型
        oracle.sql.STRUCT st = (oracle.sql.STRUCT) geometryObj;
        JGeometry jGeom = JGeometry.load(st);
        // wkt工具
        WKT wkt = new WKT();
        // 转换为WKT
        byte[] wktBytes = wkt.fromJGeometry(jGeom);
        return new String(wktBytes);
    }

其中 geometryObj 是从数据库中查询出来的 SHAPE 字段对象,为 SDO_GEOMETRY 类型,是一个Oracle结构体,将其转为 JGeometry 对象,再用WKT工具转换为 WKT(Well-Know Text)

WKT 示例:

MULTILINESTRING ((109.482054059221 30.2774865831163, 109.481696777458 30.2760374389536, 109.481671950774 30.2759150187401, 109.481654679294 30.275798723809, 109.481647122291 30.2756446870296, 109.481652157595 30.2754647075072, 109.48167194268 30.2752515798734, 109.481707558531 30.275032507721, 109.48173454179 30.2749293680728))

Java代码来源:Oracle Spatial and Graph Java API,该API版本为12.1,还有其他更新版本(更老的没注意),使用起来更方便。