欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue+OpenLayer實現(xiàn)測距功能

 更新時間:2022年04月20日 14:19:27   作者:秦浩鋮  
OpenLayers?是一個專為Web?GIS?客戶端開發(fā)提供的JavaScript?類庫包,用于實現(xiàn)標準格式發(fā)布的地圖數(shù)據(jù)訪問。本文將通過Vue和OpenLayer實現(xiàn)測距功能?,需要的可以參考一下

前言

首先呢說明一下,我是跟著一個大佬學的,所以我是個小次佬,openlayer的官網(wǎng)上面給出了案例,但是習慣vue開發(fā)的我完全不理解,關(guān)鍵是連注釋都沒多少,而且我 openlayer 用的本來就不多。

然后這里分享一下官網(wǎng)的測距案例

引入相關(guān)庫文件

這個庫文件直接按照官網(wǎng)的來就可以了。 首先說一個事情哈,官網(wǎng)用的案例是地圖使用的 EPSG:3857, 如果我們改成 EPSG:4326,測量數(shù)據(jù)不準確,切記這一點。

  import 'ol/ol.css';
  import Draw from 'ol/interaction/Draw';
  import Map from 'ol/Map';
  import Overlay from 'ol/Overlay';
  import View from 'ol/View';
  import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style';
  import { LineString, Polygon } from 'ol/geom';
  import { OSM, Vector as VectorSource } from 'ol/source';
  import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
  import { getArea, getLength } from 'ol/sphere';
  import { unByKey } from 'ol/Observable';

上面是我引入的庫文件,和官網(wǎng)基本上一樣。

繪制提示文字

首先我們看下圖官網(wǎng)效果,官網(wǎng)開始繪制或者是繪制中都在鼠標旁邊有一個title文本框用來提示用戶操作信息。

我們首先來實現(xiàn)一下這個功能。

首先說明一點哈,這是關(guān)鍵代碼,有些參數(shù)可能用起來發(fā)現(xiàn)沒有聲明,都是全局的,自己加在全局就可以,主要是下面這一些。

  var map = null
  var helpTooltipElement = null
  var feature = null;
  var helpTooltip = null;
  var draw = null;
  var measureTooltipElement = null;
  var measureTooltip = null;
  var listener = null;
  var mapMouseMove = null;

首先我們在需要實現(xiàn)測距功能的頁面上寫兩個按鈕,一個開始測距,一個結(jié)束測距。然后點擊開始測距的時候,執(zhí)行一個方法,假設(shè)是distance方法。

  distance() {
        let source = new VectorSource()  // 首先創(chuàng)建一個數(shù)據(jù)源,用來放置繪制過程中和繪制結(jié)束后的線段
        const layer = new VectorLayer({  // 添加一個圖層,用來放置數(shù)據(jù)源,樣式自己隨便設(shè)置就可以了,我這里默認的官網(wǎng)
          source: source,
          style: new Style({
            fill: new Fill({
              color: 'rgba(255, 255, 255, 0.2)',
            }),
            stroke: new Stroke({
              color: '#ffcc33',
              width: 4,
            }),
            image: new CircleStyle({
              radius: 7,
              fill: new Fill({
                color: '#ffcc33',
              }),
            }),
          }),
        });
        mapMouseMove = map.on('pointermove', (ev) => {  // 給地圖添加一個鼠標移動事件
          let helpMsg = '點擊開始測量'    // 默認開始的操作提示文本
          if (feature) {  // featuer 是全局的,判斷有沒有點擊鼠標繪制過
            helpMsg = '雙擊結(jié)束測量'    // 如果之前點擊繪制了就顯示雙擊結(jié)束
          }
          helpTooltipElement.innerHTML = helpMsg;   // 設(shè)置dom的提示文字
          helpTooltip.setPosition(ev.coordinate);  // 設(shè)置位置跟著鼠標走
          helpTooltipElement.classList.remove('hidden')  // 讓他顯示出來
        })
        this.createHelpTooltip()   // 創(chuàng)建那個helpTooltipElement方法
        map.addLayer(layer)  // 把圖層添加到地圖
      },

然后調(diào)用了一個初始化操作提示的dom元素。這個就是官網(wǎng)的函數(shù),如果參數(shù)名和自己起的或者是map的指向問題需要自己根據(jù)自己的實際修改一下。

      createHelpTooltip() {
        if (helpTooltipElement) {
          helpTooltipElement.parentNode.removeChild(helpTooltipElement);
        }
        helpTooltipElement = document.createElement('div');
        helpTooltipElement.className = 'ol-tooltip hidden';
        helpTooltip = new Overlay({
          element: helpTooltipElement,
          offset: [15, 0],
          positioning: 'center-left',
        });
        map.addOverlay(helpTooltip);
      },

