diff --git a/CHANGELOG.md b/CHANGELOG.md index e7d8024..8a9d22b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## v0.5.0 + +* Update viewport method to take an optional `allowAntiMeridian` parameter + ## v0.4.0 * Update viewport method to take an optional `allowFloat` parameter to allow float values (h/t @TeaSeaLancs) [#15](https://github.com/mapbox/geo-viewport/pull/15) diff --git a/README.md b/README.md index d4ce4d6..2f638ef 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ console.log(center); ## api -### `viewport(bounds, dimensions, minzoom, maxzoom, tileSize, allowFloat)` +### `viewport(bounds, dimensions, minzoom, maxzoom, tileSize, allowFloat, allowAntiMeridian)` Given a `WSEN` array of bounds and a `[x, y]` array of pixel dimensions, return a `{ center: [lon, lat], zoom: zoom }` viewport. Use `allowFloat` to retain float values in the output. diff --git a/index.js b/index.js index b6dc690..b0393c1 100644 --- a/index.js +++ b/index.js @@ -11,14 +11,16 @@ var smCache = {}; module.exports.viewport = viewport; module.exports.bounds = bounds; -function fetchMerc(tileSize) { +function fetchMerc(tileSize, allowAntiMeridian) { tileSize = tileSize || 256; + antiMeridian = allowAntiMeridian || false; - if (!smCache[tileSize]) { - smCache[tileSize] = new SphericalMercator({ size: tileSize }); + var cacheKey = tileSize + String(antiMeridian); + if (!smCache[cacheKey]) { + smCache[cacheKey] = new SphericalMercator({ size: tileSize, antimeridian: antiMeridian }); } - return smCache[tileSize]; + return smCache[cacheKey]; } function getAdjusted(base, ratios, allowFloat) { @@ -29,10 +31,10 @@ function getAdjusted(base, ratios, allowFloat) { return allowFloat ? adjusted : Math.floor(adjusted); } -function viewport(bounds, dimensions, minzoom, maxzoom, tileSize, allowFloat) { +function viewport(bounds, dimensions, minzoom, maxzoom, tileSize, allowFloat, allowAntiMeridian) { minzoom = (minzoom === undefined) ? 0 : minzoom; maxzoom = (maxzoom === undefined) ? 20 : maxzoom; - var merc = fetchMerc(tileSize); + var merc = fetchMerc(tileSize, allowAntiMeridian); var base = maxzoom; var bl = merc.px([bounds[0], bounds[1]], base); var tr = merc.px([bounds[2], bounds[3]], base); diff --git a/package-lock.json b/package-lock.json index 97f421e..a843ac1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@mapbox/geo-viewport", - "version": "0.4.1", + "version": "0.5.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -332,9 +332,9 @@ "dev": true }, "@mapbox/sphericalmercator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@mapbox/sphericalmercator/-/sphericalmercator-1.1.0.tgz", - "integrity": "sha512-pEsfZyG4OMThlfFQbCte4gegvHUjxXCjz0KZ4Xk8NdOYTQBLflj6U8PL05RPAiuRAMAQNUUKJuL6qYZ5Y4kAWA==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@mapbox/sphericalmercator/-/sphericalmercator-1.2.0.tgz", + "integrity": "sha512-ZTOuuwGuMOJN+HEmG/68bSEw15HHaMWmQ5gdTsWdWsjDe56K1kGvLOK6bOSC8gWgIvEO0w6un/2Gvv1q5hJSkQ==" }, "@tootallnate/once": { "version": "1.1.2", diff --git a/package.json b/package.json index dfe3e0c..96e1127 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,9 @@ "bugs": { "url": "https://github.com/mapbox/geo-viewport/issues" }, - "version": "0.4.1", + "version": "0.5.0", "dependencies": { - "@mapbox/sphericalmercator": "~1.1.0" + "@mapbox/sphericalmercator": "^1.2.0" }, "scripts": { "test": "nyc tap test/*.js", @@ -42,4 +42,4 @@ "index.js" ] } -} \ No newline at end of file +} diff --git a/test/viewport.js b/test/viewport.js index 6ddacdb..7acf519 100644 --- a/test/viewport.js +++ b/test/viewport.js @@ -64,6 +64,20 @@ test('viewport in Southern hemisphere', function(t) { t.end(); }); +test('viewport across the antimeridian', function(t) { + t.ok(areViewportsApproximatelyEqual( + viewport.viewport([175, -43, 190, -43], [300, 200], undefined, undefined, 512, true, false), + { center: [177.5000001490116, -43.00000017011762], zoom: 5.398743777929521 } + )); + + t.ok(areViewportsApproximatelyEqual( + viewport.viewport([175, -43, 190, -43], [300, 200], undefined, undefined, 512, true, true), + { center: [182.50000018626451, -43.00000017011762], zoom: 3.8137812127148685 } + )); + + t.end(); +}); + test('bounds for 512px tiles', function(t) { var bounds = viewport.bounds([-77.036556, 38.897708], 17, [1080, 350], 512); var xMin = bounds[0];