类名 common/document/layer/GraphicsLayer.js
import { ElevationInfo, FeatureSet, Zondy, Feature } from '../../base'
import { LayerType, LoadStatus } from '../../base/enum'
import {defaultValue, toJSON} from '../../util'
import { Layer } from './baseLayer'
import FeatureCollection from './support/FeatureCollection'
import {jsonClone} from '../../util/Utils';
import {setElevationInfo} from './Utils';

/**
 * 几何图形图层,不支持在线数据,仅支持传入多个几何对象并绘制<br/>
 * 目前二维和三维上支持4326(包括4490,4214以及4610),3857以及EPSG支持的自定义坐标系,若是想要绘制非4326坐标系几何,需要在初始化要素对象的几何时,指定具体坐标系
 * <br><br>[ES5引入方式]:<br/>
 * Zondy.Layer.GraphicsLayer() <br/>
 * [ES6引入方式]:<br/>
 * import { GraphicsLayer } from "@mapgis/webclient-common" <br/>
 * <br/>
 * 针对图层的操作请在图层加载完毕事件中进行<br/>
 * Layer.on('layerview-created', function (result) {<br/>
 *   console.log("加载完毕:", result.layer)<br/>
 * });<br/>
 * 如果不想在该事件中放入业务代码,则请确认图层资源已加载完毕后再进行操作<br/>
 * if(layer.loadStatus === 'loaded') {<br/>
 *   // 你的业务逻辑<br/>
 * }
 * @class GraphicsLayer
 * @moduleEX LayerModule
 * @classdesc 几何图形图层
 * @extends Layer
 * @fires Layer#图层加载完毕事件
 * @fires Layer#图层销毁完毕事件
 * @fires Layer#图层更新完毕事件
 * @fires Layer#图层显隐更新完毕事件
 * @fires Layer#图层透明度更新完毕事件
 * @fires Layer#图层顺序更新完毕事件
 * @fires GraphicsLayer#添加要素事件
 * @fires GraphicsLayer#添加多个要素事件
 * @fires GraphicsLayer#删除要素事件
 * @fires GraphicsLayer#删除多个要素事件
 * @fires GraphicsLayer#删除所有要素事件
 * @param {Object} options 构造参数
 * @param {Array<Feature>} [options.graphics] 几何对象,支持的几何数据如下:<br/>
 * [1、点几何]{@link Point}<br/>
 * [2、多点几何]{@link MultiPoint}<br/>
 * [3、线几何]{@link LineString}<br/>
 * [4、多线几何]{@link MultiLineString}<br/>
 * [5、区几何]{@link Polygon}<br/>
 * [6、多区几何]{@link MultiPolygon}<br/>
 * [7、矩形几何]{@link Extent}<br/>
 * [8、圆几何]{@link Circle}<br/>
 * 参考示例:<br/>
 * <a href='#GraphicsLayer'>[1、创建图层]</a><br/>
 * <a href='#remove'>[2、删除图层]</a><br/>
 * <a href='#add'>[3、添加要素]</a><br/>
 * <a href='#add-custom'>[4、添加自定义坐标系的要素]</a>
 * @param {String} [options.id] 图层id,不给则给一个随机的id
 * @param {Boolean} [options.visible = show] 图层可见性,参考示例:<a href='#visible'>[图层可见性]</a>
 * @param {Number} [options.opacity = 1] 图层透明度,0~1之间的值,0完全透明,1不透明,参考示例:<a href='#opacity'>[图层透明度]</a>
 * @param {ElevationInfo} [options.ElevationInfo] 高度参数
 *
 * @summary <h5>支持如下方法:</h5>
 * <a href='#add-feature'>[1、添加要素]</a><br/>
 * <a href='#delete-feature'>[2、删除要素]</a><br/>
 * <a href='#addMany'>[3、添加要素组]</a><br/>
 * <a href='#removeMany'>[4、删除要素组]</a><br/>
 * <a href='#removeAll'>[5、删除全部要素]</a><br/>
 * <a href='#fromJSON'>[6、通过传入的json构造并返回一个新的几何对象]</a><br/>
 * [7、导出为json对象]{@link OGCLayer#toJSON}<br/>
 * [8、克隆几何对象]{@link OGCLayer#clone}
 *
 * @example <caption><h7 id='GraphicsLayer'>初始化图层</h7></caption>
 * // ES5引入方式
 * const { Map,MapView,Feature,Color} = Zondy
 * const { Circle } = Zondy.Geometry
 * const { SimpleFillSymbol } = Zondy.Symbol
 * const { GraphicsLayer } = Zondy.Layer
 * // ES6引入方式
 * import { Map,MapView,Color,Feature,Circle, GraphicsLayer,SimpleFillSymbol} from "@mapgis/webclient-common"
 * // 初始化图层管理容器
 * const map = new Map();
 * // 初始化地图视图对象
 * const mapView = new MapView({
 *   // 视图id
 *   viewId: "viewer-id",
 *   // 图层管理容器
 *   map: map
 * });
 * // 创建一个要素
 * const feature = new Feature({
 *   //不填则创建一个随机的guid
 *   id: '你的id',
 *   //设置属性
 *   attributes: {},
 *   //构建几何
 *   geometry: new Circle({
 *     // 中心点
 *     center: [113, 30],
 *     // 半径
 *     radius: 4
 *   }),
 *   //设置样式
 *   symbol: new SimpleFillSymbol({
 *     //设置颜色
 *     color: new Color(255, 0, 112, 1)
 *   })
 * })
 * // 初始化几何图层
 * const graphicsLayer = new GraphicsLayer({
 *   graphics:[feature]
 * })
 * map.add(graphicsLayer)
 *
 * @example <caption><h7 id='remove'>删除图层</h7></caption>
 * map.remove(graphicsLayer)
 *
 * @example <caption><h7 id='add'>将要素添加入图层</h7></caption>
 * // ES5引入方式
 * const { Feature,Color} = Zondy
 * const { Circle } = Zondy.Geometry
 * const { SimpleFillSymbol } = Zondy.Symbol
 * const { GraphicsLayer } = Zondy.Layer
 * // ES6引入方式
 * import { Feature,Color,Circle, GraphicsLayer,SimpleFillSymbol} from "@mapgis/webclient-common"
 * // 创建一个要素
 * const feature = new Feature({
 *   //不填则创建一个随机的guid
 *   id: '你的id',
 *   //设置属性
 *   attributes: {},
 *   //构建几何
 *   geometry: new Circle({
 *     // 中心点
 *     center: [113, 30],
 *     // 半径
 *     radius: 4
 *   }),
 *   //设置样式
 *   symbol: new SimpleFillSymbol({
 *     //设置颜色
 *     color: new Color(255, 0, 112, 1)
 *   })
 * })
 * // 创建图层
 * const graphicsLayer = new GraphicsLayer()
 * map.add(graphicsLayer)
 * // 添加要素
 * graphicsLayer.add(feature)
 *
 * @example <caption><h7 id='add-custom'>添加自定义坐标系的要素</h7></caption>
 * // ES5引入方式
 * const { Feature,SpatialReference,Color} = Zondy
 * const { Circle } = Zondy.Geometry
 * const { SimpleFillSymbol } = Zondy.Symbol
 * const { GraphicsLayer } = Zondy.Layer
 * // ES6引入方式
 * import { Feature,SpatialReference,Color,Circle, GraphicsLayer,SimpleFillSymbol} from "@mapgis/webclient-common"
 * // 创建一个要素
 * const feature = new Feature({
 *   //构建几何
 *   geometry: new Circle({
 *     // 中心点
 *     center: [403511.251934197, 3320534.43647428],
 *     // 半径,单位像素
 *     radius: 4,
 *     // 设置坐标系
 *     spatialReference: new SpatialReference({
 *       wkid: '坐标系的wkid'
 *     })
 *   }),
 *   //设置样式
 *   symbol: new SimpleFillSymbol({
 *     //设置颜色
 *     color: new Color(255, 0, 112, 1)
 *   })
 * })
 * // 创建图层
 * const graphicsLayer = new GraphicsLayer()
 * map.add(graphicsLayer)
 * // 添加要素
 * graphicsLayer.add(feature)
 *
 * @example <caption><h7 id='visible'>图层可见性</h7></caption>
 *  // ES5引入方式
 * const { GraphicsLayer } = Zondy.Layer
 * // ES6引入方式
 * import {  GraphicsLayer } from "@mapgis/webclient-common"
 * // 创建图层时设置可见性
 * const graphicsLayer = new GraphicsLayer({
 *   // 设置图层visible
 *   visible: true
 * })
 * map.add(graphicsLayer)
 *
 * // 图层加载完成后,设置可见性
 * graphicsLayer.visible = !graphicsLayer.visible
 *
 * @example <caption><h7 id='opacity'>图层透明度</h7></caption>
 * // ES5引入方式
 * const { GraphicsLayer } = Zondy.Layer
 * // ES6引入方式
 * import {  GraphicsLayer } from "@mapgis/webclient-common"
 * // 创建图层时设置透明度
 * const graphicsLayer = new GraphicsLayer({
 *   opacity: 1
 * })
 * map.add(graphicsLayer)
 *
 * // 图层加载完成后,设置可见性
 * graphicsLayer.opacity = 0.5
 *
 * @example <caption><h7 id='index'>图层顺序</h7></caption>
 * // 加载完毕后,更改图层顺序
 * map.reorder(graphicsLayer, '要移动到的index');
 */

