import * as esriLoader from 'esri-loader'
import BasicAdapter from './BasicAdapter'
import { MapLineType, MapLayerType } from '../export/BasicClass'
import { EsriMapOverLayer } from '../layers/EsriMapOverLayer'
import { animationLayerName, infoLayerName, movingObjectLayerName } from './MapLocalConfig'
import '../css/style.css'
import EsriMapEditor from './EsriMapEditor'
import { color2RGB } from './ColorTrans'
import { GeospatialAnalysis } from '../export/GeospatialAnalysis'

/**
 * @class EsriMapAdapter
 * @classdesc ESRI接口适配类
 */
export default class EsriMapAdapter extends BasicAdapter {
  /**
   * 初始化地图实例
   * @param {function} callback 回调函数
   */
  initialMap(callback) {
    let that = this
    esriLoader
      .loadModules(['esri/map', 'esri/layers/ArcGISTiledMapServiceLayer', 'esri/geometry/Point'])
      .then(([Map, ArcGISTiledMapServiceLayer, Point]) => {
        var mopts = {
          logo: false,
          slider: false,
          fitExtent: true,
          center: new Point(window.mapconfig.center[0], window.mapconfig.center[1]),
          zoom: window.mapconfig.zoom || 2
        }
        var comOpts = mopts
        if (window.mapconfig.minZoom) {
          var mzopts = { minZoom: window.mapconfig.minZoom }
          comOpts = Object.assign(mopts, mzopts)
        }
        if (window.mapconfig.maxZoom) {
          var mzopts = { maxZoom: window.mapconfig.maxZoom }
          comOpts = Object.assign(mopts, mzopts)
        }

        that.map = new Map(that.div, comOpts)

        let baseMapLayer = new ArcGISTiledMapServiceLayer(window.mapconfig.dataUrl)
        this.baseMapLayers.push(baseMapLayer)

        that.map.addLayer(baseMapLayer)
        //初始化编辑器
        that.mapEditor = new EsriMapEditor(that.map)
        return Promise.resolve(that.map)
      })
      .then(function (map) {
        callback(map)
      })
  }

