超图supermap sdx数据库用sql实现空间查询

在此介绍用sql对超图的空间数据库(sdx)进行空间查询,优点如下:

1。超图推荐的方式是用iobject,此方法要引入iobject

2。超图另一个推荐的方式是用iserver的REST接口,但web接口缺点在于性能一般,尤其是返回数据比较多以及并发频繁的情况下性能不好

 

超图空间数据库支持多种数据库产品(DBMS),可这种方式只支持PostGIS,也即是下图的

2eec879275222514cbca42fdc163ca8ccc1.jpg

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);
        }
    }

 

转载于:https://my.oschina.net/u/1251858/blog/2963059

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值