SuperMap iClient for MapLibreGL

主要介绍 SuperMap iClient for MapLibreGL 的入门用法,详细的接口参数请参考 API 页面。

准备

获取 MapLibreGL 和 SuperMap iClient for MapLibreGL

开发时需要引入 MapLibreGL 和 SuperMap iClient for MapLibreGL。其中,MapLibreGL 具体包括 CSS 文件和 JS 文件。你可以通过以下方式获取这些文件:

MapLibreGL

SuperMap iClient for MapLibreGL

引入

文件方式引入

以下详细介绍如何在线引入 MapLibreGL 文件,以及如何通过在线站点引入 SuperMap iClient for MapLibreGL。

新建一个 HTML 文件,在 <head> 标签中引入 MapLibreGL CSS 文件和 JS 文件,填入 UNPKG 的托管地址,如下:

      <!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <link href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css" rel="stylesheet">
        <script type="text/javascript" src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
    </head>
</html>
  

引入 iclient-maplibregl CSS 文件和 JS 文件,填入 SuperMap iClient for MapLibreGL 在线站点地址:

      <!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <link href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css" rel="stylesheet" />
        <link href="https://iclient.supermap.io/dist/maplibregl/iclient-maplibregl.min.css" rel="stylesheet" />
        <script type="text/javascript" src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
        <script type="text/javascript" src="https://iclient.supermap.io/dist/maplibregl/iclient-maplibregl.js"></script>
    </head>
</html>

npm 方式引入

使用此方式前请先检查电脑中是否已安装应用程序 Node.js,若未安装,可通过下载 安装程序 来安装。然后在命令行中输入以下命令安装 SuperMap iClient for MapLibreGL:

 npm install @supermap/iclient-maplibregl
                                    
引入 CSS

新建一个 HTML 文件,在 <head> 标签中引入 MapLibreGL CSS 文件 和 iclient-maplibregl CSS 文件,如下:

  <link rel="stylesheet" href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css"/>

<link href="https://iclient.supermap.io/dist/maplibregl/iclient-maplibregl.min.css" rel="stylesheet"/> 
                                    

模块化开发

ES6

开发前需使用 npm 安装依赖,然后通过 ES6 的 import 模块加载语法引入相应的模块。

  按需引入

首先,安装 @supermap/babel-plugin-import:

                              npm install @supermap/babel-plugin-import -D
                              

然后,在 .babelrc 中添加如下配置:

                                {
  "plugins": [
    ["@supermap/babel-plugin-import",
        {
        "libraryName": "@supermap/iclient-maplibregl"
        }
    ]
  ]
}
                              

接下来,如果你只希望引入部分组件,比如 QueryByBoundsParameters, QueryService,那么需要写入以下内容:

 import maplibregl from 'maplibre-gl';
import {QueryByBoundsParameters, QueryService} from '@supermap/iclient-maplibregl';

var url = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
var map = new maplibregl.Map({
    container: 'map',
    style: 'https://iserver.supermap.io/iserver/services/map-mvt-China/rest/maps/China/tileFeature/vectorstyles.json?type=MapBox_GL&styleonly=true',
    center: [0, 0],
    zoom: 2
});

map.on('load', function () {
    var param = new QueryByBoundsParameters(...);
    new QueryService(url).queryByBounds(param).then(function (serviceResult) {
        map.addLayer(...);
    });
});
                            

  全模块引入

     import maplibregl from 'maplibre-gl';
import '@supermap/iclient-maplibregl';

var url = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
var map = new maplibregl.Map({
    container: 'map',
    style: 'https://iserver.supermap.io/iserver/services/map-mvt-China/rest/maps/China/tileFeature/vectorstyles.json?type=MapBox_GL&styleonly=true',
    center: [0, 0],
    zoom: 2
});

map.on('load', function () {
    var param = new maplibregl.supermap.QueryByBoundsParameters(...);
    new maplibregl.supermap.QueryService(url).queryByBounds(param).then(function (serviceResult) {
        map.addLayer(...);
    });
});

                            

CommonJS

CommonJS 是基于 Node.js 环境的 JavaScript 模块化规范。开发前需使用 npm 安装依赖,然后通过 require 方法引入相应的模块。

  部分模块引入

     var maplibregl = require('maplibregl') ;
var QueryByBoundsParameters = require('@supermap/iclient-maplibregl').QueryByBoundsParameters;
var QueryService = require('@supermap/iclient-maplibregl').QueryService;

var url = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
var map = new maplibregl.Map({
    container: 'map',
    style: 'https://iserver.supermap.io/iserver/services/map-mvt-China/rest/maps/China/tileFeature/vectorstyles.json?type=MapBox_GL&styleonly=true',
    center: [0, 0],
    zoom: 2
});

map.on('load', function () {
    var param = new QueryByBoundsParameters(...);
    new QueryService(url).queryByBounds(param).then(function (serviceResult) {
        map.addLayer(...);
    });
});
                            

  全模块引入

     var maplibregl = require('maplibregl') ;
require('@supermap/iclient-maplibregl');

var url = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
var map = new maplibregl.Map({
    container: 'map',
    style: 'https://iserver.supermap.io/iserver/services/map-mvt-China/rest/maps/China/tileFeature/vectorstyles.json?type=MapBox_GL&styleonly=true',
    center: [0, 0],
    zoom: 2
});

map.on('load', function () {
    var param = new maplibregl.supermap.QueryByBoundsParameters(...);
    new maplibregl.supermap.QueryService(url).queryByBounds(param).then(function (serviceResult) {
        map.addLayer(...);
    });
});
                            

AMD

以下例子利用 RequireJS 库实现,将 maplibre-gl.js 和 iclient-maplibregl.js 通过 “ 获取 MapLibreGL 和 SuperMap iClient for MapLibreGL ” 下载后放在与 RequireJS 指定的入口主文件所在目录下。

  全模块引入

                            require(['js/maplibre-gl.js'], function(maplibregl) {
    window.maplibregl = maplibregl;
    require(['js/iclient-maplibregl'], function() {
        var url = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
        var map = new maplibregl.Map({
            container: 'map',
            style: 'https://iserver.supermap.io/iserver/services/map-mvt-China/rest/maps/China/tileFeature/vectorstyles.json?type=MapBox_GL&styleonly=true',
            center: [0, 0],
            zoom: 2
        });

        map.on('load', function() {
            var param = new maplibregl.supermap.QueryByBoundsParameters(...);
            new maplibregl.supermap.QueryService(url).queryByBounds(param).then(function (serviceResult) {
                map.addLayer(...);
            });
        });
    });
});
                            

CMD

以下例子利用 SeaJS 库实现,将 maplibre-gl.js 和 iclient-maplibregl.js 通过 “ 获取 MapLibreGL 和 SuperMap iClient for MapLibreGL ” 下载后放在与 SeaJS 指定的入口主文件所在目录下。

  全模块引入

                                                define(function(require, exports, module) {
    require('./maplibre-gl.js');
    require('./iclient-maplibregl.js');

    var url = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
    var map = new maplibregl.Map({
        container: 'map',
        style: 'https://iserver.supermap.io/iserver/services/map-mvt-China/rest/maps/China/tileFeature/vectorstyles.json?type=MapBox_GL&styleonly=true',
        center: [0, 0],
        zoom: 2
    });

    map.on('load', function() {
        var param = new maplibregl.supermap.QueryByBoundsParameters(...);
        new maplibregl.supermap.QueryService(url).queryByBounds(param).then(function (serviceResult) {
            map.addLayer(...);
        });
    });
});
                            

打包配置

SuperMap iClient for MapLibreGL 使用了 ES6 语法,为了兼容不支持 ES6 语法的浏览器,需要在打包的过程中进行一些配置,包括语法转换的处理。

这里的打包配置是针对于 ES6 和 CommonJS 模块开发,对于 AMD 和 CMD 模块开发的项目, 不需要利用打包工具。

这里以 webpack4 为例,由于使用不同的包管理器会导致安装包的结构有所不同,所以下面分别介绍了 npm 和 cnpm 两种配置方式:

若您用 npm install 或者 cnpm install --by=npm 安装的依赖,那么您需要在 webpack.config.js 的配置文件的 module 中加入如下配置项:

 module: {
    rules: [{
        // 使用babel-loader将ES6语法转换为ES5
        test: /\.js$/,
        loader: 'babel-loader',
        options: {
            presets: ['@babel/preset-env']
        }
    }]
}
                            

若您用 cnpm install 安装的依赖,那么您需要在 webpack.config.js 的配置文件的 module 中加入如下配置项:

                                                module: {
    rules: [{
        // 使用babel-loader将ES6语法转换为ES5
        test: /\.js$/,
        loader: 'babel-loader',
        options: {
            presets: ['@babel/preset-env']
        }
    }]
}
                            

创建一幅地图

SuperMap iServer 发布的地图

在准备章节,已经新建了一个 HTML 页面,在页面 <body> 标签中添加代码以创建地图,如下:

                         <!DOCTYPE HTML>
<html>
    <head>
        <meta charset="UTF-8">
        <link href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css" rel="stylesheet">
        <script type="text/javascript" src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
        <script type="text/javascript" src="https://iclient.supermap.io/dist/maplibregl/iclient-maplibregl.js"></script>
    </head>
    <body>
        // 地图显示的div
        <div id="map" style="position:absolute;left:0px;right:0px;width:800px;height:500px;"></div>
    </body>
</html>
                        

以嵌入 SuperMap iServer 发布的中国地图为例,在 <script> 中继续添加如下代码,初始化地图信息:

  var map = new maplibregl.Map({
    container: 'map',
    style: {
        "version": 8,
        "sources": {
            "raster-tiles": {
                "attribution": attribution,
                "type": "raster",
                "tiles": ['https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China/zxyTileImage.png?z={z}&x={x}&y={y}'],
                "tileSize": 256
            }
        },
        "layers": [{
            "id": "simple-tiles",
            "type": "raster",
            "source": "raster-tiles",
            "minzoom": 0,
            "maxzoom": 22
        }]
    },
    center: [120.143, 30.236], // 地图初始中心点
    zoom: 3 // 地图初始缩放级别
});查看源码 »
                        

运行效果

添加控件

通过向地图添加控件的方式,实现对图层的放大,缩小,全屏等交互操作,常用的控件包括:

控件 类名 简介
导航 maplibregl.NavigationControl 默认位于地图左上角
比例尺 maplibregl.ScaleControl 默认位于地图左下角
全屏 maplibregl.FullscreenControl 默认位于地图右上角
定位 maplibregl.GeolocateControl 默认位于地图右上角
版权 maplibregl.AttributionControl 默认位于右下角

添加控件时,首先初始化地图,然后通过 addControl() 方法将控件添加到地图上,例如:

导航控件:

 // 添加控件
map.addControl(new maplibregl.NavigationControl(), 'top-left');查看源码 »
                        

运行效果

比例尺控件:

 map.addControl(new maplibregl.ScaleControl({}));查看源码 »
                        

运行效果

使用矢量瓦片

矢量瓦片是将矢量数据通过不同的描述文件来组织和定义,在客户端实时解析数据并完成绘制。使用 SuperMap iServer 提供的矢量瓦片示例如下:

 var map = new maplibregl.Map({
    container: 'map', // 指定地图容器
    style: 'https://iserver.supermap.io/iserver/services/map-mvt-China/rest/maps/China/tileFeature/vectorstyles.json?type=MapBox_GL&styleonly=true',
    center: [120.143, 30.236], // 地图初始中心点
    zoom: 0,
    attributionControl: false
});查看源码 »
                        

运行效果

地物查询

SuperMap iClient for MapLibreGL 支持的地物查询功能主要包括:

  • 指定 ID 查询
  • 指定 SQL 查询
  • 矩形范围查询
  • 任意几何范围查询
  • 距离查询
  • 缓冲区查询
  • 查询栅格信息
  • 查询字段信息

指定 ID 查询

指定 ID 查询,即在数据集中查询符合指定 ID 的地理空间要素,并在客户端中展示出来。本示例为:在 World 数据服务中查询指定 ID 的要素。

