超图REST服务加载、分页查询、统计、空间条件过滤

由于公司有业务要求,要对超图服务做预研,来完善系统功能,主要分为REST服务加载、服务的分页查询以及统计、对地图的加载增加属性过滤

服务加载

服务加载可以参考官方文档示例

如果是非openlayer的原生坐标系,即3857和4526,则需要引入proj4来注册你要用的坐标系

//以4490为例
 proj4.defs("EPSG:4490", "+proj=longlat +ellps=GRS80 +no_defs +type=crs");
        ol.proj.proj4.register(proj4);

定义好坐标系之后就可以开始加载服务了,首先配置服务地址,超图的服务地址配置到这一层及即可

通过这个界面可以知道服务的四至、以及中心点信息,这些在后面加载底图是需要用到的。

定义加载服务前的基础信息

        //服务地址
        var url = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/长春市区图";
        //服务四至
        var extent = [48.4, -7668.25, 8958.85, -55.58];
        //根据四至定义坐标系
        var projection = new ol.proj.Projection({
            code: '',
            extent: extent,
            units: 'm',
            getPointResolution: function (resolution, point) {
                return resolution
            }
        });
        //创建视图
        var view=new ol.View({
            center: [5105, -3375],
            zoom: 1,
            projection: projection,
            origin: [48.4, -55.58],
            multiWorld: true
        })
        var map = new ol.Map({
            target: 'map',
            controls: ol.control.defaults({ attributionOptions: { collapsed: false } })
                .extend([new ol.supermap.control.Logo()]),
            view
        })
        var layer = null;

接下来调用超图api提供的方法来叠加地图

        //初始化地图信息
        new ol.supermap.MapService(url).getMapInfo(function (serviceResult) {
            var mapJSONObj = serviceResult.result;            
            layer = new ol.layer.Tile({
                source: new ol.source.TileSuperMapRest(ol.source.TileSuperMapRest.optionsFromMapJSON(url, mapJSONObj))
            });

            map.addLayer(layer);
        });

注意点:如果有自己系统地图的比例尺数组,建议是自己创建TileGrid,创建超图REST服务最主要的是TileGrid,以下是自定义TileGrid参考代码:

       var tileGrid = new ol.tilegrid.TileGrid({
            resolutions: [34.80645970950213, 17.403229854751064, 8.701614927375532,
                4.350807463687766, 2.175403731843883, 1.0877018659219415, 0.5438509329609708,
                0.2719254664804854, 0.1359627332402427, 0.06798136662012134, 0.03399068331006067,
                0.016995341655030336, 0.008497670827515168, 0.004248835413757584, 0.002124417706878792,
                0.001062208853439396, 0.000531104426719698, 0.000265552213359849, 0.0001327761066799245,
                0.00006638805333996225, 0.000033194026669981125, 0.000016597013334990563],//你自己系统比例尺数组
            origin
        });
        

        var layer = new ol.layer.Tile({
            source: new ol.source.TileSuperMapRest({
                url,
                tileGrid,
                tileSize: 256,//默认用256
                crossOrigin: "anonymous",
            })
        });
        map.addLayer(layer);

以上两种方式都可以正确加载服务

分页查询

分页查询可以参考地图服务queryResults的POST请求

如上图所示,可以通过查询起始记录位置和期望返回记录数目来控制分页

 相关代码如下

  //超图服务查询的主要参数
        var queryParam = {
            queryMode: "SqlQuery",//查询类型,主要有SqlQuery(条件查询)和SpatialQuery(空间图形查询)
            queryParameters: {
                queryParams: [{
                    name: "单值专题图",//需要查询的图层名称
                    fields: [],//显示字段
                    groupBy: "",//分组查询使用的分组字段
                    attributeFilter: "1=1"//where条件
                }],
                startRecord: 0,//起始索引
                expectCount: 10,//需要查询的数量
            },           
            spatialQueryMode: "INTERSECT",//使用
            geometry: null,
        }
        axios.post(url + "/queryResults.json?returnContent=true", queryParam)//returnContent表示直接返回结果
            .then(res => {
                //输出查询结果
                console.log(res.data)
            })
            .catch(err => {
                console.log('错误' + err)
            })

