uniapp 整合 OpenLayers - 测距测面

news2024/11/14 1:58:35

代码如下(测距、测面和清除)

import Draw from 'ol/interaction/Draw'
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import Point from "ol/geom/Point";
import {
  unByKey
} from 'ol/Observable.js';
import Overlay from 'ol/Overlay';
import {Feature } from "ol";
import {getLength} from 'ol/sphere';
import {getArea} from 'ol/sphere';
import LineString from 'ol/geom/LineString';
import Polygon from 'ol/geom/Polygon';
import {
  Circle as CircleStyle,
  Fill,
  Stroke,
  Style
} from 'ol/style.js';
 
// 测距所需对象
var lineVectorLayer = null;
var lineDraw = null;

// 测面所需对象
var areaVectorLayer = null;
var areaDraw = null;


// 测距
export const measureLineMethod = (map) => {
  clearMeasures(map);//清空测量图层
  // 创建数据源
  var source = new VectorSource();
 
  lineVectorLayer = new VectorLayer({
    id:'Line',
    source: source,
    style: new Style({
      fill: new Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      }),
      stroke: new Stroke({
        color: 'red',
        width: 2
      }),
      image: new CircleStyle({
        radius: 7,
        fill: new Fill({
          color: '#ffcc33'
        })
      })
    }),
    zIndex:16
  });
  
  map.addLayer(lineVectorLayer)
  
  /**
   * Currently drawn feature.
   * @type {module:ol/Feature~Feature}
   */
  var sketch;
 
 
  /** 测距
   * The help tooltip element.
   * @type {Element}
   */
  var lineHelpTooltipElement;
 
 
  /**
   * Overlay to show the help messages.
   * @type {module:ol/Overlay}
   */
  var lineHelpTooltip;
 
 
  /**
   * The measure tooltip element.
   * @type {Element}
   */
  var measureTooltipElement;
 
 
  /**
   * Overlay to show the measurement.
   * @type {module:ol/Overlay}
   */
  var measureTooltip;
 
 
 
  /**
   * Message to show when the user is drawing a line.
   * @type {string}
   */
  var continueLineMsg = '';
 
  createMeasureTooltip();
  createHelpTooltip();
 
  /**
   * Handle pointer move.
   * @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt The event.
   */
  var pointerMoveHandler = function (evt) {
    if (evt.dragging) {
      return;
    }
    /** @type {string} */
    var helpMsg = '请点击开始测距';
 
    if (sketch) {
      // 测量时的提示文字
      var geom = (sketch.getGeometry());
      if (geom instanceof LineString) {
        helpMsg = continueLineMsg;
      }
       
    }
 
    // 设置提示对话框
    //lineHelpTooltipElement.innerHTML = helpMsg;// 文字没有颜色
    lineHelpTooltipElement.innerHTML = "<span style='color: red;'>"+helpMsg+"</span>";
    lineHelpTooltip.setPosition(evt.coordinate);
 
    lineHelpTooltipElement.classList.remove('hidden');
  };
  // 监听鼠标移动方法
  map.on('pointermove', pointerMoveHandler);
 
  map.getViewport().addEventListener('mouseout', function () {
    lineHelpTooltipElement.classList.add('hidden');
  });
 
  var draw;// 绘制对象
 
  var formatLength = function (line) {
      //获取投影坐标系
      var sourceProj = map.getView().getProjection();
      //ol/sphere里有getLength()和getArea()用来测量距离和区域面积,默认的投影坐标系是EPSG:3857, 其中有个options的参数,可以设置投影坐标系
      var length = getLength(line, {projection: sourceProj});
      //var length = getLength(line);
      var output;
      if (length > 100) {
        output = (Math.round(length / 1000 * 100) / 100) +
          ' ' + 'km';
      } else {
        output = (Math.round(length * 100) / 100) +
          ' ' + 'm';
      }
      return output;
    };
 
 
  // 获取存放feature的vectorlayer层。map初始化的时候可以添加好了
  for(let layerTmp of map.getLayers().getArray()){
    if(layerTmp.get("name")=="feature"){
      source = layerTmp.getSource();
    }
  }
 
   // 测量距离
  function addLineInteraction() {
    var type = "LineString";
    draw = new Draw({
      source: source,
      type: type,
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: 'rgba(0, 200, 255, 0.5)',
          lineDash: [10, 10],
          width: 2
        }),
        image: new CircleStyle({
          radius: 5,
          stroke: new Stroke({
            color: 'rgba(0, 200, 255, 0.7)'
          }),
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          })
        })
      })
    });
  // 赋值
  lineDraw = draw;
  map.addInteraction(lineDraw);
    
    var listener;
    draw.on('drawstart',
      function (evt) {
        // set sketch
        sketch = evt.feature;
 
        /** @type {module:ol/coordinate~Coordinate|undefined} */
        var tooltipCoord = evt.coordinate;
 
        listener = sketch.getGeometry().on('change', function (evt) {
          var geom = evt.target;
          var output;
          if (geom instanceof LineString) {
            output = formatLength(geom);
            tooltipCoord = geom.getLastCoordinate();
          }
          //measureTooltipElement.innerHTML = output;// 文字没有颜色
          measureTooltipElement.innerHTML = "<span style='color: red;'>"+output+"</span>";
          measureTooltip.setPosition(tooltipCoord);
        });
 
       /* //地图双击事件-点位不准确
        map.on('dblclick', function (evt) {
			// 添加点
            var point = new Point(evt.coordinate);
            source.addFeature(new Feature(point));
        }); */
 
      }, this);
 
 
    draw.on('drawend',
      function (evt) {
        //measureTooltipElement.className = 'tooltip tooltip-static';
        measureTooltip.setOffset([0, -7]);
        // unset sketch
        sketch = null;
        // unset tooltip so that a new one can be created
        measureTooltipElement = null;
        createMeasureTooltip();
        unByKey(listener);
        map.un('pointermove', pointerMoveHandler);
        map.removeInteraction(draw);
        lineHelpTooltipElement.classList.add('hidden');
		
		// 下面代码在绘制结束后添加点(线的最后一个坐标点)
		// 获取properties
		//var properties = evt.feature.getProperties();
		//console.log("properties",JSON.stringify(properties));
		// 获取geometry
		var geometry = evt.feature.getGeometry();
		// 获取坐标点集合
		var corrdinates = geometry.getCoordinates();
		//console.log("corrdinates",corrdinates);
		// 创建线
		var lineString = new LineString(corrdinates);
		// 获取线段最后的点坐标
		//console.log("lineString.getLastCoordinate()",lineString.getLastCoordinate());
		var point = new Point(lineString.getLastCoordinate());
		source.addFeature(new Feature(point));
      }, this);
  }
 
  function createHelpTooltip() {
    if (lineHelpTooltipElement) {
      lineHelpTooltipElement.parentNode.removeChild(lineHelpTooltipElement);
    }
    lineHelpTooltipElement = document.createElement('div');
    //lineHelpTooltipElement.className = 'tooltip hidden';
    lineHelpTooltip = new Overlay({
      element:lineHelpTooltipElement,
      offset: [15, 0],
      positioning: 'center-left',
    });
    map.addOverlay(lineHelpTooltip);
  }
 
  function createMeasureTooltip() {
    if (measureTooltipElement) {
      measureTooltipElement.parentNode.removeChild(measureTooltipElement);
    }
    measureTooltipElement = document.createElement('div');
    //measureTooltipElement.className = 'tooltip tooltip-measure';
    measureTooltip = new Overlay({
      element: measureTooltipElement,
      offset: [0, -15],
      positioning: 'bottom-center'
    });
    map.addOverlay(measureTooltip);
  }
 
  // 量测调用
  addLineInteraction();
}