  /**
   * 地图居中于坐标点
   * @param {number[]} center 中心点坐标 [117.204348, 39.345704]
   */
  centerAt(center) {
    esriLoader.loadModules(['esri/geometry/Point']).then(([Point]) => {
      this.map.centerAndZoom(new Point(center), window.mapconfig.zoom)
    })
  }
  /**
   * 地图缩放至指定级别并以指定点为地图显示中心点
   * @param {number[]} center 中心点坐标 [117.204348, 39.345704]
   * @param {number} zoom 缩放等级 8
   */
  setCenterAndZoom(center, zoom) {
    esriLoader.loadModules(['esri/geometry/Point']).then(([Point]) => {
      this.map.centerAndZoom(new Point(center), zoom)
    })
  }
  setMapLayers(options) {
    var url = options.url
    for (var i = 0; i < this.baseMapLayers.length; i++) {
      this.map.removeLayer(this.baseMapLayers[i])
    }
    var _this = this
    esriLoader.loadModules(['esri/layers/ArcGISTiledMapServiceLayer']).then(([ArcGISTiledMapServiceLayer]) => {
      let baseMapLayer = new ArcGISTiledMapServiceLayer(url)
      _this.map.addLayer(baseMapLayer)
      _this.baseMapLayers.push(baseMapLayer)
    })
  }
  /**
   * 添加点图层
   * @param {string} layername 图层名
   * @param {[{}]} geoObj 构成图层的几何集合 {name: '', attribute: [{name:,value:}], longitude:'',latitude:'',style:MapPointStyle}
   */
  async addPointsLayer(layername, geoObj) {
    await this.setPoints(layername, geoObj)
  }
  async addPointsLayerWithTxt(layername, geoObj) {
    await this.setPointsWithText(layername, geoObj)
  }
  /**
   * 添加线图层
   * @param {string} layername 图层名
   * @param {[{}]} geoObj 构成图层的几何集合 {name: '', attribute: [{name:,value:}], path:[[],[]],style:MapLineStyle}
   */
  async addLinesLayer(layername, geoObj) {
    await this.setLines(layername, geoObj)
  }
  /**
   * 添加面图层
   * @param {string} layername 图层名
   * @param {[{}]} geoObj 构成图层的几何集合 {name: '', attribute: [{name:,value:}], path:[[],[]],style:MapPolygonStyle}
   */
  async addPolygonsLayer(layername, geoObj) {
    await this.setPolygons(layername, geoObj)
  }
  /**
   * 添加文字图层
   * @param {string} layername 图层名
   * @param {[{}]} geoObj 构成图层的几何集合 {name:',content: '', longitude:'',latitude:'',style:MapTextStyle}
   */
  async addLabels(layername, geoObj) {
    await this.setLabels(layername, geoObj)
  }
  /** 添加信息窗图层
   * @param {string} layername 图层名
   * @param {[{}]} geoObj 构成图层的几何集合 {name: '',content: '', longitude:'',latitude:'',xoffset:0,yoffset:0}
   */
  async addInfowindow(geoObj) {
    // let that = this
    // await this.map.on('load', function (e) {
    await this.setInfowindow(infoLayerName, geoObj)
    // })
  }
  /**
   * 根据数据生成点要素graphicslayer，并添加到地图上
   * @param {string} layername 图层名
   * @param {[{}]} geoObj 构成图层的几何集合 {name: '', attribute: [{name:,value:}], longitude:'',latitude:'',style:MapPointStyle}
   * @param {graphicslayer} glyr 如存在，则geoObj内数据插入此图层，否则新建图层
   */
  async setPoints(layername, geoObj, glyr) {
    await esriLoader
      .loadModules([
        'esri/layers/GraphicsLayer',
        'esri/geometry/Point',
        'esri/graphic',
        'esri/symbols/PictureMarkerSymbol'
      ])
      .then(([GraphicsLayer, Point, Graphic, PictureMarkerSymbol]) => {
        let glayer
        if (glyr == undefined) {
          glayer = new GraphicsLayer()
          this.map.addLayer(glayer)
        } else {
          glayer = glyr
        }
        for (let i = 0, len = geoObj.length; i < len; i++) {
          if (geoObj[i].longitude == null || geoObj[i].latitude == null) continue
          if (geoObj[i].longitude === 0 || geoObj[i].latitude === 0) continue
          let xCoor = geoObj[i].longitude
          let yCoor = geoObj[i].latitude

          let pt = new Point(xCoor, yCoor)
          let marker = new Graphic(pt)

          var att = []
          att.push({ name: geoObj[i].name })
          if (geoObj[i].attribute != undefined || geoObj[i].attribute.length > 0) {
            att = att.concat(geoObj[i].attribute)
          }
          marker.setAttributes(att)
          let picSymbol = new PictureMarkerSymbol(geoObj[i].style.icon, geoObj[i].style.width, geoObj[i].style.height)
          marker.setSymbol(picSymbol)
          glayer.add(marker)
        }
        if (glyr == undefined) {
          this.mapLayers.push(new EsriMapOverLayer(layername, glayer, true, MapLayerType.Point))
        }
      })
  }
  async setPointsWithText(layername, geoObj) {
    await esriLoader
      .loadModules([
        'esri/symbols/PictureMarkerSymbol',
        'esri/graphic',
        'esri/geometry/Point',
        'esri/layers/GraphicsLayer',
        'esri/symbols/TextSymbol',
        'esri/symbols/Font',
        'esri/Color'
      ])
      .then(([PictureMarkerSymbol, Graphic, Point, GraphicsLayer, TextSymbol, Font, Color]) => {
        let glayer = new GraphicsLayer()

        for (let i = 0, len = geoObj.length; i < len; i++) {
          if (geoObj[i].longitude == null || geoObj[i].latitude == null) continue
          if (geoObj[i].longitude === 0 || geoObj[i].latitude === 0) continue
          let xCoor = geoObj[i].longitude
          let yCoor = geoObj[i].latitude

          let pt = new Point(xCoor, yCoor)
          let marker = new Graphic(pt)

          var att = []
          att.push({ name: geoObj[i].name })
          if (geoObj[i].attribute != undefined || geoObj[i].attribute.length > 0) {
            att = att.concat(geoObj[i].attribute)
          }
          marker.setAttributes(att)

          let picSymbol = new PictureMarkerSymbol(
            geoObj[i].ptStyle.icon,
            geoObj[i].ptStyle.width,
            geoObj[i].ptStyle.height
          )
          var fColor = color2RGB(geoObj[i].txtStyle.fontColor) || '#000'
          var textSymbol = new TextSymbol(
            geoObj[i].text || (i + 1).toString(),
            new Font(
              geoObj[i].txtStyle.fontSize || 12,
              'STYLE_NORMAL',
              'VARIANT_NORMAL',
              geoObj[i].txtStyle.fontWeight || 'WEIGHT_NORMAL',
              geoObj[i].txtStyle.fontFamily || 'Serif'
            ),
            new Color(fColor)
          )

          textSymbol.setOffset(geoObj[i].txtStyle.xOffset || 0, geoObj[i].txtStyle.yOffset || 0)

          var labelPointGraphic = new Graphic(pt, textSymbol)
          marker.setSymbol(picSymbol)
          glayer.add(marker)
          glayer.add(labelPointGraphic)
        }
        this.map.addLayer(glayer)

        this.mapLayers.push(new EsriMapOverLayer(layername, glayer, true, MapLayerType.Point))
      })
  }
  /**
   * 根据数据生成线要素graphicslayer，并添加到地图上
   * @param {string} layername 图层名
   * @param {[{}]} geoObj 构成图层的几何集合 {name: '', attribute: [{name:,value:}], path:[[],[]],style:MapLineStyle}
   * @param {graphicslayer} glyr 如存在，则geoObj内数据插入此图层，否则新建图层
   */
  async setLines(layername, geoObj, glyr) {
    await esriLoader
      .loadModules([
        'esri/layers/GraphicsLayer',
        'esri/geometry/Polyline',
        'esri/graphic',
        'esri/symbols/SimpleLineSymbol',
        'esri/Color'
      ])
      .then(([GraphicsLayer, Polyline, Graphic, SimpleLineSymbol, Color]) => {
        let glayer
        if (glyr == undefined) {
          glayer = new GraphicsLayer()
          this.map.addLayer(glayer)
        } else {
          glayer = glyr
        }
        for (let i = 0, len = geoObj.length; i < len; i++) {
          if (!geoObj[i].path) continue
          let paths = geoObj[i].path
          let polyline = new Polyline(paths)
          let marker = new Graphic(polyline)

          let lineStyle = SimpleLineSymbol.STYLE_SOLID
          if (geoObj[i].style.lineType !== undefined) {
            lineStyle =
              geoObj[i].style.lineType === MapLineType.Dashed
                ? SimpleLineSymbol.STYLE_DASH
                : SimpleLineSymbol.STYLE_SOLID
          }

          let fcolor = new Color(geoObj[i].style.color || [0, 211, 252, 0.9])
          if (geoObj[i].style.opacity !== 1) {
            fcolor.a = geoObj[i].style.opacity
          }

          let lSymbol = new SimpleLineSymbol(lineStyle, fcolor, geoObj[i].style.width || 2)
          // var lSymbol = new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([245, 113, 6, 0.85]), 8)
          marker.setSymbol(lSymbol)
          var att = []
          att.push({ name: geoObj[i].name })
          if (geoObj[i].attribute != undefined || geoObj[i].attribute.length > 0) {
            att = att.concat(geoObj[i].attribute)
          }
          marker.setAttributes(att)
          glayer.add(marker)
        }
        if (glyr == undefined) {
          this.mapLayers.push(new EsriMapOverLayer(layername, glayer, true, MapLayerType.Line))
        }
      })
  }
  /**
   * 根据数据生成线要素graphicslayer，并添加到地图上
   * @param {string} layername 图层名
   * @param {[{}]} geoObj 构成图层的几何集合 {name: '', attribute: [{name:,value:}], path:[[],[]],style:MapPolygonStyle}
   * @param {graphicslayer} glyr 如存在，则geoObj内数据插入此图层，否则新建图层
   */
  async setPolygons(layername, geoObj, glyr) {
    await esriLoader
      .loadModules([
        'esri/layers/GraphicsLayer',
        'esri/geometry/Polygon',
        'esri/graphic',
        'esri/symbols/SimpleFillSymbol',
        'esri/symbols/SimpleLineSymbol',
        'esri/Color'
      ])
      .then(([GraphicsLayer, Polygon, Graphic, SimpleFillSymbol, SimpleLineSymbol, Color]) => {
        let glayer
        if (glyr == undefined) {
          glayer = new GraphicsLayer()
          this.map.addLayer(glayer)
        } else {
          glayer = glyr
        }
        for (let i = 0, len = geoObj.length; i < len; i++) {
          if (!geoObj[i].path) continue
          let polygon = new Polygon(geoObj[i].path)
          let marker = new Graphic(polygon)

          let fillStyle = SimpleFillSymbol.STYLE_NULL
          let lineStyle = SimpleLineSymbol.STYLE_NULL
          let fcolor = new Color([0, 178, 213, 0.5])
          let outlinecolor = new Color([0, 211, 252, 0.9])
          let strokeWeight = 2

          if (geoObj[i].style.strokeType === MapLineType.Solid) {
            lineStyle = SimpleLineSymbol.STYLE_SOLID
          } else if (geoObj[i].style.strokeType === MapLineType.Dashed) {
            lineStyle = SimpleLineSymbol.STYLE_DASH
          }

          if (geoObj[i].style.fillColor != null) {
            fcolor = new Color(geoObj[i].style.fillColor)
            fillStyle = SimpleFillSymbol.STYLE_SOLID
          }
          if (geoObj[i].style.fillOpacity !== 1) {
            fcolor.a = geoObj[i].style.fillOpacity
          }
          if (geoObj[i].style.strokeColor != null) {
            outlinecolor = new Color(geoObj[i].style.strokeColor)
          }
          if (geoObj[i].style.strokeOpacity !== 1) {
            outlinecolor.a = geoObj[i].style.strokeOpacity
          }
          if (geoObj[i].style.strokeWeight !== 0) {
            strokeWeight = geoObj[i].style.strokeWeight
          }

          let fSymbol = new SimpleFillSymbol(
            fillStyle,
            new SimpleLineSymbol(lineStyle, outlinecolor, strokeWeight),
            fcolor
          )

          marker.setSymbol(fSymbol)
          var att = []
          att.push({ name: geoObj[i].name })
          if (geoObj[i].attribute != undefined || geoObj[i].attribute.length > 0) {
            att = att.concat(geoObj[i].attribute)
          }
          marker.setAttributes(att)
          glayer.add(marker)
        }
        if (glyr == undefined) {
          this.mapLayers.push(new EsriMapOverLayer(layername, glayer, true, MapLayerType.Polygon))
        }
      })
  }
  /**
   * 根据数据生成文字graphicslayer，并添加到地图上
   * @param {string} layername 图层名
   * @param {[{}]} geoObj 构成图层的几何集合 {name:'',content: '', longitude:'',latitude:'',style:json}
   * @param {graphicslayer} glyr 如存在，则geoObj内数据插入此图层，否则新建图层
   */
  async setLabels(layername, geoObj, glyr) {
    await esriLoader
      .loadModules(['esri/layers/GraphicsLayer', 'esri/graphic', 'esri/symbols/TextSymbol', 'esri/geometry/Point'])
      .then(([GraphicsLayer, Graphic, TextSymbol, Point]) => {
        let tLayer
        if (glyr == undefined) {
          tLayer = new GraphicsLayer()
          this.map.addLayer(tLayer)
        } else {
          tLayer = glyr
        }

        for (let i = 0, len = geoObj.length; i < len; i++) {
          if (geoObj[i].longitude == null || geoObj[i].latitude == null) continue
          if (geoObj[i].longitude === 0 || geoObj[i].latitude === 0) continue

          let pt = new Point(geoObj[i].longitude, geoObj[i].latitude)

          let tSym = new TextSymbol({
            color: [geoObj[i].style.fontColor[0], geoObj[i].style.fontColor[1], geoObj[i].style.fontColor[2], 255] || [
              0, 0, 0, 255
            ],
            xoffset: geoObj[i].style.xOffset || 0,
            yoffset: geoObj[i].style.yOffset || 0,
            font: {
              family: geoObj[i].style.fontFamily || 'Arial',
              size: geoObj[i].style.fontSize + 'px' || 12 + 'px',
              style: geoObj[i].style.fontWeight || 'normal',
              decoration: 'none'
            }
          })
          let markerTxt = new Graphic(pt, tSym)
          markerTxt.setAttributes([{ name: geoObj[i].name }])
          tSym.setText(geoObj[i].content)
          tLayer.add(markerTxt)
        }
        if (glyr == undefined) {
          this.mapLayers.push(new EsriMapOverLayer(layername, tLayer, true, MapLayerType.Text))
        }
      })
  }
  /**
   * 根据数据生成信息窗数组，并添加到地图上指定位置
   * @param {string} layername 图层名
   * @param {[{}]} geoObj 构成图层的几何集合 {name:'',content: '', longitude:'',latitude:'',style:json}
   * @param {graphicslayer} glyr 如存在，则geoObj内数据插入此图层，否则新建图层
   */
  async setInfowindow(layername, geoObj) {
    await esriLoader
      .loadModules(['esri/dijit/Popup', 'dojo/dom-construct', 'dojo/dom-class', 'esri/geometry/Point'])
      .then(([Popup, domConstruct, domClass, Point]) => {
        var glyr = this.getLyrByName(infoLayerName)
        let glayer = []
        if (glyr !== undefined) {
          glayer = glyr
        } else {
          this.mapLayers.push(new EsriMapOverLayer(layername, glayer, true, MapLayerType.Infowindow))
        }

        for (let i = 0, len = geoObj.length; i < len; i++) {
          if (geoObj[i].longitude == null || geoObj[i].latitude == null) continue
          if (geoObj[i].longitude === 0 || geoObj[i].latitude === 0) continue
          let xCoor = geoObj[i].longitude
          let yCoor = geoObj[i].latitude

          var popTip = new Popup({ anchor: 'auto' }, domConstruct.create('div'))
          popTip.startup()
          popTip.setContent(geoObj[i].content)
          popTip.setMap(this.map)
          popTip.set('attributes', [{ name: geoObj[i].name }])
          popTip.offsetX = geoObj[i].xOffset || 0
          popTip.offsetY = geoObj[i].yOffset || 0

          popTip.show(new Point(xCoor, yCoor))
          glayer.push(popTip)
        }
      })
  }
  /**
   * 关闭指定名称信息窗
   * @param {string} name
   * @returns
   */
  closeInfowindow(name) {
    var lyr = this.getLyrByName(infoLayerName)
    if (lyr) {
      for (let i = 0; i < lyr.length; i++) {
        var att = lyr[i].attributes
        var ele = att.find((item) => item.name === name)
        if (ele != undefined) {
          lyr[i].hide()
          return
        }
      }
    }
  }
  /**
   * 打开指定名称信息窗
   * @param {string} name 信息窗名
   * @returns
   */
  openInfowindow(name) {
    var lyr = this.getLyrByName(infoLayerName)
    if (lyr) {
      for (let i = 0; i < lyr.length; i++) {
        var att = lyr[i].attributes
        var ele = att.find((item) => item.name === name)
        if (ele != undefined) {
          lyr[i].show(lyr[i].location)
          return
        }
      }
    }
  }
  /**
   * 移除指定信息窗
   * @param {string} name 信息窗名
   * @returns
   */
  removeInfowindow(name) {
    var lyr = this.getLyrByName(infoLayerName)
    if (lyr) {
      for (let i = 0; i < lyr.length; i++) {
        var att = lyr[i].attributes
        var ele = att.find((item) => item.name === name)
        if (ele != undefined) {
          lyr[i].unsetMap(this.map)
          lyr[i].destroy()
          lyr.splice(i, 1)
          return
        }
      }
    }
  }
  setLayerMask(boundries, borderStyle) {
    const options = { version: '4.20', css: true }
    esriLoader
      .loadModules(['esri/map'], options)
      .then(([Map]) => {
        console.log(Map)
      })
      .catch((err) => {
        // handle any script or module loading errors
        console.error(err)
      })
  }

