1. Import

This commit is contained in:
2026-03-29 10:34:57 +02:00
parent b0e00c1259
commit a1129565af
4899 changed files with 3007593 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [3.3.0] - 2018-03-14
- ADDED: `options.style` to use [custom map styles](https://msdn.microsoft.com/en-us/library/mt823632.aspx)
- ADDED: `AerialWithLabelsOnDemand` imagery set
- ADDED: `minNativeZoom` and `maxNativeZoom` options
- FIXED: imageryProviders error [#25](https://github.com/digidem/leaflet-bing-layer/pull/25)
## [v3.2.0] - 2017-08-09
- CHANGED: Use `https` requests
- ADDED: Additional imagery sets (`RoadOnDemand`, `CanvasLight`, `CanvasDark`, `CanvasGray`, `OrdnanceSurvey`)
## [v3.1.0] - 2016-04-29
- ADDED: Use `https` for Bing API requests.
## [v3.0.1] - 2015-12-13
- FIXED: options.BingMapsKey backwards compatability
- FIXED: options.bingMapsKey was not working for getMetaData
- FIXED: catch errors (and log to console) for jsonp
## [v3.0.0] - 2015-12-08
- FIXED: **[BREAKING]** Export factory function on `L.tileLayer.bing` not `L.TileLayer.bing`
- CHANGED: BingMapsKey is now passed on `options.bingMapsKey` (`options.BingMapsKey` will still work, but for convention this should start with a lowercase character)
- IMPROVED: Package with browserify and require dependencies
- IMPROVED: Throws error if invalid imagerySet is passed as option
- ADDED: `getMetaData` method
## v2.0.2 - 2015-12-03
Initial release
[Unreleased]: https://github.com/digidem/leaflet-bing-layer/compare/v3.2.0...HEAD
[v3.2.0]: https://github.com/digidem/leaflet-bing-layer/compare/v3.1.0...v3.2.0
[v3.1.0]: https://github.com/digidem/leaflet-bing-layer/compare/v3.0.1...v3.1.0
[v3.0.1]: https://github.com/digidem/leaflet-bing-layer/compare/v3.0.0...v3.0.1
[v3.0.0]: https://github.com/digidem/leaflet-bing-layer/compare/v2.0.2...v3.0.0

View File

@@ -0,0 +1,43 @@
# leaflet-bing-layer
Bing Maps Layer for Leaflet v1.0.0
### L.TileLayer.Bing(options|BingMapsKey)
Create a new Bing Maps Layer. Depends on [Promises](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) which needs a polyfill for [older browsers](http://caniuse.com/#feat=promises) by adding this script to your html `<head>`:
```html
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Promise"></script>
```
### Parameters
| parameter | type | description |
| ----------------------------- | -------------- | ----------------------------------------------------------------------------------------------------- |
| `options` | string\|object | A valid [Bing Maps Key](https://msdn.microsoft.com/en-us/library/ff428642.aspx) or an `options` object. `options` inherits from [L.TileLayer options](http://mourner.github.io/Leaflet/reference.html#tilelayer-options) (e.g. you can use `minZoom` and `opacity` and etc) |
| `options.bingMapsKey` | string | A valid Bing Maps Key [_required_] |
| `[options.imagerySet]` | string | _optional:_ [Imagery Type](https://msdn.microsoft.com/en-us/library/ff701716.aspx) [_default=Aerial_]<br>- `Aerial` - Aerial imagery<br>- `AerialWithLabels` - Aerial imagery with a road overlay<br>- `AerialWithLabelsOnDemand` - Aerial imagery with on-demand road overlay.<br>- `CanvasDark` - A dark version of the road maps.<br>- `CanvasLight` - A lighter version of the road maps which also has some of the details such as hill shading disabled.<br>- `CanvasGray` - A grayscale version of the road maps.<br>- `Road` - Roads without additional imagery. Uses the legacy static tile service.<br>- `RoadOnDemand` - Roads without additional imagery. Uses the dynamic tile service.<br>- `OrdnanceSurvey` - Ordnance Survey imagery. This imagery is visible only for the London area.<br>**[Not supported](https://social.msdn.microsoft.com/Forums/en-US/3d80d4a6-f4c9-4926-a336-e0d545b1ef3c/is-it-possible-to-retrieve-birdseye-map-tiles-using-rest-services?forum=bingmapsservices)**: `Birdseye` and `BirdseyeWithLabels` |
| `[options.culture]` | string | _optional:_ Language for labels, [see options](https://msdn.microsoft.com/en-us/library/hh441729.aspx) [_default=en_US_] |
| `[options.style]` | string | _optional:_ Use a [custom map style](https://msdn.microsoft.com/en-us/library/mt823632.aspx) - only works with the `AerialWithLabelsOnDemand` and `RoadOnDemand` imagerySet options. |
Other options are passed through to a [Leaflet TileLayer](http://leafletjs.com/reference-1.3.0.html#tilelayer-l-tilelayer)
### Methods
| Method | Returns | Description |
| ---------- | -------------- | ------------- |
| `getMetaData(<LatLng> latlng, <Number> zoom)` | `Promise` | Get the [Bing Imagery metadata](https://msdn.microsoft.com/en-us/library/ff701712.aspx) for a specific [`LatLng`](http://leafletjs.com/reference.html#latlng) and zoom level. `latLng` or `zoom` are optional *if* the layer is attached to a map, they default to current map center and zoom. Returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves to the metadata JSON from Bing |
### Example
```js
var map = L.map('map').setView([51.505, -0.09], 13)
L.tileLayer.bing(MyBingMapsKey).addTo(map)
```
[Live Example](http://digidem.github.io/leaflet-bing-layer/) see [index.html](index.html)
### License
MIT

View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui' />
<title>Leaflet Bing Maps Layer</title>
<script src='http://cdn.leafletjs.com/leaflet/v1.0.0-rc.1/leaflet.js'></script>
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Promise"></script>
<script src="leaflet-bing-layer.js"></script>
<link href='http://cdn.leafletjs.com/leaflet/v1.0.0-rc.1/leaflet.css' rel='stylesheet' />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id='map'></div>
<script>
var BING_KEY = 'AuhiCJHlGzhg93IqUH_oCpl_-ZUrIE6SPftlyGYUvr9Amx5nzA-WqGcPquyFZl4L'
var map = L.map('map').setView([51.505, -0.09], 13)
var bingLayer = L.tileLayer.bing(BING_KEY).addTo(map)
</script>
</body>
</html>

View File

@@ -0,0 +1,276 @@
var L = require('leaflet')
var fetchJsonp = require('fetch-jsonp')
var bboxIntersect = require('bbox-intersect')
/**
* Converts tile xyz coordinates to Quadkey
* @param {Number} x
* @param {Number} y
* @param {Number} z
* @return {Number} Quadkey
*/
function toQuadKey (x, y, z) {
var index = ''
for (var i = z; i > 0; i--) {
var b = 0
var mask = 1 << (i - 1)
if ((x & mask) !== 0) b++
if ((y & mask) !== 0) b += 2
index += b.toString()
}
return index
}
/**
* Converts Leaflet BBoxString to Bing BBox
* @param {String} bboxString 'southwest_lng,southwest_lat,northeast_lng,northeast_lat'
* @return {Array} [south_lat, west_lng, north_lat, east_lng]
*/
function toBingBBox (bboxString) {
var bbox = bboxString.split(',')
return [bbox[1], bbox[0], bbox[3], bbox[2]]
}
var VALID_IMAGERY_SETS = [
'Aerial',
'AerialWithLabels',
'AerialWithLabelsOnDemand',
'Road',
'RoadOnDemand',
'CanvasLight',
'CanvasDark',
'CanvasGray',
'OrdnanceSurvey'
]
var DYNAMIC_IMAGERY_SETS = [
'AerialWithLabelsOnDemand',
'RoadOnDemand'
]
/**
* Create a new Bing Maps layer.
* @param {string|object} options Either a [Bing Maps Key](https://msdn.microsoft.com/en-us/library/ff428642.aspx) or an options object
* @param {string} options.BingMapsKey A valid Bing Maps Key (required)
* @param {string} [options.imagerySet=Aerial] Type of imagery, see https://msdn.microsoft.com/en-us/library/ff701716.aspx
* @param {string} [options.culture='en-US'] Language for labels, see https://msdn.microsoft.com/en-us/library/hh441729.aspx
* @return {L.TileLayer} A Leaflet TileLayer to add to your map
*
* Create a basic map
* @example
* var map = L.map('map').setView([51.505, -0.09], 13)
* L.TileLayer.Bing(MyBingMapsKey).addTo(map)
*/
L.TileLayer.Bing = L.TileLayer.extend({
options: {
bingMapsKey: null, // Required
imagerySet: 'Aerial',
culture: 'en-US',
minZoom: 1,
minNativeZoom: 1,
maxNativeZoom: 19
},
statics: {
METADATA_URL: 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/{imagerySet}?key={bingMapsKey}&include=ImageryProviders&uriScheme=https&c={culture}',
POINT_METADATA_URL: 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/{imagerySet}/{lat},{lng}?zl={z}&key={bingMapsKey}&uriScheme=https&c={culture}'
},
initialize: function (options) {
if (typeof options === 'string') {
options = { bingMapsKey: options }
}
if (options && options.BingMapsKey) {
options.bingMapsKey = options.BingMapsKey
console.warn('use options.bingMapsKey instead of options.BingMapsKey')
}
if (!options || !options.bingMapsKey) {
throw new Error('Must supply options.BingMapsKey')
}
options = L.setOptions(this, options)
if (VALID_IMAGERY_SETS.indexOf(options.imagerySet) < 0) {
throw new Error("'" + options.imagerySet + "' is an invalid imagerySet, see https://github.com/digidem/leaflet-bing-layer#parameters")
}
if (options && options.style && DYNAMIC_IMAGERY_SETS.indexOf(options.imagerySet) < 0) {
console.warn('Dynamic styles will only work with these imagerySet choices: ' + DYNAMIC_IMAGERY_SETS.join(', '))
}
var metaDataUrl = L.Util.template(L.TileLayer.Bing.METADATA_URL, {
bingMapsKey: this.options.bingMapsKey,
imagerySet: this.options.imagerySet,
culture: this.options.culture
})
this._imageryProviders = []
this._attributions = []
// Keep a reference to the promise so we can use it later
this._fetch = fetchJsonp(metaDataUrl, {jsonpCallback: 'jsonp'})
.then(function (response) {
return response.json()
})
.then(this._metaDataOnLoad.bind(this))
.catch(console.error.bind(console))
// for https://github.com/Leaflet/Leaflet/issues/137
if (!L.Browser.android) {
this.on('tileunload', this._onTileRemove)
}
},
createTile: function (coords, done) {
var tile = document.createElement('img')
L.DomEvent.on(tile, 'load', L.bind(this._tileOnLoad, this, done, tile))
L.DomEvent.on(tile, 'error', L.bind(this._tileOnError, this, done, tile))
if (this.options.crossOrigin) {
tile.crossOrigin = ''
}
/*
Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons
http://www.w3.org/TR/WCAG20-TECHS/H67
*/
tile.alt = ''
// Don't create closure if we don't have to
if (this._url) {
tile.src = this.getTileUrl(coords)
} else {
this._fetch.then(function () {
tile.src = this.getTileUrl(coords)
}.bind(this)).catch(function (e) {
console.error(e)
done(e)
})
}
return tile
},
getTileUrl: function (coords) {
var quadkey = toQuadKey(coords.x, coords.y, coords.z)
var url = L.Util.template(this._url, {
quadkey: quadkey,
subdomain: this._getSubdomain(coords),
culture: this.options.culture
})
if (typeof this.options.style === 'string') {
url += '&st=' + this.options.style
}
return url
},
// Update the attribution control every time the map is moved
onAdd: function (map) {
map.on('moveend', this._updateAttribution, this)
L.TileLayer.prototype.onAdd.call(this, map)
this._attributions.forEach(function (attribution) {
map.attributionControl.addAttribution(attribution)
})
},
// Clean up events and remove attributions from attribution control
onRemove: function (map) {
map.off('moveend', this._updateAttribution, this)
this._attributions.forEach(function (attribution) {
map.attributionControl.removeAttribution(attribution)
})
L.TileLayer.prototype.onRemove.call(this, map)
},
/**
* Get the [Bing Imagery metadata](https://msdn.microsoft.com/en-us/library/ff701712.aspx)
* for a specific [`LatLng`](http://leafletjs.com/reference.html#latlng)
* and zoom level. If either `latlng` or `zoom` is omitted and the layer is attached
* to a map, the map center and current map zoom are used.
* @param {L.LatLng} latlng
* @param {Number} zoom
* @return {Promise} Resolves to the JSON metadata
*/
getMetaData: function (latlng, zoom) {
if (!this._map && (!latlng || !zoom)) {
return Promise.reject(new Error('If layer is not attached to map, you must provide LatLng and zoom'))
}
latlng = latlng || this._map.getCenter()
zoom = zoom || this._map.getZoom()
var PointMetaDataUrl = L.Util.template(L.TileLayer.Bing.POINT_METADATA_URL, {
bingMapsKey: this.options.bingMapsKey,
imagerySet: this.options.imagerySet,
z: zoom,
lat: latlng.lat,
lng: latlng.lng
})
return fetchJsonp(PointMetaDataUrl, {jsonpCallback: 'jsonp'})
.then(function (response) {
return response.json()
})
.catch(console.error.bind(console))
},
_metaDataOnLoad: function (metaData) {
if (metaData.statusCode !== 200) {
throw new Error('Bing Imagery Metadata error: \n' + JSON.stringify(metaData, null, ' '))
}
var resource = metaData.resourceSets[0].resources[0]
this._url = resource.imageUrl
this._imageryProviders = resource.imageryProviders || []
this.options.subdomains = resource.imageUrlSubdomains
this._updateAttribution()
return Promise.resolve()
},
/**
* Update the attribution control of the map with the provider attributions
* within the current map bounds
*/
_updateAttribution: function () {
var map = this._map
if (!map || !map.attributionControl) return
var zoom = map.getZoom()
var bbox = toBingBBox(map.getBounds().toBBoxString())
this._fetch.then(function () {
var newAttributions = this._getAttributions(bbox, zoom)
var prevAttributions = this._attributions
// Add any new provider attributions in the current area to the attribution control
newAttributions.forEach(function (attr) {
if (prevAttributions.indexOf(attr) > -1) return
map.attributionControl.addAttribution(attr)
})
// Remove any attributions that are no longer in the current area from the attribution control
prevAttributions.filter(function (attr) {
if (newAttributions.indexOf(attr) > -1) return
map.attributionControl.removeAttribution(attr)
})
this._attributions = newAttributions
}.bind(this))
},
/**
* Returns an array of attributions for given bbox and zoom
* @private
* @param {Array} bbox [west, south, east, north]
* @param {Number} zoom
* @return {Array} Array of attribution strings for each provider
*/
_getAttributions: function (bbox, zoom) {
return this._imageryProviders.reduce(function (attributions, provider) {
for (var i = 0; i < provider.coverageAreas.length; i++) {
if (bboxIntersect(bbox, provider.coverageAreas[i].bbox) &&
zoom >= provider.coverageAreas[i].zoomMin &&
zoom <= provider.coverageAreas[i].zoomMax) {
attributions.push(provider.attribution)
return attributions
}
}
return attributions
}, [])
}
})
L.tileLayer.bing = function (options) {
return new L.TileLayer.Bing(options)
}
module.exports = L.TileLayer.Bing

View File

@@ -0,0 +1,399 @@
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
(function (global){
var L = (typeof window !== "undefined" ? window['L'] : typeof global !== "undefined" ? global['L'] : null)
var fetchJsonp = require('fetch-jsonp')
var bboxIntersect = require('bbox-intersect')
/**
* Converts tile xyz coordinates to Quadkey
* @param {Number} x
* @param {Number} y
* @param {Number} z
* @return {Number} Quadkey
*/
function toQuadKey (x, y, z) {
var index = ''
for (var i = z; i > 0; i--) {
var b = 0
var mask = 1 << (i - 1)
if ((x & mask) !== 0) b++
if ((y & mask) !== 0) b += 2
index += b.toString()
}
return index
}
/**
* Converts Leaflet BBoxString to Bing BBox
* @param {String} bboxString 'southwest_lng,southwest_lat,northeast_lng,northeast_lat'
* @return {Array} [south_lat, west_lng, north_lat, east_lng]
*/
function toBingBBox (bboxString) {
var bbox = bboxString.split(',')
return [bbox[1], bbox[0], bbox[3], bbox[2]]
}
var VALID_IMAGERY_SETS = [
'Aerial',
'AerialWithLabels',
'AerialWithLabelsOnDemand',
'Road',
'RoadOnDemand',
'CanvasLight',
'CanvasDark',
'CanvasGray',
'OrdnanceSurvey'
]
var DYNAMIC_IMAGERY_SETS = [
'AerialWithLabelsOnDemand',
'RoadOnDemand'
]
/**
* Create a new Bing Maps layer.
* @param {string|object} options Either a [Bing Maps Key](https://msdn.microsoft.com/en-us/library/ff428642.aspx) or an options object
* @param {string} options.BingMapsKey A valid Bing Maps Key (required)
* @param {string} [options.imagerySet=Aerial] Type of imagery, see https://msdn.microsoft.com/en-us/library/ff701716.aspx
* @param {string} [options.culture='en-US'] Language for labels, see https://msdn.microsoft.com/en-us/library/hh441729.aspx
* @return {L.TileLayer} A Leaflet TileLayer to add to your map
*
* Create a basic map
* @example
* var map = L.map('map').setView([51.505, -0.09], 13)
* L.TileLayer.Bing(MyBingMapsKey).addTo(map)
*/
L.TileLayer.Bing = L.TileLayer.extend({
options: {
bingMapsKey: null, // Required
imagerySet: 'Aerial',
culture: 'en-US',
minZoom: 1,
minNativeZoom: 1,
maxNativeZoom: 19
},
statics: {
METADATA_URL: 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/{imagerySet}?key={bingMapsKey}&include=ImageryProviders&uriScheme=https',
POINT_METADATA_URL: 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/{imagerySet}/{lat},{lng}?zl={z}&key={bingMapsKey}&uriScheme=https'
},
initialize: function (options) {
if (typeof options === 'string') {
options = { bingMapsKey: options }
}
if (options && options.BingMapsKey) {
options.bingMapsKey = options.BingMapsKey
console.warn('use options.bingMapsKey instead of options.BingMapsKey')
}
if (!options || !options.bingMapsKey) {
throw new Error('Must supply options.BingMapsKey')
}
options = L.setOptions(this, options)
if (VALID_IMAGERY_SETS.indexOf(options.imagerySet) < 0) {
throw new Error("'" + options.imagerySet + "' is an invalid imagerySet, see https://github.com/digidem/leaflet-bing-layer#parameters")
}
if (options && options.style && DYNAMIC_IMAGERY_SETS.indexOf(options.imagerySet) < 0) {
console.warn('Dynamic styles will only work with these imagerySet choices: ' + DYNAMIC_IMAGERY_SETS.join(', '))
}
var metaDataUrl = L.Util.template(L.TileLayer.Bing.METADATA_URL, {
bingMapsKey: this.options.bingMapsKey,
imagerySet: this.options.imagerySet
})
this._imageryProviders = []
this._attributions = []
// Keep a reference to the promise so we can use it later
this._fetch = fetchJsonp(metaDataUrl, {jsonpCallback: 'jsonp'})
.then(function (response) {
return response.json()
})
.then(this._metaDataOnLoad.bind(this))
.catch(console.error.bind(console))
// for https://github.com/Leaflet/Leaflet/issues/137
if (!L.Browser.android) {
this.on('tileunload', this._onTileRemove)
}
},
createTile: function (coords, done) {
var tile = document.createElement('img')
L.DomEvent.on(tile, 'load', L.bind(this._tileOnLoad, this, done, tile))
L.DomEvent.on(tile, 'error', L.bind(this._tileOnError, this, done, tile))
if (this.options.crossOrigin) {
tile.crossOrigin = ''
}
/*
Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons
http://www.w3.org/TR/WCAG20-TECHS/H67
*/
tile.alt = ''
// Don't create closure if we don't have to
if (this._url) {
tile.src = this.getTileUrl(coords)
} else {
this._fetch.then(function () {
tile.src = this.getTileUrl(coords)
}.bind(this)).catch(function (e) {
console.error(e)
done(e)
})
}
return tile
},
getTileUrl: function (coords) {
var quadkey = toQuadKey(coords.x, coords.y, coords.z)
var url = L.Util.template(this._url, {
quadkey: quadkey,
subdomain: this._getSubdomain(coords),
culture: this.options.culture
})
if (typeof this.options.style === 'string') {
url += '&st=' + this.options.style
}
return url
},
// Update the attribution control every time the map is moved
onAdd: function (map) {
map.on('moveend', this._updateAttribution, this)
L.TileLayer.prototype.onAdd.call(this, map)
this._attributions.forEach(function (attribution) {
map.attributionControl.addAttribution(attribution)
})
},
// Clean up events and remove attributions from attribution control
onRemove: function (map) {
map.off('moveend', this._updateAttribution, this)
this._attributions.forEach(function (attribution) {
map.attributionControl.removeAttribution(attribution)
})
L.TileLayer.prototype.onRemove.call(this, map)
},
/**
* Get the [Bing Imagery metadata](https://msdn.microsoft.com/en-us/library/ff701712.aspx)
* for a specific [`LatLng`](http://leafletjs.com/reference.html#latlng)
* and zoom level. If either `latlng` or `zoom` is omitted and the layer is attached
* to a map, the map center and current map zoom are used.
* @param {L.LatLng} latlng
* @param {Number} zoom
* @return {Promise} Resolves to the JSON metadata
*/
getMetaData: function (latlng, zoom) {
if (!this._map && (!latlng || !zoom)) {
return Promise.reject(new Error('If layer is not attached to map, you must provide LatLng and zoom'))
}
latlng = latlng || this._map.getCenter()
zoom = zoom || this._map.getZoom()
var PointMetaDataUrl = L.Util.template(L.TileLayer.Bing.POINT_METADATA_URL, {
bingMapsKey: this.options.bingMapsKey,
imagerySet: this.options.imagerySet,
z: zoom,
lat: latlng.lat,
lng: latlng.lng
})
return fetchJsonp(PointMetaDataUrl, {jsonpCallback: 'jsonp'})
.then(function (response) {
return response.json()
})
.catch(console.error.bind(console))
},
_metaDataOnLoad: function (metaData) {
if (metaData.statusCode !== 200) {
throw new Error('Bing Imagery Metadata error: \n' + JSON.stringify(metaData, null, ' '))
}
var resource = metaData.resourceSets[0].resources[0]
this._url = resource.imageUrl
this._imageryProviders = resource.imageryProviders || []
this.options.subdomains = resource.imageUrlSubdomains
this._updateAttribution()
return Promise.resolve()
},
/**
* Update the attribution control of the map with the provider attributions
* within the current map bounds
*/
_updateAttribution: function () {
var map = this._map
if (!map || !map.attributionControl) return
var zoom = map.getZoom()
var bbox = toBingBBox(map.getBounds().toBBoxString())
this._fetch.then(function () {
var newAttributions = this._getAttributions(bbox, zoom)
var prevAttributions = this._attributions
// Add any new provider attributions in the current area to the attribution control
newAttributions.forEach(function (attr) {
if (prevAttributions.indexOf(attr) > -1) return
map.attributionControl.addAttribution(attr)
})
// Remove any attributions that are no longer in the current area from the attribution control
prevAttributions.filter(function (attr) {
if (newAttributions.indexOf(attr) > -1) return
map.attributionControl.removeAttribution(attr)
})
this._attributions = newAttributions
}.bind(this))
},
/**
* Returns an array of attributions for given bbox and zoom
* @private
* @param {Array} bbox [west, south, east, north]
* @param {Number} zoom
* @return {Array} Array of attribution strings for each provider
*/
_getAttributions: function (bbox, zoom) {
return this._imageryProviders.reduce(function (attributions, provider) {
for (var i = 0; i < provider.coverageAreas.length; i++) {
if (bboxIntersect(bbox, provider.coverageAreas[i].bbox) &&
zoom >= provider.coverageAreas[i].zoomMin &&
zoom <= provider.coverageAreas[i].zoomMax) {
attributions.push(provider.attribution)
return attributions
}
}
return attributions
}, [])
}
})
L.tileLayer.bing = function (options) {
return new L.TileLayer.Bing(options)
}
module.exports = L.TileLayer.Bing
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"bbox-intersect":2,"fetch-jsonp":3}],2:[function(require,module,exports){
module.exports = function(bbox1, bbox2){
if(!(
bbox1[0] > bbox2[2] ||
bbox1[2] < bbox2[0] ||
bbox1[3] < bbox2[1] ||
bbox1[1] > bbox2[3]
)){
return true;
} else {
return false;
}
}
},{}],3:[function(require,module,exports){
(function (global, factory) {
if (typeof define === 'function' && define.amd) {
define(['exports', 'module'], factory);
} else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
factory(exports, module);
} else {
var mod = {
exports: {}
};
factory(mod.exports, mod);
global.fetchJsonp = mod.exports;
}
})(this, function (exports, module) {
'use strict';
var defaultOptions = {
timeout: 5000,
jsonpCallback: 'callback',
jsonpCallbackFunction: null
};
function generateCallbackFunction() {
return 'jsonp_' + Date.now() + '_' + Math.ceil(Math.random() * 100000);
}
// Known issue: Will throw 'Uncaught ReferenceError: callback_*** is not defined' error if request timeout
function clearFunction(functionName) {
// IE8 throws an exception when you try to delete a property on window
// http://stackoverflow.com/a/1824228/751089
try {
delete window[functionName];
} catch (e) {
window[functionName] = undefined;
}
}
function removeScript(scriptId) {
var script = document.getElementById(scriptId);
document.getElementsByTagName('head')[0].removeChild(script);
}
var fetchJsonp = function fetchJsonp(url) {
var options = arguments[1] === undefined ? {} : arguments[1];
var timeout = options.timeout != null ? options.timeout : defaultOptions.timeout;
var jsonpCallback = options.jsonpCallback != null ? options.jsonpCallback : defaultOptions.jsonpCallback;
var timeoutId = undefined;
return new Promise(function (resolve, reject) {
var callbackFunction = options.jsonpCallbackFunction || generateCallbackFunction();
window[callbackFunction] = function (response) {
resolve({
ok: true,
// keep consistent with fetch API
json: function json() {
return Promise.resolve(response);
}
});
if (timeoutId) clearTimeout(timeoutId);
removeScript(jsonpCallback + '_' + callbackFunction);
clearFunction(callbackFunction);
};
// Check if the user set their own params, and if not add a ? to start a list of params
url += url.indexOf('?') === -1 ? '?' : '&';
var jsonpScript = document.createElement('script');
jsonpScript.setAttribute('src', url + jsonpCallback + '=' + callbackFunction);
jsonpScript.id = jsonpCallback + '_' + callbackFunction;
document.getElementsByTagName('head')[0].appendChild(jsonpScript);
timeoutId = setTimeout(function () {
reject(new Error('JSONP request to ' + url + ' timed out'));
clearFunction(callbackFunction);
removeScript(jsonpCallback + '_' + callbackFunction);
}, timeout);
});
};
// export as global function
/*
let local;
if (typeof global !== 'undefined') {
local = global;
} else if (typeof self !== 'undefined') {
local = self;
} else {
try {
local = Function('return this')();
} catch (e) {
throw new Error('polyfill failed because global object is unavailable in this environment');
}
}
local.fetchJsonp = fetchJsonp;
*/
module.exports = fetchJsonp;
});
},{}]},{},[1]);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,47 @@
{
"name": "leaflet-bing-layer",
"version": "3.3.0",
"description": "Bing Maps Layer for Leaflet v1.0.0",
"main": "index.js",
"browserify": {
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
"leaflet": "global:L"
},
"scripts": {
"build": "browserify index.js > leaflet-bing-layer.js",
"postbuild": "uglifyjs leaflet-bing-layer.js -cm -o leaflet-bing-layer.min.js",
"preversion": "npm test && npm run build",
"lint": "standard index.js",
"start": "budo index.js:leaflet-bing-layer.js --live",
"test": "npm run lint"
},
"keywords": [
"leaflet",
"bing"
],
"author": "Gregor MacLennan",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/gmaclennan/leaflet-bing-layer.git"
},
"bugs": {
"url": "https://github.com/gmaclennan/leaflet-bing-layer/issues"
},
"homepage": "https://github.com/gmaclennan/leaflet-bing-layer",
"dependencies": {
"bbox-intersect": "^0.1.1",
"browserify-shim": "^3.8.11",
"fetch-jsonp": "^1.0.0",
"leaflet": "^1.0.0-beta.2"
},
"devDependencies": {
"browserify": "^12.0.1",
"budo": "^7.0.2",
"standard": "^5.4.1"
}
}