import L, { Util as LUtil} from "leaflet"; import "@supermap/iclient-leaflet/core/Base"; import { SecurityManager, Unit, ServerGeometry, CommonUtil } from '@supermap/iclient-common'; import * as Util from "@supermap/iclient-leaflet/core/Util"; import Attributions from '@supermap/iclient-leaflet/core/Attributions' export let TiledMapLayer = L.TileLayer.extend({ options: { //如果有layersID,则是在使用专题图 layersID: null, //如果为 true,则将请求重定向到瓦片的真实地址;如果为 false,则响应体中是瓦片的字节流 redirect: false, transparent: true, cacheEnabled: true, clipRegionEnabled: false, //地图显示裁剪的区域 clipRegion: null, //请求的地图的坐标参考系统。 如:prjCoordSys={"epsgCode":3857} prjCoordSys: null, //地图对象在同一范围内时,是否重叠显示 overlapDisplayed: false, //避免地图对象压盖显示的过滤选项 overlapDisplayedOptions: null, //切片版本名称,cacheEnabled 为 true 时有效。 tileversion: null, crs: null, format: 'png', //启用托管地址。 tileProxy:null, attribution: Attributions.Common.attribution, subdomains: null }, initialize: function (url, options) { this._url = url; L.TileLayer.prototype.initialize.apply(this, arguments); L.setOptions(this, options); L.stamp(this); //当前切片在切片集中的index this.tileSetsIndex = -1; this.tempIndex = -1; }, /** * @private * @function L.supermap.tiledMapLayer.prototype.onAdd * @description 添加地图。 * @param {L.Map} map - 待添加的影像地图参数。 */ onAdd: function (map) { this._crs = this.options.crs || map.options.crs; L.TileLayer.prototype.onAdd.call(this, map); }, /** * @function L.supermap.tiledMapLayer.prototype.getTileUrl * @description 根据行列号获取瓦片地址。 * @param {Object} coords - 行列号。 * @returns {string} 瓦片地址。 */ getTileUrl: function (coords) { var scale = this.getScaleFromCoords(coords); var layerUrl = this._getLayerUrl(); var tileUrl = layerUrl + "&scale=" + scale + "&x=" + coords.x + "&y=" + coords.y; //支持代理 if (this.options.tileProxy) { tileUrl = this.options.tileProxy + encodeURIComponent(tileUrl); } if (!this.options.cacheEnabled) { tileUrl += "&_t=" + new Date().getTime(); } if (this.options.subdomains) { tileUrl = L.Util.template(tileUrl, {s: this._getSubdomain(coords)}); } return tileUrl; }, /** * @function L.supermap.tiledMapLayer.prototype.getScale * @description 根据缩放级别获取比例尺。 * @param {number} zoom - 缩放级别。 * @returns {number} 比例尺。 */ getScale: function (zoom) { var me = this; //返回当前比例尺 var z = zoom || me._map.getZoom(); return me.scales[z]; }, /** * @function L.supermap.tiledMapLayer.prototype.getScaleFromCoords * @description 通过行列号获取比例尺。 * @param {Object} coords - 行列号。 * @returns {number} 比例尺。 */ getScaleFromCoords: function (coords) { var me = this, scale; if (me.scales && me.scales[coords.z]) { return me.scales[coords.z]; } me.scales = me.scales || {}; scale = me.getDefaultScale(coords); me.scales[coords.z] = scale; return scale; }, /** * @private * @function L.supermap.tiledMapLayer.prototype.getDefaultScale * @description 获取默认比例尺信息。 * @param {Object} coords - 坐标对象参数。 */ getDefaultScale: function (coords) { var me = this, crs = me._crs; if (crs.scales) { return crs.scales[coords.z]; } else { var tileBounds = me._tileCoordsToBounds(coords); var ne = crs.project(tileBounds.getNorthEast()); var sw = crs.project(tileBounds.getSouthWest()); var tileSize = me.options.tileSize; var resolution = Math.max( Math.abs(ne.x - sw.x) / tileSize, Math.abs(ne.y - sw.y) / tileSize ); var mapUnit = Unit.METER; if (crs.code) { var array = crs.code.split(':'); if (array && array.length > 1) { var code = parseInt(array[1]); mapUnit = code && code >= 4000 && code <= 5000 ? Unit.DEGREE : Unit.METER; } } return Util.resolutionToScale(resolution, 96, mapUnit); } }, /** * @function L.supermap.tiledMapLayer.prototype.setTileSetsInfo * @description 设置瓦片集信息。 * @param {Object} tileSets - 瓦片对象集。 */ setTileSetsInfo: function (tileSets) { this.tileSets = tileSets; if (L.Util.isArray(this.tileSets)) { this.tileSets = this.tileSets[0]; } if (!this.tileSets) { return; } /** * @event L.supermap.tiledMapLayer#tilesetsinfoloaded * @description 瓦片集信息设置完成后触发。 * @property {Array.} tileVersions - 瓦片集信息。 */ this.fire('tilesetsinfoloaded', { tileVersions: this.tileSets.tileVersions }); this.changeTilesVersion(); }, /** * @function L.supermap.tiledMapLayer.prototype.lastTilesVersion * @description 请求上一个版本切片,并重新绘制。 */ lastTilesVersion: function () { this.tempIndex = this.tileSetsIndex - 1; this.changeTilesVersion(); }, /** * @function L.supermap.tiledMapLayer.prototype.nextTilesVersion * @description 请求下一个版本切片,并重新绘制。 */ nextTilesVersion: function () { this.tempIndex = this.tileSetsIndex + 1; this.changeTilesVersion(); }, /** * @function L.supermap.tiledMapLayer.prototype.changeTilesVersion * @description 切换到某一版本的切片,并重绘。通过 this.tempIndex 保存需要切换的版本索引 */ changeTilesVersion: function () { var me = this; //切片版本集信息是否存在 if (me.tileSets == null) { //版本信息为空,重新查询,查询成功继续跳转到相应的版本 //me.getTileSetsInfo(); return; } if (me.tempIndex === me.tileSetsIndex || this.tempIndex < 0) { return; } //检测index是否可用 var tileVersions = me.tileSets.tileVersions; if (tileVersions && me.tempIndex < tileVersions.length && me.tempIndex >= 0) { var name = tileVersions[me.tempIndex].name; var result = me.mergeTileVersionParam(name); if (result) { me.tileSetsIndex = me.tempIndex; /** * @event L.supermap.tiledMapLayer#tileversionschanged * @description 切片的版本切换和重绘成功之后触发。 * @property {Object} tileVersion - 该版本的切片。 */ me.fire('tileversionschanged', { tileVersion: tileVersions[me.tempIndex] }); } } }, /** * @function L.supermap.tiledMapLayer.prototype.updateCurrentTileSetsIndex * @description 手动设置当前切片集索引,目前主要提供给控件使用。 * @param {number} index - 索引值。 */ updateCurrentTileSetsIndex: function (index) { this.tempIndex = index; }, /** * @function L.supermap.tiledMapLayer.prototype.mergeTileVersionParam * @description 更改URL请求参数中的切片版本号,并重绘。 * @param {string} version - 切片版本号。 * @returns {boolean} 是否成功。 */ mergeTileVersionParam: function (version) { if (version) { this.requestParams["tileversion"] = version; this._paramsChanged = true; this.redraw(); this._paramsChanged = false; return true; } return false; }, _getLayerUrl: function () { if (this._paramsChanged) { this._layerUrl = this._createLayerUrl(); } return this._layerUrl || this._createLayerUrl(); }, _createLayerUrl: function () { let layerUrl = CommonUtil.urlPathAppend(this._url, `tileImage.${this.options.format}`); this.requestParams = this.requestParams || this._getAllRequestParams(); layerUrl = CommonUtil.urlAppend(layerUrl, LUtil.getParamString(this.requestParams)); layerUrl = SecurityManager.appendCredential(layerUrl); this._layerUrl = layerUrl; return layerUrl; }, _getAllRequestParams: function () { var me = this, options = me.options || {}, params = {}; var tileSize = this.options.tileSize; if (!(tileSize instanceof L.Point)) { tileSize = L.point(tileSize, tileSize); } params["width"] = tileSize.x; params["height"] = tileSize.y; params["redirect"] = options.redirect === true; params["transparent"] = options.transparent === true; params["cacheEnabled"] = !(options.cacheEnabled === false); if (options.prjCoordSys) { params["prjCoordSys"] = JSON.stringify(options.prjCoordSys); } if (options.layersID) { params["layersID"] = options.layersID.toString(); } if (options.clipRegionEnabled && options.clipRegion) { options.clipRegion = ServerGeometry.fromGeometry(Util.toSuperMapGeometry(options.clipRegion)); params["clipRegionEnabled"] = options.clipRegionEnabled; params["clipRegion"] = JSON.stringify(options.clipRegion); } //切片的起始参考点,默认为地图范围的左上角。 var crs = me._crs; if (crs.options && crs.options.origin) { params["origin"] = JSON.stringify({ x: crs.options.origin[0], y: crs.options.origin[1] }); } else if (crs.projection && crs.projection.bounds) { var bounds = crs.projection.bounds; var tileOrigin = L.point(bounds.min.x, bounds.max.y); params["origin"] = JSON.stringify({ x: tileOrigin.x, y: tileOrigin.y }); } if (options.overlapDisplayed === false) { params["overlapDisplayed"] = false; if (options.overlapDisplayedOptions) { params["overlapDisplayedOptions"] = me.overlapDisplayedOptions.toString(); } } else { params["overlapDisplayed"] = true; } if (params.cacheEnabled === true && options.tileversion) { params["tileversion"] = options.tileversion.toString(); } if (options.rasterfunction) { params["rasterfunction"] = JSON.stringify(options.rasterfunction); } return params; } }); export let tiledMapLayer = function (url, options) { return new TiledMapLayer(url, options); }; //-------------------------------------------------------------- //打点 export function makePoint(map,markers){ markers.forEach((index,item)=>{ console.log(index,item) L.marker(item.latlon).addTo(map); }) }