uniapp 整合 OpenLayers - 测距测面

news/2024/11/8 16:48:18 标签: uni-app

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

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) => {
  clearMeasure(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 () {
        //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');
      }, 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) =>{
  clearMeasure(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 () {
        //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 clearMeasure = (map) =>{
  
  // 清除测量距离
  if(lineVectorLayer != null){
    lineVectorLayer.getSource().clear();// 清除数据源
    map.removeLayer(lineVectorLayer);// 清除图层
    // 结束测距绘制
    map.removeInteraction(lineDraw);
    lineDraw = null;
  }
 
  // 清除测面
  if(areaVectorLayer != null){
    areaVectorLayer.getSource().clear();// 清除数据源
    map.removeLayer(areaVectorLayer);// 清除图层
     // 结束测面绘制
    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,clearMeasure} from '../../utils/measure/measure.js'
export default {
	    data () {
            return {
    
            }
        },
        methods:{
            method(){
                //measureLineMethod(this.map);
				measurePolygonMethod(this.map)
            }
        }
}

</scripc>


http://www.niftyadmin.cn/n/5744172.html

相关文章

大数据工具 flume 的安装配置与使用 (详细版)

参考网址&#xff1a;Flume 1.9用户手册中文版 — 可能是目前翻译最完整的版本了 1&#xff0c;上传安装包 安装包链接&#xff1a;文件下载-奶牛快传 Download &#xff5c;CowTransfer 口令&#xff1a;x8bhcg 1&#xff0c;切换盘符到安装目录 cd /opt/moudles 解压文件…

【科普】conda、virtualenv, venv分别是什么?它们之间有什么区别?

Conda&#xff1a; 定义&#xff1a;Conda 是一个开源的包管理系统和环境管理系统&#xff0c;主要用于安装和管理软件包、库和环境&#xff0c;特别是在科学计算领域。用途&#xff1a;Conda 可以用于创建隔离的环境&#xff0c;每个环境都有自己的一套库和依赖&#xff0c;适…

初始JavaEE篇——多线程(7):定时器、CAS

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 定时器的使用 定时器的原理 模拟实现定时器 CAS 介绍 CAS的应用场景 解析 AtomicInteger 类 实现自旋锁 CAS的缺陷…

安卓智能指针sp、wp、RefBase浅析

目录 前言一、RefBase1.1 引用计数机制1.2 设计目的1.3 主要方法1.4 如何使用1.5 小结 二、sp和wp2.1 引用计数机制2.2 设计目的2.3 主要方法2.3.1 sp2.3.2 wp 2.4 如何使用2.5 小结 四、参考链接 前言 安卓底层binder中&#xff0c;为什么 IInterface要继承自RefBase &#x…

Threejs随机生成建筑

生成建筑&#xff0c;重点在于&#xff0c;什么&#xff1f; 答案当然是数量&#xff0c;生成的建筑过多&#xff0c;那么一定会卡顿模糊&#xff0c;所以。生成建筑的难点而是在于对性能的优化。优化的解决方案就是&#xff1a;BufferGeometryUtils BufferGeometryUtils的用…

ubuntu22.04 docker-compose安装postgresql数据库

在 Ubuntu 22.04 上使用 Docker Compose 来安装和运行 PostgreSQL 数据库的过程如下&#xff1a; 1. 创建 Docker Compose 文件 在项目文件夹中创建一个 docker-compose.yml 文件&#xff0c;以配置 PostgreSQL 数据库的服务。 mkdir postgres_docker cd postgres_docker to…

基于MATLAB的实现垃圾分类Matlab源码

⼀、垃圾分类 如何通过垃圾分类管理&#xff0c;最⼤限度地实现垃圾资源利⽤&#xff0c;减少垃圾处置量&#xff0c;改善⽣存环境质量&#xff0c;是当前世界各国共同关注的迫切问题之⼀。根据国家制定的统⼀标准&#xff0c;现在⽣活垃圾被⼴泛分为四类&#xff0c;分别是可…

.Net IOC理解及代码实现

IOC理解 IoC(Inversion of Control)&#xff1a;即控制反转&#xff0c;这是一种设计思想&#xff0c;指将对象的控制权交给IOC容器&#xff0c;由容器来实现对象的创建、管理&#xff0c;程序员只需要从容器获取想要的对象就可以了。DI(Dependency Injection)&#xff0c;即依…