在此介绍用sql对超图的空间数据库(sdx)进行空间查询,优点如下:
1。超图推荐的方式是用iobject,此方法要引入iobject
2。超图另一个推荐的方式是用iserver的REST接口,但web接口缺点在于性能一般,尤其是返回数据比较多以及并发频繁的情况下性能不好
超图空间数据库支持多种数据库产品(DBMS),可这种方式只支持PostGIS,也即是下图的
PS:注意在超图sdx的体系,Postgresql和PostGIS是两种数据库,而开源空间数据库PostGIS依赖于postgresql,可以说空间数据库PostGIS也是postgresql,注意区别
PS:超图idesktop部分版本不支持PostGIS,例如我只在idesktop 9D java 2019(9.1.0)能成功使用
当超图PostGIS数据库建好后,建立好jdbc连接(本文略,总之按postgresql建连接就行),然后就可以用sql做空间查询,以及输出几何对象
sql中使用空间查询的“接口”跟开源空间数据库PostGIS是一样的,原理是超图PostGIS也兼容开源PostGIS的功能
开源PostGIS的空间查询接口遵循OpenGIS标准,以下是开源PostGIS的官方文档,有接口的详细说明:https://postgis.net/docs/manual-dev/reference.html
另外个人也可以baidu关键词:postgis查询,来找到相关文章
以下贴一些代码
/**
* 属性查询
*
* @throws Exception
*/
private void attrQuery() throws Exception {
//属性查询
//例子:查询名称为f1的字段,值等于 面1 的要素(数据/行)
//图层名
//sde数据库带空间属性的表叫图层,因此图层跟表类似
String layerName = "polygon1";
//获取默认数据库连接
Connection conn = JdbcConnConfigUtil.getDefaultConn();
//查询使用的是sql,就是普通的sql
//select至from之间是输出的字段,其中ST_AsText(smgeometry)是输出几何对象并转成wkt格式,smgeometry代表几何对象,ST_AsText是一个函数可以把几何对象转成wkt格式的字符串
//ST_开头的函数属于开源空间数据库PostGIS的功能,可以理解为写在sql语句里的一些函数,详细api在这https://postgis.net/docs/manual-dev/reference.html
String sql = "select f1,ST_AsText(smgeometry) as wkt" +
" from " + layerName + " t " +
//查询条件,本demo是属性查询因此跟一般sql一样
"where t.f1='面1'";
//查询代码,跟jdbc一样的用法
PreparedStatement pst = null;
ResultSet rs = null;
try {
pst = conn.prepareStatement(sql);
//执行查询
rs = pst.executeQuery();
//while循环变量查询结果
while (rs.next()) {
//通过字段索引获取字段值,注意:索引从1开始!!!!
//获取几何对象,wkt格式
//wkt格式既可以构建几何对象(如何构建后面有说),也可以输出到前端供前端使用
String wkt = rs.getString(2);
//获取普通字段的值
Long f1 = DataConvertUtil.strToLong(rs.getString(1));
}
} finally {
//关闭连接,清除各种对象
DbUtils.closeQuietly(conn, pst, rs);
}
}
/**
* 空间查询,点查询面图层
*
* @throws Exception
*/
private void pointQueryPolygonLayer() throws Exception {
//空间查询,点查询面图层
//图层名
//sde数据库带空间属性的表叫图层,因此图层跟表类似
String layerName = "polygon1";
//点以坐标形式存在
double x = 38794.80;
double y = 25327.295;
//获取默认数据库连接
Connection conn = JdbcConnConfigUtil.getDefaultConn();
//获取图层的srid
//srid代表图层的空间参考(也可以说是坐标系),sr=spatial reference
String srid = SdxUtil.getSridByTableName(conn, layerName, JdbcConnConfigUtil.getDefaultMapProperties());
conn = JdbcConnConfigUtil.getDefaultConn();
//查询使用的是sql,就是普通的sql
//因为是普通sql,所以在navicat也能运行,调试sql可以直接在navicat中调试
String sql = "select ST_AsText(smgeometry) as wkt" +
" from " + layerName + " t " +
//查询条件,以下写法意思是查询面图层中与点(点坐标值就是x,y变量)相交的面
//其中ST_Intersects是相交的判断函数,参数是两个几何对象,第一个t.smgeometry代表本表的几何对象
//第二个ST_PointFromText('POINT(" + x + " " + y + ")', " + srid + "),这里使用了ST_PointFromText函数通过xy坐标值构建点的几何对象,其中srid是直接使用了图层的srid
//关于srid:所以空间对象,例如图层和几何对象,都有坐标系(也可叫做空间参考),srid就代表坐标系
//在空间查询,一般来说,被查询的图层和作为查询条件的几何对象的坐标系要统一,否则很可能出错或造成查询结果不对
//ST_Intersects的详细描述请看api
"where ST_Intersects(t.smgeometry,ST_PointFromText('POINT(" + x + " " + y + ")', " + srid + ")) = true";
//查询代码,跟jdbc一样的用法
PreparedStatement pst = null;
ResultSet rs = null;
try {
pst = conn.prepareStatement(sql);
//执行查询
rs = pst.executeQuery();
//while循环变量查询结果
while (rs.next()) {
//通过字段索引获取字段值,注意:索引从1开始!!!!
//获取几何对象,wkt格式
//wkt格式既可以构建几何对象(如何构建后面有说),也可以输出到前端供前端使用
String wkt = rs.getString(1);
}
} finally {
//关闭连接,清除各种对象
DbUtils.closeQuietly(conn, pst, rs);
}
}
/**
* 空间查询,点缓冲区查询面图层
*
* @throws Exception
*/
private void pointBufferQueryPolygonLayer() throws Exception {
//空间查询,点缓冲区查询面图层
//图层名
//sde数据库带空间属性的表叫图层,因此图层跟表类似
String layerName = "polygon1";
//点以坐标形式存在
double x = 38821.471;
double y = 25274.206;
//缓冲半径
double bufferDistance = 100.0;
//获取默认数据库连接
Connection conn = JdbcConnConfigUtil.getDefaultConn();
//获取图层的srid
//srid代表图层的空间参考(也可以说是坐标系),sr=spatial reference
String srid = SdxUtil.getSridByTableName(conn, layerName, JdbcConnConfigUtil.getDefaultMapProperties());
conn = JdbcConnConfigUtil.getDefaultConn();
//查询使用的是sql,就是普通的sql
String sql = "select ST_AsText(smgeometry) as wkt" +
" from " + layerName + " t " +
//查询条件,以下写法意思是查询面图层中与点的缓冲区相交的面
//此方法常用于点击地图查询点和线,因为点击通常很难绝对点中点和线,所有要加一个小小的缓冲范围
//ST_Buffer是构建缓冲区的意思,在此例中是对点对象建立半径为xx(值在变量bufferDistance)的缓冲区,参数1是几何对象,参数2是缓冲半径
//ST_Buffer外部有select sde.ST_Buffer.... ,大家可能会觉得加这一步多余(实际上也不会影响查询结果)
//ST_Buffer的详细描述请看api
"where st_intersects(t.smgeometry,(select ST_Buffer(ST_PointFromText('POINT(" + x + " " + y + ")', " + srid + ")," + bufferDistance + "))) = true";
//查询代码,跟jdbc一样的用法
PreparedStatement pst = null;
ResultSet rs = null;
try {
pst = conn.prepareStatement(sql);
//执行查询
rs = pst.executeQuery();
//while循环变量查询结果
while (rs.next()) {
//通过字段索引获取字段值,注意:索引从1开始!!!!
//获取几何对象,wkt格式
//wkt格式既可以构建几何对象(如何构建后面有说),也可以输出到前端供前端使用
String wkt = rs.getString(1);
}
} finally {
//关闭连接,清除各种对象
DbUtils.closeQuietly(conn, pst, rs);
}
}
/**
* 空间查询,线查询面图层,也包括使用参数查询
*
* @throws Exception
*/
private void lineQueryPolygonLayer() throws Exception {
//空间查询,线查询面图层
//此demo中查询条件的线的格式是wkt,因此此demo同样适用于wkt格式的点线面作为查询条件
//图层名
//sde数据库带空间属性的表叫图层,因此图层跟表类似
String layerName = "polygon1";
//作为查询条件的线,wkt格式
String queryConditionWkt = "LINESTRING (38778.80641398 25400.74843392, 38829.229274779995 25320.265790719997, 38787.53344758 25269.35809472)";
//获取默认数据库连接
Connection conn = JdbcConnConfigUtil.getDefaultConn();
//获取图层的srid
//srid代表图层的空间参考(也可以说是坐标系),sr=spatial reference
String srid = SdxUtil.getSridByTableName(conn, layerName, JdbcConnConfigUtil.getDefaultMapProperties());
conn = JdbcConnConfigUtil.getDefaultConn();
//查询使用的是sql,就是普通的sql
String sql = "select st_astext(t.smgeometry) as wkt,t.f1" +
" from " + layerName + " t " +
//查询条件,以下写法意思是查询面图层中与线(不止线,同样可用于点和面)相交的面
//ST_GeomFromText是传入的值生成几何对象,此demo的值是wkt格式,实际不止支持wkt,详细可看api
//ST_GeomFromText第一个参数是问号(?)而不是具体的值,问号意思是参数化查询,把值用参数传入(如何传入参数下面有写),参数查询是jdbc的特性
//为何要用参数查询(而不是直接把值内容拼成string)?因为wkt的长度通常都很长,以本demo为例,一个点的字符串长度就有31,假设一条线有1000个点字符长度就是310000,sql语句会超长
//构建几何对象的函数还有ST_GeomFromWKB,ST_Polygon,ST_PolygonFromText等等,具体请看api
" where st_intersects(t.smgeometry,(select ST_GeomFromText(?," + srid + "))) = true" +
//字符型字段的参数查询例子(字符,整形,浮点型的参数化使用都比较简单,而且类似)
" and t.f1=?";
//查询代码,跟jdbc一样的用法
PreparedStatement pst = null;
ResultSet rs = null;
try {
pst = conn.prepareStatement(sql);
//wkt字符字段参数查询例子
pst.setString(1, queryConditionWkt);
//字符字段参数查询例子
pst.setString(2, "面2");
//执行查询
rs = pst.executeQuery();
//while循环变量查询结果
while (rs.next()) {
//通过字段索引获取字段值,注意:索引从1开始!!!!
//获取几何对象,wkt格式
//wkt格式既可以构建几何对象(如何构建后面有说),也可以输出到前端供前端使用
String wkt = rs.getString(1);
String f1 = rs.getString(2);
}
} finally {
//关闭连接,清除各种对象
DbUtils.closeQuietly(conn, pst, rs);
}
}