/**
 * 添加要素事件,请注意该事件是图层更新事件(layerview-update)的子事件
 * @event GraphicsLayer#添加要素事件
 * @property {Object} event 事件对象
 * @property {String} [event.type = 'layerview-update'] 图层更新完毕事件
 * @property {String} [event.message = null] 更新描述
 * @property {Array<UpdateContent>} [event.updateContent = null] 更新详情对象
 * @property {Layer} [event.layer = null] 地图图层对象
 * @property {MapView} [event.layerView = null] 图层的视图对象
 * @property {Layer} [event.sourceTarget = null] 事件发起对象
 * @property {Map} [event.target = null] 事件接收对象
 * @example <caption><h5>子图层显隐更新完毕事件</h5></caption>
 * Layer.on('layerview-update', function (event) {
 *   // 获取更新事件对象
 *   console.log("更新完毕:", event)
 *   // 获取更新详情数组
 *   const updateContent = event.updateContent
 *   // 循环数组,根据事件名进行后续操作
 *   for (let i = 0; i < updateContent.length; i++) {
 *     // 添加要素事件
 *     if(updateContent[i].name === 'add'){
 *       console.log("添加要素事件:", event);
 *     }
 *   }
 * });
 */

/**
 * 添加多个要素事件,请注意该事件是图层更新事件(layerview-update)的子事件
 * @event GraphicsLayer#添加多个要素事件
 * @property {Object} event 事件对象
 * @property {String} [event.type = 'layerview-update'] 图层更新完毕事件
 * @property {String} [event.message = null] 更新描述
 * @property {Array<UpdateContent>} [event.updateContent = null] 更新详情对象
 * @property {Layer} [event.layer = null] 地图图层对象
 * @property {MapView} [event.layerView = null] 图层的视图对象
 * @property {Layer} [event.sourceTarget = null] 事件发起对象
 * @property {Map} [event.target = null] 事件接收对象
 * @example <caption><h5>子图层显隐更新完毕事件</h5></caption>
 * Layer.on('layerview-update', function (event) {
 *   // 获取更新事件对象
 *   console.log("更新完毕:", event)
 *   // 获取更新详情数组
 *   const updateContent = event.updateContent
 *   // 循环数组,根据事件名进行后续操作
 *   for (let i = 0; i < updateContent.length; i++) {
 *     // 添加多个要素事件
 *     if(updateContent[i].name === 'addMany'){
 *       console.log("添加多个要素事件:", event);
 *     }
 *   }
 * });
 */

