Files
openlayers/src/ol/source/bingmapssource.js
Éric Lemoine e128bab625 Do not pass tile grid to getTile and tileUrlFunc
getTile and the tileUrlFunc are functions of the source, so they do need to be passed the tile grid. The tile source knows its tile grid, and can get the projection's tile grid if it doesn't have a tile grid.
2013-04-02 11:12:43 +02:00

163 lines
4.8 KiB
JavaScript

goog.provide('ol.source.BingMaps');
goog.require('goog.Uri');
goog.require('goog.array');
goog.require('goog.net.Jsonp');
goog.require('ol.Attribution');
goog.require('ol.Extent');
goog.require('ol.Size');
goog.require('ol.TileCoord');
goog.require('ol.TileRange');
goog.require('ol.TileUrlFunction');
goog.require('ol.projection');
goog.require('ol.source.ImageTileSource');
goog.require('ol.tilegrid.XYZ');
/**
* @constructor
* @extends {ol.source.ImageTileSource}
* @param {ol.source.BingMapsOptions} bingMapsOptions Bing Maps options.
*/
ol.source.BingMaps = function(bingMapsOptions) {
goog.base(this, {
crossOrigin: 'anonymous',
opaque: true,
projection: ol.projection.get('EPSG:3857')
});
/**
* @private
* @type {string}
*/
this.culture_ = goog.isDef(bingMapsOptions.culture) ?
bingMapsOptions.culture : 'en-us';
/**
* @private
* @type {boolean}
*/
this.ready_ = false;
var uri = new goog.Uri(
'//dev.virtualearth.net/REST/v1/Imagery/Metadata/' +
bingMapsOptions.style);
var jsonp = new goog.net.Jsonp(uri, 'jsonp');
jsonp.send({
'include': 'ImageryProviders',
'key': bingMapsOptions.key
}, goog.bind(this.handleImageryMetadataResponse, this));
};
goog.inherits(ol.source.BingMaps, ol.source.ImageTileSource);
/**
* @param {BingMapsImageryMetadataResponse} response Response.
*/
ol.source.BingMaps.prototype.handleImageryMetadataResponse =
function(response) {
goog.asserts.assert(
response.authenticationResultCode == 'ValidCredentials');
goog.asserts.assert(response.statusCode == 200);
goog.asserts.assert(response.statusDescription == 'OK');
var brandLogoUri = response.brandLogoUri;
var copyright = response.copyright;
goog.asserts.assert(response.resourceSets.length == 1);
var resourceSet = response.resourceSets[0];
goog.asserts.assert(resourceSet.resources.length == 1);
var resource = resourceSet.resources[0];
var zoomMin = resource.zoomMin;
var zoomMax = resource.zoomMax;
var tileSize = new ol.Size(resource.imageWidth, resource.imageHeight);
var tileGrid = new ol.tilegrid.XYZ({
maxZoom: zoomMax,
tileSize: tileSize
});
this.tileGrid = tileGrid;
var culture = this.culture_;
this.tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform(
function(tileCoord) {
if (tileCoord.z < zoomMin || zoomMax < tileCoord.z) {
return null;
}
var n = 1 << tileCoord.z;
var y = -tileCoord.y - 1;
if (y < 0 || n <= y) {
return null;
} else {
var x = goog.math.modulo(tileCoord.x, n);
return new ol.TileCoord(tileCoord.z, x, y);
}
},
ol.TileUrlFunction.createFromTileUrlFunctions(
goog.array.map(
resource.imageUrlSubdomains,
function(subdomain) {
var imageUrl = resource.imageUrl
.replace('{subdomain}', subdomain)
.replace('{culture}', culture);
return function(tileCoord, projection) {
goog.asserts.assert(ol.projection.equivalent(
projection, this.getProjection()));
if (goog.isNull(tileCoord)) {
return undefined;
} else {
return imageUrl.replace(
'{quadkey}', tileCoord.quadKey());
}
};
})));
var transform = ol.projection.getTransformFromProjections(
ol.projection.get('EPSG:4326'), this.getProjection());
var attributions = goog.array.map(
resource.imageryProviders,
function(imageryProvider) {
var html = imageryProvider.attribution;
/** @type {Object.<string, Array.<ol.TileRange>>} */
var tileRanges = {};
goog.array.forEach(
imageryProvider.coverageAreas,
function(coverageArea) {
var minZ = coverageArea.zoomMin;
var maxZ = coverageArea.zoomMax;
var bbox = coverageArea.bbox;
var epsg4326Extent =
new ol.Extent(bbox[1], bbox[0], bbox[3], bbox[2]);
var extent = epsg4326Extent.transform(transform);
var tileRange, z, zKey;
for (z = minZ; z <= maxZ; ++z) {
zKey = z.toString();
tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
if (zKey in tileRanges) {
tileRanges[zKey].push(tileRange);
} else {
tileRanges[zKey] = [tileRange];
}
}
});
return new ol.Attribution(html, tileRanges);
});
this.setAttributions(attributions);
this.ready_ = true;
this.dispatchLoadEvent();
};
/**
* @inheritDoc
*/
ol.source.BingMaps.prototype.isReady = function() {
return this.ready_;
};