这个时候返回的查询结果就是10条,同事可以通过返回的totalCount来知道总的记录数,方便计算总页数。

统计/分组统计

统计和分组统计做法和查询类似,通过类似于sql语句中的count方法来进行统计、分组就是添加groupby字段

参数设置如下:

 //统计参数
        queryParam = {
            queryMode: "SqlQuery",//查询类型,主要有SqlQuery(条件查询)和SpatialQuery(空间图形查询)
            queryParameters: {
                queryParams: [{
                    name: "单值专题图",//需要查询的图层名称
                    fields:["COUNT(SmX) as COUNT","SUM(SmX) as SUM","AVG(SmX) as AVG",
                "MAX(SmX) as MAX","MIN(SmX) as MIN"],//显示字段
                    groupBy: "",//分组查询使用的分组字段
                    attributeFilter: "1=1"//where条件
                }],
            },           
            spatialQueryMode: "INTERSECT",//使用
            geometry: null,
        }

返回结果:

分组的话就是添加一个groupBy,下面我们用name字段来进行分组统计

//统计参数
        queryParam = {
            queryMode: "SqlQuery",//查询类型,主要有SqlQuery(条件查询)和SpatialQuery(空间图形查询)
            queryParameters: {
                queryParams: [{
                    name: "单值专题图",//需要查询的图层名称
                    fields:["COUNT(SmX) as COUNT","SUM(SmX) as SUM","AVG(SmX) as AVG",
                "MAX(SmX) as MAX","MIN(SmX) as MIN","name"],//显示字段
                    groupBy: "name",//分组查询使用的分组字段
                    attributeFilter: "1=1"//where条件
                }],
            },           
            spatialQueryMode: "INTERSECT",//使用
            geometry: null,
        }

结果如下:

 

 

 空间过滤显示

空间过滤显示意思就是对服务中的图层显隐过滤、以及对图层中某些符合条件的才显示

通过查看超图官方的帮助文档可以了解到在创建ol.source.TileSuperMapRest是有一个layersID参数,那么这个ID就是我们控制服务的图层显隐以及条件显示的关键了。

 

打开超图服务界面,可以看到这么一个选项:tempLayersSet

在这个里面可以去勾选这个图层,以及配置图层的sql条件,来请求得到一个ID,最终控制服务的显隐。

那么在代码里面我们也是通过这种逻辑来实现。

首先先直接请求这个接口,得到一个ID,然后再请求这个ID拿到这个服务相关tempLayersSet所需的参数,在进行自定义的配置

var layerParam;
        axios.post("url" + "/tempLayersSet.json")
            .then(res => {
                //首先请求tempLayersSet得到一个结果ID,在根据结果ID拿到基础的参数配置
                axios.post(res.newResourceLocation)
                    .then(res => {
                        layerParam = res;
                        console.log(res)
                    })
                    .catch(err => {
                        console.log('错误' + err)
                    })
                console.log(res.data)
            })
            .catch(err => {
                console.log('错误' + err)
            })

其中sublayers就是服务中显示的图层定义了,需要显示哪个图层就保留哪个。

接下来我们就以WaterPoly@Changchun这个图层为例,只显示这个图层,

  //条件替换初始参数
        layerParam[0].subLayers.layers = layerParam[0].subLayers.layers.filter(t => t.name == "WaterPoly@Changchun");
        //然后去请求得到一个ID
        axios.post("url" + "/tempLayersSet.json", layerParam)
            .then(res => {
                //首先请求tempLayersSet得到一个结果ID,在根据结果ID拿到基础的参数配置
                let id = res.newResourceID;
                layer.getSource().tileLoadFunction = function (imageTile, src) {
                    imageTile.getImage().src = src + "&layersID=" + id;

                }
            })
            .catch(err => {
                console.log('错误' + err)
            })

