supermap+openlayers距离和面积测算

该博客介绍了如何在超图项目中添加距离和面积测算功能。通过使用OpenLayers库,实现了在用户鼠标落下时显示提示,并在绘制完成后动态显示测算结果。在测绘过程中,利用overlay和动态DOM元素更新测量信息,包括长度以公里和米为单位,面积以平方公里和平方米为单位。同时,博客详细展示了测量工具的创建、测绘结果的显示以及清理历史绘制的过程。

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

距离测算,面积测算

最近超图项目要加一个测算功能,距离测算和面积测算,要求在用户鼠标落下之后给出提示,画完之后需要在区域内显示测算结果。最后决定使用overlay+动态添加dom的方式实现。

工具方法

utils.js

import Overlay from 'ol/Overlay'
// 这里是提示文字
export const helpTool = (map, sketch) => {
    let helpTooltipElement;
    // 清除历史提示图层
    map.removeOverlay(map.getOverlayById('measurehelp'))
    if (helpTooltipElement) {
        helpTooltipElement.parentNode.removeChild(helpTooltipElement)
    }
    // 创建dom
    helpTooltipElement = document.createElement('div')
    helpTooltipElement.className = 'tooltip hidden'
    helpTooltipElement.style.color = '#389bcb';
    // 实例overlay
    const helpTooltip = new Overlay({
        id: 'measurehelp',
        element: helpTooltipElement,
        offset: [15, 0],
        positioning: 'center-left',
    })
    map.addOverlay(helpTooltip)

    // 笔触监听
    let pointerMoveHandler = function (evt) {
        if (evt.dragging) {
            return
        }
        let helpMsg = '请点击开始绘制'

        if (sketch) {
            const geom = (sketch.getGeometry())
            if (geom instanceof Polygon || geom instanceof LineString) {
                helpMsg = ''
            }
        }

        helpTooltipElement.innerHTML = helpMsg
        helpTooltip.setPosition(evt.coordinate)
        helpTooltipElement.classList.remove('hidden')
    }
    map.on('pointermove', pointerMoveHandler)
    // 笔触移出地图后隐藏
    map.getViewport().addEventListener('mouseout', () => {
        helpTooltipElement.classList.add('hidden')
    })
    return { pointerMoveHandler, helpTooltipElement };
}

// 测量结果显示
export const measureTool = (map) => {
    let measureTooltipElement;
    // 清除历史渲染
    map.removeOverlay(map.getOverlayById('measure'))
    if (measureTooltipElement) {
        measureTooltipElement.parentNode.removeChild(measureTooltipElement)
    }
    // 创建dom
    measureTooltipElement = document.createElement('div')
    measureTooltipElement.className = 'tooltip tooltip-measure'
    // 实例overlay
    let measureTooltip = new Overlay({
        id: 'measure',
        element: measureTooltipElement,
        offset: [0, -15],
        positioning: 'bottom-center',
    })
    map.addOverlay(measureTooltip);
    return { measureTooltip, measureTooltipElement };
}

在页面中引入工具方法

import { getArea, getLength } from 'ol/sphere'
import { unByKey } from 'ol/Observable.js'
import { LineString, Polygon } from 'ol/geom.js'
import { helpTool, measureTool } from '../util.js'
export default {
    data() {
        return {
            // 监听绘制元素变化
            listener: null,
            // 绘制元素
            sketch: null,
            // 笔触移动监听
            pointerMoveHandler: null,
            // 测绘结果提示
            measureTooltip: null,
            // 测绘结果提示的dom
            measureTooltipElement: null,
            // 提示dom
            helpTooltipElement: null
        }
    },
    methods: {
        // 测量
        measure(type) {
            // 初始化画板
            this.initDraw({
                type,
            });
            // 测绘时的提示文字 和 测绘结果的提示文字
            let help = helpTool(this.map),
                measure = measureTool(this.map);
            // 提示元素
            this.helpTooltipElement = help.helpTooltipElement;
            // 笔触移动监听
            this.pointerMoveHandler = help.pointerMoveHandler;
            // 测绘结果提示
            this.measureTooltip = measure.measureTooltip;
            // 测绘结果元素
            this.measureTooltipElement = measure.measureTooltipElement;
            // 测绘开始监听
            this.draw.on('drawstart', (evt) => {
                // 清除历史绘制
                this.map.getLayers().getArray().forEach((layer) => {
                    if (layer.get('layerName') === 'drawLayer') {
                        layer.getSource().clear()
                    }
                })
                // 绘制元素
                this.sketch = evt.feature
                let tooltipCoord = evt.coordinate
                // 监听绘制元素的变化
                this.listener = this.sketch.getGeometry().on('change', (e) => {
                    const geom = e.target
                    let output
                    // 长度测量
                    if (geom instanceof LineString) {
                        const length = getLength(geom, {
                            projection: 'EPSG:' + this.EPSG
                        })
                        if (length > 100) {
                            output = `${(Math.round(length / 1000 * 100) / 100)}  km`
                        } else {
                            output = `${(Math.round(length * 100) / 100)}  m`
                        }
                        tooltipCoord = geom.getLastCoordinate()
                    } else if (geom instanceof Polygon) {
                        // 面积测量
                        const area = getArea(geom, {
                            projection: 'EPSG:' + this.EPSG
                        })
                        if (area > 10000) {
                            output = `${(Math.round(area / 1000000 * 100) / 100)}  km<sup>2</sup>`
                        } else {
                            output = `${(Math.round(area * 100) / 100)}  m<sup>2</sup>`
                        }
                        tooltipCoord = geom.getInteriorPoint().getCoordinates()
                    }
                    // 测绘结果显示
                    this.measureTooltipElement.innerHTML = output
                    this.measureTooltipElement.className = 'tooltip tooltip-static'
                    this.measureTooltip.setPosition(tooltipCoord)
                })
            })
            // 绘制结束
            this.draw.on('drawend', () => {
                this.measureTooltipElement.className = 'tooltip tooltip-static'
                this.measureTooltip.setOffset([0, -7])
                this.sketch = null
                this.helpTooltipElement.classList.add('hidden')
            })
        },
        // 释放
        unmeasure() {
            // 清除绘制
            this.map.getLayers().getArray().forEach((layer) => {
                if (layer.get('layerName') === 'drawLayer') {
                    layer.getSource().clear()
                }
            })

            // 清除提示
            this.map.removeOverlay(this.map.getOverlayById('measure'))
            // 清除监听
            if (this.pointerMoveHandler) this.map.un('pointermove', this.pointerMoveHandler)
            if (this.listener) unByKey(this.listener)

            // 清除画板
            this.removeDraw();
            this.map.removeInteraction(this.draw);
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值