1 L
.BingLayer
= L
.TileLayer
.extend({
3 subdomains
: [0, 1, 2, 3],
9 initialize: function (key
, options
) {
10 L
.Util
.setOptions(this, options
);
15 this.metaRequested
= false;
18 tile2quad: function (x
, y
, z
) {
20 for (var i
= z
; i
> 0; i
--) {
22 var mask
= 1 << (i
- 1);
23 if ((x
& mask
) !== 0) digit
+= 1;
24 if ((y
& mask
) !== 0) digit
+= 2;
30 getTileUrl: function (tilePoint
) {
31 var zoom
= this._getZoomForUrl();
32 var subdomains
= this.options
.subdomains
,
33 s
= this.options
.subdomains
[Math
.abs((tilePoint
.x
+ tilePoint
.y
) % subdomains
.length
)];
34 return this._url
.replace('{subdomain}', s
)
35 .replace('{quadkey}', this.tile2quad(tilePoint
.x
, tilePoint
.y
, zoom
))
36 .replace('{culture}', this.options
.culture
);
39 loadMetadata: function () {
40 if (this.metaRequested
) return;
41 this.metaRequested
= true;
43 var cbid
= '_bing_metadata_' + L
.Util
.stamp(this);
44 window
[cbid
] = function (meta
) {
45 window
[cbid
] = undefined;
46 var e
= document
.getElementById(cbid
);
47 e
.parentNode
.removeChild(e
);
48 if (meta
.errorDetails
) {
49 throw new Error(meta
.errorDetails
);
52 _this
.initMetadata(meta
);
54 var urlScheme
= (document
.location
.protocol
=== 'file:') ? 'http' : document
.location
.protocol
.slice(0, -1);
55 var url
= urlScheme
+ '://dev.virtualearth.net/REST/v1/Imagery/Metadata/'
56 + this.options
.type
+ '?include=ImageryProviders&jsonp=' + cbid
+
57 '&key=' + this._key
+ '&UriScheme=' + urlScheme
;
58 var script
= document
.createElement('script');
59 script
.type
= 'text/javascript';
62 document
.getElementsByTagName('head')[0].appendChild(script
);
65 initMetadata: function (meta
) {
66 var r
= meta
.resourceSets
[0].resources
[0];
67 this.options
.subdomains
= r
.imageUrlSubdomains
;
68 this._url
= r
.imageUrl
;
69 if (r
.imageryProviders
) {
70 for (var i
= 0; i
< r
.imageryProviders
.length
; i
++) {
71 var p
= r
.imageryProviders
[i
];
72 for (var j
= 0; j
< p
.coverageAreas
.length
; j
++) {
73 var c
= p
.coverageAreas
[j
];
74 var coverage
= {zoomMin
: c
.zoomMin
, zoomMax
: c
.zoomMax
, active
: false};
75 var bounds
= new L
.LatLngBounds(
76 new L
.LatLng(c
.bbox
[0]+0.01, c
.bbox
[1]+0.01),
77 new L
.LatLng(c
.bbox
[2]-0.01, c
.bbox
[3]-0.01)
79 coverage
.bounds
= bounds
;
80 coverage
.attrib
= p
.attribution
;
81 this._providers
.push(coverage
);
88 _update: function () {
89 if (this._url
=== null || !this._map
) return;
90 this._update_attribution();
91 L
.TileLayer
.prototype._update
.apply(this, []);
94 _update_attribution: function () {
95 var bounds
= L
.latLngBounds(this._map
.getBounds().getSouthWest().wrap(),this._map
.getBounds().getNorthEast().wrap());
96 var zoom
= this._map
.getZoom();
97 for (var i
= 0; i
< this._providers
.length
; i
++) {
98 var p
= this._providers
[i
];
99 if ((zoom
<= p
.zoomMax
&& zoom
>= p
.zoomMin
) &&
100 bounds
.intersects(p
.bounds
)) {
101 if (!p
.active
&& this._map
.attributionControl
)
102 this._map
.attributionControl
.addAttribution(p
.attrib
);
105 if (p
.active
&& this._map
.attributionControl
)
106 this._map
.attributionControl
.removeAttribution(p
.attrib
);
112 onAdd: function (map
) {
114 L
.TileLayer
.prototype.onAdd
.apply(this, [map
]);
117 onRemove: function (map
) {
118 for (var i
= 0; i
< this._providers
.length
; i
++) {
119 var p
= this._providers
[i
];
120 if (p
.active
&& this._map
.attributionControl
) {
121 this._map
.attributionControl
.removeAttribution(p
.attrib
);
125 L
.TileLayer
.prototype.onRemove
.apply(this, [map
]);
129 L
.bingLayer = function (key
, options
) {
130 return new L
.BingLayer(key
, options
);