使用接口 maplibregl.supermap.FeatureService 在数据集 “World:Countries” 中查询 ID 为 234 的地理空间要素。

         // 数据集ID查询服务参数
var idsParam = new maplibregl.supermap.GetFeaturesByIDsParameters({
    IDs: [234],
    datasetNames: ["World:Countries"]
});
// 创建指定ID查询实例
var url = "https://iserver.supermap.io/iserver/services/data-world/rest/data";
new maplibregl.supermap.FeatureService(url).getFeaturesByIDs(idsParam).then(function (serviceResult) {
    // 获取服务器返回的结果
    var features = serviceResult.result.features;
});查看源码 »
         

运行效果

指定 SQL 查询

指定 SQL 查询,即在指定数据集集合中查找符合 SQL 条件的矢量要素,并在客户端中展示出来。本示例为:在 World 数据服务中查询指定 SMID 的要素。

使用接口 maplibregl.supermap.FeatureService 在数据集 “World:Countries” 中查询 SMID 为 234 的要素。

              // 指定SQL查询服务参数
var sqlParam = new maplibregl.supermap.GetFeaturesBySQLParameters({
    queryParameter: {
        name: "Countries@World",
        attributeFilter: "SMID = 234"
    },
    datasetNames: ["World:Countries"]
});
// 创建SQL查询实例
var url = "https://iserver.supermap.io/iserver/services/data-world/rest/data";
new maplibregl.supermap.FeatureService(url).getFeaturesBySQL(sqlParam).then(function (serviceResult) {
    // 获取服务器返回的结果
    var features = serviceResult.result.features;
});查看源码 »
     

运行效果

矩形范围查询

矩形范围查询,即在指定数据集集合中查找符合矩形范围的矢量要素,并在客户端中展示出来。本示例为:在 World 数据服务中查询指定矩形范围的要素。

使用接口 maplibregl.supermap.FeatureService 在数据集 “World:Capitals” 中查找符合此矩形范围的矢量要素。

          var url =  "https://iserver.supermap.io/iserver/services/data-world/rest/data";
// 指定矩形范围查询处理
var sw = new maplibregl.LngLat(-20, -20);
var ne = new maplibregl.LngLat(20, 20);
var lngLatBounds = new maplibregl.LngLatBounds(sw, ne);

// 设置矩形范围查询参数
var boundsParam = new maplibregl.supermap.GetFeaturesByBoundsParameters({
    datasetNames: ["World:Capitals"],
    bounds: lngLatBounds
});
// 创建矩形范围查询实例
new maplibregl.supermap.FeatureService(url).getFeaturesByBounds(boundsParam).then(function (serviceResult) {
    // 获取服务器返回的结果
    var features = serviceResult.result.features;
});查看源码 »
     

运行效果

任意几何范围查询

几何范围查询,即在指定数据集集合中查找符合几何范围的矢量要素,并在客户端中展示出来。本示例为:在 World 数据服务中查询任意几何范围的要素。

使用接口 maplibregl.supermap.FeatureService 在 “World:Countries” 数据集中采用相交空间查询模式查询符合此几何范围的矢量要素。

         var url = "https://iserver.supermap.io/iserver/services/data-world/rest/data";
// 设置几何查询范围
var  queryPolygonGeometry = {
    "type": "Polygon",
    "coordinates": [[[0, 0], [-10, 30], [-30, 0], [0, 0]]]
};
// 设置任意几何范围查询参数
var geometryParam = new maplibregl.supermap.GetFeaturesByGeometryParameters({
    datasetNames: ["World:Countries"],
    geometry: queryPolygonGeometry,
    spatialQueryMode: "INTERSECT" // 相交空间查询模式
});
// 创建任意几何范围查询实例
new maplibregl.supermap .FeatureService(url).getFeaturesByGeometry(geometryParam).then(function (serviceResult) {
    // 获取服务器返回的结果
    var features = serviceResult.result.features;
});查看源码 »
    

运行效果

距离查询

距离查询,即在地图服务中的指定图层中查找符合一定距离的矢量要素,并在客户端中展示出来。本示例为:在 World 地图服务中查询符合距离的矢量要素。

使用接口 maplibregl.supermap.QueryService 在图层 “Capitals@World.1” 中查找距离指定点为 10 度(地图坐标单位)的矢量要素。

         var url = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
// 添加查询中心点
var point = new maplibregl.LngLat(104, 30);
// 设置距离查询参数
var param = new maplibregl.supermap.QueryByDistanceParameters({
    queryParams: {name: "Capitals@World.1"},
    distance: 10, // distance的单位跟地物的坐标系单位一致,此处为度
    geometry: point
});
// 创建距离查询实例
new maplibregl.supermap.QueryService(url).queryByDistance(param).then(function (serviceResult) {
    // 获取服务器返回的结果
    var features = serviceResult.result.features;
});查看源码 »
     

运行效果

缓冲区查询

缓冲区查询,即在数据服务中的指定数据集集合中查找符合缓冲区的矢量要素,并在客户端中展示出来。本示例为:在 World 数据服务中查询指定缓冲区的要素。

使用接口 maplibregl.supermap.FeatureService 在数据集 “World:Capitals” 中查找符合此缓冲区范围距离为 30 度(地图坐标单位)的矢量要素。

         var url = "https://iserver.supermap.io/iserver/services/data-world/rest/data";
// 设置缓冲区查询范围
var queryBufferGeometry = {
    "type": "Polygon",
    "coordinates": [[[-20, 20], [-20, -20], [20, -20], [20, 20], [-20, 20]]]
};
// 设置缓冲区查询参数
var bufferParam = new maplibregl.supermap.GetFeaturesByBuffer Parameters({
    datasetNames: ["World:Capitals"],
    bufferDistance: 30, // bufferDistance的单位跟地物的坐标系单位一致,此处为度
    geometry:queryBufferGeometry
});
// 创建缓冲区查询实例,向服务器发送请求,并获取返回的结果
new maplibregl.supermap.FeatureService(url).getFeaturesByBuffer(bufferParam).then(function (serviceResult) {
    // 获取服务器返回的结果
    var features = serviceResult.result.features;
});查看源码 »
     

运行效果

查询栅格信息

查询栅格信息,即在指定数据集集合中查找某一地理位置所对应的像素值信息,并在客户端中展示出来。

使用接口 maplibregl.supermap.GridCellInfosService 在数据集 “WorldEarth” 中查询栅格信息为例,示例代码如下:

         var url = "https://iserver.supermap.io/iserver/services/data-world/rest/data";
map.on("click",function (evt) {
    // 获取当前点击的(x,y)
    var x = evt.latlng.lng;
    var y = evt.latlng.lat;
    // 设置栅格查询的参数信息
    var getGridCellInfosParam = new maplibregl.supermap.GetGridCellInfosParameters({
        dataSourceName: "World",
        datasetName:"WorldEarth",
        X: x,
        Y: y
    });
    // 创建栅格查询实例
    new maplibregl.supermap.GridCellInfosService(url).getGridCellInfos(getGridCellInfosParam).then(function(serviceResult) {
        if (!serviceResult.result) {
            return;
        }
        // 获取服务端返回数据
        var result = serviceResult.result;
    });
});查看源码 »
     

运行效果

查询字段信息

查询字段信息,即在指定数据集集合中查询字段的信息,包括:字段名称、字段类型、字段别名、字段默认值等,并在客户端中展示出来。本示例为:在 World 数据服务中查询指定字段的信息,并做字段统计。

使用接口 maplibregl.supermap.FieldService,在数据集 “continent_T” 中查询字段名为 “SmID” 的详细字段信息,并对数据集中所有 SmID 值进行统计,求出平均值、最大值、最小值等。

         var dataURL = "https://iserver.supermap.io/iserver/services/data-world/rest/data"
// 设置字段查询参数
var param = new maplibregl.supermap.FieldParameters({
    datasource: "World",
    dataset: "continent_T"
});
var fieldName = 'SmID';
// 创建字段查询实例
new maplibregl.supermap.FieldService(dataURL).getFields(param).then(function (serviceResult) {
    fieldStatistic(fieldName);
});
// 查询指定字段
function fieldStatistic(fieldName) {
    // 设置查询指定字段参数
    var param = new maplibregl.supermap.FieldStatisticsParameters({
        datasource: currentData.dataSourceName,
        dataset: currentData.dataSetName,
        fieldName: fieldName,
        statisticMode: [
            mapboxgl.supermap.StatisticMode.MAX,
            mapboxgl.supermap.StatisticMode.MIN,
            mapboxgl.supermap.StatisticMode.SUM,
            mapboxgl.supermap.StatisticMode.AVERAGE,
            mapboxgl.supermap.StatisticMode.STDDEVIATION,
            mapboxgl.supermap.StatisticMode.VARIANCE
        ]
    });
    // 向服务端发送请求并获取数据
    new maplibregl.supermap.FieldService(dataURL).getFieldStatisticsInfo(param, function (serviceResult) {
        // 获取返回数据
        var result = serviceResult.result;
    });
}查看源码 »
     

运行效果

地物编辑

地物编辑

地物编辑功能可以实现在地图中添加或删除要素。使用接口 maplibregl.supermap.FeatureService 在数据集 “Capitals” 中添加地物信息。

        // 实例化地物编辑服务
var url="https://iserver.supermap.io/iserver/services/data-world/rest/data";
var xmax = 120, xmin = 100, ymax = 50, ymin = 20;
var addPoint = [Math.floor(Math.random() * (xmax - xmin + 1) + xmin), Math.floor(Math.random() * (ymax - ymin + 1) + ymin)];
var pointFeature = {
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": addPoint
    },
    "properties": {POP: 1, CAPITAL: 'test'}
};
var featureService = new maplibregl.supermap.FeatureService(url);
// 设置地物编辑字段参数
var addFeatureParams = new maplibregl.supermap.EditFeaturesParameters({
    dataSourceName: "World",
    dataSetName: "Capitals",
    features: pointFeature,
    editType: "add",
    returnContent: true
});
// 使用地物编辑服务向服务端发送请求并获取数据
featureService.editFeatures(addFeatureParams).then(function (serviceResult) {
    // 获取返回数据
    var result = serviceResult.result;
});查看源码 »
             

运行效果

专题图

地图学中将突出而深入地表示一种或几种要素或现象,即集中表示一个主题内容的地图称为专题地图。在 SuperMap 中,专题图是地图图层的符号化显示,即用各种图形渲染风格(大小,颜色,线型,填充等)来图形化地表现专题要素的某方面特征。

服务端专题图

服务端专题图是由服务器进行专题图的制作,即客户端向服务器发送专题图参数,如数据集名称、风格等,服务器根据参数制作专题图,返回给客户端,由客户端进行展示。

SuperMap iClient for MapLibreGL 支持的服务端专题图包含:

  • 点密度专题图
  • 单值专题图
  • 分段专题图
  • 等级符号专题图
  • 标签专题图
  • 统计专题图
点密度专题图

点密度专题图用一定大小、形状相同的点表示现象分布范围、数量特征和分布密度。点的多少和所代表的意义由地图的内容决定。点密度专题图使用点的数目或者密集程度来反映一个区域或范围所对应的专题值。

SuperMap iClient for MapLibreGL 实现点密度专题图的主要代码如下:

 var url = "https://iserver.supermap.io/iserver/services/map-world/rest/maps/World";
// 获取专题图服务,url是地图访问服务
var themeService = new maplibregl.supermap.ThemeService(url);
// 实例化一个点密度专题图对象,并对专题图作相应的设置
var themeDotDensity = new maplibregl.supermap.ThemeDotDensity({
    // 创建点密度专题图的字段或字段表达式
    dotExpression:"Pop_1994",
    // 专题图中每一个点代表的数值
    value: 5000000,
    style: new maplibregl.supermap.ServerStyle({
        markerSize: 3,
        markerSymbolID: 12
    });
});
// 设置专题图参数类,该类存储了制作专题所需的参数,包括数据源、数据集名称和专题图对象
themeParameters =new maplibregl.supermap.ThemeParameters({
    themes: [themeDotDensity],
    // 要制作专题图的数据集数组,必设
    datasetNames: ["Countries"],
    // 要制作专题图的数据集所在的数据源数组,必设
    dataSourceNames: ["World"] });
