user168080 user168080 - 25 days ago 18
Javascript Question

Use Bing Quadkey tiles instead of x/y/z tiles in leafletjs map

I try to create a map with leaflet.js where it is possible to switch between different tile layers. It works great with tileservers that serve the tiles with the standard x,y and z(oom) schema. However, Microsoft Bing uses its own quadkey schema. I found a JavaScript function to convert xyz to quad, but I don't know how to use it. Please see my example:

function toQuad(x, y, z) {
var quadkey = '';
for ( var i = z; i >= 0; --i) {
var bitmask = 1 << i;
var digit = 0;
if ((x & bitmask) !== 0) {
digit |= 1;}
if ((y & bitmask) !== 0) {
digit |= 2;}
quadkey += digit;
}
return quadkey;
};
var openstreetmap = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'}),
arcgissat = L.tileLayer('http://{s}.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {subdomains: ['server', 'services'], attribution: '&copy; <a href="http://www.arcgis.com/">ArcGIS esri</a>'})
// bingsat = L.tileLayer('http://t{s}.tiles.virtualearth.net/tiles/a'+toQuad({x},{y},{z})+'.jpeg?g=1398', {subdomains: [0,1,2,3,4,5], attribution: '&copy; <a href="http://bing.com/maps">Bing Maps</a>'}),
var map = L.map('map', {
center: [48.85,2.33],
zoom: 10,
layers: [openstreetmap]
});
var baseLayers = {
"OpenStreetMap": openstreetmap,
// "Bing Sat": bingsat,
"ArcGIS esri Sat": arcgissat
};
L.control.layers(baseLayers, null, {collapsed: false}).addTo(map);


Basically I just don't know how to call the JavaScript function inside of the variable declaration with the {x}, {y} and {z} values that leafletjs provides.

Answer

You can create a simple "BingLayer" by extending the L.TileLayer class. Then you just have to override the getTileUrl method to use the new template you prefer (i.e. for bing maps). See the linked fiddle for an example:

http://jsfiddle.net/nkmbx/

var BingLayer = L.TileLayer.extend({
getTileUrl: function (tilePoint) {
    this._adjustTilePoint(tilePoint);
    return L.Util.template(this._url, {
        s: this._getSubdomain(tilePoint),
        q: this._quadKey(tilePoint.x, tilePoint.y, this._getZoomForUrl())
    });
},
_quadKey: function (x, y, z) {
    var quadKey = [];
    for (var i = z; i > 0; i--) {
        var digit = '0';
        var mask = 1 << (i - 1);
        if ((x & mask) != 0) {
            digit++;
        }
        if ((y & mask) != 0) {
            digit++;
            digit++;
        }
        quadKey.push(digit);
    }
    return quadKey.join('');
}
});
Comments