效果如下 

 可以看到和一开始加载的服务不一样了,这个里面只有一个水系的图层了。

接下来通过参数中的displayFilter可以控制水系图层根据条件只显示几个要素。

测试只显示smid<10的要素

 //条件替换初始参数
        layerParam[0].subLayers.layers = layerParam[0].subLayers.layers.filter(t => t.name == "WaterPoly@Changchun");
        layerParam[0].subLayers.layers[0].displayFilter="SmID<10"
        //然后去请求得到一个ID
        axios.post("url" + "/tempLayersSet.json", layerParam)
            .then(res => {
                //首先请求tempLayersSet得到一个结果ID,在根据结果ID拿到基础的参数配置
                let id = res.newResourceID;
                layer.getSource().tileLoadFunction = function (imageTile, src) {
                    imageTile.getImage().src = src + "&layersID=" + id;

                }
            })
            .catch(err => {
                console.log('错误' + err)
            })

预研的结果就讲完了,其实关于加载底图、查询、以及空间过滤,超图的iclientAPI都有现成的方法,

 

这些方法的确方便不少,但是我的想法还是除了地图的调用用它的方法,这些方法到最后其实也是请求这些接口来完成操作,所以我想要搞清他后面最终怎么操作的,然后自己去实现,这样对于系统的功能业务开发也比较灵活。

 

 

 

 

### 使用 OpenLayers 加载 SuperMap 影像服务 为了在项目中通过 OpenLayers 来加载来自 SuperMap 的影像服务,可以采用 WMS 或者 WMTS 协议。下面是一个基于 WMTS 协议的具体实例。 #### 创建地图容器并初始化 Map 对象 首先,在 HTML 文件内定义一个用于展示地图的 div 容器,并设置其样式以便于查看效果: ```html <div id="map" style="width: 100%; height: 400px;"></div> ``` 接着利用 JavaScript 初始化 `ol.Map` 实例以及视图配置: ```javascript import 'ol/ol.css'; import { Map, View } from 'ol'; import TileLayer from 'ol/layer/Tile'; import OSM from 'ol/source/OSM'; const map = new Map({ target: 'map', layers: [ new TileLayer({ source: new OSM() }) ], view: new View({ center: [0, 0], zoom: 2 }) }); ``` #### 添加 SuperMap 图像瓦片层 (WMTS) 对于想要集成的SuperMap影像服务而言,需创建对应的 `ImageWMS` 或者 `TileWMTS` 类型的数据源(Source),这里以 `TileWMTS`为例说明操作方式: ```javascript import TileWMTS from 'ol/source/TileWMTS'; import WMTSTileGrid from 'ol/tilegrid/WMTS'; import Projection from 'ol/proj/Projection'; // 假设已知的服务URL和服务参数如下所示 const url = "http://localhost:8090/iserver/services/map-world/rest/maps/World"; const layerName = "World"; // 构建投影对象 let proj = new Projection({ code: 'EPSG:4326' }); // 设置切片网格布局 let tileGrid = new WMTSTileGrid({ origin: [-180, 90], // 左上角坐标 resolutions: [0.703125, ...] // 各级分辨率数组 }); // 配置 WMTS 数据源 let superMapSource = new TileWMTS({ url: `${url}?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0`, layer: layerName, matrixSet: 'c', format: 'image/png', projection: proj, tileGrid: tileGrid, style: 'default' }); // 将新创建的地图图层加入到现有地图中 new ol.layer.Tile({source: superMapSource}).addTo(map); ``` 需要注意的是,实际应用时应根据具体的 SuperMap RESTful Web Service 文档调整 URL 和其他请求参数[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值