/**
 * 删除要素事件,请注意该事件是图层更新事件(layerview-update)的子事件
 * @event GraphicsLayer#删除要素事件
 * @property {Object} event 事件对象
 * @property {String} [event.type = 'layerview-update'] 图层更新完毕事件
 * @property {String} [event.message = null] 更新描述
 * @property {Array<UpdateContent>} [event.updateContent = null] 更新详情对象
 * @property {Layer} [event.layer = null] 地图图层对象
 * @property {MapView} [event.layerView = null] 图层的视图对象
 * @property {Layer} [event.sourceTarget = null] 事件发起对象
 * @property {Map} [event.target = null] 事件接收对象
 * @example <caption><h5>子图层显隐更新完毕事件</h5></caption>
 * Layer.on('layerview-update', function (event) {
 *   // 获取更新事件对象
 *   console.log("更新完毕:", event)
 *   // 获取更新详情数组
 *   const updateContent = event.updateContent
 *   // 循环数组,根据事件名进行后续操作
 *   for (let i = 0; i < updateContent.length; i++) {
 *     // 删除要素事件
 *     if(updateContent[i].name === 'remove'){
 *       console.log("删除要素事件:", event);
 *     }
 *   }
 * });
 */

/**
 * 删除多个要素事件,请注意该事件是图层更新事件(layerview-update)的子事件
 * @event GraphicsLayer#删除多个要素事件
 * @property {Object} event 事件对象
 * @property {String} [event.type = 'layerview-update'] 图层更新完毕事件
 * @property {String} [event.message = null] 更新描述
 * @property {Array<UpdateContent>} [event.updateContent = null] 更新详情对象
 * @property {Layer} [event.layer = null] 地图图层对象
 * @property {MapView} [event.layerView = null] 图层的视图对象
 * @property {Layer} [event.sourceTarget = null] 事件发起对象
 * @property {Map} [event.target = null] 事件接收对象
 * @example <caption><h5>子图层显隐更新完毕事件</h5></caption>
 * Layer.on('layerview-update', function (event) {
 *   // 获取更新事件对象
 *   console.log("更新完毕:", event)
 *   // 获取更新详情数组
 *   const updateContent = event.updateContent
 *   // 循环数组,根据事件名进行后续操作
 *   for (let i = 0; i < updateContent.length; i++) {
 *     // 删除多个要素事件
 *     if(updateContent[i].name === 'removeMany'){
 *       console.log("删除多个要素事件:", event);
 *     }
 *   }
 * });
 */