// 提交服务请求,传递服务查询参数,获取专题图信息并按照用户需求进行处理
themeService.getThemeInfo(themeParameters).then(function (serviceResult) {
    // 获取服务器返回的结果
    var result = serviceResult.result;
});查看源码 »
                 

运行效果

单值专题图

单值专题图是将专题值相同的要素归为一类,为每一类设定一种渲染风格,如颜色或符号等,专题值相同的要素采用相同的渲染风格,从而用来区分不同的类别。

SuperMap iClient for MapLibreGL 实现单值专题图的主要代码如下:

     var url = "https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China";
// 获取专题图服务,url是地图访问服务
var themeService = new maplibregl.supermap.ThemeService(url);
// 单值专题图子项
var themeUniqueIteme1 = new maplibregl.supermap.ThemeUniqueItem({
        unique: "黑龙江省",
        style: style1
    }),
    themeUniqueIteme2 = new maplibregl.supermap.ThemeUniqueItem({
        unique: "湖北省",
        style: style2
    })
var themeUniqueItemes = [
    themeUniqueIteme1, themeUniqueIteme2
];
// 实例化一个单值专题图对象,并对专题图作相应的设置
var themeUnique = new maplibregl.supermap.ThemeUnique({
    // 专题图的字段或表达式
    uniqueExpression: "Name",
    // 子项数组
    items: themeUniqueItemes,
    // 未参与单值专题图制作的对象的显示风格
    defaultStyle: style1
});
// 设置专题图参数类,该类存储了制作专题所需的参数,包括数据源、数据集名称和专题图对象
var themeParameters = new maplibregl.supermap.ThemeParameters({
    // 要制作专题图的数据集数组,必设
    datasetNames: ["China_Province_pg"],
    // 要制作专题图的数据集所在的数据源数组,必设
    dataSourceNames: ["China"],
    themes: [themeUnique]
});
// 提交服务请求,传递服务查询参数,获取专题图信息并按照用户需求进行处理
themeService.getThemeInfo(themeParameters).then(function (serviceResult) {
    // 获取服务器返回的结果
    var result = serviceResult.result;
});查看源码 »
 

运行效果

分段专题图

分段专题图是指按照某种分段方式被分成多个范围段,要素根据各自的专题值被分配到其中一个范围段中,在同一个范围段中的要素使用相同的颜色,填充,符号等风格进行显示。 分段专题图所基于的专题变量必须为数值型,分段专题图一般用来反映连续分布现象的数量或程度特征,如降水量的分布,土壤侵蚀强度的分布等。

SuperMap iClient for MapLibreGL 实现分段专题图的主要代码如下:

     var url = "https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China";
// 获取专题图服务,url是地图访问服务
var themeService = new maplibregl.supermap.ThemeService(url);
// 范围分段专题图子项
themeRangeItem1 = new maplibregl.supermap.ThemeRangeItem({
    start: 0,
    end: 500000000000,
    style: new maplibregl.supermap.ServerStyle({
        fillForeColor: new maplibregl.supermap.ServerColor(211, 255, 250),
        lineColor: new maplibregl.supermap.ServerColor(179, 209, 193),
        lineWidth: 0.1
    })
});
themeRangeItem2 = new maplibregl.supermap.ThemeRangeItem({
    start: 500000000000,
    end: 1000000000000,
    style: new maplibregl.supermap.ServerStyle({
        fillForeColor: new maplibregl.supermap.ServerColor(178, 218, 199),
        lineColor: new maplibregl.supermap.ServerColor(179, 209, 193),
        lineWidth: 0.1
    })
});
// 实例化一个分段专题图对象,并对专题图作相应的设置
themeRange = new maplibregl.supermap.ThemeRange({
    // 分段字段或表达式
    rangeExpression: "SMAREA",
    // 分段模式
    rangeMode: maplibregl.supermap.RangeMode.EQUALINTERVAL,
    // 子项数组
    items: [themeRangeItem1, themeRangeItem2]
});
// 设置专题图参数类,该类存储了制作专题所需的参数,包括数据源、数据集名称和专题图对象
var themeParameters = new maplibregl.supermap.ThemeParameters({
    // 要制作专题图的数据集数组,必设
    datasetNames: ["China_Province_pg"],
    // 要制作专题图的数据集所在的数据源数组,必设
    dataSourceNames: ["China"],
    // 专题图外部表的连接信息
    joinItems: null,
    themes: [themeRange]
});
// 提交服务请求,传递服务查询参数,获取专题图信息并按照用户需求进行处理
themeService.getThemeInfo(themeParameters).then(function (serviceResult) {
    // 获取服务器返回的结果
    var result = serviceResult.result;
});查看源码 »
 

运行效果

等级符号专题图

等级符号专题图根据各要素的某个数量特征,按照一定的分类方法用一组等级符号表示在地图上,以呈现要素间该数量特征的相对关系。

SuperMap iClient for MapLibreGL 实现等级符号专题图的主要代码如下:

     var url = "https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China";
// 获取专题图服务,url是地图访问服务
var themeService = new maplibregl.supermap.ThemeService(url);
// 实例化一个等级符号专题图对象,并对专题图作相应的设置
var themeGraduatedSymbol = new maplibregl.supermap.ThemeGraduatedSymbol({
    // 专题图的字段或字段表达式
    expression: "SMAREA",
    // 基准值
    baseValue: 3000000000000,
    // 分级模式
    graduatedMode: maplibregl.supermap.GraduatedMode.CONSTANT,
    // 正负零值显示风格
    style: new maplibregl.supermap.ThemeGraduatedSymbolStyle({
        positiveStyle: new maplibregl.supermap.ServerStyle({
            markerSize: 50,
            markerSymbolID: 0,
            lineColor: new maplibregl.supermap.ServerColor(255, 165, 0),
            fillBackColor: new maplibregl.supermap.ServerColor(255, 0, 0)
        })
    })
});
// 设置专题图参数类,该类存储了制作专题所需的参数,包括数据源、数据集名称和专题图对象
var themeParameters = new maplibregl.supermap.ThemeParameters({
    themes: [themeGraduatedSymbol],
    // 要制作专题图的数据集数组,必设
    datasetNames: ["China_Province_pg"],
    // 要制作专题图的数据集所在的数据源数组,必设
    dataSourceNames: ["China"]
});

// 提交服务请求,传递服务查询参数,获取专题图信息并按照用户需求进行处理
themeService.getThemeInfo(themeParameters).then(function (serviceResult) {
    // 获取服务器返回的结果
    var result = serviceResult.result;
});查看源码 »
 

运行效果

标签专题图

地图上的必要的标注是必不可少的,不仅帮助用户更好地区分地物要素,同时也显示了要素的某些重要属性,如行政区划、河流、机关、旅游景点的名称、等高线的高程等。在 SuperMap 中,通过制作标签专题图,用户可以轻松实现地图标注。

SuperMap iClient for MapLibreGL 实现标签专题图的主要代码如下:

     var url = "https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China";
// 获取专题图服务,url是地图访问服务
var themeService = new maplibregl.supermap.ThemeService(url);
// 分段标签专题图的子项
var themeLabelItem1 = new maplibregl.supermap.ThemeLabelItem({
    start: 300,// 110000
    end: 3508,// 350000
    style: style1
});
var themeLabelItem2 = new maplibregl.supermap.ThemeLabelItem({
    start: 3508,// 350000
    end: 5508,// 550000
    style: style2
});
// 实例化一个标签专题图对象,并对专题图作相应的设置
var themeLabel = new maplibregl.supermap.ThemeLabel({
    // 标注字段或表达式
    labelExpression: "NAME",
    // 制作分段标签专题的分段字段
    rangeExpression: "pop_2014",
    // 显示精度
    numericPrecision: 0,
    // 子项数组
    items: [themeLabelItem1, themeLabelItem2],
    // 标签的背景风格
    background: new maplibregl.supermap.ThemeLabelBackground({
        backStyle: new maplibregl.supermap.ServerStyle({
            fillForeColor: new maplibregl.supermap.ServerColor(179, 209, 193),
            fillOpaqueRate: 60,
            lineWidth: 0.1
        }),
        labelBackShape: "RECT"
    })
});
// 设置专题图参数类,该类存储了制作专题所需的参数,包括数据源、数据集名称和专题图对象。
var themeParameters = new maplibregl.supermap.ThemeParameters({
    themes: [themeLabel],
    // 要制作专题图的数据集数组,必设
    datasetNames: ["China_Province_pg"],
    // 要制作专题图的数据集所在的数据源数组,必设
    dataSourceNames: ["China"]
});
// 提交服务请求,传递服务查询参数,获取专题图信息并按照用户需求进行处理
themeService.getThemeInfo(themeParameters).then(function (serviceResult) {
    // 获取服务器返回的结果
    var result = serviceResult.result;
});查看源码 »
 

运行效果

统计专题图

统计专题图是通过为每个要素或记录绘制统计图来反映其对应的专题值的大小。统计专题图可以基于多个变量,反映多种属性,即可以将多个专题值绘制在一个统计图上,并且每个区域都会有一幅表示该区域各专题值的统计图。通过统计专题图可以在区域本身与各区域之间形成横向和纵向的对比。多用于具有相关数量特征的地图上,比如表示不同地区多年的粮食产量、GDP、人口等,不同时段客运量、地铁流量等。

SuperMap iClient for MapLibreGL 实现统计专题图的主要代码如下:

     var url = "https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China";
// 获取专题图服务,url是地图访问服务
var themeService = new maplibregl.supermap.ThemeService(url);
// 实例化一个统计专题图对象,并对专题图作相应的设置
var themeGraph = new maplibregl.supermap.ThemeGraph({
    // 统计专题图子项集合
    items: [
        new maplibregl.supermap.ThemeGraphItem({
            // 专题图子项名称
            caption: "全国省份2013_GDP",
            // 专题变量
            graphExpression: "GDP_2013",
            // 统计专题图子项显示风格
            uniformStyle: new maplibregl.supermap.ServerStyle({
                fillForeColor: new maplibregl.supermap.ServerColor(255, 215, 0),
                lineWidth: 0
            })
        }),
        new maplibregl.supermap.ThemeGraphItem({
            caption: "全国省份2014_GDP",
            graphExpression: "GDP_2014",
            uniformStyle: new maplibregl.supermap.ServerStyle({
                fillForeColor: new maplibregl.supermap.ServerColor(0, 191, 255),
                lineWidth: 0
            })
        }),
    ],
    // 柱状专题图中柱的宽度
    barWidth: 0.001,
    // 地理要素的值与图表尺寸间的映射关系
    graduatedMode: maplibregl.supermap.GraduatedMode.CONSTANT,
    // 坐标轴样式
    graphAxes: new maplibregl.supermap.ThemeGraphAxes({
        axesDisplayed: true
    }),
    // 统计符号的最大最小尺寸
    graphSize: new maplibregl.supermap.ThemeGraphSize({
        maxGraphSize: 500000,
        minGraphSize: 200000
    }),
    // 统计图上的文字是否可见以及文字标注风格
    graphText: new maplibregl.supermap.ThemeGraphText({
        graphTextDisplayed: true,
        graphTextFormat: maplibregl.supermap.ThemeGraphTextFormat.VALUE,
        graphTextStyle: new maplibregl.supermap.ServerTextStyle({
            fontHeight: 10,
            fontWidth: 10
        })
    }),
    // 是否采用避让方式显示
    overlapAvoided: false,
    // 缩放地图时符号是否固定大小
    graphSizeFixed: false,
    // 统计专题图类型
    graphType: maplibregl.supermap.ThemeGraphType.BAR
});
// 设置专题图参数类,该类存储了制作专题所需的参数,包括数据源、数据集名称和专题图对象
themeParameters = new maplibregl.supermap.ThemeParameters({
    themes: [themeGraph],
    // 要制作专题图的数据集数组,必设
    datasetNames: ["China_Province_pg"],
    // 要制作专题图的数据集所在的数据源数组,必设
    dataSourceNames: ["China"]
});
// 提交服务请求,传递服务查询参数,获取专题图信息并按照用户需求进行处理
themeService.getThemeInfo(themeParameters).then(function (serviceResult) {
    // 获取服务器返回的结果
    var result = serviceResult.result;
});查看源码 »
 

