vue+arcgis api for js实现地图测距的分段统计线段长度

ops/2025/1/22 15:57:53/

vue页面调用代码:

<template><el-button @click="handleMeasureDis">地图测距</el-button><el-button @click="handleClear">清除</el-button>
</template>
import measureDistance from '@/views/fisheryMap/components/mixins/measureDistance.js'
export default {mixins: [ measureDistance],methods: {handleMeasureDis(){this.drawLine()},handleClear(){this.clearDistanceLine()},}
}

详细实现逻辑代码:measureDistance.js

import Draw from '@arcgis/core/views/draw/Draw.js'
import GroupLayer from '@arcgis/core/layers/GroupLayer.js'
import * as geometryEngine from '@arcgis/core/geometry/geometryEngine.js'
import GraphicsLayer from '@arcgis/core/layers/GraphicsLayer.js'
import Graphic from '@arcgis/core/Graphic.js'
export default {data() {return {drawLineLayer: null,textLayer: null,draw: null,groupLayer: null,lineNum: 0,mouseOperate: {start: false,end: null,pointermove: null,drag: null,click: null},curDrawLine: null,curLineLayer: null}},methods: {drawLine() {this.lineNum += 1this.drawLineLayer = this.mapAndView.map.findLayerById('drawLineLayer')if (!this.drawLineLayer) {this.drawLineLayer = new GraphicsLayer({id: 'drawLineLayer',graphics: [],spatialReference: this.mapAndView.spatialReference})this.mapAndView.map.add(this.drawLineLayer)} else {this.drawLineLayer.graphics.removeAll()}this.textLayer = this.mapAndView.map.findLayerById('textLayer')if (!this.textLayer) {this.textLayer = new GraphicsLayer({id: 'textLayer',graphics: [],spatialReference: this.mapAndView.spatialReference})this.mapAndView.map.add(this.textLayer)} else {this.textLayer.graphics.removeAll()}this.draw = new Draw({view: this.mapAndView})let action = this.draw.create('polyline', { mode: 'click' })// fires when a vertex is addedaction.on('vertex-add', evt => {let polyline = this.createLine(evt.vertices)let lineLength =  geometryEngine.geodesicLength(polyline, 'kilometers')if (evt.vertices.length > 1) {this.createSymbol(evt.vertices[evt.vertices.length - 1][0], evt.vertices[evt.vertices.length - 1][1], lineLength.toFixed(2) + 'km')} else {this.createSymbol(evt.vertices[evt.vertices.length - 1][0], evt.vertices[evt.vertices.length - 1][1])}})// fires when the pointer movesaction.on('cursor-update', evt => {this.createLine(evt.vertices)})// fires when the drawing is completedaction.on('draw-complete', evt => {this.createLine(evt.vertices)this.groupLayer = this.mapAndView.map.findLayerById('groupLayer')if (!this.groupLayer) {this.groupLayer = new GroupLayer({id: 'groupLayer',spatialReference: this.mapAndView.spatialReference})this.mapAndView.map.add(this.groupLayer)} let lineAndTextLayer = new GraphicsLayer({id: 'distanceLineLayer' + this.lineNum,graphics: [],spatialReference: this.mapAndView.spatialReference})this.mapAndView.map.add(lineAndTextLayer)// 添加线尾的删除图标this.createLastSymbol(evt.vertices[evt.vertices.length - 1][0], evt.vertices[evt.vertices.length - 1][1])lineAndTextLayer.addMany(this.drawLineLayer.graphics.items)lineAndTextLayer.addMany(this.textLayer.graphics.items)this.groupLayer.layers.add(lineAndTextLayer)this.drawLineLayer.graphics.removeAll()this.textLayer.graphics.removeAll()})// fires when a vertex is removedaction.on('vertex-remove', evt => {this.createLine(evt.vertices)})this.mapAndView.on('pointer-move', event => {let graphic = nullthis.mapAndView.hitTest(event).then(res => {this.mapAndView.cursor = 'default'if (res.results.length) {graphic = res.results[0].graphicif (graphic?.layer?.id?.indexOf('distanceLineLayer') > -1 && (graphic.symbol?.type === 'simple-marker'|| graphic.symbol?.type === 'picture-marker')) {this.mapAndView.cursor = 'pointer'}} })if (this.mouseOperate.start && this.arrIndex > -1) {const screenPoint = {x: event.x,y: event.y,spatialReference: this.mapAndView.spatialReference}let coordinate = this.mapAndView.toMap(screenPoint)this.curDrawLine.geometry.paths[0][this.arrIndex] = [coordinate.x, coordinate.y]this.createLine(this.curDrawLine.geometry.paths[0], this.curLineLayer)this.textLayer.graphics.removeAll()this.curDrawLine.geometry.paths[0].map((item, index) => {if (index === 0) {this.createSymbol(item[0], item[1])} else if (index === this.curDrawLine.geometry.paths[0].length - 1) {this.createSymbol(item[0], item[1])this.createLastSymbol(item[0], item[1])} else {let polyline = {type: 'polyline', paths: [[this.curDrawLine.geometry.paths[0][0], item]],spatialReference: this.mapAndView.spatialReference}let lineLength =  geometryEngine.geodesicLength(polyline, 'kilometers')this.createSymbol(item[0], item[1], lineLength.toFixed(2) + 'km')}})this.curLineLayer.addMany(this.textLayer.graphics.items)this.textLayer.graphics.removeAll()}})this.mapAndView.on('double-click', event => {this.mapAndView.hitTest(event).then(res => {if (this.mouseOperate.start) {this.mouseOperate.start = false} })})this.mapAndView.on('pointer-down', event => {this.mapAndView.hitTest(event).then(res => {if (res.results.length) {let graphic = res.results[0].graphicthis.arrIndex = -1this.curDrawLine = nullthis.curLineLayer = nullif (graphic?.layer?.id?.indexOf('distanceLineLayer') > -1) {if (graphic.symbol?.type === 'simple-marker') {let lineLayer = this.groupLayer.findLayerById(graphic.layer.id)let lineGeometry = lineLayer.graphics.items[0]lineGeometry.geometry.paths[0].map((item, index) => {if (item[0] === graphic.geometry.x && item[1] === graphic.geometry.y) {this.arrIndex = index}})if (this.arrIndex > -1) {this.curDrawLine = lineGeometrythis.curLineLayer = lineLayer}if (!this.mouseOperate.start) {this.mouseOperate.start = true}  }if (graphic.symbol?.type === 'picture-marker') {let lineLayer = this.groupLayer.findLayerById(graphic.layer.id)if (lineLayer) {this.groupLayer.remove(lineLayer)}}}} })})},// 绘制线createLine(vertices, layer) {if (layer) {layer.graphics.removeAll()} else {this.drawLineLayer.graphics.removeAll()}let polyline = {type: 'polyline', paths: [vertices],spatialReference: this.mapAndView.spatialReference}let graphic = new Graphic({geometry: polyline,symbol: {type: 'simple-line', color: '#FF8C00',width: 2,cap: 'round',join: 'round'}})if (layer) {layer.graphics.add(graphic)} else {this.drawLineLayer.graphics.add(graphic)}return polyline},// 添加圆点和距离文字createSymbol(lon, lat, text) {if (!this.textLayer) {this.textLayer = new GraphicsLayer({id: 'textLayer',graphics: [],spatialReference: this.mapAndView.spatialReference})this.mapAndView.map.add(this.textLayer)} let textSymbol = {type: 'text',  color: 'white',haloColor: 'black',haloSize: '1px',text: text || '起点',xoffset: 3,yoffset: -13,font: {  size: 12,// family: 'Josefin Slab',weight: 'bold'}}let markerSymbol = {type: 'simple-marker',  size: 7,color: 'rgba(255,255,255,1)',outline: {  width: 1,color: '#ff0000'}}let geometry = {type: 'point',longitude: lon,latitude: lat,spatialReference: this.mapAndView.spatialReference}const markerGraphic = new Graphic({geometry: geometry, symbol: markerSymbol })this.textLayer.graphics.add(markerGraphic)const textGraphic = new Graphic({geometry: geometry, symbol: textSymbol })this.textLayer.graphics.add(textGraphic)},// 添加线尾的删除图标createLastSymbol(lon, lat) {let markerSymbol = {type: 'picture-marker',  xoffset: 5,yoffset: 9,width: 10,height: 10,url: require('@/assets/images/system/layer/deleteLine.jpg')}let geometry = {type: 'point',longitude: lon,latitude: lat,spatialReference: this.mapAndView.spatialReference}const markerGraphic = new Graphic({geometry: geometry, symbol: markerSymbol })this.textLayer.graphics.add(markerGraphic)},//清除测距线clearDistanceLine() {if (this.draw) {this.groupLayer.removeAll()this.draw.reset()}}}
}

效果图:
在这里插入图片描述


http://www.ppmy.cn/ops/152222.html

相关文章

【MySQL】存储引擎有哪些?区别是什么?

频率难度60%⭐⭐⭐⭐ 这个问题其实难度并不是很大&#xff0c;只是涉及到的相关知识比较繁杂&#xff0c;比如事务、锁机制等等&#xff0c;都和存储引擎有关系。有时还会根据场景选择不同的存储引擎。 下面笔者将会根据几个部分尽可能地讲清楚 MySQL 中的存储引擎&#xff0…

豆瓣Top250电影的数据采集与可视化分析(scrapy+mysql+matplotlib)

文章目录 豆瓣Top250电影的数据采集与可视化分析(scrapy+mysql+matplotlib)写在前面数据采集(Visual Studio Code+Navicat)1.观察网页信息2.编写Scrapy代码(Visual Studio Code)2.1 创建Scrapy项目`doubanProject`2.2 创建爬虫脚本`douban.py`2.3 修改`douban.py`的代码2…

springboot基于微信小程序的停车场预订系统

Spring Boot 基于微信小程序的停车场预订系统 在城市交通日益拥堵&#xff0c;停车难问题愈发凸显的当下&#xff0c;Spring Boot 基于微信小程序的停车场预订系统为车主们提供了便捷高效的停车解决方案&#xff0c;让出行停车变得从容有序。借助 Spring Boot 强大的后端开发能…

玩转 LangChain:从文档加载到高效问答系统构建的全程实战

系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChain&#xf…

LDN的蓝牙双模键盘帮助文档

文档索引 已支持的PCB列表(仅列出少部分)&#xff1a;键盘特性硬件软件键盘以及驱动蓝牙模式USB模式 驱动功能介绍主界面键盘列表页面键盘配置&#xff08;使用双模键盘的请务必细看本说明&#xff09;功能层配置(改键)触发层配置(改FN键等触发功能)功能选择&#xff08;重要&a…

【C++学习篇】滑动窗口--结合例题讲解思路

目录 1. 例题&#xff1a;最小覆盖子串 1.1 解题思路 2. 方法一代码实现&#xff1a;用kinds来记录t中有效元素的种类&#xff0c;count来记录s中的有效元素种类 3. 方法二&#xff1a;count来记录s中有效元素的个数 ok&#xff0c;这是最后一期关于滑动窗口的学习章节了…

FFmpeg常用命令

文章目录 一、 FFmpeg 音视频的处理流程二、FFmpeg 常用命令2.1、查看本机支持的采集设备2.2、 录制视频2.2.1、原始视频2.2.2、编码的视频 2.3、录制音频&#xff1a;2.3.1、原始音频2.3.2、编码的音频 2.4、录制音视频&#xff1a;2.5、文件格式转换&#xff1a;2.6、提取音频…

京华春梦,守岁这方烟火人间

文章目录 准备篇温度公共交通人流情况年货采购 文化体验传统庙会博物馆与展览烟花灯会祈福仪式民俗集市现代氛围其他活动 美食盛宴传统美食与特色小吃传统老字号京城新宠特色小吃街多元美食街 准备篇 温度 北京春节期间气温较低&#xff0c;室外通常在零下几度到零上几度之间…