Skip to content

Commit

Permalink
Merge pull request #715 from OpenGeoscience/subdomain-template-options
Browse files Browse the repository at this point in the history
Increase options for tile url templates.
  • Loading branch information
manthey authored Jun 23, 2017
2 parents ead485f + 212b1f8 commit a7ecabc
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 22 deletions.
54 changes: 44 additions & 10 deletions src/tileLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,62 @@ module.exports = (function () {
/**
* Pick a subdomain from a list of subdomains based on a the tile location.
*
* @param {number} x: the x tile coordinate.
* @param {number} y: the y tile coordinate.
* @param {list} subdomains: the list of known subdomains.
* @param {number} x The x tile coordinate.
* @param {number} y The y tile coordinate.
* @param {number} z The tile layer.
* @param {string[]} subdomains The list of known subdomains.
* @returns {string} A subdomain based on the location.
*/
function m_getTileSubdomain(x, y, subdomains) {
return subdomains[modulo(x + y, subdomains.length)];
function m_getTileSubdomain(x, y, z, subdomains) {
return subdomains[modulo(x + y + z, subdomains.length)];
}

/**
* Returns an OSM tile server formatting function from a standard format
* string. Replaces {s}, {z}, {x}, and {y}.
* string. Replaces `{s}`, `{z}`, `{x}`, and `{y}`. These may be any case
* and may be prefixed with `$` (e.g., `${X}` is the same as `{x}`). The
* subdomain can be specifed by a string of characters, listed as a range,
* or as a comma-separated list (e.g., `{s:abc}`, `{a-c}`, `{a,b,c}` are
* all equivalent. The comma-separated list can have subdimains that are of
* any length; the string and range both use one-character subdomains.
*
* @param {string} base The tile format string
* @returns: a conversion function.
* @returns {function} A conversion function.
* @private.
*/
function m_tileUrlFromTemplate(base) {
var xPattern = new RegExp(/\$?\{[xX]\}/),
yPattern = new RegExp(/\$?\{[yY]\}/),
zPattern = new RegExp(/\$?\{[zZ]\}/),
sPattern = new RegExp(/\$?\{(s|S|[sS]:[^{}]+|[^-{}]-[^-{}]|([^,{}]+,)+[^,{}]+)\}/);
var url = base
.replace(sPattern, '{s}')
.replace(xPattern, '{x}')
.replace(yPattern, '{y}')
.replace(zPattern, '{z}');
var urlSubdomains;
var sMatch = base.match(sPattern);
if (sMatch) {
if (sMatch[2]) {
urlSubdomains = sMatch[1].split(',');
} else if (sMatch[1][1] === ':') {
urlSubdomains = sMatch[1].substr(2).split('');
} else if (sMatch[1][1] === '-') {
urlSubdomains = [];
var start = sMatch[1].charCodeAt(0),
end = sMatch[1].charCodeAt(2);
for (var i = Math.min(start, end); i <= Math.max(start, end); i += 1) {
urlSubdomains.push(String.fromCharCode(i));
}
}
}

return function (x, y, z, subdomains) {
return base.replace('{s}', m_getTileSubdomain(x, y, subdomains))
.replace('{z}', z)
return url
.replace('{s}', m_getTileSubdomain(x, y, z, urlSubdomains || subdomains))
.replace('{x}', x)
.replace('{y}', y);
.replace('{y}', y)
.replace('{z}', z);
};
}

Expand Down
41 changes: 29 additions & 12 deletions tests/cases/tileLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -648,8 +648,10 @@ describe('geo.tileLayer', function () {
l._getTiles = function (level, bounds) {
expect(level).toBe(1);
expect(bounds).toEqual({
left: 0, right: 1,
bottom: 0, top: 1
left: 0,
right: 1,
bottom: 0,
top: 1
});
return [
{fetch: function () {
Expand Down Expand Up @@ -1325,21 +1327,36 @@ describe('geo.tileLayer', function () {
});
});
it('url templating', function () {
/* eslint-disable no-template-curly-in-string */
var urls = {
's={s}&x={x}&y={y}&z={z}': ['a', 'b', 'c'],
's=${S}&x=${X}&y=${Y}&z=${Z}': ['a', 'b', 'c'],
's={s:abc}&x={x}&y={y}&z={z}': ['a', 'b', 'c'],
's={a,b,c}&x={x}&y={y}&z={z}': ['a', 'b', 'c'],
's={a-c}&x={x}&y={y}&z={z}': ['a', 'b', 'c'],
's={c-a}&x={x}&y={y}&z={z}': ['a', 'b', 'c'],
's=${s:1234}&x={x}&y={y}&z={z}': ['1', '2', '3', '4'],
's=${1,2,3,4}&x={x}&y={y}&z={z}': ['1', '2', '3', '4'],
's=${1-4}&x={x}&y={y}&z={z}': ['1', '2', '3', '4'],
's={ab,bc,12}&x={x}&y={y}&z={z}': ['ab', 'bc', '12']
};
/* eslint-enable no-template-curly-in-string */
var tiles, l = geo.tileLayer({
map: map({unitsPerPixel: 1}),
wrapX: false,
wrapY: false,
topDown: true,
url: '/testdata/white.jpg?s={s}&x={x}&y={y}&z={z}'
topDown: true
});

tiles = l._getTiles(1, {left: 50, right: 500, bottom: 500, top: 50});
expect(tiles.length).toBe(5);
tiles.forEach(function (tile) {
expect($.inArray(tile._url.split('?s=')[1].split('&')[0],
['a', 'b', 'c'])).toBeGreaterThan(-1);
expect(tile._url.split('&x')[1]).toBe('=' + tile.index.x + '&y=' +
tile.index.y + '&z=' + tile.index.level);
$.each(urls, function (url, subdomains) {
l.url('/testdata/white.jpg?' + url);
tiles = l._getTiles(1, {left: 50, right: 500, bottom: 500, top: 50});
expect(tiles.length).toBe(5);
tiles.forEach(function (tile) {
expect($.inArray(tile._url.split('?s=')[1].split('&')[0],
subdomains)).toBeGreaterThan(-1);
expect(tile._url.split('&x')[1]).toBe('=' + tile.index.x + '&y=' +
tile.index.y + '&z=' + tile.index.level);
});
});
});
it('baseUrl', function () {
Expand Down

0 comments on commit a7ecabc

Please sign in to comment.