Newer
Older
urbanLifeline_YanAn / public / static / libs / map / rasterTileLayer.js
@zhangqy zhangqy on 3 Oct 85 KB first commit
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  3. typeof define === 'function' && define.amd ? define(factory) :
  4. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.rasterTileLayer = factory());
  5. }(this, (function () { 'use strict';
  6.  
  7. /*
  8. * @namespace Util
  9. *
  10. * Various utility functions, used by Leaflet internally.
  11. */
  12. Object.freeze = function (obj) {
  13. return obj;
  14. };
  15.  
  16. // @function create(proto: Object, properties?: Object): Object
  17. // Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create)
  18. var create$3 = Object.create || function () {
  19. function F() {}
  20. return function (proto) {
  21. F.prototype = proto;
  22. return new F();
  23. };
  24. }();
  25.  
  26. // @function setOptions(obj: Object, options: Object): Object
  27. // Merges the given properties to the `options` of the `obj` object, returning the resulting options. See `Class options`. Has an `L.setOptions` shortcut.
  28. function setOptions(obj, options) {
  29. if (!obj.hasOwnProperty('options')) {
  30. obj.options = obj.options ? create$3(obj.options) : {};
  31. }
  32. for (var i in options) {
  33. obj.options[i] = options[i] || obj.options[i];
  34. }
  35. return obj.options;
  36. }
  37.  
  38. var templateRe = /\{ *([\w_-]+) *\}/g;
  39.  
  40. // @function template(str: String, data: Object): String
  41. // Simple templating facility, accepts a template string of the form `'Hello {a}, {b}'`
  42. // and a data object like `{a: 'foo', b: 'bar'}`, returns evaluated string
  43. // `('Hello foo, bar')`. You can also specify functions instead of strings for
  44. // data values — they will be evaluated passing `data` as an argument.
  45. function template(str, data) {
  46. return str.replace(templateRe, function (str, key) {
  47. var value = data[key];
  48.  
  49. if (value === undefined) {
  50. throw new Error('No value provided for variable ' + str);
  51. } else if (typeof value === 'function') {
  52. value = value(data);
  53. }
  54. return value;
  55. });
  56. }
  57.  
  58. // @function isArray(obj): Boolean
  59. // Compatibility polyfill for [Array.isArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray)
  60. var isArray = Array.isArray || function (obj) {
  61. return Object.prototype.toString.call(obj) === '[object Array]';
  62. };
  63.  
  64. //坐标转换
  65. var pi = 3.1415926535897932384626;
  66. var a = 6378245.0;
  67. var ee = 0.00669342162296594323;
  68. var x_pi = pi * 3000.0 / 180.0;
  69.  
  70. //经纬度转xyz协议瓦片编号
  71. function lonLatToTileNumbers(lon_deg, lat_deg, zoom) {
  72. // 地球半径
  73. /* const r = 6378137;
  74.  
  75. // 地球周长
  76. const C = 2 * Math.PI * 6378137;
  77.  
  78. // 瓦片像素
  79. const titleSize = 256;
  80.  
  81. // 获取某一层级下的分辨率(X,Y方向适)
  82. const getResolution = (n) => {
  83. const tileNums = Math.pow(2, n)
  84. const tileTotalPx = tileNums * titleSize
  85. return C / tileTotalPx
  86. }
  87.  
  88. // 4326转3857
  89. const lngLatMercator = (lng, lat) => {
  90. //注意先转为为弧度制,弧度=角度*Math.PI/180,弧长=弧度*半径
  91. let x = lng * (Math.PI / 180) * r;
  92. let rad = lat * (Math.PI / 180)
  93. let sin = Math.sin(rad)
  94. let y = r / 2 * Math.log((1 + sin) / (1 - sin))
  95. return [x, y]
  96. }
  97.  
  98. // 根据像素坐标及缩放层级计算瓦片行列号
  99. const getTileRowAndCol = (x, y, z) => {
  100. //因为3857与4326坐标原点位于经纬度为零的地方,而瓦片坐标原点位于左上角,所以需要将3857坐标原点转到左上角
  101. x += C / 2;
  102. y = C / 2 - y;
  103. let resolutionX = getResolution(z)//获取某一层级z下的分辨率
  104. let row = Math.floor(x / resolutionX / tileSize)
  105. let col = Math.floor(y / resolutionY / tileSize)
  106. return [row, col]
  107. }
  108.  
  109. return getTileRowAndCol(...lngLatMercator(lon_deg,lat_deg),zoom);*/
  110.  
  111.  
  112.  
  113. /* console.log(lon_deg,lat_deg,zoom);
  114. function lon2tile(lon,zoom) {
  115. return (Math.floor((lon+180)/360*Math.pow(2,zoom)));
  116. }
  117. function lat2tile(lat,zoom) {
  118. return (Math.floor((1-Math.log(Math.tan(lat*Math.PI/180) + 1/Math.cos(lat*Math.PI/180))/Math.PI)/2 *Math.pow(2,zoom)));
  119. }
  120.  
  121. return [lon2tile(lon_deg,zoom),lat2tile(lat_deg,zoom)];*/
  122.  
  123.  
  124.  
  125. var lat_rad = pi / 180 * lat_deg; //math.radians(lat_deg) 角度转弧度
  126. var n = Math.pow(2, zoom);
  127. var xtile = parseInt((lon_deg + 180.0) / 360.0 * n);
  128. var ytile = parseInt((1.0 - Math.asinh(Math.tan(lat_rad)) / pi) / 2.0 * n);
  129. return [xtile, ytile];
  130. }
  131.  
  132. //xyz协议瓦片编号转经纬度
  133. function tileNumbersToLonLat(xtile, ytile, zoom) {
  134. /* function tile2long(x,z) {
  135. return (x/Math.pow(2,z)*360-180);
  136. }
  137.  
  138. function tile2lat(y,z) {
  139. var n=Math.PI-2*Math.PI*y/Math.pow(2,z);
  140. return (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
  141. }
  142.  
  143. return [tile2long(xtile, zoom),tile2lat(ytile,zoom)];*/
  144.  
  145.  
  146. let n = Math.pow(2, zoom);
  147. let lon_deg = xtile / n * 360.0 - 180.0;
  148. let lat_rad = Math.atan(Math.sinh(pi * (1 - 2 * ytile / n)));
  149.  
  150. let lat_deg = lat_rad * 180.0 / pi;
  151. return [lon_deg, lat_deg];
  152. }
  153.  
  154. /**百度转84*/
  155. function bd09_To_gps84(lng, lat) {
  156. if (isArray(lng)) {
  157. var _lng = lng[0];
  158. lat = lng[1];
  159. lng = _lng;
  160. }
  161. if (lng instanceof Object) {
  162. var _lng = lng.lng;
  163. lat = lng.lat;
  164. lng = _lng;
  165. }
  166. var gcj02 = bd09_To_gcj02(lng, lat);
  167. var map84 = gcj02_To_gps84(gcj02.lng, gcj02.lat);
  168. return map84;
  169. }
  170. /**84转百度*/
  171. function gps84_To_bd09(lng, lat) {
  172. if (isArray(lng)) {
  173. var _lng = lng[0];
  174. lat = lng[1];
  175. lng = _lng;
  176. }
  177. if (lng instanceof Object) {
  178. var _lng = lng.lng;
  179. lat = lng.lat;
  180. lng = _lng;
  181. }
  182. var gcj02 = gps84_To_gcj02(lng, lat);
  183. var bd09 = gcj02_To_bd09(gcj02.lng, gcj02.lat);
  184. return bd09;
  185. }
  186. /**84转火星*/
  187. function gps84_To_gcj02(lng, lat) {
  188. if (isArray(lng)) {
  189. var _lng = lng[0];
  190. lat = lng[1];
  191. lng = _lng;
  192. }
  193. if (lng instanceof Object) {
  194. var _lng = lng.lng;
  195. lat = lng.lat;
  196. lng = _lng;
  197. }
  198.  
  199. var dLat = transformLat(lng - 105.0, lat - 35.0);
  200. var dLng = transformLng(lng - 105.0, lat - 35.0);
  201. var radLat = lat / 180.0 * pi;
  202. var magic = Math.sin(radLat);
  203. magic = 1 - ee * magic * magic;
  204. var sqrtMagic = Math.sqrt(magic);
  205. dLat = dLat * 180.0 / (a * (1 - ee) / (magic * sqrtMagic) * pi);
  206. dLng = dLng * 180.0 / (a / sqrtMagic * Math.cos(radLat) * pi);
  207. var mgLat = lat + dLat;
  208. var mgLng = lng + dLng;
  209. var newCoord = {
  210. lng: mgLng,
  211. lat: mgLat
  212. };
  213. return newCoord;
  214. }
  215. /**火星转84*/
  216. function gcj02_To_gps84(lng, lat) {
  217. if (isArray(lng)) {
  218. var _lng = lng[0];
  219. lat = lng[1];
  220. lng = _lng;
  221. }
  222. if (lng instanceof Object) {
  223. var _lng = lng.lng;
  224. lat = lng.lat;
  225. lng = _lng;
  226. }
  227.  
  228. var coord = transform(lng, lat);
  229. var lontitude = lng * 2 - coord.lng;
  230. var latitude = lat * 2 - coord.lat;
  231. var newCoord = {
  232. lng: lontitude,
  233. lat: latitude
  234. };
  235. return newCoord;
  236. }
  237. /**火星转百度*/
  238. function gcj02_To_bd09(x, y) {
  239. var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
  240. var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
  241. var bd_lng = z * Math.cos(theta) + 0.0065;
  242. var bd_lat = z * Math.sin(theta) + 0.006;
  243. var newCoord = {
  244. lng: bd_lng,
  245. lat: bd_lat
  246. };
  247. return newCoord;
  248. }
  249. /**百度转火星*/
  250. function bd09_To_gcj02(bd_lng, bd_lat) {
  251. var x = bd_lng - 0.0065;
  252. var y = bd_lat - 0.006;
  253. var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
  254. var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
  255. var gg_lng = z * Math.cos(theta);
  256. var gg_lat = z * Math.sin(theta);
  257. var newCoord = {
  258. lng: gg_lng,
  259. lat: gg_lat
  260. };
  261. return newCoord;
  262. }
  263.  
  264. function transform(lng, lat) {
  265. var dLat = transformLat(lng - 105.0, lat - 35.0);
  266. var dLng = transformLng(lng - 105.0, lat - 35.0);
  267. var radLat = lat / 180.0 * pi;
  268. var magic = Math.sin(radLat);
  269. magic = 1 - ee * magic * magic;
  270. var sqrtMagic = Math.sqrt(magic);
  271. dLat = dLat * 180.0 / (a * (1 - ee) / (magic * sqrtMagic) * pi);
  272. dLng = dLng * 180.0 / (a / sqrtMagic * Math.cos(radLat) * pi);
  273. var mgLat = lat + dLat;
  274. var mgLng = lng + dLng;
  275. var newCoord = {
  276. lng: mgLng,
  277. lat: mgLat
  278. };
  279. return newCoord;
  280. }
  281.  
  282. function transformLat(x, y) {
  283. var ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
  284. ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
  285. ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
  286. ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
  287. return ret;
  288. }
  289.  
  290. function transformLng(x, y) {
  291. var ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
  292. ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
  293. ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
  294. ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
  295. return ret;
  296. }
  297.  
  298. /*
  299. * Created by CntChen 2016.05.04
  300. * 从百度JavaScritp API v2.0 抽取代码,并作少量命名修改
  301. * http://lbsyun.baidu.com/index.php?title=jspopular
  302. * http://api.map.baidu.com/getscript?v=2.0&ak=E4805d16520de693a3fe707cdc962045&t=20160503160001
  303. */
  304.  
  305. // ----- Baidu API start
  306.  
  307. // util function
  308. function Extend(a, b) {
  309. for (var c in b) b.hasOwnProperty(c) && (a[c] = b[c]);
  310. return a;
  311. }
  312. function S(a, b) {
  313. for (var c in b) a[c] = b[c];
  314. }
  315.  
  316. function Xa(a) {
  317. return "string" == typeof a;
  318. }
  319.  
  320. var j = void 0,
  321. p = null;
  322.  
  323. // Point
  324. function H(a, b) {
  325. isNaN(a) && (a = Ib(a), a = isNaN(a) ? 0 : a);
  326. Xa(a) && (a = parseFloat(a));
  327. isNaN(b) && (b = Ib(b), b = isNaN(b) ? 0 : b);
  328. Xa(b) && (b = parseFloat(b));
  329. this.lng = a;
  330. this.lat = b;
  331. }
  332. H.TL = function (a) {
  333. return a && 180 >= a.lng && -180 <= a.lng && 74 >= a.lat && -74 <= a.lat;
  334. };
  335. H.prototype.lb = function (a) {
  336. return a && this.lat == a.lat && this.lng == a.lng;
  337. };
  338.  
  339. // Pixel
  340. function Q(a, b) {
  341. this.x = a || 0;
  342. this.y = b || 0;
  343. this.x = this.x;
  344. this.y = this.y;
  345. }
  346. Q.prototype.lb = function (a) {
  347. return a && a.x == this.x && a.y == this.y;
  348. };
  349.  
  350. // MercatorProjection
  351. function fc() {}
  352. fc.prototype.nh = function () {
  353. aa("lngLatToPoint\u65b9\u6cd5\u672a\u5b9e\u73b0");
  354. };
  355. fc.prototype.wi = function () {
  356. aa("pointToLngLat\u65b9\u6cd5\u672a\u5b9e\u73b0");
  357. };
  358.  
  359. function R() {}
  360. R.prototype = new fc();
  361. Extend(R, {
  362. $O: 6370996.81,
  363. lG: [1.289059486E7, 8362377.87, 5591021, 3481989.83, 1678043.12, 0],
  364. Au: [75, 60, 45, 30, 15, 0],
  365. fP: [[1.410526172116255E-8, 8.98305509648872E-6, -1.9939833816331, 200.9824383106796, -187.2403703815547, 91.6087516669843, -23.38765649603339, 2.57121317296198, -0.03801003308653, 1.73379812E7], [-7.435856389565537E-9, 8.983055097726239E-6, -0.78625201886289, 96.32687599759846, -1.85204757529826, -59.36935905485877, 47.40033549296737, -16.50741931063887, 2.28786674699375, 1.026014486E7], [-3.030883460898826E-8, 8.98305509983578E-6, 0.30071316287616, 59.74293618442277, 7.357984074871, -25.38371002664745, 13.45380521110908, -3.29883767235584, 0.32710905363475, 6856817.37], [-1.981981304930552E-8, 8.983055099779535E-6, 0.03278182852591, 40.31678527705744, 0.65659298677277, -4.44255534477492, 0.85341911805263, 0.12923347998204, -0.04625736007561, 4482777.06], [3.09191371068437E-9, 8.983055096812155E-6, 6.995724062E-5, 23.10934304144901, -2.3663490511E-4, -0.6321817810242, -0.00663494467273, 0.03430082397953, -0.00466043876332, 2555164.4], [2.890871144776878E-9, 8.983055095805407E-6, -3.068298E-8, 7.47137025468032, -3.53937994E-6, -0.02145144861037, -1.234426596E-5, 1.0322952773E-4, -3.23890364E-6, 826088.5]],
  366. iG: [[-0.0015702102444, 111320.7020616939, 1704480524535203, -10338987376042340, 26112667856603880, -35149669176653700, 26595700718403920, -10725012454188240, 1800819912950474, 82.5], [8.277824516172526E-4, 111320.7020463578, 6.477955746671607E8, -4.082003173641316E9, 1.077490566351142E10, -1.517187553151559E10, 1.205306533862167E10, -5.124939663577472E9, 9.133119359512032E8, 67.5], [0.00337398766765, 111320.7020202162, 4481351.045890365, -2.339375119931662E7, 7.968221547186455E7, -1.159649932797253E8, 9.723671115602145E7, -4.366194633752821E7, 8477230.501135234, 52.5], [0.00220636496208, 111320.7020209128, 51751.86112841131, 3796837.749470245, 992013.7397791013, -1221952.21711287, 1340652.697009075, -620943.6990984312, 144416.9293806241, 37.5], [-3.441963504368392E-4, 111320.7020576856, 278.2353980772752, 2485758.690035394, 6070.750963243378, 54821.18345352118, 9540.606633304236, -2710.55326746645, 1405.483844121726, 22.5], [-3.218135878613132E-4, 111320.7020701615, 0.00369383431289, 823725.6402795718, 0.46104986909093, 2351.343141331292, 1.58060784298199, 8.77738589078284, 0.37238884252424, 7.45]],
  367. Z1: function (a, b) {
  368. if (!a || !b) return 0;
  369. var c,
  370. d,
  371. a = this.Fb(a);
  372. if (!a) return 0;
  373. c = this.Tk(a.lng);
  374. d = this.Tk(a.lat);
  375. b = this.Fb(b);
  376. return !b ? 0 : this.Pe(c, this.Tk(b.lng), d, this.Tk(b.lat));
  377. },
  378. Vo: function (a, b) {
  379. if (!a || !b) return 0;
  380. a.lng = this.JD(a.lng, -180, 180);
  381. a.lat = this.ND(a.lat, -74, 74);
  382. b.lng = this.JD(b.lng, -180, 180);
  383. b.lat = this.ND(b.lat, -74, 74);
  384. return this.Pe(this.Tk(a.lng), this.Tk(b.lng), this.Tk(a.lat), this.Tk(b.lat));
  385. },
  386. Fb: function (a) {
  387. if (a === p || a === j) return new H(0, 0);
  388. var b, c;
  389. b = new H(Math.abs(a.lng), Math.abs(a.lat));
  390. for (var d = 0; d < this.lG.length; d++) if (b.lat >= this.lG[d]) {
  391. c = this.fP[d];
  392. break;
  393. }
  394. a = this.gK(a, c);
  395. return a = new H(a.lng.toFixed(6), a.lat.toFixed(6));
  396. },
  397. Eb: function (a) {
  398. if (a === p || a === j || 180 < a.lng || -180 > a.lng || 90 < a.lat || -90 > a.lat) return new H(0, 0);
  399. var b, c;
  400. a.lng = this.JD(a.lng, -180, 180);
  401. a.lat = this.ND(a.lat, -74, 74);
  402. b = new H(a.lng, a.lat);
  403. for (var d = 0; d < this.Au.length; d++) if (b.lat >= this.Au[d]) {
  404. c = this.iG[d];
  405. break;
  406. }
  407.  
  408. // 对疑似bug的修改 start
  409. // by CntChen 2016.05.08
  410. // @2016-09-19 已经得到官方确认为bug:https://cntchen.github.io/2016/05/09/%E7%99%BE%E5%BA%A6JavaScirpt%20%20API%E4%B8%AD%E7%BB%8F%E7%BA%AC%E5%BA%A6%E5%9D%90%E6%A0%87%E8%BD%AC%E7%93%A6%E7%89%87%E5%9D%90%E6%A0%87bug/
  411. if (!c) for (d = 0; d < this.Au.length; d++) if (b.lat <= -this.Au[d]) {
  412. c = this.iG[d];
  413. break;
  414. }
  415. // 对疑似bug的修改 end
  416.  
  417. // Baidu JavaScript 中原本代码, 2016.05.08依然如此
  418. // if (!c)
  419. // for (d = this.Au.length - 1; 0 <= d; d--)
  420. // if (b.lat <= -this.Au[d]) {
  421. // c = this.iG[d];
  422. // break
  423. // }
  424. // Baidu JavaScript 中原本代码 end
  425.  
  426. a = this.gK(a, c);
  427. return a = new H(a.lng.toFixed(2), a.lat.toFixed(2));
  428. },
  429. gK: function (a, b) {
  430. if (a && b) {
  431. var c = b[0] + b[1] * Math.abs(a.lng),
  432. d = Math.abs(a.lat) / b[9],
  433. d = b[2] + b[3] * d + b[4] * d * d + b[5] * d * d * d + b[6] * d * d * d * d + b[7] * d * d * d * d * d + b[8] * d * d * d * d * d * d,
  434. c = c * (0 > a.lng ? -1 : 1),
  435. d = d * (0 > a.lat ? -1 : 1);
  436. return new H(c, d);
  437. }
  438. },
  439. Pe: function (a, b, c, d) {
  440. return this.$O * Math.acos(Math.sin(c) * Math.sin(d) + Math.cos(c) * Math.cos(d) * Math.cos(b - a));
  441. },
  442. Tk: function (a) {
  443. return Math.PI * a / 180;
  444. },
  445. Z3: function (a) {
  446. return 180 * a / Math.PI;
  447. },
  448. ND: function (a, b, c) {
  449. b != p && (a = Math.max(a, b));
  450. c != p && (a = Math.min(a, c));
  451. return a;
  452. },
  453. JD: function (a, b, c) {
  454. for (; a > c;) a -= c - b;
  455. for (; a < b;) a += c - b;
  456. return a;
  457. }
  458. });
  459. Extend(R.prototype, {
  460. Jm: function (a) {
  461. return R.Eb(a);
  462. },
  463. nh: function (a) {
  464. a = R.Eb(a);
  465. return new Q(a.lng, a.lat);
  466. },
  467. qh: function (a) {
  468. return R.Fb(a);
  469. },
  470. wi: function (a) {
  471. a = new H(a.x, a.y);
  472. return R.Fb(a);
  473. },
  474. fc: function (a, b, c, d, e) {
  475. if (a) return a = this.Jm(a, e), b = this.Lc(b), new Q(Math.round((a.lng - c.lng) / b + d.width / 2), Math.round((c.lat - a.lat) / b + d.height / 2));
  476. },
  477. zb: function (a, b, c, d, e) {
  478. if (a) return b = this.Lc(b), this.qh(new H(c.lng + b * (a.x - d.width / 2), c.lat - b * (a.y - d.height / 2)), e);
  479. },
  480. Lc: function (a) {
  481. return Math.pow(2, 18 - a);
  482. }
  483. });
  484.  
  485. var Je = R.prototype;
  486. S(Je, {
  487. lngLatToPoint: Je.nh,
  488. pointToLngLat: Je.wi
  489. });
  490.  
  491. // ----- Baidu API end
  492.  
  493. let BMap = {
  494. Point: H,
  495. Pixel: Q,
  496. MercatorProjection: R
  497. };
  498.  
  499. /*
  500. * Created by CntChen 2016.05.04
  501. * 坐标相关参考文章:
  502. * http://www.cnblogs.com/jz1108/archive/2011/07/02/2095376.html
  503. * http://www.cnblogs.com/janehlp/archive/2012/08/27/2658106.html
  504. * 适用地图:百度
  505. */
  506.  
  507. class TransformClassBaidu {
  508. constructor(levelRange_max, LevelRange_min) {
  509. this.levelMax = levelRange_max;
  510. this.levelMin = LevelRange_min;
  511.  
  512. this.projection = new BMap.MercatorProjection();
  513. }
  514.  
  515. _getRetain(level) {
  516. return Math.pow(2, level - 18);
  517. }
  518.  
  519. /*
  520. * 分辨率,表示水平方向上一个像素点代表的真实距离(m)
  521. * 百度地图18级时的平面坐标就是地图距离原点的距离(m)
  522. * 使用{lng:180, lat:0}时候的pointX是否等于地球赤道长一半来验证
  523. */
  524. getResolution(latitude, level) {
  525. return Math.pow(2, 18 - level) * Math.cos(latitude);
  526. }
  527.  
  528. /*
  529. * 从经纬度到百度平面坐标
  530. */
  531. lnglatToPoint(longitude, latitude) {
  532. let lnglat = new BMap.Point(longitude, latitude);
  533. let point = this.projection.lngLatToPoint(lnglat);
  534.  
  535. // 提取对象的字段并返回
  536. return {
  537. pointX: point.x,
  538. pointY: point.y
  539. };
  540. }
  541.  
  542. /*
  543. * 从百度平面坐标到经纬度
  544. */
  545. pointToLnglat(pointX, pointY) {
  546. let point = new BMap.Pixel(pointX, pointY);
  547. let lnglat = this.projection.pointToLngLat(point);
  548.  
  549. // 不直接返回lnglat对象,因为该对象在百SDK中还有其他属性和方法
  550. // 提取对象的字段后,与其他地图平台统一Lnglat的格式
  551. return {
  552. lng: lnglat.lng,
  553. lat: lnglat.lat
  554. };
  555. }
  556.  
  557. _lngToTileX(longitude, level) {
  558. let point = this.lnglatToPoint(longitude, 0);
  559. let tileX = Math.floor(point.pointX * this._getRetain(level) / 256);
  560.  
  561. return tileX;
  562. }
  563.  
  564. _latToTileY(latitude, level) {
  565. let point = this.lnglatToPoint(0, latitude);
  566. let tileY = Math.floor(point.pointY * this._getRetain(level) / 256);
  567.  
  568. return tileY;
  569. }
  570.  
  571. /*
  572. * 从经纬度获取某一级别瓦片编号
  573. */
  574. lnglatToTile(longitude, latitude, level) {
  575. let tileX = this._lngToTileX(longitude, level);
  576. let tileY = this._latToTileY(latitude, level);
  577.  
  578. return [tileX, tileY];
  579. }
  580.  
  581. _lngToPixelX(longitude, level) {
  582. let tileX = this._lngToTileX(longitude, level);
  583. let point = this.lnglatToPoint(longitude, 0);
  584. let pixelX = Math.floor(point.pointX * this._getRetain(level) - tileX * 256);
  585.  
  586. return pixelX;
  587. }
  588.  
  589. _latToPixelY(latitude, level) {
  590. let tileY = this._latToTileY(latitude, level);
  591. let point = this.lnglatToPoint(0, latitude);
  592. let pixelY = Math.floor(point.pointY * this._getRetain(level) - tileY * 256);
  593.  
  594. return pixelY;
  595. }
  596.  
  597. /*
  598. * 从经纬度到瓦片的像素坐标
  599. */
  600. lnglatToPixel(longitude, latitude, level) {
  601. let pixelX = this._lngToPixelX(longitude, level);
  602. let pixelY = this._latToPixelY(latitude, level);
  603.  
  604. return {
  605. pixelX,
  606. pixelY
  607. };
  608. }
  609.  
  610. _pixelXToLng(pixelX, tileX, level) {
  611. let pointX = (tileX * 256 + pixelX) / this._getRetain(level);
  612. let lnglat = this.pointToLnglat(pointX, 0);
  613.  
  614. return lnglat.lng;
  615. }
  616.  
  617. _pixelYToLat(pixelY, tileY, level) {
  618. let pointY = (tileY * 256 + pixelY) / this._getRetain(level);
  619. let lnglat = this.pointToLnglat(0, pointY);
  620.  
  621. return lnglat.lat;
  622. }
  623.  
  624. /*
  625. * 从某一瓦片的某一像素点到经纬度
  626. */
  627. pixelToLnglat(pixelX, pixelY, tileX, tileY, level) {
  628. let pointX = (tileX * 256 + pixelX) / this._getRetain(level);
  629. let pointY = (tileY * 256 + pixelY) / this._getRetain(level);
  630. let lnglat = this.pointToLnglat(pointX, pointY);
  631.  
  632. return [lnglat.lng, lnglat.lat];
  633. }
  634. }
  635.  
  636. function _classCallCheck(instance, Constructor) {
  637. if (!(instance instanceof Constructor)) {
  638. throw new TypeError("Cannot call a class as a function");
  639. }
  640. }
  641.  
  642. function _defineProperties(target, props) {
  643. for (var i = 0; i < props.length; i++) {
  644. var descriptor = props[i];
  645. descriptor.enumerable = descriptor.enumerable || false;
  646. descriptor.configurable = true;
  647. if ("value" in descriptor) descriptor.writable = true;
  648. Object.defineProperty(target, descriptor.key, descriptor);
  649. }
  650. }
  651.  
  652. function _createClass(Constructor, protoProps, staticProps) {
  653. if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  654. if (staticProps) _defineProperties(Constructor, staticProps);
  655. return Constructor;
  656. }
  657.  
  658. function getDefaultExportFromCjs (x) {
  659. return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
  660. }
  661.  
  662. var _typeof$1 = {exports: {}};
  663.  
  664. (function (module) {
  665. function _typeof(obj) {
  666. "@babel/helpers - typeof";
  667.  
  668. if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
  669. module.exports = _typeof = function _typeof(obj) {
  670. return typeof obj;
  671. };
  672.  
  673. module.exports["default"] = module.exports, module.exports.__esModule = true;
  674. } else {
  675. module.exports = _typeof = function _typeof(obj) {
  676. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  677. };
  678.  
  679. module.exports["default"] = module.exports, module.exports.__esModule = true;
  680. }
  681.  
  682. return _typeof(obj);
  683. }
  684.  
  685. module.exports = _typeof;
  686. module.exports["default"] = module.exports, module.exports.__esModule = true;
  687. }(_typeof$1));
  688.  
  689. var _typeof = /*@__PURE__*/getDefaultExportFromCjs(_typeof$1.exports);
  690.  
  691. function _assertThisInitialized(self) {
  692. if (self === void 0) {
  693. throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  694. }
  695.  
  696. return self;
  697. }
  698.  
  699. function _possibleConstructorReturn(self, call) {
  700. if (call && (_typeof(call) === "object" || typeof call === "function")) {
  701. return call;
  702. }
  703.  
  704. return _assertThisInitialized(self);
  705. }
  706.  
  707. function _getPrototypeOf(o) {
  708. _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
  709. return o.__proto__ || Object.getPrototypeOf(o);
  710. };
  711. return _getPrototypeOf(o);
  712. }
  713.  
  714. function _setPrototypeOf(o, p) {
  715. _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
  716. o.__proto__ = p;
  717. return o;
  718. };
  719.  
  720. return _setPrototypeOf(o, p);
  721. }
  722.  
  723. function _inherits(subClass, superClass) {
  724. if (typeof superClass !== "function" && superClass !== null) {
  725. throw new TypeError("Super expression must either be null or a function");
  726. }
  727.  
  728. subClass.prototype = Object.create(superClass && superClass.prototype, {
  729. constructor: {
  730. value: subClass,
  731. writable: true,
  732. configurable: true
  733. }
  734. });
  735. if (superClass) _setPrototypeOf(subClass, superClass);
  736. }
  737.  
  738. function _arrayWithHoles(arr) {
  739. if (Array.isArray(arr)) return arr;
  740. }
  741.  
  742. function _iterableToArrayLimit(arr, i) {
  743. var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
  744.  
  745. if (_i == null) return;
  746. var _arr = [];
  747. var _n = true;
  748. var _d = false;
  749.  
  750. var _s, _e;
  751.  
  752. try {
  753. for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
  754. _arr.push(_s.value);
  755.  
  756. if (i && _arr.length === i) break;
  757. }
  758. } catch (err) {
  759. _d = true;
  760. _e = err;
  761. } finally {
  762. try {
  763. if (!_n && _i["return"] != null) _i["return"]();
  764. } finally {
  765. if (_d) throw _e;
  766. }
  767. }
  768.  
  769. return _arr;
  770. }
  771.  
  772. function _arrayLikeToArray(arr, len) {
  773. if (len == null || len > arr.length) len = arr.length;
  774.  
  775. for (var i = 0, arr2 = new Array(len); i < len; i++) {
  776. arr2[i] = arr[i];
  777. }
  778.  
  779. return arr2;
  780. }
  781.  
  782. function _unsupportedIterableToArray(o, minLen) {
  783. if (!o) return;
  784. if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  785. var n = Object.prototype.toString.call(o).slice(8, -1);
  786. if (n === "Object" && o.constructor) n = o.constructor.name;
  787. if (n === "Map" || n === "Set") return Array.from(o);
  788. if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
  789. }
  790.  
  791. function _nonIterableRest() {
  792. throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  793. }
  794.  
  795. function _slicedToArray(arr, i) {
  796. return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
  797. }
  798.  
  799. /**
  800. * Common utilities
  801. * @module glMatrix
  802. */
  803. // Configuration Constants
  804. var EPSILON = 0.000001;
  805. var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array;
  806. if (!Math.hypot) Math.hypot = function () {
  807. var y = 0,
  808. i = arguments.length;
  809.  
  810. while (i--) {
  811. y += arguments[i] * arguments[i];
  812. }
  813.  
  814. return Math.sqrt(y);
  815. };
  816.  
  817. /**
  818. * 4 Dimensional Vector
  819. * @module vec4
  820. */
  821.  
  822. /**
  823. * Creates a new, empty vec4
  824. *
  825. * @returns {vec4} a new 4D vector
  826. */
  827.  
  828. function create$2() {
  829. var out = new ARRAY_TYPE(4);
  830.  
  831. if (ARRAY_TYPE != Float32Array) {
  832. out[0] = 0;
  833. out[1] = 0;
  834. out[2] = 0;
  835. out[3] = 0;
  836. }
  837.  
  838. return out;
  839. }
  840. /**
  841. * Scales a vec4 by a scalar number
  842. *
  843. * @param {vec4} out the receiving vector
  844. * @param {ReadonlyVec4} a the vector to scale
  845. * @param {Number} b amount to scale the vector by
  846. * @returns {vec4} out
  847. */
  848.  
  849. function scale$1(out, a, b) {
  850. out[0] = a[0] * b;
  851. out[1] = a[1] * b;
  852. out[2] = a[2] * b;
  853. out[3] = a[3] * b;
  854. return out;
  855. }
  856. /**
  857. * Transforms the vec4 with a mat4.
  858. *
  859. * @param {vec4} out the receiving vector
  860. * @param {ReadonlyVec4} a the vector to transform
  861. * @param {ReadonlyMat4} m matrix to transform with
  862. * @returns {vec4} out
  863. */
  864.  
  865. function transformMat4(out, a, m) {
  866. var x = a[0],
  867. y = a[1],
  868. z = a[2],
  869. w = a[3];
  870. out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
  871. out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
  872. out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
  873. out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
  874. return out;
  875. }
  876. /**
  877. * Perform some operation over an array of vec4s.
  878. *
  879. * @param {Array} a the array of vectors to iterate over
  880. * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed
  881. * @param {Number} offset Number of elements to skip at the beginning of the array
  882. * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array
  883. * @param {Function} fn Function to call for each vector in the array
  884. * @param {Object} [arg] additional argument to pass to fn
  885. * @returns {Array} a
  886. * @function
  887. */
  888.  
  889. (function () {
  890. var vec = create$2();
  891. return function (a, stride, offset, count, fn, arg) {
  892. var i, l;
  893.  
  894. if (!stride) {
  895. stride = 4;
  896. }
  897.  
  898. if (!offset) {
  899. offset = 0;
  900. }
  901.  
  902. if (count) {
  903. l = Math.min(count * stride + offset, a.length);
  904. } else {
  905. l = a.length;
  906. }
  907.  
  908. for (i = offset; i < l; i += stride) {
  909. vec[0] = a[i];
  910. vec[1] = a[i + 1];
  911. vec[2] = a[i + 2];
  912. vec[3] = a[i + 3];
  913. fn(vec, vec, arg);
  914. a[i] = vec[0];
  915. a[i + 1] = vec[1];
  916. a[i + 2] = vec[2];
  917. a[i + 3] = vec[3];
  918. }
  919.  
  920. return a;
  921. };
  922. })();
  923.  
  924. function createMat4() {
  925. return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
  926. }
  927. function transformVector(matrix, vector) {
  928. var result = transformMat4([], vector, matrix);
  929. scale$1(result, result, 1 / result[3]);
  930. return result;
  931. }
  932.  
  933. /**
  934. * Inverts a mat4
  935. *
  936. * @param {mat4} out the receiving matrix
  937. * @param {ReadonlyMat4} a the source matrix
  938. * @returns {mat4} out
  939. */
  940.  
  941. function invert(out, a) {
  942. var a00 = a[0],
  943. a01 = a[1],
  944. a02 = a[2],
  945. a03 = a[3];
  946. var a10 = a[4],
  947. a11 = a[5],
  948. a12 = a[6],
  949. a13 = a[7];
  950. var a20 = a[8],
  951. a21 = a[9],
  952. a22 = a[10],
  953. a23 = a[11];
  954. var a30 = a[12],
  955. a31 = a[13],
  956. a32 = a[14],
  957. a33 = a[15];
  958. var b00 = a00 * a11 - a01 * a10;
  959. var b01 = a00 * a12 - a02 * a10;
  960. var b02 = a00 * a13 - a03 * a10;
  961. var b03 = a01 * a12 - a02 * a11;
  962. var b04 = a01 * a13 - a03 * a11;
  963. var b05 = a02 * a13 - a03 * a12;
  964. var b06 = a20 * a31 - a21 * a30;
  965. var b07 = a20 * a32 - a22 * a30;
  966. var b08 = a20 * a33 - a23 * a30;
  967. var b09 = a21 * a32 - a22 * a31;
  968. var b10 = a21 * a33 - a23 * a31;
  969. var b11 = a22 * a33 - a23 * a32; // Calculate the determinant
  970.  
  971. var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
  972.  
  973. if (!det) {
  974. return null;
  975. }
  976.  
  977. det = 1.0 / det;
  978. out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
  979. out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
  980. out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
  981. out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
  982. out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
  983. out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
  984. out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
  985. out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
  986. out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
  987. out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
  988. out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
  989. out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
  990. out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
  991. out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
  992. out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
  993. out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
  994. return out;
  995. }
  996. /**
  997. * Multiplies two mat4s
  998. *
  999. * @param {mat4} out the receiving matrix
  1000. * @param {ReadonlyMat4} a the first operand
  1001. * @param {ReadonlyMat4} b the second operand
  1002. * @returns {mat4} out
  1003. */
  1004.  
  1005. function multiply(out, a, b) {
  1006. var a00 = a[0],
  1007. a01 = a[1],
  1008. a02 = a[2],
  1009. a03 = a[3];
  1010. var a10 = a[4],
  1011. a11 = a[5],
  1012. a12 = a[6],
  1013. a13 = a[7];
  1014. var a20 = a[8],
  1015. a21 = a[9],
  1016. a22 = a[10],
  1017. a23 = a[11];
  1018. var a30 = a[12],
  1019. a31 = a[13],
  1020. a32 = a[14],
  1021. a33 = a[15]; // Cache only the current line of the second matrix
  1022.  
  1023. var b0 = b[0],
  1024. b1 = b[1],
  1025. b2 = b[2],
  1026. b3 = b[3];
  1027. out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  1028. out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  1029. out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  1030. out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  1031. b0 = b[4];
  1032. b1 = b[5];
  1033. b2 = b[6];
  1034. b3 = b[7];
  1035. out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  1036. out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  1037. out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  1038. out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  1039. b0 = b[8];
  1040. b1 = b[9];
  1041. b2 = b[10];
  1042. b3 = b[11];
  1043. out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  1044. out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  1045. out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  1046. out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  1047. b0 = b[12];
  1048. b1 = b[13];
  1049. b2 = b[14];
  1050. b3 = b[15];
  1051. out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  1052. out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  1053. out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  1054. out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  1055. return out;
  1056. }
  1057. /**
  1058. * Translate a mat4 by the given vector
  1059. *
  1060. * @param {mat4} out the receiving matrix
  1061. * @param {ReadonlyMat4} a the matrix to translate
  1062. * @param {ReadonlyVec3} v vector to translate by
  1063. * @returns {mat4} out
  1064. */
  1065.  
  1066. function translate(out, a, v) {
  1067. var x = v[0],
  1068. y = v[1],
  1069. z = v[2];
  1070. var a00, a01, a02, a03;
  1071. var a10, a11, a12, a13;
  1072. var a20, a21, a22, a23;
  1073.  
  1074. if (a === out) {
  1075. out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
  1076. out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
  1077. out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
  1078. out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
  1079. } else {
  1080. a00 = a[0];
  1081. a01 = a[1];
  1082. a02 = a[2];
  1083. a03 = a[3];
  1084. a10 = a[4];
  1085. a11 = a[5];
  1086. a12 = a[6];
  1087. a13 = a[7];
  1088. a20 = a[8];
  1089. a21 = a[9];
  1090. a22 = a[10];
  1091. a23 = a[11];
  1092. out[0] = a00;
  1093. out[1] = a01;
  1094. out[2] = a02;
  1095. out[3] = a03;
  1096. out[4] = a10;
  1097. out[5] = a11;
  1098. out[6] = a12;
  1099. out[7] = a13;
  1100. out[8] = a20;
  1101. out[9] = a21;
  1102. out[10] = a22;
  1103. out[11] = a23;
  1104. out[12] = a00 * x + a10 * y + a20 * z + a[12];
  1105. out[13] = a01 * x + a11 * y + a21 * z + a[13];
  1106. out[14] = a02 * x + a12 * y + a22 * z + a[14];
  1107. out[15] = a03 * x + a13 * y + a23 * z + a[15];
  1108. }
  1109.  
  1110. return out;
  1111. }
  1112. /**
  1113. * Scales the mat4 by the dimensions in the given vec3 not using vectorization
  1114. *
  1115. * @param {mat4} out the receiving matrix
  1116. * @param {ReadonlyMat4} a the matrix to scale
  1117. * @param {ReadonlyVec3} v the vec3 to scale the matrix by
  1118. * @returns {mat4} out
  1119. **/
  1120.  
  1121. function scale(out, a, v) {
  1122. var x = v[0],
  1123. y = v[1],
  1124. z = v[2];
  1125. out[0] = a[0] * x;
  1126. out[1] = a[1] * x;
  1127. out[2] = a[2] * x;
  1128. out[3] = a[3] * x;
  1129. out[4] = a[4] * y;
  1130. out[5] = a[5] * y;
  1131. out[6] = a[6] * y;
  1132. out[7] = a[7] * y;
  1133. out[8] = a[8] * z;
  1134. out[9] = a[9] * z;
  1135. out[10] = a[10] * z;
  1136. out[11] = a[11] * z;
  1137. out[12] = a[12];
  1138. out[13] = a[13];
  1139. out[14] = a[14];
  1140. out[15] = a[15];
  1141. return out;
  1142. }
  1143. /**
  1144. * Rotates a matrix by the given angle around the X axis
  1145. *
  1146. * @param {mat4} out the receiving matrix
  1147. * @param {ReadonlyMat4} a the matrix to rotate
  1148. * @param {Number} rad the angle to rotate the matrix by
  1149. * @returns {mat4} out
  1150. */
  1151.  
  1152. function rotateX(out, a, rad) {
  1153. var s = Math.sin(rad);
  1154. var c = Math.cos(rad);
  1155. var a10 = a[4];
  1156. var a11 = a[5];
  1157. var a12 = a[6];
  1158. var a13 = a[7];
  1159. var a20 = a[8];
  1160. var a21 = a[9];
  1161. var a22 = a[10];
  1162. var a23 = a[11];
  1163.  
  1164. if (a !== out) {
  1165. // If the source and destination differ, copy the unchanged rows
  1166. out[0] = a[0];
  1167. out[1] = a[1];
  1168. out[2] = a[2];
  1169. out[3] = a[3];
  1170. out[12] = a[12];
  1171. out[13] = a[13];
  1172. out[14] = a[14];
  1173. out[15] = a[15];
  1174. } // Perform axis-specific matrix multiplication
  1175.  
  1176.  
  1177. out[4] = a10 * c + a20 * s;
  1178. out[5] = a11 * c + a21 * s;
  1179. out[6] = a12 * c + a22 * s;
  1180. out[7] = a13 * c + a23 * s;
  1181. out[8] = a20 * c - a10 * s;
  1182. out[9] = a21 * c - a11 * s;
  1183. out[10] = a22 * c - a12 * s;
  1184. out[11] = a23 * c - a13 * s;
  1185. return out;
  1186. }
  1187. /**
  1188. * Rotates a matrix by the given angle around the Z axis
  1189. *
  1190. * @param {mat4} out the receiving matrix
  1191. * @param {ReadonlyMat4} a the matrix to rotate
  1192. * @param {Number} rad the angle to rotate the matrix by
  1193. * @returns {mat4} out
  1194. */
  1195.  
  1196. function rotateZ(out, a, rad) {
  1197. var s = Math.sin(rad);
  1198. var c = Math.cos(rad);
  1199. var a00 = a[0];
  1200. var a01 = a[1];
  1201. var a02 = a[2];
  1202. var a03 = a[3];
  1203. var a10 = a[4];
  1204. var a11 = a[5];
  1205. var a12 = a[6];
  1206. var a13 = a[7];
  1207.  
  1208. if (a !== out) {
  1209. // If the source and destination differ, copy the unchanged last row
  1210. out[8] = a[8];
  1211. out[9] = a[9];
  1212. out[10] = a[10];
  1213. out[11] = a[11];
  1214. out[12] = a[12];
  1215. out[13] = a[13];
  1216. out[14] = a[14];
  1217. out[15] = a[15];
  1218. } // Perform axis-specific matrix multiplication
  1219.  
  1220.  
  1221. out[0] = a00 * c + a10 * s;
  1222. out[1] = a01 * c + a11 * s;
  1223. out[2] = a02 * c + a12 * s;
  1224. out[3] = a03 * c + a13 * s;
  1225. out[4] = a10 * c - a00 * s;
  1226. out[5] = a11 * c - a01 * s;
  1227. out[6] = a12 * c - a02 * s;
  1228. out[7] = a13 * c - a03 * s;
  1229. return out;
  1230. }
  1231. /**
  1232. * Generates a perspective projection matrix with the given bounds.
  1233. * Passing null/undefined/no value for far will generate infinite projection matrix.
  1234. *
  1235. * @param {mat4} out mat4 frustum matrix will be written into
  1236. * @param {number} fovy Vertical field of view in radians
  1237. * @param {number} aspect Aspect ratio. typically viewport width/height
  1238. * @param {number} near Near bound of the frustum
  1239. * @param {number} far Far bound of the frustum, can be null or Infinity
  1240. * @returns {mat4} out
  1241. */
  1242.  
  1243. function perspective(out, fovy, aspect, near, far) {
  1244. var f = 1.0 / Math.tan(fovy / 2),
  1245. nf;
  1246. out[0] = f / aspect;
  1247. out[1] = 0;
  1248. out[2] = 0;
  1249. out[3] = 0;
  1250. out[4] = 0;
  1251. out[5] = f;
  1252. out[6] = 0;
  1253. out[7] = 0;
  1254. out[8] = 0;
  1255. out[9] = 0;
  1256. out[11] = -1;
  1257. out[12] = 0;
  1258. out[13] = 0;
  1259. out[15] = 0;
  1260.  
  1261. if (far != null && far !== Infinity) {
  1262. nf = 1 / (near - far);
  1263. out[10] = (far + near) * nf;
  1264. out[14] = 2 * far * near * nf;
  1265. } else {
  1266. out[10] = -1;
  1267. out[14] = -2 * near;
  1268. }
  1269.  
  1270. return out;
  1271. }
  1272. /**
  1273. * Returns whether or not the matrices have approximately the same elements in the same position.
  1274. *
  1275. * @param {ReadonlyMat4} a The first matrix.
  1276. * @param {ReadonlyMat4} b The second matrix.
  1277. * @returns {Boolean} True if the matrices are equal, false otherwise.
  1278. */
  1279.  
  1280. function equals(a, b) {
  1281. var a0 = a[0],
  1282. a1 = a[1],
  1283. a2 = a[2],
  1284. a3 = a[3];
  1285. var a4 = a[4],
  1286. a5 = a[5],
  1287. a6 = a[6],
  1288. a7 = a[7];
  1289. var a8 = a[8],
  1290. a9 = a[9],
  1291. a10 = a[10],
  1292. a11 = a[11];
  1293. var a12 = a[12],
  1294. a13 = a[13],
  1295. a14 = a[14],
  1296. a15 = a[15];
  1297. var b0 = b[0],
  1298. b1 = b[1],
  1299. b2 = b[2],
  1300. b3 = b[3];
  1301. var b4 = b[4],
  1302. b5 = b[5],
  1303. b6 = b[6],
  1304. b7 = b[7];
  1305. var b8 = b[8],
  1306. b9 = b[9],
  1307. b10 = b[10],
  1308. b11 = b[11];
  1309. var b12 = b[12],
  1310. b13 = b[13],
  1311. b14 = b[14],
  1312. b15 = b[15];
  1313. return Math.abs(a0 - b0) <= EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= EPSILON * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= EPSILON * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= EPSILON * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= EPSILON * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= EPSILON * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= EPSILON * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= EPSILON * Math.max(1.0, Math.abs(a15), Math.abs(b15));
  1314. }
  1315.  
  1316. /**
  1317. * 2 Dimensional Vector
  1318. * @module vec2
  1319. */
  1320.  
  1321. /**
  1322. * Creates a new, empty vec2
  1323. *
  1324. * @returns {vec2} a new 2D vector
  1325. */
  1326.  
  1327. function create$1() {
  1328. var out = new ARRAY_TYPE(2);
  1329.  
  1330. if (ARRAY_TYPE != Float32Array) {
  1331. out[0] = 0;
  1332. out[1] = 0;
  1333. }
  1334.  
  1335. return out;
  1336. }
  1337. /**
  1338. * Adds two vec2's
  1339. *
  1340. * @param {vec2} out the receiving vector
  1341. * @param {ReadonlyVec2} a the first operand
  1342. * @param {ReadonlyVec2} b the second operand
  1343. * @returns {vec2} out
  1344. */
  1345.  
  1346. function add(out, a, b) {
  1347. out[0] = a[0] + b[0];
  1348. out[1] = a[1] + b[1];
  1349. return out;
  1350. }
  1351. /**
  1352. * Negates the components of a vec2
  1353. *
  1354. * @param {vec2} out the receiving vector
  1355. * @param {ReadonlyVec2} a vector to negate
  1356. * @returns {vec2} out
  1357. */
  1358.  
  1359. function negate$1(out, a) {
  1360. out[0] = -a[0];
  1361. out[1] = -a[1];
  1362. return out;
  1363. }
  1364. /**
  1365. * Performs a linear interpolation between two vec2's
  1366. *
  1367. * @param {vec2} out the receiving vector
  1368. * @param {ReadonlyVec2} a the first operand
  1369. * @param {ReadonlyVec2} b the second operand
  1370. * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
  1371. * @returns {vec2} out
  1372. */
  1373.  
  1374. function lerp(out, a, b, t) {
  1375. var ax = a[0],
  1376. ay = a[1];
  1377. out[0] = ax + t * (b[0] - ax);
  1378. out[1] = ay + t * (b[1] - ay);
  1379. return out;
  1380. }
  1381. /**
  1382. * Perform some operation over an array of vec2s.
  1383. *
  1384. * @param {Array} a the array of vectors to iterate over
  1385. * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed
  1386. * @param {Number} offset Number of elements to skip at the beginning of the array
  1387. * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array
  1388. * @param {Function} fn Function to call for each vector in the array
  1389. * @param {Object} [arg] additional argument to pass to fn
  1390. * @returns {Array} a
  1391. * @function
  1392. */
  1393.  
  1394. (function () {
  1395. var vec = create$1();
  1396. return function (a, stride, offset, count, fn, arg) {
  1397. var i, l;
  1398.  
  1399. if (!stride) {
  1400. stride = 2;
  1401. }
  1402.  
  1403. if (!offset) {
  1404. offset = 0;
  1405. }
  1406.  
  1407. if (count) {
  1408. l = Math.min(count * stride + offset, a.length);
  1409. } else {
  1410. l = a.length;
  1411. }
  1412.  
  1413. for (i = offset; i < l; i += stride) {
  1414. vec[0] = a[i];
  1415. vec[1] = a[i + 1];
  1416. fn(vec, vec, arg);
  1417. a[i] = vec[0];
  1418. a[i + 1] = vec[1];
  1419. }
  1420.  
  1421. return a;
  1422. };
  1423. })();
  1424.  
  1425. /**
  1426. * 3 Dimensional Vector
  1427. * @module vec3
  1428. */
  1429.  
  1430. /**
  1431. * Creates a new, empty vec3
  1432. *
  1433. * @returns {vec3} a new 3D vector
  1434. */
  1435.  
  1436. function create() {
  1437. var out = new ARRAY_TYPE(3);
  1438.  
  1439. if (ARRAY_TYPE != Float32Array) {
  1440. out[0] = 0;
  1441. out[1] = 0;
  1442. out[2] = 0;
  1443. }
  1444.  
  1445. return out;
  1446. }
  1447. /**
  1448. * Negates the components of a vec3
  1449. *
  1450. * @param {vec3} out the receiving vector
  1451. * @param {ReadonlyVec3} a vector to negate
  1452. * @returns {vec3} out
  1453. */
  1454.  
  1455. function negate(out, a) {
  1456. out[0] = -a[0];
  1457. out[1] = -a[1];
  1458. out[2] = -a[2];
  1459. return out;
  1460. }
  1461. /**
  1462. * Perform some operation over an array of vec3s.
  1463. *
  1464. * @param {Array} a the array of vectors to iterate over
  1465. * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
  1466. * @param {Number} offset Number of elements to skip at the beginning of the array
  1467. * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
  1468. * @param {Function} fn Function to call for each vector in the array
  1469. * @param {Object} [arg] additional argument to pass to fn
  1470. * @returns {Array} a
  1471. * @function
  1472. */
  1473.  
  1474. (function () {
  1475. var vec = create();
  1476. return function (a, stride, offset, count, fn, arg) {
  1477. var i, l;
  1478.  
  1479. if (!stride) {
  1480. stride = 3;
  1481. }
  1482.  
  1483. if (!offset) {
  1484. offset = 0;
  1485. }
  1486.  
  1487. if (count) {
  1488. l = Math.min(count * stride + offset, a.length);
  1489. } else {
  1490. l = a.length;
  1491. }
  1492.  
  1493. for (i = offset; i < l; i += stride) {
  1494. vec[0] = a[i];
  1495. vec[1] = a[i + 1];
  1496. vec[2] = a[i + 2];
  1497. fn(vec, vec, arg);
  1498. a[i] = vec[0];
  1499. a[i + 1] = vec[1];
  1500. a[i + 2] = vec[2];
  1501. }
  1502.  
  1503. return a;
  1504. };
  1505. })();
  1506.  
  1507. function assert(condition, message) {
  1508. if (!condition) {
  1509. throw new Error(message || 'viewport-mercator-project: assertion failed.');
  1510. }
  1511. }
  1512.  
  1513. var PI$1 = Math.PI;
  1514. var PI_4 = PI$1 / 4;
  1515. var DEGREES_TO_RADIANS$1 = PI$1 / 180;
  1516. var RADIANS_TO_DEGREES = 180 / PI$1;
  1517. var TILE_SIZE$1 = 512;
  1518. var EARTH_CIRCUMFERENCE$1 = 40.03e6;
  1519. var DEFAULT_ALTITUDE = 1.5;
  1520. function zoomToScale$1(zoom) {
  1521. return Math.pow(2, zoom);
  1522. }
  1523. function lngLatToWorld(_ref, scale) {
  1524. var _ref2 = _slicedToArray(_ref, 2),
  1525. lng = _ref2[0],
  1526. lat = _ref2[1];
  1527.  
  1528. assert(Number.isFinite(lng) && Number.isFinite(scale));
  1529. assert(Number.isFinite(lat) && lat >= -90 && lat <= 90, 'invalid latitude');
  1530. scale *= TILE_SIZE$1;
  1531. var lambda2 = lng * DEGREES_TO_RADIANS$1;
  1532. var phi2 = lat * DEGREES_TO_RADIANS$1;
  1533. var x = scale * (lambda2 + PI$1) / (2 * PI$1);
  1534. var y = scale * (PI$1 - Math.log(Math.tan(PI_4 + phi2 * 0.5))) / (2 * PI$1);
  1535. return [x, y];
  1536. }
  1537. function worldToLngLat(_ref3, scale) {
  1538. var _ref4 = _slicedToArray(_ref3, 2),
  1539. x = _ref4[0],
  1540. y = _ref4[1];
  1541.  
  1542. scale *= TILE_SIZE$1;
  1543. var lambda2 = x / scale * (2 * PI$1) - PI$1;
  1544. var phi2 = 2 * (Math.atan(Math.exp(PI$1 - y / scale * (2 * PI$1))) - PI_4);
  1545. return [lambda2 * RADIANS_TO_DEGREES, phi2 * RADIANS_TO_DEGREES];
  1546. }
  1547. function getDistanceScales$1(_ref6) {
  1548. var latitude = _ref6.latitude,
  1549. longitude = _ref6.longitude,
  1550. zoom = _ref6.zoom,
  1551. scale = _ref6.scale,
  1552. _ref6$highPrecision = _ref6.highPrecision,
  1553. highPrecision = _ref6$highPrecision === void 0 ? false : _ref6$highPrecision;
  1554. scale = scale !== undefined ? scale : zoomToScale$1(zoom);
  1555. assert(Number.isFinite(latitude) && Number.isFinite(longitude) && Number.isFinite(scale));
  1556. var result = {};
  1557. var worldSize = TILE_SIZE$1 * scale;
  1558. var latCosine = Math.cos(latitude * DEGREES_TO_RADIANS$1);
  1559. var pixelsPerDegreeX = worldSize / 360;
  1560. var pixelsPerDegreeY = pixelsPerDegreeX / latCosine;
  1561. var altPixelsPerMeter = worldSize / EARTH_CIRCUMFERENCE$1 / latCosine;
  1562. result.pixelsPerMeter = [altPixelsPerMeter, -altPixelsPerMeter, altPixelsPerMeter];
  1563. result.metersPerPixel = [1 / altPixelsPerMeter, -1 / altPixelsPerMeter, 1 / altPixelsPerMeter];
  1564. result.pixelsPerDegree = [pixelsPerDegreeX, -pixelsPerDegreeY, altPixelsPerMeter];
  1565. result.degreesPerPixel = [1 / pixelsPerDegreeX, -1 / pixelsPerDegreeY, 1 / altPixelsPerMeter];
  1566.  
  1567. if (highPrecision) {
  1568. var latCosine2 = DEGREES_TO_RADIANS$1 * Math.tan(latitude * DEGREES_TO_RADIANS$1) / latCosine;
  1569. var pixelsPerDegreeY2 = pixelsPerDegreeX * latCosine2 / 2;
  1570. var altPixelsPerDegree2 = worldSize / EARTH_CIRCUMFERENCE$1 * latCosine2;
  1571. var altPixelsPerMeter2 = altPixelsPerDegree2 / pixelsPerDegreeY * altPixelsPerMeter;
  1572. result.pixelsPerDegree2 = [0, -pixelsPerDegreeY2, altPixelsPerDegree2];
  1573. result.pixelsPerMeter2 = [altPixelsPerMeter2, 0, altPixelsPerMeter2];
  1574. }
  1575.  
  1576. return result;
  1577. }
  1578. function getViewMatrix(_ref7) {
  1579. var height = _ref7.height,
  1580. pitch = _ref7.pitch,
  1581. bearing = _ref7.bearing,
  1582. altitude = _ref7.altitude,
  1583. _ref7$center = _ref7.center,
  1584. center = _ref7$center === void 0 ? null : _ref7$center,
  1585. _ref7$flipY = _ref7.flipY,
  1586. flipY = _ref7$flipY === void 0 ? false : _ref7$flipY;
  1587. var vm = createMat4();
  1588. translate(vm, vm, [0, 0, -altitude]);
  1589. scale(vm, vm, [1, 1, 1 / height]);
  1590. rotateX(vm, vm, -pitch * DEGREES_TO_RADIANS$1);
  1591. rotateZ(vm, vm, bearing * DEGREES_TO_RADIANS$1);
  1592.  
  1593. if (flipY) {
  1594. scale(vm, vm, [1, -1, 1]);
  1595. }
  1596.  
  1597. if (center) {
  1598. translate(vm, vm, negate([], center));
  1599. }
  1600.  
  1601. return vm;
  1602. }
  1603. function getProjectionParameters(_ref8) {
  1604. var width = _ref8.width,
  1605. height = _ref8.height,
  1606. _ref8$altitude = _ref8.altitude,
  1607. altitude = _ref8$altitude === void 0 ? DEFAULT_ALTITUDE : _ref8$altitude,
  1608. _ref8$pitch = _ref8.pitch,
  1609. pitch = _ref8$pitch === void 0 ? 0 : _ref8$pitch,
  1610. _ref8$nearZMultiplier = _ref8.nearZMultiplier,
  1611. nearZMultiplier = _ref8$nearZMultiplier === void 0 ? 1 : _ref8$nearZMultiplier,
  1612. _ref8$farZMultiplier = _ref8.farZMultiplier,
  1613. farZMultiplier = _ref8$farZMultiplier === void 0 ? 1 : _ref8$farZMultiplier;
  1614. var pitchRadians = pitch * DEGREES_TO_RADIANS$1;
  1615. var halfFov = Math.atan(0.5 / altitude);
  1616. var topHalfSurfaceDistance = Math.sin(halfFov) * altitude / Math.sin(Math.PI / 2 - pitchRadians - halfFov);
  1617. var farZ = Math.cos(Math.PI / 2 - pitchRadians) * topHalfSurfaceDistance + altitude;
  1618. return {
  1619. fov: 2 * Math.atan(height / 2 / altitude),
  1620. aspect: width / height,
  1621. focalDistance: altitude,
  1622. near: nearZMultiplier,
  1623. far: farZ * farZMultiplier
  1624. };
  1625. }
  1626. function getProjectionMatrix(_ref9) {
  1627. var width = _ref9.width,
  1628. height = _ref9.height,
  1629. pitch = _ref9.pitch,
  1630. altitude = _ref9.altitude,
  1631. nearZMultiplier = _ref9.nearZMultiplier,
  1632. farZMultiplier = _ref9.farZMultiplier;
  1633.  
  1634. var _getProjectionParamet = getProjectionParameters({
  1635. width: width,
  1636. height: height,
  1637. altitude: altitude,
  1638. pitch: pitch,
  1639. nearZMultiplier: nearZMultiplier,
  1640. farZMultiplier: farZMultiplier
  1641. }),
  1642. fov = _getProjectionParamet.fov,
  1643. aspect = _getProjectionParamet.aspect,
  1644. near = _getProjectionParamet.near,
  1645. far = _getProjectionParamet.far;
  1646.  
  1647. var projectionMatrix = perspective([], fov, aspect, near, far);
  1648. return projectionMatrix;
  1649. }
  1650. function worldToPixels(xyz, pixelProjectionMatrix) {
  1651. var _xyz2 = _slicedToArray(xyz, 3),
  1652. x = _xyz2[0],
  1653. y = _xyz2[1],
  1654. _xyz2$ = _xyz2[2],
  1655. z = _xyz2$ === void 0 ? 0 : _xyz2$;
  1656.  
  1657. assert(Number.isFinite(x) && Number.isFinite(y) && Number.isFinite(z));
  1658. return transformVector(pixelProjectionMatrix, [x, y, z, 1]);
  1659. }
  1660. function pixelsToWorld(xyz, pixelUnprojectionMatrix) {
  1661. var targetZ = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  1662.  
  1663. var _xyz3 = _slicedToArray(xyz, 3),
  1664. x = _xyz3[0],
  1665. y = _xyz3[1],
  1666. z = _xyz3[2];
  1667.  
  1668. assert(Number.isFinite(x) && Number.isFinite(y), 'invalid pixel coordinate');
  1669.  
  1670. if (Number.isFinite(z)) {
  1671. var coord = transformVector(pixelUnprojectionMatrix, [x, y, z, 1]);
  1672. return coord;
  1673. }
  1674.  
  1675. var coord0 = transformVector(pixelUnprojectionMatrix, [x, y, 0, 1]);
  1676. var coord1 = transformVector(pixelUnprojectionMatrix, [x, y, 1, 1]);
  1677. var z0 = coord0[2];
  1678. var z1 = coord1[2];
  1679. var t = z0 === z1 ? 0 : ((targetZ || 0) - z0) / (z1 - z0);
  1680. return lerp([], coord0, coord1, t);
  1681. }
  1682.  
  1683. var IDENTITY = createMat4();
  1684.  
  1685. var Viewport = function () {
  1686. function Viewport() {
  1687. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  1688. width = _ref.width,
  1689. height = _ref.height,
  1690. _ref$viewMatrix = _ref.viewMatrix,
  1691. viewMatrix = _ref$viewMatrix === void 0 ? IDENTITY : _ref$viewMatrix,
  1692. _ref$projectionMatrix = _ref.projectionMatrix,
  1693. projectionMatrix = _ref$projectionMatrix === void 0 ? IDENTITY : _ref$projectionMatrix;
  1694.  
  1695. _classCallCheck(this, Viewport);
  1696.  
  1697. this.width = width || 1;
  1698. this.height = height || 1;
  1699. this.scale = 1;
  1700. this.pixelsPerMeter = 1;
  1701. this.viewMatrix = viewMatrix;
  1702. this.projectionMatrix = projectionMatrix;
  1703. var vpm = createMat4();
  1704. multiply(vpm, vpm, this.projectionMatrix);
  1705. multiply(vpm, vpm, this.viewMatrix);
  1706. this.viewProjectionMatrix = vpm;
  1707. var m = createMat4();
  1708. scale(m, m, [this.width / 2, -this.height / 2, 1]);
  1709. translate(m, m, [1, -1, 0]);
  1710. multiply(m, m, this.viewProjectionMatrix);
  1711. var mInverse = invert(createMat4(), m);
  1712.  
  1713. if (!mInverse) {
  1714. throw new Error('Pixel project matrix not invertible');
  1715. }
  1716.  
  1717. this.pixelProjectionMatrix = m;
  1718. this.pixelUnprojectionMatrix = mInverse;
  1719. this.equals = this.equals.bind(this);
  1720. this.project = this.project.bind(this);
  1721. this.unproject = this.unproject.bind(this);
  1722. this.projectPosition = this.projectPosition.bind(this);
  1723. this.unprojectPosition = this.unprojectPosition.bind(this);
  1724. this.projectFlat = this.projectFlat.bind(this);
  1725. this.unprojectFlat = this.unprojectFlat.bind(this);
  1726. }
  1727.  
  1728. _createClass(Viewport, [{
  1729. key: "equals",
  1730. value: function equals$1(viewport) {
  1731. if (!(viewport instanceof Viewport)) {
  1732. return false;
  1733. }
  1734.  
  1735. return viewport.width === this.width && viewport.height === this.height && equals(viewport.projectionMatrix, this.projectionMatrix) && equals(viewport.viewMatrix, this.viewMatrix);
  1736. }
  1737. }, {
  1738. key: "project",
  1739. value: function project(xyz) {
  1740. var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
  1741. _ref2$topLeft = _ref2.topLeft,
  1742. topLeft = _ref2$topLeft === void 0 ? true : _ref2$topLeft;
  1743.  
  1744. var worldPosition = this.projectPosition(xyz);
  1745. var coord = worldToPixels(worldPosition, this.pixelProjectionMatrix);
  1746.  
  1747. var _coord = _slicedToArray(coord, 2),
  1748. x = _coord[0],
  1749. y = _coord[1];
  1750.  
  1751. var y2 = topLeft ? y : this.height - y;
  1752. return xyz.length === 2 ? [x, y2] : [x, y2, coord[2]];
  1753. }
  1754. }, {
  1755. key: "unproject",
  1756. value: function unproject(xyz) {
  1757. var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
  1758. _ref3$topLeft = _ref3.topLeft,
  1759. topLeft = _ref3$topLeft === void 0 ? true : _ref3$topLeft,
  1760. targetZ = _ref3.targetZ;
  1761.  
  1762. var _xyz = _slicedToArray(xyz, 3),
  1763. x = _xyz[0],
  1764. y = _xyz[1],
  1765. z = _xyz[2];
  1766.  
  1767. var y2 = topLeft ? y : this.height - y;
  1768. var targetZWorld = targetZ && targetZ * this.pixelsPerMeter;
  1769. var coord = pixelsToWorld([x, y2, z], this.pixelUnprojectionMatrix, targetZWorld);
  1770.  
  1771. var _this$unprojectPositi = this.unprojectPosition(coord),
  1772. _this$unprojectPositi2 = _slicedToArray(_this$unprojectPositi, 3),
  1773. X = _this$unprojectPositi2[0],
  1774. Y = _this$unprojectPositi2[1],
  1775. Z = _this$unprojectPositi2[2];
  1776.  
  1777. if (Number.isFinite(z)) {
  1778. return [X, Y, Z];
  1779. }
  1780.  
  1781. return Number.isFinite(targetZ) ? [X, Y, targetZ] : [X, Y];
  1782. }
  1783. }, {
  1784. key: "projectPosition",
  1785. value: function projectPosition(xyz) {
  1786. var _this$projectFlat = this.projectFlat(xyz),
  1787. _this$projectFlat2 = _slicedToArray(_this$projectFlat, 2),
  1788. X = _this$projectFlat2[0],
  1789. Y = _this$projectFlat2[1];
  1790.  
  1791. var Z = (xyz[2] || 0) * this.pixelsPerMeter;
  1792. return [X, Y, Z];
  1793. }
  1794. }, {
  1795. key: "unprojectPosition",
  1796. value: function unprojectPosition(xyz) {
  1797. var _this$unprojectFlat = this.unprojectFlat(xyz),
  1798. _this$unprojectFlat2 = _slicedToArray(_this$unprojectFlat, 2),
  1799. X = _this$unprojectFlat2[0],
  1800. Y = _this$unprojectFlat2[1];
  1801.  
  1802. var Z = (xyz[2] || 0) / this.pixelsPerMeter;
  1803. return [X, Y, Z];
  1804. }
  1805. }, {
  1806. key: "projectFlat",
  1807. value: function projectFlat(xyz) {
  1808. arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.scale;
  1809. return xyz;
  1810. }
  1811. }, {
  1812. key: "unprojectFlat",
  1813. value: function unprojectFlat(xyz) {
  1814. arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.scale;
  1815. return xyz;
  1816. }
  1817. }]);
  1818.  
  1819. return Viewport;
  1820. }();
  1821.  
  1822. function fitBounds(_ref) {
  1823. var width = _ref.width,
  1824. height = _ref.height,
  1825. bounds = _ref.bounds,
  1826. _ref$minExtent = _ref.minExtent,
  1827. minExtent = _ref$minExtent === void 0 ? 0 : _ref$minExtent,
  1828. _ref$maxZoom = _ref.maxZoom,
  1829. maxZoom = _ref$maxZoom === void 0 ? 24 : _ref$maxZoom,
  1830. _ref$padding = _ref.padding,
  1831. padding = _ref$padding === void 0 ? 0 : _ref$padding,
  1832. _ref$offset = _ref.offset,
  1833. offset = _ref$offset === void 0 ? [0, 0] : _ref$offset;
  1834.  
  1835. var _bounds = _slicedToArray(bounds, 2),
  1836. _bounds$ = _slicedToArray(_bounds[0], 2),
  1837. west = _bounds$[0],
  1838. south = _bounds$[1],
  1839. _bounds$2 = _slicedToArray(_bounds[1], 2),
  1840. east = _bounds$2[0],
  1841. north = _bounds$2[1];
  1842.  
  1843. if (Number.isFinite(padding)) {
  1844. var p = padding;
  1845. padding = {
  1846. top: p,
  1847. bottom: p,
  1848. left: p,
  1849. right: p
  1850. };
  1851. } else {
  1852. assert(Number.isFinite(padding.top) && Number.isFinite(padding.bottom) && Number.isFinite(padding.left) && Number.isFinite(padding.right));
  1853. }
  1854.  
  1855. var viewport = new WebMercatorViewport({
  1856. width: width,
  1857. height: height,
  1858. longitude: 0,
  1859. latitude: 0,
  1860. zoom: 0
  1861. });
  1862. var nw = viewport.project([west, north]);
  1863. var se = viewport.project([east, south]);
  1864. var size = [Math.max(Math.abs(se[0] - nw[0]), minExtent), Math.max(Math.abs(se[1] - nw[1]), minExtent)];
  1865. var targetSize = [width - padding.left - padding.right - Math.abs(offset[0]) * 2, height - padding.top - padding.bottom - Math.abs(offset[1]) * 2];
  1866. assert(targetSize[0] > 0 && targetSize[1] > 0);
  1867. var scaleX = targetSize[0] / size[0];
  1868. var scaleY = targetSize[1] / size[1];
  1869. var offsetX = (padding.right - padding.left) / 2 / scaleX;
  1870. var offsetY = (padding.bottom - padding.top) / 2 / scaleY;
  1871. var center = [(se[0] + nw[0]) / 2 + offsetX, (se[1] + nw[1]) / 2 + offsetY];
  1872. var centerLngLat = viewport.unproject(center);
  1873. var zoom = viewport.zoom + Math.log2(Math.abs(Math.min(scaleX, scaleY)));
  1874. return {
  1875. longitude: centerLngLat[0],
  1876. latitude: centerLngLat[1],
  1877. zoom: Math.min(zoom, maxZoom)
  1878. };
  1879. }
  1880.  
  1881. var WebMercatorViewport = function (_Viewport) {
  1882. _inherits(WebMercatorViewport, _Viewport);
  1883.  
  1884. function WebMercatorViewport() {
  1885. var _this;
  1886.  
  1887. var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
  1888. width = _ref.width,
  1889. height = _ref.height,
  1890. _ref$latitude = _ref.latitude,
  1891. latitude = _ref$latitude === void 0 ? 0 : _ref$latitude,
  1892. _ref$longitude = _ref.longitude,
  1893. longitude = _ref$longitude === void 0 ? 0 : _ref$longitude,
  1894. _ref$zoom = _ref.zoom,
  1895. zoom = _ref$zoom === void 0 ? 0 : _ref$zoom,
  1896. _ref$pitch = _ref.pitch,
  1897. pitch = _ref$pitch === void 0 ? 0 : _ref$pitch,
  1898. _ref$bearing = _ref.bearing,
  1899. bearing = _ref$bearing === void 0 ? 0 : _ref$bearing,
  1900. _ref$altitude = _ref.altitude,
  1901. altitude = _ref$altitude === void 0 ? 1.5 : _ref$altitude,
  1902. nearZMultiplier = _ref.nearZMultiplier,
  1903. farZMultiplier = _ref.farZMultiplier;
  1904.  
  1905. _classCallCheck(this, WebMercatorViewport);
  1906.  
  1907. width = width || 1;
  1908. height = height || 1;
  1909. var scale = zoomToScale$1(zoom);
  1910. altitude = Math.max(0.75, altitude);
  1911. var center = lngLatToWorld([longitude, latitude], scale);
  1912. center[2] = 0;
  1913. var projectionMatrix = getProjectionMatrix({
  1914. width: width,
  1915. height: height,
  1916. pitch: pitch,
  1917. bearing: bearing,
  1918. altitude: altitude,
  1919. nearZMultiplier: nearZMultiplier || 1 / height,
  1920. farZMultiplier: farZMultiplier || 1.01
  1921. });
  1922. var viewMatrix = getViewMatrix({
  1923. height: height,
  1924. center: center,
  1925. pitch: pitch,
  1926. bearing: bearing,
  1927. altitude: altitude,
  1928. flipY: true
  1929. });
  1930. _this = _possibleConstructorReturn(this, _getPrototypeOf(WebMercatorViewport).call(this, {
  1931. width: width,
  1932. height: height,
  1933. viewMatrix: viewMatrix,
  1934. projectionMatrix: projectionMatrix
  1935. }));
  1936. _this.latitude = latitude;
  1937. _this.longitude = longitude;
  1938. _this.zoom = zoom;
  1939. _this.pitch = pitch;
  1940. _this.bearing = bearing;
  1941. _this.altitude = altitude;
  1942. _this.scale = scale;
  1943. _this.center = center;
  1944. _this.pixelsPerMeter = getDistanceScales$1(_assertThisInitialized(_assertThisInitialized(_this))).pixelsPerMeter[2];
  1945. Object.freeze(_assertThisInitialized(_assertThisInitialized(_this)));
  1946. return _this;
  1947. }
  1948.  
  1949. _createClass(WebMercatorViewport, [{
  1950. key: "projectFlat",
  1951. value: function projectFlat(lngLat) {
  1952. var scale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.scale;
  1953. return lngLatToWorld(lngLat, scale);
  1954. }
  1955. }, {
  1956. key: "unprojectFlat",
  1957. value: function unprojectFlat(xy) {
  1958. var scale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.scale;
  1959. return worldToLngLat(xy, scale);
  1960. }
  1961. }, {
  1962. key: "getMapCenterByLngLatPosition",
  1963. value: function getMapCenterByLngLatPosition(_ref2) {
  1964. var lngLat = _ref2.lngLat,
  1965. pos = _ref2.pos;
  1966. var fromLocation = pixelsToWorld(pos, this.pixelUnprojectionMatrix);
  1967. var toLocation = lngLatToWorld(lngLat, this.scale);
  1968. var translate = add([], toLocation, negate$1([], fromLocation));
  1969. var newCenter = add([], this.center, translate);
  1970. return worldToLngLat(newCenter, this.scale);
  1971. }
  1972. }, {
  1973. key: "getLocationAtPoint",
  1974. value: function getLocationAtPoint(_ref3) {
  1975. var lngLat = _ref3.lngLat,
  1976. pos = _ref3.pos;
  1977. return this.getMapCenterByLngLatPosition({
  1978. lngLat: lngLat,
  1979. pos: pos
  1980. });
  1981. }
  1982. }, {
  1983. key: "fitBounds",
  1984. value: function fitBounds$1(bounds) {
  1985. var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  1986. var width = this.width,
  1987. height = this.height;
  1988.  
  1989. var _fitBounds2 = fitBounds(Object.assign({
  1990. width: width,
  1991. height: height,
  1992. bounds: bounds
  1993. }, options)),
  1994. longitude = _fitBounds2.longitude,
  1995. latitude = _fitBounds2.latitude,
  1996. zoom = _fitBounds2.zoom;
  1997.  
  1998. return new WebMercatorViewport({
  1999. width: width,
  2000. height: height,
  2001. longitude: longitude,
  2002. latitude: latitude,
  2003. zoom: zoom
  2004. });
  2005. }
  2006. }]);
  2007.  
  2008. return WebMercatorViewport;
  2009. }(Viewport);
  2010.  
  2011. /**
  2012. * borrow from
  2013. * https://github.com/uber-common/viewport-mercator-project/blob/master/src/web-mercator-utils.js
  2014. */
  2015.  
  2016. const PI = Math.PI;
  2017. const DEGREES_TO_RADIANS = PI / 180;
  2018. // const RADIANS_TO_DEGREES = 180 / PI;
  2019. const TILE_SIZE = 512;
  2020. // Average circumference (40075 km equatorial, 40007 km meridional)
  2021. const EARTH_CIRCUMFERENCE = 40.03e6;
  2022.  
  2023. // Mapbox default altitude
  2024. // const DEFAULT_ALTITUDE = 1.5;
  2025.  
  2026. function zoomToScale(zoom) {
  2027. return Math.pow(2, zoom);
  2028. }
  2029.  
  2030. /**
  2031. * Calculate distance scales in meters around current lat/lon, both for
  2032. * degrees and pixels.
  2033. * In mercator projection mode, the distance scales vary significantly
  2034. * with latitude.
  2035. */
  2036. function getDistanceScales(options) {
  2037. let {
  2038. latitude = 0, zoom = 1, scale, highPrecision = false
  2039. } = options;
  2040.  
  2041. // Calculate scale from zoom if not provided
  2042. scale = scale !== undefined ? scale : zoomToScale(zoom);
  2043.  
  2044. const result = {};
  2045. const worldSize = TILE_SIZE * scale;
  2046. const latCosine = Math.cos(latitude * DEGREES_TO_RADIANS);
  2047.  
  2048. /**
  2049. * Number of pixels occupied by one degree longitude around current lat/lon:
  2050. pixelsPerDegreeX = d(lngLatToWorld([lng, lat])[0])/d(lng)
  2051. = scale * TILE_SIZE * DEGREES_TO_RADIANS / (2 * PI)
  2052. pixelsPerDegreeY = d(lngLatToWorld([lng, lat])[1])/d(lat)
  2053. = -scale * TILE_SIZE * DEGREES_TO_RADIANS / cos(lat * DEGREES_TO_RADIANS) / (2 * PI)
  2054. */
  2055. const pixelsPerDegreeX = worldSize / 360;
  2056. const pixelsPerDegreeY = pixelsPerDegreeX / latCosine;
  2057.  
  2058. /**
  2059. * Number of pixels occupied by one meter around current lat/lon:
  2060. */
  2061. const altPixelsPerMeter = worldSize / EARTH_CIRCUMFERENCE / latCosine;
  2062.  
  2063. /**
  2064. * LngLat: longitude -> east and latitude -> north (bottom left)
  2065. * UTM meter offset: x -> east and y -> north (bottom left)
  2066. * World space: x -> east and y -> south (top left)
  2067. *
  2068. * Y needs to be flipped when converting delta degree/meter to delta pixels
  2069. */
  2070. result.pixelsPerMeter = [altPixelsPerMeter, -altPixelsPerMeter, altPixelsPerMeter];
  2071. result.metersPerPixel = [1 / altPixelsPerMeter, -1 / altPixelsPerMeter, 1 / altPixelsPerMeter];
  2072.  
  2073. result.pixelsPerDegree = [pixelsPerDegreeX, -pixelsPerDegreeY, altPixelsPerMeter];
  2074. result.degreesPerPixel = [1 / pixelsPerDegreeX, -1 / pixelsPerDegreeY, 1 / altPixelsPerMeter];
  2075.  
  2076. /**
  2077. * Taylor series 2nd order for 1/latCosine
  2078. f'(a) * (x - a)
  2079. = d(1/cos(lat * DEGREES_TO_RADIANS))/d(lat) * dLat
  2080. = DEGREES_TO_RADIANS * tan(lat * DEGREES_TO_RADIANS) / cos(lat * DEGREES_TO_RADIANS) * dLat
  2081. */
  2082. if (highPrecision) {
  2083. const latCosine2 = DEGREES_TO_RADIANS * Math.tan(latitude * DEGREES_TO_RADIANS) / latCosine;
  2084. const pixelsPerDegreeY2 = pixelsPerDegreeX * latCosine2 / 2;
  2085.  
  2086. const altPixelsPerDegree2 = worldSize / EARTH_CIRCUMFERENCE * latCosine2;
  2087. const altPixelsPerMeter2 = altPixelsPerDegree2 / pixelsPerDegreeY * altPixelsPerMeter;
  2088.  
  2089. result.pixelsPerDegree2 = [0, -pixelsPerDegreeY2, altPixelsPerDegree2];
  2090. result.pixelsPerMeter2 = [altPixelsPerMeter2, 0, altPixelsPerMeter2];
  2091. }
  2092.  
  2093. // Main results, used for converting meters to latlng deltas and scaling offsets
  2094. return result;
  2095. }
  2096.  
  2097. window.customTileLayer = class {
  2098.  
  2099. constructor(layerId, url, options) {
  2100. this.id = layerId;
  2101. this.type = "custom";
  2102. this.renderingMode = '2d';
  2103. this.url = url;
  2104.  
  2105. this.options = {
  2106.  
  2107. //服务器编号
  2108. subdomains: null,
  2109.  
  2110. minZoom: 3,
  2111. maxZoom: 18,
  2112. tileType: 'xyz' //bd09,xyz
  2113. };
  2114. setOptions(this, options); //合并属性
  2115.  
  2116. //着色器程序
  2117. this.program;
  2118.  
  2119. //存放当前显示的瓦片
  2120. this.showTiles = [];
  2121.  
  2122. //存放所有加载过的瓦片
  2123. this.tileCache = {};
  2124.  
  2125. //存放瓦片号对应的经纬度
  2126. this.gridCache = {};
  2127.  
  2128. //记录渲染时的变换矩阵。
  2129. //如果瓦片因为网速慢,在渲染完成后才加载过来,可以使用这个矩阵主动更新渲染
  2130. this.matrix;
  2131.  
  2132. this.map;
  2133.  
  2134. //记录当前图层是否在显示
  2135. this.isLayerShow;
  2136.  
  2137. this.transformBaidu = new TransformClassBaidu();
  2138. }
  2139.  
  2140. onAdd(map, gl) {
  2141. this.map = map;
  2142.  
  2143. // 着色器程序参考:https://github.com/xiaoiver/custom-mapbox-layer/blob/master/src/shaders/project.glsl
  2144. var vertexSource = "" + "uniform mat4 u_matrix;" + "attribute vec2 a_pos;" + "attribute vec2 a_TextCoord;" + "varying vec2 v_TextCoord;" + "const float TILE_SIZE = 512.0;" + "const float PI = 3.1415926536;" + "const float WORLD_SCALE = TILE_SIZE / (PI * 2.0);" + "uniform float u_project_scale;" + "uniform bool u_is_offset;" + "uniform vec3 u_pixels_per_degree;" + "uniform vec3 u_pixels_per_degree2;" + "uniform vec3 u_pixels_per_meter;" + "uniform vec2 u_viewport_center;" + "uniform vec4 u_viewport_center_projection;" + "uniform vec2 u_viewport_size;" + "float project_scale(float meters) {" + " return meters * u_pixels_per_meter.z;" + "}" + "vec3 project_scale(vec3 position) {" + " return position * u_pixels_per_meter;" + "}" + "vec2 project_mercator(vec2 lnglat) {" + " float x = lnglat.x;" + " return vec2(" + " radians(x) + PI, PI - log(tan(PI * 0.25 + radians(lnglat.y) * 0.5))" + " );" + "}" + "vec4 project_offset(vec4 offset) {" + " float dy = offset.y;" + " dy = clamp(dy, -1., 1.);" + " vec3 pixels_per_unit = u_pixels_per_degree + u_pixels_per_degree2 * dy;" + " return vec4(offset.xyz * pixels_per_unit, offset.w);" + "}" + "vec4 project_position(vec4 position) {" + " if (u_is_offset) {" + " float X = position.x - u_viewport_center.x;" + " float Y = position.y - u_viewport_center.y;" + " return project_offset(vec4(X, Y, position.z, position.w));" + " }" + " else {" + " return vec4(" + " project_mercator(position.xy) * WORLD_SCALE * u_project_scale, project_scale(position.z), position.w" + " );" + " }" + "}" + "vec4 project_to_clipping_space(vec3 position) {" + " vec4 project_pos = project_position(vec4(position, 1.0));" + " return u_matrix * project_pos + u_viewport_center_projection;" + "}" + "void main() {" + " vec4 project_pos = project_position(vec4(a_pos, 0.0, 1.0));" + " gl_Position = u_matrix * project_pos + u_viewport_center_projection;" + " v_TextCoord = a_TextCoord;" + "}";
  2145.  
  2146. var fragmentSource = "" + "precision mediump float;" + "uniform sampler2D u_Sampler; " + "varying vec2 v_TextCoord; " + "void main() {" + " gl_FragColor = texture2D(u_Sampler, v_TextCoord);" +
  2147. // " gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);" +
  2148. "}";
  2149.  
  2150. //初始化顶点着色器
  2151. var vertexShader = gl.createShader(gl.VERTEX_SHADER);
  2152. gl.shaderSource(vertexShader, vertexSource);
  2153. gl.compileShader(vertexShader);
  2154. //初始化片元着色器
  2155. var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  2156. gl.shaderSource(fragmentShader, fragmentSource);
  2157. gl.compileShader(fragmentShader);
  2158. //初始化着色器程序
  2159. this.program = gl.createProgram();
  2160. gl.attachShader(this.program, vertexShader);
  2161. gl.attachShader(this.program, fragmentShader);
  2162. gl.linkProgram(this.program);
  2163.  
  2164. //获取顶点位置变量
  2165. this.a_Pos = gl.getAttribLocation(this.program, "a_pos");
  2166. this.a_TextCoord = gl.getAttribLocation(this.program, 'a_TextCoord');
  2167.  
  2168. this.isLayerShow = true;
  2169. map.on('move', () => {
  2170. if (this.isLayerShow) this.update(gl, map);
  2171. });
  2172. this.update(gl, map);
  2173. }
  2174.  
  2175. update(gl, map) {
  2176. var center = map.getCenter();
  2177. var zoom;
  2178. var bounds = map.getBounds();
  2179.  
  2180. var minTile, maxTile;
  2181. if (this.options.tileType === 'xyz') {
  2182. zoom = parseInt(map.getZoom() + 1.4); //解决瓦片上文字偏大的问题
  2183. //把当前显示范围做偏移,后面加载瓦片时会再偏移回来
  2184. //如果不这样做的话,大比例尺时,瓦片偏移后,屏幕边缘会有空白区域
  2185. var northWest = gcj02_To_gps84(bounds.getNorthWest());
  2186. var southEast = gcj02_To_gps84(bounds.getSouthEast());
  2187. //算出当前范围的瓦片编号
  2188. minTile = lonLatToTileNumbers(northWest.lng, northWest.lat, zoom);
  2189. maxTile = lonLatToTileNumbers(southEast.lng, southEast.lat, zoom);
  2190. } else if (this.options.tileType === 'bd09') {
  2191. zoom = parseInt(map.getZoom() + 1.8); //解决瓦片上文字偏大的问题
  2192. var southWest = gps84_To_bd09(bounds.getSouthWest());
  2193. var northEast = gps84_To_bd09(bounds.getNorthEast());
  2194. minTile = this.transformBaidu.lnglatToTile(southWest.lng, southWest.lat, zoom);
  2195. maxTile = this.transformBaidu.lnglatToTile(northEast.lng, northEast.lat, zoom);
  2196. }
  2197. var currentTiles = [];
  2198. for (var x = minTile[0]; x <= maxTile[0]; x++) {
  2199. for (var y = minTile[1]; y <= maxTile[1]; y++) {
  2200. var xyz = {
  2201. x: x,
  2202. y: y,
  2203. z: zoom
  2204. };
  2205. currentTiles.push(xyz);
  2206.  
  2207. //把瓦片号对应的经纬度缓存起来,
  2208. //存起来是因为贴纹理时需要瓦片4个角的经纬度,这样可以避免重复计算
  2209. //行和列向外多计算一个瓦片数,这样保证瓦片4个角都有经纬度可以取到
  2210. this.addGridCache(xyz, 0, 0);
  2211. if (x === maxTile[0]) this.addGridCache(xyz, 1, 0);
  2212. if (y === maxTile[1]) this.addGridCache(xyz, 0, 1);
  2213. if (x === maxTile[0] && y === maxTile[1]) this.addGridCache(xyz, 1, 1);
  2214. }
  2215. }
  2216.  
  2217. //瓦片设置为从中间向周边的排序
  2218. if (this.options.tileType === 'xyz') var centerTile = lonLatToTileNumbers(center.lng, center.lat, zoom); //计算中心点所在的瓦片号
  2219. else if (this.options.tileType === 'bd09') centerTile = this.transformBaidu.lnglatToTile(center.lng, center.lat, zoom);
  2220. currentTiles.sort((a, b) => {
  2221. return this.tileDistance(a, centerTile) - this.tileDistance(b, centerTile);
  2222. });
  2223.  
  2224. //加载瓦片
  2225. this.showTiles = [];
  2226. for (var xyz of currentTiles) {
  2227. //走缓存或新加载
  2228. if (this.tileCache[this.createTileKey(xyz)]) {
  2229. this.showTiles.push(this.tileCache[this.createTileKey(xyz)]);
  2230. } else {
  2231. var tile = this.createTile(gl, xyz);
  2232. this.showTiles.push(tile);
  2233. this.tileCache[this.createTileKey(xyz)] = tile;
  2234. }
  2235. }
  2236. }
  2237.  
  2238. //缓存瓦片号对应的经纬度
  2239. addGridCache(xyz, xPlus, yPlus) {
  2240. var key = this.createTileKey(xyz.x + xPlus, xyz.y + yPlus, xyz.z);
  2241. if (!this.gridCache[key]) {
  2242. if (this.options.tileType === 'xyz') this.gridCache[key] = gps84_To_gcj02(tileNumbersToLonLat(xyz.x + xPlus, xyz.y + yPlus, xyz.z));else if (this.options.tileType === 'bd09') this.gridCache[key] = bd09_To_gps84(this.transformBaidu.pixelToLnglat(0, 0, xyz.x + xPlus, xyz.y + yPlus, xyz.z));
  2243. }
  2244. }
  2245.  
  2246. //计算两个瓦片编号的距离
  2247. tileDistance(tile1, tile2) {
  2248. //计算直角三角形斜边长度,c(斜边)=√(a²+b²)。(a,b为两直角边)
  2249. return Math.sqrt(Math.pow(tile1.x - tile2[0], 2) + Math.pow(tile1.y - tile2[1], 2));
  2250. }
  2251.  
  2252. //创建瓦片id
  2253. createTileKey(xyz, y, z) {
  2254. if (xyz instanceof Object) {
  2255. return xyz.z + '/' + xyz.x + '/' + xyz.y;
  2256. } else {
  2257. var x = xyz;
  2258. return z + '/' + x + '/' + y;
  2259. }
  2260. }
  2261.  
  2262. //创建瓦片
  2263. createTile(gl, xyz) {
  2264. //替换请求地址中的变量
  2265. var _url = template(this.url, {
  2266. s: this.options.subdomains[Math.abs(xyz.x + xyz.y) % this.options.subdomains.length],
  2267. x: xyz.x,
  2268. y: xyz.y,
  2269. z: xyz.z
  2270. });
  2271.  
  2272. var tile = {
  2273. xyz: xyz
  2274. };
  2275.  
  2276. //瓦片编号转经纬度,并进行偏移
  2277. var leftTop, rightTop, leftBottom, rightBottom;
  2278. if (this.options.tileType === 'xyz') {
  2279. leftTop = this.gridCache[this.createTileKey(xyz)];
  2280. rightTop = this.gridCache[this.createTileKey(xyz.x + 1, xyz.y, xyz.z)];
  2281. leftBottom = this.gridCache[this.createTileKey(xyz.x, xyz.y + 1, xyz.z)];
  2282. rightBottom = this.gridCache[this.createTileKey(xyz.x + 1, xyz.y + 1, xyz.z)];
  2283. } else if (this.options.tileType === 'bd09') {
  2284. leftTop = this.gridCache[this.createTileKey(xyz.x, xyz.y + 1, xyz.z)];
  2285. rightTop = this.gridCache[this.createTileKey(xyz.x + 1, xyz.y + 1, xyz.z)];
  2286. leftBottom = this.gridCache[this.createTileKey(xyz)];
  2287. rightBottom = this.gridCache[this.createTileKey(xyz.x + 1, xyz.y, xyz.z)];
  2288. }
  2289.  
  2290. //顶点坐标+纹理坐标
  2291. var attrData = new Float32Array([leftTop.lng, leftTop.lat, 0.0, 1.0, leftBottom.lng, leftBottom.lat, 0.0, 0.0, rightTop.lng, rightTop.lat, 1.0, 1.0, rightBottom.lng, rightBottom.lat, 1.0, 0.0]);
  2292. // var attrData = new Float32Array([
  2293. // 116.38967958133532, 39.90811009556515, 0.0, 1.0,
  2294. // 116.38967958133532, 39.90294980726742, 0.0, 0.0,
  2295. // 116.39486013141436, 39.90811009556515, 1.0, 1.0,
  2296. // 116.39486013141436, 39.90294980726742, 1.0, 0.0
  2297. // ])
  2298. var FSIZE = attrData.BYTES_PER_ELEMENT;
  2299. //创建缓冲区并传入数据
  2300. var buffer = gl.createBuffer();
  2301. gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  2302. gl.bufferData(gl.ARRAY_BUFFER, attrData, gl.STATIC_DRAW);
  2303. tile.buffer = buffer;
  2304. //从缓冲区中获取顶点数据的参数
  2305. tile.PosParam = {
  2306. size: 2,
  2307. stride: FSIZE * 4,
  2308. offset: 0
  2309. //从缓冲区中获取纹理数据的参数
  2310. };tile.TextCoordParam = {
  2311. size: 2,
  2312. stride: FSIZE * 4,
  2313. offset: FSIZE * 2
  2314.  
  2315. //加载瓦片
  2316. };var img = new Image();
  2317. img.onload = () => {
  2318. // 创建纹理对象
  2319. tile.texture = gl.createTexture();
  2320. //向target绑定纹理对象
  2321. gl.bindTexture(gl.TEXTURE_2D, tile.texture);
  2322. //对纹理进行Y轴反转
  2323. gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
  2324. //配置纹理图像
  2325. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
  2326.  
  2327. tile.isLoad = true;
  2328.  
  2329. this.map.triggerRepaint(); //主动让地图重绘
  2330. };
  2331. img.crossOrigin = true;
  2332. img.src = _url;
  2333.  
  2334. return tile;
  2335. }
  2336.  
  2337. //渲染
  2338. render(gl, matrix) {
  2339.  
  2340. if (this.map.getZoom() < this.options.minZoom || this.map.getZoom() > this.options.maxZoom) return;
  2341.  
  2342. //记录变换矩阵,用于瓦片加载后主动绘制
  2343. this.matrix = matrix;
  2344.  
  2345. //应用着色程序
  2346. //必须写到这里,不能写到onAdd中,不然gl中的着色程序可能不是上面写的,会导致下面的变量获取不到
  2347. gl.useProgram(this.program);
  2348.  
  2349. for (var tile of this.showTiles) {
  2350. if (!tile.isLoad) continue;
  2351.  
  2352. //向target绑定纹理对象
  2353. gl.bindTexture(gl.TEXTURE_2D, tile.texture);
  2354. //开启0号纹理单元
  2355. gl.activeTexture(gl.TEXTURE0);
  2356. //配置纹理参数
  2357. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  2358. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  2359. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT);
  2360. // 获取纹理的存储位置
  2361. var u_Sampler = gl.getUniformLocation(this.program, 'u_Sampler');
  2362. //将0号纹理传递给着色器
  2363. gl.uniform1i(u_Sampler, 0);
  2364.  
  2365. gl.bindBuffer(gl.ARRAY_BUFFER, tile.buffer);
  2366. //设置从缓冲区获取顶点数据的规则
  2367. gl.vertexAttribPointer(this.a_Pos, tile.PosParam.size, gl.FLOAT, false, tile.PosParam.stride, tile.PosParam.offset);
  2368. gl.vertexAttribPointer(this.a_TextCoord, tile.TextCoordParam.size, gl.FLOAT, false, tile.TextCoordParam.stride, tile.TextCoordParam.offset);
  2369. //激活顶点数据缓冲区
  2370. gl.enableVertexAttribArray(this.a_Pos);
  2371. gl.enableVertexAttribArray(this.a_TextCoord);
  2372.  
  2373. // 设置位置的顶点参数
  2374. this.setVertex(gl);
  2375.  
  2376. //开启阿尔法混合,实现注记半透明效果
  2377. gl.enable(gl.BLEND);
  2378. gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
  2379.  
  2380. //绘制图形
  2381. gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  2382. }
  2383. }
  2384.  
  2385. // 设置位置的顶点参数
  2386. //参考:https://github.com/xiaoiver/custom-mapbox-layer/blob/master/src/layers/PointCloudLayer2.ts
  2387. setVertex(gl) {
  2388. const currentZoomLevel = this.map.getZoom();
  2389. const bearing = this.map.getBearing();
  2390. const pitch = this.map.getPitch();
  2391. const center = this.map.getCenter();
  2392.  
  2393. const viewport = new WebMercatorViewport({
  2394. // width: gl.drawingBufferWidth*1.11,
  2395. // height: gl.drawingBufferHeight*1.11,
  2396. width: gl.drawingBufferWidth,
  2397. height: gl.drawingBufferHeight,
  2398.  
  2399. longitude: center.lng,
  2400. latitude: center.lat,
  2401. zoom: currentZoomLevel,
  2402. pitch,
  2403. bearing
  2404. });
  2405.  
  2406. // @ts-ignore
  2407. const { viewProjectionMatrix, projectionMatrix, viewMatrix, viewMatrixUncentered } = viewport;
  2408.  
  2409. let drawParams = {
  2410. // @ts-ignore
  2411. 'u_matrix': viewProjectionMatrix,
  2412. 'u_point_size': this.pointSize,
  2413. 'u_is_offset': false,
  2414. 'u_pixels_per_degree': [0, 0, 0],
  2415. 'u_pixels_per_degree2': [0, 0, 0],
  2416. 'u_viewport_center': [0, 0],
  2417. 'u_pixels_per_meter': [0, 0, 0],
  2418. 'u_project_scale': zoomToScale(currentZoomLevel),
  2419. 'u_viewport_center_projection': [0, 0, 0, 0]
  2420. };
  2421.  
  2422. if (currentZoomLevel > 12) {
  2423. const { pixelsPerDegree, pixelsPerDegree2 } = getDistanceScales({
  2424. longitude: center.lng,
  2425. latitude: center.lat,
  2426. zoom: currentZoomLevel,
  2427. highPrecision: true
  2428. });
  2429.  
  2430. const positionPixels = viewport.projectFlat([Math.fround(center.lng), Math.fround(center.lat)], Math.pow(2, currentZoomLevel));
  2431.  
  2432. const projectionCenter = transformMat4([], [positionPixels[0], positionPixels[1], 0.0, 1.0], viewProjectionMatrix);
  2433.  
  2434. // Always apply uncentered projection matrix if available (shader adds center)
  2435. let viewMatrix2 = viewMatrixUncentered || viewMatrix;
  2436.  
  2437. // Zero out 4th coordinate ("after" model matrix) - avoids further translations
  2438. // viewMatrix = new Matrix4(viewMatrixUncentered || viewMatrix)
  2439. // .multiplyRight(VECTOR_TO_POINT_MATRIX);
  2440. let viewProjectionMatrix2 = multiply([], projectionMatrix, viewMatrix2);
  2441. const VECTOR_TO_POINT_MATRIX = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0];
  2442. viewProjectionMatrix2 = multiply([], viewProjectionMatrix2, VECTOR_TO_POINT_MATRIX);
  2443.  
  2444. drawParams['u_matrix'] = viewProjectionMatrix2;
  2445. drawParams['u_is_offset'] = true;
  2446. drawParams['u_viewport_center'] = [Math.fround(center.lng), Math.fround(center.lat)];
  2447. // @ts-ignore
  2448. drawParams['u_viewport_center_projection'] = projectionCenter;
  2449. drawParams['u_pixels_per_degree'] = pixelsPerDegree && pixelsPerDegree.map(p => Math.fround(p));
  2450. drawParams['u_pixels_per_degree2'] = pixelsPerDegree2 && pixelsPerDegree2.map(p => Math.fround(p));
  2451. }
  2452.  
  2453. gl.uniformMatrix4fv(gl.getUniformLocation(this.program, "u_matrix"), false, drawParams['u_matrix']);
  2454.  
  2455. gl.uniform1f(gl.getUniformLocation(this.program, "u_project_scale"), drawParams['u_project_scale']);
  2456. gl.uniform1i(gl.getUniformLocation(this.program, "u_is_offset"), drawParams['u_is_offset'] ? 1 : 0);
  2457. gl.uniform3fv(gl.getUniformLocation(this.program, "u_pixels_per_degree"), drawParams['u_pixels_per_degree']);
  2458. gl.uniform3fv(gl.getUniformLocation(this.program, "u_pixels_per_degree2"), drawParams['u_pixels_per_degree2']);
  2459. gl.uniform3fv(gl.getUniformLocation(this.program, "u_pixels_per_meter"), drawParams['u_pixels_per_meter']);
  2460. gl.uniform2fv(gl.getUniformLocation(this.program, "u_viewport_center"), drawParams['u_viewport_center']);
  2461. gl.uniform4fv(gl.getUniformLocation(this.program, "u_viewport_center_projection"), drawParams['u_viewport_center_projection']);
  2462. }
  2463.  
  2464. //当map移除当前图层时调用
  2465. onRemove(map, gl) {
  2466. this.isLayerShow = false;
  2467. }
  2468.  
  2469. }
  2470.  
  2471. function RasterTileLayer(layerId, layerType, options) {
  2472.  
  2473. var _options = options || {};
  2474.  
  2475. var providers = {
  2476. TianDiTu: {
  2477. Normal: {
  2478. Map: "http://t{s}.tianditu.com/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk={key}",
  2479. Annotion: "http://t{s}.tianditu.com/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk={key}",
  2480. minzoom: 0,
  2481. maxzoom: 18
  2482. },
  2483. Satellite: {
  2484. Map: "http://t{s}.tianditu.com/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk={key}",
  2485. Annotion: "http://t{s}.tianditu.com/DataServer?T=cia_w&X={x}&Y={y}&L={z}&tk={key}",
  2486. minzoom: 0,
  2487. maxzoom: 18
  2488. },
  2489. Terrain: {
  2490. Map: "http://t{s}.tianditu.com/DataServer?T=ter_w&X={x}&Y={y}&L={z}&tk={key}",
  2491. Annotion: "http://t{s}.tianditu.com/DataServer?T=cta_w&X={x}&Y={y}&L={z}&tk={key}",
  2492. minzoom: 0,
  2493. maxzoom: 14
  2494. },
  2495. Subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
  2496. key: ""
  2497. },
  2498. GaoDe: {
  2499. Normal: {
  2500. Map: 'http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
  2501. minzoom: 3,
  2502. maxzoom: 18
  2503. },
  2504. Normal_NoTag: {
  2505. Map: 'https://wprd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&scl=1&ltype=11&x={x}&y={y}&z={z}',
  2506. minzoom: 3,
  2507. maxzoom: 18
  2508. },
  2509. Satellite: {
  2510. Map: 'http://webst0{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
  2511. Annotion: 'http://webst0{s}.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}',
  2512. minzoom: 3,
  2513. maxzoom: 18
  2514. },
  2515. Subdomains: ["1", "2", "3", "4"]
  2516. },
  2517. Baidu: {
  2518. Normal: {
  2519. Map: '//online{s}.map.bdimg.com/onlinelabel/?qt=tile&x={x}&y={y}&z={z}&styles=pl&scaler=1&p=1'
  2520. },
  2521. Satellite: {
  2522. Map: '//shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46',
  2523. Annotion: '//online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=sl&v=020'
  2524. },
  2525. Subdomains: '0123456789',
  2526. tileType: 'bd09'
  2527. },
  2528. Geoq: {
  2529. Normal: {
  2530. Map: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineCommunity/MapServer/tile/{z}/{y}/{x}",
  2531. PurplishBlue: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
  2532. Gray: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetGray/MapServer/tile/{z}/{y}/{x}",
  2533. Warm: "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetWarm/MapServer/tile/{z}/{y}/{x}",
  2534. minzoom: 3,
  2535. maxzoom: 16
  2536. },
  2537. Subdomains: []
  2538. },
  2539. OSM: {
  2540. Normal: {
  2541. Map: "//{s}.tile.osm.org/{z}/{x}/{y}.png",
  2542. minzoom: 0,
  2543. maxzoom: 18
  2544. },
  2545. Subdomains: ['a', 'b', 'c']
  2546. }
  2547. };
  2548.  
  2549. var parts = layerType.split('.');
  2550.  
  2551. var providerName = parts[0];
  2552. var mapName = parts[1];
  2553. var mapType = parts[2];
  2554.  
  2555. var url = providers[providerName][mapName][mapType];
  2556. var subdomains = providers[providerName].Subdomains;
  2557. var minzoom = providers[providerName][mapName].minzoom;
  2558. var maxzoom = providers[providerName][mapName].maxzoom;
  2559. var tileType = providers[providerName].tileType;
  2560.  
  2561. var tilelayer;
  2562. if (providerName === 'TianDiTu' || providerName === 'OSM') {
  2563. //天地图使用大地2000坐标可以直接使用,不用偏移
  2564. var key = _options.key || providers[providerName].key;
  2565. var urls = [];
  2566. for (var sub of subdomains) {
  2567. urls.push(url.replace('{s}', sub).replace('{key}', key));
  2568. }
  2569. tilelayer = {
  2570. "id": layerId,
  2571. "type": "raster",
  2572. "source": {
  2573. "type": "raster",
  2574. 'tiles': urls,
  2575. "tileSize": 256,
  2576. "minzoom": minzoom,
  2577. "maxzoom": maxzoom
  2578. }
  2579. };
  2580. } else {
  2581. tilelayer = new customTileLayer(layerId, url, {
  2582. subdomains: subdomains,
  2583. minZoom: minzoom,
  2584. maxZoom: maxzoom,
  2585. tileType: tileType
  2586. });
  2587. }
  2588.  
  2589. return tilelayer;
  2590. }
  2591.  
  2592. return RasterTileLayer;
  2593.  
  2594. })));
  2595. //# sourceMappingURL=rasterTileLayer-src.js.map