import { MapImageLayer } from '../baseLayer'
import { Zondy, Collection, Projection } from '../../../base'
import { LayerEventType, LayerType, LoadStatus } from '../../../base/enum'
import { defaultValue, isNull, Log } from '../../../util'
import { MapServer } from '../../../service'
import { Extent, SpatialReference } from '../../../base/geometry'
import IGSMapImageSubLayer from './IGSMapImageSubLayer'
import { fireEvent, setSublayer } from '../Utils'
/**
* IGS地图图片图层,<br/>
* 支持IGS1.0和2.0两个服务版本,支持自定义坐标系,当IGS版本是1.0时,需要手动设置图层坐标系,当IGS版本是2.0时,会自动读取元信息上的坐标系,不需要用户指定<br/>
* <br><br>[ES5引入方式]:<br/>
* Zondy.Layer.IGSMapImageLayer() <br/>
* [ES6引入方式]:<br/>
* import { IGSMapImageLayer } 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 IGSMapImageLayer
* @moduleEX LayerModule
* @classdesc IGS地图图层
* @extends MapImageLayer
* @fires Layer#图层加载完毕事件
* @fires Layer#图层销毁完毕事件
* @fires Layer#图层更新完毕事件
* @fires Layer#图层显隐更新完毕事件
* @fires Layer#图层透明度更新完毕事件
* @fires Layer#图层顺序更新完毕事件
* @fires Layer#图层刷新完毕事件
* @fires IGSMapImageLayer#子图层显隐更新完毕事件
* @param {Object} options 构造参数
* @param {String} [options.url] 服务基地址,可以在末尾指定子图层id,若指定,则仅显示该子图层,例如:http://{服务基地址}/子图层id,<a href='#show-sublayer'>[仅显示指定子图层]<br/>
* @param {String} [options.httpMethod="GET"] HTTP请求方式,默认为GET请求
* IGS1.0的服务为:http://{ip}:6163/igs/rest/mrms/docs/{serviceName},暂时无法从元信息中获取坐标系,请自行指定图层坐标系,参考示例:<a href='#igs-1'>[IGS1.0的地图图片图层示例]</a><br/>
* IGS2.0的服务为:http://{ip}:{port}/igs/rest/services/{folder}/{serviceName}/MapServer,参考示例:<a href='#igs-2'>[IGS2.0的地图图片图层示例]</a><br/>
* 删除图层方法:<a href='#remove-layer'>[删除图层]</a>
* @param {String} [options.id] 图层id,不给则给一个随机的id
* @param {Number} [options.opacity = 1] 图层透明度,0到1之间的值,0为完全透明,1为不透明,参考示例:<a href='#opacity'>[设置图层透明度]</a>
* @param {Boolean} [options.visible = true] 图层显示或隐藏,true则显示,false则隐藏,参考示例:<a href='#visible'>[设置图层显示或隐藏]</a>
* @param {Array<Collection>} [options.sublayers = []] 指定子图层参数,可设置子图层的可见性,顺序以及子图层渲染参数,其中图层可见性支持IGS1.0以及2.0服务,
* 子图层顺序以及专题图参数仅支持IGS2.0服务,目前子图层支持的专题图如下:<br/>
* [1、单值专题图]{@link UniqueValueRenderer}<br/>
* [2、分段专题图]{@link ClassBreakRenderer}<br/>
* 参考示例:<br/>
* <a href='#showAllSubLayers'>[1、显示所有子图层]</a><br/>
* <a href='#showSubLayersById'>[2、根据id显示子图层]</a><br/>
* <a href='#showSubLayers-method'>[3、通过方法设置子图层显隐]</a><br/>
* <a href='#showSubLayers-property'>[4、通过修改子图参数,设置子图层显隐]</a><br/>
* <a href='#setLayerIndex'>[5、设置子图层顺序]</a><br/>
* <a href='#setLayerIndex-method'>[6、通过方法设设置子图层顺序]</a><br/>
* <a href='#setLayerIndex-property'>[7、通过修改子图参数,设置子图层顺序]</a><br/>
* <a href='#setLayerRenderer-unique'>[8、设置子图层专题图-单值专题图]</a><br/>
* <a href='#setLayerRenderer-break'>[9、设置子图层专题图-分段专题图]</a><br/>
* <a href='#setLayerRenderer-method'>[10、通过方法设置子图层专题图]</a><br/>
* <a href='#setLayerRenderer-property'>[11、通过修改子图参数,设置子图层专题图]</a><br/>
* @param {SpatialReference} [options.spatialReference] 图层坐标系,支持4326(包含4490,4214以及4610)、3857以及EPSG上的自定义坐标系,坐标系默认从元信息中获取,也可指定坐标系,
* 参考示例:<a href='#spatialReference'>[设置图层坐标系]</a>
* @param {Number} [options.imageWidth = 256] 图片宽度,单位px,参考示例:<a href='#tileSize'>[设置图片大小]</a>
* @param {Number} [options.imageHeight = 256] 图片高度,单位px,参考示例:<a href='#tileSize'>[设置图片大小]</a>
* @param {Number} [options.minScale = null] 最小比例尺,只有当地图视图的比例尺大于最小比例尺时显示地图图片图层
* @param {Number} [options.maxScale = null] 最大比例尺,只有当地图视图的比例尺小于最大比例尺时显示地图图片图层
* @param {String} [options.tokenKey = 'token'] token名
* @param {String} [options.tokenValue] token值,只有当tokenValue存在时,才会绑定token
* @param {Boolean} [options.imageTransparency = true] 图片中没有数据的地方是否透明,默认为true,即透明
* @param {Polygon|Extent|Circle|null} [options.clippingArea = null] 图层空间裁剪范围,仅支持多边形裁剪、矩形裁剪、圆形裁剪
*
* @summary <h5>支持如下方法:</h5>
* <a href='#load'>[1、加载图层资源]</a><br/>
* <a href='#findSublayerById'>[2、根据子图层id查询子图层]</a><br/>
* [3、刷新图层]{@link Layer#refresh}<br/>
* <a href='#fetchImage'>[4、根据范围和大小获取image标签]</a><br/>
* <a href='#createServiceSublayers'>[5、创建一个该服务的子图层克隆对象]</a><br/>
* <a href='#getImageUrl'>[6、根据参数获取图片的url]</a><br/>
* <a href='#setSubLayer'>[7、更新子图层]</a><br/>
* <a href='#toJSON'>[8、将图层转为json对象]</a><br/>
* <a href='#clone'>[9、克隆图层对象]</a><br/>
*
* @example <caption><h7 id='igs-1'>IGS1.0的地图图片图层示例</h7></caption>
* // ES5引入方式
* const { Map,MapView,SpatialReference } = Zondy
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { Map,MapView,SpatialReference,IGSMapImageLayer } from "@mapgis/webclient-common"
* // 初始化图层管理容器
* const map = new Map();
* // 初始化地图视图对象
* const mapView = new MapView({
* // 视图id
* viewId: "viewer-id",
* // 图层管理容器
* map: map
* });
* // 添加图层
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:6163/igs/rest/mrms/docs/{serviceName}',
* // IGS1.0服务,暂时无法从元信息中获取坐标系,请自行指定图层坐标系
* spatialReference: new SpatialReference({
* wkid: 4326
* })
* });
* map.add(igsMapImageLayer);
*
* @example <caption><h7 id='igs-2'>IGS2.0的地图图片图层示例</h7></caption>
* // ES5引入方式
* const { Map,MapView } = Zondy
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { Map,MapView,IGSMapImageLayer } from "@mapgis/webclient-common"
* // 初始化图层管理容器
* const map = new Map();
* // 初始化地图视图对象
* const mapView = new MapView({
* // 视图id
* viewId: "viewer-id",
* // 图层管理容器
* map: map
* });
* // 添加图层
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer'
* });
* map.add(igsMapImageLayer);
*
* @example <caption><h7 id='spatialReference'>指定地图图片图层的坐标系示例</h7></caption>
* // ES5引入方式
* const { SpatialReference} = Zondy
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { SpatialReference,IGSMapImageLayer } from "@mapgis/webclient-common"
* // 添加图层
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer',
* // 自定义坐标新
* spatialReference: new SpatialReference({
* // 指定的wkid号,可在https://epsg.io/网站查询
* wkid: '指定的wkid号'
* })
* });
* map.add(igsMapImageLayer);
*
* @example <caption><h7 id='tileSize'>IGS2.0的地图图层示例 - 设置图片大小</h7></caption>
* // ES5引入方式
* const { Map,MapView} = Zondy
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { Map,MapView,IGSMapImageLayer } from "@mapgis/webclient-common"
* // 初始化图层管理容器
* const map = new Map();
* // 初始化地图视图对象
* const mapView = new MapView({
* // 视图id
* viewId: "viewer-id",
* // 图层管理容器
* map: map
* });
* // 添加图层
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer',
* // 瓦片宽度
* imageWidth: 512,
* // 瓦片高度
* imageHeight: 512
* });
* map.add(igsMapImageLayer);
*
* @example <caption><h7 id='showAllSubLayers'>显示所有子图层</h7></caption>
* // ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { IGSMapImageLayer } from "@mapgis/webclient-common"
* // 添加图层
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer',
* // 当sublayers为空时显示所有子图层
* sublayers: []
* });
* map.add(igsMapImageLayer);
*
* @example <caption><h7 id='showSubLayersById'>根据id显示子图层</h7></caption>
* // ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { IGSMapImageLayer } from "@mapgis/webclient-common"
* // 添加图层
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer',
* // 根据id显示子图层
* sublayers: [
* {
* // 子图层id
* id: 1,
* // 显示子图层
* visible: true
* }
* ]
* });
* map.add(igsMapImageLayer);
*
* @example <caption><h7 id='showSubLayers-method'>通过方法设置子图层显隐</h7></caption>
* // ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { IGSMapImageLayer } from "@mapgis/webclient-common"
* // 添加图层
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer'
* });
* map.add(igsMapImageLayer);
* // 通过方法设置子图层显隐
* igsMapImageLayer.setSubLayer({
* id: 0,
* visible: false
* })
*
* @example <caption><h7 id='showSubLayers-property'>通过修改子图参数,设置子图层显隐</h7></caption>
* // ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { IGSMapImageLayer } from "@mapgis/webclient-common"
* // 添加图层
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer'
* });
* map.add(igsMapImageLayer);
* // 根据id获取子图层
* const subLayer = igsMapImageLayer.findSublayerById(0)
* // 设置子图层显隐
* subLayer.visible = false
*
* @example <caption><h7 id='setLayerIndex'>设置子图层顺序</h7></caption>
* // ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { IGSMapImageLayer } from "@mapgis/webclient-common"
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer',
* // 设置子图层顺序
* sublayers: [{
* id: '0',
* index: 2
* },{
* id: '1',
* index: 1
* }]
* });
* map.add(igsMapImageLayer);
*
* @example <caption><h7 id='setLayerIndex-method'>通过方法设置子图层顺序</h7></caption>
* // ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { IGSMapImageLayer } from "@mapgis/webclient-common"
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer'
* });
* map.add(igsMapImageLayer);
* // 设置子图层顺序
* igsMapImageLayer.setSubLayer({
* // 子图层id
* id: '子图层id',
* // 子图层顺序
* index: 2
* })
*
* @example <caption><h7 id='setLayerIndex-property'>通过修改子图参数,设置子图层顺序</h7></caption>
* // ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { IGSMapImageLayer } from "@mapgis/webclient-common"
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer'
* });
* map.add(igsMapImageLayer);
* // 根据id获取子图层
* const subLayer = igsMapImageLayer.findSublayerById(0)
* // 设置子图层顺序
* subLayer.index = 2
*
* @example <caption><h7 id='setLayerRenderer-unique'>设置子图层专题图-单值专题图</h7></caption>
* // ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* const { UniqueValueRenderer } = Zondy.Renderer
* const { SimpleFillSymbol,SimpleLineSymbol } = Zondy.Symbol
* const { Color } = Zondy
* // ES6引入方式
* import { IGSMapImageLayer,UniqueValueRenderer,SimpleFillSymbol,SimpleLineSymbol,Color } from "@mapgis/webclient-common"
* igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer',
* // 设置子图层专题图
* sublayers: [
* {
* // 子图层id
* id: '子图层id',
* // 专题图参数
* renderer: new UniqueValueRenderer({
* //字段名
* field: '你的字段名',
* // 默认符号,不在专题图指定范围内的会采用该样式,可不设置
* defaultSymbol: new SimpleFillSymbol({
* // 填充颜色
* color: 'rgba(1,1,252,0)',
* // 外边线样式
* outline: new SimpleLineSymbol({
* //线颜色
* color: new Color(255, 1, 0, 1),
* //线宽
* width: 1
* })
* }),
* //单值专题图字段样式
* uniqueValueInfos: [{
* //指定字段值
* value: "指定的值",
* //匹配到该值后的样式
* symbol: new SimpleFillSymbol({
* // 填充颜色
* color: 'rgba(1,1,252,1)',
* // 外边线样式
* outline: new SimpleLineSymbol({
* //线符号颜色
* color: new Color(255, 1, 0, 11),
* //线宽
* width: 1
* })
* })
* },{
* //指定字段值
* value: "指定的值",
* //匹配到该值后的样式
* symbol: new SimpleFillSymbol({
* // 填充颜色
* color: new Color(211, 111, 11, 1)
* })
* }]
* })
* }
* ]
* });
* map.add(igsMapImageLayer);
*
* @example <caption><h7 id='setLayerRenderer-break'>设置子图层专题图-分段专题图</h7></caption>
* // ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* const { ClassBreakRenderer } = Zondy.Renderer
* const { SimpleFillSymbol,SimpleLineSymbol } = Zondy.Symbol
* const { Color } = Zondy
* // ES6引入方式
* import { IGSMapImageLayer,ClassBreakRenderer,SimpleFillSymbol,SimpleLineSymbol,Color } from "@mapgis/webclient-common"
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer',
* // 设置子图层专题图
* sublayers: [
* {
* // 子图层id
* id: '子图层id',
* // 专题图参数
* renderer: new ClassBreakRenderer({
* //字段名
* field: '你的字段名',
* // 指定默认样式,不在专题图指定范围内的会采用该样式,可不设置
* defaultSymbol: new SimpleFillSymbol({
* // 填充颜色
* color: 'rgba(222,1,252,1)',
* // 线符号样式
* outline: new SimpleLineSymbol({
* //线符号颜色
* color: new Color(255, 1, 0, 1),
* //线宽
* width: 1
* })
* }),
* //单值专题图字段样式
* classBreakInfos: [{
* // 最大范围
* maxValue: "最大范围",
* // 最小范围
* minValue: "最小范围",
* //匹配到该值后的样式
* symbol: new SimpleFillSymbol({
* // 填充颜色
* color: 'rgba(1,1,252,1)',
* // 线符号样式
* outline: new SimpleLineSymbol({
* //线符号颜色
* color: new Color(255, 1, 0, 1),
* //线宽
* width: 1
* })
* })
* }]
* })
* }
* ]
* });
* map.add(igsMapImageLayer);
*
* @example <caption><h7 id='setLayerRenderer-method'>通过方法设置子图层专题图</h7></caption>
* // ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* const { ClassBreakRenderer } = Zondy.Renderer
* const { SimpleFillSymbol,SimpleLineSymbol } = Zondy.Symbol
* const { Color } = Zondy
* // ES6引入方式
* import { IGSMapImageLayer,ClassBreakRenderer,SimpleFillSymbol,SimpleLineSymbol,Color } from "@mapgis/webclient-common"
* const igsMapImageLayer = new Zondy.Layer.IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer'
* });
* map.add(igsMapImageLayer);
* // 设置子图层专题图
* igsMapImageLayer.setSubLayer({
* // 子图层id
* id: '子图层id',
* // 专题图参数
* renderer: new Zondy.Renderer.ClassBreakRenderer({
* //字段名
* field: '你的字段名',
* // 指定默认样式,不在专题图指定范围内的会采用该样式,可不设置
* defaultSymbol: new Zondy.Symbol.SimpleFillSymbol({
* // 填充颜色
* color: 'rgba(222,1,252,1)',
* // 线符号样式
* outline: new Zondy.Symbol.SimpleLineSymbol({
* //线符号颜色
* color: new Zondy.Color(255, 1, 0, 1),
* //线宽
* width: 1
* })
* }),
* //单值专题图字段样式
* classBreakInfos: [{
* // 最大范围
* maxValue: "最大范围",
* // 最小范围
* minValue: "最小范围",
* //匹配到该值后的样式
* symbol: new Zondy.Symbol.SimpleFillSymbol({
* // 填充颜色
* color: 'rgba(1,1,252,1)',
* // 线符号样式
* outline: new Zondy.Symbol.SimpleLineSymbol({
* //线符号颜色
* color: new Zondy.Color(255, 1, 0, 1),
* //线宽
* width: 1
* })
* })
* }]
* })
* })
*
* @example <caption><h7 id='setLayerRenderer-property'>通过修改子图参数,设置子图层专题图</h7></caption>
* // ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* const { ClassBreakRenderer } = Zondy.Renderer
* const { SimpleFillSymbol,SimpleLineSymbol } = Zondy.Symbol
* const { Color } = Zondy
* // ES6引入方式
* import { IGSMapImageLayer,ClassBreakRenderer,SimpleFillSymbol,SimpleLineSymbol,Color } from "@mapgis/webclient-common"
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer'
* });
* map.add(igsMapImageLayer);
* // 根据id获取子图层
* const subLayer = igsMapImageLayer.findSublayerById(0)
* // 设置子图专题图
* subLayer.renderer = new ClassBreakRenderer({
* //字段名
* field: '你的字段名',
* // 指定默认样式,不在专题图指定范围内的会采用该样式,可不设置
* defaultSymbol: new SimpleFillSymbol({
* // 填充颜色
* color: 'rgba(222,1,252,1)',
* // 线符号样式
* outline: new SimpleLineSymbol({
* //线符号颜色
* color: new Color(255, 1, 0, 1),
* //线宽
* width: 1
* })
* }),
* //单值专题图字段样式
* classBreakInfos: [{
* // 最大范围
* maxValue: "最大范围",
* // 最小范围
* minValue: "最小范围",
* //匹配到该值后的样式
* symbol: new SimpleFillSymbol({
* // 填充颜色
* color: 'rgba(1,1,252,1)',
* // 线符号样式
* outline: new SimpleLineSymbol({
* //线符号颜色
* color: new Color(255, 1, 0, 1),
* //线宽
* width: 1
* })
* })
* }]
* })
*
* @example <caption><h7 id='opacity'>设置图层透明度</h7></caption>
* // ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { IGSMapImageLayer } from "@mapgis/webclient-common"
* // 初始化时设置
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer',
* // 设置透明度
* opacity: 1.0
* });
* map.add(igsMapImageLayer);
* // 加载完成后设置
* igsMapImageLayer.on('layerview-created', function (result) {
* console.log("加载完毕:", result.layer)
* // 视点跳转
* igsMapImageLayer.opacity = 0.5
* })
*
* @example <caption><h7 id='visible'>显示或隐藏图层</h7></caption>
* / ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { IGSMapImageLayer } from "@mapgis/webclient-common"
* // 初始化时设置
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer',
* // 显示或隐藏图层
* visible: true
* });
* map.add(igsMapImageLayer);
* // 加载完成后设置
* igsMapImageLayer.on('layerview-created', function (result) {
* console.log("加载完毕:", result.layer)
* // 显示或隐藏图层
* igsMapImageLayer.visible = !igsMapImageLayer.visible
* })
*
* @example <caption><h7 id='remove-layer'>删除图层</h7></caption>
* map.remove(igsMapImageLayer)
*
* @example <caption><h7 id='show-sublayer'>显示指定子图层</h7></caption>
* / ES5引入方式
* const { IGSMapImageLayer } = Zondy.Layer
* // ES6引入方式
* import { IGSMapImageLayer } from "@mapgis/webclient-common"
* // 初始化时设置
* const igsMapImageLayer = new IGSMapImageLayer({
* // 服务基地址,可指定子图层id
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer/{子图层id}',
* // 显示或隐藏图层
* visible: true
* });
* map.add(igsMapImageLayer);
*
* @example <caption><h7>添加arcgis的MapImage图层</h7></caption>
* // 初始化图层管理容器
* / ES5引入方式
* const { Map ,SceneView,SpatialReference} = Zondy
* const { IGSMapImageLayer} = Zondy.Layer
* // ES6引入方式
* import {Map ,SceneView,SpatialReference, IGSMapImageLayer } from "@mapgis/webclient-common"
* const map = new Map();
* // 初始化地图视图对象
* const sceneView = new SceneView({
* // 视图id
* viewId: "mapgis-3d-viewer",
* // 图层管理容器
* map: map
* });
* const arcgisMapImageLayer = new IGSMapImageLayer({
* url: 'https://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetWarm/MapServer',
* // 注意一个MapImage图层可能支持多个坐标系,这里指定4326坐标系
* spatialReference: new SpatialReference({
* wkid: 4326
* })
* });
* map.add(arcgisMapImageLayer);
* // 图层加载完毕
* igsMapImageLayer.on('layerview-created', function (result) {
* console.log("加载完毕:", result.layer)
* // 视点跳转
* sceneView.flyTo({
* extent: result.layer.extent
* })
* })
*
* @example <caption><h7 id='index'>图层顺序</h7></caption>
* // 加载完毕后,更改图层顺序
* map.reorder(igsMapImageLayer, '要移动到的index');
*/
/**
* 子图层显隐更新完毕事件,请注意该事件是图层更新事件(layerview-update)的子事件
* @event IGSMapImageLayer#子图层显隐更新完毕事件
* @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 === 'sublayerVisible'){
* console.log("子图层显隐更新完毕事件:", event);
* }
* }
* });
*/
class IGSMapImageLayer extends MapImageLayer {
constructor(options) {
super(options)
options = defaultValue(options, {})
/**
* 图层类型
* @readonly
* @member {String} IGSMapImageLayer.prototype.type
*/
this.type = LayerType.igsMapImage
// 空间裁剪范围
this._clippingArea = defaultValue(options.clippingArea, null)
this.description = 'IGS地图服务图层'
// igs服务版本号,默认2.0
this._igsVersion = '2.0'
// 是否使用url后面的id,作为显示子图层的id
this._urlLayerId = false
// IGSMapImageLayer的真实URL
const _urlArr = this.url.split('MapServer/')
if (_urlArr.length === 1) {
this._url = _urlArr[0]
} else {
this._url = `${_urlArr[0]}MapServer`
this.layers = `show:${_urlArr[1]}`
this._urlLayerId = true
}
// 地图服务对象
this._mapServer = new MapServer({
url: this._url
})
}
/**
* 加载图层资源
* @example <caption><h7 id='load'>不加载图层,仅获取图层信息</h7></caption>
* // 初始化图层
* const igsMapImageLayer = new Zondy.Layer.IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:{port}/igs/rest/services/{serviceName}/MapServer',
* });
* igsMapImageLayer.load().then((result) => {
* // 获取完图层信息
* console.log(result)
* })
* */
load() {
return super.load()
}
/**
* 子类请求服务资源的方法
* @private
* */
_load() {
const self = this
return this._mapServer.queryServerInfo().then((result) => {
Log.info('MapServer信息查询成功:', result)
const data = result.data
// 查询图层列表参数
const queryLayerListOpts = {}
// IGS2.0服务
if (self.url.indexOf('/igs/rest/services/') > -1) {
self._igsVersion = '2.0'
self.documentInfo = defaultValue(self.documentInfo, data.documentInfo)
self.mapName = defaultValue(self.mapName, data.mapName)
if (self.capabilities.length === 0) {
self.capabilities = data.childResources.split(',')
}
self.dynamicProjectionEnabled = defaultValue(
self.dynamicProjectionEnabled,
data.dynamicProjectionEnabled
)
if (!self._spatialReferenceSrc) {
if (!isNull(data.spatialReference.wkt)) {
self._spatialReferenceSrc = new SpatialReference({
wkt: data.spatialReference.wkt
})
}
if (!isNull(data.spatialReference.wkid)) {
self._spatialReferenceSrc = new SpatialReference({
wkid: data.spatialReference.wkid
})
}
}
if (!self._extentSrc && !isNull(data.extent)) {
// 获取图层坐标系
const _serverSP = new SpatialReference(data.spatialReference)
// 设置可现实范围
self._extentSrc = new Extent({
xmin: data.extent.xmin,
ymin: data.extent.ymin,
xmax: data.extent.xmax,
ymax: data.extent.ymax,
spatialReference: _serverSP
})
// 如果用户输入的坐标系和图层的坐标系不一致,则将范围动态投影
if (!_serverSP.equals(self._spatialReferenceSrc)) {
self._extentSrc = Projection.project(
self._extentSrc,
self._spatialReferenceSrc
)
}
}
} // IGS1.0服务
else {
self._igsVersion = '1.0'
queryLayerListOpts.mapIndex = '0'
if (!self._spatialReferenceSrc) {
Log.error('IGS1.0服务必须设置参考系')
}
if (
!self._extentSrc &&
!isNull(data.xMin) &&
!isNull(data.yMin) &&
!isNull(data.xMax) &&
!isNull(data.yMax)
) {
self._extentSrc = new Extent({
xmin: data.xMin,
ymin: data.yMin,
xmax: data.xMax,
ymax: data.yMax,
spatialReference: self._spatialReferenceSrc
})
}
self.mapName = data.name
}
return self._mapServer
.queryLayerList(queryLayerListOpts)
.then((layerList) => {
Log.info('子图层信息查询成功:', layerList)
// 清空子图层
self.allSublayers.items = []
let sublayers = []
// IGS2.0服务
if (self._igsVersion === '2.0') {
sublayers = layerList.data.layers
} else {
sublayers = layerList.data
for (let i = 0; i < sublayers.length; i++) {
sublayers[i].visible = sublayers[i].State === 'Visible'
sublayers[i].index = sublayers[i].LayerIndex
sublayers[i].type =
sublayers[i].GeomType === 'Unknown'
? 'Group'
: sublayers[i].GeomType
}
}
// 更新所有图层信息
for (let i = 0; i < self.sublayers.length; i++) {
self._updateLayerInfo(sublayers, self.sublayers[i])
}
// 初始化所有子图层集合
self._sublayers = new Collection()
for (let i = 0; i < sublayers.length; i++) {
const _subLayer = new IGSMapImageSubLayer(sublayers[i])
_subLayer.layer = self
self._sublayers.add(_subLayer)
self.allSublayers.add(_subLayer)
if (
sublayers[i].children &&
sublayers[i].children instanceof Array
) {
self._initAllSubLayers(sublayers[i].children)
}
}
// 设置子图层显隐
self._setLayers()
// 图层信息加载完毕
self.loadStatus = LoadStatus.loaded
self.loaded = true
return new Promise((resolve) => {
resolve(self)
})
})
})
}
/**
* @description 转换为json对象
* @return {Object} json对象
*/
toJSON() {
const _json = super.toJSON()
_json.description = this.description
_json.documentInfo = this.documentInfo
return _json
}
/**
* 用本地的子图层信息,更细服务端子图层信息
* @private
* @param {Array} serverSubLayers 服务端图层信息数组,有子图层
* @param {Object} clientSubLayer 客户端单个图层信息
* */
_updateLayerInfo(serverSubLayers, clientSubLayer) {
for (let i = 0; i < serverSubLayers.length; i++) {
if (String(serverSubLayers[i].index) === String(clientSubLayer.id)) {
serverSubLayers[i] = Object.assign(serverSubLayers[i], clientSubLayer)
}
if (serverSubLayers[i].children) {
this._updateLayerInfo(serverSubLayers[i].children, clientSubLayer)
}
}
}
/**
* 通过服务端图层信息,初始化所有子图层集合
* @private
* @param {Array} sublayers 服务端图层信息数组
* */
_initAllSubLayers(sublayers) {
for (let i = 0; i < sublayers.length; i++) {
sublayers[i].layer = this
this.allSublayers.add(new IGSMapImageSubLayer(sublayers[i]))
if (sublayers[i].children && sublayers[i].children instanceof Array) {
this._initAllSubLayers(sublayers[i].children)
}
}
}
/**
* 根据子图层id查询子图层<a id='findSublayerById'></a>
* @param {String} id 子图层id
* @return Object 子图层信息
* */
findSublayerById(id) {
if (this.loadStatus === LoadStatus.loaded && this.allSublayers) {
for (let i = 0; i < this.allSublayers.items.length; i++) {
if (String(this.allSublayers.items[i].id) === String(id)) {
return this.allSublayers.items[i]
}
}
}
}
/**
* 根据范围和大小获取image标签
* @param {Extent} extent
* @param {Number} [width = 256] 图片宽度,单位px
* @param {Number} [height = 256] 图片高度,单位px
* @example <caption><h7 id='fetchImage'>根据范围和大小获取image标签</h7></caption>
* igsMapImageLayer.fetchImage({
* // 你的范围
* extent: new Zondy.Geometry.Extent(),
* // 图片宽度
* width: 256,
* // 图片高度
* height: 256
* }).then((image) => {
* // 这里返回一个html的image标签
* })
* */
fetchImage(extent, width, height) {
width = defaultValue(width, 256)
height = defaultValue(height, 256)
const url = this.getImageUrl({
extent,
width,
height
})
return new Promise((resolve) => {
const image = new Image()
image.src = url
image.width = width
image.height = height
resolve(image)
})
}
/**
* 创建一个该服务的子图层克隆对象,注意不是本地的子图层对象<a id='createServiceSublayers'></a>
* @return {Array} 服务上的子图层对象
* */
createServiceSublayers() {
return this.serviceSublayers
}
/**
* 根据参数获取图片的url
* @param options
* @param {Extent} [options.extent] 图片范围
* @param {Number} [options.width] 图片宽度
* @param {Number} [options.height] 图片高度
* @return String 图片的url
* @example <caption><h7 id='getImageUrl'>根据参数获取图片的url</h7></caption>
* const url = igsMapImageLayer.getImageUrl({
* // 你的范围
* extent: new Zondy.Geometry.Extent(),
* // 图片宽度
* width: 256,
* // 图片高度
* height: 256
* })
* */
getImageUrl(options) {
return this._mapServer.getImage(options)
}
/**
* 更新子图层<a id='setSubLayer'></a>
* @param {IGSMapImageSubLayer} igsMapImageSubLayer 要更新的子图层
* */
setSubLayer(igsMapImageSubLayer) {
// 更新子图层
setSublayer(this, igsMapImageSubLayer, IGSMapImageSubLayer)
// 设置子图层显隐
this._setLayers()
// 发送更新事件
fireEvent(
this,
LayerEventType.layerUpdate,
LayerEventType.layerSublayerVisible
)
}
_setLayers() {
// 如果url后面没有id,则计算layers
if (!this._urlLayerId) {
// 设置子图层显隐
let layers = 'show:'
this.allSublayers.forEach(function (sublayer) {
if (sublayer.visible && sublayer.type !== 'Group') {
layers += `${sublayer.id},`
}
})
layers = layers.substring(0, layers.length - 1)
this.layers = layers
}
}
/**
* 克隆图层对象
* @param {IGSMapImageLayer} igsMapImageLayer 被克隆的对象
* @return {IGSMapImageLayer} 克隆后的图层对象
* @example <caption><h7 id='getImageUrl'>根据参数获取图片的url</h7></caption>
* // 添加图层
* const igsMapImageLayer = new Zondy.Layer.IGSMapImageLayer({
* // 服务基地址
* url: 'http://{ip}:6163/igs/rest/mrms/docs/{serviceName}'
* });
* const newLayer = Zondy.Layer.IGSMapImageLayer.clone(igsMapImageLayer)
*/
static clone(igsMapImageLayer) {
return new IGSMapImageLayer(igsMapImageLayer.toJSON())
}
/**
* 获取服务端要素过滤参数字符串
* @return {Object} 服务端要素过滤参数,格式为{"子图层id":{"where":"sql语句"}}
* */
getFilters() {
const _layerFilters = {}
this.allSublayers.forEach(function (sublayer) {
const definitionExpression = sublayer.definitionExpression
if (definitionExpression) {
_layerFilters[sublayer.id] = {
where: definitionExpression
}
}
})
return JSON.stringify(_layerFilters) === '{}' ? '' : _layerFilters
}
static fromJSON(json) {
json = defaultValue(json, {})
const _layer = new IGSMapImageLayer(json)
_layer._isFromJSON = true
const _sublayers = json.sublayers
if (_sublayers && _sublayers instanceof Array) {
_layer._sublayers = new Collection()
for (let i = 0; i < _sublayers.length; i++) {
_layer._sublayers.add(new IGSMapImageSubLayer(_sublayers[i]))
}
}
const _allSublayers = json.allSublayers
if (_allSublayers && _allSublayers instanceof Array) {
_layer.allSublayers = new Collection()
for (let i = 0; i < _allSublayers.length; i++) {
_layer.allSublayers.add(new IGSMapImageSubLayer(_allSublayers[i]))
}
}
return _layer
}
}
Object.defineProperties(IGSMapImageLayer.prototype, {
/**
* 子图层对象集合
* @member IGSMapImageLayer.prototype.sublayers
* @type {Collection}
*/
sublayers: {
get() {
return this._sublayers
},
set(value) {
this._sublayers = value
}
},
/**
* 空间裁剪范围
* @member IGSMapImageLayer.prototype.clippingArea
* @type {Polygon|Extent|Circle|null}
*/
clippingArea: {
get() {
return this._clippingArea
},
set(value) {
this._clippingArea = value
this._fireUpdateEvent('空间裁剪区域', [
{
name: 'clippingArea',
params: [this._clippingArea],
dataChanged: true,
operationType: 'property'
}
])
}
}
})
Zondy.Layer.IGSMapImageLayer = IGSMapImageLayer
export default IGSMapImageLayer