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/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

发表回复

登录后才能评论