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

首先先封装一些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.FeaturelastPolygonLabelFeature = 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.FeaturelastLengthLabelFeature = 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.Featurevar 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.Featurelet 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 sketchsketch = 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.hqwc.cn/news/687215.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】项目自动化构建工具make/makefile

🎉博主首页: 有趣的中国人 🎉专栏首页: Linux 🎉其它专栏: C初阶 | C进阶 | 初阶数据结构 小伙伴们大家好,本片文章将会讲解Linux中项目自动化构建工具make/makefile的相关内容。 如果看到最后…

单链表经典oj题(2)

前言 这次将要把剩下的oj题将以图解和自己的理解把它讲解完,希望对大家有所帮助,这次的讲解也是干货 第一题 21. 合并两个有序链表 - 力扣(LeetCode) ok这次就简单点,大家自己去看题目了 将两个升序链表合并为一个…

Ubuntu18.04--虚拟机配置Samba并从Windows登录

前言: 本文记录我自己在Windows上安装 Virtualbox ,并在Virtualbox中安装 Ubuntu-18.04 虚拟机,在Ubuntu-18.04虚拟机里安装配置Smaba服务器,从 Windows 宿主系统上访问虚拟机共享samba目录的配置命令。 引用: N/A 正文 虚拟…

​​​【收录 Hello 算法】5.1 栈

目录 5.1 栈 5.1.1 栈的常用操作 5.1.2 栈的实现 1. 基于链表的实现 2. 基于数组的实现 5.1.3 两种实现对比 5.1.4 栈的典型应用 5.1 栈 栈(stack)是一种遵循先入后出逻辑的线性数据结构。 我们可以将栈类比为桌面上的一摞盘子…

Linux diff命令(比较两个文件或目录的内容差异)

文章目录 Linux diff 命令详解教程基本用法比较文件输出解释 递归比较(-r)示例代码 控制输出格式统一格式(-u)上下文格式(-c) 高级选项忽略所有空白差异(-w)仅报告文件是否不同 Linu…

SVN 合并到 Git 时有文件大于 100 M 被限制 Push

如果有文件大小大于 100M,GitHub 是会被限制推送到仓库中的,大概率情况会显示下面的错误: remote: Resolving deltas: 100% (3601/3601), done. remote: error: Trace: aea1f450da6f2ef7bfce457c715d0fbb9b0f6d428fdca80233aff34b601ff59b re…

RobbitMQ基本消息队列的消息发送过程

RabbitMQ: One broker to queue them all | RabbitMQ RabbitMQ官网 SpringAmqp的官方地址:Spring AMQP 代码示例:对着代码看应该能看明白 publisher:消息发送者的代码示例 package cn.itcast.mq.helloworld;import com.rabbitmq.client.Channel; import com.rabb…

线路和绕组中的波过程(一)

本篇为本科课程《高电压工程基础》的笔记。 本篇为这一单元的第一篇笔记。下一篇传送门。 当电路中的设备(元件)最大实际尺寸l大于人们所感兴趣的谐波波长 λ \lambda λ时,可以作为集中参数处理,否则就要当做分布参数处理。即&…

基于STM32移植lvgl(V8.2)(SPI接口的LCD)

目录 概述 1 认识LVGL 1.1 LVGL官网 1.2 LVGL库文件下载 2 认识SPI接口型LCD 2.1 PIN引脚定义 2.2 MCU IO与LCD PIN对应关系 3 实现LCD驱动 3.1 使用STM32Cube配置Project 3.2 STM32Cube生成工程 4 移植LVGL 4.1 准备移植文件 4.2 添加lvgl库文件到项目 4.2.1 src下…

linux fdisk 银河麒麟操作系统 v10 磁盘分区和挂载 详细教程

1查看 未加载的磁盘 fdisk -l 2 开始分区 fdisk /dev/vdb #查看分区 #新建分区和保存 3 格式化和挂载 fdisk -l mkfs.xfs /dev/vdb1 #查看uuid blkid /dev/vdb1 mkdir /data vi /etc/fstab UUID209daa-fb1c-48f2-bf5e-e63f38cb8a /data xfs defaults 0 0 #加载下 mo…

探秘未来科技:数字化无人巡检的奇妙之旅

嘿,朋友们!下午茶时间到!趁着这会儿咱们来聊一个超级炫酷的话题——数字化无人巡检。想象一下,那些曾经需要人工跋山涉水、风吹日晒的巡检工作,现在正被一群“智能小分队”悄悄接手,是不是觉得既神奇又方便…

Ascent DMS AE电源说明书和设备连接调试教程

Ascent DMS AE电源说明书和设备连接调试教程