/**
 * 删除所有要素事件,请注意该事件是图层更新事件(layerview-update)的子事件
 * @event GraphicsLayer#删除所有要素事件
 * @property {Object} event 事件对象
 * @property {String} [event.type = 'layerview-update'] 图层更新完毕事件
 * @property {String} [event.message = null] 更新描述
 * @property {Array<UpdateContent>} [event.updateContent = null] 更新详情对象
 * @property {Layer} [event.layer = null] 地图图层对象
 * @property {MapView} [event.layerView = null] 图层的视图对象
 * @property {Layer} [event.sourceTarget = null] 事件发起对象
 * @property {Map} [event.target = null] 事件接收对象
 * @example <caption><h5>子图层显隐更新完毕事件</h5></caption>
 * Layer.on('layerview-update', function (event) {
 *   // 获取更新事件对象
 *   console.log("更新完毕:", event)
 *   // 获取更新详情数组
 *   const updateContent = event.updateContent
 *   // 循环数组,根据事件名进行后续操作
 *   for (let i = 0; i < updateContent.length; i++) {
 *     // 删除所有要素事件
 *     if(updateContent[i].name === 'removeAll'){
 *       console.log("删除所有要素事件:", event);
 *     }
 *   }
 * });
 */
class GraphicsLayer extends Layer {
  constructor(options) {
    super(options)
    options = defaultValue(options, {})
    this.type = LayerType.graphics
    /**
     * 最小比例尺,只有当地图视图的比例尺大于最小比例尺时显示覆盖物图层
     * @member {Number} GraphicsLayer.prototype.minScale
     */
    this.minScale = defaultValue(options.minScale, undefined)
    /**
     * 最大比例尺,只有当地图视图的比例尺小于最大比例尺时显示覆盖物图层
     * @member {Number} GraphicsLayer.prototype.maxScale
     */
    this.maxScale = defaultValue(options.maxScale, undefined)
    /**
     * token名
     * @member {String} GraphicsLayer.prototype.tokenKey
     */
    this.tokenKey = defaultValue(options.tokenKey, 'token')
    /**
     * token值
     * @member {String} GraphicsLayer.prototype.tokenValue
     */
    this.tokenValue = defaultValue(options.tokenValue, undefined)
    /**
     * 高程信息
     * @member {ElevationInfo} GraphicsLayer.prototype.elevationInfo
     */
    this.elevationInfo = defaultValue(
      options.elevationInfo,
      new ElevationInfo()
    )
    /**
     * 几何对象数组
     * @member {FeatureCollection<Feature>} GraphicsLayer.prototype.graphics
     */
    this.graphics = this._decorate(
      'graphics',
      options.graphics,
      FeatureCollection,
      FeatureCollection.collect
    )
    this.loadStatus = LoadStatus.loaded
  }

