VueOpenLayers——一個用於地圖開發的vue組件庫

VueOpenLayers是一個基於Vue.js和開源JavaScript庫OpenLayers構建的地圖組件庫。可以方便地用Vue.js技術棧來構建高性能的WebGIS應用。在這篇文章中,我們將從幾個方面探究VueOpenLayers的使用。

一、根據經緯度畫圓形

在WebGIS應用開發中,根據某個點和半徑在地圖上畫圓形是一個常見的需求。VueOpenLayers提供了相應的組件和方法,方便用戶實現這個需求。

  <template>
    <openlayers-map>
      <openlayers-layer>
        <openlayers-source>
          <openlayers-feature :geometry="myCircleGeometry">
            <openlayers-style
              :fill="{ color: 'rgba(255, 0, 0, 0.1)' }"
              :stroke="{ color: 'red', width: 2 }"
            />
          </openlayers-feature>
        </openlayers-source>
      </openlayers-layer>
    </openlayers-map>
  </template>
  
  <script>
  import { fromCircle } from 'ol/geom'
  import { Component, Prop } from 'vue-property-decorator'
  import { VueOpenLayers } from 'vue-openlayers'

  @Component
  export class MyComponent extends VueOpenLayers {
    @Prop({ required: true }) lat!: number
    @Prop({ required: true }) lon!: number
    @Prop({ required: true }) radius!: number

    get myCircleGeometry() {
      return fromCircle([this.lon, this.lat], this.radius)
    }
  }
  </script>

在上述代碼中,我們首先定義了一個MyComponent組件,接收經緯度和半徑作為傳入參數,然後通過定義myCircleGeometry計算屬性及其依賴數據來實現圓形的繪製。

二、在地圖上標註

除了疊加各種圖層,標註也是WebGIS應用中常見的需求,VueOpenLayers在標註方面提供了多種方式,以下是其中的一種。

  <template>
    <div>
      <openlayers-map>
        <openlayers-layer
          :source="imageLayer"
          :style="imageStyle"
        />
      </openlayers-map>
    </div>
  </template>

  <script>
  import { Component } from 'vue-property-decorator'
  import { View, Map, Feature } from 'ol'
  import { Point } from 'ol/geom'
  import { Tile, Vector as VectorSource } from 'ol/source'
  import { fromLonLat } from 'ol/proj'
  import Icon from 'ol/style/Icon'
  import Style from 'ol/style/Style'
  import ImageLayer from 'ol/layer/Image'

  import image from './images/marker.png'

  @Component
  export class MarkersMap extends Vue {
    private map!: Map
    private imageLayer!: ImageLayer
    private imageStyle: Style = new Style({
      image: new Icon({
        src: image,
        anchor: [0.5, 1],
        crossOrigin: 'anonymous'
      })
    })
    private markerCoords = [104.0665, 30.5728]

    private mounted() {
      const markerFeature = new Feature({
        geometry: new Point(fromLonLat(this.markerCoords))
      })
      this.imageLayer = new ImageLayer({
        source: new VectorSource({
          features: [markerFeature]
        })
      })
      this.map = new Map({
        target: this.$el.querySelector('.map') as HTMLElement,
        view: new View({
          center: fromLonLat(this.markerCoords),
          zoom: 15
        })
      })
    }
  }
  </script>

在上述代碼中,我們自定義了MarkersMap組件,並在其中定義了一個點,並在地圖中顯示。我們使用ImageLayer來實現這個需求,將一張圖片作為標註點。

三、圖層管理

在WebGIS應用中,圖層的管理是一個十分重要的環節。VueOpenLayers提供了多種方式來管理地圖圖層,以下是其中的一種:

  <template>
    <div>
      <openlayers-map :zoom.sync="zoom">
        <openlayers-layer
          v-for="(layer, index) in layers"
          :key="index"
          :z-index="index"
          :source="layer.source"
          :style="layer.style"
        />
      </openlayers-map>
      <div class="layer-chooser">
        <div
          v-for="(layer, index) in layers"
          :key="layer.name"
          @click="layer.visible = !layer.visible"
          class="layer-chooser-item"
          :class="{ enabled: layer.visible }"
        >
          {{ layer.name }}
          <i></i>
        </div>
      </div>
    </div>
  </template>

  <script>
  import { Component, Vue, Watch } from 'vue-property-decorator'
  import { Vector as VectorSource } from 'ol/source'
  import { Style, Icon } from 'ol/style'
  import { Fill, Stroke } from 'ol/style'
  import { Point, LineString, Polygon } from 'ol/geom'
  import { Map, View } from 'ol'

  import 'ol/ol.css'

  @Component
  export class LayerChooser extends Vue {
    public zoom: number = 4
    public layers = [
      {
        name: '點圖層',
        visible: true,
        source: new VectorSource({
          features: [
            {
              geometry: new Point([0, 0]),
              style: new Style({
                image: new Icon({
                  src: require('@/assets/icons/pin.png'),
                  anchor: [0.5, 1]
                })
              })
            }
          ]
        }),
        style: null
      },
      {
        name: '線圖層',
        visible: true,
        source: new VectorSource({
          features: [
            {
              geometry: new LineString([
                [0, 0],
                [10e6, 0]
              ]),
              style: new Style({
                stroke: new Stroke({
                  color: [255, 0, 0, 1],
                  width: 2
                })
              })
            }
          ]
        }),
        style: null
      },
      {
        name: '面圖層',
        visible: true,
        source: new VectorSource({
          features: [
            {
              geometry: new Polygon([[[0, 0], [10e6, 0], [10e6, 1000000]]]),
              style: new Style({
                fill: new Fill({
                  color: [0, 0, 255, 0.1]
                }),
                stroke: new Stroke({
                  color: [0, 0, 255, 1],
                  width: 2
                })
              })
            }
          ]
        }),
        style: null
      }
    ]

    public mounted() {
      const mapContainer = document.getElementById('map-container') as HTMLElement
      this.$nextTick(() => {
        new Map({
          view: new View({
            center: [0, 0],
            zoom: this.zoom
          }),
          target: mapContainer.querySelector('.map') as HTMLElement,
          layers: this.layers.map(layer => {
            const olLayer: any = {}
            for (const key in layer) {
              if (key === 'source') {
                olLayer.source = layer.source
              } else if (key === 'style') {
                olLayer.style = layer.style
              } else {
                olLayer[key] = layer[key]
              }
            }
            return olLayer
          })
        })
      })
    }

    @Watch('zoom')
    handleZoom() {
      console.log('zoom changed', this.zoom)
    }
  }
  </script>

