TiledMapLayer.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. import L, { Util as LUtil} from "leaflet";
  2. import "@supermap/iclient-leaflet/core/Base";
  3. import {
  4. SecurityManager,
  5. Unit,
  6. ServerGeometry,
  7. CommonUtil
  8. } from '@supermap/iclient-common';
  9. import * as Util from "@supermap/iclient-leaflet/core/Util";
  10. import Attributions from '@supermap/iclient-leaflet/core/Attributions'
  11. export let TiledMapLayer = L.TileLayer.extend({
  12. options: {
  13. //如果有layersID,则是在使用专题图
  14. layersID: null,
  15. //如果为 true,则将请求重定向到瓦片的真实地址;如果为 false,则响应体中是瓦片的字节流
  16. redirect: false,
  17. transparent: true,
  18. cacheEnabled: true,
  19. clipRegionEnabled: false,
  20. //地图显示裁剪的区域
  21. clipRegion: null,
  22. //请求的地图的坐标参考系统。 如:prjCoordSys={"epsgCode":3857}
  23. prjCoordSys: null,
  24. //地图对象在同一范围内时,是否重叠显示
  25. overlapDisplayed: false,
  26. //避免地图对象压盖显示的过滤选项
  27. overlapDisplayedOptions: null,
  28. //切片版本名称,cacheEnabled 为 true 时有效。
  29. tileversion: null,
  30. crs: null,
  31. format: 'png',
  32. //启用托管地址。
  33. tileProxy:null,
  34. attribution: Attributions.Common.attribution,
  35. subdomains: null
  36. },
  37. initialize: function (url, options) {
  38. this._url = url;
  39. L.TileLayer.prototype.initialize.apply(this, arguments);
  40. L.setOptions(this, options);
  41. L.stamp(this);
  42. //当前切片在切片集中的index
  43. this.tileSetsIndex = -1;
  44. this.tempIndex = -1;
  45. },
  46. /**
  47. * @private
  48. * @function L.supermap.tiledMapLayer.prototype.onAdd
  49. * @description 添加地图。
  50. * @param {L.Map} map - 待添加的影像地图参数。
  51. */
  52. onAdd: function (map) {
  53. this._crs = this.options.crs || map.options.crs;
  54. L.TileLayer.prototype.onAdd.call(this, map);
  55. },
  56. /**
  57. * @function L.supermap.tiledMapLayer.prototype.getTileUrl
  58. * @description 根据行列号获取瓦片地址。
  59. * @param {Object} coords - 行列号。
  60. * @returns {string} 瓦片地址。
  61. */
  62. getTileUrl: function (coords) {
  63. var scale = this.getScaleFromCoords(coords);
  64. var layerUrl = this._getLayerUrl();
  65. var tileUrl = layerUrl + "&scale=" + scale + "&x=" + coords.x + "&y=" + coords.y;
  66. //支持代理
  67. if (this.options.tileProxy) {
  68. tileUrl = this.options.tileProxy + encodeURIComponent(tileUrl);
  69. }
  70. if (!this.options.cacheEnabled) {
  71. tileUrl += "&_t=" + new Date().getTime();
  72. }
  73. if (this.options.subdomains) {
  74. tileUrl = L.Util.template(tileUrl, {s: this._getSubdomain(coords)});
  75. }
  76. return tileUrl;
  77. },
  78. /**
  79. * @function L.supermap.tiledMapLayer.prototype.getScale
  80. * @description 根据缩放级别获取比例尺。
  81. * @param {number} zoom - 缩放级别。
  82. * @returns {number} 比例尺。
  83. */
  84. getScale: function (zoom) {
  85. var me = this;
  86. //返回当前比例尺
  87. var z = zoom || me._map.getZoom();
  88. return me.scales[z];
  89. },
  90. /**
  91. * @function L.supermap.tiledMapLayer.prototype.getScaleFromCoords
  92. * @description 通过行列号获取比例尺。
  93. * @param {Object} coords - 行列号。
  94. * @returns {number} 比例尺。
  95. */
  96. getScaleFromCoords: function (coords) {
  97. var me = this,
  98. scale;
  99. if (me.scales && me.scales[coords.z]) {
  100. return me.scales[coords.z];
  101. }
  102. me.scales = me.scales || {};
  103. scale = me.getDefaultScale(coords);
  104. me.scales[coords.z] = scale;
  105. return scale;
  106. },
  107. /**
  108. * @private
  109. * @function L.supermap.tiledMapLayer.prototype.getDefaultScale
  110. * @description 获取默认比例尺信息。
  111. * @param {Object} coords - 坐标对象参数。
  112. */
  113. getDefaultScale: function (coords) {
  114. var me = this,
  115. crs = me._crs;
  116. if (crs.scales) {
  117. return crs.scales[coords.z];
  118. } else {
  119. var tileBounds = me._tileCoordsToBounds(coords);
  120. var ne = crs.project(tileBounds.getNorthEast());
  121. var sw = crs.project(tileBounds.getSouthWest());
  122. var tileSize = me.options.tileSize;
  123. var resolution = Math.max(
  124. Math.abs(ne.x - sw.x) / tileSize,
  125. Math.abs(ne.y - sw.y) / tileSize
  126. );
  127. var mapUnit = Unit.METER;
  128. if (crs.code) {
  129. var array = crs.code.split(':');
  130. if (array && array.length > 1) {
  131. var code = parseInt(array[1]);
  132. mapUnit = code && code >= 4000 && code <= 5000 ? Unit.DEGREE : Unit.METER;
  133. }
  134. }
  135. return Util.resolutionToScale(resolution, 96, mapUnit);
  136. }
  137. },
  138. /**
  139. * @function L.supermap.tiledMapLayer.prototype.setTileSetsInfo
  140. * @description 设置瓦片集信息。
  141. * @param {Object} tileSets - 瓦片对象集。
  142. */
  143. setTileSetsInfo: function (tileSets) {
  144. this.tileSets = tileSets;
  145. if (L.Util.isArray(this.tileSets)) {
  146. this.tileSets = this.tileSets[0];
  147. }
  148. if (!this.tileSets) {
  149. return;
  150. }
  151. /**
  152. * @event L.supermap.tiledMapLayer#tilesetsinfoloaded
  153. * @description 瓦片集信息设置完成后触发。
  154. * @property {Array.<Object>} tileVersions - 瓦片集信息。
  155. */
  156. this.fire('tilesetsinfoloaded', {
  157. tileVersions: this.tileSets.tileVersions
  158. });
  159. this.changeTilesVersion();
  160. },
  161. /**
  162. * @function L.supermap.tiledMapLayer.prototype.lastTilesVersion
  163. * @description 请求上一个版本切片,并重新绘制。
  164. */
  165. lastTilesVersion: function () {
  166. this.tempIndex = this.tileSetsIndex - 1;
  167. this.changeTilesVersion();
  168. },
  169. /**
  170. * @function L.supermap.tiledMapLayer.prototype.nextTilesVersion
  171. * @description 请求下一个版本切片,并重新绘制。
  172. */
  173. nextTilesVersion: function () {
  174. this.tempIndex = this.tileSetsIndex + 1;
  175. this.changeTilesVersion();
  176. },
  177. /**
  178. * @function L.supermap.tiledMapLayer.prototype.changeTilesVersion
  179. * @description 切换到某一版本的切片,并重绘。通过 this.tempIndex 保存需要切换的版本索引
  180. */
  181. changeTilesVersion: function () {
  182. var me = this;
  183. //切片版本集信息是否存在
  184. if (me.tileSets == null) {
  185. //版本信息为空,重新查询,查询成功继续跳转到相应的版本
  186. //me.getTileSetsInfo();
  187. return;
  188. }
  189. if (me.tempIndex === me.tileSetsIndex || this.tempIndex < 0) {
  190. return;
  191. }
  192. //检测index是否可用
  193. var tileVersions = me.tileSets.tileVersions;
  194. if (tileVersions && me.tempIndex < tileVersions.length && me.tempIndex >= 0) {
  195. var name = tileVersions[me.tempIndex].name;
  196. var result = me.mergeTileVersionParam(name);
  197. if (result) {
  198. me.tileSetsIndex = me.tempIndex;
  199. /**
  200. * @event L.supermap.tiledMapLayer#tileversionschanged
  201. * @description 切片的版本切换和重绘成功之后触发。
  202. * @property {Object} tileVersion - 该版本的切片。
  203. */
  204. me.fire('tileversionschanged', {
  205. tileVersion: tileVersions[me.tempIndex]
  206. });
  207. }
  208. }
  209. },
  210. /**
  211. * @function L.supermap.tiledMapLayer.prototype.updateCurrentTileSetsIndex
  212. * @description 手动设置当前切片集索引,目前主要提供给控件使用。
  213. * @param {number} index - 索引值。
  214. */
  215. updateCurrentTileSetsIndex: function (index) {
  216. this.tempIndex = index;
  217. },
  218. /**
  219. * @function L.supermap.tiledMapLayer.prototype.mergeTileVersionParam
  220. * @description 更改URL请求参数中的切片版本号,并重绘。
  221. * @param {string} version - 切片版本号。
  222. * @returns {boolean} 是否成功。
  223. */
  224. mergeTileVersionParam: function (version) {
  225. if (version) {
  226. this.requestParams["tileversion"] = version;
  227. this._paramsChanged = true;
  228. this.redraw();
  229. this._paramsChanged = false;
  230. return true;
  231. }
  232. return false;
  233. },
  234. _getLayerUrl: function () {
  235. if (this._paramsChanged) {
  236. this._layerUrl = this._createLayerUrl();
  237. }
  238. return this._layerUrl || this._createLayerUrl();
  239. },
  240. _createLayerUrl: function () {
  241. let layerUrl = CommonUtil.urlPathAppend(this._url, `tileImage.${this.options.format}`);
  242. this.requestParams = this.requestParams || this._getAllRequestParams();
  243. layerUrl = CommonUtil.urlAppend(layerUrl, LUtil.getParamString(this.requestParams));
  244. layerUrl = SecurityManager.appendCredential(layerUrl);
  245. this._layerUrl = layerUrl;
  246. return layerUrl;
  247. },
  248. _getAllRequestParams: function () {
  249. var me = this,
  250. options = me.options || {},
  251. params = {};
  252. var tileSize = this.options.tileSize;
  253. if (!(tileSize instanceof L.Point)) {
  254. tileSize = L.point(tileSize, tileSize);
  255. }
  256. params["width"] = tileSize.x;
  257. params["height"] = tileSize.y;
  258. params["redirect"] = options.redirect === true;
  259. params["transparent"] = options.transparent === true;
  260. params["cacheEnabled"] = !(options.cacheEnabled === false);
  261. if (options.prjCoordSys) {
  262. params["prjCoordSys"] = JSON.stringify(options.prjCoordSys);
  263. }
  264. if (options.layersID) {
  265. params["layersID"] = options.layersID.toString();
  266. }
  267. if (options.clipRegionEnabled && options.clipRegion) {
  268. options.clipRegion = ServerGeometry.fromGeometry(Util.toSuperMapGeometry(options.clipRegion));
  269. params["clipRegionEnabled"] = options.clipRegionEnabled;
  270. params["clipRegion"] = JSON.stringify(options.clipRegion);
  271. }
  272. //切片的起始参考点,默认为地图范围的左上角。
  273. var crs = me._crs;
  274. if (crs.options && crs.options.origin) {
  275. params["origin"] = JSON.stringify({
  276. x: crs.options.origin[0],
  277. y: crs.options.origin[1]
  278. });
  279. } else if (crs.projection && crs.projection.bounds) {
  280. var bounds = crs.projection.bounds;
  281. var tileOrigin = L.point(bounds.min.x, bounds.max.y);
  282. params["origin"] = JSON.stringify({
  283. x: tileOrigin.x,
  284. y: tileOrigin.y
  285. });
  286. }
  287. if (options.overlapDisplayed === false) {
  288. params["overlapDisplayed"] = false;
  289. if (options.overlapDisplayedOptions) {
  290. params["overlapDisplayedOptions"] = me.overlapDisplayedOptions.toString();
  291. }
  292. } else {
  293. params["overlapDisplayed"] = true;
  294. }
  295. if (params.cacheEnabled === true && options.tileversion) {
  296. params["tileversion"] = options.tileversion.toString();
  297. }
  298. if (options.rasterfunction) {
  299. params["rasterfunction"] = JSON.stringify(options.rasterfunction);
  300. }
  301. return params;
  302. }
  303. });
  304. export let tiledMapLayer = function (url, options) {
  305. return new TiledMapLayer(url, options);
  306. };
  307. //--------------------------------------------------------------
  308. //打点
  309. export function makePoint(map,markers){
  310. markers.forEach((index,item)=>{
  311. console.log(index,item)
  312. L.marker(item.latlon).addTo(map);
  313. })
  314. }