用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,还有其他更新版本(更老的没注意),使用起来更方便。