Skip to content

Commit

Permalink
Merge pull request #21 from kartotherian/master
Browse files Browse the repository at this point in the history
Fixed bugs for low zooms with tiles exceeding the world's size
  • Loading branch information
flippmoke authored Oct 26, 2016
2 parents a2c5484 + c2797ad commit cb9f527
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 37 deletions.
18 changes: 8 additions & 10 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ var crypto = require('crypto');
module.exports = abaculus;

function abaculus(arg, callback) {
var z = arg.zoom || 1,
var z = arg.zoom || 0,
s = arg.scale || 1,
center = arg.center || null,
bbox = arg.bbox || null,
Expand Down Expand Up @@ -107,15 +107,15 @@ abaculus.tileList = function(z, s, center, tileSize) {
return {
row: Math.floor(obj.row),
column: Math.floor(obj.column),
zoom: Math.floor(obj.zoom)
zoom: obj.zoom
};
}

var maxTilesInRow = Math.pow(2, z);
var tl = floorObj(pointCoordinate({x: 0, y:0}));
var br = floorObj(pointCoordinate(dimensions));
var coords = {};
coords.tiles = [];
var tileCount = (br.column - tl.column + 1) * (br.row - tl.row + 1);

for (var column = tl.column; column <= br.column; column++) {
for (var row = tl.row; row <= br.row; row++) {
Expand All @@ -127,11 +127,10 @@ abaculus.tileList = function(z, s, center, tileSize) {
var p = coordinatePoint(c);

// Wrap tiles with negative coordinates.
c.column = c.column < 0 ?
Math.pow(2,c.zoom) + c.column :
c.column % Math.pow(2,c.zoom);
c.column = c.column % maxTilesInRow;
if (c.column < 0) c.column = maxTilesInRow + c.column;

if (c.row < 0) continue;
if (c.row < 0 || c.row >= maxTilesInRow) continue;
coords.tiles.push({
z: c.zoom,
x: c.column,
Expand All @@ -151,7 +150,6 @@ abaculus.tileList = function(z, s, center, tileSize) {
abaculus.stitchTiles = function(coords, format, quality, getTile, callback) {
if (!coords) return callback(new Error('No coords object.'));
var tileQueue = queue(32);
var dat = [];
var w = coords.dimensions.x,
h = coords.dimensions.y,
s = coords.scale,
Expand All @@ -168,7 +166,7 @@ abaculus.stitchTiles = function(coords, format, quality, getTile, callback) {
y: py,
reencode: true
})
}
};
cb.scale = s;
cb.format = format;
// getTile is a function that returns
Expand All @@ -181,7 +179,7 @@ abaculus.stitchTiles = function(coords, format, quality, getTile, callback) {
if (err) return callback(err);
if (!data) return callback(new Error('No tiles to stitch.'));
var headers = [];
data.forEach(function(d, i) {
data.forEach(function(d) {
headers.push(d.headers);
});

Expand Down
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
{
"name": "abaculus",
"version": "2.0.1",
"version": "2.0.2",
"description": "stitches map tiles together for high-res exporting from tm2",
"main": "index.js",
"contributors": [
"Yuri Astrakhan <[email protected]>"
],
"scripts": {
"test": "mocha -R spec"
},
Expand All @@ -16,6 +19,6 @@
"d3-queue": "^2.0.2"
},
"devDependencies": {
"mocha": "1.x"
"mocha": "2.x"
}
}
134 changes: 109 additions & 25 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,33 @@ var tiles = fs.readdirSync(path.resolve(__dirname + '/fixtures/')).reduce(functi
}, {});

describe('Get center from bbox', function() {
it('should fail if (x1, y1) and (x2,y2) are equal', function(done) {
it('should fail if (x1, y1) and (x2,y2) are equal', function() {
var bbox = [0, 0, 0, 0];

assert.throws( function() {
printer.coordsFromBbox(zoom, scale, bbox, limit);
}, /Incorrect coordinates/);
done();
});
it('should fail if the image is too large', function(done) {
it('should fail if the image is too large', function() {
var bbox = [-60, -60, 60, 60];

assert.throws( function() {
printer.coordsFromBbox(7, 2, bbox, limit);
}, /Desired image is too large./);
done();
});
it('should return the correct coordinates', function(done) {
it('should return the correct coordinates', function() {
var bbox = [-60, -60, 60, 60];

var center = printer.coordsFromBbox(zoom, scale, bbox, limit);
assert.deepEqual(center.w, 10920);
assert.deepEqual(center.h, 13736);
assert.deepEqual(center.x, x);
assert.deepEqual(center.y, y);
done();
});
});

describe('get coordinates from center', function() {
it('should should fail if the image is too large', function(done) {
it('should should fail if the image is too large', function() {
var center = {
x: 0,
y: 0,
Expand All @@ -61,9 +58,8 @@ describe('get coordinates from center', function() {
assert.throws( function() {
printer.coordsFromCenter(zoom, scale, center, limit);
}, /Desired image is too large./);
done();
});
it('should return correct origin coords', function(done) {
it('should return correct origin coords', function() {
var center = {
x: 0,
y: 20,
Expand All @@ -73,28 +69,116 @@ describe('get coordinates from center', function() {
center = printer.coordsFromCenter(zoom, scale, center, limit);
assert.equal(center.x, x);
assert.equal(center.y, 3631);
done();
});
it('should return correct origin coords for negative y', function() {
var zoom = 2,
center = {
x: 39,
y: -14,
w: 1000,
h: 1000
};
center = printer.coordsFromCenter(zoom, scale, center, limit);
assert.equal(center.x, 623);
assert.equal(center.y, 552);
});
});

describe('create list of tile coordinates', function() {
var center = {x: x, y: y, w: 1824, h: 1832 };

var expectedCoords = {
tiles: [
{ z: 5, x: 15, y: 15, px: -112, py: -108 },
{ z: 5, x: 15, y: 16, px: -112, py: 916 },
{ z: 5, x: 16, y: 15, px: 912, py: -108 },
{ z: 5, x: 16, y: 16, px: 912, py: 916 }
],
dimensions: { x: 1824, y: 1832 },
center: { row: 16, column: 16, zoom: 5 },
scale: 4
};
it('should return a tiles object with correct coords', function(done) {
it('should return a tiles object with correct coords', function() {
var zoom = 5,
scale = 4,
width = 1824,
height = 1832,
center = { x: 4096, y: 4096, w: width, h: height };

var expectedCoords = {
tiles: [
{ z: zoom, x: 15, y: 15, px: -112, py: -108 },
{ z: zoom, x: 15, y: 16, px: -112, py: 916 },
{ z: zoom, x: 16, y: 15, px: 912, py: -108 },
{ z: zoom, x: 16, y: 16, px: 912, py: 916 }
],
dimensions: { x: width, y: height },
center: { row: 16, column: 16, zoom: zoom },
scale: scale
};
var coords = printer.tileList(zoom, scale, center);
assert.deepEqual(JSON.stringify(coords), JSON.stringify(expectedCoords));
});

it('should return a tiles object with correct coords when image exceeds y coords', function() {
var zoom = 2,
scale = 1,
width = 1000,
height = 1000,
center = {x: 623, y: 552, w: width, h: height};

var expectedCoords = {
tiles: [
{ z: zoom, x: 0, y: 0, px: -123, py: -52 },
{ z: zoom, x: 0, y: 1, px: -123, py: 204 },
{ z: zoom, x: 0, y: 2, px: -123, py: 460 },
{ z: zoom, x: 0, y: 3, px: -123, py: 716 },
{ z: zoom, x: 1, y: 0, px: 133, py: -52 },
{ z: zoom, x: 1, y: 1, px: 133, py: 204 },
{ z: zoom, x: 1, y: 2, px: 133, py: 460 },
{ z: zoom, x: 1, y: 3, px: 133, py: 716 },
{ z: zoom, x: 2, y: 0, px: 389, py: -52 },
{ z: zoom, x: 2, y: 1, px: 389, py: 204 },
{ z: zoom, x: 2, y: 2, px: 389, py: 460 },
{ z: zoom, x: 2, y: 3, px: 389, py: 716 },
{ z: zoom, x: 3, y: 0, px: 645, py: -52 },
{ z: zoom, x: 3, y: 1, px: 645, py: 204 },
{ z: zoom, x: 3, y: 2, px: 645, py: 460 },
{ z: zoom, x: 3, y: 3, px: 645, py: 716 },
{ z: zoom, x: 0, y: 0, px: 901, py: -52 },
{ z: zoom, x: 0, y: 1, px: 901, py: 204 },
{ z: zoom, x: 0, y: 2, px: 901, py: 460 },
{ z: zoom, x: 0, y: 3, px: 901, py: 716 }
],
dimensions: {x: width, y: height},
center: {row: 2, column: 2, zoom: zoom},
scale: scale
};
var coords = printer.tileList(zoom, scale, center);
assert.deepEqual(JSON.stringify(coords), JSON.stringify(expectedCoords));
});

it('should return a tiles object with correct coords when image is much bigger than world', function() {
var zoom = 1,
scale = 1,
width = 2000,
height = 2100,
center = {x: 100, y: 100, w: width, h: height};

var expectedCoords = {
tiles: [
{z: zoom, x: 0, y: 0, px: -124, py: 950},
{z: zoom, x: 0, y: 1, px: -124, py: 1206},
{z: zoom, x: 1, y: 0, px: 132, py: 950},
{z: zoom, x: 1, y: 1, px: 132, py: 1206},
{z: zoom, x: 0, y: 0, px: 388, py: 950},
{z: zoom, x: 0, y: 1, px: 388, py: 1206},
{z: zoom, x: 1, y: 0, px: 644, py: 950},
{z: zoom, x: 1, y: 1, px: 644, py: 1206},
{z: zoom, x: 0, y: 0, px: 900, py: 950},
{z: zoom, x: 0, y: 1, px: 900, py: 1206},
{z: zoom, x: 1, y: 0, px: 1156, py: 950},
{z: zoom, x: 1, y: 1, px: 1156, py: 1206},
{z: zoom, x: 0, y: 0, px: 1412, py: 950},
{z: zoom, x: 0, y: 1, px: 1412, py: 1206},
{z: zoom, x: 1, y: 0, px: 1668, py: 950},
{z: zoom, x: 1, y: 1, px: 1668, py: 1206},
{z: zoom, x: 0, y: 0, px: 1924, py: 950},
{z: zoom, x: 0, y: 1, px: 1924, py: 1206}
],
dimensions: {x: width, y: height},
center: {row: 0, column: 0, zoom: zoom},
scale: scale
};
var coords = printer.tileList(zoom, scale, center);
assert.deepEqual(JSON.stringify(coords), JSON.stringify(expectedCoords));
done();
});
});

Expand Down

0 comments on commit cb9f527

Please sign in to comment.