    import BaseServer from '../BaseServer'
    import { Zondy } from '../../base'
    import { defaultValue, Log } from '../../util'
    import { FetchMethod } from '../../base/enum'
    import { checkParam } from '../Utils'

    /**
     * 场景服务
     * @class SceneServer
     * @moduleEx ServiceModule
     * @extends BaseServer
     * @param {Object} options 构造参数
     * @param {String} [options.url] 服务基地址
     * @example <caption><h5>IGS2.0的SceneServer</h5></caption>
     * // ES5引入方式
     * const { SceneServer } = Zondy.Service
     * // ES6引入方式
     * import { SceneServer } from "@mapgis/webclient-common
     * const sceneServer = new SceneServer({
     *   // 服务基地址，folder为igs服务的文件夹名，没有可不填，serviceName为服务名
     *   url: 'http://{ip}:{port}/igs/rest/services/{folder}/{serviceName}/SceneServer'
     * });
     *
     * @example <caption><h5>G3DServer</h5></caption>
     * // ES5引入方式
     * const { SceneServer } = Zondy.Service
     * // ES6引入方式
     * import { SceneServer } from "@mapgis/webclient-common
     * const sceneServer = new SceneServer({
     *   // 服务基地址，serviceName为服务名，端口号为6163则是.net服务，端口号为8089则是java服务
     *   url: 'http://{ip}:{port}/igs/rest/g3d/{serviceName}'
     * });
     *
     * @example <caption><h5>设置拦截器</h5></caption>
     * // ES5引入方式
     * const { SceneServer } = Zondy.Service
     * // ES6引入方式
     * import { SceneServer } from "@mapgis/webclient-common
     * const sceneServer = new SceneServer({
     *   // 服务基地址，folder为igs服务的文件夹名，没有可不填，serviceName为服务名
     *   url: 'http://localhost:8089/igs/rest/services/{folder}/{serviceName}/SceneServer'
     *   // 请求发送前的拦截器
     *   requestInterceptor: {
     *     before: function (config) {
     *       return config;
     *     },
     *     failure: function (error) {
     *       console.log("请求发送失败(拦截器):", error)
     *     }
     *   },
     *   // 请求完成后的拦截器
     *   responseInterceptor: {
     *     success: function (result) {
     *       console.log("请求成功拦截响应")
     *       return result;
     *     },
     *     failure: function (result) {
     *       console.log("请求失败拦截响应")
     *       return result;
     *     }
     *   }
     * });
     */
    class SceneServer extends BaseServer {
      constructor(options) {
        super(options)
      }

      /**
       * 请求成功时的回调
       * @callback queryLayerListInfoSuccess
       * @param {Object} result 回调参数
       * @param {String} [result.msg] 响应信息
       * @param {Boolean} [result.succeed = true] 接口是否调用成功
       * @param {Object} [result.data] 请求成功数据
       * @param {Object} [result.data.layers] [图层信息数组]{@link queryLayerInfoSuccess}
       */

      /**
       * 获取图层列表信息，IGS2.0服务
       * @param options 查询参数
       * @param {queryLayerListInfoSuccess} [options.success] 查询成功回调函数，若使用Promise方式则不必填写
       * @param {queryFailure} [options.failure] 查询失败回调函数，若使用Promise方式则不必填写
       * @example <caption><h5>获取图层列表信息-回调方式</h5></caption>
       * sceneServer.queryLayerListInfo({
       *   success: function (result) {
       *     console.log('请求成功：', result);
       *   },
       *   failure: function (result) {
       *     console.log('请求失败：', result);
       *   }
       * });
       *
       * @example <caption><h5>获取图层列表信息-promise方式</h5></caption>
       * const server = sceneServer.queryLayerListInfo();
       * server.then(function (result) {
       *   console.log('请求成功：', result);
       * }).catch(function (result) {
       *   console.log('请求失败：', result);
       * })
       */
      queryLayerListInfo(options) {
        // 调用基类的查询信息方法
        return this._querySimpleInfo(options, function (url) {
          // 拼装返回基地址
          return `${url}/layers?f=json`
        })
      }

      /**
       * 请求成功时的回调
       * @callback queryLayerInfoSuccess
       * @param {Object} result 回调参数
       * @param {String} [result.msg] 响应信息
       * @param {Boolean} [result.succeed = true] 接口是否调用成功
       * @param {Object} [result.data] 请求成功数据
       * @param {Number} [result.data.beginLevel] 起始级数
       * @param {Array} [result.data.children] 子图层
       * @param {String} [result.data.dataType] 数据类型
       * @param {Boolean} [result.data.displayGridNet] 是否显示网格点
       * @param {Boolean} [result.data.displaySceneBox] 是否显示外包盒
       * @param {Number} [result.data.endLevel] 结束级数
       * @param {Array} [result.data.frameSizes] frameSizes
       * @param {String} [result.data.gdbpUrl] 图层对应的GDPB地址
       * @param {String} [result.data.layerIndex] 图层序号
       * @param {Number} [result.data.layerLodNum] layerLodNum
       * @param {String} [result.data.layerName] 图层名
       * @param {Number} [result.data.layerRenderIndex] layerRenderIndex
       * @param {Number} [result.data.layerRenderType] layerRenderType
       * @param {String} [result.data.layerType] 图层类型
       * @param {Number} [result.data.lodDistance] lodDistance
       * @param {Number} [result.data.maxDisplayDistance] 最大显示距离
       * @param {Number} [result.data.minDisplayDistance] 最小显示距离
       * @param {Number} [result.data.minDisplayPixel] 最小显示像素
       * @param {Array} [result.data.originalPoints] 原点坐标
       * @param {String} [result.data.ownerLayers] ownerLayers
       * @param {Array} [result.data.position] position
       * @param {Object} [result.data.range] 图层范围
       * @param {Object} [result.data.range3D] 图层范围(3D)
       * @param {Array} [result.data.scale] 图层缩放
       * @param {Object} [result.data.spatialReference] 图层坐标系
       * @param {Number} [result.data.topLevelDataNum] topLevelDataNum
       * @param {Number} [result.data.transparency] 图层透明度
       * @param {String} [result.data.url] 图层GDBP地址
       * @param {String} [result.data.version] 版本号
       * @param {Boolean} [result.data.visible] 是否可见
       */

      /**
       * 获取图层信息，IGS2.0服务
       * @param options 查询参数
       * @param {String} [options.layerId] 图层id，必填
       * @param {queryLayerInfoSuccess} [options.success] 查询成功回调函数，若使用Promise方式则不必填写
       * @param {queryFailure} [options.failure] 查询失败回调函数，若使用Promise方式则不必填写
       * @example
       * //回调方式
       * const server = sceneServer.queryLayerInfo({
       *   layerId: "0",
       *   success: function (result) {
       *     console.log('请求成功：', result);
       *   },
       *   failure: function (result) {
       *     console.log('请求失败：', result);
       *   }
       * });
       * //promise方式
       * const server = sceneServer.queryLayerInfo({
       *   layerId: "0"
       * });
       * server.then(function (result) {
       *   console.log('请求成功：', result);
       * }).catch(function (result) {
       *   console.log('请求失败：', result);
       * })
       */
      queryLayerInfo(options) {
        // 调用基类的查询信息方法
        return this._queryInfoByLayerId(options, function (url, options) {
          // 拼装返回基地址
          return `${url}/layers/${options.layerId}?f=json`
        })
      }

      /**
       * 获取指定覆盖物图层的数据，IGS2.0服务
       * @param options 查询参数
       * @param {String} [options.layerId] 图层id，必填
       * @param {Function} [options.success] 查询成功回调函数，若使用Promise方式则不必填写
       * @param {queryFailure} [options.failure] 查询失败回调函数，若使用Promise方式则不必填写
       * @param {Extent} [options.bbox] 出图范围
       * @param {String} [options.size = '512,512'] 图片大小，格式：width,height，默认512,512
       * @param {Boolean} [options.transparent = true] 返回的图片是否透明，支持true/false, 默认true
       * @param {ReturnFormat} [options.format = ReturnFormat.png] 返回图片格式，支持png/jpg/gif，默认png
       * @param {Boolean} [options.isAntialiasing = false] 返回的图片是否抗锯齿，支持true/false, 默认false
       * @example
       * //回调方式
       * // ES5引入方式
       * const { Extent } = Zondy.Geometry
       * // ES6引入方式
       * import { Extent } from "@mapgis/webclient-common"
       * sceneServer.getCoverings({
       *   layerId: '0',
       *   bbox: new Extent({
       *     "xmin":-180,
       *     "ymin":-90,
       *     "xmax":180,
       *     "ymax":90,
       *   }),
       *   size: "512,512",
       *   format: "png",
       *   transparent: true,
       *   isAntialiasing: true,
       *   success: function (result) {
       *     console.log('请求成功：', result);
       *   }
       * });
       * //promise方式
       * sceneServer.getCoverings({
       *   layerId: '0'
       * }).then(function (result) {
       *   console.log('请求成功：', result);
       * }).catch(function (result) {
       *   console.log('请求失败：', result);
       * });
       */
      getCoverings(options) {
        options = defaultValue(options, {})

        // 检查PathParameters参数
        if (!this._checkPathParameters(options)) {
          return
        }
        // 设置返回格式，必须为JSON
        const url = `${this.url}/layers/${options.layerId}/coverings?f=image`
        // 请求方式为GET
        options.method = FetchMethod.get

        // 检查参数
        const checkOptions = {
          bbox: {
            type: 'Extent'
          },
          size: {
            type: 'String'
          },
          transparent: {
            type: 'Boolean'
          },
          format: {
            type: 'String'
          },
          isAntialiasing: {
            type: 'Boolean'
          }
        }

        Log.info('SceneServer.getCoverings。')
        return this._checkAndRequest(
          checkParam(options, checkOptions),
          url,
          options
        )
      }

      /**
       * 请求成功时的回调
       * @callback queryM3DInfoSuccess
       * @param {Object} result 回调参数
       * @param {String} [result.msg] 响应信息
       * @param {Boolean} [result.succeed = true] 接口是否调用成功
       * @param {Object} [result.data] 请求成功数据
       * @param {String} [result.data.WKT] 空间参考系参数
       * @param {Object} [result.data.asset] M3D信息
       * @param {Boolean} [result.data.asset.compression] 是否压缩
       * @param {String} [result.data.asset.gltfUpAxis] 模型主轴
       * @param {String} [result.data.asset.guid] 模型的id
       * @param {String} [result.data.asset.layerName] 图层名
       * @param {String} [result.data.asset.lodStrategyType] lodStrategyType
       * @param {Boolean} [result.data.asset.monomerization] 是否单体化
       * @param {Array} [result.data.asset.offset] 模型偏移
       * @param {String} [result.data.asset.version] 模型版本
       * @param {Object} [result.data.root] 节点信息
       * @param {Object} [result.data.root.boundingVolume] 外包盒
       * @param {Array} [result.data.root.children] 子节点
       * @param {Number} [result.data.root.geometricError] 几何误差
       * @param {String} [result.data.root.refine] 数据加载方式，replace或者add
       * @param {Array} [result.data.root.transform] 矩阵信息
       * @param {Array} [result.data.geometricError] 几何误差
       */

      /**
       * 获取指定图层的M3d数据信息，IGS2.0服务
       * @param options 查询参数
       * @param {String} [options.layerId] 图层id，必填
       * @param {queryM3DInfoSuccess} [options.success] 查询成功回调函数，若使用Promise方式则不必填写
       * @param {queryFailure} [options.failure] 查询失败回调函数，若使用Promise方式则不必填写
       * @example
       * // 回调方式
       * sceneServer.queryM3DInfo({
       *   layerId: '0',
       *   success: function (result) {
       *     console.log('请求成功：', result);
       *   },
       *   failure: function (result) {
       *     console.log('请求失败：', result);
       *   }
       * });
       * // promise方式
       * sceneServer.queryM3DInfo({
       *   layerId: '0'
       * }).then(function (result) {
       *   console.log('请求成功：', result);
       * }).catch(function (result) {
       *   console.log('请求失败：', result);
       * });
       */
      queryM3DInfo(options) {
        // 调用基类的查询信息方法
        return this._queryInfoByLayerId(options, function (url, options) {
          // 拼装返回基地址
          return `${url}/layers/${options.layerId}/m3d?f=json`
        })
      }

      /**
       * 请求成功时的回调
       * @callback queryRootNodeInfoSuccess
       * @param {Object} result 回调参数
       * @param {String} [result.msg] 响应信息
       * @param {Boolean} [result.succeed = true] 接口是否调用成功
       * @param {Object} [result.data] 请求成功数据
       * @param {Object} [result.data.boundingVolume] 节点外包盒
       * @param {Array} [result.data.childrenNode] 子节点
       * @param {Number} [result.data.lodError] lodError
       * @param {Number} [result.data.lodLevel] lodLevel
       * @param {String} [result.data.lodMode] lodMode
       * @param {String} [result.data.name] 节点名
       */

      /**
       * 获取指定M3d图层的根节点信息，IGS2.0服务
       * @param options 查询参数
       * @param {String} [options.layerId] 图层id，必填
       * @param {queryRootNodeInfoSuccess} [options.success] 查询成功回调函数，若使用Promise方式则不必填写
       * @param {queryFailure} [options.failure] 查询失败回调函数，若使用Promise方式则不必填写
       * @param {String} [options.include] 返回节点信息包括的类型，默认为空，等于descendants时返回节点信息包括节点的子孙后代
       * @param {Number} [options.maxDepth = 1] 节点最大深度
       * @param {Number} [options.maxCount = 1000] 节点最大个数
       * @example
       * // 回调方式
       * sceneServer.queryRootNodeInfo({
       *    layerId: '0',
       *    success: function (result) {
       *      console.log('请求成功：', result);
       *    },
       *    failure: function (result) {
       *      console.log('请求失败：', result);
       *    }
       *  });
       *  //promise方式
       *  sceneServer.queryRootNodeInfo({
       *    layerId: '0'
       *  }).then(function (result) {
       *    console.log('请求成功：', result);
       *  }).catch(function (result) {
       *    console.log('请求失败：', result);
       *  });
       */
      queryRootNodeInfo(options) {
        // 设置PATH PARAMETERS校验
        const checkPathOpts = {
          layerId: {
            type: 'String'
          }
        }

        // 设置QUERY PARAMETERS校验
        const checkQueryOpts = {
          include: {
            type: 'String'
          },
          maxDepth: {
            type: 'Number'
          },
          maxCount: {
            type: 'Number'
          }
        }

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

      /**
       * 请求成功时的回调
       * @callback queryNodeInfoSuccess
       * @param {Object} result 回调参数
       * @param {String} [result.msg] 响应信息
       * @param {Boolean} [result.succeed = true] 接口是否调用成功
       * @param {Object} [result.data] 请求成功数据
       * @param {Object} [result.data.boundingVolume] 节点外包盒
       * @param {Array} [result.data.childrenNode] 子节点
       * @param {Number} [result.data.lodError] lodError
       * @param {Number} [result.data.lodLevel] lodLevel
       * @param {String} [result.data.lodMode] lodMode
       * @param {String} [result.data.name] 节点名
       * @param {String} [result.data.nodeId] 节点ID
       * @param {String} [result.data.nodeUrl] 节点URL
       * @param {Object} [result.data.parentNode] 父节点
       * @param {Object} [result.data.shared] shared
       * @param {Number} [result.data.tileDataInfoIndex] tileDataInfoIndex
       * @param {Array} [result.data.tileDataInfoList] []
       * @param {Array} [result.data.transform] 节点矩阵
       */

      /**
       * 获取指定M3d图层的节点信息，IGS2.0服务
       * @param options 查询参数
       * @param {String} [options.layerId] 图层id，必填
       * @param {String} [options.nodeId] 节点id，必填
       * @param {queryNodeInfoSuccess} [options.success] 查询成功回调函数，若使用Promise方式则不必填写
       * @param {queryFailure} [options.failure] 查询失败回调函数，若使用Promise方式则不必填写
       * @param {String} [options.include] 返回节点信息包括的类型，默认为空，等于descendants时返回节点信息包括节点的子孙后代
       * @param {Number} [options.maxDepth = 1] 节点最大深度
       * @param {Number} [options.maxCount = 1000] 节点最大个数
       * @example
       * // 回调方式
       * sceneServer.queryNodeInfo({
       *   layerId: '0',
       *   nodeId: '1',
       *   success: function (result) {
       *     console.log('请求成功：', result);
       *   },
       *   failure: function (result) {
       *     console.log('请求失败：', result);
       *   }
       * });
       * // promise方式
       * sceneServer.queryNodeInfo({
       *   layerId: '0',
       *   nodeId: '1'
       * }).then(function (result) {
       *   console.log('请求成功：', result);
       * }).catch(function (result) {
       *   console.log('请求失败：', result);
       * });
       */
      queryNodeInfo(options) {
        // 设置PATH PARAMETERS校验
        const checkPathOpts = {
          layerId: {
            type: 'String'
          },
          nodeId: {
            type: 'String'
          }
        }

        // 设置QUERY PARAMETERS校验
        const checkQueryOpts = {
          include: {
            type: 'String'
          },
          maxDepth: {
            type: 'Number'
          },
          maxCount: {
            type: 'Number'
          }
        }

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

      /**
       * 获取指定图层的M3d共享资源，IGS2.0服务
       * @param options 查询参数
       * @param {String} [options.layerId] 图层id，必填
       * @param {Function} [options.success] 查询成功回调函数，若使用Promise方式则不必填写
       * @param {queryFailure} [options.failure] 查询失败回调函数，若使用Promise方式则不必填写
       * @example
       * // 回调方式
       * sceneServer.getSharedResources({
       *   layerId: '0',
       *   success: function (result) {
       *     console.log('请求成功：', result);
       *   },
       *   failure: function (result) {
       *     console.log('请求失败：', result);
       *   }
       * });
       * // promise方式
       * sceneServer.getSharedResources({
       *   layerId: '0'
       * }).then(function (result) {
       *     console.log('请求成功：', result);
       *   }).catch(function (result) {
       *     console.log('请求失败：', result);
       *   });
       */
      getSharedResources(options) {
        // 调用基类的查询信息方法
        return this._queryInfoByLayerId(
          options,
          // 拼装返回基地址
          function (url, options) {
            return `${url}/layers/${options.layerId}/m3d/sharedResources`
          }
        )
      }

      /**
       * 指定图层的要素查询，IGS2.0服务
       * @param options 要素查询参数
       * @param {String} [options.layerId] 图层id，必填
       * @param {FetchMethod} [options.method = FetchMethod.get] 请求类型，FetchMethod.get或FetchMethod.post
       * @param {queryFeaturesSuccess} [options.success] 查询成功回调函数，若使用Promise方式则不必填写
       * @param {queryFailure} [options.failure] 查询失败回调函数，若使用Promise方式则不必填写
       * @param {Geometry} [options.geometry] 要素查询几何条件
       * @param {String} [options.where] 要素查询where条件
       * @param {String} [options.outFields] 输出属性字段，可为*表示所有，多个用英文逗号分隔
       * @param {String} [options.objectIds] 过滤id，多个用英文逗号分隔(参数优先级很高，可能导致其它筛选条件失效)
       * @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 {String} [options.orderByFields] 排序字段,格式: fieldName [ASC|DESC]
       * @param {String} [options.groupByFieldsForStatistics] 分组统计的字段信息,格式为field1,field2
       * @param {Number} [options.resultRecordCount = 20] 分页参数：结果返回条数，默认20
       * @param {Number} [options.resultOffset] 分页参数：跳过条数
       * @param {Array} [options.outStatistics] 计算一个或多个基于字段的统计信息结构,统计类型包括:FUNCTION_MAX/FUNCTION_MIN/FUNCTION_SUM/FUNCTION_AVG/FUNCTION_COUNT/FUNCTION_MAX_OID，示例："[{"statisticType": "FUNCTION_SUM","onStatisticField": "field1","outStatisticFieldName":"fieldName1"}]"
       * @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
       * // 回调方式
       * // ES5引入方式
       * const { Point } = Zondy.Geometry
       * // ES6引入方式
       * import { Point } from "@mapgis/webclient-common"
       * sceneServer.queryFeatures({
       *   layerId: "0-0",
       *   success: function (result) {
       *     console.log('请求成功：', result);
       *   },
       *   failure: function (result) {
       *     console.log('请求失败：', result);
       *   }
       * });
       * // promise方式
       * sceneServer.queryFeatures({
       *   layerId: "0-0",
       *   geometry: new Point({
       *     coordinates: [108.9590, 34.2193]
       *   }),
       *   distance: 0.004
       * }).then(function (result) {
       *   console.log('请求成功：', result);
       * }).catch(function (result) {
       *   console.log('请求失败：', result);
       * });
       */
      queryFeatures(options) {
        // 设置PATH PARAMETERS校验
        const checkPathOpts = {
          layerId: {
            type: 'String'
          }
        }

        // 设置QUERY PARAMETERS校验
        const checkQueryOpts = {
          geometry: {
            type: 'Geometry'
          },
          where: {
            type: 'String'
          },
          outFields: {
            type: 'String'
          },
          objectIds: {
            type: 'String'
          },
          distance: {
            type: 'Number'
          },
          geometryPrecision: {
            type: 'Number'
          },
          spatialRel: {
            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`
          }
        )
      }

      /**
       * 多图层的要素查询，IGS2.0服务
       * @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 { Point } = Zondy.Geometry
       * // ES6引入方式
       * import { Point } from "@mapgis/webclient-common"
       * sceneServer.queryFeaturesInLayers({
       *   layerDefs: [{
       *     layerId: "0-0",
       *     where: "mpName='餐厅'"
       *   }],
       *   success: function (result) {
       *     console.log('请求成功：', result);
       *   },
       *   failure: function (result) {
       *     console.log('请求失败：', result);
       *   }
       * });
       * // promise方式
       * sceneServer.queryFeaturesInLayers({
       *   geometry: new Point({
       *     coordinates: [108.9590, 34.2193]
       *   }),
       *   distance: 0.0004
       * }).then(function (result) {
       *   console.log('请求成功：', result);
       * }).catch(function (result) {
       *   console.log('请求失败：', result);
       * });
       */
      queryFeaturesInLayers(options) {
        if (this.url.indexOf('/igs/rest/g3d/') > -1) {
          // 设置PATH PARAMETERS校验
          const checkPathOpts = {
            ip: {
              type: 'String'
            },
            port: {
              type: 'String'
            }
          }

          // 设置QUERY PARAMETERS校验
          const checkQueryOpts = {
            docName: {
              type: 'String'
            },
            layerIndex: {
              type: 'String'
            },
            gdbp: {
              type: 'String'
            },
            where: {
              type: 'String'
            },
            geometry: {
              type: 'Geometry',
              process: 'igsGeometryOld'
            },
            distance: {
              type: 'Number',
              default: 0
            },
            structs: {
              type: 'Object',
              process(structs, defaultValue) {
                return `&structs=${JSON.stringify(structs || defaultValue)}`
              },
              default: {
                IncludeAttribute: true,
                IncludeGeometry: true,
                IncludeWebGraphic: true
              }
            },
            page: {
              type: 'Number'
            },
            pageCount: {
              type: 'Number'
            },
            objectIds: {
              type: 'String'
            },
            orderField: {
              type: 'String'
            },
            isAsc: {
              type: 'Boolean'
            },
            rtnLabel: {
              type: 'Boolean'
            }
          }

          // 调用基类的查询信息方法
          return this._queryByParameters(
            options,
            checkPathOpts,
            checkQueryOpts,
            // 拼装返回基地址
            function (url, options) {
              return `http://${options.ip}:${options.port}/igs/rest/g3d/getFeature?f=json`
            }
          )
        } else {
          // 设置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`
            }
          )
        }
      }

      /**
       * 查询G3D服务的文档图层信息
       * @param options
       * @param {Function} [options.success] 查询成功回调函数，若使用Promise方式则不必填写
       * @param {queryFailure} [options.failure] 查询失败回调函数，若使用Promise方式则不必填写
       * @return {Promise<Object>} Promise对象
       * @example <caption><h5>查询G3D服务的文档图层信息</h5></caption>
       * sceneServer.queryDocInfo()
       *   .then((result) => {
       *     console.log('查询成功：', result)
       *   })
       *   .catch((result) => {
       *     console.log('查询失败：', result)
       *   })
       * */
      queryDocInfo(options) {
        // 调用基类的查询信息方法
        return this._querySimpleInfo(options, function (url) {
          // 拼装返回基地址
          return `${url}/GetDocInfo?f=json&format=json`
        })
      }

      /**
       * 获取所有发布的G3D文档列表
       * @param options
       * @param {String} [options.ip] 服务器的ip地址，必填
       * @param {String} [options.port] 服务器的端口号，必填
       * @param {Function} [options.success] 查询成功回调函数，若使用Promise方式则不必填写
       * @param {queryFailure} [options.failure] 查询失败回调函数，若使用Promise方式则不必填写
       * @return {Promise<Object>} Promise对象
       * @example <caption><h5>获取所有发布的G3D文档列表</h5></caption>
       * sceneServer.queryDocListInfo({
       *   // 服务器的ip地址
       *   ip: 'localhost',
       *   // 服务器的端口号
       *   port: '6163'
       * })
       * .then((result) => {
       *   console.log('查询成功：', result)
       * })
       * .catch((result) => {
       *   console.log('查询失败：', result)
       * })
       * */
      queryDocListInfo(options) {
        // 设置PATH PARAMETERS校验
        const checkPathOpts = {
          ip: {
            type: 'String'
          },
          port: {
            type: 'String'
          }
        }

        // 设置QUERY PARAMETERS校验
        const checkQueryOpts = {}

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

    Zondy.Service.SceneServer = SceneServer
    export default SceneServer