类名 document/ArcGISVectorTileLayerView.js
import { LayerView, proj4 } from '@mapgis/webclient-common'
import * as L from '@mapgis/leaflet'
// eslint-disable-next-line import/no-extraneous-dependencies
import { mapboxCustomCRS } from './support/mapbox/mapboxCustomUtil'
// 添加leaflet和mapbox兼容插件
// eslint-disable-next-line import/extensions
import leafletMapbox from './support/mapbox/leafletMapbox.js'
import LeafletPlugin from '../util/LeafletPlugin'

function setLayerOpacity(map, opacity) {
  if (!map) return
  const canvas = map.getCanvas()
  if (canvas) {
    canvas.style.opacity = opacity
  }
}

function setLayerVisible(layer, style, visible) {
  // link https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#layout-line-visibility
  layer.sublayers.forEach((sublayer) => {
    style.setLayoutProperty(
      sublayer.id,
      'visibility',
      visible ? 'visible' : 'none'
    )
  })
}

function processStyle(mapboxMap, layerUpdateCotent, layer, innerLayer) {
  if (mapboxMap[layerUpdateCotent.name]) {
    // eslint-disable-next-line prefer-spread
    mapboxMap[layerUpdateCotent.name].apply(mapboxMap, layerUpdateCotent.params)
    return
  }
  switch (layerUpdateCotent.name) {
    case 'setPaintProperties': {
      const style = mapboxMap.style
      const args = layerUpdateCotent.params
      // 解析paint style 此参数键值对
      const keys = Object.keys(args[1])
      const layerId = args[0]
      keys.forEach((key) => {
        style.setPaintProperty(layerId, key, args[1][key])
      })
      // 触发更新
      if (mapboxMap._update) {
        mapboxMap._update(true)
      }
      break
    }
    case 'setLayoutProperties': {
      const style = mapboxMap.style
      const args = layerUpdateCotent.params
      // 解析layout style 此参数键值对
      const keys = Object.keys(args[1])
      const layerId = args[0]
      keys.forEach((key) => {
        style.setLayoutProperty(layerId, key, args[1][key])
      })
      // 触发更新
      if (mapboxMap._update) {
        mapboxMap._update(true)
      }
      break
    }
    case 'setStyleLayer': {
      mapboxMap.setStyle(layer.style)
      break
    }
    case 'deleteStyleLayer': {
      mapboxMap.setStyle(layer.style)
      break
    }
    case 'setStyleLayerFilter': {
      const args = layerUpdateCotent.params
      mapboxMap.setFilter(args[0], args[1])
      break
    }
    case 'setStyleLayerZoomRange': {
      const args = layerUpdateCotent.params
      mapboxMap.setLayerZoomRange(args[0], args[1], args[2])
      break
    }
    case 'opacity': {
      const args = layerUpdateCotent.params
      // 解析layout style 此参数键值对
      const opacity = args[0]
      setLayerOpacity(mapboxMap, opacity)
      // 触发更新
      if (mapboxMap._update) {
        mapboxMap._update(true)
      }
      break
    }
    case 'visible': {
      const style = mapboxMap.style
      const args = layerUpdateCotent.params
      // 解析layout style 此参数键值对
      const visible = args[0]
      setLayerVisible(layer, style, visible)
      // 触发更新
      if (mapboxMap._update) {
        mapboxMap._update(true)
      }
      break
    }
    case 'clippingArea': {
      const args = layerUpdateCotent.params
      // 解析layout style 此参数键值对
      const clippingArea = args[0]
      innerLayer.setClippingArea(
        LeafletPlugin.convertClippingArea(clippingArea)
      )
      break
    }
    default: {
      break
    }
  }
}

function applyVectorTileStyle(mapboxMap, layerUpdateCotent, layer, innerLayer) {
  if (layerUpdateCotent) {
    if (mapboxMap._loaded) {
      processStyle(mapboxMap, layerUpdateCotent, layer, innerLayer)
    } else {
      mapboxMap.once('load', () => {
        processStyle(mapboxMap, layerUpdateCotent, layer, innerLayer)
      })
    }
  }
}
class ArcGISVectorTileLayerView extends LayerView {
  /**
   * 添加图层视图
   * @param {LayerEvent} 图层事件
   * @return {Promise<LayerView>} 图层视图
   */
  onAdd(event) {
    const layer = this.layer
    const innerView = this.innerView
    const _options = {
      style: JSON.parse(JSON.stringify(layer.style)),
      noWrap: true,
      // 初始化裁剪区
      clippingArea: LeafletPlugin.convertClippingArea(layer.clippingArea)
    }

    if (layer.tokenValue) {
      _options.accessToken = layer.tokenValue
    }

    let mapboxgl
    if (typeof module === 'object') {
      // eslint-disable-next-line global-require
      mapboxgl = require('@mapgis/mapbox-gl')
    } else {
      mapboxgl = window.mapboxgl
    }
    // 定义自定义坐标系
    mapboxCustomCRS(mapboxgl, proj4)
    // 构建L.mapboxGL图层
    leafletMapbox(L, mapboxgl)
    // 必须设置innerLayer
    this.innerLayer = L.mapboxGL(_options).addTo(innerView)
    this.innerLayer.commonLayerId = layer.id
    const mapboxMap = this.innerLayer.getMapboxMap()
    mapboxMap.once('load', () => {
      // 初始化透明度和显示隐藏
      setLayerVisible(layer, mapboxMap.style, layer._visible)
      setLayerOpacity(mapboxMap, layer._opacity)
      // 触发更新
      if (mapboxMap._update) {
        mapboxMap._update(true)
      }
    })

    return Promise.resolve(this)
  }

  /**
   * 移除图层视图
   * @param {LayerEvent} 图层事件
   * @return {Promise<LayerView>} 图层视图
   */
  onRemove(event) {
    this.innerView.removeLayer(this.innerLayer)
    return Promise.resolve(this)
  }

  /**
   * 更新图层视图
   * @param {LayerViewUpdateEvent} 图层事件
   * @return {Promise<LayerView>} 图层视图
   */
  onUpdate(event) {
    const _layer = this.innerLayer
    const layer = this.layer
    // 更新样式
    if (event.updateContent && _layer && _layer.getMapboxMap) {
      const mapboxMap = _layer.getMapboxMap()
      event.updateContent.forEach((layerUpdateCotent) => {
        applyVectorTileStyle(mapboxMap, layerUpdateCotent, layer, _layer)
      })
    }
    return Promise.resolve(this)
  }
}
export default ArcGISVectorTileLayerView
构造函数
成员变量
方法
事件