    import BaseServer from '../BaseServer'
    import { Zondy } from '../../base'
    import { FetchMethod } from '../../base/enum'
    import { defaultValue, isNull } from '../../util'

    /**
     * 地图服务
     * @class MapServer
     * @moduleEx ServiceModule
     * @extends BaseServer
     * @param {Object} options 构造参数
     * @example
     * //初始化MapServer服务对象
     * // ES5引入方式
     * const { MapServer } = Zondy.Service
     * // ES6引入方式
     * import { MapServer } from "@mapgis/webclient-common"
     * const mapServer = new MapServer({
     *   //从igs详情里面获取的服务地址
     *   url: 'http://localhost:8089/igs/rest/services/动态裁图/MapServer'
     * });
     */
    class MapServer extends BaseServer {
      constructor(options) {
        super(options)

        // 默认为igs2.0服务
        this.igsType = '2.0'

        // 是igs1.0服务
        if (
          this.url.indexOf('/igs/rest/mrcs/docs') > -1 ||
          this.url.indexOf('/igs/rest/mrms/docs') > -1
        ) {
          this.igsType = '1.0'
        }
      }

      /**
       * 请求失败时的回调
       * @callback queryFailure
       * @param {Object} result 回调参数
       * @param {Object} [result.data] 请求成功数据
       * @param {String} [result.msg] 响应信息
       * @param {Boolean} [result.succeed = true] 接口是否调用成功
       * @param {String} [result.errorCode = true] 请求失败时的错误码
       */

      /**
       * 请求成功时的回调
       * @callback queryLayerListSuccess
       * @param {Object} result 回调参数
       * @param {String} [result.msg] 响应信息
       * @param {Boolean} [result.succeed = true] 接口是否调用成功
       * @param {Object} [result.data] 请求成功数据
       * @param {Array} [result.data.layers] 图层信息数组
       * @param {Array} [result.data.layers[i].fields] 要素属性字段名数组
       * @param {String} [result.data.layers[i].geomType] 要素的几何类型
       * @param {Number} [result.data.layers[i].minScale] 最小缩放比
       * @param {Number} [result.data.layers[i].maxScale] 最大缩放比
       * @param {String} [result.data.layers[i].name] 图层名
       * @param {Object} [result.data.layers[i].range] 图层范围
       * @param {Object} [result.data.layers[i].spatialReference] 图层坐标系
       * @param {Object} [result.data.layers[i].supportedMethods] 图层支持的方法
       * @param {String} [result.data.layers[i].systemLibGuid] 系统库id
       * @param {String} [result.data.layers[i].systemLibName] 系统名称
       * @param {String} [result.data.layers[i].type] 图层类型
       * @param {String} [result.data.layers[i].type] 图层对应的GDBP地址
       * @param {Boolean} [result.data.layers[i].visible] 图层是否可见
       */

      /**
       * 获取图层列表信息
       * @param {Object} options 构造参数
       * @param {queryLayerListSuccess} [options.success] 请求成功时的回调
       * @param {queryFailure} [options.failure] 请求失败时的回调
       * @param {String} [options.clientId] 临时图层ID
       * @param {String} [options.mapIndex] 地图索引，IGS1.0参数
       * @param {String} [options.guid] 用户会话id，IGS1.0参数
       * @example
       * //获取图层列表信息
       * //回调方式
       * mapServer.queryLayerList({
       * 	success: function(result) {
       * 		console.log('请求成功：',result);
       * 	},
       * 	failure: function(result) {
       * 	  console.log('请求失败：',result);
       * 	}
       * });
       * //promise方式
       * mapServer.queryLayerList({
       * }).then(function (result) {
       *   console.log('请求成功：', result);
       * }).catch(function (result) {
       *   console.log(' n请求失败：', result);
       * });
       */
      queryLayerList(options) {
        if (this.igsType === '2.0') {
          // 调用基类的查询信息方法
          return this._querySimpleInfo(options, function (url) {
            // 拼装返回基地址
            return `${url}/layers?f=json`
          })
        } else if (this.igsType === '1.0') {
          // 设置PATH PARAMETERS校验
          const checkPathOpts = {
            mapIndex: {
              type: 'String'
            }
          }

          // 设置QUERY PARAMETERS校验
          const checkQueryOpts = {
            guid: {
              type: 'String'
            }
          }

          // 调用基类的查询信息方法
          return this._queryByParameters(
            options,
            checkPathOpts,
            checkQueryOpts,
            // 拼装返回基地址
            function (url, options) {
              url = url.replace('mrms', 'mrcs')
              return `${url}/${options.mapIndex}/layers?f=json`
            }
          )
        }
      }

      /**
       * 添加临时文档图层
       * @param {Object} options 构造参数
       * @param {Array} [options.addInfo] 图层添加信息，必填
       * @param {Function} [options.success] 请求成功时的回调
       * @param {queryFailure} [options.failure] 请求失败时的回调
       * @param {String} [options.clientId] 客户端Id
       */
      addLayer(options) {
        if (this.url.indexOf('/igs/rest/mrcs/docs/') > -1) {
          // 设置PATH PARAMETERS校验
          const checkPathOpts = {
            mapIndex: {
              type: 'String'
            }
          }

          // 设置QUERY PARAMETERS校验
          const checkQueryOpts = {
            s: {
              type: 'Array',
              required: true,
              process(s) {
                return `&s=${JSON.stringify(s)}`
              }
            }
          }

          options.method = FetchMethod.post
          // 调用基类的查询信息方法
          return this._queryByParameters(
            options,
            checkPathOpts,
            checkQueryOpts,
            // 拼装返回基地址
            function (url, options) {
              return `${url}/${options.mapIndex}/layers/add?f=json`
            }
          )
        } else {
          // 设置PATH PARAMETERS校验
          const checkPathOpts = {}

          // 设置QUERY PARAMETERS校验
          const checkQueryOpts = {
            addInfo: {
              type: 'Array',
              required: true,
              process(addInfo) {
                return `&addInfo=${JSON.stringify(addInfo)}`
              }
            },
            clientId: {
              type: 'String'
            }
          }

          options.method = FetchMethod.post
          // 调用基类的查询信息方法
          return this._queryByParameters(
            options,
            checkPathOpts,
            checkQueryOpts,
            // 拼装返回基地址
            function (url) {
              return `${url}/layers?addInfo`
            }
          )
        }
      }

      /**
       * 请求成功时的回调
       * @callback queryLayerInfoSuccess
       * @param {Object} result 回调参数
       * @param {String} [result.msg] 响应信息
       * @param {Boolean} [result.succeed = true] 接口是否调用成功
       * @param {Object} [result.data] 请求成功数据
       * @param {String} [result.data.childResources] 子资源
       * @param {String} [result.data.index] 图层序号或id
       * @param {Array} [result.data.fields] 要素属性字段名数组
       * @param {String} [result.data.geomType] 要素的几何类型
       * @param {Number} [result.data.minScale] 最小缩放比
       * @param {Number} [result.data.maxScale] 最大缩放比
       * @param {String} [result.data.name] 图层名
       * @param {Object} [result.data.range] 图层范围
       * @param {Object} [result.data.spatialReference] 图层坐标系
       * @param {Object} [result.data.supportedMethods] 图层支持的方法
       * @param {String} [result.data.systemLibGuid] 系统库id
       * @param {String} [result.data.systemLibName] 系统名称
       * @param {String} [result.data.type] 图层类型
       * @param {String} [result.data.type] 图层对应的GDBP地址
       * @param {Boolean} [result.data.visible] 图层是否可见
       */

      /**
       * 查询指定图层信息
       * @param {Object} options 构造参数
       * @param {String} [options.layerId] 图层id，必填
       * @param {queryLayerInfoSuccess} [options.success] 请求成功时的回调
       * @param {queryFailure} [options.failure] 请求失败时的回调
       * @param {String} [options.clientId] 客户端Id
       * @param {String} [options.mapIndex] 地图索引，igs1.0参数
       * @param {Boolean} [options.returnFullStyle] 是否返回全部信息的标志位
       * @param {String} [options.guid] 用户会话id
       * @example
       * //查询指定图层信息
       * //回调方式
       * mapServer.queryLayerInfo({
       *  //图层id
       * 	layerId: 0,
       * 	//成功回调
       * 	success: function(result) {
       * 		console.log('请求成功：',result);
       * 	},
       *  failure: function (result) {
       *    console.log('请求失败：', result);
       *  }
       * });
       * //promise方式
       * mapServer.queryLayerInfo({
       *   //图层id
       *   layerId: '0'
       * }).then(function (result) {
       *   console.log('请求成功：', result);
       * }).catch(function (result) {
       *   console.log(' n请求失败：', result);
       * });
       */
      queryLayerInfo(options) {
        if (this.igsType === '2.0') {
          // 调用基类的查询信息方法
          return this._queryInfoByLayerId(options, function (url, options) {
            // 拼装返回基地址
            return `${url}/layers/${options.layerId}?f=json`
          })
        } else if (this.igsType === '1.0') {
          // 设置PATH PARAMETERS校验
          const checkPathOpts = {
            mapIndex: {
              type: 'String'
            },
            layerId: {
              type: 'String'
            }
          }

          // 设置QUERY PARAMETERS校验
          const checkQueryOpts = {
            guid: {
              type: 'String'
            },
            returnFullStyle: {
              type: 'Boolean'
            }
          }

          // 调用基类的查询信息方法
          return this._queryByParameters(
            options,
            checkPathOpts,
            checkQueryOpts,
            // 拼装返回基地址
            function (url, options) {
              return `${url}/${options.mapIndex}/${options.layerId}?f=json`
            }
          )
        }
      }

      /**
       * 删除临时文档图层
       * @param {Object} options 构造参数
       * @param {String} [options.layerId] 图层id，必传
       * @param {Function} [options.success] 请求成功时的回调
       * @param {Function} [options.failure] 请求失败时的回调
       * @param {String} [options.clientId] 客户端Id
       */
      deleteLayer(options) {
        // 设置PATH PARAMETERS校验
        const checkPathOpts = {
          layerId: {
            type: 'String'
          }
        }

        // 设置QUERY PARAMETERS校验
        const checkQueryOpts = {
          clientId: {
            type: 'String'
          }
        }

        options.method = FetchMethod.delete
        // 调用基类的查询信息方法
        return this._queryByParameters(
          options,
          checkPathOpts,
          checkQueryOpts,
          // 拼装返回基地址
          function (url, options) {
            return `${url}/layers/${options.layerId}?f=json`
          }
        )
      }

      /**
       * 请求成功时的回调
       * @callback queryFeaturesSuccess
       * @param {Object} result 回调参数
       * @param {String} [result.msg] 响应信息
       * @param {Boolean} [result.succeed = true] 接口是否调用成功
       * @param {Object} [result.data] 请求成功数据
       * @param {FeatureSet} [result.data.featureSet] 查询的要素集合
       * @param {Array} [result.data.fields] 要素属性字段名数组
       * @param {String} [result.data.geomType] 要素的几何类型
       * @param {Number} [result.data.id] 图层id
       * @param {String} [result.data.name] 图层名
       * @param {Object} [result.data.spatialReference] 图层坐标系
       */

      /**
       * 指定图层的要素查询
       * @param {Object} options 构造参数
       * @param {String} [options.layerId] 图层id，必传
       * @param {queryFeaturesSuccess} [options.success] 请求成功时的回调
       * @param {queryFailure} [options.failure] 请求失败时的回调
       * @param {FetchMethod} [options.method = FetchMethod.get] 请求方式，包括FetchMethod.get，FetchMethod.post
       * @param {String} [options.where] 要素查询where条件，类似sql语句
       * @param {Geometry} [options.geometry] 要素查询几何条件
       * @param {Number} [options.distance = 0] 几何缓冲的距离，geometry为point、line时有效（若数据源为大数据PG数据，且geometryType为line或者point时为必填数据）
       * @param {Number} [options.geometryPrecision] 指定返回要素中几何坐标的小数点位数，例如2，则返回两位小数
       * @param {SpatialRelation} [options.spatialRel] 几何条件的空间判定规则，Intersects(相交)、EnvelopeIntersects(外包矩形相交)、Contains(包含)、Disjoint(相离)
       * @param {String} [options.outFields] 指定要输出的属性字段，可为*表示所有，多个用英文逗号分隔
       * @param {String} [options.objectIds] 过滤id，多个用英文逗号分隔(参数优先级很高，可能导致其它筛选条件失效)
       * @param {String} [options.orderByFields] 排序字段,格式: fieldName [ASC|DESC]
       * @param {String} [options.groupByFieldsForStatistics] 分组统计的字段信息,格式为field1,field2
       * @param {Number} [options.resultRecordCount = 20] 分页参数：结果返回条数，默认20
       * @param {Number} [options.resultOffset] 分页参数：跳过条数，例如resultOffset为4，则跳过前4条，从第5条开始返回resultRecordCount的数量
       * @param {Array<OutStatistic>} [options.outStatistics] 字段统计参数数组
       * @param {Boolean} [options.returnGeometry = true] 是否返回要素几何信息，默认为true
       * @param {Boolean} [options.returnAttribute = true] 是否返回要素属性，默认为true
       * @param {Boolean} [options.returnStyle = false] 是否返回要素样式，默认为false
       * @param {Boolean} [options.returnIdsOnly = false] 是否只返回要素id，默认为false
       * @param {Boolean} [options.returnCountOnly = false] 是否只返回要素条数，默认为false
       * @param {Boolean} [options.returnExtentOnly = false] 是否只返回范围，默认为false
       * @param {Boolean} [options.returnZ = false] 是否返回Z轴，默认为false
       * @example
       * //通过where语句进行查询
       * //回调方式
       * // ES5引入方式
       * const { Point } = Zondy.Geometry
       *  // ES6引入方式
       * import { Point } from "@mapgis/webclient-common"
       * mapServer.queryFeatures({
       *   //图层id
       *   layerId: '1',
       *   //where查询条件，类似sql语句，这里查询2011年GDP大于20的城市
       * 	 where: "GDP2011>20",
       * 	 //以GDP2011字段进行升序排序
       *   orderByFields: "GDP2011 ASC",
       * 	 //指定输出的属性字段为NAME,GDP2011
       * 	 outFields: "NAME,GDP2011",
       * 	 //指定返回要素中几何坐标的小数点位数为2
       * 	 geometryPrecision: 2,
       * 	 //成功返回结果
       * 	 success: function(result) {
       * 		 console.log('请求成功：',result);
       * 	 },
       * 	 failure: function(result) {
       * 		 console.log('请求失败：',result);
       * 	 }
       * });
       * //promise方式
       * //通过geometry语句进行查询
       * let point = new Point({
       * 	coordinates: [113.8178, 30.172834]
       * });
       * mapServer.queryFeatures({
       *   //图层id
       *   layerId: 1,
       *   //几何条件
       *   geometry: point,
       *   //设置缓冲距离，仅当几何类型为point、line时有效
       *   distance: 100
       * }).then(function (result) {
       *   console.log('请求成功：', result);
       * }).catch(function (result) {
       *   console.log(' n请求失败：', result);
       * });
       */
      queryFeatures(options) {
        // 设置PATH PARAMETERS校验
        const checkPathOpts = {
          layerId: {
            type: 'String'
          }
        }

        // 设置QUERY PARAMETERS校验
        const checkQueryOpts = {
          where: {
            type: 'String'
          },
          geometry: {
            type: 'Geometry'
          },
          distance: {
            type: 'Number'
          },
          geometryPrecision: {
            type: 'Number'
          },
          spatialRel: {
            type: 'String'
          },
          outFields: {
            type: 'String'
          },
          objectIds: {
            type: 'String'
          },
          orderByFields: {
            type: 'String'
          },
          groupByFieldsForStatistics: {
            type: 'String'
          },
          resultRecordCount: {
            type: 'Number'
          },
          resultOffset: {
            type: 'Number'
          },
          outStatistics: {
            type: 'OutStatistics'
          },
          returnGeometry: {
            type: 'Boolean'
          },
          returnAttribute: {
            type: 'Boolean'
          },
          returnStyle: {
            type: 'Boolean'
          },
          returnIdsOnly: {
            type: 'Boolean'
          },
          returnCountOnly: {
            type: 'Boolean'
          },
          returnExtentOnly: {
            type: 'Boolean'
          },
          returnZ: {
            type: 'Boolean'
          }
        }

        // 调用基类的查询信息方法
        return this._queryByParameters(
          options,
          checkPathOpts,
          checkQueryOpts,
          // 拼装返回基地址
          function (url, options) {
            return `${url}/layers/${options.layerId}/query?f=json`
          }
        )
      }

      /**
       * 设置图层的系统库
       * @param {Object} options 构造参数
       * @param {String} [options.layerId] 图层id，必填
       * @param {String} [options.systemLibId] 系统库id，必填
       * @param {String} [options.systemLibName] 系统库名，当systemLibId为空时有效，必填
       * @param {Function} [options.success] 请求成功时的回调
       * @param {Function} [options.failure] 请求失败时的回调
       */
      setSystemLib(options) {
        // 设置PATH PARAMETERS校验
        const checkPathOpts = {
          layerId: {
            type: 'String'
          }
        }

        // 设置QUERY PARAMETERS校验
        const checkQueryOpts = {
          systemLibId: {
            type: 'String',
            required: true
          },
          systemLibName: {
            type: 'String',
            required: true
          }
        }

        options.method = FetchMethod.put
        // 调用基类的查询信息方法
        return this._queryByParameters(
          options,
          checkPathOpts,
          checkQueryOpts,
          // 拼装返回基地址
          function (url, options) {
            return `${url}/layers/${options.layerId}/systemLib?f=json`
          }
        )
      }

      /**
       * 请求成功时的回调
       * @callback getLegendSuccess
       * @param {Object} result 回调参数
       * @param {String} [result.msg] 响应信息
       * @param {Boolean} [result.succeed = true] 接口是否调用成功
       * @param {Object} [result.data] 请求成功数据
       * @param {Array} [result.data.layers] 查询的图例集合
       * @param {String} [result.data.layers[i].layerId] 图层id
       * @param {String} [result.data.layers[i].layerName] 图层名称
       * @param {Array} [result.data.layers[i].legend] 图例数组
       * @param {Array} [result.data.layers[i].legend[j].contentType] 图例类型
       * @param {Number} [result.data.layers[i].legend[j].height] 图例高度
       * @param {Number} [result.data.layers[i].legend[j].width] 图例宽度
       * @param {Array} [result.data.layers[i].legend[j].values] 图例值数组
       * @param {String} [result.data.layers[i].legend[j].label] 注记
       * @param {String} [result.data.layers[i].legend[j].imageData] 图例的BASE64数据
       * @param {String} [result.data.minScale] 图例的最小缩放比
       * @param {String} [result.data.maxScale] 图例的最大缩放比
       * @param {Number} [result.data.total] 图例数量
       */

      /**
       * 获取图例
       * @param {Object} options 构造参数
       * @param {getLegendSuccess} [options.success] 请求成功时的回调
       * @param {queryFailure} [options.failure] 请求失败时的回调
       * @param {String} [options.layers] 图层索引列表，多个用英文逗号隔开
       * @param {String} [options.size] 图例图片的大小，格式：width,height
       * @param {String} [options.where] 属性条件,类SQL语句
       * @param {Extent} [options.bbox] 矩形范围过滤条件
       * @param {Number} [options.page] 图例结果分页页数
       * @param {Number} [options.pageSize] 图例结果分页大小
       * @param {Number} [options.maxQueryFeatureCount] 查询要素的最大条数
       * @example
       * //回调方式
       * mapServer.getLegend({
       *   layers: "0",
       *   size: '45,45',
       *   success: function (result) {
       *     console.log('请求成功：', result);
       *   },
       *   failure: function (result) {
       *     console.log('请求失败：', result);
       *   }
       * });
       * //promise方式
       * mapServer.getLegend({
       *   layers: "1"
       * }).then(function (result) {
       *   console.log('请求成功：', result);
       * }).catch(function (result) {
       *   console.log('请求失败：', result);
       * });
       */
      getLegend(options) {
        // 设置PATH PARAMETERS校验
        const checkPathOpts = {}

        // 设置QUERY PARAMETERS校验
        const checkQueryOpts = {
          layers: {
            type: 'String'
          },
          where: {
            type: 'String'
          },
          bbox: {
            type: 'Extent'
          },
          page: {
            type: 'Number'
          },
          pageSize: {
            type: 'Number'
          },
          maxQueryFeatureCount: {
            type: 'Number'
          },
          clientId: {
            type: 'String'
          },
          size: {
            type: 'String'
          }
        }

        // 调用基类的查询信息方法
        return this._queryByParameters(
          options,
          checkPathOpts,
          checkQueryOpts,
          // 拼装返回基地址
          function (url) {
            return `${url}/legend?f=json`
          }
        )
      }

      /**
       * 请求成功时的回调
       * @callback queryFeaturesInLayersSuccess
       * @param {Object} result 回调参数
       * @param {String} [result.msg] 响应信息
       * @param {Boolean} [result.succeed = true] 接口是否调用成功
       * @param {Object} [result.data] 请求成功数据
       * @param {Array} [result.layers] 要素查询结果，以图层分组
       * @param {FeatureSet} [result.layers[i].featureSet] 要素查询结果集合
       * @param {Array} [result.data.layers[i].fields] 要素属性字段名数组
       * @param {String} [result.data.layers[i].geomType] 要素的几何类型
       * @param {Number} [result.data.layers[i].id] 图层id
       * @param {String} [result.data.layers[i].name] 图层名
       * @param {Object} [result.data.layers[i].spatialReference] 图层坐标系
       */

      /**
       * 多图层的要素查询
       * @param options 要素查询参数
       * @param {queryFeaturesInLayersSuccess} [options.success] 查询成功回调函数，若使用Promise方式则不必填写
       * @param {queryFailure} [options.failure] 查询失败回调函数，若使用Promise方式则不必填写
       * @param {Array} [options.layerDefs] 多图层的属性条件,包括layerId、where、outFields；当值为空时，查询所有图层，示例："[{ "layerId":"0-0","where": "name='中国'", "outfields": "field1,field2"}]"
       * @param {Geometry} [options.geometry] 要素查询几何条件
       * @param {Number} [options.distance = 0] 几何缓冲的距离，geometry为point、line时有效（若数据源为大数据PG数据，且geometryType为line或者point时为必填数据）
       * @param {Number} [options.geometryPrecision] 返回要素几何信息中坐标xy的精度
       * @param {SpatialRelation} [options.spatialRel] 几何条件的空间判定规则，Intersects(相交)、EnvelopeIntersects(外包矩形相交)、Contains(包含)、Disjoint(相离)
       * @param {Number} [options.resultRecordCount = 20] 分页参数：结果返回条数，默认20
       * @param {Boolean} [options.returnGeometry = true] 是否返回几何，默认为true
       * @param {Boolean} [options.returnAttribute = true] 是否返回属性，默认为true
       * @param {Boolean} [options.returnStyle = false] 是否返回图形参数信息，默认为false
       * @param {Boolean} [options.returnIdsOnly = false] 是否只返回id，默认为false
       * @param {Boolean} [options.returnCountOnly = false] 是否只返回条数，默认为false
       * @param {Boolean} [options.returnZ = false] 是否返回Z轴，默认为false
       * @example
       * //回调方式
       * // ES5引入方式
       * const { Extent } = Zondy.Geometry
       * const { FetchMethod } = Zondy.Enum
       * // ES6引入方式
       * import { Extent,FetchMethod } from "@mapgis/webclient-common"
       * mapServer.queryFeaturesInLayers({
       *   geometry: new Extent({
       *     xmin: 110.66,
       *     ymin: 29.61,
       *     xmax: 114.05,
       *     ymax: 32.43
       *   }),
       *   method: FetchMethod.post,
       *   success: function (result) {
       *     console.log('请求成功：', result);
       *   },
       *   failure: function (result) {
       *     console.log('请求击败：', result);
       *   }
       * });
       * //promise方式
       * mapServer.queryFeaturesInLayers({
       *   layerDefs: [{
       *     layerId: "0",
       *     outfields: "mpLayer,mpPerimeter"
       *   },{
       *     layerId: "1",
       *     where: "mpLayer=1",
       *     outfields: "mpLayer"
       *   }]
       * }).then(function (result) {
       *   console.log('请求成功：', result);
       * }).catch(function (result) {
       *   console.log(' n请求失败：', result);
       * });
       */
      queryFeaturesInLayers(options) {
        // 设置PATH PARAMETERS校验
        const checkPathOpts = {}

        // 设置QUERY PARAMETERS校验
        const checkQueryOpts = {
          layerDefs: {
            type: 'Array',
            process(layerDefs) {
              return `&layerDefs=${JSON.stringify(layerDefs)}`
            }
          },
          geometry: {
            type: 'Geometry'
          },
          distance: {
            type: 'Number'
          },
          geometryPrecision: {
            type: 'Number'
          },
          spatialRel: {
            type: 'String'
          },
          resultRecordCount: {
            type: 'Number'
          },
          returnGeometry: {
            type: 'Boolean'
          },
          returnAttribute: {
            type: 'Boolean'
          },
          returnStyle: {
            type: 'Boolean'
          },
          returnIdsOnly: {
            type: 'Boolean'
          },
          returnCountOnly: {
            type: 'Boolean'
          },
          returnZ: {
            type: 'Boolean'
          }
        }

        // 调用基类的查询信息方法
        return this._queryByParameters(
          options,
          checkPathOpts,
          checkQueryOpts,
          // 拼装返回基地址
          function (url) {
            return `${url}/query?f=json`
          }
        )
      }

      /**
       * 根据参数获取图片的url
       * @param options
       * @param {Extent} [options.extent] 图片范围
       * @param {Number} [options.width = 256] 图片宽度，单位像素
       * @param {Number} [options.height = 256] 图片高度，单位像素
       * @return String 图片的url
       * */
      getImage(options) {
        options = defaultValue(options, {})

        let url = `${this.url}/image?f=image`

        const extent = defaultValue(options.extent, undefined)
        if (!isNull(extent)) {
          url += `&bbox=${extent.toString()}`
        }

        const width = defaultValue(options.width, 256)
        const height = defaultValue(options.height, 256)
        if (!isNull(width) && !isNull(height)) {
          url += `&size=${width},${height}`
        }
        return url
      }

      exportImage(options) {
        options = defaultValue(options, {})
        options.method = FetchMethod.post
        options.headers = {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
        options.responseType = 'blob'

        // 设置PATH PARAMETERS校验
        const checkPathOpts = {}

        // 设置QUERY PARAMETERS校验
        const checkQueryOpts = {
          size: {
            type: 'String'
          },
          clientId: {
            type: 'String'
          },
          format: {
            type: 'String'
          },
          layers: {
            type: 'String'
          },
          dynamicLayers: {
            type: 'String'
          },
          imageTransparent: {
            type: 'Boolean'
          },
          f: {
            type: 'String'
          },
          bbox: {
            type: 'String'
          }
        }

        // 调用基类的查询信息方法
        return this._queryByParameters(
          options,
          checkPathOpts,
          checkQueryOpts,
          // 拼装返回基地址
          function (url) {
            return `${url}/image`
          }
        )
      }
    }

    Zondy.Service.MapServer = MapServer
    export default MapServer