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

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

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

2。超图另外一个推荐的方式是用iserver的REST接口,但web接口缺点在于性能通常,尤为是返回数据比较多以及并发频繁的状况下性能很差java

 

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

PS:注意在超图sdx的体系,Postgresql和PostGIS是两种数据库,而开源空间数据库PostGIS依赖于postgresql,能够说空间数据库PostGIS也是postgresql,注意区别sql

PS:超图idesktop部分版本不支持PostGIS,例如我只在idesktop 9D java 2019(9.1.0)能成功使用数据库

 

当超图PostGIS数据库建好后,创建好jdbc链接(本文略,总之按postgresql建链接就行),而后就能够用sql作空间查询,以及输出几何对象api

 

sql中使用空间查询的“接口”跟开源空间数据库PostGIS是同样的,原理是超图PostGIS也兼容开源PostGIS的功能并发

开源PostGIS的空间查询接口遵循OpenGIS标准,如下是开源PostGIS的官方文档,有接口的详细说明:https://postgis.net/docs/manual-dev/reference.htmlide

另外我的也能够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);
        }
    }
相关文章
相关标签/搜索