  removeLayerMask() {}
  /**
   * 移除指定图层
   * @param {string} layername 图层名
   */
  removeLayer(layername) {
    if (layername == undefined) {
      for (let i = 0; i < this.mapLayers.length; i++) {
        this.map.removeLayer(this.mapLayers[i].element)
      }
      super.removeMapLayers()
    } else {
      var ind = this.getLyrIndexByName(layername)
      this.map.removeLayer(this.mapLayers[ind].element)
      super.removeMapLayer(ind)
    }
  }
  /**
   * 移除指定图层内指定属性要素
   * @param {string} layername 图层名
   * @param {string} name 要素名
   */
  removeElementByFieldName(layername, name) {
    var lyr = this.getLyrByName(layername)
    if (lyr) {
      var ele = this.getElementByFieldName(lyr, name)
      lyr.remove(ele)
    }
  }
  /**
   * 移除指定要素
   * @param {*} layername 图层名
   * @param {Marker｜Polyline｜Polygon｜Text} element 需要删除的元素
   */
  removeElement(layername, element) {
    var lyr = this.getLyrByName(layername)
    if (lyr) {
      lyr.remove(element)
    }
    // var name = element.attributes[0].name
    // this.removeElementByFieldName(layername, name)
  }
  /**
   * 获得指定图层内指定属性要素
   * @param {Graphicslayer} layer 要素集合
   * @param {string} name 要素名
   * @returns graphic
   */
  getElementByFieldName(layer, name) {
    var elements = layer.graphics
    for (let i = 0; i < elements.length; i++) {
      var att = elements[i].attributes
      var ele = att.find((item) => item.name === name)
      if (ele != undefined) return elements[i]
    }
  }
  /**
   * 根据图层名获得图层坐标数据
   * @param {string} layername 图层名
   * @returns object { layer: layername, postion: [{lng,lat},...] }
   */
  getLayerGeometryByName(layername) {
    var index = this.getLyrIndexByName(layername)
    if (index === -1) {
      return
    }
    var type = this.mapLayers[index].type
    var ele = this.mapLayers[index].element.graphics

    var postions = ele.map(function (item) {
      if (type == MapLayerType.Point) {
        var pos = item.geometry
        return { lng: pos.x, lat: pos.y }
      } else if (type === MapLayerType.Polygon) {
        var path = item.geometry.rings
        var llpos = []
        for (var i = 0; i < path.length; i++) {
          for (var j = 0; j < path[i].length; j++) {
            llpos.push({ lng: path[i][j][0], lat: path[i][j][1] })
          }
        }
        return llpos
      } else if (type === MapLayerType.Line) {
        var path = item.geometry.paths
        var llpos = []
        for (var i = 0; i < path.length; i++) {
          for (var j = 0; j < path[i].length; j++) {
            llpos.push({ lng: path[i][j][0], lat: path[i][j][1] })
          }
        }
        return llpos
      }
    })
    return { layer: layername, postion: postions }
  }
  /**
   * 插入要素到某一图层
   * @param {string} layername 要插入要素的图层名
   * @param {array} geoObj 构成图层的几何集合 [MapPolygon、MapPolyline、MapPoint、MapText]
   *  @param {MapLayerType} layertype 要插入要素的图层类型
   */
  async insertintoLayer(layername, geoObj, lyrtype) {
    var lyr = this.getLyrByNameandGeometry(layername, lyrtype)
    if (lyr == undefined) return
    switch (lyrtype) {
      case MapLayerType.Point:
        this.setPoints(layername, geoObj, lyr)
        break
      case MapLayerType.Line:
        this.setLines(layername, geoObj, lyr)
        break
      case MapLayerType.Polygon:
        this.setPolygons(layername, geoObj, lyr)
        break
      case MapLayerType.Text:
        this.setLabels(layername, geoObj, lyr)
        break
    }
  }
  /**
   * 添加自定义gif动图到指定位置
   * @param {[MapAnimation]} geoObj 构成图层的几何集合
   */
  startAnimation(geoObj) {
    esriLoader
      .loadModules([
        'esri/layers/GraphicsLayer',
        'esri/graphic',
        'esri/geometry/Point',
        'esri/symbols/PictureMarkerSymbol'
      ])
      .then(([GraphicsLayer, Graphic, Point, PictureMarkerSymbol]) => {
        let glayer = this.getLyrByName(animationLayerName)
        if (!glayer) {
          glayer = new GraphicsLayer()
          this.map.addLayer(glayer)
          this.mapLayers.push(new EsriMapOverLayer(animationLayerName, glayer, true, MapLayerType.Animation))
        }

        for (let i = 0, len = geoObj.length; i < len; i++) {
          if (geoObj[i].longitude == null || geoObj[i].latitude == null) continue
          if (geoObj[i].longitude === 0 || geoObj[i].latitude === 0) continue
          let xCoor = geoObj[i].longitude
          let yCoor = geoObj[i].latitude
          let symbol = new PictureMarkerSymbol(geoObj[i].content, 64, 64)

          let pt = new Point(xCoor, yCoor)
          let graphicFlash = new Graphic(pt, symbol)
          graphicFlash.setAttributes([{ name: geoObj[i].name }])
          glayer.add(graphicFlash)
        }
      })
  }
  /**
   * 根据动画名称移除gif动图
   * @param {string} name 动画名
   */
  removeAnimation(name) {
    this.removeElementByFieldName(animationLayerName, name)
  }
  startObjectMoving(name, path, duaration, speed, objectStyle) {
    esriLoader
      .loadModules([
        'esri/layers/GraphicsLayer',
        'esri/graphic',
        'esri/geometry/Point',
        'esri/symbols/PictureMarkerSymbol'
      ])
      .then(([GraphicsLayer, Graphic, Point, PictureMarkerSymbol]) => {
        // 移动物体
        var modelSymbol = new PictureMarkerSymbol(objectStyle.icon, objectStyle.width || 36, objectStyle.height || 36)
        // this.modelSymbol = new PictureMarkerSymbol({
        //   "url": objectStyle.icon,
        //   "height": objectStyle.height,
        //   "width": objectStyle.width,
        //   "type": "esriPMS",
        //   "angle": -66.18959524592748,
        // });
        var seed = 200 //多长时间执行一次,(单位:毫秒/次)
        var _running = true

        var moveLayer
        var lyr = this.getLyrIndexByName(movingObjectLayerName)
        if (lyr != -1) {
          var layer = this.mapLayers[lyr].element
          moveLayer = layer
        } else {
          moveLayer = new GraphicsLayer({
            id: 'moveLayer'
          })
          this.map.addLayer(moveLayer)
          this.mapLayers.push(new EsriMapOverLayer(movingObjectLayerName, moveLayer, true, MapLayerType.Animation))
        }

        // 设置起点
        var startingPoint = new Point(path[0][0], path[0][1])
        var moveCarGra = new Graphic(startingPoint, modelSymbol)

        var anal = new GeospatialAnalysis()
        var movingPath = anal.getPathStepPoints(path, speed, seed, objectStyle.angle)
        moveCarGra.setAttributes({ name: name, running: _running, movingPath: movingPath, ptIndex: 0 })

        moveLayer.add(moveCarGra)
        this._move(seed, moveCarGra)
      })
  }
  _move(seed, moveGraphic) {
    esriLoader.loadModules(['esri/geometry/Point']).then(([Point]) => {
      var that = this
      var attr = moveGraphic.attributes
      if (!attr) {
        return
      }
      var moving = setInterval(function () {
        if (attr.running) {
          if (attr.ptIndex >= attr.movingPath.length) {
            clearInterval(that.moving)
          }
          if (attr.ptIndex <= attr.movingPath.length - 1) {
            var pt = attr.movingPath[attr.ptIndex]
            var ptGeometry = new Point({
              longitude: pt.longitude,
              latitude: pt.latitude
            })
            var modelSymbol = moveGraphic.symbol
            modelSymbol.setAngle(pt.angle)
            moveGraphic.setGeometry(ptGeometry)
            attr.ptIndex++
          }
        }
      }, seed)
      attr.moving = moving
      moveGraphic.setAttributes(attr)
    })
  }
  pauseObjectMoving(name) {
    var lyr = this.getLyrIndexByName(movingObjectLayerName)
    if (lyr != -1) {
      var layer = this.mapLayers[lyr].element
      for (var i = 0; i < layer.graphics.length; i++) {
        var attr = layer.graphics[i].attributes
        if (attr.name == name) {
          attr.running = !attr.running
          break
        }
      }
    }
  }
  continueObjectMoving(name) {
    var lyr = this.getLyrIndexByName(movingObjectLayerName)
    if (lyr != -1) {
      var layer = this.mapLayers[lyr].element
      for (var i = 0; i < layer.graphics.length; i++) {
        var attr = layer.graphics[i].attributes
        if (attr.name == name) {
          attr.running = !attr.running
          break
        }
      }
    }
  }
  stopObjectMoving(name) {
    var lyr = this.getLyrIndexByName(movingObjectLayerName)
    if (lyr != -1) {
      var layer = this.mapLayers[lyr].element
      for (var i = 0; i < layer.graphics.length; i++) {
        var attr = layer.graphics[i].attributes
        if (attr.name == name) {
          if (attr.moving != null) {
            clearInterval(attr.moving)
            attr.running = false
            attr.ptIndex = 0
            attr.movingPath = []
          }
          break
        }
      }
    }
  }
  /**
   * 获取地图中心点坐标
   * @returns 地图中心点[number,number]
   */
  getCenter() {
    if (this.map) {
      var pt = this.map.extent.getCenter()
      return [parseFloat(pt.x.toFixed(8)), parseFloat(pt.y.toFixed(8))]
    }
  }
  /**
   * 获取地图最小缩放级别
   * @returns 地图最小缩放级别
   */
  getMinZoom() {
    if (this.map) {
      return this.map.getMinZoom()
    }
  }
  /**
   * 获取地图最大缩放级别
   * @returns 地图最大缩放级别
   */
  getMaxZoom() {
    if (this.map) {
      return this.map.getMaxZoom()
    }
  }
  /**
   * 在地图上显示指定图层名图层
   * @param {string} layername
   */
  showLayer(layername) {
    var index = this.getLyrIndexByName(layername)
    if (index == -1) return
    super.setLayerVisibility(index, true)
    this.mapLayers[index].element.show()
  }
  /**
   * 在地图上隐藏指定图层名图层
   * @param {string} layername
   */
  hideLayer(layername) {
    var index = this.getLyrIndexByName(layername)
    if (index == -1) return
    super.setLayerVisibility(index, false)
    this.mapLayers[index].element.hide()
  }
  /*
   *注册事件
   */
  addEventListener(eventType, callback) {
    if (this.map == null) {
      return
    }
    var eEvt = eventType
    if (eventType == 'mouseover') {
      eEvt = 'mouse-over'
    } else if (eventType == 'mouseout') {
      eEvt = 'mouse-out'
    }
    super.addEvent(
      this.map.on(eEvt, function (e) {
        if (e.graphic) {
          return
        } // 存在覆盖物退出
        callback(e)
      }),
      eventType
    )
  }
  /*
   *移除事件
   */
  removeEventListener(eventType) {
    if (this.map == null) {
      return
    }
    if (eventType == 'mouseover') {
      eEvt = 'mouse-over'
    } else if (eventType == 'mouseout') {
      eEvt = 'mouse-out'
    }
    var inx = this.events.findIndex((item) => item.type === eventType)
    if (inx > -1) {
      this.events[inx].event.remove()
      this.events.splice(inx, 1)
    }
  }

  /**
   * 编辑指定图层
   * @param {string} layername 图层名
   */
  enableLayerEditing(layername) {
    var indx = this.getLyrIndexByName(layername)
    if (indx == -1) {
      return
    }
    var type = this.mapLayers[indx].type
    var lyrs = this.mapLayers[indx].element.graphics
    this.mapEditor.enableEditing(lyrs, type)
  }
  /**
   * 停止编辑指定图层
   */
  disableLayerEditing(layername = null) {
    this.mapEditor.disableEditing()
  }
}
