当前位置: 首页 > article >正文

uniapp 整合 OpenLayers - 测距测面

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

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.kler.cn/a/383430.html

相关文章:

  • 训练和部署Qwen2.5,实战教程步骤,训练qwen2.5教程,vLLM,Open WebUI,LLaMA-Factory
  • RabbitMQ 管理平台(控制中心)的介绍
  • 利用 AI 自动直播,提升抖音小程序流量主变现效率
  • 淘宝反爬虫机制的主要手段有哪些?
  • 《Linux运维总结:基于银河麒麟V10+ARM64架构CPU部署redis 6.2.14 TLS/SSL哨兵集群》
  • A15基于Spring Boot的宠物爱心组织管理系统的设计与实现
  • 安装mysql主从复制
  • SpringMVC快速上手
  • 微信小程序uniapp基于Android的流浪动物管理系统 70c3u
  • mysql代码生成器
  • Linux云计算个人学习总结(一)
  • 遥测终端机RTU产品如何选型和配置
  • 人工智能从业证书--抓住未来十年的趋势!
  • 【动态规划】似包非包
  • 架构赋能 AI:知识工程推动下的软件架构数字化
  • 本地Docker部署ZFile网盘打造个人云存储,告别公共网盘让你数据安全感爆棚
  • 剑指offer第五天
  • element-plus table tableRowClassName 无效
  • HTTP动词与状态码
  • 真正的Agent来了,智谱新模型AutoGLM的相关应用,以及AutoGLM的python代码部署实战
  • 兴业严选|美国总统都是不良资产出身 法拍市场是否将大众化
  • 使用 Python 和 OpenCV 实现实时人脸识别
  • React Native使用axios会不会有问题
  • ROS话题通信机制理论模型的学习
  • 应用插件化及其进程关系梳理
  • 数据揭秘:掌握K-means聚类算法的精髓与实践