還有一點,為了好看,把官網(wǎng)的樣式復制一下子。

<style scoped>
  /deep/.ol-tooltip {
    position: relative;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 4px;
    color: white;
    padding: 4px 8px;
    opacity: 0.7;
    white-space: nowrap;
    font-size: 12px;
    cursor: default;
    user-select: none;
  }

  /deep/.ol-tooltip-measure {
    opacity: 1;
    font-weight: bold;
  }

  /deep/.ol-tooltip-static {
    background-color: #ffcc33;
    color: black;
    border: 1px solid white;
  }

  /deep/.ol-tooltip-measure:before,
  /deep/.ol-tooltip-static:before {
    border-top: 6px solid rgba(0, 0, 0, 0.5);
    border-right: 6px solid transparent;
    border-left: 6px solid transparent;
    content: "";
    position: absolute;
    bottom: -6px;
    margin-left: -7px;
    left: 50%;
  }

  /deep/.ol-tooltip-static:before {
    border-top-color: #ffcc33;
  }
</style>

然后就可以看到我們點擊“開始測距”按鈕之后,上面代碼執(zhí)行,鼠標旁邊就出現(xiàn)一個小小的操作提示。

鼠標繪制線

好的,通過上面的代碼呢,我們成功的繪制出了提示框,然后就是鼠標繪制,代碼也很簡單,在map監(jiān)聽的pointermove方法中,繼續(xù)創(chuàng)建一個draw進行繪制,關(guān)鍵代碼就是下面:

		draw = new Draw({
          source,  // 這個數(shù)據(jù)源就是我們最開始的那個數(shù)據(jù)源,這是簡寫,實際上是 source:source,
          type: 'LineString',  // 繪制線
          style: new Style({   // 繪制完成之前線的樣式,這是官網(wǎng)的樣式,需要的話自己可以修改成自己想要的樣子
            fill: new Fill({
              color: 'rgba(255, 255, 255, 0.2)',
            }),
            stroke: new Stroke({
              color: 'rgba(0, 0, 0, 0.5)',
              lineDash: [10, 10],
              width: 4,
            }),
            image: new CircleStyle({
              radius: 5,
              stroke: new Stroke({
                color: 'rgba(0, 0, 0, 0.7)',
              }),
              fill: new Fill({
                color: 'rgba(255, 255, 255, 0.2)',
              }),
            }),
          }),
        });

然后把draw綁定到地圖上面。

map.addInteraction(draw);   // draw 綁定到地圖上面去

然后就實現(xiàn)了鼠標繪制線。

設(shè)置距離信息窗

在我們點擊開始測量的時候呢,在我們拖動鼠標的時候,會在上方顯示出當前距離起點的距離,這個地方代碼實現(xiàn)就是下面的樣子,繼續(xù)在上面的代碼后面寫:

		// 開始監(jiān)聽繪制
        draw.on('drawstart', (evt) => {
          feature = evt.feature;  // feature就是全局的
          let tooltipCoord = evt.coordinate;  // 鼠標當前的位置 
          listener = feature.getGeometry().on('change', function (evt) {
            const geom = evt.target;
            let output = formatLength(geom);   // 距離的格式
            tooltipCoord = geom.getLastCoordinate();    // 設(shè)置鼠標位置改變后的實時位置
            measureTooltipElement.innerHTML = output;  // 設(shè)置提示框的內(nèi)容,就是距離
            measureTooltip.setPosition(tooltipCoord);  // 設(shè)置距離提示框的位置
          });
        });
        
        // 格式化長度, 直接官網(wǎng)代碼
        const formatLength = function (line) {
          const length = getLength(line);
          let output;
          if (length > 100) {
            output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km';
          } else {
            output = Math.round(length * 100) / 100 + ' ' + 'm';
          }
          return output;
        };
        
		this.createMeasureTooltip()  // 創(chuàng)建那個距離的提示框

然后上面代碼調(diào)用了一個方法。

	createMeasureTooltip() {
        if (measureTooltipElement) {
          measureTooltipElement.parentNode.removeChild(measureTooltipElement);
        }
        measureTooltipElement = document.createElement('div');
        measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
        measureTooltip = new Overlay({
          element: measureTooltipElement,
          offset: [0, -15],
          positioning: 'bottom-center',
          stopEvent: false,
          insertFirst: false,
        });
        this.drawElements.push(measureTooltip)
        map.addOverlay(measureTooltip);
      },

