首先 ,选用arcgis制图的原因是它支持原生、JS、安卓、IOS等多种API开发,生态链丰富,同时它可以完成图层和数据分析,这是最关键的一个原因,是其他制图工具做不到的。
uniapp中实现地图交互必须通过renderjs来完成,当地图功能非常繁琐的时候renderjs层将会十分庞大,所以我把使用到的arcgis方法封装成ES6的class类,这样地图功能调用初始化均可以通过new一个对象来实现。
简单加载一个地图页面 步骤
- 1.npm install--save esri-loader下载esri包
- 2.地图页面
<template>
<view >
<view id="myMapView" style=" height: 623px " />
</view>
</template>
<script module="myMapViews" lang="renderjs">
//renderjs部分
import {
loadModules
} from 'esri-loader'
export default {
name: 'myMapView',
data() {
return {};
},
mounted() {
this.createMapView()
},
methods: {
createMapView() {
const options = {
url: 'https://js.arcgis.com/4.14/init.js',
css: 'https://js.arcgis.com/4.14/esri/themes/light/main.css'
};
loadModules([
"esri/Map",
"esri/views/MapView"
], options).then(([Map, MapView]) => {
var map = new Map({
basemap: "topo-vector"
});
var view = new MapView({
container: "myMapView",
map: map,
center: [-118.80500, 34.02700], // longitude, latitude
zoom: 13
});
})
}
}
}
</script>
<scrip>
// service 层
</scrip>
<style>
</style>
注意:service层与renderjs层的交互与注意问题我在上一篇中简单介绍过,可以简单参考renderjs与service层交互
项目专题地图功能界面
首先是左侧功能列表,实现了地图的矢量测量、坐标查询、实时定位以及重置功能,这些基础功能实现是比较简单的。繁琐的是右侧右侧功能列表,从上面依次向下是图层控制、图层数据查询、地块占压分析等特定功能。逻辑功能是比较容易实现的,但是频繁调用地图功能以及频繁交互是很头痛的事。所以我在renderjs监听的render对象中添加很多属性,对应不同的响应事件,当不同属性值改变代表对应的地图功能触发。每次触发监听事件完成后,重置为空,下次就可以继续触发,在renderjs层接收传递的值,通过if条件判断值存在触发引入的地图方法。
图层控制
图层数据点查询,根据图层控制中打开的图层进行数据查询
图层数据区域查询
草图工具(撤销、恢复绘制区域)(当地图绘制点三个及以上时显示草图草图控制模块)
地块占地分析
定义地图类,需要使用loadModules导入arcgis方法包,因为import引入导致一部分方法无法使用,试过arcgis的不同版本依然存在问题,所以建议使用loadModules导入
ES6写法,将JTMapKit方法添加到原型上
草图工具相关
建议与地图绘制相关操作全部使用草图工具,比自己添加绘制层方便许多,且地图交互响应很快。自带sketchviewModel层用于存储临时标注,绘制完成自动删除。
/* 草图编辑工具--扩展方法 */
Object.assign(JTMapKit.prototype, {
/**
* 启用草图编辑工具
* @param {JSON} options 配置项
* options.onadded{function}:添加点回调
* options.onredo{function}:恢复回调
* options.onundo{function}:撤销回调
* @param {function} callSuccess 成功回调
*/
_sketchToolsInit: function(options, callSuccess) {
/* 自身替换 */
let _self = this;
loadModules([
"esri/layers/GraphicsLayer",
"esri/widgets/Sketch/SketchViewModel",
"esri/geometry/projection",
"esri/geometry/SpatialReference"
]).then(([GraphicsLayer, SketchViewModel, projection, SpatialReference]) => {
/* 判断是否存在草图图层 不存在则创建并加入地图中 */
if (!_self.layerSketch) {
_self.layerSketch = new GraphicsLayer();
_self.map.add(_self.layerSketch);
}
/* 草图辅助图层 */
if (!_self.graphicsLayer) {
_self.graphicsLayer = new GraphicsLayer();
_self.map.layers.add(_self.graphicsLayer);
}
/* 判断草图工具是否存在 不存在则创建 */
if (!_self.sketchViewModel) {
_self.sketchViewModel = new SketchViewModel({
layer: _self.layerSketch,
view: _self.mapView,
pointSymbol: _self.sketchPointSymbol,
polylineSymbol: _self.sketchLineSymbol,
polygonSymbol: _self.sketchPolygonSymbol,
});
/* 绑定创建事件 */
_self.sketchViewModel.on("create", function(event) {
if (event.state == "start") {
_self.layerSketch.removeAll(); //删除全部
}
if (event.toolEventInfo && event.toolEventInfo.type === "vertex-add") {
if (options && options.onadded) options.onadded(event.graphic
.geometry);
}
if (event.state === 'complete') {
if (options && options.oncomplete) options.oncomplete(event.graphic
.geometry);
}
});
/* 绑定redo事件 */
_self.sketchViewModel.on('redo', function(event) {
if (event.graphics && options && options.onredo) options.onredo(event
.graphics[0]
.geometry);
});
/* 绑定undo事件 */
_self.sketchViewModel.on('undo', function(event) {
if (event.graphics && options && options.onundo) options.onundo(event
.graphics[0]
.geometry);
});
// _self.sketchViewModel.create()
/* 回调 */
if (callSuccess) callSuccess();
}
});
},
})