index.js (4755B)
1 import L from 'leaflet'; 2 3 function tile2quad(x, y, z) { 4 var quad = ''; 5 for (var i = z; i > 0; i--) { 6 var digit = 0; 7 var mask = 1 << (i - 1); 8 if ((x & mask) !== 0) { 9 digit += 1; 10 } 11 if ((y & mask) !== 0) { 12 digit += 2; 13 } 14 quad += digit; 15 } 16 return quad; 17 } 18 19 const BingLayer = L.TileLayer.extend({ 20 options: { 21 subdomains: [0, 1, 2, 3], 22 type: 'Aerial', 23 attribution: 'Bing', 24 culture: '' 25 }, 26 27 initialize: function(key, options) { 28 L.Util.setOptions(this, options); 29 30 this._key = key; 31 this._url = null; 32 this._providers = []; 33 this.metaRequested = false; 34 }, 35 36 getTileUrl: function(tilePoint) { 37 var zoom = this._getZoomForUrl(); 38 var subdomains = this.options.subdomains, 39 s = this.options.subdomains[Math.abs((tilePoint.x + tilePoint.y) % subdomains.length)]; 40 return this._url.replace('{subdomain}', s) 41 .replace('{quadkey}', tile2quad(tilePoint.x, tilePoint.y, zoom)) 42 .replace('{culture}', this.options.culture); 43 }, 44 45 loadMetadata: function() { 46 if (this.metaRequested) { 47 return; 48 } 49 this.metaRequested = true; 50 var that = this; 51 var cbid = '_bing_metadata_' + L.Util.stamp(this); 52 window[cbid] = function(meta) { 53 window[cbid] = undefined; 54 var e = document.getElementById(cbid); 55 e.parentNode.removeChild(e); 56 if (meta.errorDetails) { 57 throw new Error(meta.errorDetails); 58 } 59 that.initMetadata(meta); 60 }; 61 var urlScheme = 'https'; 62 var url = urlScheme + '://dev.virtualearth.net/REST/v1/Imagery/Metadata/' + 63 this.options.type + '?include=ImageryProviders&jsonp=' + cbid + 64 '&key=' + this._key + '&UriScheme=' + urlScheme; 65 var script = document.createElement('script'); 66 script.type = 'text/javascript'; 67 script.src = url; 68 script.id = cbid; 69 document.getElementsByTagName('head')[0].appendChild(script); 70 }, 71 72 initMetadata: function(meta) { 73 var r = meta.resourceSets[0].resources[0]; 74 this.options.subdomains = r.imageUrlSubdomains; 75 this._url = r.imageUrl; 76 if (r.imageryProviders) { 77 for (var i = 0; i < r.imageryProviders.length; i++) { 78 var p = r.imageryProviders[i]; 79 for (var j = 0; j < p.coverageAreas.length; j++) { 80 var c = p.coverageAreas[j]; 81 var coverage = {zoomMin: c.zoomMin, zoomMax: c.zoomMax, active: false}; 82 var bounds = new L.LatLngBounds( 83 new L.LatLng(c.bbox[0] + 0.01, c.bbox[1] + 0.01), 84 new L.LatLng(c.bbox[2] - 0.01, c.bbox[3] - 0.01) 85 ); 86 coverage.bounds = bounds; 87 coverage.attrib = p.attribution; 88 this._providers.push(coverage); 89 } 90 } 91 } 92 this._update(); 93 }, 94 95 _update: function() { 96 if (this._url === null || !this._map) { 97 return; 98 } 99 this._update_attribution(); 100 L.TileLayer.prototype._update.apply(this, []); 101 }, 102 103 _update_attribution: function() { 104 var bounds = L.latLngBounds( 105 this._map.getBounds().getSouthWest().wrap(), 106 this._map.getBounds().getNorthEast().wrap() 107 ); 108 var zoom = this._map.getZoom(); 109 for (var i = 0; i < this._providers.length; i++) { 110 var p = this._providers[i]; 111 if ((zoom <= p.zoomMax && zoom >= p.zoomMin) && 112 bounds.intersects(p.bounds)) { 113 if (!p.active && this._map.attributionControl) { 114 this._map.attributionControl.addAttribution(p.attrib); 115 } 116 p.active = true; 117 } else { 118 if (p.active && this._map.attributionControl) { 119 this._map.attributionControl.removeAttribution(p.attrib); 120 } 121 p.active = false; 122 } 123 } 124 }, 125 126 onAdd: function(map) { 127 this.loadMetadata(); 128 L.TileLayer.prototype.onAdd.apply(this, [map]); 129 }, 130 131 onRemove: function(map) { 132 for (var i = 0; i < this._providers.length; i++) { 133 var p = this._providers[i]; 134 if (p.active && this._map.attributionControl) { 135 this._map.attributionControl.removeAttribution(p.attrib); 136 p.active = false; 137 } 138 } 139 L.TileLayer.prototype.onRemove.apply(this, [map]); 140 } 141 }); 142 143 export {BingLayer};