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

时间:2025-01-22 07:31:56
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