01、vue+openlayers6实现自定义测量功能(提供源码)

news2024/11/26 4:24:21

首先先封装一些openlayers的工具函数,如下所示:

import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import Style from 'ol/style/Style';
import Fill from 'ol/style/Fill';
import Stroke from 'ol/style/Stroke';
import Circle from 'ol/style/Circle';
import Polygon from 'ol/geom/Polygon';
import LineString from 'ol/geom/LineString';
import Point from 'ol/geom/Point';
import Feature from 'ol/Feature';
import Text from 'ol/style/Text';
import { getLength } from 'ol/sphere';
import { getArea } from 'ol/sphere';
import Draw from 'ol/interaction/Draw';
import { unByKey } from 'ol/Observable';

let draw;
let drawSource;//定义绘制图层
let drawLayer;//定义绘制图层
let sketch;
let output = 0;
let lastPolygonLabelFeature; //记录上一个面标注要素
let lastLengthLabelFeature; //记录上一个点标注要素

// 初始化测量绘制图层
export function initDrawLayer(map) {
    drawSource = new VectorSource({
        crossOrigin: "anonymous",
    });
    drawLayer = new VectorLayer({
        source: drawSource,
        style: new Style({
            fill: new Fill({
                color: "rgba(255, 255, 255, 0.2)",
            }),
            stroke: new Stroke({
                color: "#ffcc33",
                width: 2,
            }),
            image: new Circle({
                radius: 7,
                fill: new Fill({
                    color: "#ffcc33",
                }),
            }),
        }),
    });
    map.addLayer(drawLayer);
    map.on("pointermove", function (evt) {
        if (evt.dragging) {
            return;
        }
        let Coord;
        if (sketch) {
            let geom = sketch.getGeometry();
            if (geom instanceof Polygon) {
                if (lastPolygonLabelFeature) {
                    // console.log(lastPolygonLabelFeature);
                    //  鼠标移动,不停的添加和删除
                    drawSource.removeFeature(
                        lastPolygonLabelFeature
                    );
                }
                Coord = geom.getInteriorPoint().getCoordinates();
                //新建一个要素ol.Feature
                lastPolygonLabelFeature = new Feature({
                    geometry: new Point(Coord), //几何信息
                    name: output,
                });
                lastPolygonLabelFeature.setStyle(
                    createLabelStyle(lastPolygonLabelFeature, 0, 0)
                );
                drawSource.addFeature(lastPolygonLabelFeature);
            } else if (geom instanceof LineString) {
                if (lastLengthLabelFeature) {
                    drawSource.removeFeature(
                        lastLengthLabelFeature
                    );
                }
                Coord = geom.getLastCoordinate();
                // 新建一个要素ol.Feature
                lastLengthLabelFeature = new Feature({
                    geometry: new Point(Coord), //几何信息
                    name: output,
                });
                lastLengthLabelFeature.setStyle(
                    createLabelStyle(lastLengthLabelFeature, 35, -10)
                );
                // 设置要素样式
                drawSource.addFeature(lastLengthLabelFeature);
            }

        }
    });
    map.on("click", function (evt) {
        let coordinate = evt.coordinate; //鼠标单击点的坐标
        // //console.log(coordinate);
        if (output == "0") {
            lastPolygonLabelFeature = null;
            if (lastLengthLabelFeature) {
                drawSource.removeFeature(lastLengthLabelFeature);
                lastLengthLabelFeature = null;
            }
            return;
        }
        var Coord;
        if (sketch) {
            var geom = sketch.getGeometry();
            if (geom instanceof Polygon) {
                if (lastPolygonLabelFeature) {
                    drawSource.removeFeature(
                        lastPolygonLabelFeature
                    );
                }
                Coord = geom.getInteriorPoint().getCoordinates();
                //新建一个要素ol.Feature
                var newFeature = new Feature({
                    geometry: new Point(Coord), //几何信息
                    name: output,
                });
                lastPolygonLabelFeature = newFeature;
                newFeature.setStyle(
                    createLabelStyle(newFeature, 0, 0)
                ); //设置要素样式
                drawSource.addFeature(newFeature);
            } else if (geom instanceof LineString) {
                Coord = geom.getLastCoordinate();
                //新建一个要素ol.Feature
                let newFeature = new Feature({
                    geometry: new Point(Coord), //几何信息
                    name: output,
                });
                newFeature.setStyle(
                    createLabelStyle(newFeature, 35, -10)
                ); //设置要素样式
                drawSource.addFeature(newFeature);
            }
            let pointFeature = new Feature({
                geometry: new Point(coordinate), //几何信息
                name: output,
            });
            drawSource.addFeature(pointFeature);
        }
    });
}