完成上面的代碼之后,我們在點擊開始測量之后,會在鼠標上方實時顯示當前鼠標位置距離起點的距離。

繪制完成

上邊已經(jīng)實現(xiàn)了點擊開始測距,并且實時顯示距離信息,接下來就是雙擊完成時候顯示出總長度。

繼續(xù)在之前代碼后邊寫:

		// 雙擊繪制完成
        draw.on('drawend', () => {
          measureTooltipElement.className = 'ol-tooltip ol-tooltip-static';
          measureTooltip.setOffset([0, -7]);
          feature = null;
          measureTooltipElement = null;
          this.createMeasureTooltip();
          unByKey(listener);
        });

上邊的代碼基本上就是官網(wǎng)的代碼,但是變量名不一樣的地方需要稍微改一下。

通過上面的代碼就實現(xiàn)了雙擊測量完成的功能。

OK,到此為止,測距功能全部完成!

取消繪制

繪制功能完成了,就需要取消繪制,取消繪制需要在點擊“取消繪制”按鈕之后,取消地圖繪制功能,刪除界面上已經(jīng)繪制過的內(nèi)容。

首先我們需要刪除地圖上繪制過的內(nèi)容,包括連線,以及彈窗。

這個地方需要注意一下,我們需要把繪制的圖層,比如連線,和彈窗都保存到一個或者是幾個列表里面,然后在點擊按鈕的時候,去遍歷刪除。

所以說我們要在點擊測距時候加載到地圖的圖層之后,將創(chuàng)建的圖層添加到一個數(shù)組存起來。

map.addLayer(layer)
this.drawLayers.push(layer)  // 保存起來

包括那個總距離的彈窗。

this.drawElements.push(measureTooltip)
map.addOverlay(measureTooltip);  // 保存起來

然后點擊“取消測量”按鈕的時候執(zhí)行下面的代碼:

      // 取消繪制
      cancal() {
        for(let i = 0 ; i< this.drawLayers.length; i++) {
          map.removeLayer(this.drawLayers[i])
        }
        for (let i = 0; i < this.drawElements.length; i++) {
          map.removeOverlay(this.drawElements[i])
        }
        this.drawLayers = []
        this.drawElements = []
        map.removeInteraction(draw)
        unByKey(mapMouseMove);
      },

這樣就可以了。

這樣就完成了!

全部代碼

這里分享一下全部代碼,就不放資源了,下載還花錢,我也是跟人家學的,沒必要都。

<template>
  <div class="home">
    <div class="set">
      <button class="btn" @click="distance()">測距</button>
      <button class="btn" @click="cancal()">取消</button>
    </div>
    <div id="map" ref="map"></div>
  </div>
</template>