在上述代碼中,我們首先定義了一個LayerChooser組件,可以管理多個圖層,並且為每個圖層提供可見性切換功能。我們使用了VectorSource來實現不同類型的圖層。

通過上述的介紹,我們可以看到VueOpenLayers提供了非常多的功能和組件來滿足WebGIS應用開發中的需求。在實際開發中,根據實際需求進行選擇和使用VueOpenLayers的組件和方法,可以大大提高開發效率。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/154202.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-15 03:26
下一篇 2024-11-15 03:26

相關推薦

  • 使用Vue實現前端AES加密並輸出為十六進制的方法

    在前端開發中,數據傳輸的安全性問題十分重要,其中一種保護數據安全的方式是加密。本文將會介紹如何使用Vue框架實現前端AES加密並將加密結果輸出為十六進制。 一、AES加密介紹 AE…

    編程 2025-04-29
  • 用Python畫疫情地圖

    COVID-19疫情在全世界範圍內肆虐了數月,為了讓人們了解當前疫情的最新情況,很多技術人員都開始使用數據可視化的手段展示疫情數據。其中一個重要的展示形式就是利用Python編程語…

    編程 2025-04-29
  • Echarts 地圖 Label 增加背景圖

    本文將從多個方面對 Echarts 地圖 Label 增加背景圖進行詳細的闡述。 一、背景圖的作用 為 Echarts 地圖添加背景圖可以使 Label 更加直觀、美觀,提升視覺效…

    編程 2025-04-29
  • Vue TS工程結構用法介紹

    在本篇文章中,我們將從多個方面對Vue TS工程結構進行詳細的闡述,涵蓋文件結構、路由配置、組件間通訊、狀態管理等內容,並給出對應的代碼示例。 一、文件結構 一個好的文件結構可以極…

    編程 2025-04-29
  • 如何修改ant組件的動效為中心

    當我們使用Ant Design時,其默認的組件動效可能不一定符合我們的需求,這時我們需要修改Ant Design組件動效,使其更加符合我們的UI設計。本文將從多個方面詳細闡述如何修…

    編程 2025-04-29
  • Ant Design組件的動效

    Ant Design是一個基於React技術棧的UI組件庫,其中動效是該組件庫中的一個重要特性之一。動效的使用可以讓用戶更清晰、更直觀地了解到UI交互的狀態變化,從而提高用戶的滿意…

    編程 2025-04-29
  • Vue3的vue-resource使用教程

    本文將從以下幾個方面詳細闡述Vue3如何使用vue-resource。 一、安裝Vue3和vue-resource 在使用vue-resource前,我們需要先安裝Vue3和vue…

    編程 2025-04-27
  • Vue模擬按鍵按下

    本文將從以下幾個方面對Vue模擬按鍵按下進行詳細闡述: 一、Vue 模擬按鍵按下的場景 在前端開發中,我們常常需要模擬按鍵按下的場景,比如在表單中填寫內容後,按下「回車鍵」提交表單…

    編程 2025-04-27
  • ThinkPHP6 + Vue.js: 不使用Fetch的數據請求方法

    本文將介紹如何在ThinkPHP6和Vue.js中進行數據請求,同時避免使用Fetch函數。 一、AJAX:XMLHttpRequest的基礎使用 在進行數據請求時,最基礎的方式就…

    編程 2025-04-27
  • 開發前端程序,Vue是否足夠?

    Vue是一個輕量級,高效,漸進式的JavaScript框架,用於構建Web界面。開發人員可以使用Vue輕鬆完成前端編程,開發響應式應用程序。然而,當涉及到需要更大的生態系統,或利用…

    編程 2025-04-27

發表回復

登錄後才能評論