// 定义测量结果的显示的样式
function createLabelStyle(feature, offsetX, offsetY) {
    return new Style({
        text: new Text({
            textAlign: "center", //位置
            textBaseline: "middle", //基准线
            font: "normal 10px sans-serif", //文字样式
            text: feature.get("name"), //文本内容
            fill: new Fill({
                //文本填充样式(即文字颜色)
                color: "white",
            }),
            stroke: new Stroke({
                color: "black",
                width: 5,
            }),
            offsetX: offsetX,
            offsetY: offsetY,
        }),
    });
}

function formatLength(line) {
    let length = getLength(line, {
        projection: "EPSG:3857",
        radius: 6378137,
    });
    let output;
    if (length > 100) {
        output = Math.round((length / 1000) * 100) / 100 + " " + "千米";
    } else {
        output = Math.round(length * 100) / 100 + " " + "米";
    }
    return output;
}

function formatArea(polygon) {
    var area = getArea(polygon, {
        projection: "EPSG:3857",
        radius: 6378137,
    });
    var output;
    if (area > 10000) {
        output =
            Math.round((area / 1000000) * 100) / 100 + " " + "平方公里";
    } else {
        output = Math.round(area * 100) / 100 + " " + "平方米";
    }
    return output;
}

function addInteraction(drawType, map) {
    let type = drawType == "area" ? "Polygon" : "LineString";
    draw = new Draw({
        source: drawSource,
        type: type,
        style: new Style({
            fill: new Fill({
                color: "rgba(255, 0, 0, 0.2)",
            }),
            stroke: new Stroke({
                color: "rgb(255,116,3)",
                width: 2,
            }),
            image: new Circle({
                radius: 5,
                stroke: new Stroke({
                    color: "rgba(255, 0, 0, 0.1)",
                }),
                fill: new Fill({
                    color: "rgba(255,116,3, 0.3)",
                }),
            }),
        }),
    });
    map.addInteraction(draw);
    var listener;
    draw.on(
        "drawstart",
        function (evt) {
            // set sketch
            sketch = evt.feature;
            listener = sketch
                .getGeometry()
                .on("change", function (evt) {
                    var geom = evt.target;
                    if (geom instanceof Polygon) {
                        output = formatArea(geom);
                    } else if (geom instanceof LineString) {
                        output = formatLength(geom);
                    }
                });
        }
    );
    draw.on(
        "drawend",
        function () {
            sketch = null;
            unByKey(listener);
            output = "0";
        }
    );
}

export function measureDistance(map) {
    if (draw) {
        map.removeInteraction(draw);
    }
    addInteraction("length", map);
}

export function measureArea(map) {
    if (draw) {
        map.removeInteraction(draw);
    }
    addInteraction("area", map);
}

export function measureClear(map) {
    map.removeInteraction(draw);
    drawLayer.setSource(null);
    drawSource = new VectorSource({
        crossOrigin: "anonymous",
    });
    drawLayer.setSource(drawSource);
    lastPolygonLabelFeature = null;
    lastLengthLabelFeature = null;
    sketch = null;
    output = "0";
}