<script>
  import 'ol/ol.css';
  import Draw from 'ol/interaction/Draw';
  import Map from 'ol/Map';
  import Overlay from 'ol/Overlay';
  import View from 'ol/View';
  import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style';
  import { LineString, Polygon } from 'ol/geom';
  import { OSM, Vector as VectorSource } from 'ol/source';
  import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
  import { getArea, getLength } from 'ol/sphere';
  import { unByKey } from 'ol/Observable';

  var map = null

  var helpTooltipElement = null
  var feature = null;
  var helpTooltip = null;
  var draw = null;
  var measureTooltipElement = null;
  var measureTooltip = null;
  var listener = null;
  var mapMouseMove = null;

  export default {
    name: "Home",
    data() {
      return {
        drawLayers: [],
        drawElements: [],
      }
    },
    mounted() {
      this.initMap()
    },
    methods: {
      // 初始化地圖
      initMap() {
      
        map = new Map({
          layers: [
            new TileLayer({
              source: new OSM(),
            }),
          ],
          target: 'map',
          view: new View({
            center: [0, 0],
            zoom: 5,
            maxZoom: 18,
            // projection: 'EPSG:4326',
            constrainResolution: true,  // 設(shè)置縮放級別為整數(shù) 
            smoothResolutionConstraint: false,  // 關(guān)閉無級縮放地圖
          }),
        });
      },


      // 測距
      distance() {

        let source = new VectorSource()
        const layer = new VectorLayer({
          source: source,
          style: new Style({
            fill: new Fill({
              color: 'rgba(255, 255, 255, 0.2)',
            }),
            stroke: new Stroke({
              color: '#ffcc33',
              width: 4,
            }),
            image: new CircleStyle({
              radius: 7,
              fill: new Fill({
                color: '#ffcc33',
              }),
            }),
          }),
        });

        mapMouseMove = map.on('pointermove', (ev) => {
          let helpMsg = '點擊開始測量'
          if (feature) {
            helpMsg = '雙擊結(jié)束測量'
          }
          helpTooltipElement.innerHTML = helpMsg;
          helpTooltip.setPosition(ev.coordinate);
          helpTooltipElement.classList.remove('hidden')

        })

        map.getViewport().addEventListener('mouseout', function () {
          helpTooltipElement.classList.add('hidden');
        });

        draw = new Draw({
          source,
          type: 'LineString',
          style: new Style({
            fill: new Fill({
              color: 'rgba(255, 255, 255, 0.2)',
            }),
            stroke: new Stroke({
              color: 'rgba(0, 0, 0, 0.5)',
              lineDash: [10, 10],
              width: 4,
            }),
            image: new CircleStyle({
              radius: 5,
              stroke: new Stroke({
                color: 'rgba(0, 0, 0, 0.7)',
              }),
              fill: new Fill({
                color: 'rgba(255, 255, 255, 0.2)',
              }),
            }),
          }),
        });

        // 開始堅挺繪制
        draw.on('drawstart', (evt) => {
          feature = evt.feature;

          let tooltipCoord = evt.coordinate;

          listener = feature.getGeometry().on('change', function (evt) {
            const geom = evt.target;
            let output = formatLength(geom);
            tooltipCoord = geom.getLastCoordinate();
            measureTooltipElement.innerHTML = output;
            measureTooltip.setPosition(tooltipCoord);
          });
        });

        // 雙擊繪制完成
        draw.on('drawend', () => {
          measureTooltipElement.className = 'ol-tooltip ol-tooltip-static';
          measureTooltip.setOffset([0, -7]);
          feature = null;
          measureTooltipElement = null;
          this.createMeasureTooltip();
          unByKey(listener);
        });

        // 格式化長度
        const formatLength = function (line) {
          const length = getLength(line);
          let output;
          if (length > 100) {
            output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km';
          } else {
            output = Math.round(length * 100) / 100 + ' ' + 'm';
          }
          return output;
        };

        this.createHelpTooltip()
        this.createMeasureTooltip()
        map.addLayer(layer)
        this.drawLayers.push(layer)
        map.addInteraction(draw);
      },

      // 取消繪制
      cancal() {
        for(let i = 0 ; i< this.drawLayers.length; i++) {
          map.removeLayer(this.drawLayers[i])
        }
        for (let i = 0; i < this.drawElements.length; i++) {
          map.removeOverlay(this.drawElements[i])
        }
        this.drawLayers = []
        this.drawElements = []
        map.removeInteraction(draw)
        unByKey(mapMouseMove);
      },

      createMeasureTooltip() {
        if (measureTooltipElement) {
          measureTooltipElement.parentNode.removeChild(measureTooltipElement);
        }
        measureTooltipElement = document.createElement('div');
        measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure';
        measureTooltip = new Overlay({
          element: measureTooltipElement,
          offset: [0, -15],
          positioning: 'bottom-center',
          stopEvent: false,
          insertFirst: false,
        });
        this.drawElements.push(measureTooltip)
        map.addOverlay(measureTooltip);
      },

      createHelpTooltip() {
        if (helpTooltipElement) {
          helpTooltipElement.parentNode.removeChild(helpTooltipElement);
        }
        helpTooltipElement = document.createElement('div');
        helpTooltipElement.className = 'ol-tooltip hidden';
        helpTooltip = new Overlay({
          element: helpTooltipElement,
          offset: [15, 0],
          positioning: 'center-left',
        });
        map.addOverlay(helpTooltip);
      },
      
    },
  };

