当前位置: 首页 > article >正文

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

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 += 1
            this.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 added
            action.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 moves
            action.on('cursor-update', evt => {
                this.createLine(evt.vertices)
            })

            // fires when the drawing is completed
            action.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 removed
            action.on('vertex-remove', evt => {
                this.createLine(evt.vertices)
            })

            this.mapAndView.on('pointer-move', event => {
                let graphic = null
                this.mapAndView.hitTest(event).then(res => {
                    this.mapAndView.cursor = 'default'
                    if (res.results.length) {
                        graphic = res.results[0].graphic
                        if (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].graphic
                        this.arrIndex = -1
                        this.curDrawLine = null
                        this.curLineLayer = null
                        if (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 = lineGeometry
                                    this.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.kler.cn/a/513105.html

相关文章:

  • 图的基本概念
  • 前端 window.print() 打印图片
  • 二叉树--堆排序
  • 二十七、资源限制-LimitRange
  • SDL2:arm64下编译使用 -- SDL2多媒体库使用音频实例
  • 阿里云 Serverless 助力盟主直播:高并发下的稳定性和成本优化
  • SQLmap 自动注入 -02
  • 【服务器报错】libGL.so.1: cannot open shared object file:
  • 记录一次排查服务器硬盘资源不足的过程
  • OFD 套版生成原理与 C# 实现详解
  • PyQt 异步任务 多线程的几种方案
  • linux-NFS网络共享存储服务配置
  • 深度学习进展
  • 档案事业与数据要素之间有什么关系?
  • vue3组件传值具体使用
  • AI软件栈:中间表示
  • MySQL 8.4及以上版本压缩包安装 windows
  • Java中的几个元老 Object Class 和 @Retention
  • 使用 Helm 部署 RabbitMQ 高可用集群(HA)
  • 1.2.神经网络基础
  • @LoadBalanced注解的实现原理
  • 打游戏时总是“红网”怎么回事,如何解决
  • C# 网络协议第三方库Protobuf的使用
  • 【EdgeAI实战】(1)STM32 边缘 AI 生态系统
  • 软件工程的原则
  • SpringBoot笔记(1)