openlayers 图层管理(1) | 「掘金日新计划 · 12 月更文挑战」

567 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

前段时间第一次使用openlayers开发了一个应急系统的可视化,本编文章大致记录一下在项目中封装的图层管理部分的相关功能代码。

image.png

功能描述

  • 动态添加图层:能支持不同类型的图层动态叠加上图展示【文中会遇到的图层类型有Arcgis dynamic动态服务、Arcgis tile切片服务、geojson矢量数据、 image图片、矢量MVT服务'】
  • 动态移动图层层级:支持点击上下移动图标移动图层显示层级【Zindex】
  • 动态设置图层透明度:支持滑动透明度滑竿改变图层透明度【Opacity】
  • 动态设置图层可见与否:点击眼睛小图标设置图层是否可见【Visible】
  • 动态移除图层:点击回收站小图标移除图层【removeLayer】

话不多讲,上代码

创建一个地图容器

基本操作,简单描述,后续代码中涉及的 viewer 皆为此map地图实例

import Map from 'ol/Map';
import View from 'ol/View';
const map = new Map({
  target: document.getElementById('map'),
  view: new View({
    zoom: 10,
    minZoom: 2,
    maxZoom: 19,
   center: [104.8888, 35.6666], // 中心点
    projection: 'EPSG:4326', // 我这里以4326坐标系为实例,默认不写的话是3857
  }),
  layers: [ ],
});

动态添加图层

Arcgis dynamic动态服务

  addarcgisdynamic (data, viewer) {
      let layer = new ol.layer.Tile({
      id: data.id, // 图层的唯一标识,便于管理
      title: data.text, // 图层的唯一名称,便于管理
      opacity: data.attributes.opacity || 1, // 图层的初始透明度
      zIndex: this.getlayerZindex(viewer),  // 图层的初始化层级,便于上下移动设置层级
      source: new ol.source.TileArcGISRest({
        crossOrigin: 'anonymous', // 跨域处理,可打印
        url: data.attributes.serviceURL // 图层地址
        // params: { // 在这里可以设置一些需要传递到arcgis server中的参数
        //   TRANSPARENT: true, // 如果为 true,则图像将以地图的背景色作为其透明颜色导出。
        //   LAYERS: 'show:0,1,2,3'
        // }
      })
    })
      viewer.addLayer(layer) // 加入到地图实例中
  }

Arcgis tile服务

tile服务使用的是zxy数据源,但是注意之处在于先去获取arcgis服务信息,然后通过动态的匹配当前服务的坐标系,中心点,和地图范围,分辨率等信息

  toArcgisTileLayer (data, viewer) {
    let _options = {
      url: data.attributes.serviceURL + '/tile/{z}/{y}/{x}',
      crossOrigin: 'crossOrigin'
    }
    let _that = this
    // 同步请求服务元数据信息
    $.ajax({
      url: data.attributes.serviceURL + '?f=json',
      type: 'get',
      contentType: 'application/json',
      dataType: 'jsonp',
      async: false, // 同步
      success: function (result) {
        const resObj = result
        let wkid = 4326
        if (resObj.spatialReference && resObj.spatialReference.wkid) {
          wkid = resObj.spatialReference.wkid
        }
        // 地图坐标 这里利用proj4def 进行的完整的封装,可后面进行分享一下,
        // 意思就是需要注册跟wkid相对应的坐标系 等价于 let projection = ol.proj.get('EPSG:4326')
        let projection = _that._proj4def.getProjection(wkid)
        // 坐标原点
        let origin = [resObj.tileInfo.origin.x, resObj.tileInfo.origin.y]
        // 分辨率
        let resolutions = []
        for (var i = 0; i < resObj.tileInfo.lods.length; i++) {
          resolutions.push(resObj.tileInfo.lods[i].resolution)
        }
        // 地图范围
        let fullExtent = [resObj.fullExtent.xmin, resObj.fullExtent.ymin,       resObj.fullExtent.xmax, resObj.fullExtent.ymax]
        //适配切片网格
        let tileGrid = new ol.tilegrid.TileGrid({
          tileSize: resObj.tileInfo.rows,
          origin: origin,
          extent: fullExtent,
          resolutions: resolutions
        })
        _options.tileGrid = tileGrid
        _options.projection = projection
        let layer = new ol.layer.Tile({
          id: data.id, // 图层的唯一标识,便于管理
          title: data.text,
          opacity: data.attributes.opacity || 1,
          zIndex: _that.getlayerZindex(viewer),
          source: new ol.source.XYZ(_options)
        })
        viewer.addLayer(layer)
      },
      error: function (result) {
      }
    })
  }

image图片

叠加一张图片,主要使用ol.source.ImageStatic用于显示单个静态图像的图层源

/**
     * 加载图片服务
     * @param data 服务参数
     * viewer 地图实例
     */
  addArcgispng (data, viewer) {
    let { serviceURL } = data.attributes
    let extent = [18.160896, 17.15, 135.1015, 53.56207]// 中国图层四至 图片范围
    let projection = new ol.proj.Projection({// 定义坐标系 创建投影
      code: 'xkcd-image',
      units: 'pixels', //像素单位
      extent: extent
    })
    let layer = new ol.layer.Image({
      title: data.text,
      opacity: data.attributes.opacity || 1,
      zIndex: this.getlayerZindex(viewer),
      source: new ol.source.ImageStatic({
        crossOrigin: 'anonymous',
        url: serviceURL, // 地址
        projection,
        imageExtent: extent
      })
    })
    viewer.addLayer(layer)
  }

总结

心有所想,目有所望,每个人眼中都有一个不同的世界,世界如此美好。 此次总结可能涉及代码和文本篇幅过多,待分章节叙述