export function interactionClear(map) {
    map.removeInteraction(draw);
}

然后再vue的组件中调用以上方法,代码如下:

在组件的monted中调用 initDrawLayer(map);方法

 //根据传入type值调用对应方法
         measure(type) {
            const that = this;
            
            if (type =="distance" ) {
                that.hideOverlay();
                measureDistance(window.map);
            }else  if (type =="area" ) {
                that.hideOverlay();
                measureArea(window.map);
            }else  if (type =="clear" ) {
                that.hideOverlay();
                measureClear(window.map);
            }
        }

最终实现效果如下:

源码地址连接:https://github.com/enjoyMaps/map_vue

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1660058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【SpringBoot整合系列】SpringBoot整合RabbitMQ-消息过期(死信队列和延迟队列)

目录 业务场景传统轮询消息队列完整版 默认情况TTL(消息的有效期)TTL 的设置有两种不同的方式单条消息过期队列消息过期特殊情况 死信队列概述应用场景产生原因原理图死信交换机死信队列实现一下 延迟队列背景定时任务?延迟队列实现思路代码 …

Spring @Repository 注解

Spring 的项目严重依赖注解。 Repository 注解 在Spring2.0之前的版本中,Repository注解可以标记在任何的类上,用来表明该类是用来执行与数据库相关的操作(即dao对象),并支持自动处理数据库操作产生的异常 在Spring2.5版本中,引…

校园网拨号上网环境下多开虚拟机,实现宿主机与虚拟机互通,并访问外部网络

校园网某些登录客户端只允许同一时间一台设备登录,因此必须使用NAT模式共享宿主机的真实IP,相当于访问外网时只使用宿主机IP,此方式通过虚拟网卡与物理网卡之间的数据转发实现访问外网及互通 经验证,将centos的物理地址与主机物理…

【概率论基础】 一篇文章缕清概率论常见概念关系

碎碎念:再写CSDN之前有一小段时间写数模公众号的经历,但是公众号看的人实在太少了,而且排版和公式、代码编辑都没有CSDN这么方便,所以坚持一算时间就没有更新了。公众号大多写的是概念性的基础,稍加修改搬到咱们的主战…

《二十二》Qt 音频编程实战---做一个音频播放器

1.UI界面制作 作为一个音乐播放器,最基础的肯定就是播放、暂停、上一首以及下一首,为了使这个界面好看一点,还加入了音量控制、进度条、歌曲列表等内容,至于这种配色和效果好不好看,我也不知道,个人审美一如…

C语言初阶(6) - 指针

目录 1.指针是什么? 2. 指针和指针类型 2.1 指针 - 整数 2.2 指针的解引用 3. 野指针 3.1 野指针成因 3.2 如何规避野指针 4. 常量指针和指针常量 (const) 4.1.常量指针 4.2.指针常量 5. 指针运算 5.1 指针-整数 5.2 指针-指针 5.3指针的关系运算 6.…

离线使用evaluate

一、目录 步骤demorouge-n 含义 二、实现 步骤 离线使用evaluate: 1. 下载evaluate 文件:https://github.com/huggingface/evaluate/tree/main2. 离线使用 路径/evaluate-main/metrics/rougedemo import evaluate离线使用evaluate: 1. 下载evaluate 文件&…

Android 百度语音识别(详细步骤+源码),京东android面试题

改好之后,请注意,每个人都是不一样,你如果发现你创建的应用的配置的值和我创建的是一模一样的,你马上去百度提BUG,他们的程序员要就要下岗了~ OK,现在配置也完成了,接下来就是使用了。 ③ 使用…

五一超级课堂---Llama3-Tutorial(Llama 3 超级课堂)---第四节Llama 3 高效部署实践(LMDeploy 版)