  /**
   * 添加要素,参考示例:<a id='add-feature' href='#add'>[添加要素]</a>
   * @param {Feature} feature 要添加的要素
   */
  add(feature) {
    if (!feature) return
    if (this._getFeatureIndexById(feature.id) > -1) {
      throw new Error(`id为'${feature.id}'的要素重复添加,请检查传入要素的id`)
    }
    // 如果要素上没有高程参数,就用图层上的,否则用要素自己的
    setElevationInfo(feature, this)
    this.graphics.add(feature)
    this._fireUpdateEvent('添加要素', [
      {
        params: arguments,
        dataChanged: true,
        name: 'add',
        operationType: 'method'
      }
    ])
  }

  /**
   * 删除要素
   * @param {Feature} feature 要删除的要素
   * @example <caption><h7 id='delete-feature'>删除要素</h7></caption>
   * // ES5引入方式
   * const { Feature,Color } = Zondy
   * const { Circle } = Zondy.Geometry
   * const { GraphicsLayer } = Zondy.Layer
   * const { SimpleFillSymbol } = Zondy.Symbol
   * // ES6引入方式
   * import {  Feature,Color,Circle,GraphicsLayer,SimpleFillSymbol } from "@mapgis/webclient-common"
   * // 创建一个要素
   * const feature = new Feature({
   *   //不填则创建一个随机的guid
   *   id: '你的id',
   *   //设置属性
   *   attributes: {},
   *   //构建几何
   *   geometry: new Circle({
   *     // 中心点
   *     center: [113, 30],
   *     // 半径
   *     radius: 4
   *   }),
   *   //设置样式
   *   symbol: new SimpleFillSymbol({
   *     //设置颜色
   *     color: new Color(255, 0, 112, 1)
   *   })
   * })
   * // 创建图层
   * const graphicsLayer = new GraphicsLayer()
   * graphicsLayer.add(feature)
   * map.add(graphicsLayer)
   * // 删除要素
   * graphicsLayer.remove(feature)
   */
  remove(feature) {
    if (!feature) return
    const fIndex = this._getFeatureIndexById(feature.id)
    if (fIndex === -1) return
    this._removeGraphicByIndex(fIndex)
    this._fireUpdateEvent('移除要素', [
      {
        params: arguments,
        dataChanged: true,
        name: 'remove',
        operationType: 'method'
      }
    ])
  }