// 测面
export const measurePolygonMethod = (map) =>{
  clearMeasures(map);//清空测量图层
  // 创建数据源
  var source = new VectorSource();
 
  areaVectorLayer = new VectorLayer({
    id:'Area',
    source: source,
    style: new Style({
      fill: new Fill({
        color: 'rgba(255, 255, 255, 0.2)'
      }),
      stroke: new Stroke({
        color: 'red',
        width: 2
      }),
      image: new CircleStyle({
        radius: 7,
        fill: new Fill({
          color: '#ffcc33'
        })
      })
    }),
    zIndex:16
  });
 
  map.addLayer(areaVectorLayer);
 
  /**
   * Currently drawn feature.
   * @type {module:ol/Feature~Feature}
   */
  var sketch;
 
 
  /**
   * The help tooltip element.
   * @type {Element}
   */
  var areaHelpTooltipElement;
 
 
  /**
   * Overlay to show the help messages.
   * @type {module:ol/Overlay}
   */
  var areaHelpTooltip;
 
 
  /**
   * The measure tooltip element.
   * @type {Element}
   */
  var measureTooltipElement;
 
 
  /**
   * Overlay to show the measurement.
   * @type {module:ol/Overlay}
   */
  var measureTooltip;
 
 
  /**
   * Message to show when the user is drawing a polygon.
   * @type {string}
   */
  var continuePolygonMsg = '';
 
 
  createMeasureTooltip();
  createHelpTooltip();
 
  /**
   * Handle pointer move.
   * @param {module:ol/MapBrowserEvent~MapBrowserEvent} evt The event.
   */
  var pointerMoveHandler = function (evt) {
    if (evt.dragging) {
      return;
    }
    /** @type {string} */
    var helpMsg = '请点击开始测面';
 
    if (sketch) {
      var geom = (sketch.getGeometry());
      if (geom instanceof Polygon) {
        helpMsg = continuePolygonMsg;
      }
    }
 
    //areaHelpTooltipElement.innerHTML = helpMsg;//没有颜色
    areaHelpTooltipElement.innerHTML = "<span style='color: red;'>"+helpMsg+"</span>";
    areaHelpTooltip.setPosition(evt.coordinate);
 
    areaHelpTooltipElement.classList.remove('hidden');
  };
  // 监听鼠标移动方法
  map.on('pointermove', pointerMoveHandler);
 
  map.getViewport().addEventListener('mouseout', function () {
    areaHelpTooltipElement.classList.add('hidden');
  });
 
  var draw;
 
 
var formatArea = function (polygon) {
  //获取投影坐标系
  var sourceProj = map.getView().getProjection();
  var area = getArea(polygon, {projection: sourceProj})
  //var area = getArea(polygon);
  //console.info(area)
  var output;
  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>';
  }
  return output;
};
 
  // 获取存放feature的vectorlayer层。map初始化的时候可以添加好了
  for(let layerTmp of map.getLayers().getArray()){
    if(layerTmp.get("name")=="feature"){
      // layer = layerTmp;
      // layerTmp.setSource(null)
      source = layerTmp.getSource();
    }
  }
 
  // 测量面
  function addAreaInteraction() {
    
    var type = "Polygon";
    draw = new Draw({
      source: source,
      type: type,
      style: new Style({
        fill: new Fill({
          color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new Stroke({
          color: 'rgba(0, 200, 255, 0.5)',
          lineDash: [10, 10],
          width: 2
        }),
        image: new CircleStyle({
          radius: 5,
          stroke: new Stroke({
            color: 'rgba(0, 200, 255, 0.7)'
          }),
          fill: new Fill({
            color: 'rgba(255, 255, 255, 0.2)'
          })
        })
      })
    });
    //赋值
    areaDraw = draw;
    map.addInteraction(areaDraw);
 
    var listener;
    draw.on('drawstart',
      function (evt) {
        // set sketch
        sketch = evt.feature;
 
        /** @type {module:ol/coordinate~Coordinate|undefined} */
        var tooltipCoord = evt.coordinate;
 
        listener = sketch.getGeometry().on('change', function (evt) {
          var geom = evt.target;
          var output;
          if (geom instanceof Polygon) {
            output = formatArea(geom);
            tooltipCoord = geom.getInteriorPoint().getCoordinates();
          } 
          //measureTooltipElement.innerHTML = output;// 没有颜色
          measureTooltipElement.innerHTML = "<span style='color: red;'>"+output+"</span>";
          measureTooltip.setPosition(tooltipCoord);
        });
 
        //地图双击事件-绘制结束时有个小黄点
       /* map.on('dblclick', function (evt) {
            var point = new Point(evt.coordinate);
            source.addFeature(new Feature(point));
        });*/
 
 
 
      }, this);
 
 
    draw.on('drawend',
      function (evt) {
        //measureTooltipElement.className = 'tooltip tooltip-static';
        measureTooltip.setOffset([0, -7]);
        // unset sketch
        sketch = null;
        // unset tooltip so that a new one can be created
        measureTooltipElement = null;
        createMeasureTooltip();
        unByKey(listener);
        map.un('pointermove', pointerMoveHandler);
        map.removeInteraction(draw);
        areaHelpTooltipElement.classList.add('hidden');

      }, this);
  }
 
 
 
  function createHelpTooltip() {
    if (areaHelpTooltipElement) {
      areaHelpTooltipElement.parentNode.removeChild(areaHelpTooltipElement);
    }
    areaHelpTooltipElement = document.createElement('div');
    //areaHelpTooltipElement.className = 'tooltip hidden';
    areaHelpTooltip = new Overlay({
      element: areaHelpTooltipElement,
      offset: [15, 0],
      positioning: 'center-left'
    });
    map.addOverlay(areaHelpTooltip);
  }
 
  function createMeasureTooltip() {
    if (measureTooltipElement) {
      measureTooltipElement.parentNode.removeChild(measureTooltipElement);
    }
    measureTooltipElement = document.createElement('div');
    //measureTooltipElement.className = 'tooltip tooltip-measure';
    measureTooltip = new Overlay({
      element: measureTooltipElement,
      offset: [0, -15],
      positioning: 'bottom-center'
    });
    map.addOverlay(measureTooltip);
  }
  // 量测调用
  addAreaInteraction();
  
}

// 清空测量图层
export const clearMeasures = (map) =>{
  
  // 清除测量距离
  if(lineVectorLayer != null){
    lineVectorLayer.getSource().clear();// 清除数据源
    map.removeLayer(lineVectorLayer);// 清除图层
    if(lineDraw != null){
		// 禁止绘制
    	lineDraw.setActive(false);
    	// 结束测距绘制
    	map.removeInteraction(lineDraw);
    	lineDraw = null;
    }
  }
 
  // 清除测面
  if(areaVectorLayer != null){
    areaVectorLayer.getSource().clear();// 清除数据源
    map.removeLayer(areaVectorLayer);// 清除图层
	if(areaDraw != null){
		// 禁止绘制
		areaDraw.setActive(false);
		// 结束测面绘制
		map.removeInteraction(areaDraw);
		areaDraw = null;
	}
  }
  // 清除overlays层
  map.getOverlays().clear();
}

使用方法:

<!-- 逻辑层 -->
<script>
***
***
export default {
	    data () {
            return {
    
            }
        },
        methods:{
        
        }
}

</scripc>
<!-- renderjs层 -->
<script module="ol" lang="renderjs" type="module">
***
***
// 测距测面工具js
import {measureLineMethod,measurePolygonMethod,clearMeasures} from '../../utils/measure/measure.js'
export default {
	    data () {
            return {
    
            }
        },
        methods:{
            method(){
                //measureLineMethod(this.map);
				measurePolygonMethod(this.map)
                //clearMeasures(this.map);
            }
        }
}

</scripc>

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

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

相关文章

【人工智能训练师】3 集群搭建

开启集群环境 本次环境为单节点伪集群环境&#xff0c;环境中已经安装JDK1.8、Hadoop2.7.7、Mysql5.7、hive2.3.4。— 1.环境中已经安装/root/software/hadoop-2.7.7&#xff0c;格式化HDFS&#xff0c;开启集群&#xff0c;查看集群状态。&#xff08;HDFS端口为9000&#x…

使用 GPT-4V 全面评估泛化情绪识别 (GER)

概述 由于情绪在人机交互中扮演着重要角色&#xff0c;因此情绪识别备受研究人员关注。目前的情感识别研究主要集中在两个方面&#xff1a;一是识别刺激物引起的情感&#xff0c;并预测观众观看这些刺激物后的感受。另一个方面是分析图像和视频中的人类情绪。在本文中&#xf…

8.机器学习--决策树

(⊙﹏⊙)下周有要开组会&#xff0c;不知道该说啥&#xff0c;啊啊啊啊&#x1f62b; 目录 1.基本概念 2.ID3算法 3.C4.5算法 4.CART算法 5.连续与缺失值处理 5.1.连续值处理 5.2.缺失值处理 6.剪枝处理 6.1.预剪枝策略 6.2.后剪枝策略 7.实例代码 1.基本概念 提…

uniApp之uni-file-picker使用踩坑

标题党~也不算坑吧 就是初体验 上传是需要存储一下子的&#xff0c;我以为uniApp是自己免费开的服务给大家中转使用&#xff0c;就没管这个事&#xff0c;但是官网是这么说的&#xff1a; 就我是怎么发现的&#xff0c;使用了一段时间后&#xff0c;上传的图片都裂了&#xff…

22.04Ubuntu---ROS2使用rclcpp编写节点C++

节点需要存在于功能包当中&#xff0c;功能包需要存在于工作空间当中。 所以我们要想创建节点&#xff0c;就要先创建一个工作空间&#xff0c;再创建功能包。 第一步&#xff1a;创建工作空间 mkdir -p chapt2_ws/src/ 第二步&#xff1a;创建example_cpp功能包&#xff0c…

UIStackView使用进阶

01 技术背景 前端的布局方式比较灵活&#xff0c;提供有Flex的布局方式&#xff0c;可以实现不同方向的弹性布局。Flex就像一个容器&#xff0c;可以将其内部的子控件统一进行布局。其包含主轴方向和交叉轴方向&#xff0c;主轴方向表示控件的排布方向&#xff0c;交叉轴方向和…

AMD-OLMo:在 AMD Instinct MI250 GPU 上训练的新一代大型语言模型。

AMD-OLMo是一系列10亿参数语言模型&#xff0c;由AMD公司在AMD Instinct MI250 GPU上进行训练&#xff0c;AMD Instinct MI250 GPU是一个功能强大的图形处理器集群&#xff0c;它利用了OLMo这一公司开发的尖端语言模型。AMD 创建 OLMo 是为了突出其 Instinct GPU 在运行 “具有…

【HarmonyOS】Install Failed: error: failed to install bundle.code:9568289

【HarmonyOS】Install Failed: error: failed to install bundle.code:9568289 一、问题背景&#xff1a; Install Failed: error: failed to install bundle. code:9568289 error: install failed due to grant request permissions failed. View detailed instructions. 11/…

#渗透测试#SRC漏洞挖掘#CSRF漏洞的防御

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…

C++builder中的人工智能(7)如何在C++中开发特别的AI激活函数?

在当今的AI开发中&#xff0c;人工智能模型正迅速增加。这些模型使用数学函数来执行和学习&#xff0c;以便在传播时优化最佳结果&#xff0c;或在反向传播时选择最佳解决方案。其中之一就是激活函数。也称为转移函数或阈值函数&#xff0c;它决定了神经元的激活值作为输出&…

ReactPress数据库表结构设计全面分析

ReactPress Github项目地址&#xff1a;https://github.com/fecommunity/reactpress 欢迎Star。 ReactPress是一个基于React框架开发的开源发布平台和内容管理系统&#xff08;CMS&#xff09;。它不仅支持用户在支持React和MySQL数据库的服务器上搭建自己的博客和网站&#…

小菜家教平台(四):基于SpringBoot+Vue打造一站式学习管理系统

前言 昨天配置完了过滤器&#xff0c;权限检验&#xff0c;基本的SpringSecurity功能已经配置的差不多了&#xff0c;今天继续开发&#xff0c;明天可能会暂停一天整理一下需求&#xff0c;然后就进行CRUD了。 今日进度 补充SpringSecurity异常处理和全局异常处理器 详细操作…

零基础Java第十五期:抽象类接口(一)

目录 一、抽象类 1.1. 抽象的概念 1.2. 抽象类语法 1.3. 抽象类的特性 1.4. 图形类例子 二、 接口 2.1. 接口的概念 2.2. 语法规则 2.3. 接口的特性 2.4. 接口的使用 2.5. 实现多个接口 2.6. 工作当中常用的接口 一、抽象类 1.1. 抽象的概念 如果 一个类中没…

13.UE5流星火雨,引导施法技能制作

2-15 流星火雨&#xff0c;引导施法技能制作、随机数_哔哩哔哩_bilibili 目录 1.为流星火雨添加按键映射 2.创建流星火雨的动画蒙太奇 3.实现播放动画蒙太奇的逻辑 ​编辑 4.定义发射一波流星火雨的发射物 5.使用动画通知释放流星火雨 1.为流星火雨添加按键映射 创建名为流…

让redis一直开启服务/自动启动

文章目录 你的redis是怎么打开的黑窗不能关?必须要自动启动吗?再说说mysql 本文的所有指令都建议在管理员权限下打开cmd控制台 推荐的以管理员身份打开控制台的方式 Win R 打开运行 输入cmdShift Ctrl Enter 你的redis是怎么打开的 安装过redis的朋友都知道, redis的安…

【安装配置教程】二、VMware安装并配置ubuntu22.04

一、准备&#xff1a; 虚拟机安装ubuntu&#xff0c;首先要先找到一个镜像&#xff0c;可以去ubuntu官方下载一个&#xff0c;地址&#xff1a;下载Ubuntu桌面系统 | Ubuntu&#xff0c;下载好iso的镜像文件后保存好&#xff0c;接下来打开VMware。 二、安装&#xff…

Latex中给公式加边框

1、这里使用的不是 amsmath 的 \boxed 命令, 而是 empheq 的 empheq 环境以及 xcolor 的 \fcolorbox 命令, 下面是代码, 可以分别阅读这两个手册来获取更多的信息 \documentclass{article} \usepackage{xcolor} \usepackage{empheq} \usepackage{amsmath} \begin{document}\be…

Android Parcelable和Serializable的区别与联系

在Android开发中&#xff0c;Parcelable和Serializable是两种用来在组件之间传递数据的序列化机制。它们有不同的使用场景和性能特点。 以下是它们之间的关系和区别&#xff1a; 1. 什么是 Parcelable Parcelable 是 Android 特有的接口&#xff0c;用于高效地在进程间传递数…

Android 实现柱形图

在 Android 中实现柱状图&#xff0c;可以使用流行的图表库 MPAndroidChart&#xff0c;它支持多种类型的图表&#xff0c;包括柱状图、折线图、饼图等。下面是一个基本的柱状图实现步骤&#xff0c;具体分为以下几个部分&#xff1a; 1. 添加依赖 首先&#xff0c;你需要在 …

通过交互式网页学习相机成像原理

​ 入门摄影这门艺术&#xff0c;你是否有以下这些问题&#xff1f; 焦距、光圈、CMOS是什么&#xff1f;为什么光圈越大&#xff0c;背景虚化效果越好&#xff1f;什么是过曝&#xff1f;… 今天我将分享一个简单的、可交互的相机成像模型&#xff0c;可供大家以可视化的方式…