课程文档: https://github.com/SmartFlowAI/Llama3-Tutorial 课程视频: https://space.bilibili.com/3546636263360696/channel/collectiondetail?sid2892740&spm_id_from333.788.0.0 操作平台: https://studio.intern-ai.org.cn/consol…

浅谈现代消息队列与云存储

一、前言 1970 年代末,消息系统用于管理多主机的打印作业,这种削峰解耦的能力逐渐被标准化为“点对点模型”和稍复杂的“发布订阅模型”,实现了数据处理的分布式协同。随着时代的发展,Kafka,Amazon SQS,Ro…

charts3D地球--添加航线

要在地球视角下画出海运路线图 方案 添加 globl 地球创建geo地理坐标系创建canvas对象用于承载地图世界地图this.worldChart//初始化canvas节点let cav = document.createElement("canvas");this.$echarts.registerMap("world", geoJson);this.worldChart…

AVL树的原理及其实现

文章目录 前言了解AVL树AVL树的特点AVL树的节点调整方案右单旋为什么要右单旋呢?右单旋代码 左单旋为什么要左单旋?左单旋代码 左右双旋左右双旋之后平衡因子的情况左右双旋代码实现 右左双旋右左双旋代码: 简单测试 前言 回顾我们对于二叉搜…

保研面试408复习 4——操作系统、计网

文章目录 1、操作系统一、文件系统中文件是如何组织的?二、文件的整体概述三、UNIX外存空闲空间管理 2、计算机网络一、CSMA/CD 协议(数据链路层协议)二、以太网MAC帧MTU 标记文字记忆,加粗文字注意,普通文字理解。 1、…

值得推荐的10+REST API测试工具

什么是API? API是一个软件解决方案,作为中介,使两个应用程序能够相互交互。以下一些特征让API变得更加有用和有价值: 遵守REST和HTTP等易于访问、广泛理解和开发人员友好的标准。API不仅仅是几行代码;这些是为移动开…

qml 和 c++类的数据交互

1、 新建一个需要交互的C++类 1)添加QObject头文件 2)添加自QObject的继承 3)添加Q_OBJECT宏 4)使用Q_PROPERTY,定义两个交互的属性,并设置读写的方法和变更属性的信号。 5)添加方法、槽函数和变量 2、在main.cpp中添加实例化对象的QML上下文 1)添加需要QML交互的…

Kubernetes学习-集群搭建篇(一) 搭建Master结点

🏷️个人主页:牵着猫散步的鼠鼠 🏷️系列专栏:Kubernetes渐进式学习-专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 目录 1. 前言 2. 集群搭建方式 3. 环境说明 4. 利用kubeadm初始化Ma…

应该在哪里找海外ip代理?

出于学习工作,或者游戏娱乐的需求,许多人需要使用海外代理ip。那么我们该如何寻找到合适的、正规的、安全的海外代理ip呢? 首先,我们需要明白使用海外IP代理可能带来的风险,包括隐私泄露、网络速度变慢、安全风险以及可…

百融云创回购计划加速落实 机构看好中长期吸引力

单日回购近400万港元B类股份,一站式服务的AI科技领航者百融云创(百融云-W,6608.HK)的回购计划正在加速落实。 此前,在百融云创2023年年度业绩公告的同时,该公司一并披露将在2024年不时在公开市场购回总金额不超过2.5亿…

原生微信小程序canvas签名功能

半个月前百度搜出来的,没存书签现在不知道是哪篇文章了,再搜也没搜出来那篇文章,还好当时把代码复制到本地跑了一下,现在再发csdn存一下。 sign.js Page({data: {ctx: null,width: null,height: null,drawCount: 0,drawState: &…

WebStorm开发插件

WebStorm开发插件 开发 WebStorm 插件是一项令人兴奋的任务,它可以帮助提升开发效率,定制 IDE 来满足个人或团队的需求。在这份指南中,我将向你介绍如何开始开发 WebStorm 插件,并提供一些实用的技巧和建议。 1. 准备工作 在开…