Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow arbitrary scales to be specified, e.g. @4.2x (particularly useful for static api and printing) #36

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 39 additions & 7 deletions lib/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ var tessera = require("./index");
debug = debug("tessera");

var FLOAT_PATTERN = "[+-]?(?:\\d+|\\d+\.?\\d+)";
var SCALE_PATTERN = "@[23]x";
var SCALE_PATTERN = "@(?:\\d+|\\d+\.?\\d+)x";

// TODO a more complete implementation of this exists...somewhere
var getExtension = function(format) {
Expand All @@ -33,7 +33,7 @@ var getExtension = function(format) {
};

var getScale = function(scale) {
return (scale || "@1x").slice(1, 2) | 0;
return parseFloat((scale || "@1x").slice(1));
};

var normalizeHeaders = function(headers) {
Expand Down Expand Up @@ -121,18 +121,50 @@ module.exports = function(tilelive, options) {
1: uri
};

[2, 3].forEach(function(scale) {
var retinaURI = clone(uri);
// We cache 100 sourceURIs, randomly evict when over limit
var sourceURIsCacheKeys = [];
var sourceURIsCacheSizeLimit = 100;

var makeScaledSourceURI = function(scale, permanent) {
var retinaURI = clone(uri),
randomIndex;

retinaURI.query.scale = scale;
// explicitly tell tilelive-mapnik to use larger tiles
retinaURI.query.tileSize = scale * 256;

retinaURI.query.tileSize = (scale * 256) | 0;

if (!permanent) {
// Save the URI to the uri cache, but limit its size
while (sourceURIsCacheKeys.length > sourceURIsCacheSizeLimit) {
// Delete random sourceURI
randomIndex = Math.floor(Math.random()*sourceURIsCacheKeys.length);
delete sourceURIs[sourceURIsCacheKeys[randomIndex]];
sourceURIsCacheKeys.splice(randomIndex, 1);
}
sourceURIsCacheKeys.push(scale);
}
sourceURIs[scale] = retinaURI;

return retinaURI;
};

// make scaled source urls for retina @2x and @3x
[2, 3].forEach(function(scale) {
// these are not added to sourceURIsCacheKeys so that they are not ever removed from the cache
makeScaledSourceURI(scale, true);
});

var getSourceURI = function(scale) {
if (scale in sourceURIs) {
return sourceURIs[scale];
} else {
// scaled uri does not exist so we make one
return makeScaledSourceURI(scale);
}
};

var getTile = function(z, x, y, scale, format, callback) {
var sourceURI = sourceURIs[scale],
var sourceURI = getSourceURI(scale),
params = {
tile: {
zoom: z,
Expand Down