    import { LayerEvent, Event, Evented, Collection, Projection } from '../base'
    import { Log, defaultValue } from '../util'
    import { LayerEventType, LayerType, MapEventType } from '../base/enum'
    import { Layer, TileInfoUtil } from '../document/layer'
    import LayerView from './LayerView'
    import { Extent, Point, SpatialReference } from '../base/geometry'
    import Map from '../document/mapCollection/Map'

    /**
     * 视图类
     * @class BaseView
     * @extends Event
     * @moduleEX ViewModule
     * @param {Object} options 构造参数
     * @param {Map}  [options.map = '']  图层管理器
     * @param {String} [options.viewId = ''] 图层容器ID
     */

    /**
     * @event BaseView#地图视图加载完毕事件
     * @property {Object} event 事件对象
     * @example <caption><h7>地图视图加载完毕事件</h7></caption>
     * view.on('loaded', (event) => {
     *   console.log("点击事件:", event)
     * })
     */

    /**
     * @event BaseView#鼠标点击事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'click'] 事件类型
     * @property {Object} [event.mapPoint] 鼠标在地图上的经纬度位置
     * @property {Object} [event.x] 鼠标的像素x坐标，单位px
     * @property {Object} [event.y] 鼠标的像素y坐标，单位px
     * @property {Number} [event.button]
     * @property {Number} [event.buttons]
     * @property {Function} [event.stopPropagation] 阻止事件捕获或冒泡
     * @property {Object} [event.timeStamp] 时间戳，单位ms
     * @property {Object} [event.native] 事件对象
     * @property {BaseView} [event.sourceTarget] 事件发起对象
     * @property {Map} [event.target] 事件接收对象
     * @example <caption><h7>鼠标点击事件</h7></caption>
     * view.on('click', (event) => {
     *   console.log("点击事件:", event)
     * })
     */

    /**
     * @event BaseView#鼠标点击事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'immediate-click'] 事件类型
     * @property {Object} [event.mapPoint] 鼠标在地图上的经纬度位置
     * @property {Object} [event.x] 鼠标的像素x坐标，单位px
     * @property {Object} [event.y] 鼠标的像素y坐标，单位px
     * @property {Number} [event.button]
     * @property {Number} [event.buttons]
     * @property {Function} [event.stopPropagation] 阻止事件捕获或冒泡
     * @property {Object} [event.timeStamp] 时间戳，单位ms
     * @property {Object} [event.native] 事件对象
     * @property {BaseView} [event.sourceTarget] 事件发起对象
     * @property {Map} [event.target] 事件接收对象
     * @example <caption><h7>鼠标立即点击事件</h7></caption>
     * view.on('immediate-click', (event) => {
     *   console.log("点击事件:", event)
     * })
     */

    /**
     * @event BaseView#鼠标双击事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'double-click'] 事件类型
     * @property {Object} [event.mapPoint] 鼠标在地图上的经纬度位置
     * @property {Object} [event.longitude] 鼠标的经度坐标，单位度
     * @property {Object} [event.latitude] 鼠标的纬度坐标，单位度
     * @property {Object} [event.x] 鼠标的像素x坐标，单位px
     * @property {Object} [event.y] 鼠标的像素y坐标，单位px
     * @property {Object} [event.timeStamp] 时间戳，单位ms
     * @property {BaseView} [event.sourceTarget] 事件发起对象
     * @property {Map} [event.target] 事件接收对象
     * @property {Object} [event.event] 事件对象
     * @example <caption><h7>鼠标双击事件</h7></caption>
     * view.on('double-click', (event) => {
     *   console.log("双击事件:", event)
     * })
     */

    /**
     * @event BaseView#鼠标按下事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'pointer-down'] 事件类型
     * @property {Object} [event.mapPoint] 鼠标在地图上的经纬度位置
     * @property {Object} [event.longitude] 鼠标的经度坐标，单位度
     * @property {Object} [event.latitude] 鼠标的纬度坐标，单位度
     * @property {Object} [event.x] 鼠标的像素x坐标，单位px
     * @property {Object} [event.y] 鼠标的像素y坐标，单位px
     * @property {Object} [event.timeStamp] 时间戳，单位ms
     * @property {BaseView} [event.sourceTarget] 事件发起对象
     * @property {Map} [event.target] 事件接收对象
     * @property {Object} [event.event] 事件对象
     * @example <caption><h7>鼠标按下事件</h7></caption>
     * view.on('pointer-down', (event) => {
     *   console.log("鼠标按下事件:", event)
     * })
     */

    /**
     * @event BaseView#鼠标抬起事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'pointer-up'] 事件类型
     * @property {Object} [event.mapPoint] 鼠标在地图上的经纬度位置
     * @property {Object} [event.longitude] 鼠标的经度坐标，单位度
     * @property {Object} [event.latitude] 鼠标的纬度坐标，单位度
     * @property {Object} [event.x] 鼠标的像素x坐标，单位px
     * @property {Object} [event.y] 鼠标的像素y坐标，单位px
     * @property {Object} [event.timeStamp] 时间戳，单位ms
     * @property {BaseView} [event.sourceTarget] 事件发起对象
     * @property {Map} [event.target] 事件接收对象
     * @property {Object} [event.event] 事件对象
     * @example <caption><h7>鼠标抬起事件</h7></caption>
     * view.on('pointer-up', (event) => {
     *   console.log("鼠标抬起事件:", event)
     * })
     */

    /**
     * @event BaseView#鼠标移动事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'pointer-move'] 事件类型
     * @property {Object} [event.mapPoint] 鼠标在地图上的经纬度位置
     * @property {Object} [event.longitude] 鼠标的经度坐标，单位度
     * @property {Object} [event.latitude] 鼠标的纬度坐标，单位度
     * @property {Object} [event.x] 鼠标的像素x坐标，单位px
     * @property {Object} [event.y] 鼠标的像素y坐标，单位px
     * @property {Object} [event.timeStamp] 时间戳，单位ms
     * @property {BaseView} [event.sourceTarget] 事件发起对象
     * @property {Map} [event.target] 事件接收对象
     * @property {Object} [event.event] 事件对象
     * @example <caption><h7>鼠标移动事件</h7></caption>
     * view.on('pointer-move', (event) => {
     *   console.log("鼠标移动事件:", event)
     * })
     */

    /**
     * @event BaseView#鼠标拖拽事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'drag'] 事件类型
     * @property {Object} [event.x] 鼠标的像素x坐标，单位px
     * @property {Object} [event.y] 鼠标的像素y坐标，单位px
     * @property {Number} [event.button]
     * @property {Number} [event.buttons]
     * @property {Boolean} [event.cancelable]
     * @property {Object} [event.origin] 拖拽起点
     * @property {Function} [event.stopPropagation] 阻止事件捕获或冒泡
     * @property {Object} [event.timeStamp] 时间戳，单位ms
     * @property {Object} [event.native] 事件对象
     * @property {String} [event.action] 拖拽状态
     * @property {String} [event.type] 事件类型
     * @example <caption><h7>鼠标拖拽事件</h7></caption>
     * view.on('drag', (event) => {
     *   console.log("鼠标拖拽事件:", event)
     * })
     */

    /**
     * @event BaseView#地图大小变化事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'resize'] 事件类型
     * @property {Number} [event.oldWidth] 变化前的视图宽度，单位px
     * @property {Number} [event.oldHeight] 变化前的视图高度，单位px
     * @property {Number} [event.width] 变化后的视图高度，单位px
     * @property {Number} [event.height] 变化后的视图高度，单位px
     * @property {BaseView} [event.sourceTarget] 事件发起对象
     * @property {Map} [event.target] 事件接收对象
     * @property {Object} [event.event] 事件对象
     * @example <caption><h7>地图大小变化事件</h7></caption>
     * view.on('resize', (event) => {
     *   console.log("地图大小变化事件:", event)
     * })
     */

    /**
     * @event BaseView#键盘按下事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'key-down'] 事件类型
     * @property {String} [event.key] 变化后的视图高度，单位px
     * @property {Number} [event.timeStamp] 时间戳，单位ms
     * @property {BaseView} [event.sourceTarget] 事件发起对象
     * @property {Map} [event.target] 事件接收对象
     * @property {Object} [event.event] 事件对象
     * @example <caption><h7>键盘按下事件</h7></caption>
     * view.on('key-down', (event) => {
     *   console.log("键盘按下事件:", event)
     * })
     */

    /**
     * @event BaseView#键盘抬起事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'key-up'] 事件类型
     * @property {String} [event.key] 变化后的视图高度，单位px
     * @property {Number} [event.timeStamp] 时间戳，单位ms
     * @property {BaseView} [event.sourceTarget] 事件发起对象
     * @property {Map} [event.target] 事件接收对象
     * @property {Object} [event.event] 事件对象
     * @example <caption><h7>键盘抬起事件</h7></caption>
     * view.on('key-up', (event) => {
     *   console.log("键盘抬起事件:", event)
     * })
     */

    /**
     * @event BaseView#地图视图改变事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'view-change'] 事件类型
     * @property {BaseView} [event.target] 事件接收对象
     * @property {BaseView} [event.mapView] 事件地图视图对象
     * @property {Number} [event.scale] 事件地图比例尺
     * @property {Number} [event.zoom] 事件地图层级
     * @property {Point} [event.center] 事件地图视图中心
     * @example <caption><h7>地图视野改变事件</h7></caption>
     * view.on('view-change', (event) => {
     *   console.log("地图视图改变事件:", event)
     * })
     */

    /**
     * @event BaseView#视图图层创建事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'layerview-created'] 事件类型
     * @property {Layer} [event.layer] 事件接收对象
     * @property {LayerView} [event.layerView] 事件地图视图中心
     * @property {BaseView} [event.view] 事件地图视图对象
     * @example <caption><h7>视图图层创建事件</h7></caption>
     * view.on('layerview-created', (event) => {
     *   console.log("添加地图图层事件:", event)
     * })
     */

    /**
     * @event BaseView#视图图层移除事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'layerview-remove'] 事件类型
     * @property {Layer} [event.layer] 事件接收对象
     * @property {LayerView} [event.layerView] 事件地图视图中心
     * @property {BaseView} [event.view] 事件地图视图对象
     * @example <caption><h7>视图图层移除事件</h7></caption>
     * view.on('layerview-remove', (event) => {
     *   console.log("销毁地图图层事件:", event)
     * })
     */

    /**
     * @event BaseView#视图图层创建错误事件
     * @property {Object} event 事件对象
     * @property {LayerEventType} [event.type = 'layerview-created-error'] 事件类型
     * @property {Layer} [event.layer] 事件接收对象
     * @property {BaseView} [event.view] 事件地图视图对象
     * @property {String} [event.error] 错误消息
     * @example <caption><h7>视图图层创建错误事件</h7></caption>
     * view.on('layerview-created-error', (event) => {
     *   console.log("添加地图图层事件:", event)
     * })
     */
    class BaseView extends Evented {
      constructor(options) {
        super()
        options = defaultValue(options, {})
        // 地图对象
        this._map = null
        /**
         * 鼠标样式，参考css的cursor样式
         * @member {String} BaseView.prototype.cursor
         */
        this.cursor = defaultValue(options.cursor, undefined)
        /**
         * 地图视图的比例尺，改变该值后会立刻改变视图范围
         * @member {Number} BaseView.prototype.scale
         */
        this.scale = defaultValue(options.scale, undefined)
        /**
         * 最小缩放比例尺
         * @member {Number} BaseView.prototype.minScale
         */
        this.minScale = undefined
        /**
         * 最大缩放比例尺
         * @member {Number} BaseView.prototype.maxScale
         */
        this.maxScale = undefined
        /**
         * 视图旋转角度
         * @member {Number} BaseView.prototype.rotation
         */
        this.rotation = 0
        /**
         * 视图中心点
         * @member {Array} BaseView.prototype.center
         */
        this.center = defaultValue(options.center, [0, 0])
        /**
         * 最小缩放级数
         * @member {Number} BaseView.prototype.minZoom
         */
        this.minZoom = defaultValue(options.minZoom, 0)
        /**
         * 最大缩放级数
         * @member {Number} BaseView.prototype.maxZoom
         */
        this.maxZoom = defaultValue(options.maxZoom, 19)
        /**
         * 初始化级数
         * @member {Number} BaseView.prototype.zoom
         */
        this.zoom = defaultValue(options.zoom, 1)
        /**
         * 弹窗设置
         * @member {Object} BaseView.prototype.popup
         */
        this.popup = undefined
        /**
         * 视图是否静止
         * @readonly
         * @member {Boolean} BaseView.prototype.stationary
         */
        this.stationary = true
        /**
         * 视图空间参考系
         * @readonly
         * @member {SpatialReference} BaseView.prototype._spatialReference
         */
        this._spatialReference = new SpatialReference('EPSG:4326')
        // 图层管理器传递事件处理
        this._initMapEventHandlers()
        // 添加图层管理模块
        this.setMap(options.map)
        // 图层容器ID
        this._viewId = defaultValue(options.viewId, '')
        // 视图容器
        this._mapCollection = []
        // 引擎视图
        this._innerView = null
        this.graphics = new Collection()
        // 设置鼠标样式
        this._initCursor()
      }

      /**
       * 添加图层管理容器
       * @param {Map} map 图层管理容器
       * */
      setMap(map) {
        if (!this._map) {
          // 设置图层管理器
          this._map = map instanceof Map ? map : Map.fromJSON(map)
          // 初始化 图层管理器-> 视图 事件
          this._linkMapEvent()
          // 初始化 图层 -> 图层管理器 -> 视图 事件
          this._linkLayerEvent()
          if (this._innerView) {
            this._map._haveInnerView = true
          } else {
            this._map._haveInnerView = false
          }
          // 加载图层
          this._map._loadLayers()
          // 加载basemap图层
          this._map._loadBasemap()
        }
      }

      /**
       * @description 链接图层Layer事件
       */
      _linkLayerEvent() {
        if (this._map) {
          for (const eventStr in LayerEventType) {
            const self = this
            this._map.on(
              LayerEventType[eventStr],
              function (event) {
                const data = event
                // 扩展事件属性
                if (data instanceof Event) {
                  data.addProperty('view', self)
                } else if (data) {
                  data.view = self
                }
                self.fire(LayerEventType[eventStr], data)
              },
              this._map
            )
          }
        }
      }

      /**
       * @description 链接图层管理器Map事件
       */
      _linkMapEvent() {
        if (this._map) {
          for (const eventStr in MapEventType) {
            const self = this
            this._map.on(MapEventType[eventStr], function (event) {
              const data = event
              // 扩展事件属性
              if (data instanceof Event) {
                data.addProperty('view', self)
              } else if (data) {
                data.view = self
              }
              self.fire(MapEventType[eventStr], data)
            })
          }
        }
      }

      /**
       * @description 获取引擎视图对象,在leaflet引擎上返回leafelt map,在cesium引擎上返回cesium viewer
       * @return {Object}
       */
      getInnerView() {
        return this._innerView
      }

      /**
       * @description 初始化图层管理器事件handler
       */
      _initMapEventHandlers() {
        this._processEvent = this._processEvent.bind(this)
        this.on(MapEventType.layerAdd, this._processEvent)
        this.on(MapEventType.layerRemove, this._processEvent)
        // this.on(LayerEventType.featureAdd, this._processEvent)
        this.on(LayerEventType.layerUpdate, this._processEvent)
        this.on(MapEventType.layerRemoveMany, this._processEvent)
        this.on(MapEventType.layerRemoveAll, this._processEvent)
        // this.on(MapEventType.baseLayerAdd, this._processEvent)
      }

      /**
       * @description 事件处理器
       */
      _processEvent(event) {
        // 地图文档Map事件处理
        // 1.图层的增删操作等/地图状态变化操作等
        if (event.type === MapEventType.layerAdd) {
          if (event.layer instanceof Layer) {
            this._addLayerView(event.layer, event)
          }
        }

        if (event.type === MapEventType.layerRemove) {
          if (event.layer instanceof Layer) {
            this._removeLayerView(event.layer, event)
          }
        }
        // 图层事件处理
        // 2.图层的更新
        if (event.type === LayerEventType.layerUpdate) {
          if (event.layer instanceof Layer) {
            this._updateLayerView(event.layer, event)
          }
        }
        // if (event.type === MapEventType.baseLayerAdd) {
        //   if (event.layer instanceof Layer) {
        //     this._addLayerView(event.layer, event)
        //   }
        // }
      }

      /**
       * @description 添加图层视图
       * @private
       */
      _addLayerView(layer, event) {
        const self = this
        layer.load().then(
          (result) => {
            // 图层信息获取完毕，根据图层的参考系，设置view空间参考系
            // 如果view空间参考系和该图层参考系不同，则初始化引擎view。相同则不做改变
            // 如果加载图层是basemap的图层，则在basemap上获取坐标系
            if (layer._isBasemapLayer) {
              self._map.basemap.setSpatialReference()
            }
            this._loadedLayer = layer
            if (self._setSpatialReference) {
              self._setSpatialReference(layer)
            }
            this._loadedLayer = undefined
            // 没有参考系或者 || result._isSRLayer
            if (!self._spatialReference) return
            const loadedEvent = new LayerEvent({
              type: LayerEventType.layerLoaded,
              target: result,
              message: '图层资源加载完毕',
              layer: result
            })

            // 发送图层创建失败事件
            function fireCreatedError(err) {
              const data = new LayerEvent({
                type: LayerEventType.layerViewCreatedError,
                target: result,
                error: err || '图层在视图中创建失败',
                layer: result
              })
              data.addProperty('view', self)
              data.addProperty('layerView', null)
              self.dispatchEvent(LayerEventType.layerViewCreatedError, data)
              Log.error(err)
            }

            // 发送load事件
            self.dispatchEvent(LayerEventType.layerLoaded, loadedEvent)
            // 添加图层
            if (!result) {
              Log.error('图层加载失败,请检查数据服务是否正常')
            }
            // 添加图层到所有图层中
            self._map.allLayers.add(layer)
            // 有子图层获取子图层
            if (
              layer.type === LayerType.igsMapImage ||
              layer.type === LayerType.wms ||
              layer.type === LayerType.arcgisMapImage ||
              layer.type === LayerType.igsVectorTile
            ) {
              layer.allSublayers.forEach(function (sublayer) {
                self._map.allLayers.add(sublayer)
              })
            } else if (layer.type === LayerType.scene) {
              for (let i = 0; i < layer.scenes.length; i++) {
                for (let j = 0; j < layer.scenes[i].sublayers.length; j++) {
                  self._map.allLayers.add(layer.scenes[i].sublayers[j])
                }
              }
            }
            self._waitLayerLoaded(layer, result, fireCreatedError)
          },
          (message) => {
            // 请求失败信息
            this.dispatchEvent(
              LayerEventType.layerLoadError,
              new LayerEvent({
                type: LayerEventType.layerLoadError,
                target: layer,
                message: message || '图层资源加载失败，请检查网络状态或服务器状态'
              })
            )
          }
        )
      }

      _getFlyToCenter(options) {
        // 获取center
        let center = undefined
        if (options.center) {
          if (Array.isArray(options.center) && options.center.length > 1) {
            const coordinates =
              options.center.length > 2
                ? [options.center[0], options.center[1], options.center[2]]
                : [options.center[0], options.center[1]]
            const code =
              this._innerView.options && this._innerView.options.crs
                ? this._innerView.options.crs.code
                : 'EPSG:4326'
            center = new Point({
              coordinates,
              spatialReference: new SpatialReference(code)
            })
          } else if (options.center instanceof Point) {
            center = Point.fromJSON(options.center)
          } else if (!(options.center instanceof Point)) {
            Log.error('center类型为不支持的类型!')
          }
          if (!center.spatialReference.isGeographic) {
            center = Projection.project(
              center,
              new SpatialReference({
                wkid: 4326
              })
            )
          }
        }

        return center
      }

      _getFlyToExtent(options) {
        // 获取extent
        let extent = undefined
        if (options.extent) {
          if (options.extent instanceof Extent) {
            extent = Extent.fromJSON(options.extent)
            if (!extent.spatialReference.isGeographic) {
              extent = Projection.project(
                extent,
                new SpatialReference({
                  wkid: 4326
                })
              )
            }
          } else {
            Log.error('extent类型为不支持的类型!')
          }
        }
        return extent
      }

      /**
       * 等待图层加载完毕，可有BaseView的子类重写
       * @param {Layer} layer 基础图层对象
       * @param {Object} result 图层加载完毕后的对象
       * @param {Function} fireCreatedError 创建失败回调
       * */
      _waitLayerLoaded(layer, result, fireCreatedError) {
        const self = this
        const promise = self._addLayer(result, event)
        self._layerLoaded(promise, layer, result, fireCreatedError)
      }

      /**
       * 图层加载完毕后做的事情
       * @private
       * @param {Promise} promise Promise对象
       * @param {Layer} layer 基础图层对象
       * @param {Object} result 图层加载完毕后的对象
       * @param {Function} fireCreatedError 创建失败回调
       * */
      _layerLoaded(promise, layer, result, fireCreatedError) {
        const self = this
        // 视频调绘的视频图层在_addLayer后不会返回一个Promise
        if (!promise) {
          return
        }
        promise
          .then((layerView) => {
            Log.info('创建图层', layer)
            // // 如果加载图层是basemap的图层，则在basemap上获取坐标系
            // if (layer._isBasemapLayer) {
            //   self._map.basemap.setSpatialReference()
            //   self._setSpatialReference()
            // }
            const data = new LayerEvent({
              type: LayerEventType.layerViewCreated,
              message: '图层在视图中创建完毕',
              layer: result
            })
            data.addProperty('view', self)
            data.addProperty('layerView', layerView)
            self.dispatchEvent(LayerEventType.layerViewCreated, data)
            // if (self._map.basemap && layer._isBasemapLayer) {
            //   self._map.basemap.fire(LayerEventType.layerViewCreated, data)
            //   // self._map.basemap.dispatchEvent(LayerEventType.layerViewCreated, data)
            // }
          })
          .catch((err) => {
            fireCreatedError(err)
          })
      }

      /**
       * @description 添加图层(在视图中创建成功后返回promise，创建失败返回null)
       * @private
       * @param {Layer} layer
       * @return {Promise<LayerView>|null}
       */
      _addLayer(layer, event) {
        const layerView = this._createLayerView(layer, event)
        if (layerView instanceof LayerView) {
          // layerView添加
          return layerView.onAdd(event).then(() => {
            // 在图层视图加载到引擎内后,加入视图队列
            this._mapCollection.push(layerView)
            // 保证返回的是图层视图
            return layerView
          })
        }
        Log.info('图层视图创建失败,未定义该类型的图层视图!')
        // 添加失败
        return null
      }

      /**
       * @description 移除图层视图
       * @private
       */
      _removeLayerView(layer, event) {
        const self = this
        const promise = this._removeLayer(layer, event)
        if (promise) {
          promise.then((layerView) => {
            Log.info('删除图层', layer)
            const data = new LayerEvent({
              type: LayerEventType.layerViewRemove,
              message: '删除图层',
              layer
            })
            data.addProperty('view', self)
            data.addProperty('layerView', layerView)
            self.dispatchEvent(LayerEventType.layerViewRemove, data)
          })
        }
      }

      /**
       * @description 删除图层(在视图中删除成功后返回promise，删除失败返回null)
       * @private
       * @param {Layer} layer 待删除图层
       * @return {Promise|null}
       */
      _removeLayer(layer, event) {
        const layerView = this._findLayerById(layer.id)
        if (layerView instanceof LayerView) {
          // layerView添加
          return layerView.onRemove(event).then(() => {
            // 引擎内在移除图层视图后,删除队列中图层视图
            this._removeLayerById(layer.id)
            // 保证返回的是图层视图
            return layerView
          })
        }
        Log.info('图层删除失败,未找到该类型的视图!')
        return null
      }

      /**
       * @description 更新图层视图
       */
      _updateLayerView(layer, event) {
        const promise = this._updateLayer(layer, event)
        if (promise) {
          promise.then((layerView) => {
            Log.info('更新图层', layer)
            if (event) {
              event.addProperty('view', self)
              event.addProperty('layerView', layerView)
            }
            this.dispatchEvent(LayerEventType.layerViewUpdate, event)
          })
        }
      }

      /**
       * @description 更新图层(在视图中更新成功后返回promise，更新失败返回null)
       * @private
       * @param {Layer} layer 带更新图层
       * @param {LayerViewUpdateEvent} event 图层视图更新事件
       * @return {Promise|null}
       */
      _updateLayer(layer, event) {
        const layerView = this._findLayerById(layer.id)
        if (layerView instanceof LayerView) {
          // layerView添加
          return layerView.onUpdate(event)
        }
        Log.info('图层更新失败,未找到该类型的视图!')
        return null
      }

      /**
       * @description 事件触发器
       */
      dispatchEvent(type, data, propagate) {
        // 传递给图层
        if (data instanceof LayerEvent && data.layer) {
          data.layer.fire(type, data, propagate)
        }

        // 传递给图层管理器和图层容器
        if (this._map) {
          this._map.dispatchEvent(type, data, propagate)
        }

        if (
          this._map &&
          this._map.basemap &&
          data.layer &&
          data.layer._isBasemapLayer
        ) {
          this._map.basemap.fire(LayerEventType.layerViewCreated, data)
        }

        return this
      }

      _findLayerById(id) {
        let _layer
        for (let i = 0; i < this._mapCollection.length; i++) {
          // 如果是组图层，则遍历子图层的layerview
          if (this._mapCollection[i].layer.type === LayerType.group) {
            const layerViews = this._mapCollection[i].layerViews
            for (let j = 0; j < layerViews.length; j++) {
              if (layerViews[j].id === id) {
                _layer = layerViews[j]
                break
              }
            }
          }
          // 非组图层逻辑
          else if (this._mapCollection[i].id === id) {
            _layer = this._mapCollection[i]
            break
          }
        }

        return _layer
      }

      _removeLayerById(id) {
        for (let i = 0; i < this._mapCollection.length; i++) {
          if (this._mapCollection[i].id === id) {
            this._mapCollection.splice(i, 1)
            break
          }
        }
      }

      _findLayerIndex(id) {
        let _index
        for (let i = 0; i < this._mapCollection.length; i++) {
          if (this._mapCollection[i].id === id) {
            _index = i
            break
          }
        }
        return _index
      }

      /* *********************************     基类需要实现的方法      ************************************* */
      /**
       * @description 创建图层视图
       * @private
       * @param {Layer} layer 图层
       * @param {LayerEvent} event 添加事件
       * @return {LayerView| null}
       */
      _createLayerView(layer) {
        return null
      }

      /**
       * @description 初始化鼠标样式
       * @private
       */
      _initCursor() {
        this._setCursor(this.cursor)
        Object.defineProperty(this, 'cursor', {
          set(newVal) {
            this._setCursor(newVal)
          }
        })
      }

      /**
       * @description 设置鼠标样式
       * @param {String}  type 鼠标样式名
       * @private
       */
      _setCursor(type) {
        if (type) {
          this._innerView._container.style.cursor = type
        }
      }

      /**
       * 根据基础图层对象或者图层id查询并返回实际图层，如果是场景图层，则会返回一个数组对象
       * @param {Object | String} layer 基础图层对象或者图层id
       * @return {Object} 实际图层对象
       * @example <caption><h7>根据基础图层对象或者图层id查询并返回实际图层</h7></caption>
       * // ES5引入方式
       * const { Map, SceneView } = Zondy
       * const { IGSSceneLayer } = Zondy.Layer
       * // ES6引入方式
       * import { Map, SceneView, IGSSceneLayer } from "@@mapgis/webclient-cesium-plugin"
       * // 初始化图层管理容器
       * const map = new Map();
       * // 初始化地图视图对象
       * const sceneView = new SceneView({
       *   // 视图id
       *   viewId: "mapgis-3d-viewer",
       *   // 图层管理容器
       *   map: map
       * });
       * // 添加一个场景图层
       * const igsSceneLayer = new IGSSceneLayer({
       *   url: 'http://192.168.82.89:8089/igs/rest/g3d/Scene:DaYanTa-M3D'
       * });
       * map.add(igsSceneLayer);
       * // 添加完毕后，过去实际图层对象
       * igsSceneLayer.on("layerview-created", function (result) {
       *   console.log("加载完毕:", result.layer)
       *   const innerLayer = sceneView.getInnerLayer(igsSceneLayer)
       *   console.log("innerLayer:", innerLayer)
       * })
       * */
      getInnerLayer(layer) {
        let innerLayer = undefined
        for (let i = 0; i < this._mapCollection.length; i++) {
          if (typeof layer === 'string') {
            if (this._mapCollection[i].layer.id === layer) {
              innerLayer = this._mapCollection[i].innerLayer
              break
            }
          } else if (layer instanceof Object) {
            if (this._mapCollection[i].layer.id === layer.id) {
              innerLayer = this._mapCollection[i].innerLayer
              break
            }
          }
        }
        return innerLayer
      }

      _getLayerView(layer) {
        let layerView = undefined
        for (let i = 0; i < this._mapCollection.length; i++) {
          if (typeof layer === 'string') {
            if (this._mapCollection[i].layer.id === layer) {
              layerView = this._mapCollection[i]
              break
            }
          } else if (layer instanceof Object) {
            if (this._mapCollection[i].layer.id === layer.id) {
              layerView = this._mapCollection[i]
              break
            }
          }
        }
        return layerView
      }

      /**
       * 根据基础图层id查询并返回基础图层对象
       * @param {String} layerId 基础图层ID
       * @return {Layer} 基础图层对象
       * */
      getLayer(layerId) {
        let layer = undefined
        for (let i = 0; i < this._mapCollection.length; i++) {
          if (this._mapCollection[i].layer.id === layerId) {
            layer = this._mapCollection[i].layer
            break
          }
        }
        return layer
      }
    }

    Object.defineProperties(BaseView.prototype, {
      /**
       * 地图管理容器对象
       * @member {Map} BaseView.prototype.map
       * */
      map: {
        get() {
          return this._map
        },
        set(value) {
          this._map = value
        }
      }
    })

    export default BaseView