运行效果

空间分析

空间分析(Spatial Analysis)是基于地理对象的位置和形态特征的空间数据分析技术,其目的在于提取和传输空间信息。SuperMap iClient for MapLibreGL 支持的空间分析功能包括:

  • 缓冲区分析
  • 泰森多边形
  • 叠加分析
  • 表面分析
  • 点定里程
  • 里程定点
  • 里程定线
  • 栅格代数运算
  • 地形计算

缓冲区分析

缓冲区分析(buffer)是根据指定的距离在点、线和多边形实体周围自动建立一定宽度的区域范围的分析方法。例如,在环境治理时,常在污染的河流周围划出一定宽度的范围表示受到污染的区域;又如在飞机场,常根据附近居民的健康需要在周围划分出一定范围的区域作为非居住区等。

下面以京津数据为例,对“莲花池东路”进行半径为 300 米的圆头缓冲分析,缓冲区分析的接口使用方法如下:

设置缓冲区分析参数、缓冲区通用参数。

     // 设置缓冲区分析参数
var dsBufferAnalystParams = new maplibregl.supermap.DatasetBufferAnalystParameters({
    // 用来做缓冲区分析的数据源中数据集名称
    dataset: "Road_L@Jingjin",
    // 设置数据集中集合对象的过滤条件
    filterQueryParameter: new maplibregl.supermap.FilterParameter({
        // 属性过滤条件
        attributeFilter: "NAME='莲花池东路'"
    }),
    // 缓冲区分析通用参数设置
    bufferSetting: new maplibregl.supermap.BufferSetting({
        // 缓冲区端点枚举值,包含FLAT和ROUND
        endType: maplibregl.supermap.BufferEndType.ROUND,
        // 左侧缓冲距离
        leftDistance: {value: 300},
        // 右侧缓冲距离
        rightDistance: {value: 300},
        // 圆头缓冲圆弧处线段的个数
        semicircleLineSegment: 10,
        radiusUnit:'METER'
    })
});
 

设置缓冲区分析服务对象,用于将客户端设置的缓冲区分析服务参数传递给服务端,并接收服务端返回的缓冲区分析结果数据。当向服务端发送请求并且服务端成功返回结果时,用户可对获得的缓冲区分析结果做相应处理。

             var serviceUrl = "https://iserver.supermap.io/iserver/services/spatialanalyst-sample/restjsr/spatialanalys"
// 创建缓冲区分析服务
var bufferServiceByDatasets =new maplibregl.supermap.SpatialAnalystService(serviceUrl);
// 向服务端发送服务请求,并获取返回的结果
bufferServiceByDatasets.bufferAnalysis(dsBufferAnalystParams).then(function(serviceResult){
    // 获取服务端返回的数据
    var result = serviceResult.result;
});查看源码 »
 

运行效果

泰森多边形

泰森多边形是荷兰气候学家 A.H.Thiessen 提出的一种根据离散分布的气象站的降雨量来计算平均降雨量的方法,即将所有相邻气象站连成三角形,作这些三角形各边的垂直平分线,于是每个气象站周围的若干垂直平分线便围成一个多边形。用这个多边形内所包含的一个唯一气象站的降雨强度来表示这个多边形区域内的降雨强度,并称这个多边形为泰森多边形。泰森多边形又称为 Voronoi 图,是由一组连接两邻点直线的垂直平分线组成的连续多边形组成。

泰森多边形的特性为:

  • 每个泰森多边形内仅含有一个离散点数据;
  • 泰森多边形内的点到相应离散点的距离最近;
  • 位于泰森多边形边上的点到其两边的离散点的距离相等。

泰森多边形的接口使用方法如下:

下面以数据集泰森多边形为例,设置泰森多边形服务对象,用于将客户端设置的泰森多边形服务参数传递给服务端,并接收服务端返回的泰森多边形分析结果数据。

     var serviceUrl = "https://iserver.supermap.io/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst";
// 设置泰森多边形分析参数
var dsThiessenAnalystParameters = new maplibregl.supermap.DatasetThiessenAnalystParameters({
    dataset: "Town_P@Jingjin"
});
// 创建泰森多边形分析实例
new maplibregl.supermap.SpatialAnalystService(serviceUrl).thiessenAnalysis(dsThiessenAnalystParameters).then(function (serviceResult) {
    // 获取返回的features数据
    var features = serviceResult.result.regions;
});查看源码 »
 

运行效果

叠加分析

叠加分析是 GIS 中的一项非常重要的空间分析功能,是指在统一空间参考系统下,通过对两个数据集进行的一系列集合运算,产生新数据集的过程,其目的是通过对空间数据的加工或分析,提取用户需要的新的空间几何信息。同时,通过叠加分析,还将对数据的各种属性信息进行处理。

目前叠加分析广泛应用于资源管理、城市建设评估、国土管理、农林牧业、统计等领域。叠加分析在各领域中的作用:

  • 资源管理主要应用于农业和林业领域,解决农业和林业领域各种资源(如土地、森林、草场等)分布变化、统计等问题;
  • 城市建设评估主要应用于分析城市人口、经济、建设等的发展变化,统计变化趋势和变化规律;
  • 土地和地籍管理涉及土地使用性质变化、地块轮廓变化、地籍权属关系变化等许多内容,借助 GIS 的叠加分析功能可以高效、高质量地完成这些工作;
  • 生态、环境的管理评价用于区域生态规划的评价、环境现状评价、环境影响评价、污染物削减分配的决策支持等;
  • 地学研究与应用中的地形分析、流域分析、土地利用研究、经济地理研究、空间统计分析、制图等都可以借助叠加分析来完成。

下面将京津地区的行政区域与临边地区的行政区域进行叠加分析,叠加分析接口使用方法如下所示:

设置叠加分析参数:

     // 设置叠加分析参数
var dsOverlayAnalyParams = new maplibregl.supermap.DatasetOverlayAnalystParameters({
    // 叠加分析中源数据集的名称
    sourceDataset: "BaseMap_R@Jingjin",
    // 叠加分析中操作数据集名称
    operateDataset: "Neighbor_R@Jingjin",
    // 容限
    tolerance: 0,
    // 叠加分析操作类型
    operation: maplibregl.supermap.OverlayOperationType.UNION
});
 

设置叠加分析服务对象,用于将客户端设置的叠加分析服务参数传递给服务端,并接收服务端返回的分析结果数据。当向服务端发送请求并且服务端成功返回结果时,用户可对获得的叠加分析结果做相应处理。

             var serviceUrl = "https://iserver.supermap.io/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst";
// 创建叠加分析服务实例
var overlayAnalystService =new maplibregl.supermap.SpatialAnalystService(serviceUrl);
// 向服务端发送服务请求,并获取返回的结果
overlayAnalystService.overlayAnalysis(dsOverlayAnalyParams).then(function (serviceResult) {
    // 获取返回的features数据
    var features = serviceResult.result.regions;
});查看源码 »
 

运行效果

提取等值线/面

提取等值线和提取等值面。等值线是将相邻的、具有相同值的点连起来的线,常用的等值线有等高线、等深线、等温线、等压线、等降水量线等。等值线的分布反映了栅格表面上值的变化,等值线分布越密集的地方,表示栅格表面值的变化比较剧烈。等值线分布较稀疏的地方,表示栅格表面值的变化较小。通过提取等值线,可以找到高程、温度、降水量等值相同的位置,同时等值线的分布状况也可以反映出变化的陡峭和平缓区。等值面是由相邻的等值线封闭组成的面,等值面的变化可以很直观地表示出相邻等值线之间的变化,诸如高程、降水、温度或大气压力等。通过提取等值面可以获得高程、降水、温度等值相同的地方。

本节将通过从全国平均气温采样点中提取等值线的功能来具体说明表面分析的接口使用。

设置表面分析参数、表面分析提取操作参数。

     // 剪裁区域设置
var region = {
    "type": "Feature",
    "geometry": {
        "type": "Polygon",
        "coordinates": [[
            [0, 4010338],
            [1063524, 4010338],
            [1063524, 3150322],
            [0, 3150322]
        ]]
    }
};
// 表面分析参数设置
var extractParams = new maplibregl.supermap.SurfaceAnalystParametersSetting({
    datumValue: 0, // 表面分析中提取等值线基准值
    interval: 2, // 等值距,两条等值线之间的间隔值
    resampleTolerance: 0, // 重采样容限
    smoothMethod: maplibregl.supermap.SmoothMethod.BSPLINE, // 光滑处理所使用的方法
    smoothness: 3, // 等值线的光滑度
    clipRegion: region // 裁剪对象
});
// 表面分析提取操作参数
var surfaceAnalystParams = new maplibregl.supermap.DatasetSurfaceAnalystParameters({
    extractParameter: extractParams, // 表面分析参数
    dataset: "SamplesP@Interpolation", // 叠加分析中源数据集名称
    resolution: 3000, // 中间结果分辨率
    zValueFieldName: "AVG_TMP" // 用于提取操作的字段名称
});
 

设置表面分析服务对象,用于将客户端设置的表面分析服务参数传递给服务端,并接收服务端返回的表面分析结果数据。当向服务端发送请求并且服务端成功返回结果时,用户可对获得的表面分析结果做相应处理。

             var serviceUrl = "https://iserver.supermap.io/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst" ;
// 创建表面分析服务实例
var surfaceAnalystService =new maplibregl.supermap.SpatialAnalystService(serviceUrl);
// 向服务端发送请求,并对返回的结果进行处理
surfaceAnalystService.surfaceAnalysis(surfaceAnalystParams).then(function (serviceResult) {
    // 获取返回的features数据
    var features = serviceResult.result.regions;
});查看源码 »
 

运行效果

点定里程

点定里程是计算路由上某点到起始点的 M 值,实际应用情景例如:知道某事故发生的位置确定该点位于某路口距离。

下面以京津数据为例,计算一条路上发生交通事故的地点到该条路路口的距离,点定里程接口使用方法如下:

地图加载完成后进行点定里程分析服务,构造路由对象之后才能进行后续的点定里程操作。

      // 为了构造下面点定里程服务sourceRoute属性的routeLine
var piontLists = [
    [116.2143386597, 39.8959419733, 0],
    [116.217501999125, 39.896670999665, 282.3879789906],
    [116.220156000875, 39.896820999605, 509.9746364534],
    [116.228716999, 39.8968419995966, 1242.1340098965],
    [116.25000000025, 39.8968619995886, 3062.3045713007],
    [116.27412300025, 39.8967689996258, 5125.3836697258],
    [116.310443000875, 39.8971139994878, 8231.7823666408],
    [116.344168500812, 39.8976724992644, 11116.7053546891]
];

