UNIAPP中使用arcgis JS完成复杂地图功能

本文介绍选用ArcGIS制图的原因,因其支持多API开发且能完成图层和数据分析。在Uni-app中实现地图交互,将ArcGIS方法封装成ES6类。还阐述简单加载地图页面步骤、项目专题地图功能界面及草图工具相关内容,给出地图功能实现的方法和建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     首先 ,选用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();
			}
		});
	},
})

### 实现 UniApp 的 Map 组件图层切换 在 UniApp 中实现 `map` 组件的图层切换,可以通过动态修改地图组件的属性来完成。以下是基于提供的引用内容和专业知识的具体方法。 #### 1. 创建基础地图并初始化 首先需要引入必要的依赖库,并设置初始的地图参数。如果使用的是 ArcGIS 地图服务,则可以按照以下方式构建: ```javascript import { ref } from 'vue'; export default { setup() { const mapLayers = ref([ { name: 'Street', url: 'https://your-street-map-url' }, { name: 'Satellite', url: 'https://your-satellite-map-url' } ]); const currentLayerIndex = ref(0); function toggleLayer() { currentLayerIndex.value = (currentLayerIndex.value + 1) % mapLayers.value.length; } return { mapLayers, currentLayerIndex, toggleLayer }; } }; ``` 此部分代码实现了两个主要功能:存储不同类型的图层 URL 和提供一个函数用于切换当前显示的图层[^1]。 --- #### 2. 配置 Map 组件以支持图层切换 在模板中绑定数据源到 `map` 组件上,并通过按钮或其他交互控件触发图层切换逻辑。具体如下所示: ```html <template> <view class="container"> <!-- 地图 --> <map id="myMap" :longitude="116.397428" :latitude="39.90923" scale="12" :show-location="true" :enable-zoom="true" :enable-scroll="true" :enable-rotate="false" :layer-style="{ src: mapLayers[currentLayerIndex].url, type: 'webgl' }" ></map> <!-- 切换按钮 --> <button @click="toggleLayer">切换图层</button> </view> </template> ``` 上述代码片段展示了如何利用 Vue 数据驱动的方式更新 `map` 属性中的 `layerStyle.src` 值,从而达到实时切换的效果[^2]。 --- #### 3. 解决跨平台兼容性问题 由于 UniApp 是一个多端框架,在某些平台上可能会遇到特定限制或异常行为(如 iOS 下可能无法正常加载 WebGL 类型资源),因此建议针对这些情况进行适配处理。例如,对于 Android 平台推荐优先采用标准 Web 图片格式作为底图来源;而对于 H5 或小程序环境则继续沿用高性能矢量瓦片技术[^4]。 另外需要注意的一点是,当涉及到复杂 UI 控制时(比如浮动工具栏或者额外标注信息框),应考虑使用 `cover-view` 及其子标签系列来进行布局设计,因为它们能够很好地叠加于原生 `<map>` 元素之上而不会干扰底层渲染过程。 --- #### 完整示例总结 综合以上各部分内容后得到最终版本的应用程序结构如下: ```javascript // main.js import { createSSRApp } from 'vue'; import App from './App.vue'; export function createApp() { const app = createSSRApp(App); return { app }; } ``` ```css /* styles.css */ .container { position: relative; } .map-container { width: 100%; height: calc(100vh - 50px); /* 减去顶部导航高度 */ } .toggle-button { z-index: 999; position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); } ``` ```html <!-- index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>UniApp Map Layer Switcher</title> </head> <body> <div id="app"></div> </body> </html> ``` --- ###
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值