diff --git a/NEWS.md b/NEWS.md index e70b8df2..25008b8f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,9 +1,21 @@ # Changelog -## 4.3.1 +## 4.4.1 Released 2017-mm-dd + +## 4.4.0 +Released 2017-12-12 + Announcements: + - Upgrades camshaft to [0.60.0](https://github.com/CartoDB/camshaft/releases/tag/0.60.0). + + +## 4.3.1 +Released 2017-12-12 + +Bug fix: + - Fixed bug introduced in version 4.0.1 that brokes the static map generation using JPG as format #808 ## 4.3.0 Released 2017-12-11 diff --git a/lib/cartodb/controllers/layergroup.js b/lib/cartodb/controllers/layergroup.js index 43dd9c3a..23c0f6cd 100644 --- a/lib/cartodb/controllers/layergroup.js +++ b/lib/cartodb/controllers/layergroup.js @@ -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(); -} \ No newline at end of file +} diff --git a/lib/cartodb/controllers/named_maps.js b/lib/cartodb/controllers/named_maps.js index a88c8592..cd2d120f 100644 --- a/lib/cartodb/controllers/named_maps.js +++ b/lib/cartodb/controllers/named_maps.js @@ -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; diff --git a/package.json b/package.json index 779b72c7..9c0e4273 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "windshaft-cartodb", - "version": "4.3.1", + "version": "4.4.1", "description": "A map tile server for CartoDB", "keywords": [ "cartodb" @@ -23,7 +23,7 @@ ], "dependencies": { "body-parser": "^1.18.2", - "camshaft": "0.59.4", + "camshaft": "0.60.0", "cartodb-psql": "0.10.2", "cartodb-query-tables": "0.3.0", "cartodb-redis": "0.14.0", diff --git a/test/acceptance/named_maps_static_view.js b/test/acceptance/named_maps_static_view.js index b7af4197..9844c667 100644 --- a/test/acceptance/named_maps_static_view.js +++ b/test/acceptance/named_maps_static_view.js @@ -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'); }); }); }); diff --git a/test/fixtures/previews/populated_places_simple_reduced-zoom-center.jpeg b/test/fixtures/previews/populated_places_simple_reduced-zoom-center.jpeg new file mode 100644 index 00000000..e3f62673 Binary files /dev/null and b/test/fixtures/previews/populated_places_simple_reduced-zoom-center.jpeg differ diff --git a/test/results/jpeg/.gitignore b/test/results/jpeg/.gitignore new file mode 100644 index 00000000..c23ac972 --- /dev/null +++ b/test/results/jpeg/.gitignore @@ -0,0 +1,3 @@ +*.jpeg +*.jpg +*.js diff --git a/test/support/assert.js b/test/support/assert.js index bcb186aa..6815a63f 100644 --- a/test/support/assert.js +++ b/test/support/assert.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) { diff --git a/yarn.lock b/yarn.lock index 9a089a3d..a7aed387 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,7 +10,11 @@ mapnik "~3.5.0" sphericalmercator "1.0.x" -abbrev@1, abbrev@1.0.x: +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +abbrev@1.0.x: version "1.0.9" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" @@ -29,13 +33,13 @@ ajv@^4.9.1: json-stable-stringify "^1.0.1" ajv@^5.1.0: - version "5.2.3" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.3.tgz#c06f598778c44c6b161abafe3466b81ad1814ed2" + version "5.5.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.1.tgz#b38bb8876d9e86bee994956a04e721e88b248eb2" dependencies: co "^4.6.0" fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" - json-stable-stringify "^1.0.1" align-text@^0.1.1, align-text@^0.1.3: version "0.1.4" @@ -211,9 +215,9 @@ camelcase@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" -camshaft@0.59.4: - version "0.59.4" - resolved "https://registry.yarnpkg.com/camshaft/-/camshaft-0.59.4.tgz#7d4d0b8585fa180b5e750206aa84940870ebabfc" +camshaft@0.60.0: + version "0.60.0" + resolved "https://registry.yarnpkg.com/camshaft/-/camshaft-0.60.0.tgz#0433b5a576e08cabbc9bae1e1b22305274b8b7b6" dependencies: async "^1.5.2" bunyan "1.8.1" @@ -520,7 +524,11 @@ domutils@1.5: dom-serializer "0" domelementtype "1" -dot@^1.0.3, dot@~1.0.2: +dot@^1.0.3: + version "1.1.2" + resolved "https://registry.yarnpkg.com/dot/-/dot-1.1.2.tgz#c7377019fc4e550798928b2b9afeb66abfa1f2f9" + +dot@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/dot/-/dot-1.0.3.tgz#f8750bfb6b03c7664eb0e6cb1eb4c66419af9427" @@ -644,14 +652,22 @@ extend@~3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" -extsprintf@1.3.0, extsprintf@^1.2.0: +extsprintf@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + fast-deep-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -776,7 +792,7 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" -glob@7.1.1, glob@^7.1.1: +glob@7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" dependencies: @@ -807,7 +823,7 @@ glob@^6.0.1: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^7.0.5: +glob@^7.0.5, glob@^7.1.1: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" dependencies: @@ -845,8 +861,8 @@ growl@1.9.2: resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" handlebars@^4.0.1: - version "4.0.10" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.10.tgz#3d30c718b09a3d96f23ea4cc1f403c4d3ba9ff4f" + version "4.0.11" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.11.tgz#630a35dfe0294bc281edae6ffc5d329fc7982dcc" dependencies: async "^1.4.0" optimist "^0.6.1" @@ -998,8 +1014,8 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" is-buffer@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" is-builtin-module@^1.0.0: version "1.0.0" @@ -1057,8 +1073,8 @@ istanbul@~0.4.3: wordwrap "^1.0.0" js-base64@^2.1.9: - version "2.3.2" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.3.2.tgz#a79a923666372b580f8e27f51845c6f7e8fbfbaf" + version "2.4.0" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa" js-string-escape@1.0.1: version "1.0.1" @@ -1325,7 +1341,7 @@ mime@~1.3.4: dependencies: brace-expansion "^1.1.7" -minimist@0.0.8, minimist@~0.0.1: +minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" @@ -1333,6 +1349,10 @@ minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + minimist@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.2.0.tgz#4dffe525dae2b864c66c2e23c6271d7afdecefce" @@ -1359,7 +1379,11 @@ mocha@~3.4.1: mkdirp "0.5.1" supports-color "3.1.2" -moment@^2.10.6, moment@~2.18.1: +moment@^2.10.6: + version "2.19.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.19.4.tgz#17e5e2c6ead8819c8ecfad83a0acccb312e94682" + +moment@~2.18.1: version "2.18.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" @@ -1379,11 +1403,7 @@ mv@~2: ncp "~2.0.0" rimraf "~2.4.0" -nan@^2.0.8, nan@^2.3.4, nan@~2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.7.0.tgz#d95bf721ec877e08db276ed3fc6eb78f9083ad46" - -nan@^2.4.0: +nan@^2.0.8, nan@^2.3.4, nan@^2.4.0: version "2.8.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a" @@ -1395,6 +1415,10 @@ nan@~2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.6.2.tgz#e4ff34e6c95fdfb5aecc08de6596f43605a7db45" +nan@~2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.7.0.tgz#d95bf721ec877e08db276ed3fc6eb78f9083ad46" + ncp@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" @@ -1588,6 +1612,10 @@ pg-connection-string@0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7" +pg-int8@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + pg-pool@1.*: version "1.8.0" resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-1.8.0.tgz#f7ec73824c37a03f076f51bfdf70e340147c4f37" @@ -1596,15 +1624,16 @@ pg-pool@1.*: object-assign "4.1.0" pg-types@1.*: - version "1.12.1" - resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-1.12.1.tgz#d64087e3903b58ffaad279e7595c52208a14c3d2" + version "1.13.0" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-1.13.0.tgz#75f490b8a8abf75f1386ef5ec4455ecf6b345c63" dependencies: + pg-int8 "1.0.1" postgres-array "~1.0.0" postgres-bytea "~1.0.0" postgres-date "~1.0.0" postgres-interval "^1.1.0" -pg@cartodb/node-postgres#6.1.6-cdb1: +"pg@github:cartodb/node-postgres#6.1.6-cdb1": version "6.1.6" resolved "https://codeload.github.com/cartodb/node-postgres/tar.gz/3eef52dd1e655f658a4ee8ac5697688b3ecfed44" dependencies: @@ -1920,18 +1949,14 @@ safe-json-stringify@~1: version "1.0.4" resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.0.4.tgz#81a098f447e4bbc3ff3312a243521bc060ef5911" -"semver@2 || 3 || 4 || 5", semver@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" +"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.3.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" semver@4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7" -semver@^5.1.0, semver@^5.3.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" - semver@~4.3.3: version "4.3.6" resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" @@ -1940,6 +1965,10 @@ semver@~5.0.3: version "5.0.3" resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + send@0.16.1: version "0.16.1" resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" @@ -1998,8 +2027,8 @@ sntp@1.x.x: hoek "2.x.x" sntp@2.x.x: - version "2.0.2" - resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.0.2.tgz#5064110f0af85f7cfdb7d6b67a40028ce52b4b2b" + version "2.1.0" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" dependencies: hoek "4.x.x" @@ -2082,7 +2111,11 @@ sshpk@^1.7.0: jsbn "~0.1.0" tweetnacl "~0.14.0" -"statuses@>= 1.3.1 < 2", statuses@~1.3.1: +"statuses@>= 1.3.1 < 2": + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + +statuses@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e"