var LineGeometryData = {
    "type": "Feature",
    "geometry": {
        "type": "LineString",
        "coordinates": piontLists
}

// 将形成路由的点提出来,为了构造下面点定里程服务sourceRoute
var routeObj = LineGeometryData.geometry.coordinates;
var routeLine = LineGeometryData;

// 在组成路由的点中选取一个查询点(数组中第4个点),并添加到地图上
var point = [routeObj[4][0], routeObj[4][1]];
var pointGeometryData = {
    "type": "Feature",
    "geometry": {
        "type": "Point",
        "coordinates": point
    }
};
// 创建点定里程服务实例
var serviceUrl ="https://iserver.supermap.io/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst";
var routeCalculateMeasureService =new maplibregl.supermap.SpatialAnalystService(serviceUrl);
// 点定里程服务参数设置
var routeCalculateMeasureParameters = new maplibregl.supermap.RouteCalculateMeasureParameters({
        "sourceRoute": routeLine, // 路由类型
        "point": pointGeometryData,// 查询点
        "tolerance": 0.0001,
        "isIgnoreGap": false
});
// 向服务端发送请求并获取数据
routeCalculateMeasureService.routeCalculateMeasure(routeCalculateMeasureParameters).then(function (routeCaculateServiceResult) {
    // 获取服务端返回的数据
    var result = routeCaculateServiceResult.result;
});查看源码 »
                        

运行效果

里程定点

里程定点是根据指定路由上的 M 值来定位点。应用情景与点定里程相反,如知道某事故距离某路口位置,需要确定其相对精确的坐标的时候使用。

下面以京津数据为例,确定一条发生交通事故的路上与路口距离为 6753 m 的事故点,里程定点的接口使用方法:

地图加载完成后进行里程定点分析服务,构造路由对象之后才能进行后续的里程定点操作。

     // 为了构造下面里程定点服务sourceRoute属性的routeLine
var piontLists = [
    [116.2143386597, 39.8959419733, 0],
    [116.217501999125, 39.896670999665, 282.3879789906],
    [116.220156000875, 39.896820999605, 511.787745072744],
    [116.228716999, 39.8968419995966, 1253.201708792909],
    [116.25000000025, 39.8968619995886, 3103.167523778722],
    [116.27412300025, 39.8967689996258, 5201.062444476062],
    [116.310443000875, 39.8971139994878, 8360.617856315024],
    [116.344168500812, 39.8976724992644, 11294.738396325054]
    ];

var LineGeometryData = {
    "type": "Feature",
    "geometry": {
        "type": "LineString",
         "coordinates": piontLists
    }
};
// 将形成路由的点提出来,为了构造下面点定里程服务sourceRoute
var routeLine = LineGeometryData;

// 创建里程定点服务实例
var serviceUrl ="https://iserver.supermap.io/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst";
var routeLocatorService =new maplibregl.supermap.SpatialAnalystService(serviceUrl);
// 里程定点参数设置
var routeLocatorParams_point = new maplibregl.supermap.RouteLocatorParameters({
    "sourceRoute": routeLine, // 路由对象
    "type": "POINT", // 类型,点或线
    "measure": 6753, // 里程值
    "offset": 0, // 定位点偏移量
    "isIgnoreGap": true // 是否忽略子对象之间的距离
});
// 向服务器发送请求进行里程定点服务分析,并将返回的结果进行处理展现在客户端上
routeLocatorService.routeLocate(routeLocatorParams_point).then(function (serviceResult) {
    // 获取服务端返回的数据
    var result = routeCaculateServiceResult.result;
});查看源码 »
 

运行效果

里程定线

里程定线是根据指定线的范围来确定路由上对应的线对象。应用场景如当知道某一路段发生阻塞,能够确定该路段相对精确的位置范围。

下面以京津数据为例,一条路在距离路口 1123-4489 m 之间的发生堵塞。

地图加载完成后进行里程定线分析服务,构造路由对象之后才能进行后续的里程定线操作。里程定线的接口使用方法如下:

             // 为了构造下面里程定点服务sourceRoute属性的routeLine
var piontLists = [
    [116.2143386597, 39.8959419733, 0],
    [116.217501999125, 39.896670999665, 282.3879789906],
    [116.220156000875, 39.896820999605, 511.787745072744],
    [116.228716999, 39.8968419995966, 1253.201708792909],
    [116.25000000025, 39.8968619995886, 3103.167523778722],
    [116.27412300025, 39.8967689996258, 5201.062444476062],
    [116.310443000875, 39.8971139994878, 8360.617856315024],
    [116.344168500812, 39.8976724992644, 11294.738396325054]
];

var LineGeometryData = {
    "type": "Feature",
    "geometry": {
        "type": "LineString",
        "coordinates": piontLists
    }
};

// 将形成路由的点提出来,为了构造下面点定里程服务sourceRoute
var routeLine = LineGeometryData;
// 里程定线参数设置
var routeLocatorParams_line = new maplibregl.supermap.RouteLocatorParameters({
   "sourceRoute": routeLine, // 路由对象
   "type": "LINE", // 类型,点或线
   "startMeasure": 1123, // 定位线的起始M值
   "endMeasure": 4489, // 定位线的终止M值
   "isIgnoreGap": true // 是否忽略子对象之间的距离
});
// 创建里程定线服务实例
var serviceUrl ="https://iserver.supermap.io/iserver/services/spatialanalyst-sample/restjsr/spatialanalyst";
var routeLocatorService =new maplibregl.supermap.SpatialAnalystService(serviceUrl);
// 向服务器发送请求进行里程定线服务分析,并将返回的结果进行处理展现在客户端上
routeLocatorService.routeLocate(routeLocatorParams_line).then(function (serviceResult) {
    // 获取服务端返回的数据
    var result = routeCaculateServiceResult.result;
});查看源码 »
         

运行效果

栅格代数运算

栅格代数运算是运用代数学的观点对地理特征和现象进行空间分析,即对一个或多个栅格数据进行数学运算和函数运算。同时,运算得出的结果栅格数据的像元值是由一个或多个输入栅格数据的同一位置的像元值通过代数运算得到的。

为了更好地实现栅格代数运算功能,SuperMap 提供了丰富的运算符、函数和运算表达式,除了常用的算术运算(如加、减、乘、除和取整等)方法,还支持通过用户自定义的表达式,来进行栅格的算术运算、条件运算、逻辑运算、函数运算(包括常用函数、三角函数等)和复合运算,用户可以通过栅格代数运算实现多种栅格分析需求。

栅格代数运算接口使用方法如下:

     // 创建栅格代数运算服务实例
var mathExpressionAnalysisService =new maplibregl.supermap.SpatialAnalystService(serviceUrl);
// 创建栅格代数运算参数实例
var mathExpressionAnalysisParameters = new maplibregl.supermap.MathExpressionAnalysisParameters({
    // 指定数据集,必设
    dataset: "JingjinTerrain@Jingjin",
    // 要执行的栅格运算代数表达式,必设
    expression: "[Jingjin.JingjinTerrain] + 600",
    // 存储结果数据集的数据源,必设
    targetDatasource: "Jingjin",
    // 结果数据集名称,必设
    resultGridName: "MathExpressionAnalysis_Result",
    deleteExistResultDataset: true
});
// 向iServer发起栅格代数运算请求
mathExpressionAnalysisService.mathExpressionAnalysis(mathExpressionAnalysisParameters).then(function (serviceResult) {
    // 获取服务端返回的数据
    var mathExpressionAnalysisResult = serviceResult.result;
});查看源码 »
 

运行效果

地形计算

地形计算又称地形曲率计算,栅格数据表面的曲率,包括平均曲率、剖面曲率和平面曲率。曲率是表面的二阶导数,或者可称之为坡度的坡度。输出结果为地形栅格每个像元的表面曲率,该值通过将该像元与八个相邻像元拟合而得。结果输出为栅格数据集,可输出曲率类型为:平均曲率、剖面曲率和平面曲率,平均曲率为必须输出的结果,剖面曲率和平面曲率为可选择输出。其中,剖面曲率是指沿最大斜率方向的曲率,平面曲率是指垂直于最大斜率方向的曲率。

设置曲率计算的栅格数据集有以下几个:

  • 数据源:列出了当前工作空间中所有的数据源,选择要进行曲率计算的栅格数据集所在的数据源;
  • 数据集:列出了当前数据源中所有的栅格数据集,在列表中选择曲率计算栅格数据集。若在工作空间管理器中选中了栅格数据集,则会自动定位到该数据集;
  • 高程缩放系数:计算曲率时,要求地形栅格值(即高程值)的单位与 x,y 坐标的单位相同,通常需要将高程值乘以一个高程缩放系数,使得三者单位一致。例如,X、Y 方向上的单位是米,而 Z 方向的单位是英尺,由于 1 英尺等于 0.3048 米,则需要指定缩放系数为 0.3048。如果设置为 1,表示不缩放。

在进行地形计算处理之前,需要先初始化地图。

地图加载完成后进行地形计算分析服务。

     // 设置地形曲率计算服务参数
var terrainCurvatureCalculationParameters = new maplibregl.supermap.TerrainCurvatureCalculationParameters({
    dataset: "JingjinTerrain@Jingjin",
    zFactor: 1.0,
    averageCurvatureName: "CurvatureA",
    deleteExistResultDataset: true
});
// 创建地形曲率计算服务实例
var terrainCurvatureCalculationService =new maplibregl.supermap.SpatialAnalystService(serviceUrl);
// 向iServer发起地形曲率计算请求
var terrainCurvatureCalculationService.terrainCurvatureCalculate(terrainCurvatureCalculationParameters).then(function (serviceResult) {
    // 获取服务端返回的数据
    var terrainCurvatureCalculationResult = serviceResult.result;
});查看源码 »
 

运行效果

地址匹配

SuperMap iClient for MapLibreGL 支持地址匹配服务。地址匹配服务包含正向匹配与反向匹配两种方式,即,用户可通过地点名称找到地址位置,也可以找到指定位置上的地点。

正向地址匹配

正向地址匹配根据地点描述、城市范围返回对应的地理坐标和结构化的地址详细描述,支持中文模糊匹配。

                        // 正向匹配参数
var geoCodeParam = new maplibregl.supermap.GeoCodingParameter({
    address: "超图软件", // 地址
    fromIndex:0, // 设置返回对象的起始索引值
    toIndex:10, // 设置返回对象的结束索引值
    filters: "北京市,朝阳区", // 过滤条件
    prjCoordSys:{epsgcode26}, // 坐标设置
    maxReturn:3 // 最大返回结果数
});
//创建地址匹配服务
var addressUrl = "https://iserver.supermap.io/iserver/services/addressmatch-Address/restjsr/v1/address",
var addressMatchService =new maplibregl.supermap.AddressMatchService(addressUrl);
// 向服务端发送请求进行正向地址匹配,并获取返回的结果
addressMatchService.code(geoCodeParam).then(function (obj){
    // 获取服务端返回的结果
    var features = obj.result
});查看源码 »
                    

运行效果

反向地址匹配

反向地址匹配通过输入地址坐标来获取对应的规范化的地址描述。

                        // 反向匹配参数
var geoDecodeParam = new maplibregl.supermap.GeoDecodingParameter({
    x: 116.3518541194, // 横坐标
    y: 40.00097839595, // 纵坐标
    fromIndex: 0, // 设置返回对象的起始索引值
    toIndex: 10, // 设置返回对象的结束索引值
    filters: "", // 过滤字段
    prjCoordSys: {epsgcode26}, // 坐标设置
    maxReturn: 3, // 最大结果数
    geoDecodingRadius: 1000 // 查询半径
});
// 创建地址匹配服务
var addressUrl = "https://iserver.supermap.io/iserver/services/addressmatch-Address/restjsr/v1/address",
addressMatchService = new maplibregl.supermap.AddressMatchService(addressUrl);
// 向服务端发送请求进行反向地址匹配,并获取返回的结果
addressMatchService.decode(geoDecodeParam).then(function (obj){
    // 获取服务端返回的结果
    var features = obj.result
});查看源码 »
                    

运行效果

大数据分析

SuperMap iClient for MapLibreGL 对接了 SuperMap iServer 的分布式分析服务,为用户提供大数据分析功能,主要包括:

  • 密度分析
  • 点聚合分析
  • 单对象空间查询分析
  • 区域汇总分析
  • 矢量裁剪分析
  • 属性汇总分析
  • 拓扑检查分析

密度分析

SuperMap iServer 的分布式分析服务中的密度分析包括简单点密度分析和核密度分析两种:

  • 简单点密度分析:用于计算每个点的指定邻域形状内的每单位面积量值。计算方法为点的测量值除以指定邻域面积,点的邻域叠加处,其密度值也相加,每个输出栅格的密度均为叠加在栅格上的所有邻域密度值之和。结果栅格值的单位为原数据集单位的平方的倒数,即若原数据集单位为米,则结果栅格值的单位为每平方米;
  • 核密度分析:用于计算点、线要素测量值在指定邻域范围内的单位密度。简单来说,它能直观地反映出离散测量值在连续区域内的分布情况。其结果是中间值大周边值小的光滑曲面,栅格值即为单位密度,在邻域边界处降为 0。核密度分析可用于计算人口密度、建筑密度、获取犯罪情况报告、旅游区人口密度监测、连锁店经营情况分析等等。

下面对大数据进行简单点密度分析,网格面类型为四边形网格。其接口使用方法如下:

设置密度分析参数 kernelDensityJobParam,包括数据集、分析方法、分析类型、格网大小等。

     // 密度分析参数
var kernelDensityJobParam = new maplibregl.supermap.KernelDensityJobParameter({
    // 数据集名
    datasetName: "newyork_taxi_2013_01_14k_csv_newyork_taxi_2013-01_14k",
    // 网格大小,对于四边形网格为网格的边长;对于六边形网格为六边形顶点到中心点的距离
    resolution: 80,
    // 分析方法,指定分析方法为简单点密度分析,还是核密度分析。0表示前者,1表示后者
    method:0,
    // 格网面类型,指定网格单元为四边形网格,还是六边形网格。0表示前者,1表示后者
    meshType:0,
    // 指定待分析的点的权重值所在的字段索引列号集合,字段索引从0开始。格式如:col7,col8
    fields: col7,col8,
    query: Bounds, // 分析范围
    radius: 300, // 分析的影响半径
    meshSizeUnit: Meter, // 网格大小单位
    radiusUnit: Meter, // 搜索半径单位
    areaUnit: SquareMile, // 面积单位
});
                        

向服务端提交密度分析的请求,获取服务端成功处理并返回的密度分析结果。

 // 创建密度分析实例
var processingUrl ="https://iserver.supermap.io/iserver/services/spatialprocessing/rest/v1/jobs";
var processingService = new maplibregl.supermap.ProcessingService(processingUrl);
// 向服务器发送请求进行密度分析服务,并获取返回的数据
processingService.addKernelDensityJob(kernelDensityJobParams).then(function (serviceResult) {
    // 获取服务端返回的数据
    var result = serviceResult.result;
});查看源码 »
                        

运行效果

点聚合分析

点聚合分析,是指针对点数据集制作聚合图的一种空间分析作业。通过网格面或多边形对地图点要素进行划分,然后计算每个面对象内点要素的数量,并作为面对象的统计值,也可以引入点的权重信息,考虑面对象内点的加权值作为面对象的统计值;最后基于面对象的统计值,按照统计值大小排序的结果,通过色带对面对象进行色彩填充。

目前支持的点聚合分析类型包括:网格面聚合和多边形聚合,其中网格面聚合图按照网格类型又可分为四边形网格和六边形网格。

下面进行点聚合分析,其中聚合类型为网格面聚合,网格面类型为四边形网格。其接口使用方法如下:

设置点聚合分析参数 summaryMeshJobParam,包括数据集、聚合类型、统计模式、格网大小等。

// 点聚合分析参数
var summaryMeshJobParam = new maplibregl.supermap.SummaryMeshJobParameter({
    // 数据集名
    datasetName: "newyork_taxi_2013_01_14k_csv_newyork_taxi_2013-01_14k",
    // 网格大小,对于四边形网格为网格的边长;对于六边形网格为六边形顶点到中心点的距离
    resolution: 80,
    // 网格面类型,指定网格单元为四边形网格,还是六边形网格。0表示前者,1表示后者
    meshType:0,
    // 指定待分析的点的权重值所在的字段索引列号集合,字段索引从0开始。格式如:col7,col8
    fields: col7,
    query: Bounds, // 分析范围
    statisticModes:, // 统计模式,需与“权重值字段”个数保持一致
    type:SummaryType, // 聚合类型,指定聚合类型为网格面聚合,还是多边形聚合
    regionDataset: 'regionDataset' // 聚合面数据集,在多边形聚合时使用
});

向服务端提交点聚合分析的请求,待服务端成功处理并返回点聚合分析结果后对其进行解析处理。

// 创建点聚合分析实例
var processingUrl ="https://iserver.supermap.io/iserver/services/spatialprocessing/rest/v1/jobs";
var processingService = new maplibregl.supermap.ProcessingService(processingUrl);
// 向服务器发送请求进行点聚合分析服务,并获取返回的结果
processingService.addSummaryMeshJob(summaryMeshJobParam).then(function (serviceResult){
    // 获取服务端返回的数据
    var result = serviceResult.result;
});查看源码 »
                        

运行效果

单对象空间查询分析

空间查询是通过几何对象之间的空间位置关系来构建过滤条件的一种查询方式。例如:通过空间查询可以找到被包含在面中的空间对象,相离或者相邻的空间对象等。

SuperMap iServer 的分布式分析服务中的单对象空间查询,是指只支持查询对象数据集中的一个对象对被查询数据集做空间查询。如果查询对象数据集中有多个对象,则默认用 SmID 最小的对象对被查询数据集做空间查询。

该示例需要引入

                        mapbox-gl-draw (https://github.com/mapbox/mapbox-gl-draw)
                      

下面进行单对象空间查询分析,其中空间查询模式使用“相交”。其接口使用方法如下:

设置单对象空间查询分析参数 singleObjectQueryJobsParam,包括源数据集、查询对象数据集、空间查询模式。

    // 单对象空间查询分析参数
var singleObjectQueryJobsParam = new maplibregl.supermap.SingleObjectQueryJobsParameter({
    datasetName: 'ProcessingData_processing_newyorkZone_R', // 数据集名
    datasetQuery: 'ProcessingData_processing_singleRegion_R', // 查询对象所在数据集名称
    mode:'INTERSECT' // 空间查询模式
});
                    

向服务端提交单对象空间查询分析的请求,待服务端成功处理并返回单对象空间查询分析结果后对其进行解析处理。

    // 创建单对象空间查询分析实例
var processingUrl ="https://iserver.supermap.io/iserver/services/spatialprocessing/rest/v1/jobs";
var processingService = new maplibregl.supermap.ProcessingService(processingUrl);
// 向服务器发送请求进行单对象空间查询分析服务,并对返回结果进行处理展现在地图上
processingService.addQueryJob(singleObjectQueryJobsParam).then(function (serviceResult){
    // 获取服务端返回的数据
    var result = serviceResult.result;
});查看源码 »
                        

运行效果

区域汇总分析

区域汇总分析,是指针对线数据集和面数据集制作聚合图的一种空间分析作业。指通过网格面或多边形对地图线或面要素进行划分,然后,以标准属性字段或权重字段对每个网格单元内线或面要素进行统计,将统计结果作为该网格单元的统计值。最后按照网格单元统计值的大小进行排序,通过色带对网格单元进行色彩填充。

区域汇总分析的概念与点聚合分析的概念类似,不同的是点聚合分析是对点数据集进行统计计算,而区域汇总分析是对线数据集和面数据集进行统计计算。在区域汇总分析的概念里,网格单元的统计值有两种统计方式,以标准属性字段统计和以权重字段统计。

下面进行区域汇总分析,其中汇总类型为网格面汇总,网格面类型为四边形网格。其接口使用方法如下:

设置区域汇总分析参数 summaryRegionJobParam,包括数据集、汇总类型、网格面汇总类型等。

    // 区域汇总分析参数
var summaryRegionJobParam = new maplibregl.supermap.SummaryRegionJobParameter({
    datasetName: 'ProcessingData_processing_newyorkZone_R', // 数据集名
    // 聚合面数据集,在多边形聚合时使用
    regionDataset: 'regionDataset',
    // 汇总类型,包括网格面汇总和多边形汇总两种类型
    type: SummaryType,
    // 网格面类型,指定网格单元为四边形网格,还是六边形网格。0表示前者,1表示后者
    meshType:0,
    query: Bounds, // 分析范围
    standardSummaryFields: true, // 是否以标准属性字段统计
    // 当以标准属性字段统计时,标准属性字段统计的统计模式
    standardStatisticModes: StatisticAnalystMode,
    // 当以标准属性字段统计时,标准属性字段统计的字段名称
    standardFields: "LocationID",
    weightedFields:false,// 是否以权重字段统计
    // 使用权重字段统计模式,权重字段统计的统计模式
    weightedStatisticModes: "",
    // 使用权重字段统计模式时,权重字段统计的字段名称
    weightedSummaryFields: "",
    // 网格大小,对于四边形网格为网格的边长;对于六边形网格为六边形顶点到中心点的距离
    resolution:100,
    meshSizeUnit: Meter, // 网格大小单位
    sumShape:true // 是否统计长度或面积
});
                    

向服务端提交区域汇总分析的请求,待服务端成功处理并返回区域汇总分析结果后对其进行解析处理。

    // 创建区域汇总分析实例
var processingUrl ="https://iserver.supermap.io/iserver/services/spatialprocessing/rest/v1/jobs";
var processingService = new maplibregl.supermap.ProcessingService(processingUrl);
// 向服务器发送请求进行区域汇总分析服务,并获取返回的结果
processingService.addSummaryRegionJob(summaryRegionJobParam).then(function (serviceResult){
    // 获取服务端返回的数据
    var result = serviceResult.result;
});查看源码 »
                        

运行效果

矢量裁剪分析

矢量裁剪分析为对矢量数据集进行裁剪。包括内部裁剪和外部裁剪。内部裁剪指被裁剪的矢量数据集在裁剪区范围内的部分被保留到结果数据集中;相反,使用外部裁剪,则保留不在裁剪区范围内的那部分数据到结果数据集中。

SuperMap iServer 的分布式分析服务中的矢量裁剪分析,只支持裁剪对象数据集中的一个对象对源数据集做矢量裁剪。如果裁剪数据集中有多个对象,则默认用 SmID 最小的对象对源数据集做矢量裁剪。

该示例需要引入

                        mapbox-gl-draw (https://github.com/mapbox/mapbox-gl-draw)
                      

下面进行矢量裁剪分析,裁剪矢量分析模式使用内部裁剪。其接口使用方法如下:

设置矢量裁剪分析参数 vectorClipJobsParam,包括源数据、裁剪对象数据集、裁剪分析模式。

    // 矢量裁剪分析参数
var vectorClipJobsParam = new maplibregl.supermap.VectorClipJobsParameter({
    datasetName: 'ProcessingData_newyork_taxi_2013-01_14k', // 数据集名
    datasetOverlay: 'ProcessingData_processing_singleRegion_R', // 裁剪对象所在数据集名称
    mode:ClipAnalystMode // 裁剪分析模式
});
                    

向服务端提交矢量裁剪分析的请求,待服务端成功处理并返回矢量裁剪分析结果后对其进行解析处理。

    // 创建矢量裁剪分析实例
var processingUrl ="https://iserver.supermap.io/iserver/services/spatialprocessing/rest/v1/jobs";
var processingService = new maplibregl.supermap.ProcessingService(processingUrl);
//向服务器发送请求进行矢量裁剪分析服务,并对返回结果进行处理展现在地图上
processingService.addVectorClipJob(vectorClipJobsParam).then(function (serviceResult){
    // 获取服务端返回的数据
    var result = serviceResult.result;
});查看源码 »
                        

运行效果

属性汇总分析

属性汇总统计,指的是对输入的数据集中所选择的属性进行汇总统计。通过对输入的数据集设定分组字段、属性字段以及对属性字段需进行的统计模式,从而得到汇总统计的结果。

SuperMap iServer 的分布式分析服务中的属性汇总分析,默认将对所有对象进行属性汇总统计,也可使用逗号","分隔,设置多个字段,对对象进行分组后,每组分别进行属性汇总。属性汇总分析支持的统计模式有:max、min、average、sum、variance、stdDeviation。

下面进行属性汇总分析,统计模式使用 sum。其接口使用方法如下:

设置属性汇总分析参数 summaryAttributesJobsParameter,包括属性汇总数据集、分组字段、属性字段、统计模式。

// 属性汇总分析参数
var summaryAttributesJobsParameter = new maplibregl.supermap.SummaryAttributesJobsParameter({
    datasetName: 'sample_processing_newyorkZone_R',//数据集名
    groupField: 'borough',//分组字段
    attributeField: 'LocationID',//属性字段
    statisticModes: 'sum'//统计模式
});
                        

向服务端提交属性汇总分析的请求,待服务端成功处理并返回属性汇总分析结果后对其进行解析处理。

// 创建属性汇总分析实例
var processingUrl ="https://iserver.supermap.io/iserver/services/spatialprocessing/rest/v1/jobs";
var processingService = new maplibregl.supermap.ProcessingService(processingUrl);
// 向服务器发送请求进行属性汇总分析服务,并对返回结果进行处理展现在地图上
processingService.addSummaryAttributesJob(summaryAttributesJobsParameter).then( function(serviceResult){
    // 获取服务端返回的数据
    var result = serviceResult.result;
});查看源码 »
                

运行效果

拓扑检查分析

拓扑检查分析,指的是根据相应的拓扑规则对点、线和面数据进行检查,检查出数据集本身及不同类型数据集相互之间不符合拓扑规则的对象,并返回检查出的拓扑错误数据集的一种操作作业。

SuperMap iServer 的分布式分析服务中的拓扑检查分析,支持以下 7 种拓扑规则:面数据集内部无交叠、面数据集和面数据集无交叠、面数据集被面数据集包含、面数据集被面数据集覆盖、线数据集内部无交叠、线数据集与线数据集无交叠、点数据集内部无重复点。

下面进行拓扑检查分析,拓扑规则使用:面数据集被面数据集覆盖。其接口使用方法如下:

设置拓扑检查分析参数 topologyValidatorJobsParameter,包括拓扑检查数据集、拓扑检查规则、容限。

// 拓扑检查分析参数
var topologyValidatorJobsParameter = new maplibregl.supermap.TopologyValidatorJobsParameter({
    datasetName: 'samples_processing_newyorkZone_R',// 数据集名
    datasetTopology: 'samples_processing_newyorkResidential_R',// 检查对象所在的数据集名称
    rule: maplibregl.supermap.TopologyValidatorRule.REGIONCOVEREDBYREGION,// 拓扑检查规则
    tolerance: 0.000001// 容限
});
                        

向服务端提交拓扑检查分析的请求,待服务端成功处理并返回拓扑检查分析结果后对其进行解析处理。

        // 创建拓扑检查分析实例
var processingUrl ="https://iserver.supermap.io/iserver/services/spatialprocessing/rest/v1/jobs";
var processingService = new maplibregl.supermap.ProcessingService(processingUrl);
// 向服务器发送请求进行拓扑检查分析服务,并对返回结果进行处理展现在地图上
processingService.addTopologyValidatorJob(topologyValidatorJobsParameter).then(function (serviceResult){
    // 获取服务端返回的数据
    var result = serviceResult.result;
});查看源码 »
                        

运行效果

数据流

SuperMap iServer 提供数据流服务,使客户端与服务器之间实现低延迟和实时数据传输。数据流服务采用 WebSocket 协议,支持全双工、双向式通信。服务器可将实时数据服务的分析处理结果作为数据来源向客户端广播,客户端与数据流服务建立连接后,即可自动接收服务器广播的数据。

                    // 初始化地图
var map,urlQuery ="https://iserver.supermap.io/iserver/services/map-china400/rest/maps/China_4326",
urlDataFlow ="https://iserver.supermap.io/iserver/services/dataflowTest/dataflow";
var popup = new maplibregl.Popup();
map.on('load', function () {
    var options = {
        ws: urlDataFlow
    };
    var dataFlowSubscribe = new maplibregl.supermap.DataFlowService(options.ws, {
        geometry: options.geometry,
        prjCoordSys: options.prjCoordSys,
        excludeField: options.excludeField
    }).initSubscribe();
    dataFlowSubscribe.on('messageSuccessed', function (msg) {
        popup.remove();
        addLayer(msg);
    });
    query();
});

// 模拟实时数据
// 查询一个线数据,每两秒将一个点通过dataFlowService广播给iSevrer的dataflow服务
function query() {
    var param = new maplibregl.supermap.QueryBySQLParameters({
        queryParams: {
            name: "Main_Road_L@China#1",
            attributeFilter: "SMID = 1755"
        }
    });
    queryService = new maplibregl.supermap.QueryService(urlQuery).queryBySQL(param).then(function (serviceResult) {
        featureResult = serviceResult;
        dataFlowBroadcast = new maplibregl.supermap.DataFlowService(urlDataFlow).initBroadcast();
        dataFlowBroadcast.on('broadcastSocketConnected', function (e) {
            timer = window.setInterval("broadcast()", 2000);
        });
    });
}

var count = 200;

function broadcast() {
    if (count >= featureResult.result.recordsets[0].features.features[0].geometry.coordinates.length) {
        window.clearInterval(timer);
        return;
    }
    var point = featureResult.result.recordsets[0].features.features[0].geometry.coordinates[count];
    var feature = {
        geometry: {
            coordinates: [point[0], point[1]],
            type: "Point"
        },
        type: "Feature",
        properties: {
            id: 1,
            time: new Date()
        }
    };
    dataFlowBroadcast.broadcast(feature);
    count += 3;
}

function addLayer(msg) {
    if (!msg.featureResult) {
        return;
    }
    var feature = msg.featureResult;
    var coord = feature.geometry.coordinates;
    var data = {
        geometry: {
            type: 'Point',
            coordinates: coord,
        },
        type: "Feature"
    };

    if (!map.getSource('location')) {
        map.addSource('location', {
            'type': 'geojson',
            'data': data
        });
        map.addLayer({
            "id": "point",
            "type": "circle",
            "paint": {
                "circle-radius": 6,
                "circle-color": 'red',
            },
            "source": 'location'
        });
    }
}查看源码 »
            

运行效果

数据可视化

SuperMap iClient for MapLibreGL 支持可视化包含:

热力图

原理:在客户端直接渲染的栅格图,热力图的渲染需要三大要素:

  • 热力数据,热力数据需要点数据,每一个热力数据需要有地理位置以及权重值 (能够明显地表现某位置某事件发生频率或事物分布密度等,如可以为温度的高低、人口密集度等等)
  • 热力衰减渐变填充色集合, 用于渲染每一个热力从中心向外衰减时的渐变色
  • 热力半径,也就是衰减半径。每一个热力需要从中心点外四周根据半径计算衰减度, 对在热力衰减区内的每一个像素计算需要渲染的颜色值,然后进行客户端渲染

应用场景:由于热力图的衰减是像素级别的,视觉效果方面极佳,但不能与具体数据进行一一对应,只能表示权重之间的差别,所以可以用于一些对精度要求不高而需要重点突出权重渐变的行业,如可以制作气象温度对比动态效果图、地震区域的震点强弱图等。

示例代码

        // 定义热力点数量,加热力半径
heatMapLayer = new maplibregl.supermap.HeatMapLayer(
    "heatMap",
    {
        "map": map,
        "id": "heatmap",
        "radius": 45,
        // featureWeight指定以哪个属性值为热力权重值创建热力图
        "featureWeight": "value",
    }
);

// 构造热力中心点
function createHeatPoints() {
    clearHeatPoints();
    var heatPoints = [];
    var num = 200;
    var radius = 50;
    var unit = "px";
    heatMapLayer.useGeoUnit = true;
}
heatMapLayer.radius = radius;

var features = [];

for (var i = 0; i < num; i++) {
    features[i] =
        {
            "type": "feature",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    Math.random() * 360 - 180,
                    Math.random() * 160 - 80]
            },
            "properties": {
                "value": Math.random() * 9,
            }
        };
}

var heatPoints = {
    "type": "FeatureCollection",
    "features": features
};

heatMapLayer.addFeatures(heatPoints);
map.addLayer(heatMapLayer);查看源码 »
                

运行效果

高效率点图层

高效率点图层(graphicLayer),主要是针对前端大数据量的点渲染。graphicLayer 支持选取对象事件。

该示例需要引入

                        PapaParse (https://github.com/mholt/PapaParse)
deck.gl (https://github.com/visgl/deck.gl)
dat-gui (https://github.com/dataarts/dat.gui)
                      

下面以纽约出租车上车点为例,进行可视化的展示:

直接通过 CDN 引入插件 papaparse.min.js

<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.3.2/papaparse.min.js"></script>
                    $.get('../data/nyc-taxi.csv', function (csvstr) {
    // 读取文件中的数据
    var result = Papa.parse(csvstr, {skipEmptyLines: true, header: true});
    addLayer(result.data);
});
// 定义样式相关属性
function addLayer(points) {
    var graphics = [];
    for (var i = 0; i < points.length; i++) {
        var lngLat = {
            lng: parseFloat(points[i].lng),
            lat: parseFloat(points[i].lat)
        };
        /**
            * 可以单独给要素设置颜色和半径:
            * new maplibregl.supermap.Graphic(lngLat,{
            *      color:[255,0,0],
            *      radius:40
            * });
            */
        graphics.push(new maplibregl.supermap.Graphic(lngLat));
    }

    var graphicStyle = {
        color: [0, 255, 128],
        radius: 10
    };
    // 绘制对象,并添加到图层上
    graphicLayer = new maplibregl.supermap.GraphicLayer("graphic", {
        graphics: graphics,
        radius: graphicStyle.radius,
        color: graphicStyle.color,
        highlightColor: [255, 0, 0, 255],
    });
    // 将画出来的点渲染到地图上
    map.addLayer(graphicLayer);
}查看源码 »
    

运行效果

ECharts

ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari 等),底层依赖轻量级的矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。

ECharts 提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭。

该示例需要引入

                        ECharts (https://github.com/apache/echarts)
echartsLayer (https://github.com/lzxue/echartsLayer)
                      

下面以长春市公交路特效图为例,将公交路线的数据进行可视化的展示:

                    var uploadedDataURL = "../data/changchunBus.json";
$.get(uploadedDataURL, function (data) {
    option = {
        animation: false,
        GLMap: {
            roam: true
        },
        coordinateSystem: 'GLMap',
        geo: {
            map: 'GLMap',
        },

        series: [{
            type: 'lines',
            polyline: true,
            data: data,
            silent: true,
            lineStyle: {
                normal: {
                    opacity: 0.2,
                    width: 1
                }
            },
            progressiveThreshold: 500,
            progressive: 100,
        }, {

            type: 'lines',
            coordinateSystem: 'GLMap',
            polyline: true,
            data: data,
            lineStyle: {
                normal: {
                    width: 0.2
                }
            },
            effect: {
                constantSpeed: 40,
                show: true,
                trailLength: 0.02,
                symbolSize: 2
            },
        }]
    };
    var echartslayer = new EchartsLayer(map);
    echartslayer.chart.setOption(option);
});查看源码 »
                

运行效果

DeckGL

DeckGL 是由 Uber 开发并开源出来的基于 WebGL 的大数据量可视化框架。

它具有提供不同类型可视化图层,GPU 渲染的高性能,React 和 Mapbox GL 集成,结合地理信息数据(GPS)的特点。

该示例需要引入

                        deck.gl (https://github.com/visgl/deck.gl)
                      

以下例子对数据进行蜂巢图层展示

                    $.get('../data/deck.gl/sf-bike-parking.json', function (features) {
    addLayer(features);
});
function addLayer(features) {
    deckglLayer = new maplibregl.supermap.DeckglLayer("hexagon-layer", {
        data: features,
        props: {
                extruded: true, // 是否拉伸要素,默认为 false
                radius: 200, // 六边形半径值,默认为 1000
                elevationScale: 4, // 高程乘数
                coverage: 0.8 // 六边形半径乘数,介于0 - 1之间,六边形的最终半径通过覆盖半径计算。
            // 还可配置的参数:
            // colorRange 色带,
            // 默认为 [[255,255,178,255],[254,217,118,255],[254,178,76,255],[253,141,60,255],[240,59,32,255],[189,0,38,255]]
            },
        callback: {
            getPosition: d => d.COORDINATES,
        }
    });
    map.addLayer(deckglLayer);
}查看源码 »
                

运行效果

MapV

MapV 是一款地理信息可视化开源库,可以用来展示大量地理信息数据,点、线、面的数据,每种数据也有不同的展示类型,如直接打点、热力图、网格、聚合等方式展示数据。

MapV 可展示大量的点数据,形式可以为热力图、网格、蜂窝状、点聚合、按颜色区间、按半径大小等。可展示大量的线数据,如普通画线、高亮叠加、热力线数据展示等方式,还有各种动画效果,适合用于呈现大量轨迹的场景。也可展示大量的自定义面数据,按颜色区间来展示,行政区域也是其中一种应用场景,可直接使用。

该示例需要引入

                        Mapv (https://github.com/huiyan-fe/mapv)
                      

SuperMap iClient for MapLibreGL 提供了对使用 MapV 可视化效果图层的支持,接口为:

                        maplibregl.supermap.MapvLayer(dataSet, options)
                    

下面以 MapV 强边界图为例,将数据进行可视化的展示。

指定图层的配置项和数据:

                    var randomCount = 500;
var node_data = {
    "0": {"x": 108.154518, "y": 36.643346},
    "1": {"x": 121.485124, "y": 31.235317},
};
var edge_data = [
    {"source": "1", "target": "0"}
];
var citys = ["北京", "天津", "上海", "重庆", "石家庄", "太原", "呼和浩特", "哈尔滨", "长春", "沈阳", "济南", "南京", "合肥", "杭州", "南昌", "福州", "郑州", "武汉", "长沙", "广州", "南宁", "西安", "银川", "兰州", "西宁", "乌鲁木齐", "成都", "贵阳", "昆明", "拉萨", "海口"];

// 构造数据
for (var i = 1; i < randomCount; i++) {
    var cityCenter = mapv.utilCityCenter.getCenterByCityName(citys[parseInt(Math.random() * citys.length)]);
    node_data[i] = {
        x: cityCenter.lng - 5 + Math.random() * 10,
        y: cityCenter.lat - 5 + Math.random() * 10,
    };
    edge_data.push(
        {"source": ~~(i * Math.random()), "target": '0'}
    );
}

var fbundling = mapv.utilForceEdgeBundling()
    .nodes(node_data)
    .edges(edge_data);

var results = fbundling();

var data = [];
var timeData = [];

for (var i = 0; i < results.length; i++) {
    var line = results[i];
    var coordinates = [];
    for (var j = 0; j < line.length; j++) {
        coordinates.push([line[j].x, line[j].y]);
        timeData.push({
            geometry: {
                type: 'Point',
                coordinates: [line[j].x, line[j].y]
            },
            count: 1,
            time: j
        });
    }

    data.push({
        geometry: {
            type: 'LineString',
            coordinates: transformCoords(coordinates)
        }
    });

    function transformCoords(coordinates) {
        var coords = [];
        coordinates.map(function (coordinate) {
            coords.push(coordinate);
        });
        return coords;
    }
}

var dataSet = new mapv.DataSet(data);

var options = {
    strokeStyle: 'rgba(55, 50, 250, 0.3)',
    globalCompositeOperation: 'lighter',
    shadowColor: 'rgba(55, 50, 250, 0.5)',
    shadowBlur: 10,
    lineWidth: 1.0,
    draw: 'simple'
};

var mapVLinelayer = new maplibregl.supermap.MapvLayer(dataSet, options);
map.addLayer(mapVLinelayer);

// 创建MapV图层
var dataSet = new mapv.DataSet(timeData);

var options = {
    fillStyle: 'rgba(255, 250, 250, 0.9)',
    globalCompositeOperation: 'lighter',
    size: 1.5,
    animation: {
        type: 'time',
        stepsRange: {
            start: 0,
            end: 100
        },
        trails: 1,
        duration: 5
    },
    draw: 'simple'
};

var mapVAnimationLinelayer = new maplibregl.supermap.MapvLayer(dataSet, options);
map.addLayer(mapVAnimationLinelayer);查看源码 »
                

运行效果

Threejs

Three.js 是一款开源的主流 3D 绘图 JS 引擎(名字 Three 就是 3D 的含义),原作者为 Mr.Doob,项目地址为:https://github.com/mrdoob/three.js/。我们知道 WebGL 是一种网页 3D 绘图标准,和 jQuery 简化了 HTML DOM 操作一样,Three.js 可以简化 WebGL 编程。

该示例需要引入

                        three.js (https://github.com/mrdoob/three.js)
GLTFLoader (https://github.com/johh/three-gltf-loader)
                      

SuperMap iClient for MapLibreGL 提供了对使用 three.js 可视化效果图层的支持,接口为:

maplibregl.supermap.ThreeLayer('three')
                            
                        function loaderModels() {
    var loader = new THREE.GLTFLoader();
    // 加载gltf格式数据
    loader.load('./js/airplane/airplane.glb', function (gltf) {
        var scene = gltf.scene;
        scene.rotation.x = -Math.PI / 2;
        scene.rotation.y = Math.PI / 2;
        scene.scale.multiplyScalar(150);

        addThreeLayer(scene);
    });
}

function addThreeLayer(meshes) {
    threeLayer = new maplibregl.supermap.ThreeLayer('three');
    threeLayer.on("initialized", render);
    threeLayer.addTo(map);

    function render() {
        var renderer = threeLayer.getThreeRenderer(),
            scene = threeLayer.getScene();
            camera = threeLayer.getCamera();

        this.light = new THREE.PointLight(0xaaaaaa, 0.5);
        this.light.position.copy(camera.position);
        scene.add(this.light);
        scene.add(new THREE.AmbientLight(0xffffff));
        threeLayer.setPosition(meshes, position);
        // 设置飞行高度
        meshes.translateY(5000);
        scene.add(meshes);

        (function animate() {
            requestAnimationFrame(animate);
            meshes.position.y -= 60;
            var center = map.getCenter().toArray();
            center[1] += 0.00008;
            map.setCenter(center);
            renderer.render(scene, camera);
        })()
    }

    // 均匀光照,与相机位置同步
    threeLayer.on("render", function () {
        threeLayer.light.position.copy(threeLayer.renderer.camera.position);
    });
}查看源码 »

                    

运行效果

Web符号

Web符号覆盖 SuperMap iDesktop、SuperMap iDesktopX 部分点线面符号,用户可通过 Web符号ID 快速添加符号到地图。同时,也可以按照符号规范自定义符号。 本节主要介绍Web符号的入门用法,详细接口请参考 API 页面

引入

文件方式引入

首先,引入 MaplibreGL 和 SuperMap iClient for MaplibreGL

然后,根据以下两种情况,设置 basePath 为 resources 文件夹的绝对或相对路径。

  • 默认 resources 文件夹路径

    resources 文件夹和入口 HTML 文件放在同级文件夹,则不需要配置 basePath,可直接使用默认值。

  • 自定义 resources 文件夹路径

    首先,下载的 SuperMap iClient for MaplibreGL 包,移动 resources 文件夹到项目任意位置。

    然后,设置 basePath 为 resources 文件夹绝对或相对于入口 HTML 路径。

                                new maplibregl.supermap.WebSymbol().init({basePath: "./resources/symbols"});
                                

npm 方式引入

首先,安装 @supermap/iclient-maplibregl

然后,移动 @supermap/iclient-maplibregl 安装包下 resources 文件夹到项目根目录下任意文件夹。

接下来,设置 basePath 为 resources 文件夹绝对或相对于根目录路径。

                    new maplibregl.supermap.WebSymbol().init({basePath: "./resources/symbols"});
                    

快速上手

符号规范

Web符号是由 Maplibre Layers 中的 paintlayout ( visibility 属性除外 )组成的符号对象。

使用Web符号

首先,获取 Web符号ID

然后,使用 new maplibregl.supermap.WebSymbol().init 初始化Web符号,并且指定符号资源路径。

再然后,使用接口 loadSymbol 加载Web符号。

接下来,使用接口 addSymbol 将符号添加到地图。

最后,使用接口 addLayer 添加图层,同时图层设置 Web 符号。

示例代码

                        // Web符号ID
const symbolId = "line-962524";
// 配置符号资源路径
new maplibregl.supermap.WebSymbol().init({basePath: "./resources/symbols"});
// 加载Web符号
map.loadSymbol(symbolId, (error, symbol) => {
    if (error) throw error;

    // 添加Web符号到地图
    map.addSymbol(symbolId, symbol);
    // 给指定图层设置Web符号
    map.addLayer({
        "id": "pl@landuse(0_24)",
        "source": "landuse",
        "source-layer": "pl@landuse",
        "type": "line",
        "symbol": symbolId
    });
});查看源码 »

                    

运行效果

使用自定义Web符号

首先,使用 new maplibregl.supermap.WebSymbol().init 初始Web符号。

然后,使用接口 addSymbol 将符号添加到地图。

接下来 addLayer 添加图层,同时图层设置 Web 符号。

示例代码

                        // 配置符号资源路径
new maplibregl.supermap.WebSymbol().init({basePath: "./resources/symbols"});                            
// 加载自定义点符号图片                            
map.loadImage("../img/cirecleRed.png", (error, image) => {
    if (error) throw error;

    // 自定义点符号图片
    const imageId = "cityPoint";
    // 添加点符号图片到地图
    map.addImage(imageId, image); 
    // 自定义点符号
    const customPointSymbol = {
        "paint": {
            "icon-translate": [0, 4]
        },
        "layout": {
            "icon-image": imageId,
            "icon-size": 0.1
        }
    };

    // 自定义点符号ID
    const pointSymbolId = "Province_P";
    // 添加点符号到地图
    map.addSymbol(pointSymbolId, customPointSymbol);
    // 给指定图层设置Web点符号
    map.addLayer({
        "id": "layerId",
        "source": "sourceId",
        "type": "symbol",
        "symbol": symbolId
    });
});

// 自定义线符号
const customLineSymbol = {
    "paint": {
        "line-width": 0.38,
        "line-dasharray": [
            2.5,
            2
        ],
        "line-color": "#AE10FC"
    }
};
// 自定义线符号ID
const lineSymbolId = "Province_P";
// 添加线符号到地图
map.addSymbol(lineSymbolId, customLineSymbol);
// 给指定图层设置线符号
map.addLayer({
    "id": "Province_L@Population",
    "source": "全国人口密度空间分布图",
    "source-layer": "Province_L@Population",
    "type": "line",
    "symbol": "Province_L"
});

// 自定义面符号数据驱动
map.addLayer({
    "id": "PopDensity_R@Population",
    "source": "全国人口密度空间分布图",
    "source-layer": "PopDensity_R@Population",
    "type": "fill",
    "symbol": [
        "case",
        ["all", ["<=", ["get", "dMaxZValue"], 70]], "PoPdensity_R_MAX70",
        ["all", [">", ["get", "dMaxZValue"], 70],["<=", ["get", "dMaxZValue"], 140]], "PoPdensity_R_MAX140",
        ["all", [">", ["get", "dMaxZValue"], 210],["<=", ["get", "dMaxZValue"], 280]], "PoPdensity_R_MAX280",
        ["all", [">", ["get", "dMaxZValue"], 350],["<=", ["get", "dMaxZValue"], 420]], "PoPdensity_R_MAX420",
        ["all", [">", ["get", "dMaxZValue"], 490],["<=", ["get", "dMaxZValue"], 560]], "PoPdensity_R_MAX560",
        ["all", [">", ["get", "dMaxZValue"], 640],["<=", ["get", "dMaxZValue"], 700]], "PoPdensity_R_MAX700",
        ["all", [">", ["get", "dMaxZValue"], 770],["<=", ["get", "dMaxZValue"], 1000]], "PoPdensity_R_MAX1000",
        ["all", [">", ["get", "dMaxZValue"], 1000]], "PoPdensity_R_Exceed1000",
        "Country_R"
    ]
});查看源码 »                          

                    

运行效果