</script>
<style scoped>
  .home {
    width: 100%;
    height: 100%;
    background-color: aliceblue;
    position: relative;
  }

  #map {
    height: 100%;
    width: 100%;
  }

  .set {
    position: absolute;
    top: 0px;
    right: 0px;
    z-index: 99;
  }

  .btn {
    margin: 10px;
  }

  /deep/.hidden {
    display: none;
  }

  /deep/.ol-tooltip {
    position: relative;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 4px;
    color: white;
    padding: 4px 8px;
    opacity: 0.7;
    white-space: nowrap;
    font-size: 12px;
    cursor: default;
    user-select: none;
  }

  /deep/.ol-tooltip-measure {
    opacity: 1;
    font-weight: bold;
  }

  /deep/.ol-tooltip-static {
    background-color: #ffcc33;
    color: black;
    border: 1px solid white;
  }

  /deep/.ol-tooltip-measure:before,
  /deep/.ol-tooltip-static:before {
    border-top: 6px solid rgba(0, 0, 0, 0.5);
    border-right: 6px solid transparent;
    border-left: 6px solid transparent;
    content: "";
    position: absolute;
    bottom: -6px;
    margin-left: -7px;
    left: 50%;
  }

  /deep/.ol-tooltip-static:before {
    border-top-color: #ffcc33;
  }
</style>

以上就是Vue+OpenLayer實現(xiàn)測距功能 的詳細內(nèi)容,更多關(guān)于Vue OpenLayer測距的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue截取視頻第一幀的圖片問題

    vue截取視頻第一幀的圖片問題

    這篇文章主要介紹了vue截取視頻第一幀的圖片問題,基本就是用cavas進行繪制,解決一下跨域問題,截視頻第一幀,然后根據(jù)視頻原本的寬高進行繪制,最后轉(zhuǎn)一下圖片格式即可,需要的朋友可以參考下
    2022-11-11
  • vue使用echarts實現(xiàn)三維圖表繪制

    vue使用echarts實現(xiàn)三維圖表繪制

    這篇文章主要為大家詳細介紹了vue如何在項目中使用echarts實現(xiàn)三維圖表的繪制,文中的示例代碼講解詳細,感興趣的小伙伴可以參考一下
    2023-08-08
  • 淺談vue.js中v-for循環(huán)渲染

    淺談vue.js中v-for循環(huán)渲染

    本篇文章主要介紹了淺談vue.js中v-for循環(huán)渲染,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • Vue Promise解決回調(diào)地獄問題實現(xiàn)方法

    Vue Promise解決回調(diào)地獄問題實現(xiàn)方法

    這篇文章主要介紹了Vue Promise解決回調(diào)地獄問題,總的來說這并不是一道難題,那為什么要拿出這道題介紹?拿出這道題真正想要傳達的是解題的思路,以及不斷優(yōu)化探尋最優(yōu)解的過程。希望通過這道題能給你帶來一種解題優(yōu)化的思路
    2023-01-01
  • Vue transition實現(xiàn)點贊動畫效果的示例

    Vue transition實現(xiàn)點贊動畫效果的示例

    點贊動畫是網(wǎng)頁評論中常見的功能,本文將介紹如何用vue實現(xiàn)這一效果。點贊時愛心縮小變大,變大時略微大一點再變正常,取消點贊時愛心無動畫,同時數(shù)字滾動,+1 時向上滾動,-1 時向下滾動
    2021-05-05
  • 關(guān)于axios配置多個請求地址(打包后可通過配置文件修改)

    關(guān)于axios配置多個請求地址(打包后可通過配置文件修改)

    這篇文章主要介紹了關(guān)于axios配置多個請求地址(打包后可通過配置文件修改),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • vue3.0如何在全局掛載對象和方法

    vue3.0如何在全局掛載對象和方法

    這篇文章主要介紹了vue3.0如何在全局掛載對象和方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue使用技巧及vue項目中遇到的問題

    vue使用技巧及vue項目中遇到的問題

    這篇文章主要介紹了vue使用技巧及vue項目中遇到的問題,本文給大家?guī)淼闹皇且徊糠?,后續(xù)還會持續(xù)更新,感興趣的朋友跟隨腳本之家小編一起學習吧
    2018-06-06
  • vue跳轉(zhuǎn)同一個組件,參數(shù)不同,頁面接收值只接收一次的解決方法

    vue跳轉(zhuǎn)同一個組件,參數(shù)不同,頁面接收值只接收一次的解決方法

    今天小編就為大家分享一篇vue跳轉(zhuǎn)同一個組件,參數(shù)不同,頁面接收值只接收一次的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-11-11
  • 在vue項目實現(xiàn)一個ctrl+f的搜索功能

    在vue項目實現(xiàn)一個ctrl+f的搜索功能

    剛剛接到領(lǐng)導通知,需要實現(xiàn)搜索功能,因為項目是vue的而且是手機端,對我來說有點小難度。經(jīng)過小編的一番思索最終還是解決了,今天小編把實現(xiàn)過程分享到腳本之家平臺,需要的朋友參考下
    2020-02-02

最新評論