  /**
   * 添加要素组
   * @param {FeatureSet | Array<Feature>} features 要添加的要素数组或集合
   * @example <caption><h7 id='addMany'>添加要素组</h7></caption>
   * // ES5引入方式
   * const { Feature } = Zondy
   * const { Circle } = Zondy.Geometry
   * const { GraphicsLayer } = Zondy.Layer
   * // ES6引入方式
   * import {  Feature,Circle,GraphicsLayer } from "@mapgis/webclient-common"
   * // 创建一个要素
   * const feature1 = new Feature({
   *   //构建几何
   *   geometry: new Circle({
   *     // 中心点
   *     center: [113, 30],
   *     // 半径
   *     radius: 4
   *   })
   * })
   * const feature2 = new Feature({
   *   //构建几何
   *   geometry: new Circle({
   *     // 中心点
   *     center: [123, 33],
   *     // 半径
   *     radius: 4
   *   })
   * })
   * // 创建图层
   * const graphicsLayer = new GraphicsLayer()
   * map.add(graphicsLayer)
   * // 一次添加多个要素
   * graphicsLayer.addMany([feature1, feature2])
   */
  addMany(features) {
    let featureArr = []
    if (features instanceof FeatureSet) {
      featureArr = features.clone().features.map((v) => v.clone())
    } else {
      featureArr = features.map((v) => v.clone())
    }
    featureArr.forEach((feature) => {
      this.graphics.add(feature)
    })
    this._fireUpdateEvent('添加要素组', [
      {
        params: arguments,
        dataChanged: true,
        name: 'addMany',
        operationType: 'method'
      }
    ])
  }

  /**
   * 删除要素组
   * @param {Array<Feature>} features 要删除的要素数组或集合
   * @example <caption><h7 id='removeMany'>删除要素组</h7></caption>
   * // ES5引入方式
   * const { Feature } = Zondy
   * const { Circle } = Zondy.Geometry
   * const { GraphicsLayer } = Zondy.Layer
   * // ES6引入方式
   * import {  Feature,Circle,GraphicsLayer } from "@mapgis/webclient-common"
   * // 创建一个要素
   * const feature1 = new Feature({
   *   //构建几何
   *   geometry: new Circle({
   *     // 中心点
   *     center: [113, 30],
   *     // 半径
   *     radius: 4
   *   })
   * })
   * const feature2 = new Feature({
   *   //构建几何
   *   geometry: new Circle({
   *     // 中心点
   *     center: [123, 33],
   *     // 半径
   *     radius: 4
   *   })
   * })
   * // 创建图层
   * const graphicsLayer = new GraphicsLayer({
   *   graphics: [feature1, feature2]
   * })
   * map.add(graphicsLayer)
   * // 一次删除多个要素
   * graphicsLayer.removeMany([feature1, feature2])
   */
  removeMany(features) {
    const featureArr = []
    if (!Array.isArray(features)) return
    features.forEach((v) => {
      const feature = this._getFeatureById(v.id)
      if (feature) {
        this._removeGraphic(feature)
        featureArr.push(feature)
      }
    })
    this._fireUpdateEvent('删除要素组', [
      {
        params: featureArr,
        dataChanged: true,
        name: 'removeMany',
        operationType: 'method'
      }
    ])
  }

