    import { Zondy, Evented, Collection, LayerEvent } from '../../base'
    import { LayerType, MapEventType } from '../../base/enum'
    import { Layer, SubLayer } from '../layer/baseLayer'
    import { cloneObject, defaultValue, isNull, toJSON } from '../../util'
    import {
      IGSMapImageLayer,
      WMSLayer,
      IGSTileLayer,
      WMTSLayer,
      IGSFeatureLayer,
      GeoJSONLayer,
      WFSLayer,
      GraphicsLayer,
      IGSVectorTileLayer,
      M3DModelCacheLayer,
      Cesium3DTilesCacheLayer,
      IGSSceneLayer,
      TerrainCacheLayer
    } from '../layer'

    /**
     * 图层管理容器，和地图引擎无关，通过此对象而不是地图引擎来对图层进行管理
     * <br>[ES5引入方式]：<br/>
     * Zondy.Map() <br/>
     * [ES6引入方式]：<br/>
     * import { Map } from "@mapgis/webclient-common" <br/>
     * @class Map
     * @moduleEX MapModule
     * @extends Evented
     * @fires Map#添加图层事件
     * @fires Map#添加多个图层事件
     * @fires Map#删除图层事件
     * @fires Map#移除多个图层事件
     * @fires Map#移除所有图层事件
     * @param {Object} options 构造参数
     * @param {Basemap}  [options.basemap] 设置地图视图中的底图；<br/>
     * 1、如果底图存在，则会使用底图上的参考系作为地图视图的参考系，如果没有，则使用常规图层上的坐标系;<br/>
     * 2、底图图层在常规图层的最下面；
     * 3、除GraphicsLayer外的二维地图都可以作为底图<br/>
     *
     * @summary <h5>支持如下方法：</h5>
     * <a href='#add'>[1、添加图层对象]</a><br/>
     * <a href='#addMany'>[2、添加多个图层]</a><br/>
     * <a href='#findLayerById'>[3、根据id查询图层]</a><br/>
     * <a href='#remove'>[4、删除指定图层]</a><br/>
     * <a href='#removeMany'>[5、移除多个图层]</a><br/>
     * <a href='#removeAll'>[6、删除所有图层]</a><br/>
     * <a href='#reorder'>[7、调整图层顺序]</a><br/>
     * <a href='#destroy'>[8、销毁Map对象]</a><br/>
     * <a href='#fromJSON'>[9、通过json对象构造并返回一个新的Map对象]</a><br/>
     * <a href='#toJSON'>[10、转换为json对象]</a><br/>
     * <a href='#clone'>[11、克隆并返回一个新的Map对象]</a><br/>
     *
     * @example <caption><h7 id='valueExpression'>初始化Map对象</h7></caption>
     * // ES5引入方式
     * const { Map } = Zondy
     * // ES6引入方式
     * import { Map } from "@mapgis/webclient-common"
     * //创建Map对象
     * let map = new Map();
     *
     * @example <caption><h7 id='valueExpression'>添加底图图层</h7></caption>
     * // ES5引入方式
     * const { Map, Basemap, Collection } = Zondy
     * const { IGSTileLayer } = Zondy.Layer
     * // ES6引入方式
     * import { Map, Basemap, Collection, IGSTileLayer } from "@mapgis/webclient-common"
     * //创建Map对象
     * const map = new Map({
     *   // 初始化底图图层集合
     *   basemap: new Basemap({
     *     // 可以设置多个图层到底图集合中
     *     baseLayers: new Collection(
     *       [
     *         // 创建一个图层
     *         new IGSTileLayer({
     *           url: '服务及地址'
     *         })
     *       ]
     *     )
     *   })
     * });
     */

    /**
     * 添加图层事件
     * @event Map#添加图层事件
     * @property {Object} event 事件对象
     * @property {String} [event.type = 'layer-add'] 添加图层事件
     * @property {Layer} [event.layer = null] 被添加的图层对象
     * @property {View} [event.view = null] 地图视图对象
     * @property {Map} [event.sourceTarget = null] 事件发起对象
     * @property {View} [event.target = null] 事件接收对象
     * @example <caption><h5>添加图层事件</h5></caption>
     * map.on('layer-add', function (event) {
     *   // 添加图层事件
     *   console.log("添加图层事件:", event)
     * });
     */

    /**
     * 添加多个图层事件
     * @event Map#添加多个图层事件
     * @property {Object} event 事件对象
     * @property {String} [event.type = 'layer-add-many'] 添加多个图层事件
     * @property {Array<Layer>} [event.layers = []] 被添加的所有图层对象数组
     * @property {View} [event.view = null] 地图视图对象
     * @property {Map} [event.sourceTarget = null] 事件发起对象
     * @property {View} [event.target = null] 事件接收对象
     * @example <caption><h5>添加多个图层事件</h5></caption>
     * map.on('layer-add-many', function (event) {
     *   // 添加多个图层事件
     *   console.log("添加图层事件:", event)
     * });
     */

    /**
     * 删除图层事件
     * @event Map#删除图层事件
     * @property {Object} event 事件对象
     * @property {String} [event.type = 'layer-remove'] 删除图层事件
     * @property {Layer} [event.layer = null] 被删除的图层对象
     * @property {View} [event.view = null] 地图视图对象
     * @property {Map} [event.sourceTarget = null] 事件发起对象
     * @property {View} [event.target = null] 事件接收对象
     * @example <caption><h5>删除图层事件</h5></caption>
     * map.on('layer-remove', function (event) {
     *   // 删除图层事件
     *   console.log("删除图层事件:", event)
     * });
     */

    /**
     * 移除多个图层事件
     * @event Map#移除多个图层事件
     * @property {Object} event 事件对象
     * @property {String} [event.type = 'layer-remove-many'] 移除多个图层事件
     * @property {Array<Layer>} [event.layers = []] 被删除的所有图层对象数组
     * @property {View} [event.view = null] 地图视图对象
     * @property {Map} [event.sourceTarget = null] 事件发起对象
     * @property {View} [event.target = null] 事件接收对象
     * @example <caption><h5>移除多个图层事件</h5></caption>
     * map.on('layer-remove-many', function (event) {
     *   // 移除多个图层事件
     *   console.log("移除多个图层事件:", event)
     * });
     */

    /**
     * 移除所有图层事件
     * @event Map#移除所有图层事件
     * @property {Object} event 事件对象
     * @property {String} [event.type = 'layer-remove-all'] 移除所有图层事件
     * @property {View} [event.view = null] 地图视图对象
     * @property {Map} [event.sourceTarget = null] 事件发起对象
     * @property {View} [event.target = null] 事件接收对象
     * @example <caption><h5>移除所有图层事件</h5></caption>
     * map.on('layer-remove-all', function (event) {
     *   // 移除所有图层事件
     *   console.log("移除所有图层事件:", event)
     * });
     */
    class Map extends Evented {
      constructor(options) {
        options = defaultValue(options, {})
        super()
        /**
         * 图层管理容器中包含的子图层
         * @member {Collection} Map.prototype.layers
         */
        this.layers = new Collection()
        /**
         * 图层管理容器中所有的子图层，包括子图层的子图层，并穷举所有子图层
         * @member {Collection} Map.prototype.allLayers
         */
        this.allLayers = new Collection()
        /**
         * 基础地图
         * @member {Collection} Map.prototype.basemap
         */
        this._basemap = defaultValue(options.basemap, undefined)
        // 是否绑定Cesium
        this._initCesiumView = false
        // 是否绑定Leaflet
        this._initLeafletView = false
        // 是否删除全部图层
        this._isRemoveAll = false
        // 是否删除多个图层
        this._isRemoveMany = false
      }

      /**
       * 通过json对象构造并返回一个新的Map对象<a id='fromJSON'></a>
       * @param {Object} json json数据
       * @return {Map} 一个新的Map对象
       * */
      static fromJSON(json) {
        json = defaultValue(json, {})
        const layers = defaultValue(json.layers, [])

        const map = new Map()
        for (let i = 0; i < layers.length; i++) {
          let _layer
          switch (layers[i].type) {
            case LayerType.igsMapImage:
              _layer = IGSMapImageLayer.fromJSON(layers[i])
              break
            case LayerType.igsTile:
              _layer = IGSTileLayer.fromJSON(layers[i])
              break
            case LayerType.wms:
              _layer = WMSLayer.fromJSON(layers[i])
              break
            case LayerType.wmts:
              _layer = WMTSLayer.fromJSON(layers[i])
              break
            case LayerType.igsFeature:
              _layer = IGSFeatureLayer.fromJSON(layers[i])
              break
            case LayerType.geojson:
              _layer = GeoJSONLayer.fromJSON(layers[i])
              break
            case LayerType.wfs:
              _layer = WFSLayer.fromJSON(layers[i])
              break
            case LayerType.graphics:
              _layer = GraphicsLayer.fromJSON(layers[i])
              break
            case LayerType.igsVectorTile:
              _layer = IGSVectorTileLayer.fromJSON(layers[i])
              break
            case LayerType.m3dCache:
              _layer = M3DModelCacheLayer.fromJSON(layers[i])
              break
            case LayerType.cesium3DTiles:
              _layer = Cesium3DTilesCacheLayer.fromJSON(layers[i])
              break
            case LayerType.scene:
              _layer = IGSSceneLayer.fromJSON(layers[i])
              break
            case LayerType.terrain:
              _layer = TerrainCacheLayer.fromJSON(layers[i])
              break
            default:
              break
          }
          map.add(_layer)
        }

        return map
      }

      /**
       * 转换为json对象<a id='toJSON'></a>
       * @return {Object} 导出的json对象
       */
      toJSON() {
        const _json = {}
        _json.layers = []
        for (let i = 0; i < this.layers.items.length; i++) {
          _json.layers.push(toJSON(this.layers.items[i], Layer))
        }

        // 设置导出配置
        // 导出时间
        _json['exportTime'] = new Date().toISOString()

        return _json
      }

      /**
       * 克隆并返回一个新的Map对象<a id='clone'></a>
       * @return {Map} 一个新的Map对象
       */
      clone() {
        return cloneObject(this)
      }

      /**
       * 添加图层对象<a id='add'></a>
       * @param {Object} layer 要添加的图层对象
       * @example
       * //添加图层
       * map.add(layer);
       */
      add(layer) {
        if (layer) {
          // layer = Layer.fromJSON(layer.toJSON())
          if (this.findLayerById(layer.id)) {
            throw new Error(`id为'${layer.id}'的图层重复添加，请检查传入图层的id`)
          }
          if (!layer._isBasemapLayer) {
            this._setLayerIndex(layer)
          } else {
            this._setBasemapIndex(layer)
          }
          layer.setMap(this)
          this.layers.add(layer)
          this.dispatchEvent(MapEventType.layerAdd, {
            type: MapEventType.layerAdd,
            target: this,
            layer
          })
        }
      }

      // 设置basemap图层顺序
      _setBasemapIndex(baseLayer) {
        let maxBaseLayerIndex = null
        let minLayerIndex = null
        if (isNull(baseLayer.index)) {
          this.layers.forEach((layer) => {
            if (
              layer._isBasemapLayer &&
              (minLayerIndex === null || maxBaseLayerIndex < layer.index)
            ) {
              maxBaseLayerIndex = layer.index
            } else if (
              !layer._isBasemapLayer &&
              (minLayerIndex === null || minLayerIndex > layer.index)
            ) {
              minLayerIndex = layer.index
            }
          })
        }
        if (minLayerIndex !== null && baseLayer.index >= minLayerIndex) {
          throw new Error(`id为'${baseLayer.id}'的基础图层index不合法`)
        }
        if (minLayerIndex === null) {
          this._setLayerIndex(baseLayer)
        } else {
          if (maxBaseLayerIndex === null) {
            baseLayer.index = 0
          } else if (maxBaseLayerIndex < minLayerIndex) {
            baseLayer.index = maxBaseLayerIndex + 1
          } else {
            baseLayer.index = minLayerIndex
          }
          this.layers.forEach((layer) => {
            if (!layer._isBasemapLayer) {
              layer.index++
            }
          })
        }
      }

      _getSRLayer() {
        const layers = this.layers.all()
        let layer = undefined

        for (let i = 0; i < layers.length; i++) {
          if (layers[i]._isSRLayer) {
            layer = layers[i]
            break
          }
        }

        return layer
      }

      /**
       * 销毁Map对象<a id='destroy'></a>
       * @example
       * map.destroy()
       */
      destroy() {
        const layers = this.layers.all()
        for (let i = 0; i < layers.length; i++) {
          this.remove(layers[i])
        }
        this.layers = undefined
      }

      /**
       * 根据id查询图层<a id='findLayerById'></a>
       * @param {String} id 图层id
       * @return Object 找到的图层
       * @example
       * //根据id查询图层
       * map.findLayerById('图层id');
       */
      findLayerById(id) {
        const index = this.layers.findIndex((v) => v.id === id)
        if (index > -1) {
          return this.layers.get(index)
        }
        return undefined
      }

      /**
       * 删除指定图层，需要传入一个图层对象<a id='remove'></a>
       * @param {Object} layer 要删除的图层对象
       * @example
       * //删除指定图层
       * map.findLayerById(layer);
       */
      remove(layer) {
        // 如果是basemap上的baseLayer，则不受删除map上图层影响
        if (layer && layer._isBasemapLayer) {
          return
        }
        if (layer) {
          // todo 删除图层时将loaded置为false
          layer.loaded = false
          // end todo
          layer.destroy()
          this.layers.remove(layer)
          // 删除allLayers中的图层
          this.allLayers.remove(layer)
          // 删除关联的子图层
          let _allLayers = [].concat(this.allLayers.items)
          for (let i = 0; i < _allLayers.length; i++) {
            if (_allLayers[i] instanceof SubLayer) {
              const _parentLayer = _allLayers[i].layer
              if (_parentLayer && _parentLayer.id && _parentLayer.id === layer.id) {
                this.allLayers.remove(_allLayers[i])
              }
            }
          }
          _allLayers = undefined
          this.dispatchEvent(MapEventType.layerRemove, {
            type: MapEventType.layerRemove,
            target: this,
            layer
          })
        }
      }

      /**
       * 删除所有图层<a id='removeAll'></a>
       * @example
       * map.removeAll();
       */
      removeAll() {
        let _items = []
        this._isRemoveAll = true
        for (let i = 0; i < this.layers.items.length; i++) {
          _items.push(this.layers.items[i])
        }
        const self = this
        _items.forEach(function (layer) {
          self.remove(layer)
        })
        _items = undefined
        this.dispatchEvent(MapEventType.layerRemoveAll, {
          type: MapEventType.layerAdd,
          target: this
        })
        this._isRemoveAll = false
      }

      /**
       * 添加多个图层<a id='addMany'></a>
       * @param {Array} layers 要添加的图层数组
       * @example
       * map.addMany(layers);
       */
      addMany(layers) {
        if (!layers) return this
        let _isAdd = false
        if (layers instanceof Layer) {
          this.add(layers)
          _isAdd = true
        } else if (Array.isArray(layers)) {
          layers.forEach((layer) => {
            if (layer instanceof Layer) {
              this.add(layer)
            }
          })
          _isAdd = true
        } else {
          arguments.forEach((layer) => {
            if (layer instanceof Layer) {
              this.add(layer)
            }
          })
          _isAdd = true
        }

        if (_isAdd) {
          this.dispatchEvent(MapEventType.layerAddMany, {
            type: MapEventType.layerAddMany,
            target: this,
            layers
          })
        }
      }

      /**
       * 移除多个图层<a id='removeMany'></a>
       * @param {Array} layers 要移除的图层数组
       * @example
       * map.removeMany(layers);
       */
      removeMany(layers) {
        if (!layers) return this
        let _isRomove = false
        this._isRemoveMany = true
        if (layers instanceof Layer) {
          this.remove(layers)
          _isRomove = true
        } else if (Array.isArray(layers)) {
          layers.forEach((layer) => {
            if (layer instanceof Layer) {
              this.remove(layer)
            }
          })
          _isRomove = true
        } else {
          arguments.forEach((layer) => {
            if (layer instanceof Layer) {
              this.remove(layer)
            }
          })
          _isRomove = true
        }
        if (_isRomove) {
          this.dispatchEvent(MapEventType.layerRemoveMany, {
            type: MapEventType.layerAddMany,
            target: this,
            layers
          })
        }
        this._isRemoveMany = false
      }

      /**
       * 调整图层顺序<a id='reorder'></a>
       * @param {Object} layer 要调整顺序的图层
       * @param {Number} index 指定的index
       * @example
       * map.reorder(layer, '要移动到的index');
       */
      reorder(layer, index) {
        this._reorder(layer, index)
      }

      _reorder(layer, index) {
        layer.index = index
        const _layerSet = this._getSmallEqualLargeLayers(layer)
        if (_layerSet.equalIndexLayer) {
          this._moveEqualLayer(layer, _layerSet.equalIndexLayer)
        }
        // 如果smallIndexLayer存在
        else if (_layerSet.smallIndexLayer) {
          this._moveSmallLayer(layer, _layerSet.smallIndexLayer)
        }
        // 如果largeIndexLayers长度大于0
        if (_layerSet.largeIndexLayers.length > 0) {
          this._moveLargeLayers(layer, _layerSet.largeIndexLayers)
        }
        // 更新图层顺序
        layer._updateIndex()
        for (let i = 0; i < _layerSet.largeIndexLayers.length; i++) {
          if (_layerSet.largeIndexLayers[i].id !== layer.id) {
            _layerSet.largeIndexLayers[i]._updateIndex()
          }
        }
        // 更新Map中的图层实际位置
        let _index = undefined
        let _layer
        for (let i = 0; i < this.layers.items.length; i++) {
          if (this.layers.items[i].id === layer.id) {
            _index = i
            break
          }
        }
        if (_index !== undefined) {
          _layer = this.layers.items.splice(_index, 1)[0]
          this.layers.items.splice(index, 0, _layer)
        }
      }

      dispatchEvent(type, data, propagate) {
        this.fire(type, data, propagate)
        this.layers.fire(type, data, propagate)
        return this
      }

      _loadLayers() {
        this.layers.forEach((layer) => {
          this.dispatchEvent(
            MapEventType.layerAdd,
            new LayerEvent({
              type: MapEventType.layerAdd,
              target: this,
              layer
            })
          )
        })
        return this
      }

      /**
       * 设置子图层的逻辑index和realIndex
       * @private
       * @param {Object} layer 图层对象
       * @param {Number} realIndex realIndex值
       * */
      _setSubLayerIndex(layer, realIndex) {
        for (let i = 0; i < layer.layers.length; i++) {
          // 指定子图层逻辑顺序
          layer.layers[i].index = i
          // 指定子图层实际顺序
          layer.layers[i]._realIndex = realIndex + i + 1
        }
      }

      /**
       * 设置图层的实际顺序
       * @private
       * @param {Object} layer 图层对象
       * @param {Number} realIndex 从哪个index开始累加
       * */
      _setLayerAndSubLayer(layer, realIndex) {
        // 是组图层，则设置组图层的子图层的顺序
        if (layer.type === LayerType.group) {
          this._setSubLayerIndex(layer, realIndex)
        } else {
          layer._realIndex = realIndex + 1
        }
      }

      /**
       * 增加图层的realIndex对象
       * @private
       * @param {Object} layer 图层对象
       * @param {Number} addIndex 要增加的index
       * */
      _addLayerRealIndex(layer, addIndex) {
        // 是组图层
        if (layer.type === LayerType.group) {
          for (let i = 0; i < layer.layers.length; i++) {
            // 指定子图层实际顺序
            layer.layers[i]._realIndex += addIndex
          }
        } else {
          layer._realIndex += addIndex
        }
      }

      /**
       * 获取图层中最大的realIndex值
       * @private
       * @param {Array} layers 图层数组
       * @return {Number} 最大的realIndex值
       * */
      _getMaxRealIndexInLayers(layers) {
        let maxRealIndex = 0
        for (let i = 0; i < layers.length; i++) {
          if (layers[i]._realIndex > maxRealIndex) {
            maxRealIndex = layers[i]._realIndex
          }
        }
        return maxRealIndex
      }

      /**
       * 获取图层中最小的realIndex值
       * @private
       * @param {Array} layers 图层数组
       * @return {Number} 最小的realIndex值
       * */
      _getMinRealIndexInLayers(layers) {
        let minRealIndex = 0
        if (layers.length > 0) {
          minRealIndex = layers[0]._realIndex
        }
        for (let i = 0; i < layers.length; i++) {
          if (layers[i]._realIndex < minRealIndex) {
            minRealIndex = layers[i]._realIndex
          }
        }
        return minRealIndex
      }

      /**
       * 获取图层组中逻辑index最小的图层
       * @private
       * @param {Array} layers 图层数组
       * @return {Object} 逻辑index最小的图层
       * */
      _getMinIndexLayer(layers) {
        let smallerLargeLayer = undefined
        for (let i = 0; i < layers.length; i++) {
          if (!smallerLargeLayer) {
            smallerLargeLayer = layers[i]
          } else if (smallerLargeLayer.index > layers[i].index) {
            smallerLargeLayer = layers[i]
          }
        }
        return smallerLargeLayer
      }

      /**
       * 获取图层的realIndex
       * @private
       * @param {Object} layer 图层对象
       * @param {String} type 获取的方式
       * @return {Number} 图层的realIndex
       * */
      _getRealIndexInLayer(layer, type) {
        let _layerRealIndex = 0
        if (layer.type === LayerType.group) {
          if (type === 'max') {
            _layerRealIndex = this._getMaxRealIndexInLayers(layer.layers)
          } else {
            _layerRealIndex = this._getMinRealIndexInLayers(layer.layers)
          }
        } else {
          _layerRealIndex = layer._realIndex
        }
        return _layerRealIndex
      }

      /**
       * 增加逻辑index大于当前图层的图层逻辑index和realIndex
       * @private
       * @param {Object} layer 当前图层对象
       * @param {Array} largeIndexLayers 增加逻辑index大于当前图层的图层数组
       * */
      _moveLargeLayers(layer, largeIndexLayers) {
        // 获取当前图层的最大realIndex
        const _layerRealIndex = this._getRealIndexInLayer(layer, 'max')
        // 获取largeIndexLayers中index最小的图层
        const smallerLargeLayer = this._getMinIndexLayer(largeIndexLayers)
        // 获取smallerLargeLayer的最小realIndex
        const _smallerRealIndex = this._getRealIndexInLayer(
          smallerLargeLayer,
          'min'
        )
        // smallerLargeLayer的逻辑index小于当前图层的逻辑index
        // 所有largeIndexLayers的逻辑index加1
        if (smallerLargeLayer.index <= layer.index) {
          for (let i = 0; i < largeIndexLayers.length; i++) {
            // if (largeIndexLayers[i].id !== layer.id) largeIndexLayers[i].index++
          }
        }
        // smallerLargeLayer的最小realIndex小于当前图层的最大realIndex
        // 所有largeIndexLayers的realIndex加_layerRealIndex - _smallerRealIndex + 1
        if (_smallerRealIndex < _layerRealIndex) {
          for (let i = 0; i < largeIndexLayers.length; i++) {
            this._addLayerRealIndex(
              largeIndexLayers[i],
              _layerRealIndex - _smallerRealIndex + 1
            )
          }
        }
      }

      /**
       * 如果当前图层对象和摸一个图层的逻辑index相等，则将当前图层向后移动一位
       * @private
       * @param {Object} layer 当前图层对象
       * @param {Object} equalIndexLayer 和当前图层对象逻辑index相等的图层
       * */
      _moveEqualLayer(layer, equalIndexLayer) {
        // 逻辑顺序加1
        // layer.index++
        let _realIndex = 0
        // index相等的图层不是组图层
        if (equalIndexLayer.type !== LayerType.group) {
          _realIndex = equalIndexLayer._realIndex
        }
        // index相等的图层是组图层
        else {
          // 找到其中最大的realIndex
          _realIndex = this._getMaxRealIndexInLayers(equalIndexLayer.layers)
        }
        this._setLayerAndSubLayer(layer, _realIndex)
      }

      /**
       * 如果当前图层的realIndex小于等于离的最近的
       * 图层的realIndex（该图层的逻辑index和当前图层的逻辑index最接近，但不相等，图层类型为组图层）
       * 则增加当前图层的realIndex，如果大于，则直接设置
       * @private
       * @param {Object} layer 当前图层对象
       * @param {Object} smallIndexLayer 里的最近的图层对象
       * */
      _moveSmallLayer(layer, smallIndexLayer) {
        let _realIndex
        if (smallIndexLayer.type === LayerType.group) {
          let sIndex = 0
          // 找到其中最大的realIndex
          _realIndex = this._getMaxRealIndexInLayers(smallIndexLayer.layers)
          for (let i = 0; i < smallIndexLayer.layers.length; i++) {
            if (smallIndexLayer.layers[i]._realIndex > sIndex) {
              sIndex = smallIndexLayer.layers[i]._realIndex
            }
          }
        } else {
          _realIndex = smallIndexLayer._realIndex
        }
        if (_realIndex >= layer.index) {
          this._setLayerAndSubLayer(layer, _realIndex)
        } else {
          this._setLayerAndSubLayer(layer, layer.index - 1)
        }
      }

      /**
       * 获取逻辑index小于、等于和大于当前图层的图层
       * @private
       * @param {Object} layer 当前图层
       * @return {Object} 图层集合
       * */
      _getSmallEqualLargeLayers(layer) {
        // index小于当前图层的图层
        let smallIndexLayer = undefined
        // index等于当前图层的图层
        let equalIndexLayer = undefined
        // index大于当前图层的图层数组
        const largeIndexLayers = []
        // 遍历当前数组，将图层分为index小于当前图层、等于当前图层和大于当前图层两组
        for (let i = 0; i < this.layers.items.length; i++) {
          if (this.layers.items[i].index < layer.index) {
            if (!smallIndexLayer) {
              smallIndexLayer = this.layers.items[i]
            } else if (smallIndexLayer.index < this.layers.items[i].index) {
              smallIndexLayer = this.layers.items[i]
            }
          } else if (
            this.layers.items[i].index === layer.index &&
            this.layers.items[i].id !== layer.id
          ) {
            equalIndexLayer = this.layers.items[i]
          } else {
            largeIndexLayers.push(this.layers.items[i])
          }
        }

        return {
          smallIndexLayer,
          equalIndexLayer,
          largeIndexLayers
        }
      }

      /**
       * 设置图层在当前图层组中的顺序
       * @private
       * @param {Object} layer 添加的图层
       * */
      _setLayerIndex(layer) {
        let _realIndex = 0
        // 没有指定顺序，则按找先来后到的顺序排列
        if (layer.index === undefined) {
          // 指定逻辑顺序
          layer.index = this.layers.items.length
          // 图层数量为0
          if (this.layers.items.length === 0) {
            this._setLayerAndSubLayer(layer, layer.index - 1)
          }
          // 图层数量大于0，则在上一个图层的基础上加一
          else if (this.layers.items.length > 0) {
            // 找到上一个图层
            const prevLayer = this.layers.items[this.layers.items.length - 1]

            // 上一个图层不是组图层
            if (prevLayer.type !== LayerType.group) {
              _realIndex = prevLayer._realIndex
            }
            // 上一个图层是组图层
            else {
              _realIndex = this._getMaxRealIndexInLayers(prevLayer.layers)
            }

            // 如果上一个图层不是是graphic layer，则该图层在最上层。
            // 如果上一个图层是graphic layer，graphicLayer在最上层，该图层在graphicLayer下。
            if (prevLayer.type !== LayerType.graphics) {
              this._setLayerAndSubLayer(layer, _realIndex)
            } else {
              this._setLayerAndSubLayer(layer, _realIndex - 1)
              this._setLayerAndSubLayer(prevLayer, _realIndex)
            }
          }
        }
        // 指定图层的index
        else {
          // 设置index
          this._setLayerAndSubLayer(layer, layer.index - 1)
          const _layerSet = this._getSmallEqualLargeLayers(layer)
          // 如果equalIndexLayer存在
          if (_layerSet.equalIndexLayer) {
            this._moveEqualLayer(layer, _layerSet.equalIndexLayer)
          }
          // 如果smallIndexLayer存在
          else if (_layerSet.smallIndexLayer) {
            this._moveSmallLayer(layer, _layerSet.smallIndexLayer)
          }
          if (_layerSet.largeIndexLayers.length > 0) {
            this._moveLargeLayers(layer, _layerSet.largeIndexLayers)
          }
        }
      }

      _loadBasemap() {
        this._haveView = true
        if (this._basemap) {
          this._addBaseLayers()
        }
      }

      _addBaseLayers() {
        if (this._basemap._baseLayers) {
          for (let i = 0; i < this._basemap._baseLayers.items.length; i++) {
            const layer = this._basemap._baseLayers.items[i]
            if (!layer.loaded) {
              layer._isBasemapLayer = true
              this.add(layer)
            } else {
              this._basemap._baseLayers.splice(i, 1)
              i--
            }
          }
        }
      }

      _removeBaseLayers(layer) {
        if (layer) {
          layer.destroy()
          this.layers.remove(layer)
          // 删除allLayers中的图层
          this.allLayers.remove(layer)
          // 删除关联的子图层
          let _allLayers = [].concat(this.allLayers.items)
          for (let i = 0; i < _allLayers.length; i++) {
            if (_allLayers[i] instanceof SubLayer) {
              const _parentLayer = _allLayers[i].layer
              if (_parentLayer && _parentLayer.id && _parentLayer.id === layer.id) {
                this.allLayers.remove(_allLayers[i])
              }
            }
          }
          _allLayers = undefined
        }
      }

      _setBasemap(value) {
        // map上有_basemap，并且value不为空或undefined，则是该basemap需要初始挂载事件
        if (!this._basemap && value) {
          value.on('destroyed', () => {
            if (this._basemap._baseLayers) {
              this._basemap._baseLayers.forEach((baseLayer) => {
                baseLayer._isBasemapLayer = false
                this.remove(baseLayer)
              })
            }
            this._basemap = null
          })
        }
        // 如果value不为空或undefined，或者this._basemap不为空（即没有被销毁），则将新的value赋值给map的basemap
        if (value) {
          if (this._haveView) {
            if (this._basemap && this._basemap._baseLayers) {
              this._basemap._baseLayers.forEach((baseLayer) => {
                baseLayer._isBasemapLayer = false
              })
              this._canResetView = false
              this.removeMany(this._basemap._baseLayers.items)
              this._canResetView = true
            }
            this._basemap = value
            this._addBaseLayers()
          }
        } else {
          this._basemap.spatialReference = null
          if (this._basemap && this._basemap._baseLayers) {
            this._basemap._baseLayers.forEach((baseLayer) => {
              baseLayer._isBasemapLayer = false
            })
            this.removeMany(this._basemap._baseLayers.items)
          }
          this._basemap = value
        }
      }
    }

    Object.defineProperties(Map.prototype, {
      basemap: {
        get() {
          return this._basemap
        },
        set(value) {
          this._setBasemap(value)
        }
      }
    })

    export default Map
    Zondy.Map = Map