Openlayers + Vue 疑难杂症(一)地图构建与容器监听

需求:

  1. 使用vue + openlayers初步搭建一个webgis项目;
  2. 解决问题:随着侧栏的拉伸/隐藏,地图容器的宽度会发生变化,从而会影响到地图侧边出现空白区域。

关键词: updateSize();MutationObserver

步骤:
1. Vue-cli搭建项目
已有的教程很多,就不啰嗦了。
参考教程:vs code创建vue项目

2. 安装并引入Openlayers
有多种方式可以引入openlayers,其中npm的方式最为便捷。
直接VS Code新建终端输入如下命令:

npm install ol

随后在需要用到的Openlayers的.vue文件中import就行了。

3.构建地图
假设目标为MapView.vue文件,MapView.vue的地图构建代码如下:

<template>
<div style="" class="container-fluid">
  <div id="mapview" class="map">        //1.地图容器
    </div>
</div>
</template>
<script>
// import $ from 'jquery'
import 'ol/ol.css'                     //2.引入需要用到的openlayers库
import {Map, View} from 'ol'
import Tile from 'ol/layer/Tile'
import OSM from 'ol/source/OSM'
import * as olProj from 'ol/proj'

var map = null              //3.地图对象的声明

export default {
  name: 'MyMapView',
  data: function () {
    return {
      // map: null
    }
  },
  methods: {
    //  4.地图对象定义
    initMap: function () {
      map = new Map({
        target: 'mapview',
        layers: [
          new Tile({
            source: new OSM()
          })
        ],
        view: new View({
          center: olProj.fromLonLat([104.065861, 30.657401]),
          zoom: 12
        })
      })
    },

主要部分有四个,分别是地图容器的准备,引入需要用到的库,地图对象的声明和定义。
值得注意的是此处地图对象的声明并不是放在data里面,主要考虑的是内存的消耗:
vue地图对象的声明

4.容器监听
随着侧栏的拉伸/隐藏,地图容器的宽度会发生变化,从而会影响到地图侧边出现空白区域,如下所示:
Openlayers + Vue 疑难杂症(一)地图构建与容器监听_第1张图片
Openlayers + Vue 疑难杂症(一)地图构建与容器监听_第2张图片
这里要介绍到openlayers里面Map类中的updateSize()方法:ol.Map
和容器监听MutationObserver:MutationObserver

主要思路是MutationObserver()监听容器宽度属性发生改变,从而触发updateSize()更新地图。
详细代码如下:

``// 监听宽度变化更新地图,否则地图侧边会留下空白区域
    observer: function () {
      // 选择需要观察变动的节点
      const targetNode = document.getElementById('siderbar')
      // 观察器的配置(需要观察什么变动)
      const config = { attributes: true, childList: true, subtree: true }
      // 当观察到变动时执行的回调函数
      const callback = function (mutationsList, observer) {
        // Use traditional 'for loops' for IE 11
        for (let mutation of mutationsList) {
          if (mutation.type === 'childList') {
            console.log('A child node has been added or removed.')
          } else if (mutation.type === 'attributes') {
            map.updateSize()
            console.log('The ' + mutation.attributeName + ' attribute was modified.')
          }
        }
      }
      // 创建一个观察器实例并传入回调函数
      const observer = new MutationObserver(callback)
      // 以上述配置开始观察目标节点
      observer.observe(targetNode, config)
    }
  },`

我这里采用的是flex布局,地图容器mapview是因为侧边栏siderbar的宽度的变化而变化的,所以直接监听的是侧边栏siderbar,大家实际使用中还得对症下药。

最后别忘了调用上面两个方法:

mounted () {
    this.initMap()
    this.observer()
  }

5.全部代码

<template>
<div style="" class="container-fluid">
  <div id="mapview" class="map">
    </div>
</div>
</template>
<script>
// import $ from 'jquery'
import 'ol/ol.css'
import {Map, View} from 'ol'
import Tile from 'ol/layer/Tile'
import OSM from 'ol/source/OSM'
import * as olProj from 'ol/proj'

var map = null

export default {
  name: 'MyMapView',
  data: function () {
    return {
      // map: null
    }
  },
  methods: {
    //  初始化地图
    initMap: function () {
      map = new Map({
        target: 'mapview',
        layers: [
          new Tile({
            source: new OSM()
          })
        ],
        view: new View({
          center: olProj.fromLonLat([104.065861, 30.657401]),
          zoom: 12
        })
      })
    },

    // 监听宽度变化更新地图,否则地图侧边会留下空白区域
    observer: function () {
      // 选择需要观察变动的节点
      const targetNode = document.getElementById('siderbar')
      // 观察器的配置(需要观察什么变动)
      const config = { attributes: true, childList: true, subtree: true }
      // 当观察到变动时执行的回调函数
      const callback = function (mutationsList, observer) {
        // Use traditional 'for loops' for IE 11
        for (let mutation of mutationsList) {
          if (mutation.type === 'childList') {
            console.log('A child node has been added or removed.')
          } else if (mutation.type === 'attributes') {
            map.updateSize()
            console.log('The ' + mutation.attributeName + ' attribute was modified.')
          }
        }
      }
      // 创建一个观察器实例并传入回调函数
      const observer = new MutationObserver(callback)
      // 以上述配置开始观察目标节点
      observer.observe(targetNode, config)
    }
  },
  mounted () {
    this.initMap()
    this.observer()
  }
}
</script>

<style>
    #mapview{
          height: 100%;
          width: 100%;
          flex:1;
          border:1px #ccc solid;
        }
</style>

6.效果展示
Openlayers + Vue 疑难杂症(一)地图构建与容器监听_第3张图片
Openlayers + Vue 疑难杂症(一)地图构建与容器监听_第4张图片

你可能感兴趣的:(Openlayers,+,Vue)