index.js (3014B)
1 import L from 'leaflet'; 2 3 import {fetch} from '~/lib/xhr-promise'; 4 5 import {urlViaCorsProxy} from '../CORSProxy'; 6 7 function tile2quad(x, y, z) { 8 let quad = ''; 9 for (let i = z; i > 0; i--) { 10 let digit = 0; 11 const mask = 1 << (i - 1); 12 if ((x & mask) !== 0) { 13 digit += 1; 14 } 15 if ((y & mask) !== 0) { 16 digit += 2; 17 } 18 quad += digit; 19 } 20 return quad; 21 } 22 23 const BingBaseLayer = L.TileLayer.extend({ 24 getTileUrl: function (tilePoint) { 25 const data = { 26 quadkey: tile2quad(tilePoint.x, tilePoint.y, this._getZoomForUrl()), 27 }; 28 return L.Util.template(this._url, L.extend(data, this.options)); 29 }, 30 }); 31 32 const BingBaseLayerWithDynamicUrl = BingBaseLayer.extend({ 33 initialize: function (options) { 34 BingBaseLayer.prototype.initialize.call(this, null, options); 35 this.layerInfoRequested = false; 36 }, 37 38 onAdd: function (map) { 39 this.loadLayerInfo(); 40 L.TileLayer.prototype.onAdd.apply(this, [map]); 41 }, 42 43 _update: function () { 44 if (this._url === null || !this._map) { 45 return; 46 } 47 L.TileLayer.prototype._update.apply(this); 48 }, 49 50 getLayerUrl: async function () { 51 throw new Error('Not implemented'); 52 }, 53 54 loadLayerInfo: async function () { 55 if (this.layerInfoRequested) { 56 return; 57 } 58 this.layerInfoRequested = true; 59 this._url = await this.getLayerUrl(); 60 this._update(); 61 }, 62 }); 63 64 const BingSatLayer = BingBaseLayerWithDynamicUrl.extend({ 65 getLayerUrl: async function () { 66 const xhr = await fetch('https://www.bing.com/maps/style?styleid=aerial', { 67 responseType: 'json', 68 timeout: 5000, 69 }); 70 return xhr.response['sources']['bing-aerial']['tiles'][0].replace(/^raster/u, 'https'); 71 }, 72 }); 73 74 const BingOrdnanceSurveyLayer = BingBaseLayerWithDynamicUrl.extend({ 75 getSessionKey: async function () { 76 const xhr = await fetch(urlViaCorsProxy('https://www.bing.com/maps/'), {timeout: 5000}); 77 const match = xhr.responseText.match(/"sessionKey"\s*:\s*"([^"]+)"/u); 78 if (!match || !match[1]) { 79 throw new Error('Bing session key not found'); 80 } 81 return match[1]; 82 }, 83 84 getLayerUrlWithoutKey: async function () { 85 const xhr = await fetch('https://www.bing.com/maps/style?styleid=ordnancesurvey', { 86 responseType: 'json', 87 headers: [['accept-language', 'en-GB']], 88 timeout: 5000, 89 }); 90 return xhr.response['sources']['osMaps1']['tiles'][0].replace(/^raster/u, 'https'); 91 }, 92 93 getLayerUrl: async function () { 94 const [url, key] = await Promise.all([this.getLayerUrlWithoutKey(), this.getSessionKey()]); 95 return url.replace('{credentials}', key); 96 }, 97 }); 98 99 // eslint-disable-next-line import/no-unused-modules 100 export {BingSatLayer, BingOrdnanceSurveyLayer, BingBaseLayerWithDynamicUrl};