  /**
   * 删除全部要素
   * @example <caption><h7 id='removeAll'>删除全部要素</h7></caption>
   * // ES5引入方式
   * const { Feature } = Zondy
   * const { Circle } = Zondy.Geometry
   * const { GraphicsLayer } = Zondy.Layer
   * // ES6引入方式
   * import {  Feature,Color,Circle,GraphicsLayer } from "@mapgis/webclient-common"
   * // 创建一个要素
   * const feature1 = new Feature({
   *   //构建几何
   *   geometry: new Circle({
   *     // 中心点
   *     center: [113, 30],
   *     // 半径
   *     radius: 4
   *   })
   * })
   * const feature2 = new Feature({
   *   //构建几何
   *   geometry: new Circle({
   *     // 中心点
   *     center: [123, 33],
   *     // 半径
   *     radius: 4
   *   })
   * })
   * // 创建图层
   * const graphicsLayer = new GraphicsLayer({
   *   graphics: [feature1, feature2]
   * })
   * map.add(graphicsLayer)
   * // 删除全部要素
   * graphicsLayer.removeAll()
   */
  removeAll() {
    this.graphics = []
    this._fireUpdateEvent('删除全部要素', [
      {
        params: arguments,
        dataChanged: true,
        name: 'removeAll',
        operationType: 'method'
      }
    ])
  }

  /**
   * 通过传入的json构造并返回一个新的几何对象<a id='fromJSON'></a>
   * @param {Object} [json] JSON对象
   * @example <caption><h7>通过传入的json构造并返回一个新的几何对象</h7></caption>
   * // ES5引入方式
   * const { Feature } = Zondy
   * const { Circle } = Zondy.Geometry
   * const { GraphicsLayer } = Zondy.Layer
   * // ES6引入方式
   * import {  Feature,Circle,GraphicsLayer } from "@mapgis/webclient-common"
   * // 创建一个要素
   * const feature1 = new Feature({
   *   //构建几何
   *   geometry: new Circle({
   *     // 中心点
   *     center: [113, 30],
   *     // 半径
   *     radius: 4
   *   })
   * })
   * const feature2 = new Feature({
   *   //构建几何
   *   geometry: new Circle({
   *     // 中心点
   *     center: [123, 33],
   *     // 半径
   *     radius: 4
   *   })
   * })
   * const json = {
   *   graphics: [feature1, feature2]
   * }
   * // 创建图层
   * const graphicsLayer = new GraphicsLayer.fromJSON(json)
   */
  static fromJSON(json) {
    json = jsonClone(json)
    const _layer = new GraphicsLayer(json)
    _layer._isFromJSON = true
    _layer.elevationInfo = new ElevationInfo(json.elevationInfo)

    const _graphics = []
    for (let i = 0; i < json.graphics.length; i++) {
      _graphics.push(new Feature(json.graphics[i]))
    }
    _layer.graphics = _graphics

    return _layer
  }

  /**
   * 子类加载服务端元信息的方法
   * @private
   * */
  _load() {
    return new Promise((resolve, reject) => {
      this.loadStatus = LoadStatus.loaded
      this.loaded = true
      resolve(this)
      reject('资源请求失败!')
    })
  }

  toJSON() {
    const _json = super.toJSON()

    _json.elevationInfo = toJSON(this.elevationInfo, ElevationInfo)

    const _graphics = []
    if (this.graphics) {
      this.graphics.forEach(function (feature) {
        _graphics.push(toJSON(feature, Feature))
      })
    }
    _json.graphics = _graphics

    return _json
  }

  _getFeatureIndexById(id) {
    return this.graphics.findIndex((v) => v.id === id)
  }

  _getFeatureById(id) {
    const graphicIndex = this._getFeatureIndexById(id)
    if (graphicIndex > -1) {
      return this.graphics[graphicIndex]
    }
    return null
  }

  _removeGraphic(feature) {
    const featureIndex = this._getFeatureIndexById(feature.id)
    this._removeGraphicByIndex(featureIndex)
  }

  _removeGraphicByIndex(index) {
    if (index === -1) return
    this.graphics.items.splice(index, 1)
  }
}
Zondy.Layer.GraphicsLayer = GraphicsLayer
export default GraphicsLayer
构造函数
成员变量
方法
事件