New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

global-mercator

Package Overview
Dependencies
Maintainers
1
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

global-mercator - npm Package Compare versions

Comparing version 0.4.2 to 1.0.0

.nyc_output/4b9ec107a790c2d0af45b0f25cf5c0d8.json

1

.vscode/settings.json
// Place your settings in this file to overwrite default and user settings.
{
"editor.tabSize": 2,
"typescript.tsdk": "./node_modules/typescript/lib",
"files.exclude": {

@@ -5,0 +6,0 @@ "**/.git": true,

720

index.js
"use strict";
const Debug = require('debug');
const lodash_1 = require('lodash');
exports.debug = {
error: Debug('global-mercator:error'),
log: Debug('global-mercator:log'),
warning: Debug('global-mercator:warning'),
};
exports.tileSize = 256;

@@ -13,117 +6,119 @@ exports.initialResolution = 2 * Math.PI * 6378137 / exports.tileSize;

/**
* Converts {@link LatLng} coordinates to {@link Meters} coordinates.
* Converts {@link LngLat} coordinates to {@link Meters} coordinates.
*
* @name latLngToMeters
* @param {LngLat} lnglat LngLat [lng, lat, zoom]
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} lat Latitude (Parallels) in decimal degrees
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} [zoom] Zoom level
* @returns {Object} Meters coordinates
* @param {number} zoom Zoom level
* @returns {Meters} Meters coordinates
* @example
* latLngToMeters({lat: 37, lng: 126})
* //= Meters { mx: 14026255.83995247, my: 4439106.787250587 }
* const meters = lngLatToMeters([37, 126, 13])
* //=meters
*/
function latLngToMeters(init) {
const { lat, lng, zoom } = new LatLng(init);
function lngLatToMeters(lnglat) {
const [lng, lat, zoom] = lnglat;
let mx = lng * exports.originShift / 180.0;
let my = Math.log(Math.tan((90 + lat) * Math.PI / 360.0)) / (Math.PI / 180.0);
my = my * exports.originShift / 180.0;
return new Meters({ mx: mx, my: my, zoom: zoom });
return [mx, my, zoom];
}
exports.latLngToMeters = latLngToMeters;
exports.lngLatToMeters = lngLatToMeters;
/**
* Converts {@link Meters} coordinates to {@link LatLng} coordinates.
* Converts {@link Meters} coordinates to {@link LngLat} coordinates.
*
* @name metersToLatLng
* @param {number} mx Longitudes (Meridians) in meters
* @param {number} my Latitudes (Parallels) in decimal degrees
* @param {number} [zoom] Zoom level
* @returns {Object} LatLng coordinates
* @param {Meters} meters Meters [x, y, zoom]
* @param {number} x Longitudes (Meridians) in meters
* @param {number} y Latitudes (Parallels) in decimal degrees
* @param {number} zoom Zoom level
* @returns {LngLat} LngLat coordinates
* @example
* metersToLatLng({ mx: 14026255, my: 4439106 })
* //= LatLng { lat: 36.99999435205559, lng: 125.99999245457859 }
* const lnglat = metersToLngLat([14026255, 4439106, 13])
* //=lnglat
*/
function metersToLatLng(init) {
const { mx, my, zoom } = new Meters(init);
function metersToLngLat(meters) {
const [mx, my, zoom] = meters;
let lng = (mx / exports.originShift) * 180.0;
let lat = (my / exports.originShift) * 180.0;
lat = 180 / Math.PI * (2 * Math.atan(Math.exp(lat * Math.PI / 180.0)) - Math.PI / 2.0);
return new LatLng({ lat: lat, lng: lng, zoom: zoom });
return [lng, lat, zoom];
}
exports.metersToLatLng = metersToLatLng;
exports.metersToLngLat = metersToLngLat;
/**
* Converts {@link Meters} coordinates to {@link Pixels} coordinates.
*
* @name metersToPixels
* @param {number} mx Longitudes (Meridians) in meters
* @param {number} my Latitudes (Parallels) in decimal degrees
* @param {Meters} meters Meters [x, y, zoom]
* @param {number} x Longitudes (Meridians) in meters
* @param {number} y Latitudes (Parallels) in decimal degrees
* @param {number} zoom Zoom level
* @returns {Object} Pixels coordinates
* @returns {Pixels} Pixels coordinates
* @example
* metersToPixels({ mx: 14026255, my: 4439106, zoom: 13 })
* //= Pixels { px: 1782579.1560447346, py: 1280877.3387406059, zoom: 13 }
* const pixels = metersToPixels([14026255, 4439106, 13])
* //=pixels
*/
function metersToPixels(init) {
const { mx, my, zoom } = new Meters(init);
function metersToPixels(meters) {
const [mx, my, zoom] = meters;
const res = resolution(zoom);
const px = (mx + exports.originShift) / res;
const py = (my + exports.originShift) / res;
return new Pixels({ px: px, py: py, zoom: zoom });
return [px, py, zoom];
}
exports.metersToPixels = metersToPixels;
/**
* Converts {@link LatLng} coordinates to TMS {@link Tile}.
* Converts {@link LngLat} coordinates to TMS {@link Tile}.
*
* @name latLngToTile
* @param {LngLat} lnglat LngLat [lng, lat, zoom]
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} lat Latitude (Parallels) in decimal degrees
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} zoom Zoom level
* @returns {Object} TMS Tile
* @returns {Tile} TMS Tile
* @example
* latLngToTile({lat: 37, lng: 126, zoom: 13 })
* //= Tile { tx: 6963, ty: 5003, zoom: 13 }
* const tile = lngLatToTile([37, 126, 13])
* //=tile
*/
function latLngToTile(init) {
const meters = latLngToMeters(init);
function lngLatToTile(lnglat) {
const meters = lngLatToMeters(lnglat);
const pixels = metersToPixels(meters);
return pixelsToTile(pixels);
}
exports.latLngToTile = latLngToTile;
exports.lngLatToTile = lngLatToTile;
/**
* Converts {@link LatLng} coordinates to {@link Google} (XYZ) Tile.
* Converts {@link LngLat} coordinates to {@link Google} (XYZ) Tile.
*
* @name latLngToGoogle
* @param {LngLat} lnglat LngLat [lng, lat, zoom]
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} lat Latitude (Parallels) in decimal degrees
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} zoom Zoom level
* @returns {Object} Google (XYZ) Tile
* @returns {Google} Google (XYZ) Tile
* @example
* latLngToGoogle({lat: 37, lng: 126, zoom: 13 })
* //= Google { x: 6963, y: 3188, zoom: 13 }
* const google = lngLatToGoogle({lat: 37, lng: 126, zoom: 13 })
* //=google
*/
function latLngToGoogle(init) {
if (init.zoom === 0) {
return new Google({ x: 0, y: 0, zoom: 0 });
function lngLatToGoogle(lnglat) {
const zoom = lnglat[2];
if (zoom === 0) {
return [0, 0, 0];
}
const tile = latLngToTile(init);
return tileGoogle(tile);
const tile = lngLatToTile(lnglat);
return tileToGoogle(tile);
}
exports.latLngToGoogle = latLngToGoogle;
exports.lngLatToGoogle = lngLatToGoogle;
/**
* Converts {@link Meters} coordinates to TMS {@link Tile}.
*
* @name metersToTile
* @param {number} mx Longitudes (Meridians) in meters
* @param {number} my Latitudes (Parallels) in decimal degrees
* @param {Meters} meters Meters [x, y, zoom]
* @param {number} x Longitudes (Meridians) in meters
* @param {number} y Latitudes (Parallels) in decimal degrees
* @param {number} zoom Zoom level
* @returns {Object} TMS Tile
* @returns {Tile} TMS Tile
* @example
* metersToTile({ mx: 14026255, my: 4439106, zoom: 13 })
* //= Tile { tx: 6963, ty: 5003, zoom: 13 }
* const tile = metersToTile([14026255, 4439106, 13])
* //=tile
*/
function metersToTile(init) {
if (init.zoom === 0) {
return new Tile({ tx: 0, ty: 0, zoom: 0 });
function metersToTile(meters) {
const zoom = meters[2];
if (zoom === 0) {
return [0, 0, 0];
}
const Pixels = metersToPixels(new Meters(init));
return pixelsToTile(Pixels);
const pixels = metersToPixels(meters);
return pixelsToTile(pixels);
}

@@ -134,17 +129,17 @@ exports.metersToTile = metersToTile;

*
* @name pixelsToMeters
* @param {number} px Pixels X
* @param {number} py Pixels Y
* @param {Pixels} pixels Pixels [x, y, zoom]
* @param {number} x Pixels X
* @param {number} y Pixels Y
* @param {number} zoom Zoom level
* @returns {Object} Meters coordinates
* @returns {Meters} Meters coordinates
* @example
* pixelsToMeters({ px: 1782579, py: 1280877, zoom: 13 })
* //= Meters { mx: 14026252.018101055, my: 4439099.526918683, zoom: 13 }
* const meters = pixelsToMeters([1782579, 1280877, 13])
* //=meters
*/
function pixelsToMeters(init) {
const { px, py, zoom } = new Pixels(init);
function pixelsToMeters(pixels) {
const [px, py, zoom] = pixels;
const res = resolution(zoom);
const mx = px * res - exports.originShift;
const my = py * res - exports.originShift;
return new Meters({ mx: mx, my: my, zoom: zoom });
return [mx, my, zoom];
}

@@ -155,16 +150,16 @@ exports.pixelsToMeters = pixelsToMeters;

*
* @name pixelsToTile
* @param {Pixels} pixels Pixels [x, y, zoom]
* @param {number} px Pixels X
* @param {number} py Pixels Y
* @param {number} zoom Zoom level
* @returns {Object} TMS Tile
* @returns {Tile} TMS Tile
* @example
* pixelsToTile({ px: 1782579, py: 1280877, zoom: 13 })
* //= Tile { tx: 6963, ty: 5003, zoom: 13 }
* const tile = pixelsToTile([1782579, 1280877, 13])
* //=tile
*/
function pixelsToTile(init) {
if (init.zoom === 0) {
return new Tile({ tx: 0, ty: 0, zoom: 0 });
function pixelsToTile(pixels) {
const [px, py, zoom] = pixels;
if (zoom === 0) {
return [0, 0, 0];
}
const { px, py, zoom } = new Pixels(init);
let tx = Math.ceil(px / exports.tileSize) - 1;

@@ -178,3 +173,3 @@ let ty = Math.ceil(py / exports.tileSize) - 1;

}
return new Tile({ tx: tx, ty: ty, zoom: zoom });
return [tx, ty, zoom];
}

@@ -185,120 +180,120 @@ exports.pixelsToTile = pixelsToTile;

*
* @name tileBbox
* @param {number} tx TMS Tile X
* @param {number} ty TMS Tile Y
* @param {Tile} tile Tile [x, y, zoom]
* @param {number} x TMS Tile X
* @param {number} y TMS Tile Y
* @param {number} zoom Zoom level
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order
* @example
* tileBbox({ tx: 6963, ty: 5003, zoom: 13 })
* //= [ 14025277.445990417, 4437016.617897913, 14030169.415800672, 4441908.587708164 ]
* const bbox = tileToBBoxMeters([6963, 5003, 13])
* //=bbox
*/
function tileBbox(init) {
const { tx, ty, zoom } = new Tile(init);
let min = pixelsToMeters({ px: tx * exports.tileSize, py: ty * exports.tileSize, zoom: zoom });
let max = pixelsToMeters({ px: (tx + 1) * exports.tileSize, py: (ty + 1) * exports.tileSize, zoom: zoom });
return validateBbox([min.mx, min.my, max.mx, max.my]);
function tileToBBoxMeters(tile) {
const [tx, ty, zoom] = tile;
let min = pixelsToMeters([tx * exports.tileSize, ty * exports.tileSize, zoom]);
let max = pixelsToMeters([(tx + 1) * exports.tileSize, (ty + 1) * exports.tileSize, zoom]);
return [min[0], min[1], max[0], max[1]];
}
exports.tileBbox = tileBbox;
exports.tileToBBoxMeters = tileToBBoxMeters;
/**
* Converts TMS {@link Tile} to {@link bbox} in {@link LatLng} coordinates.
* Converts TMS {@link Tile} to {@link bbox} in {@link LngLat} coordinates.
*
* @name tileLatLngBbox
* @param {number} tx TMS Tile X
* @param {number} ty TMS Tile Y
* @param {Tile} tile Tile [x, y, zoom]
* @param {number} x TMS Tile X
* @param {number} y TMS Tile Y
* @param {number} zoom Zoom level
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order
* @example
* tileLatLngBbox({ tx: 6963, ty: 5003, zoom: 13 })
* //= [ 125.99121093749999, 36.98500309285596, 126.03515625, 37.020098201368135 ]
* const bbox = tileToBBox([6963, 5003, 13])
* //=bbox
*/
function tileLatLngBbox(init) {
if (init.zoom === 0) {
function tileToBBox(tile) {
const [tx, ty, zoom] = tile;
if (zoom === 0) {
return [-180, -85.05112877980659, 180, 85.05112877980659];
}
const { tx, ty, zoom } = new Tile(init);
const [mx1, my1, mx2, my2] = tileBbox({ tx: tx, ty: ty, zoom: zoom });
const min = metersToLatLng({ mx: mx1, my: my1, zoom: zoom });
const max = metersToLatLng({ mx: mx2, my: my2, zoom: zoom });
return validateBbox([min.lng, min.lat, max.lng, max.lat]);
const [mx1, my1, mx2, my2] = tileToBBoxMeters([tx, ty, zoom]);
const min = metersToLngLat([mx1, my1, zoom]);
const max = metersToLngLat([mx2, my2, zoom]);
return [min[0], min[1], max[0], max[1]];
}
exports.tileLatLngBbox = tileLatLngBbox;
exports.tileToBBox = tileToBBox;
/**
* Converts {@link Google} (XYZ) Tile to {@link bbox} in {@link Meters} coordinates.
*
* @name googleBbox
* @param {Google} google Google [x, y, zoom]
* @param {number} x Google (XYZ) Tile X
* @param {number} y Google (XYZ) Tile Y
* @param {number} zoom Zoom level
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order
* @example
* googleBbox({ x: 6963, y: 3188, zoom: 13 })
* //= [ 14025277.445990417, 4437016.617897913, 14030169.415800672, 4441908.587708164 ]
* const bbox = googleToBBoxMeters([6963, 3188, 13])
* //=bbox
*/
function googleBbox(init) {
const Tile = googleTile(init);
return tileBbox(Tile);
function googleToBBoxMeters(google) {
const Tile = googleToTile(google);
return tileToBBoxMeters(Tile);
}
exports.googleBbox = googleBbox;
exports.googleToBBoxMeters = googleToBBoxMeters;
/**
* Converts {@link Google} (XYZ) Tile to {@link bbox} in {@link LatLng} coordinates.
* Converts {@link Google} (XYZ) Tile to {@link bbox} in {@link LngLat} coordinates.
*
* @name googleLatLngBbox
* @param {Google} google Google [x, y, zoom]
* @param {number} x Google (XYZ) Tile X
* @param {number} y Google (XYZ) Tile Y
* @param {number} zoom Zoom level
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order
* @example
* googleLatLngBbox({ x: 6963, y: 3188, zoom: 13 })
* //= [ 125.99121093749999, 36.98500309285596, 126.03515625, 37.020098201368135 ]
* const bbox = googleToBBox([6963, 3188, 13])
* //=bbox
*/
function googleLatLngBbox(init) {
const Tile = googleTile(init);
return tileLatLngBbox(Tile);
function googleToBBox(google) {
const Tile = googleToTile(google);
return tileToBBox(Tile);
}
exports.googleLatLngBbox = googleLatLngBbox;
exports.googleToBBox = googleToBBox;
/**
* Converts TMS {@link Tile} to {@link Google} (XYZ) Tile.
*
* @name tileGoogle
* @param {Tile} tile Tile [x, y, zoom]
* @param {number} tx TMS Tile X
* @param {number} ty TMS Tile Y
* @param {number} zoom Zoom level
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @returns {Google} Google (XYZ) Tile
* @example
* tileGoogle({ tx: 6963, ty: 5003, zoom: 13 })
* //= Google { x: 6963, y: 3188, zoom: 13 }
* const google = tileToGoogle([6963, 5003, 13])
* //=google
*/
function tileGoogle(init) {
if (init.zoom === 0) {
return new Google({ x: 0, y: 0, zoom: 0 });
function tileToGoogle(tile) {
const [tx, ty, zoom] = tile;
if (zoom === 0) {
return [0, 0, 0];
}
const { tx, ty, zoom } = new Tile(init);
const x = tx;
const y = (Math.pow(2, zoom) - 1) - ty;
return new Google({ x: x, y: y, zoom: zoom });
return [x, y, zoom];
}
exports.tileGoogle = tileGoogle;
exports.tileToGoogle = tileToGoogle;
/**
* Converts {@link Google} (XYZ) Tile to TMS {@link Tile}.
*
* @name googleTile
* @param {Google} google Google [x, y, zoom]
* @param {number} x Google (XYZ) Tile X
* @param {number} y Google (XYZ) Tile Y
* @param {number} zoom Zoom level
* @returns {Object} TMS Tile
* @returns {Tile} TMS Tile
* @example
* googleTile({ x: 6963, y: 3188, zoom: 13 })
* //= Tile { tx: 6963, ty: 5003, zoom: 13 }
* const tile = googleToTile([6963, 3188, 13])
* //=tile
*/
function googleTile(init) {
const { x, y, zoom } = new Google(init);
function googleToTile(google) {
const [x, y, zoom] = google;
const tx = x;
const ty = Math.pow(2, zoom) - y - 1;
return new Tile({ tx: tx, ty: ty, zoom: zoom });
return [tx, ty, zoom];
}
exports.googleTile = googleTile;
exports.googleToTile = googleToTile;
/**
* Converts {@link Google} (XYZ) Tile to {@link Quadkey}.
*
* @name googleQuadkey
* @param {Google} google Google [x, y, zoom]
* @param {number} x Google (XYZ) Tile X

@@ -309,14 +304,14 @@ * @param {number} y Google (XYZ) Tile Y

* @example
* googleQuadkey({ x: 6963, y: 3188, zoom: 13 })
* //= '1321102330211'
* const quadkey = googleToQuadkey([6963, 3188, 13])
* //=quadkey
*/
function googleQuadkey(init) {
const Tile = googleTile(init);
return tileQuadkey(Tile);
function googleToQuadkey(google) {
const Tile = googleToTile(google);
return tileToQuadkey(Tile);
}
exports.googleQuadkey = googleQuadkey;
exports.googleToQuadkey = googleToQuadkey;
/**
* Converts TMS {@link Tile} to {@link QuadKey}.
*
* @name tileQuadkey
* @param {Tile} tile Tile [x, y, zoom]
* @param {number} tx TMS Tile X

@@ -327,14 +322,14 @@ * @param {number} ty TMS Tile Y

* @example
* tileQuadkey({ tx: 6963, ty: 5003, zoom: 13 })
* //= '1321102330211'
* const quadkey = tileToQuadkey([6963, 5003, 13])
* //=quadkey
*/
function tileQuadkey(init) {
function tileToQuadkey(tile) {
let [tx, ty, zoom] = tile;
// Zoom 0 does not exist for Quadkey
if (init.zoom === 0) {
if (zoom === 0) {
return '';
}
let { tx, ty, zoom } = new Tile(init);
let quadkey = '';
ty = (Math.pow(2, zoom) - 1) - ty;
lodash_1.range(zoom, 0, -1).map(i => {
range(zoom, 0, -1).map(i => {
let digit = 0;

@@ -352,33 +347,31 @@ let mask = 1 << (i - 1);

}
exports.tileQuadkey = tileQuadkey;
exports.tileToQuadkey = tileToQuadkey;
/**
* Converts {@link Quadkey} to TMS {@link Tile}.
*
* @name quadkeyTile
* @param {string} quadkey Microsoft's Quadkey schema
* @returns {Object} TMS Tile
* @returns {Tile} TMS Tile
* @example
* quadkeyTile('1321102330211')
* //= Tile { tx: 6963, ty: 5003, zoom: 13 }
* const tile = quadkeyToTile('1321102330211')
* //=tile
*/
function quadkeyTile(quadkey) {
const Google = quadkeyGoogle(quadkey);
return googleTile(Google);
function quadkeyToTile(quadkey) {
const Google = quadkeyToGoogle(quadkey);
return googleToTile(Google);
}
exports.quadkeyTile = quadkeyTile;
exports.quadkeyToTile = quadkeyToTile;
/**
* Converts {@link Quadkey} to {@link Google} (XYZ) Tile.
*
* @name quadkeyGoogle
* @param {string} quadkey Microsoft's Quadkey schema
* @returns {Object} Google (XYZ) Tile
* @returns {Google} Google (XYZ) Tile
* @example
* quadkeyGoogle('1321102330211')
* //= Google { x: 6963, y: 3188, zoom: 13 }
* const google = quadkeyToGoogle('1321102330211')
* //=google
*/
function quadkeyGoogle(quadkey) {
function quadkeyToGoogle(quadkey) {
let x = 0;
let y = 0;
const zoom = quadkey.length;
lodash_1.range(zoom, 0, -1).map(i => {
range(zoom, 0, -1).map(i => {
let mask = 1 << (i - 1);

@@ -402,25 +395,24 @@ switch (parseInt(quadkey[zoom - i], 0)) {

});
return new Google({ x: x, y: y, zoom: zoom });
return [x, y, zoom];
}
exports.quadkeyGoogle = quadkeyGoogle;
exports.quadkeyToGoogle = quadkeyToGoogle;
/**
* Converts {@link bbox} from {@link LatLng} coordinates to {@link Meters} coordinates
* Converts {@link BBox} from {@link LngLat} coordinates to {@link Meters} coordinates
*
* @name bboxLatLngToMeters
* @param {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @param {BBox} bbox extent in [minX, minY, maxX, maxY] order
* @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order
* @example
* bboxLatLngToMeters([ 125, 35, 127, 37 ])
* //= [ 13914936.349159198, 4163881.1440642904, 14137575.330745745, 4439106.787250587 ]
* const meters = bboxToMeters([ 125, 35, 127, 37 ])
* //=meters
*/
function bboxLatLngToMeters(bbox) {
const min = latLngToMeters({ lat: bbox[1], lng: bbox[0] });
const max = latLngToMeters({ lat: bbox[3], lng: bbox[2] });
return [min.mx, min.my, max.mx, max.my];
function bboxToMeters(bbox) {
const zoom = 13;
const min = lngLatToMeters([bbox[0], bbox[1], zoom]);
const max = lngLatToMeters([bbox[2], bbox[3], zoom]);
return [min[0], min[1], max[0], max[1]];
}
exports.bboxLatLngToMeters = bboxLatLngToMeters;
exports.bboxToMeters = bboxToMeters;
/**
* Retrieve resolution based on zoom level
*
* @name resolution
* @param {number} zoom zoom level

@@ -433,7 +425,2 @@ * @returns {number} resolution

function resolution(zoom) {
if (lodash_1.isUndefined(zoom)) {
const message = '<zoom> is required';
exports.debug.error(message);
throw new Error(message);
}
return exports.initialResolution / Math.pow(2, zoom);

@@ -445,29 +432,25 @@ }

*
* @name validateTile
* @param {number} tx TMS Tile X
* @param {number} ty TMS Tile Y
* @param {Tile} tile Tile [x, y, zoom]
* @param {number} x TMS Tile X
* @param {number} y TMS Tile Y
* @param {number} zoom Zoom level
* @param {string} [name=Tile] - name used for debugging message
* @throws {Error} Will throw an error if TMS Tile is not valid.
* @returns {Object} TMS Tile
* @returns {Tile} TMS Tile
* @example
* validateTile({tx: 60, ty: 80, zoom: 5})
* //= {tx: 60, ty: 80, zoom: 5}
* validateTile({tx: 60, ty: -43, zoom: 5})
* //= Error: Tile <ty> must not be less than 0
* validateTile([60, 80, 5])
* validateTile([60, -43, 5])
* //= Error: Tile <y> must not be less than 0
*/
function validateTile(init, name = 'Tile') {
const { tx, ty, zoom } = init;
validateZoom(zoom, 'Tile');
function validateTile(tile) {
const [tx, ty, zoom] = tile;
validateZoom(zoom);
if (tx < 0) {
const message = `${name} <tx> must not be less than 0`;
exports.debug.error(message);
const message = '<x> must not be less than 0';
throw new Error(message);
}
else if (ty < 0) {
const message = `${name} <ty> must not be less than 0`;
exports.debug.error(message);
const message = '<y> must not be less than 0';
throw new Error(message);
}
return init;
return tile;
}

@@ -478,3 +461,2 @@ exports.validateTile = validateTile;

*
* @name validateZoom
* @param {number} zoom Zoom level

@@ -485,3 +467,2 @@ * @throws {Error} Will throw an error if zoom is not valid.

* validateZoom(12)
* //= 12
* validateZoom(-4)

@@ -492,11 +473,9 @@ * //= Error: <zoom> cannot be less than 0

*/
function validateZoom(zoom, name) {
function validateZoom(zoom) {
if (zoom < 0) {
const message = (name) ? `${name} <zoom> cannot be less than 0` : '<zoom> cannot be less than 0';
exports.debug.error(message);
const message = '<zoom> cannot be less than 0';
throw new Error(message);
}
else if (zoom > 30) {
const message = (name) ? `${name} <zoom> cannot be greater than 30` : '<zoom> cannot be greater than 30';
exports.debug.error(message);
const message = '<zoom> cannot be greater than 30';
throw new Error(message);

@@ -510,6 +489,8 @@ }

*
* @name validatePixels
* @param {Array<number>} Pixels coordinates
* @param {Pixels} pixels Pixels [x, y, zoom]
* @param {number} x Pixels X
* @param {number} y Pixels Y
* @param {number} [zoom] Zoom level
* @throws {Error} Will throw an error if Pixels is not valid.
* @returns {Array<number>} Pixels coordinates
* @returns {Pixels} Pixels coordinates
* @example

@@ -519,20 +500,4 @@ * validatePixels([-115, 44])

*/
function validatePixels(init) {
if (init.length < 2 || init.length >= 3) {
const message = 'Pixels must be an Array of 2 numbers';
exports.debug.error(message);
throw new Error(message);
}
let [px, py] = init;
if (px % 1 !== 0) {
px = px - px % 1;
const message = `Pixels [px] has been modified to ${px}`;
exports.debug.warning(message);
}
if (py % 1 !== 0) {
py = py - py % 1;
const message = `Pixels [py] has been modified to ${py}`;
exports.debug.warning(message);
}
return [px, py];
function validatePixels(pixels) {
return pixels;
}

@@ -543,6 +508,8 @@ exports.validatePixels = validatePixels;

*
* @name validateMeters
* @param {Array<number>} Meters coordinates
* @param {Meters} meters Meters [x, y, zoom]
* @param {number} x Longitudes (Meridians) in meters
* @param {number} y Latitudes (Parallels) in decimal degrees
* @param {number} [zoom] Zoom level
* @throws {Error} Will throw an error if Meters is not valid.
* @returns {Array<number>} Meters coordinates
* @returns {Meters} Meters coordinates
* @example

@@ -552,59 +519,34 @@ * validateMeters([-115, 44])

*/
function validateMeters(init) {
if (init.length < 2 || init.length >= 3) {
const message = 'Meters must be an Array of 2 numbers';
exports.debug.error(message);
throw new Error(message);
}
function validateMeters(meters) {
let [mx, my] = meters;
const max = 20037508.342789244;
const min = -20037508.342789244;
let [mx, my] = init;
if (my > max) {
const message = `Meters [my] cannot be greater than ${max}`;
exports.debug.error(message);
const message = `Meters [y] cannot be greater than ${max}`;
throw new Error(message);
}
if (my < min) {
const message = `Meters [my] cannot be less than ${min}`;
exports.debug.error(message);
const message = `Meters [y] cannot be less than ${min}`;
throw new Error(message);
}
if (mx > max) {
const message = `Meters [mx] cannot be greater than ${max}`;
exports.debug.error(message);
const message = `Meters [x] cannot be greater than ${max}`;
throw new Error(message);
}
if (mx < min) {
const message = `Meters [mx] cannot be less than ${min}`;
exports.debug.error(message);
const message = `Meters [x] cannot be less than ${min}`;
throw new Error(message);
}
return [mx, my];
return meters;
}
exports.validateMeters = validateMeters;
/**
* Validates {@link LatLng} coordinates.
*
* @name validateLatLng
* @param {Array<number>} LatLng coordinates
* @throws {Error} Will throw an error if LatLng is not valid.
* @returns {Array<number>} LatLng coordinates
* @example
* validateLatLng([60, -125])
* //= [60, -125]
* validateLatLng([140, -125])
* //= Error: LatLng [lat] must be within -90 to 90 degrees
*/
function validateLatLng(init) {
const [lng, lat] = validateLngLat([init[1], init[0]]);
return [lat, lng];
}
exports.validateLatLng = validateLatLng;
/**
* Validates {@link LngLat} coordinates.
*
* @name validateLngLat
* @param {Array<number>} LngLat coordinates
* @param {LngLat} lnglat LngLat [lng, lat, zoom]
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} lat Latitude (Parallels) in decimal degrees
* @param {number} [zoom] Zoom level
* @throws {Error} Will throw an error if LngLat is not valid.
* @returns {Array<number>} LngLat coordinates
* @returns {LngLat} LngLat coordinates
* @example

@@ -614,201 +556,47 @@ * validateLngLat([-115, 44])

* validateLngLat([-225, 44])
* //= Error: LatLng [lng] must be within -180 to 180 degrees
* //= Error: LngLat [lng] must be within -180 to 180 degrees
*/
function validateLngLat(init) {
if (init.length < 2 || init.length >= 3) {
const message = 'LatLng must be an Array of 2 numbers';
exports.debug.error(message);
throw new Error(message);
}
let [lng, lat] = init;
function validateLngLat(lnglat) {
let [lng, lat] = lnglat;
if (lat < -90 || lat > 90) {
const message = 'LatLng [lat] must be within -90 to 90 degrees';
exports.debug.error(message);
const message = 'LngLat [lat] must be within -90 to 90 degrees';
throw new Error(message);
}
else if (lng < -180 || lng > 180) {
const message = 'LatLng [lng] must be within -180 to 180 degrees';
exports.debug.error(message);
const message = 'LngLat [lng] must be within -180 to 180 degrees';
throw new Error(message);
}
if (lat > 85) {
const message = 'LatLng [lat] has been modified to 85';
exports.debug.warning(message);
lat = 85;
}
if (lat < -85) {
const message = 'LatLng [lat] has been modified to -85';
exports.debug.warning(message);
lat = -85;
}
return [lng, lat];
return lnglat;
}
exports.validateLngLat = validateLngLat;
/**
* Validates {@link bbox}.
* Generate an integer Array containing an arithmetic progression.
* A port of the native Python `range()` function.
* See [the Python documentation](http://docs.python.org/library/functions.html#range).
*
* @name validateBbox
* @param {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @throws {Error} Will throw an error if bbox is not valid.
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @param {number} [start=0] Start
* @param {number} stop Stop
* @param {number} [step=1] Step
* @returns {Array<number>} range
* @example
* validateBbox([ -75, 44, -74, 45 ])
* //= [ -75, 44, -74, 45 ]
* validateBbox([ -75, 44, -74 ])
* //= Error: [bbox] must be an Array of 4 numbers
* range(20)
* range(10, 20)
* range(20, 10, -1)
*/
function validateBbox(init) {
if (init.length !== 4) {
const message = '[bbox] must be an Array of 4 numbers';
exports.debug.error(message);
throw new Error(message);
function range(start, stop, step) {
if (stop == null) {
stop = start || 0;
start = 0;
}
return [...init];
}
exports.validateBbox = validateBbox;
/**
* Assert undefined items within object.
*
* @name assertUndefined
* @param {Object} items
* @param {string} [name] - name used for debugging message
* @throws {Error} Will throw an error if any item in Object is undefined.
* @returns {Object} items
* @example
* assertUndefined({foo: 'bar'})
* //= {foo: 'bar'}
* assertUndefined({foo: undefined})
* //= Error: <foo> is required
*/
function assertUndefined(items, name) {
for (let key of lodash_1.keys(items)) {
if (lodash_1.isUndefined(items[key])) {
const message = (name) ? `${name} <${key}> is required` : `<${key}> is required`;
exports.debug.error(message);
throw new Error(message);
}
if (!step) {
step = stop < start ? -1 : 1;
}
return items;
}
exports.assertUndefined = assertUndefined;
/**
* {@link Google} (XYZ) Tile
*
* @class Google
* @property {number} x Google (XYZ) Tile X
* @property {number} y Google (XYZ) Tile Y
* @property {number} zoom Zoom level
*/
class Google {
constructor(init) {
const { x, y, zoom } = init;
this.x = x;
this.y = y;
this.zoom = zoom;
assertUndefined(this, 'Google');
const length = Math.max(Math.ceil((stop - start) / step), 0);
const range = Array(length);
for (let idx = 0; idx < length; idx++, start += step) {
range[idx] = start;
}
return range;
}
exports.Google = Google;
/**
* TMS {@link Tile}
*
* @class Tile
* @property {number} tx TMS Tile X
* @property {number} ty TMS Tile Y
* @property {number} zoom Zoom level
*/
class Tile {
constructor(init) {
const { tx, ty, zoom } = init;
this.tx = tx;
this.ty = ty;
this.zoom = zoom;
assertUndefined(this, 'Tile');
validateTile(this);
}
}
exports.Tile = Tile;
/**
* {@link Pixels} coordinates
*
* @class Pixels
* @property {number} px Pixels X
* @property {number} py Pixels Y
* @property {number} zoom Zoom level
*/
class Pixels {
constructor(init) {
const { px, py, zoom } = init;
this.px = px;
this.py = py;
if (!lodash_1.isUndefined(zoom)) {
this.zoom = zoom;
}
assertUndefined(this, 'Pixels');
validatePixels([px, py]);
}
}
exports.Pixels = Pixels;
/**
* {@link Meters} coordinates
*
* @class Meters
* @property {number} mx Longitudes (Meridians) in meters
* @property {number} my Latitudes (Parallels) in decimal degrees
* @property {number} zoom Zoom level
*/
class Meters {
constructor(init) {
const { mx, my, zoom } = init;
this.mx = mx;
this.my = my;
if (!lodash_1.isUndefined(zoom)) {
this.zoom = zoom;
}
assertUndefined(this, 'Meters');
validateMeters([mx, my]);
}
}
exports.Meters = Meters;
/**
* {@link LatLng} coordinates
*
* @class LatLng
* @property {number} lat Latitude (Parallels) in decimal degrees
* @property {number} lng Longitude (Meridians) in decimal degrees
* @property {number} zoom Zoom level
*/
class LatLng {
constructor(init) {
const { lng, lat } = init;
this.lat = lat;
this.lng = lng;
if (!lodash_1.isUndefined(init.zoom)) {
this.zoom = init.zoom;
}
assertUndefined(this, 'LatLng');
validateLatLng([lat, lng]);
}
}
exports.LatLng = LatLng;
/* istanbul ignore next */
if (require.main === module) {
// const bbox = bboxLatLngToMeters([ -75.01464843750001, 44.99588261816546, -74.97070312499999, 45.02695045318546 ])
// console.log(bbox)
// const meters = pixelsToMeters({ px: 611669, py: 1342753, zoom: 13 })
// console.log(meters)
// console.log(metersToPixels(meters))
// console.log(metersToLatLng(meters))
// gdalwarp -of GTiff -te -8581121.501851652 -1353354.7654779512 -8575634.45283096 -1349909.177990999 lima_imagery.mbtiles lima_imagery.tif
// console.log(validateLatLng([-120, 45, 1]))
// validateMeters([200000, 999150000])
// validateMeters([200000, 150000, 1])
// validatePixels([200000, 150000, 1])
// assertUndefined({x: null})
// console.log(metersToLatLng({mx: 10018754.171394622, my: 5621521.486192067}))
// console.log(metersToPixels({mx: 10000000, my: 5500000, zoom: 13}))
// console.log(metersToPixels({mx: 3000, my: 4000}))
console.log(latLngToMeters({ lat: 23, lng: 23 }));
console.log(validateBbox([-75, 44, -74]));
}
exports.range = range;
//# sourceMappingURL=index.js.map

@@ -1,2 +0,1 @@

import { range, isUndefined, keys } from 'lodash'
export const tileSize = 256

@@ -6,67 +5,65 @@ export const initialResolution = 2 * Math.PI * 6378137 / tileSize

export interface InterfaceMeters {
mx: number
my: number
zoom?: number
}
/**
* LngLat [lng, lat, zoom]
*/
export type LngLat = [number, number, number]
/**
* Meters [x, y, zoom]
*/
export type Meters = [number, number, number]
/**
* Pixels [x, y, zoom]
*/
export type Pixels = [number, number, number]
/**
* BBox extent in [minX, minY, maxX, maxY] order
*/
export type BBox = [number, number, number, number]
/**
* Google [x, y, zoom]
*/
export type Google = [number, number, number]
/**
* Tile [x, y, zoom]
*/
export type Tile = [number, number, number]
/**
* Microsoft's Quadkey schema
*/
export type Quadkey = string
export interface InterfacePixels {
px: number
py: number
zoom: number
}
export interface InterfaceLatLng {
lat: number
lng: number
zoom?: number
z?: number
}
export interface InterfaceGoogle {
x: number
y: number
zoom: number
}
export interface InterfaceTile {
tx: number
ty: number
zoom: number
}
/**
* Converts {@link LatLng} coordinates to {@link Meters} coordinates.
* Converts {@link LngLat} coordinates to {@link Meters} coordinates.
*
* @name latLngToMeters
* @param {LngLat} lnglat LngLat [lng, lat, zoom]
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} lat Latitude (Parallels) in decimal degrees
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} [zoom] Zoom level
* @returns {Object} Meters coordinates
* @param {number} zoom Zoom level
* @returns {Meters} Meters coordinates
* @example
* latLngToMeters({lat: 37, lng: 126})
* //= Meters { mx: 14026255.83995247, my: 4439106.787250587 }
* const meters = lngLatToMeters([37, 126, 13])
* //=meters
*/
export function latLngToMeters(init: InterfaceLatLng) {
const { lat, lng, zoom } = new LatLng(init)
export function lngLatToMeters(lnglat: LngLat): Meters {
const [lng, lat, zoom] = lnglat
let mx: number = lng * originShift / 180.0
let my: number = Math.log(Math.tan((90 + lat) * Math.PI / 360.0 )) / (Math.PI / 180.0)
my = my * originShift / 180.0
return new Meters({ mx, my, zoom })
return [mx, my, zoom]
}
/**
* Converts {@link Meters} coordinates to {@link LatLng} coordinates.
* Converts {@link Meters} coordinates to {@link LngLat} coordinates.
*
* @name metersToLatLng
* @param {number} mx Longitudes (Meridians) in meters
* @param {number} my Latitudes (Parallels) in decimal degrees
* @param {number} [zoom] Zoom level
* @returns {Object} LatLng coordinates
* @param {Meters} meters Meters [x, y, zoom]
* @param {number} x Longitudes (Meridians) in meters
* @param {number} y Latitudes (Parallels) in decimal degrees
* @param {number} zoom Zoom level
* @returns {LngLat} LngLat coordinates
* @example
* metersToLatLng({ mx: 14026255, my: 4439106 })
* //= LatLng { lat: 36.99999435205559, lng: 125.99999245457859 }
* const lnglat = metersToLngLat([14026255, 4439106, 13])
* //=lnglat
*/
export function metersToLatLng(init: InterfaceMeters) {
const { mx, my, zoom } = new Meters(init)
export function metersToLngLat(meters: Meters): LngLat {
const [mx, my, zoom] = meters
let lng = (mx / originShift) * 180.0

@@ -76,3 +73,3 @@ let lat = (my / originShift) * 180.0

return new LatLng({ lat, lng, zoom })
return [lng, lat, zoom]
}

@@ -83,13 +80,13 @@

*
* @name metersToPixels
* @param {number} mx Longitudes (Meridians) in meters
* @param {number} my Latitudes (Parallels) in decimal degrees
* @param {Meters} meters Meters [x, y, zoom]
* @param {number} x Longitudes (Meridians) in meters
* @param {number} y Latitudes (Parallels) in decimal degrees
* @param {number} zoom Zoom level
* @returns {Object} Pixels coordinates
* @returns {Pixels} Pixels coordinates
* @example
* metersToPixels({ mx: 14026255, my: 4439106, zoom: 13 })
* //= Pixels { px: 1782579.1560447346, py: 1280877.3387406059, zoom: 13 }
* const pixels = metersToPixels([14026255, 4439106, 13])
* //=pixels
*/
export function metersToPixels(init: InterfaceMeters) {
const { mx, my, zoom } = new Meters(init)
export function metersToPixels(meters: Meters): Pixels {
const [mx, my, zoom] = meters
const res = resolution(zoom)

@@ -99,19 +96,19 @@ const px = (mx + originShift) / res

return new Pixels({ px, py, zoom })
return [px, py, zoom]
}
/**
* Converts {@link LatLng} coordinates to TMS {@link Tile}.
* Converts {@link LngLat} coordinates to TMS {@link Tile}.
*
* @name latLngToTile
* @param {LngLat} lnglat LngLat [lng, lat, zoom]
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} lat Latitude (Parallels) in decimal degrees
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} zoom Zoom level
* @returns {Object} TMS Tile
* @returns {Tile} TMS Tile
* @example
* latLngToTile({lat: 37, lng: 126, zoom: 13 })
* //= Tile { tx: 6963, ty: 5003, zoom: 13 }
* const tile = lngLatToTile([37, 126, 13])
* //=tile
*/
export function latLngToTile(init: InterfaceLatLng) {
const meters = latLngToMeters(init)
export function lngLatToTile(lnglat: LngLat): Tile {
const meters = lngLatToMeters(lnglat)
const pixels = metersToPixels(meters)

@@ -122,17 +119,18 @@ return pixelsToTile(pixels)

/**
* Converts {@link LatLng} coordinates to {@link Google} (XYZ) Tile.
* Converts {@link LngLat} coordinates to {@link Google} (XYZ) Tile.
*
* @name latLngToGoogle
* @param {LngLat} lnglat LngLat [lng, lat, zoom]
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} lat Latitude (Parallels) in decimal degrees
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} zoom Zoom level
* @returns {Object} Google (XYZ) Tile
* @returns {Google} Google (XYZ) Tile
* @example
* latLngToGoogle({lat: 37, lng: 126, zoom: 13 })
* //= Google { x: 6963, y: 3188, zoom: 13 }
* const google = lngLatToGoogle({lat: 37, lng: 126, zoom: 13 })
* //=google
*/
export function latLngToGoogle(init: InterfaceLatLng) {
if (init.zoom === 0) { return new Google({ x: 0, y: 0, zoom: 0 })}
const tile = latLngToTile(init)
return tileGoogle(tile)
export function lngLatToGoogle(lnglat: LngLat): Google {
const zoom = lnglat[2]
if (zoom === 0) { return [0, 0, 0] }
const tile = lngLatToTile(lnglat)
return tileToGoogle(tile)
}

@@ -143,15 +141,16 @@

*
* @name metersToTile
* @param {number} mx Longitudes (Meridians) in meters
* @param {number} my Latitudes (Parallels) in decimal degrees
* @param {Meters} meters Meters [x, y, zoom]
* @param {number} x Longitudes (Meridians) in meters
* @param {number} y Latitudes (Parallels) in decimal degrees
* @param {number} zoom Zoom level
* @returns {Object} TMS Tile
* @returns {Tile} TMS Tile
* @example
* metersToTile({ mx: 14026255, my: 4439106, zoom: 13 })
* //= Tile { tx: 6963, ty: 5003, zoom: 13 }
* const tile = metersToTile([14026255, 4439106, 13])
* //=tile
*/
export function metersToTile(init: InterfaceMeters) {
if (init.zoom === 0) { return new Tile({ tx: 0, ty: 0, zoom: 0 })}
const Pixels = metersToPixels(new Meters(init))
return pixelsToTile(Pixels)
export function metersToTile(meters: Meters): Tile {
const zoom = meters[2]
if (zoom === 0) { return [0, 0, 0] }
const pixels = metersToPixels(meters)
return pixelsToTile(pixels)
}

@@ -162,13 +161,13 @@

*
* @name pixelsToMeters
* @param {number} px Pixels X
* @param {number} py Pixels Y
* @param {Pixels} pixels Pixels [x, y, zoom]
* @param {number} x Pixels X
* @param {number} y Pixels Y
* @param {number} zoom Zoom level
* @returns {Object} Meters coordinates
* @returns {Meters} Meters coordinates
* @example
* pixelsToMeters({ px: 1782579, py: 1280877, zoom: 13 })
* //= Meters { mx: 14026252.018101055, my: 4439099.526918683, zoom: 13 }
* const meters = pixelsToMeters([1782579, 1280877, 13])
* //=meters
*/
export function pixelsToMeters(init: InterfacePixels) {
const {px, py, zoom} = new Pixels(init)
export function pixelsToMeters(pixels: Pixels): Meters {
const [px, py, zoom] = pixels
const res = resolution(zoom)

@@ -178,3 +177,3 @@ const mx = px * res - originShift

return new Meters({ mx, my, zoom })
return [mx, my, zoom]
}

@@ -185,14 +184,14 @@

*
* @name pixelsToTile
* @param {Pixels} pixels Pixels [x, y, zoom]
* @param {number} px Pixels X
* @param {number} py Pixels Y
* @param {number} zoom Zoom level
* @returns {Object} TMS Tile
* @returns {Tile} TMS Tile
* @example
* pixelsToTile({ px: 1782579, py: 1280877, zoom: 13 })
* //= Tile { tx: 6963, ty: 5003, zoom: 13 }
* const tile = pixelsToTile([1782579, 1280877, 13])
* //=tile
*/
export function pixelsToTile(init: InterfacePixels) {
if (init.zoom === 0) { return new Tile({ tx: 0, ty: 0, zoom: 0 })}
const {px, py, zoom} = new Pixels(init)
export function pixelsToTile(pixels: Pixels): Tile {
const [px, py, zoom] = pixels
if (zoom === 0) { return [0, 0, 0] }
let tx = Math.ceil(px / tileSize) - 1

@@ -202,3 +201,3 @@ let ty = Math.ceil(py / tileSize) - 1

if (ty < 0) { ty = 0 }
return new Tile({ tx, ty, zoom })
return [tx, ty, zoom]
}

@@ -209,40 +208,40 @@

*
* @name tileBbox
* @param {number} tx TMS Tile X
* @param {number} ty TMS Tile Y
* @param {Tile} tile Tile [x, y, zoom]
* @param {number} x TMS Tile X
* @param {number} y TMS Tile Y
* @param {number} zoom Zoom level
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order
* @example
* tileBbox({ tx: 6963, ty: 5003, zoom: 13 })
* //= [ 14025277.445990417, 4437016.617897913, 14030169.415800672, 4441908.587708164 ]
* const bbox = tileToBBoxMeters([6963, 5003, 13])
* //=bbox
*/
export function tileBbox(init: InterfaceTile) {
const {tx, ty, zoom} = new Tile(init)
let min = pixelsToMeters({ px: tx * tileSize, py: ty * tileSize, zoom })
let max = pixelsToMeters({ px: (tx + 1) * tileSize, py: (ty + 1) * tileSize, zoom })
export function tileToBBoxMeters(tile: Tile): BBox {
const [tx, ty, zoom] = tile
let min = pixelsToMeters([tx * tileSize, ty * tileSize, zoom])
let max = pixelsToMeters([(tx + 1) * tileSize, (ty + 1) * tileSize, zoom])
return validateBbox([ min.mx, min.my, max.mx, max.my ])
return [min[0], min[1], max[0], max[1]]
}
/**
* Converts TMS {@link Tile} to {@link bbox} in {@link LatLng} coordinates.
* Converts TMS {@link Tile} to {@link bbox} in {@link LngLat} coordinates.
*
* @name tileLatLngBbox
* @param {number} tx TMS Tile X
* @param {number} ty TMS Tile Y
* @param {Tile} tile Tile [x, y, zoom]
* @param {number} x TMS Tile X
* @param {number} y TMS Tile Y
* @param {number} zoom Zoom level
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order
* @example
* tileLatLngBbox({ tx: 6963, ty: 5003, zoom: 13 })
* //= [ 125.99121093749999, 36.98500309285596, 126.03515625, 37.020098201368135 ]
* const bbox = tileToBBox([6963, 5003, 13])
* //=bbox
*/
export function tileLatLngBbox(init: InterfaceTile) {
if (init.zoom === 0) { return [ -180, -85.05112877980659, 180, 85.05112877980659 ] }
export function tileToBBox(tile: Tile): BBox {
const [tx, ty, zoom] = tile
if (zoom === 0) { return [ -180, -85.05112877980659, 180, 85.05112877980659 ] }
const {tx, ty, zoom} = new Tile(init)
const [mx1, my1, mx2, my2] = tileBbox({ tx, ty, zoom })
const min = metersToLatLng({ mx: mx1, my: my1, zoom })
const max = metersToLatLng({ mx: mx2, my: my2, zoom })
const [mx1, my1, mx2, my2] = tileToBBoxMeters([tx, ty, zoom])
const min = metersToLngLat([mx1, my1, zoom])
const max = metersToLngLat([mx2, my2, zoom])
return validateBbox([ min.lng, min.lat, max.lng, max.lat ])
return [min[0], min[1], max[0], max[1]]
}

@@ -253,31 +252,31 @@

*
* @name googleBbox
* @param {Google} google Google [x, y, zoom]
* @param {number} x Google (XYZ) Tile X
* @param {number} y Google (XYZ) Tile Y
* @param {number} zoom Zoom level
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order
* @example
* googleBbox({ x: 6963, y: 3188, zoom: 13 })
* //= [ 14025277.445990417, 4437016.617897913, 14030169.415800672, 4441908.587708164 ]
* const bbox = googleToBBoxMeters([6963, 3188, 13])
* //=bbox
*/
export function googleBbox(init: InterfaceGoogle) {
const Tile = googleTile(init)
return tileBbox(Tile)
export function googleToBBoxMeters(google: Google): BBox {
const Tile = googleToTile(google)
return tileToBBoxMeters(Tile)
}
/**
* Converts {@link Google} (XYZ) Tile to {@link bbox} in {@link LatLng} coordinates.
* Converts {@link Google} (XYZ) Tile to {@link bbox} in {@link LngLat} coordinates.
*
* @name googleLatLngBbox
* @param {Google} google Google [x, y, zoom]
* @param {number} x Google (XYZ) Tile X
* @param {number} y Google (XYZ) Tile Y
* @param {number} zoom Zoom level
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order
* @example
* googleLatLngBbox({ x: 6963, y: 3188, zoom: 13 })
* //= [ 125.99121093749999, 36.98500309285596, 126.03515625, 37.020098201368135 ]
* const bbox = googleToBBox([6963, 3188, 13])
* //=bbox
*/
export function googleLatLngBbox(init: InterfaceGoogle) {
const Tile = googleTile(init)
return tileLatLngBbox(Tile)
export function googleToBBox(google: Google): BBox {
const Tile = googleToTile(google)
return tileToBBox(Tile)
}

@@ -288,19 +287,19 @@

*
* @name tileGoogle
* @param {Tile} tile Tile [x, y, zoom]
* @param {number} tx TMS Tile X
* @param {number} ty TMS Tile Y
* @param {number} zoom Zoom level
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @returns {Google} Google (XYZ) Tile
* @example
* tileGoogle({ tx: 6963, ty: 5003, zoom: 13 })
* //= Google { x: 6963, y: 3188, zoom: 13 }
* const google = tileToGoogle([6963, 5003, 13])
* //=google
*/
export function tileGoogle(init: InterfaceTile) {
if (init.zoom === 0) { return new Google({ x: 0, y: 0, zoom: 0 })}
export function tileToGoogle(tile: Tile): Google {
const [tx, ty, zoom] = tile
if (zoom === 0) { return [0, 0, 0] }
const { tx, ty, zoom } = new Tile(init)
const x = tx
const y = (Math.pow(2, zoom) - 1) - ty
return new Google({ x, y, zoom })
return [x, y, zoom]
}

@@ -311,17 +310,17 @@

*
* @name googleTile
* @param {Google} google Google [x, y, zoom]
* @param {number} x Google (XYZ) Tile X
* @param {number} y Google (XYZ) Tile Y
* @param {number} zoom Zoom level
* @returns {Object} TMS Tile
* @returns {Tile} TMS Tile
* @example
* googleTile({ x: 6963, y: 3188, zoom: 13 })
* //= Tile { tx: 6963, ty: 5003, zoom: 13 }
* const tile = googleToTile([6963, 3188, 13])
* //=tile
*/
export function googleTile(init: InterfaceGoogle) {
const { x, y, zoom } = new Google(init)
export function googleToTile(google: Google): Tile {
const [x, y, zoom] = google
const tx = x
const ty = Math.pow(2, zoom) - y - 1
return new Tile({ tx, ty, zoom })
return [tx, ty, zoom]
}

@@ -332,3 +331,3 @@

*
* @name googleQuadkey
* @param {Google} google Google [x, y, zoom]
* @param {number} x Google (XYZ) Tile X

@@ -339,8 +338,8 @@ * @param {number} y Google (XYZ) Tile Y

* @example
* googleQuadkey({ x: 6963, y: 3188, zoom: 13 })
* //= '1321102330211'
* const quadkey = googleToQuadkey([6963, 3188, 13])
* //=quadkey
*/
export function googleQuadkey(init: InterfaceGoogle) {
const Tile = googleTile(init)
return tileQuadkey(Tile)
export function googleToQuadkey(google: Google): string {
const Tile = googleToTile(google)
return tileToQuadkey(Tile)
}

@@ -351,3 +350,3 @@

*
* @name tileQuadkey
* @param {Tile} tile Tile [x, y, zoom]
* @param {number} tx TMS Tile X

@@ -358,10 +357,10 @@ * @param {number} ty TMS Tile Y

* @example
* tileQuadkey({ tx: 6963, ty: 5003, zoom: 13 })
* //= '1321102330211'
* const quadkey = tileToQuadkey([6963, 5003, 13])
* //=quadkey
*/
export function tileQuadkey(init: InterfaceTile) {
export function tileToQuadkey(tile: Tile): string {
let [tx, ty, zoom] = tile
// Zoom 0 does not exist for Quadkey
if (init.zoom === 0) { return '' }
if (zoom === 0) { return '' }
let { tx, ty, zoom } = new Tile(init)
let quadkey = ''

@@ -384,12 +383,11 @@

*
* @name quadkeyTile
* @param {string} quadkey Microsoft's Quadkey schema
* @returns {Object} TMS Tile
* @returns {Tile} TMS Tile
* @example
* quadkeyTile('1321102330211')
* //= Tile { tx: 6963, ty: 5003, zoom: 13 }
* const tile = quadkeyToTile('1321102330211')
* //=tile
*/
export function quadkeyTile(quadkey: string) {
const Google = quadkeyGoogle(quadkey)
return googleTile(Google)
export function quadkeyToTile(quadkey: string): Tile {
const Google = quadkeyToGoogle(quadkey)
return googleToTile(Google)
}

@@ -400,10 +398,9 @@

*
* @name quadkeyGoogle
* @param {string} quadkey Microsoft's Quadkey schema
* @returns {Object} Google (XYZ) Tile
* @returns {Google} Google (XYZ) Tile
* @example
* quadkeyGoogle('1321102330211')
* //= Google { x: 6963, y: 3188, zoom: 13 }
* const google = quadkeyToGoogle('1321102330211')
* //=google
*/
export function quadkeyGoogle(quadkey: string) {
export function quadkeyToGoogle(quadkey: string): Google {
let x: number = 0

@@ -433,19 +430,19 @@ let y: number = 0

})
return new Google({ x, y, zoom })
return [x, y, zoom]
}
/**
* Converts {@link bbox} from {@link LatLng} coordinates to {@link Meters} coordinates
* Converts {@link BBox} from {@link LngLat} coordinates to {@link Meters} coordinates
*
* @name bboxLatLngToMeters
* @param {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @param {BBox} bbox extent in [minX, minY, maxX, maxY] order
* @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order
* @example
* bboxLatLngToMeters([ 125, 35, 127, 37 ])
* //= [ 13914936.349159198, 4163881.1440642904, 14137575.330745745, 4439106.787250587 ]
* const meters = bboxToMeters([ 125, 35, 127, 37 ])
* //=meters
*/
export function bboxLatLngToMeters(bbox: number[]): number[] {
const min = latLngToMeters({lat: bbox[1], lng: bbox[0]})
const max = latLngToMeters({lat: bbox[3], lng: bbox[2]})
return [min.mx, min.my, max.mx, max.my]
export function bboxToMeters(bbox: BBox): BBox {
const zoom = 13
const min = lngLatToMeters([bbox[0], bbox[1], zoom])
const max = lngLatToMeters([bbox[2], bbox[3], zoom])
return [min[0], min[1], max[0], max[1]]
}

@@ -456,3 +453,2 @@

*
* @name resolution
* @param {number} zoom zoom level

@@ -464,7 +460,3 @@ * @returns {number} resolution

*/
export function resolution(zoom: number) {
if (isUndefined(zoom)) {
const message = '<zoom> is required'
throw new Error(message)
}
export function resolution(zoom: number): number {
return initialResolution / Math.pow(2, zoom)

@@ -476,26 +468,24 @@ }

*
* @name validateTile
* @param {number} tx TMS Tile X
* @param {number} ty TMS Tile Y
* @param {Tile} tile Tile [x, y, zoom]
* @param {number} x TMS Tile X
* @param {number} y TMS Tile Y
* @param {number} zoom Zoom level
* @param {string} [name=Tile] - name used for debugging message
* @throws {Error} Will throw an error if TMS Tile is not valid.
* @returns {Object} TMS Tile
* @returns {Tile} TMS Tile
* @example
* validateTile({tx: 60, ty: 80, zoom: 5})
* //= {tx: 60, ty: 80, zoom: 5}
* validateTile({tx: 60, ty: -43, zoom: 5})
* //= Error: Tile <ty> must not be less than 0
* validateTile([60, 80, 5])
* validateTile([60, -43, 5])
* //= Error: Tile <y> must not be less than 0
*/
export function validateTile(init: InterfaceTile, name = 'Tile') {
const { tx, ty, zoom } = init
validateZoom(zoom, 'Tile')
export function validateTile(tile: Tile): Tile {
const [tx, ty, zoom] = tile
validateZoom(zoom)
if (tx < 0) {
const message = `${ name } <tx> must not be less than 0`
const message = '<x> must not be less than 0'
throw new Error(message)
} else if (ty < 0) {
const message = `${ name } <ty> must not be less than 0`
const message = '<y> must not be less than 0'
throw new Error(message)
}
return init
return tile
}

@@ -506,3 +496,2 @@

*
* @name validateZoom
* @param {number} zoom Zoom level

@@ -513,3 +502,2 @@ * @throws {Error} Will throw an error if zoom is not valid.

* validateZoom(12)
* //= 12
* validateZoom(-4)

@@ -520,8 +508,8 @@ * //= Error: <zoom> cannot be less than 0

*/
export function validateZoom(zoom: number, name?: string) {
export function validateZoom(zoom: number) {
if (zoom < 0) {
const message = (name) ? `${ name } <zoom> cannot be less than 0` : '<zoom> cannot be less than 0'
const message = '<zoom> cannot be less than 0'
throw new Error(message)
} else if (zoom > 30) {
const message = (name) ? `${ name } <zoom> cannot be greater than 30` : '<zoom> cannot be greater than 30'
const message = '<zoom> cannot be greater than 30'
throw new Error(message)

@@ -535,6 +523,8 @@ }

*
* @name validatePixels
* @param {Array<number>} Pixels coordinates
* @param {Pixels} pixels Pixels [x, y, zoom]
* @param {number} x Pixels X
* @param {number} y Pixels Y
* @param {number} [zoom] Zoom level
* @throws {Error} Will throw an error if Pixels is not valid.
* @returns {Array<number>} Pixels coordinates
* @returns {Pixels} Pixels coordinates
* @example

@@ -544,15 +534,4 @@ * validatePixels([-115, 44])

*/
export function validatePixels(init: number[]) {
if (init.length < 2 || init.length >= 3) {
const message = 'Pixels must be an Array of 2 numbers'
throw new Error(message)
}
let [px, py] = init
if (px % 1 !== 0) {
px = px - px % 1
}
if (py % 1 !== 0) {
py = py - py % 1
}
return [px, py]
export function validatePixels(pixels: Pixels): Pixels {
return pixels
}

@@ -563,6 +542,8 @@

*
* @name validateMeters
* @param {Array<number>} Meters coordinates
* @param {Meters} meters Meters [x, y, zoom]
* @param {number} x Longitudes (Meridians) in meters
* @param {number} y Latitudes (Parallels) in decimal degrees
* @param {number} [zoom] Zoom level
* @throws {Error} Will throw an error if Meters is not valid.
* @returns {Array<number>} Meters coordinates
* @returns {Meters} Meters coordinates
* @example

@@ -572,54 +553,34 @@ * validateMeters([-115, 44])

*/
export function validateMeters(init: number[]) {
if (init.length < 2 || init.length >= 3) {
const message = 'Meters must be an Array of 2 numbers'
throw new Error(message)
}
export function validateMeters(meters: Meters): Meters {
let [mx, my] = meters
const max = 20037508.342789244
const min = -20037508.342789244
let [mx, my] = init
if (my > max) {
const message = `Meters [my] cannot be greater than ${ max }`
const message = `Meters [y] cannot be greater than ${ max }`
throw new Error(message)
}
if (my < min) {
const message = `Meters [my] cannot be less than ${ min }`
const message = `Meters [y] cannot be less than ${ min }`
throw new Error(message)
}
if (mx > max) {
const message = `Meters [mx] cannot be greater than ${ max }`
const message = `Meters [x] cannot be greater than ${ max }`
throw new Error(message)
}
if (mx < min) {
const message = `Meters [mx] cannot be less than ${ min }`
const message = `Meters [x] cannot be less than ${ min }`
throw new Error(message)
}
return [mx, my]
return meters
}
/**
* Validates {@link LatLng} coordinates.
*
* @name validateLatLng
* @param {Array<number>} LatLng coordinates
* @throws {Error} Will throw an error if LatLng is not valid.
* @returns {Array<number>} LatLng coordinates
* @example
* validateLatLng([60, -125])
* //= [60, -125]
* validateLatLng([140, -125])
* //= Error: LatLng [lat] must be within -90 to 90 degrees
*/
export function validateLatLng(init: number[]) {
const [lng, lat] = validateLngLat([init[1], init[0]])
return [lat, lng]
}
/**
* Validates {@link LngLat} coordinates.
*
* @name validateLngLat
* @param {Array<number>} LngLat coordinates
* @param {LngLat} lnglat LngLat [lng, lat, zoom]
* @param {number} lng Longitude (Meridians) in decimal degrees
* @param {number} lat Latitude (Parallels) in decimal degrees
* @param {number} [zoom] Zoom level
* @throws {Error} Will throw an error if LngLat is not valid.
* @returns {Array<number>} LngLat coordinates
* @returns {LngLat} LngLat coordinates
* @example

@@ -629,184 +590,46 @@ * validateLngLat([-115, 44])

* validateLngLat([-225, 44])
* //= Error: LatLng [lng] must be within -180 to 180 degrees
* //= Error: LngLat [lng] must be within -180 to 180 degrees
*/
export function validateLngLat(init: number[]) {
if (init.length < 2 || init.length >= 3) {
const message = 'LatLng must be an Array of 2 numbers'
throw new Error(message)
}
let [lng, lat] = init
export function validateLngLat(lnglat: LngLat): LngLat {
let [lng, lat] = lnglat
if (lat < -90 || lat > 90) {
const message = 'LatLng [lat] must be within -90 to 90 degrees'
const message = 'LngLat [lat] must be within -90 to 90 degrees'
throw new Error(message)
} else if (lng < -180 || lng > 180) {
const message = 'LatLng [lng] must be within -180 to 180 degrees'
const message = 'LngLat [lng] must be within -180 to 180 degrees'
throw new Error(message)
}
if (lat > 85) {
lat = 85
}
if (lat < -85) {
lat = -85
}
return [lng, lat]
return lnglat
}
/**
* Validates {@link bbox}.
* Generate an integer Array containing an arithmetic progression.
* A port of the native Python `range()` function.
* See [the Python documentation](http://docs.python.org/library/functions.html#range).
*
* @name validateBbox
* @param {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @throws {Error} Will throw an error if bbox is not valid.
* @returns {Array<number>} bbox extent in [minX, minY, maxX, maxY] order
* @param {number} [start=0] Start
* @param {number} stop Stop
* @param {number} [step=1] Step
* @returns {Array<number>} range
* @example
* validateBbox([ -75, 44, -74, 45 ])
* //= [ -75, 44, -74, 45 ]
* validateBbox([ -75, 44, -74 ])
* //= Error: [bbox] must be an Array of 4 numbers
* range(20)
* range(10, 20)
* range(20, 10, -1)
*/
export function validateBbox(init: number[]) {
if (init.length !== 4) {
const message = '[bbox] must be an Array of 4 numbers'
throw new Error(message)
export function range(start: number, stop?: number, step?: number) {
if (stop == null) {
stop = start || 0
start = 0
}
return [...init]
}
/**
* Assert undefined items within object.
*
* @name assertUndefined
* @param {Object} items
* @param {string} [name] - name used for debugging message
* @throws {Error} Will throw an error if any item in Object is undefined.
* @returns {Object} items
* @example
* assertUndefined({foo: 'bar'})
* //= {foo: 'bar'}
* assertUndefined({foo: undefined})
* //= Error: <foo> is required
*/
export function assertUndefined(items: any, name?: string) {
for (let key of keys(items)) {
if (isUndefined(items[key])) {
const message = (name) ? `${ name } <${ key }> is required` : `<${ key }> is required`
throw new Error(message)
}
if (!step) {
step = stop < start ? -1 : 1
}
return items
}
/**
* {@link Google} (XYZ) Tile
*
* @class Google
* @property {number} x Google (XYZ) Tile X
* @property {number} y Google (XYZ) Tile Y
* @property {number} zoom Zoom level
*/
export class Google {
public x: number
public y: number
public zoom: number
public z: number
const length = Math.max(Math.ceil((stop - start) / step), 0)
const range = Array(length)
constructor(init: InterfaceGoogle) {
const {x, y, zoom} = init
this.x = x
this.y = y
this.zoom = zoom
assertUndefined(this, 'Google')
for (let idx = 0; idx < length; idx++, start += step) {
range[idx] = start
}
return range
}
/**
* TMS {@link Tile}
*
* @class Tile
* @property {number} tx TMS Tile X
* @property {number} ty TMS Tile Y
* @property {number} zoom Zoom level
*/
export class Tile {
public tx: number
public ty: number
public zoom: number
constructor(init: InterfaceTile) {
const {tx, ty, zoom} = init
this.tx = tx
this.ty = ty
this.zoom = zoom
assertUndefined(this, 'Tile')
validateTile(this)
}
}
/**
* {@link Pixels} coordinates
*
* @class Pixels
* @property {number} px Pixels X
* @property {number} py Pixels Y
* @property {number} zoom Zoom level
*/
export class Pixels {
public px: number
public py: number
public zoom: number
constructor(init: InterfacePixels) {
const {px, py, zoom} = init
this.px = px
this.py = py
if (!isUndefined(zoom)) { this.zoom = zoom }
assertUndefined(this, 'Pixels')
validatePixels([px, py])
}
}
/**
* {@link Meters} coordinates
*
* @class Meters
* @property {number} mx Longitudes (Meridians) in meters
* @property {number} my Latitudes (Parallels) in decimal degrees
* @property {number} zoom Zoom level
*/
export class Meters {
public mx: number
public my: number
public zoom: number
constructor(init: InterfaceMeters) {
const {mx, my, zoom} = init
this.mx = mx
this.my = my
if (!isUndefined(zoom)) { this.zoom = zoom }
assertUndefined(this, 'Meters')
validateMeters([mx, my])
}
}
/**
* {@link LatLng} coordinates
*
* @class LatLng
* @property {number} lat Latitude (Parallels) in decimal degrees
* @property {number} lng Longitude (Meridians) in decimal degrees
* @property {number} zoom Zoom level
*/
export class LatLng {
public lat: number
public lng: number
public zoom: number
constructor(init: InterfaceLatLng) {
const {lng, lat} = init
this.lat = lat
this.lng = lng
if (!isUndefined(init.zoom)) { this.zoom = init.zoom }
assertUndefined(this, 'LatLng')
validateLatLng([lat, lng])
}
}
{
"name": "global-mercator",
"version": "0.4.2",
"version": "1.0.0",
"description": "Global Mercator",

@@ -8,9 +8,10 @@ "main": "index.js",

"docs": "npm run build && npm run documentation",
"documentation": "cat HEADER.md > README.md && documentation build index.js -c documentation.yml -f md >> README.md",
"documentation": "cat HEADER.md > README.md && ./node_modules/documentation/bin/documentation.js build index.js -c documentation.yml -f md >> README.md",
"typings": "./node_modules/typings/dist/bin.js install",
"test": "npm run build && npm run ava && npm run lint",
"test": "npm run es6 && npm run ava && npm run lint",
"es6": "./node_modules/typescript/bin/tsc --target 'es6'",
"build": "./node_modules/typescript/bin/tsc",
"ava": "./node_modules/nyc/bin/nyc.js ./node_modules/ava/cli.js",
"coverage": "./node_modules/nyc/bin/nyc.js ./node_modules/ava/cli.js",
"lint": "./node_modules/tslint/bin/tslint index.ts test.ts",
"lint": "npm run build && ./node_modules/tslint/bin/tslint index.ts test.ts && ./node_modules/documentation/bin/documentation.js lint index.js",
"patch": "npm version patch && npm publish"

@@ -31,6 +32,2 @@ },

"homepage": "https://github.com/DenisCarriere/global-mercator#readme",
"dependencies": {
"lodash": "^4.16.1",
"@types/lodash": "^4.14.36"
},
"devDependencies": {

@@ -37,0 +34,0 @@ "ava": "^0.16.0",

@@ -28,11 +28,12 @@ [![Build Status](https://travis-ci.org/DenisCarriere/global-mercator.svg?branch=master)](https://travis-ci.org/DenisCarriere/global-mercator)

# latLngToMeters
# lngLatToMeters
Converts [LatLng](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates to [Meters](https://en.wikipedia.org/wiki/Web_Mercator) coordinates.
Converts [LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates to [Meters](https://en.wikipedia.org/wiki/Web_Mercator) coordinates.
**Parameters**
- `lnglat` **[LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System)** LngLat [lng, lat, zoom]
- `lng` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitude (Meridians) in decimal degrees
- `lat` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitude (Parallels) in decimal degrees
- `lng` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitude (Meridians) in decimal degrees
- `zoom` **\[[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)]** Zoom level
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level

@@ -42,17 +43,18 @@ **Examples**

```javascript
latLngToMeters({lat: 37, lng: 126})
//= Meters { mx: 14026255.83995247, my: 4439106.787250587 }
const meters = lngLatToMeters([37, 126, 13])
//=meters
```
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Meters coordinates
Returns **[Meters](https://en.wikipedia.org/wiki/Web_Mercator)** Meters coordinates
# metersToLatLng
# metersToLngLat
Converts [Meters](https://en.wikipedia.org/wiki/Web_Mercator) coordinates to [LatLng](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates.
Converts [Meters](https://en.wikipedia.org/wiki/Web_Mercator) coordinates to [LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates.
**Parameters**
- `mx` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitudes (Meridians) in meters
- `my` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitudes (Parallels) in decimal degrees
- `zoom` **\[[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)]** Zoom level
- `meters` **[Meters](https://en.wikipedia.org/wiki/Web_Mercator)** Meters [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitudes (Meridians) in meters
- `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitudes (Parallels) in decimal degrees
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level

@@ -62,7 +64,7 @@ **Examples**

```javascript
metersToLatLng({ mx: 14026255, my: 4439106 })
//= LatLng { lat: 36.99999435205559, lng: 125.99999245457859 }
const lnglat = metersToLngLat([14026255, 4439106, 13])
//=lnglat
```
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** LatLng coordinates
Returns **[LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System)** LngLat coordinates

@@ -75,4 +77,5 @@ # metersToPixels

- `mx` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitudes (Meridians) in meters
- `my` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitudes (Parallels) in decimal degrees
- `meters` **[Meters](https://en.wikipedia.org/wiki/Web_Mercator)** Meters [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitudes (Meridians) in meters
- `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitudes (Parallels) in decimal degrees
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level

@@ -83,16 +86,17 @@

```javascript
metersToPixels({ mx: 14026255, my: 4439106, zoom: 13 })
//= Pixels { px: 1782579.1560447346, py: 1280877.3387406059, zoom: 13 }
const pixels = metersToPixels([14026255, 4439106, 13])
//=pixels
```
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Pixels coordinates
Returns **[Pixels](https://msdn.microsoft.com/en-us/library/bb259689.aspx)** Pixels coordinates
# latLngToTile
# lngLatToTile
Converts [LatLng](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates to TMS [Tile](https://en.wikipedia.org/wiki/Tiled_web_map).
Converts [LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates to TMS [Tile](https://en.wikipedia.org/wiki/Tiled_web_map).
**Parameters**
- `lnglat` **[LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System)** LngLat [lng, lat, zoom]
- `lng` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitude (Meridians) in decimal degrees
- `lat` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitude (Parallels) in decimal degrees
- `lng` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitude (Meridians) in decimal degrees
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level

@@ -103,16 +107,17 @@

```javascript
latLngToTile({lat: 37, lng: 126, zoom: 13 })
//= Tile { tx: 6963, ty: 5003, zoom: 13 }
const tile = lngLatToTile([37, 126, 13])
//=tile
```
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** TMS Tile
Returns **[Tile](https://en.wikipedia.org/wiki/Tiled_web_map)** TMS Tile
# latLngToGoogle
# lngLatToGoogle
Converts [LatLng](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates to [Google](https://en.wikipedia.org/wiki/Tiled_web_map) (XYZ) Tile.
Converts [LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates to [Google](https://en.wikipedia.org/wiki/Tiled_web_map) (XYZ) Tile.
**Parameters**
- `lnglat` **[LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System)** LngLat [lng, lat, zoom]
- `lng` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitude (Meridians) in decimal degrees
- `lat` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitude (Parallels) in decimal degrees
- `lng` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitude (Meridians) in decimal degrees
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level

@@ -123,7 +128,7 @@

```javascript
latLngToGoogle({lat: 37, lng: 126, zoom: 13 })
//= Google { x: 6963, y: 3188, zoom: 13 }
const google = lngLatToGoogle({lat: 37, lng: 126, zoom: 13 })
//=google
```
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Google (XYZ) Tile
Returns **[Google](https://en.wikipedia.org/wiki/Tiled_web_map)** Google (XYZ) Tile

@@ -136,4 +141,5 @@ # metersToTile

- `mx` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitudes (Meridians) in meters
- `my` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitudes (Parallels) in decimal degrees
- `meters` **[Meters](https://en.wikipedia.org/wiki/Web_Mercator)** Meters [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitudes (Meridians) in meters
- `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitudes (Parallels) in decimal degrees
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level

@@ -144,7 +150,7 @@

```javascript
metersToTile({ mx: 14026255, my: 4439106, zoom: 13 })
//= Tile { tx: 6963, ty: 5003, zoom: 13 }
const tile = metersToTile([14026255, 4439106, 13])
//=tile
```
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** TMS Tile
Returns **[Tile](https://en.wikipedia.org/wiki/Tiled_web_map)** TMS Tile

@@ -157,4 +163,5 @@ # pixelsToMeters

- `px` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Pixels X
- `py` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Pixels Y
- `pixels` **[Pixels](https://msdn.microsoft.com/en-us/library/bb259689.aspx)** Pixels [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Pixels X
- `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Pixels Y
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level

@@ -165,7 +172,7 @@

```javascript
pixelsToMeters({ px: 1782579, py: 1280877, zoom: 13 })
//= Meters { mx: 14026252.018101055, my: 4439099.526918683, zoom: 13 }
const meters = pixelsToMeters([1782579, 1280877, 13])
//=meters
```
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Meters coordinates
Returns **[Meters](https://en.wikipedia.org/wiki/Web_Mercator)** Meters coordinates

@@ -178,2 +185,3 @@ # pixelsToTile

- `pixels` **[Pixels](https://msdn.microsoft.com/en-us/library/bb259689.aspx)** Pixels [x, y, zoom]
- `px` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Pixels X

@@ -186,16 +194,17 @@ - `py` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Pixels Y

```javascript
pixelsToTile({ px: 1782579, py: 1280877, zoom: 13 })
//= Tile { tx: 6963, ty: 5003, zoom: 13 }
const tile = pixelsToTile([1782579, 1280877, 13])
//=tile
```
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** TMS Tile
Returns **[Tile](https://en.wikipedia.org/wiki/Tiled_web_map)** TMS Tile
# tileBbox
# tileToBBoxMeters
Converts TMS [Tile](https://en.wikipedia.org/wiki/Tiled_web_map) to [bbox](http://geojson.org/geojson-spec.html#bounding-boxes) in [Meters](https://en.wikipedia.org/wiki/Web_Mercator) coordinates.
Converts TMS [Tile](https://en.wikipedia.org/wiki/Tiled_web_map) to [bbox](bbox) in [Meters](https://en.wikipedia.org/wiki/Web_Mercator) coordinates.
**Parameters**
- `tx` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile X
- `ty` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile Y
- `tile` **[Tile](https://en.wikipedia.org/wiki/Tiled_web_map)** Tile [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile X
- `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile Y
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level

@@ -206,16 +215,17 @@

```javascript
tileBbox({ tx: 6963, ty: 5003, zoom: 13 })
//= [ 14025277.445990417, 4437016.617897913, 14030169.415800672, 4441908.587708164 ]
const bbox = tileToBBoxMeters([6963, 5003, 13])
//=bbox
```
Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** bbox extent in [minX, minY, maxX, maxY] order
Returns **[BBox](http://geojson.org/geojson-spec.html#bounding-boxes)** bbox extent in [minX, minY, maxX, maxY] order
# tileLatLngBbox
# tileToBBox
Converts TMS [Tile](https://en.wikipedia.org/wiki/Tiled_web_map) to [bbox](http://geojson.org/geojson-spec.html#bounding-boxes) in [LatLng](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates.
Converts TMS [Tile](https://en.wikipedia.org/wiki/Tiled_web_map) to [bbox](bbox) in [LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates.
**Parameters**
- `tx` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile X
- `ty` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile Y
- `tile` **[Tile](https://en.wikipedia.org/wiki/Tiled_web_map)** Tile [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile X
- `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile Y
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level

@@ -226,14 +236,15 @@

```javascript
tileLatLngBbox({ tx: 6963, ty: 5003, zoom: 13 })
//= [ 125.99121093749999, 36.98500309285596, 126.03515625, 37.020098201368135 ]
const bbox = tileToBBox([6963, 5003, 13])
//=bbox
```
Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** bbox extent in [minX, minY, maxX, maxY] order
Returns **[BBox](http://geojson.org/geojson-spec.html#bounding-boxes)** bbox extent in [minX, minY, maxX, maxY] order
# googleBbox
# googleToBBoxMeters
Converts [Google](https://en.wikipedia.org/wiki/Tiled_web_map) (XYZ) Tile to [bbox](http://geojson.org/geojson-spec.html#bounding-boxes) in [Meters](https://en.wikipedia.org/wiki/Web_Mercator) coordinates.
Converts [Google](https://en.wikipedia.org/wiki/Tiled_web_map) (XYZ) Tile to [bbox](bbox) in [Meters](https://en.wikipedia.org/wiki/Web_Mercator) coordinates.
**Parameters**
- `google` **[Google](https://en.wikipedia.org/wiki/Tiled_web_map)** Google [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Google (XYZ) Tile X

@@ -246,14 +257,15 @@ - `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Google (XYZ) Tile Y

```javascript
googleBbox({ x: 6963, y: 3188, zoom: 13 })
//= [ 14025277.445990417, 4437016.617897913, 14030169.415800672, 4441908.587708164 ]
const bbox = googleToBBoxMeters([6963, 3188, 13])
//=bbox
```
Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** bbox extent in [minX, minY, maxX, maxY] order
Returns **[BBox](http://geojson.org/geojson-spec.html#bounding-boxes)** bbox extent in [minX, minY, maxX, maxY] order
# googleLatLngBbox
# googleToBBox
Converts [Google](https://en.wikipedia.org/wiki/Tiled_web_map) (XYZ) Tile to [bbox](http://geojson.org/geojson-spec.html#bounding-boxes) in [LatLng](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates.
Converts [Google](https://en.wikipedia.org/wiki/Tiled_web_map) (XYZ) Tile to [bbox](bbox) in [LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates.
**Parameters**
- `google` **[Google](https://en.wikipedia.org/wiki/Tiled_web_map)** Google [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Google (XYZ) Tile X

@@ -266,9 +278,9 @@ - `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Google (XYZ) Tile Y

```javascript
googleLatLngBbox({ x: 6963, y: 3188, zoom: 13 })
//= [ 125.99121093749999, 36.98500309285596, 126.03515625, 37.020098201368135 ]
const bbox = googleToBBox([6963, 3188, 13])
//=bbox
```
Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** bbox extent in [minX, minY, maxX, maxY] order
Returns **[BBox](http://geojson.org/geojson-spec.html#bounding-boxes)** bbox extent in [minX, minY, maxX, maxY] order
# tileGoogle
# tileToGoogle

@@ -279,2 +291,3 @@ Converts TMS [Tile](https://en.wikipedia.org/wiki/Tiled_web_map) to [Google](https://en.wikipedia.org/wiki/Tiled_web_map) (XYZ) Tile.

- `tile` **[Tile](https://en.wikipedia.org/wiki/Tiled_web_map)** Tile [x, y, zoom]
- `tx` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile X

@@ -287,9 +300,9 @@ - `ty` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile Y

```javascript
tileGoogle({ tx: 6963, ty: 5003, zoom: 13 })
//= Google { x: 6963, y: 3188, zoom: 13 }
const google = tileToGoogle([6963, 5003, 13])
//=google
```
Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** bbox extent in [minX, minY, maxX, maxY] order
Returns **[Google](https://en.wikipedia.org/wiki/Tiled_web_map)** Google (XYZ) Tile
# googleTile
# googleToTile

@@ -300,2 +313,3 @@ Converts [Google](https://en.wikipedia.org/wiki/Tiled_web_map) (XYZ) Tile to TMS [Tile](https://en.wikipedia.org/wiki/Tiled_web_map).

- `google` **[Google](https://en.wikipedia.org/wiki/Tiled_web_map)** Google [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Google (XYZ) Tile X

@@ -308,9 +322,9 @@ - `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Google (XYZ) Tile Y

```javascript
googleTile({ x: 6963, y: 3188, zoom: 13 })
//= Tile { tx: 6963, ty: 5003, zoom: 13 }
const tile = googleToTile([6963, 3188, 13])
//=tile
```
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** TMS Tile
Returns **[Tile](https://en.wikipedia.org/wiki/Tiled_web_map)** TMS Tile
# googleQuadkey
# googleToQuadkey

@@ -321,2 +335,3 @@ Converts [Google](https://en.wikipedia.org/wiki/Tiled_web_map) (XYZ) Tile to [Quadkey](https://msdn.microsoft.com/en-us/library/bb259689.aspx).

- `google` **[Google](https://en.wikipedia.org/wiki/Tiled_web_map)** Google [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Google (XYZ) Tile X

@@ -329,4 +344,4 @@ - `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Google (XYZ) Tile Y

```javascript
googleQuadkey({ x: 6963, y: 3188, zoom: 13 })
//= '1321102330211'
const quadkey = googleToQuadkey([6963, 3188, 13])
//=quadkey
```

@@ -336,3 +351,3 @@

# tileQuadkey
# tileToQuadkey

@@ -343,2 +358,3 @@ Converts TMS [Tile](https://en.wikipedia.org/wiki/Tiled_web_map) to [QuadKey](QuadKey).

- `tile` **[Tile](https://en.wikipedia.org/wiki/Tiled_web_map)** Tile [x, y, zoom]
- `tx` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile X

@@ -351,4 +367,4 @@ - `ty` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile Y

```javascript
tileQuadkey({ tx: 6963, ty: 5003, zoom: 13 })
//= '1321102330211'
const quadkey = tileToQuadkey([6963, 5003, 13])
//=quadkey
```

@@ -358,3 +374,3 @@

# quadkeyTile
# quadkeyToTile

@@ -370,9 +386,9 @@ Converts [Quadkey](https://msdn.microsoft.com/en-us/library/bb259689.aspx) to TMS [Tile](https://en.wikipedia.org/wiki/Tiled_web_map).

```javascript
quadkeyTile('1321102330211')
//= Tile { tx: 6963, ty: 5003, zoom: 13 }
const tile = quadkeyToTile('1321102330211')
//=tile
```
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** TMS Tile
Returns **[Tile](https://en.wikipedia.org/wiki/Tiled_web_map)** TMS Tile
# quadkeyGoogle
# quadkeyToGoogle

@@ -388,15 +404,15 @@ Converts [Quadkey](https://msdn.microsoft.com/en-us/library/bb259689.aspx) to [Google](https://en.wikipedia.org/wiki/Tiled_web_map) (XYZ) Tile.

```javascript
quadkeyGoogle('1321102330211')
//= Google { x: 6963, y: 3188, zoom: 13 }
const google = quadkeyToGoogle('1321102330211')
//=google
```
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Google (XYZ) Tile
Returns **[Google](https://en.wikipedia.org/wiki/Tiled_web_map)** Google (XYZ) Tile
# bboxLatLngToMeters
# bboxToMeters
Converts [bbox](http://geojson.org/geojson-spec.html#bounding-boxes) from [LatLng](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates to [Meters](https://en.wikipedia.org/wiki/Web_Mercator) coordinates
Converts [BBox](http://geojson.org/geojson-spec.html#bounding-boxes) from [LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates to [Meters](https://en.wikipedia.org/wiki/Web_Mercator) coordinates
**Parameters**
- `bbox` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** extent in [minX, minY, maxX, maxY] order
- `bbox` **[BBox](http://geojson.org/geojson-spec.html#bounding-boxes)** extent in [minX, minY, maxX, maxY] order

@@ -406,7 +422,7 @@ **Examples**

```javascript
bboxLatLngToMeters([ 125, 35, 127, 37 ])
//= [ 13914936.349159198, 4163881.1440642904, 14137575.330745745, 4439106.787250587 ]
const meters = bboxToMeters([ 125, 35, 127, 37 ])
//=meters
```
Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** bbox extent in [minX, minY, maxX, maxY] order
Returns **[BBox](http://geojson.org/geojson-spec.html#bounding-boxes)** bbox extent in [minX, minY, maxX, maxY] order

@@ -436,6 +452,6 @@ # resolution

- `tx` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile X
- `ty` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile Y
- `tile` **[Tile](https://en.wikipedia.org/wiki/Tiled_web_map)** Tile [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile X
- `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile Y
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level
- `name` **\[[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** name used for debugging message (optional, default `Tile`)

@@ -445,6 +461,5 @@ **Examples**

```javascript
validateTile({tx: 60, ty: 80, zoom: 5})
//= {tx: 60, ty: 80, zoom: 5}
validateTile({tx: 60, ty: -43, zoom: 5})
//= Error: Tile <ty> must not be less than 0
validateTile([60, 80, 5])
validateTile([60, -43, 5])
//= Error: Tile <y> must not be less than 0
```

@@ -454,3 +469,3 @@

Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** TMS Tile
Returns **[Tile](https://en.wikipedia.org/wiki/Tiled_web_map)** TMS Tile

@@ -469,3 +484,2 @@ # validateZoom

validateZoom(12)
//= 12
validateZoom(-4)

@@ -487,3 +501,6 @@ //= Error: <zoom> cannot be less than 0

- `Pixels` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** coordinates
- `pixels` **[Pixels](https://msdn.microsoft.com/en-us/library/bb259689.aspx)** Pixels [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Pixels X
- `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Pixels Y
- `zoom` **\[[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)]** Zoom level

@@ -499,3 +516,3 @@ **Examples**

Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** Pixels coordinates
Returns **[Pixels](https://msdn.microsoft.com/en-us/library/bb259689.aspx)** Pixels coordinates

@@ -508,3 +525,6 @@ # validateMeters

- `Meters` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** coordinates
- `meters` **[Meters](https://en.wikipedia.org/wiki/Web_Mercator)** Meters [x, y, zoom]
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitudes (Meridians) in meters
- `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitudes (Parallels) in decimal degrees
- `zoom` **\[[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)]** Zoom level

@@ -520,25 +540,4 @@ **Examples**

Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** Meters coordinates
Returns **[Meters](https://en.wikipedia.org/wiki/Web_Mercator)** Meters coordinates
# validateLatLng
Validates [LatLng](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates.
**Parameters**
- `LatLng` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** coordinates
**Examples**
```javascript
validateLatLng([60, -125])
//= [60, -125]
validateLatLng([140, -125])
//= Error: LatLng [lat] must be within -90 to 90 degrees
```
- Throws **[Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)** Will throw an error if LatLng is not valid.
Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** LatLng coordinates
# validateLngLat

@@ -550,3 +549,6 @@

- `LngLat` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** coordinates
- `lnglat` **[LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System)** LngLat [lng, lat, zoom]
- `lng` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitude (Meridians) in decimal degrees
- `lat` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitude (Parallels) in decimal degrees
- `zoom` **\[[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)]** Zoom level

@@ -559,3 +561,3 @@ **Examples**

validateLngLat([-225, 44])
//= Error: LatLng [lng] must be within -180 to 180 degrees
//= Error: LngLat [lng] must be within -180 to 180 degrees
```

@@ -565,11 +567,15 @@

Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** LngLat coordinates
Returns **[LngLat](https://en.wikipedia.org/wiki/World_Geodetic_System)** LngLat coordinates
# validateBbox
# range
Validates [bbox](http://geojson.org/geojson-spec.html#bounding-boxes).
Generate an integer Array containing an arithmetic progression.
A port of the native Python `range()` function.
See [the Python documentation](http://docs.python.org/library/functions.html#range).
**Parameters**
- `bbox` **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** extent in [minX, minY, maxX, maxY] order
- `start` **\[[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)]** Start (optional, default `0`)
- `stop` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Stop
- `step` **\[[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)]** Step (optional, default `1`)

@@ -579,82 +585,7 @@ **Examples**

```javascript
validateBbox([ -75, 44, -74, 45 ])
//= [ -75, 44, -74, 45 ]
validateBbox([ -75, 44, -74 ])
//= Error: [bbox] must be an Array of 4 numbers
range(20)
range(10, 20)
range(20, 10, -1)
```
- Throws **[Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)** Will throw an error if bbox is not valid.
Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** bbox extent in [minX, minY, maxX, maxY] order
# assertUndefined
Assert undefined items within object.
**Parameters**
- `items` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)**
- `name` **\[[string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)]** name used for debugging message
**Examples**
```javascript
assertUndefined({foo: 'bar'})
//= {foo: 'bar'}
assertUndefined({foo: undefined})
//= Error: <foo> is required
```
- Throws **[Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)** Will throw an error if any item in Object is undefined.
Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** items
# Google
[Google](https://en.wikipedia.org/wiki/Tiled_web_map) (XYZ) Tile
**Properties**
- `x` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Google (XYZ) Tile X
- `y` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Google (XYZ) Tile Y
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level
# Tile
TMS [Tile](https://en.wikipedia.org/wiki/Tiled_web_map)
**Properties**
- `tx` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile X
- `ty` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** TMS Tile Y
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level
# Pixels
[Pixels](https://msdn.microsoft.com/en-us/library/bb259689.aspx) coordinates
**Properties**
- `px` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Pixels X
- `py` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Pixels Y
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level
# Meters
[Meters](https://en.wikipedia.org/wiki/Web_Mercator) coordinates
**Properties**
- `mx` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitudes (Meridians) in meters
- `my` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitudes (Parallels) in decimal degrees
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level
# LatLng
[LatLng](https://en.wikipedia.org/wiki/World_Geodetic_System) coordinates
**Properties**
- `lat` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Latitude (Parallels) in decimal degrees
- `lng` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Longitude (Meridians) in decimal degrees
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level
Returns **[Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)&lt;[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)>** range
"use strict";
const ava_1 = require('ava');
const lodash_1 = require('lodash');
const mercator = require('./index');
const TILE = { tx: 2389, ty: 5245, zoom: 13 };
const GOOGLE = { x: 2389, y: 2946, zoom: 13 };
const ZOOM = 13;
const TILE = [2389, 5245, 13];
const GOOGLE = [2389, 2946, 13];
const QUADKEY = '0302321010121';
const QUADKEY_BAD = '030486861';
const LATLNG = { lat: 44.99988840247, lng: -75.00005722045897, zoom: 13 };
const METERS = { mx: -8348968.179247875, my: 5621503.917462073, zoom: 13 };
const PIXELS = { px: 611669, py: 1342753, zoom: 13 };
const BBOX = [-8350592.466098936, 5620873.311978721, -8345700.496288682, 5625765.281788976];
const BBOX_LATLNG = [-75.01464843750001, 44.99588261816546, -74.97070312499999, 45.02695045318546];
ava_1.default('latLngToMeters', t => {
const meters = mercator.latLngToMeters(LATLNG);
t.deepEqual(meters.mx.toFixed(2), METERS.mx.toFixed(2));
t.deepEqual(meters.my.toFixed(2), METERS.my.toFixed(2));
const LNGLAT = [-75.00005722045897, 44.99988840247, 13];
const METERS = [-8348968.179247875, 5621503.917462073, 13];
const PIXELS = [611669, 1342753, 13];
const BBOX_METERS = [-8350592.466098936, 5620873.311978721, -8345700.496288682, 5625765.281788976];
const BBOX = [-75.01464843750001, 44.99588261816546, -74.97070312499999, 45.02695045318546];
ava_1.default('lngLatToMeters', t => {
const meters = mercator.lngLatToMeters(LNGLAT);
t.deepEqual(meters[0].toFixed(2), METERS[0].toFixed(2));
t.deepEqual(meters[1].toFixed(2), METERS[1].toFixed(2));
});
ava_1.default('metersToLatLng', t => {
const latlng = mercator.metersToLatLng(METERS);
const { lat, lng, zoom } = latlng;
t.deepEqual({ lat: lat, lng: lng, zoom: zoom }, LATLNG);
ava_1.default('metersToLngLat', t => {
const lnglat = mercator.metersToLngLat(METERS);
t.deepEqual(lnglat, LNGLAT);
});
ava_1.default('metersToPixels', t => {
const pixels = mercator.metersToPixels(METERS);
const { px, py, zoom } = pixels;
t.deepEqual(px, PIXELS.px);
t.deepEqual(py, PIXELS.py);
t.deepEqual(zoom, PIXELS.zoom);
const [px, py, zoom] = pixels;
t.deepEqual(px, PIXELS[0]);
t.deepEqual(py, PIXELS[1]);
t.deepEqual(zoom, PIXELS[2]);
});
ava_1.default('pixelsToTile', t => {
const tile = mercator.pixelsToTile(PIXELS);
t.deepEqual(tile, lodash_1.pick(TILE, ['tx', 'ty', 'zoom']));
t.deepEqual(tile, TILE);
});
ava_1.default('metersToTile', t => {
const tile = mercator.metersToTile(METERS);
t.deepEqual(tile, lodash_1.pick(TILE, ['tx', 'ty', 'zoom']));
t.deepEqual(tile, TILE);
});
ava_1.default('pixelsToMeters', t => {
const meters = mercator.pixelsToMeters(PIXELS);
t.deepEqual(meters.mx.toFixed(2), METERS.mx.toFixed(2));
t.deepEqual(meters.my.toFixed(2), METERS.my.toFixed(2));
t.deepEqual(meters[0].toFixed(2), METERS[0].toFixed(2));
t.deepEqual(meters[1].toFixed(2), METERS[1].toFixed(2));
});
ava_1.default('tileBbox', t => {
const bbox = mercator.tileBbox(TILE);
ava_1.default('tileToBbox', t => {
const bbox = mercator.tileToBBox(TILE);
t.deepEqual(bbox.map(i => i.toFixed(2)), BBOX.map(i => i.toFixed(2)));
});
ava_1.default('tileLatLngBbox', t => {
const bbox = mercator.tileLatLngBbox(TILE);
t.deepEqual(bbox, BBOX_LATLNG);
ava_1.default('tileToBBoxMeters', t => {
const bbox = mercator.tileToBBoxMeters(TILE);
t.deepEqual(bbox.map(i => i.toFixed(2)), BBOX_METERS.map(i => i.toFixed(2)));
});
ava_1.default('tileGoogle', t => {
const google = mercator.tileGoogle(TILE);
t.deepEqual(google, lodash_1.pick(GOOGLE, ['x', 'y', 'zoom']));
ava_1.default('tileToGoogle', t => {
const google = mercator.tileToGoogle(TILE);
t.deepEqual(google, GOOGLE);
});
ava_1.default('tileQuadkey', t => {
const quadkey = mercator.tileQuadkey(TILE);
ava_1.default('tileToQuadkey', t => {
const quadkey = mercator.tileToQuadkey(TILE);
t.deepEqual(quadkey, QUADKEY);
});
ava_1.default('quadKeyGoogle', t => {
const google = mercator.quadkeyGoogle(QUADKEY);
t.deepEqual(google, lodash_1.pick(GOOGLE, ['x', 'y', 'zoom']));
ava_1.default('quadKeyToGoogle', t => {
const google = mercator.quadkeyToGoogle(QUADKEY);
t.deepEqual(google, GOOGLE);
});
ava_1.default('quadKeyTile', t => {
const tile = mercator.quadkeyTile(QUADKEY);
t.deepEqual(tile, lodash_1.pick(TILE, ['tx', 'ty', 'zoom']));
ava_1.default('quadKeyToTile', t => {
const tile = mercator.quadkeyToTile(QUADKEY);
t.deepEqual(tile, TILE);
});
ava_1.default('Throws Error quadkeyTile', t => {
t.throws(() => mercator.quadkeyTile(QUADKEY_BAD), 'Invalid Quadkey digit sequence');
ava_1.default('Throws Error quadkeyToTile', t => {
t.throws(() => mercator.quadkeyToTile(QUADKEY_BAD), 'Invalid Quadkey digit sequence');
});
ava_1.default('googleBbox', t => {
const bbox = mercator.googleBbox(GOOGLE);
ava_1.default('googleToBbox', t => {
const bbox = mercator.googleToBBox(GOOGLE);
t.deepEqual(bbox.map(i => i.toFixed(2)), BBOX.map(i => i.toFixed(2)));
});
ava_1.default('googleLatLonBbox', t => {
const bbox = mercator.googleLatLngBbox(GOOGLE);
t.deepEqual(bbox, BBOX_LATLNG);
ava_1.default('googleToBBoxMeters', t => {
const bbox = mercator.googleToBBoxMeters(GOOGLE);
t.deepEqual(bbox.map(i => i.toFixed(2)), BBOX_METERS.map(i => i.toFixed(2)));
});
ava_1.default('latLngToGoogle', t => {
const google = mercator.latLngToGoogle(LATLNG);
t.deepEqual(google, lodash_1.pick(GOOGLE, ['x', 'y', 'zoom']));
ava_1.default('lngLatToGoogle', t => {
const google = mercator.lngLatToGoogle(LNGLAT);
t.deepEqual(google, GOOGLE);
});
ava_1.default('googleQuadKey', t => {
const quadkey = mercator.googleQuadkey(GOOGLE);
ava_1.default('googleToQuadKey', t => {
const quadkey = mercator.googleToQuadkey(GOOGLE);
t.deepEqual(quadkey, QUADKEY);
});
ava_1.default('Throws Error Bad bbox', t => {
t.throws(() => mercator.validateBbox([1]), '[bbox] must be an Array of 4 numbers');
t.throws(() => mercator.validateBbox([1, 2]), '[bbox] must be an Array of 4 numbers');
t.throws(() => mercator.validateBbox([1, 2, 3]), '[bbox] must be an Array of 4 numbers');
t.throws(() => mercator.validateBbox([1, 2, 3, 4, 5]), '[bbox] must be an Array of 4 numbers');
});
ava_1.default('Throws Error Bad LngLat', t => {
t.throws(() => new mercator.LatLng({ lat: -220, lng: 120 }), 'LatLng [lat] must be within -90 to 90 degrees');
t.throws(() => new mercator.LatLng({ lat: 220, lng: 120 }), 'LatLng [lat] must be within -90 to 90 degrees');
t.throws(() => new mercator.LatLng({ lat: 45, lng: -220 }), 'LatLng [lng] must be within -180 to 180 degrees');
t.throws(() => new mercator.LatLng({ lat: 45, lng: 220 }), 'LatLng [lng] must be within -180 to 180 degrees');
t.throws(() => mercator.validateLngLat([-120, 220, ZOOM]), 'LngLat [lat] must be within -90 to 90 degrees');
t.throws(() => mercator.validateLngLat([120, 220, ZOOM]), 'LngLat [lat] must be within -90 to 90 degrees');
t.throws(() => mercator.validateLngLat([-220, 45, ZOOM]), 'LngLat [lng] must be within -180 to 180 degrees');
t.throws(() => mercator.validateLngLat([220, 45, ZOOM]), 'LngLat [lng] must be within -180 to 180 degrees');
});
ava_1.default('bboxLatLngToMeters', t => {
const bbox = mercator.bboxLatLngToMeters(BBOX_LATLNG);
t.deepEqual(bbox.map(i => i.toFixed(2)), BBOX.map(i => i.toFixed(2)));
ava_1.default('bboxToMeters', t => {
const bbox = mercator.bboxToMeters(BBOX);
t.deepEqual(bbox.map(i => i.toFixed(2)), BBOX_METERS.map(i => i.toFixed(2)));
});
ava_1.default('googleTile', t => {
const tile = mercator.googleTile(GOOGLE);
ava_1.default('googleToTile', t => {
const tile = mercator.googleToTile(GOOGLE);
t.deepEqual(tile, TILE);
});
ava_1.default('latLngToTile', t => {
const tile = mercator.latLngToTile(LATLNG);
ava_1.default('lngLatToTile', t => {
const tile = mercator.lngLatToTile(LNGLAT);
t.deepEqual(tile, TILE);
});
ava_1.default('validateLatLng', t => {
t.deepEqual(mercator.validateLatLng([85, -120]), [85, -120]);
});
ava_1.default('validateLngLat', t => {
t.throws(() => mercator.validateLngLat([-120, 45, 1]), 'LatLng must be an Array of 2 numbers');
t.throws(() => mercator.validateLngLat([-120, 190]), 'LatLng [lat] must be within -90 to 90 degrees');
t.throws(() => mercator.validateLngLat([-220, 45]), 'LatLng [lng] must be within -180 to 180 degrees');
t.deepEqual(mercator.validateLngLat([-120, 85.5]), [-120, 85]);
t.deepEqual(mercator.validateLngLat([-120, -85.5]), [-120, -85]);
});
ava_1.default('validateMeters', t => {
t.throws(() => mercator.validateMeters([200000, 150000, 1]), 'Meters must be an Array of 2 numbers');
t.throws(() => mercator.validateMeters([200000, 999150000]), 'Meters [my] cannot be greater than 20037508.342789244');
t.throws(() => mercator.validateMeters([200000, -999150000]), 'Meters [my] cannot be less than -20037508.342789244');
t.throws(() => mercator.validateMeters([999200000, 150000]), 'Meters [mx] cannot be greater than 20037508.342789244');
t.throws(() => mercator.validateMeters([-999200000, -150000]), 'Meters [mx] cannot be less than -20037508.342789244');
t.throws(() => mercator.validateMeters([200000, 999150000, ZOOM]), 'Meters [y] cannot be greater than 20037508.342789244');
t.throws(() => mercator.validateMeters([200000, -999150000, ZOOM]), 'Meters [y] cannot be less than -20037508.342789244');
t.throws(() => mercator.validateMeters([999200000, 150000, ZOOM]), 'Meters [x] cannot be greater than 20037508.342789244');
t.throws(() => mercator.validateMeters([-999200000, -150000, ZOOM]), 'Meters [x] cannot be less than -20037508.342789244');
t.deepEqual(mercator.validateMeters(METERS), METERS);
});
ava_1.default('validatePixels', t => {
t.throws(() => mercator.validatePixels([200000, 150000, 1]), 'Pixels must be an Array of 2 numbers');
});
ava_1.default('validateZoom', t => {

@@ -136,11 +116,20 @@ t.throws(() => mercator.validateZoom(-2), '<zoom> cannot be less than 0');

ava_1.default('validateTile', t => {
t.throws(() => mercator.validateTile({ tx: -10, ty: 30, zoom: 5 }), 'Tile <tx> must not be less than 0');
t.throws(() => mercator.validateTile({ tx: 30, ty: -10, zoom: 5 }), 'Tile <ty> must not be less than 0');
t.throws(() => mercator.validateTile([-10, 30, 5]), '<x> must not be less than 0');
t.throws(() => mercator.validateTile([30, -10, 5]), '<y> must not be less than 0');
t.deepEqual(mercator.validateTile(TILE), TILE);
});
ava_1.default('validateUndefined', t => {
t.throws(() => mercator.assertUndefined({ x: undefined }), '<x> is required');
ava_1.default('validateLngLat', t => {
t.deepEqual(mercator.validateLngLat(LNGLAT), LNGLAT);
});
ava_1.default('metersToPixels missing zoom', t => {
t.throws(() => mercator.metersToPixels({ mx: -8348968.179247875, my: 5621503.917462073 }), '<zoom> is required');
ava_1.default('validatePixels', t => {
t.deepEqual(mercator.validatePixels(PIXELS), PIXELS);
});
ava_1.default('resolution', t => {
t.deepEqual(mercator.resolution(ZOOM), 19.109257071294063);
});
ava_1.default('range', t => {
t.deepEqual(mercator.range(3), [0, 1, 2]);
t.deepEqual(mercator.range(0, 3), [0, 1, 2]);
t.deepEqual(mercator.range(3, 0, -1), [3, 2, 1]);
});
//# sourceMappingURL=test.js.map
import test from 'ava'
import { pick } from 'lodash'
import * as mercator from './index'
const TILE = { tx: 2389, ty: 5245, zoom: 13 }
const GOOGLE = { x: 2389, y: 2946, zoom: 13 }
const ZOOM = 13
const TILE: mercator.Tile = [2389, 5245, 13]
const GOOGLE: mercator.Google = [2389, 2946, 13]
const QUADKEY = '0302321010121'
const QUADKEY_BAD = '030486861'
const LATLNG = { lat: 44.99988840247, lng: -75.00005722045897, zoom: 13 }
const METERS = { mx: -8348968.179247875, my: 5621503.917462073, zoom: 13 }
const PIXELS = { px: 611669, py: 1342753, zoom: 13 }
const BBOX = [ -8350592.466098936, 5620873.311978721, -8345700.496288682, 5625765.281788976 ]
const BBOX_LATLNG = [ -75.01464843750001, 44.99588261816546, -74.97070312499999, 45.02695045318546 ]
const LNGLAT: mercator.LngLat = [-75.00005722045897, 44.99988840247, 13]
const METERS: mercator.Meters = [-8348968.179247875, 5621503.917462073, 13]
const PIXELS: mercator.Pixels = [611669, 1342753, 13]
const BBOX_METERS: mercator.BBox = [-8350592.466098936, 5620873.311978721, -8345700.496288682, 5625765.281788976]
const BBOX: mercator.BBox = [-75.01464843750001, 44.99588261816546, -74.97070312499999, 45.02695045318546]
test('latLngToMeters', t => {
const meters = mercator.latLngToMeters(LATLNG)
t.deepEqual(meters.mx.toFixed(2), METERS.mx.toFixed(2))
t.deepEqual(meters.my.toFixed(2), METERS.my.toFixed(2))
test('lngLatToMeters', t => {
const meters = mercator.lngLatToMeters(LNGLAT)
t.deepEqual(meters[0].toFixed(2), METERS[0].toFixed(2))
t.deepEqual(meters[1].toFixed(2), METERS[1].toFixed(2))
})
test('metersToLatLng', t => {
const latlng = mercator.metersToLatLng(METERS)
const { lat, lng, zoom } = latlng
t.deepEqual({lat, lng, zoom}, LATLNG)
test('metersToLngLat', t => {
const lnglat = mercator.metersToLngLat(METERS)
t.deepEqual(lnglat, LNGLAT)
})

@@ -29,6 +28,6 @@

const pixels = mercator.metersToPixels(METERS)
const { px, py, zoom } = pixels
t.deepEqual(px, PIXELS.px)
t.deepEqual(py, PIXELS.py)
t.deepEqual(zoom, PIXELS.zoom)
const [px, py, zoom] = pixels
t.deepEqual(px, PIXELS[0])
t.deepEqual(py, PIXELS[1])
t.deepEqual(zoom, PIXELS[2])
})

@@ -38,3 +37,3 @@

const tile = mercator.pixelsToTile(PIXELS)
t.deepEqual(tile, pick(TILE, ['tx', 'ty', 'zoom']))
t.deepEqual(tile, TILE)
})

@@ -44,3 +43,3 @@

const tile = mercator.metersToTile(METERS)
t.deepEqual(tile, pick(TILE, ['tx', 'ty', 'zoom']))
t.deepEqual(tile, TILE)
})

@@ -50,113 +49,90 @@

const meters = mercator.pixelsToMeters(PIXELS)
t.deepEqual(meters.mx.toFixed(2), METERS.mx.toFixed(2))
t.deepEqual(meters.my.toFixed(2), METERS.my.toFixed(2))
t.deepEqual(meters[0].toFixed(2), METERS[0].toFixed(2))
t.deepEqual(meters[1].toFixed(2), METERS[1].toFixed(2))
})
test('tileBbox', t => {
const bbox = mercator.tileBbox(TILE)
test('tileToBbox', t => {
const bbox = mercator.tileToBBox(TILE)
t.deepEqual(bbox.map(i => i.toFixed(2)), BBOX.map(i => i.toFixed(2)))
})
test('tileLatLngBbox', t => {
const bbox = mercator.tileLatLngBbox(TILE)
t.deepEqual(bbox, BBOX_LATLNG)
test('tileToBBoxMeters', t => {
const bbox = mercator.tileToBBoxMeters(TILE)
t.deepEqual(bbox.map(i => i.toFixed(2)), BBOX_METERS.map(i => i.toFixed(2)))
})
test('tileGoogle', t => {
const google = mercator.tileGoogle(TILE)
t.deepEqual(google, pick(GOOGLE, ['x', 'y', 'zoom']))
test('tileToGoogle', t => {
const google = mercator.tileToGoogle(TILE)
t.deepEqual(google, GOOGLE)
})
test('tileQuadkey', t => {
const quadkey = mercator.tileQuadkey(TILE)
test('tileToQuadkey', t => {
const quadkey = mercator.tileToQuadkey(TILE)
t.deepEqual(quadkey, QUADKEY)
})
test('quadKeyGoogle', t => {
const google = mercator.quadkeyGoogle(QUADKEY)
t.deepEqual(google, pick(GOOGLE, ['x', 'y', 'zoom']))
test('quadKeyToGoogle', t => {
const google = mercator.quadkeyToGoogle(QUADKEY)
t.deepEqual(google, GOOGLE)
})
test('quadKeyTile', t => {
const tile = mercator.quadkeyTile(QUADKEY)
t.deepEqual(tile, pick(TILE, ['tx', 'ty', 'zoom']))
test('quadKeyToTile', t => {
const tile = mercator.quadkeyToTile(QUADKEY)
t.deepEqual(tile, TILE)
})
test('Throws Error quadkeyTile', t => {
t.throws(() => mercator.quadkeyTile(QUADKEY_BAD), 'Invalid Quadkey digit sequence')
test('Throws Error quadkeyToTile', t => {
t.throws(() => mercator.quadkeyToTile(QUADKEY_BAD), 'Invalid Quadkey digit sequence')
})
test('googleBbox', t => {
const bbox = mercator.googleBbox(GOOGLE)
test('googleToBbox', t => {
const bbox = mercator.googleToBBox(GOOGLE)
t.deepEqual(bbox.map(i => i.toFixed(2)), BBOX.map(i => i.toFixed(2)))
})
test('googleLatLonBbox', t => {
const bbox = mercator.googleLatLngBbox(GOOGLE)
t.deepEqual(bbox, BBOX_LATLNG)
test('googleToBBoxMeters', t => {
const bbox = mercator.googleToBBoxMeters(GOOGLE)
t.deepEqual(bbox.map(i => i.toFixed(2)), BBOX_METERS.map(i => i.toFixed(2)))
})
test('latLngToGoogle', t => {
const google = mercator.latLngToGoogle(LATLNG)
t.deepEqual(google, pick(GOOGLE, ['x', 'y', 'zoom']))
test('lngLatToGoogle', t => {
const google = mercator.lngLatToGoogle(LNGLAT)
t.deepEqual(google, GOOGLE)
})
test('googleQuadKey', t => {
const quadkey = mercator.googleQuadkey(GOOGLE)
test('googleToQuadKey', t => {
const quadkey = mercator.googleToQuadkey(GOOGLE)
t.deepEqual(quadkey, QUADKEY)
})
test('Throws Error Bad bbox', t => {
t.throws(() => mercator.validateBbox([1]), '[bbox] must be an Array of 4 numbers')
t.throws(() => mercator.validateBbox([1, 2]), '[bbox] must be an Array of 4 numbers')
t.throws(() => mercator.validateBbox([1, 2, 3]), '[bbox] must be an Array of 4 numbers')
t.throws(() => mercator.validateBbox([1, 2, 3, 4, 5]), '[bbox] must be an Array of 4 numbers')
})
test('Throws Error Bad LngLat', t => {
t.throws(() => new mercator.LatLng({ lat: -220, lng: 120 }), 'LatLng [lat] must be within -90 to 90 degrees')
t.throws(() => new mercator.LatLng({ lat: 220, lng: 120 }), 'LatLng [lat] must be within -90 to 90 degrees')
t.throws(() => new mercator.LatLng({ lat: 45, lng: -220 }), 'LatLng [lng] must be within -180 to 180 degrees')
t.throws(() => new mercator.LatLng({ lat: 45, lng: 220 }), 'LatLng [lng] must be within -180 to 180 degrees')
t.throws(() => mercator.validateLngLat([-120, 220, ZOOM]), 'LngLat [lat] must be within -90 to 90 degrees')
t.throws(() => mercator.validateLngLat([120, 220, ZOOM]), 'LngLat [lat] must be within -90 to 90 degrees')
t.throws(() => mercator.validateLngLat([-220, 45, ZOOM]), 'LngLat [lng] must be within -180 to 180 degrees')
t.throws(() => mercator.validateLngLat([220, 45, ZOOM]), 'LngLat [lng] must be within -180 to 180 degrees')
})
test('bboxLatLngToMeters', t => {
const bbox = mercator.bboxLatLngToMeters(BBOX_LATLNG)
t.deepEqual(bbox.map(i => i.toFixed(2)), BBOX.map(i => i.toFixed(2)))
test('bboxToMeters', t => {
const bbox = mercator.bboxToMeters(BBOX)
t.deepEqual(bbox.map(i => i.toFixed(2)), BBOX_METERS.map(i => i.toFixed(2)))
})
test('googleTile', t => {
const tile = mercator.googleTile(GOOGLE)
test('googleToTile', t => {
const tile = mercator.googleToTile(GOOGLE)
t.deepEqual(tile, TILE)
})
test('latLngToTile', t => {
const tile = mercator.latLngToTile(LATLNG)
test('lngLatToTile', t => {
const tile = mercator.lngLatToTile(LNGLAT)
t.deepEqual(tile, TILE)
})
test('validateLatLng', t => {
t.deepEqual(mercator.validateLatLng([85, -120]), [85, -120])
})
test('validateLngLat', t => {
t.throws(() => mercator.validateLngLat([-120, 45, 1]), 'LatLng must be an Array of 2 numbers')
t.throws(() => mercator.validateLngLat([-120, 190]), 'LatLng [lat] must be within -90 to 90 degrees')
t.throws(() => mercator.validateLngLat([-220, 45]), 'LatLng [lng] must be within -180 to 180 degrees')
t.deepEqual(mercator.validateLngLat([-120, 85.5]), [-120, 85])
t.deepEqual(mercator.validateLngLat([-120, -85.5]), [-120, -85])
})
test('validateMeters', t => {
t.throws(() => mercator.validateMeters([200000, 150000, 1]), 'Meters must be an Array of 2 numbers')
t.throws(() => mercator.validateMeters([200000, 999150000]), 'Meters [my] cannot be greater than 20037508.342789244')
t.throws(() => mercator.validateMeters([200000, -999150000]), 'Meters [my] cannot be less than -20037508.342789244')
t.throws(() => mercator.validateMeters([999200000, 150000]), 'Meters [mx] cannot be greater than 20037508.342789244')
t.throws(() => mercator.validateMeters([-999200000, -150000]), 'Meters [mx] cannot be less than -20037508.342789244')
t.throws(() => mercator.validateMeters([200000, 999150000, ZOOM]), 'Meters [y] cannot be greater than 20037508.342789244')
t.throws(() => mercator.validateMeters([200000, -999150000, ZOOM]), 'Meters [y] cannot be less than -20037508.342789244')
t.throws(() => mercator.validateMeters([999200000, 150000, ZOOM]), 'Meters [x] cannot be greater than 20037508.342789244')
t.throws(() => mercator.validateMeters([-999200000, -150000, ZOOM]), 'Meters [x] cannot be less than -20037508.342789244')
t.deepEqual(mercator.validateMeters(METERS), METERS)
})
test('validatePixels', t => {
t.throws(() => mercator.validatePixels([200000, 150000, 1]), 'Pixels must be an Array of 2 numbers')
})
test('validateZoom', t => {

@@ -168,12 +144,23 @@ t.throws(() => mercator.validateZoom(-2), '<zoom> cannot be less than 0')

test('validateTile', t => {
t.throws(() => mercator.validateTile({tx: -10, ty: 30, zoom: 5}), 'Tile <tx> must not be less than 0')
t.throws(() => mercator.validateTile({tx: 30, ty: -10, zoom: 5}), 'Tile <ty> must not be less than 0')
t.throws(() => mercator.validateTile([-10, 30, 5]), '<x> must not be less than 0')
t.throws(() => mercator.validateTile([30, -10, 5]), '<y> must not be less than 0')
t.deepEqual(mercator.validateTile(TILE), TILE)
})
test('validateUndefined', t => {
t.throws(() => mercator.assertUndefined({x: undefined}), '<x> is required')
test('validateLngLat', t => {
t.deepEqual(mercator.validateLngLat(LNGLAT), LNGLAT)
})
test('metersToPixels missing zoom', t => {
t.throws(() => mercator.metersToPixels({ mx: -8348968.179247875, my: 5621503.917462073}), '<zoom> is required')
test('validatePixels', t => {
t.deepEqual(mercator.validatePixels(PIXELS), PIXELS)
})
test('resolution', t => {
t.deepEqual(mercator.resolution(ZOOM), 19.109257071294063)
})
test('range', t => {
t.deepEqual(mercator.range(3), [0, 1, 2])
t.deepEqual(mercator.range(0, 3), [0, 1, 2])
t.deepEqual(mercator.range(3, 0, -1), [3, 2, 1])
})

@@ -5,3 +5,3 @@ {

"module": "commonjs",
"target": "ES5",
"target": "ES6",
"noImplicitAny": true,

@@ -17,5 +17,4 @@ "removeComments": false,

"filesGlob": [
"./**/*.ts",
"typings/index.d.ts"
"./**/*.ts"
]
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc