Force png tile generation for static maps (#808)

* Force png tile generation for static maps

If the user tries to generate a static map requesting JPG it will fail
because is going to try to generate the tiles using JPG as format which
is not supported by now, this bug was introduced in the version 4.0.1

So we now force, again, the tiles to be generated as PNG but we pass
the requested format, JPG, to windshaft to generate the final image as
the user reqests

* Added support to define image format in the image assertions

* Added test for JPEG static image generation

Also I've added support for:

- JPEG images
- Different tolerance based on the file type, it seems that due to
  different compression we need different tolerance for JPG images
remotes/origin/point-grid-bug
Mario de Frutos 7 years ago committed by GitHub
parent f2fa650661
commit 8d16bf566d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,7 +3,8 @@
## 4.3.1
Released 2017-mm-dd
Announcements:
Bug fix:
- Fixed bug introduced in version 4.0.1 that brokes the static map generation using JPG as format
## 4.3.0
Released 2017-12-11

@ -357,7 +357,9 @@ LayergroupController.prototype.center = function(req, res, next) {
LayergroupController.prototype.staticMap = function(req, res, width, height, zoom /* bounds */, center, next) {
var format = req.params.format === 'jpg' ? 'jpeg' : 'png';
req.params.format = req.params.format || 'png';
// We force always the tile to be generated using PNG because
// is the only format we support by now
res.locals.format = 'png';
res.locals.layer = res.locals.layer || 'all';
var self = this;
@ -507,4 +509,4 @@ function validateLayerRouteMiddleware(req, res, next) {
}
next();
}
}

@ -28,7 +28,7 @@ NamedMapsController.prototype.register = function(app) {
userMiddleware,
this.prepareContext,
this.tile.bind(this),
vectorError()
vectorError()
);
app.get(
@ -121,7 +121,9 @@ NamedMapsController.prototype.staticMap = function(req, res, next) {
var cdbUser = res.locals.user;
var format = req.params.format === 'jpg' ? 'jpeg' : 'png';
res.locals.format = req.params.format || 'png';
// We force always the tile to be generated using PNG because
// is the only format we support by now
res.locals.format = 'png';
res.locals.layer = res.locals.layer || 'all';
var namedMapProvider;

@ -19,7 +19,8 @@ describe('named maps static view', function() {
var username = 'localhost';
var templateName = 'template_with_view';
var IMAGE_TOLERANCE = 20;
var PNG_IMAGE_TOLERANCE = 20;
var JPG_IMAGE_TOLERANCE = 100;
function createTemplate(view, layers) {
return {
@ -92,8 +93,8 @@ describe('named maps static view', function() {
});
}
function previewFixture(version) {
return './test/fixtures/previews/populated_places_simple_reduced-' + version + '.png';
function previewFixture(version, format='png') {
return './test/fixtures/previews/populated_places_simple_reduced-' + version + '.' + format;
}
it('should return an image estimating its bounds based on dataset', function (done) {
@ -103,7 +104,7 @@ describe('named maps static view', function() {
}
getStaticMap(function(err, img) {
assert.ok(!err);
assert.imageIsSimilarToFile(img, previewFixture('estimated'), IMAGE_TOLERANCE, done);
assert.imageIsSimilarToFile(img, previewFixture('estimated'), PNG_IMAGE_TOLERANCE, done);
});
});
});
@ -122,7 +123,7 @@ describe('named maps static view', function() {
}
getStaticMap(function(err, img) {
assert.ok(!err);
assert.imageIsSimilarToFile(img, previewFixture('zoom-center'), IMAGE_TOLERANCE, done);
assert.imageIsSimilarToFile(img, previewFixture('zoom-center'), PNG_IMAGE_TOLERANCE, done);
});
});
});
@ -142,7 +143,7 @@ describe('named maps static view', function() {
}
getStaticMap(function(err, img) {
assert.ok(!err);
assert.imageIsSimilarToFile(img, previewFixture('bounds'), IMAGE_TOLERANCE, done);
assert.imageIsSimilarToFile(img, previewFixture('bounds'), PNG_IMAGE_TOLERANCE, done);
});
});
});
@ -167,7 +168,7 @@ describe('named maps static view', function() {
}
getStaticMap(function(err, img) {
assert.ok(!err);
assert.imageIsSimilarToFile(img, previewFixture('zoom-center'), IMAGE_TOLERANCE, done);
assert.imageIsSimilarToFile(img, previewFixture('zoom-center'), PNG_IMAGE_TOLERANCE, done);
});
});
});
@ -192,7 +193,7 @@ describe('named maps static view', function() {
}
getStaticMap({ zoom: 3 }, function(err, img) {
assert.ok(!err);
assert.imageIsSimilarToFile(img, previewFixture('override-zoom'), IMAGE_TOLERANCE, done);
assert.imageIsSimilarToFile(img, previewFixture('override-zoom'), PNG_IMAGE_TOLERANCE, done);
});
});
});
@ -217,7 +218,7 @@ describe('named maps static view', function() {
}
getStaticMap({ bbox: '0,45,90,45' }, function(err, img) {
assert.ok(!err);
assert.imageIsSimilarToFile(img, previewFixture('override-bbox'), IMAGE_TOLERANCE, done);
assert.imageIsSimilarToFile(img, previewFixture('override-bbox'), PNG_IMAGE_TOLERANCE, done);
});
});
});
@ -256,7 +257,27 @@ describe('named maps static view', function() {
}
getStaticMap({ layer: 0 }, function(err, img) {
assert.ok(!err);
assert.imageIsSimilarToFile(img, previewFixture('bounds'), IMAGE_TOLERANCE, done);
assert.imageIsSimilarToFile(img, previewFixture('bounds'), PNG_IMAGE_TOLERANCE, done);
});
});
});
it('should return jpg static map', function (done) {
var view = {
zoom: 4,
center: {
lng: 40,
lat: 20
}
};
templateMaps.addTemplate(username, createTemplate(view), function (err) {
if (err) {
return done(err);
}
getStaticMap({ format: 'jpeg' }, function(err, img) {
assert.ok(!err);
assert.imageIsSimilarToFile(img, previewFixture('zoom-center', 'jpeg'),
JPG_IMAGE_TOLERANCE, done, 'jpeg');
});
});
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

@ -0,0 +1,3 @@
*.jpeg
*.jpg
*.js

@ -37,7 +37,7 @@ assert.imageBuffersAreSimilar = function(bufferA, bufferB, tolerance, callback)
imagesAreSimilar(testImage, referenceImage, tolerance, callback);
};
assert.imageIsSimilarToFile = function(testImage, referenceImageRelativeFilePath, tolerance, callback) {
assert.imageIsSimilarToFile = function(testImage, referenceImageRelativeFilePath, tolerance, callback, format='png') {
callback = callback || function(err) { assert.ifError(err); };
var referenceImageFilePath = path.resolve(referenceImageRelativeFilePath);
@ -46,19 +46,23 @@ assert.imageIsSimilarToFile = function(testImage, referenceImageRelativeFilePath
imagesAreSimilar(testImage, referenceImage, tolerance, function(err) {
if (err) {
var testImageFilePath = randomImagePath();
testImage.save(testImageFilePath);
var testImageFilePath = randomImagePath(format);
testImage.save(testImageFilePath, format);
}
callback(err);
});
}, format);
};
function imagesAreSimilar(testImage, referenceImage, tolerance, callback) {
function imagesAreSimilar(testImage, referenceImage, tolerance, callback, format='png') {
if (testImage.width() !== referenceImage.width() || testImage.height() !== referenceImage.height()) {
return callback(new Error('Images are not the same size'));
}
var pixelsDifference = referenceImage.compare(testImage);
var options = {};
if (format === 'jpeg') {
options.alpha = false;
}
var pixelsDifference = referenceImage.compare(testImage, options);
var similarity = pixelsDifference / (referenceImage.width() * referenceImage.height());
var tolerancePerMil = (tolerance / 1000);
@ -73,8 +77,8 @@ function imagesAreSimilar(testImage, referenceImage, tolerance, callback) {
}
}
function randomImagePath() {
return path.resolve('test/results/png/image-test-' + Date.now() + '.png');
function randomImagePath(format='png') {
return path.resolve('test/results/' + format + '/image-test-' + Date.now() + '.' + format);
}
assert.response = function(server, req, res, callback) {

Loading…
Cancel
Save