Huge News!Announcing our $40M Series B led by Abstract Ventures.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.2.6 to 0.3.0

.nyc_output/3613c09275933d8965819f9b6c3bcca5.json

3

HEADER.md

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

```javascript
import * as mercator from 'global-mercator'
import { latLngToMeters } from 'global-mercator'
```
"use strict";
const Debug = require("debug");
const lodash_1 = require("lodash");
const Debug = require('debug');
const lodash_1 = require('lodash');
exports.debug = {

@@ -9,2 +9,5 @@ error: Debug('global-mercator:error'),

};
exports.tileSize = 256;
exports.initialResolution = 2 * Math.PI * 6378137 / exports.tileSize;
exports.originShift = 2 * Math.PI * 6378137 / 2.0;
/**

@@ -23,3 +26,7 @@ * Converts {@link LatLng} coordinates to {@link Meters} coordinates.

function latLngToMeters(init) {
return mercator.latLngToMeters(init);
const { lat, lng, zoom } = new LatLng(init);
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 });
}

@@ -40,3 +47,7 @@ exports.latLngToMeters = latLngToMeters;

function metersToLatLng(init) {
return mercator.metersToLatLng(init);
const { mx, my, zoom } = new Meters(init);
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 });
}

@@ -57,3 +68,7 @@ exports.metersToLatLng = metersToLatLng;

function metersToPixels(init) {
return mercator.metersToPixels(init);
const { mx, my, zoom } = new Meters(init);
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 });
}

@@ -74,3 +89,5 @@ exports.metersToPixels = metersToPixels;

function latLngToTile(init) {
return mercator.latLngToTile(init);
const meters = latLngToMeters(init);
const pixels = metersToPixels(meters);
return pixelsToTile(pixels);
}

@@ -91,3 +108,7 @@ exports.latLngToTile = latLngToTile;

function latLngToGoogle(init) {
return mercator.latLngToGoogle(init);
if (init.zoom === 0) {
return new Google({ x: 0, y: 0, zoom: 0 });
}
const tile = latLngToTile(init);
return tileGoogle(tile);
}

@@ -108,3 +129,7 @@ exports.latLngToGoogle = latLngToGoogle;

function metersToTile(init) {
return mercator.metersToTile(init);
if (init.zoom === 0) {
return new Tile({ tx: 0, ty: 0, zoom: 0 });
}
const Pixels = metersToPixels(new Meters(init));
return pixelsToTile(Pixels);
}

@@ -125,3 +150,7 @@ exports.metersToTile = metersToTile;

function pixelsToMeters(init) {
return mercator.pixelsToMeters(init);
const { px, py, zoom } = new Pixels(init);
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 });
}

@@ -142,3 +171,15 @@ exports.pixelsToMeters = pixelsToMeters;

function pixelsToTile(init) {
return mercator.pixelsToTile(init);
if (init.zoom === 0) {
return new Tile({ tx: 0, ty: 0, zoom: 0 });
}
const { px, py, zoom } = new Pixels(init);
let tx = Math.ceil(px / exports.tileSize) - 1;
let ty = Math.ceil(py / exports.tileSize) - 1;
if (tx < 0) {
tx = 0;
}
if (ty < 0) {
ty = 0;
}
return new Tile({ tx: tx, ty: ty, zoom: zoom });
}

@@ -159,3 +200,6 @@ exports.pixelsToTile = pixelsToTile;

function tileBbox(init) {
return mercator.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]);
}

@@ -176,3 +220,10 @@ exports.tileBbox = tileBbox;

function tileLatLngBbox(init) {
return mercator.tileLatLngBbox(init);
if (init.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]);
}

@@ -193,3 +244,4 @@ exports.tileLatLngBbox = tileLatLngBbox;

function googleBbox(init) {
return mercator.googleBbox(init);
const Tile = googleTile(init);
return tileBbox(Tile);
}

@@ -210,3 +262,4 @@ exports.googleBbox = googleBbox;

function googleLatLngBbox(init) {
return mercator.googleLatLngBbox(init);
const Tile = googleTile(init);
return tileLatLngBbox(Tile);
}

@@ -227,3 +280,9 @@ exports.googleLatLngBbox = googleLatLngBbox;

function tileGoogle(init) {
return mercator.tileGoogle(init);
if (init.zoom === 0) {
return new Google({ x: 0, y: 0, zoom: 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 });
}

@@ -244,3 +303,6 @@ exports.tileGoogle = tileGoogle;

function googleTile(init) {
return mercator.googleTile(init);
const { x, y, zoom } = new Google(init);
const tx = x;
const ty = Math.pow(2, zoom) - y - 1;
return new Tile({ tx: tx, ty: ty, zoom: zoom });
}

@@ -261,3 +323,4 @@ exports.googleTile = googleTile;

function googleQuadkey(init) {
return mercator.googleQuadkey(init);
const Tile = googleTile(init);
return tileQuadkey(Tile);
}

@@ -278,3 +341,21 @@ exports.googleQuadkey = googleQuadkey;

function tileQuadkey(init) {
return mercator.tileQuadkey(init);
// Zoom 0 does not exist for Quadkey
if (init.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 => {
let digit = 0;
let mask = 1 << (i - 1);
if ((tx & mask) !== 0) {
digit += 1;
}
if ((ty & mask) !== 0) {
digit += 2;
}
quadkey = quadkey.concat(digit);
});
return quadkey;
}

@@ -293,3 +374,4 @@ exports.tileQuadkey = tileQuadkey;

function quadkeyTile(quadkey) {
return mercator.quadkeyTile(quadkey);
const Google = quadkeyGoogle(quadkey);
return googleTile(Google);
}

@@ -308,3 +390,25 @@ exports.quadkeyTile = quadkeyTile;

function quadkeyGoogle(quadkey) {
return mercator.quadkeyGoogle(quadkey);
let x = 0;
let y = 0;
const zoom = quadkey.length;
lodash_1.range(zoom, 0, -1).map(i => {
let mask = 1 << (i - 1);
switch (parseInt(quadkey[zoom - i], 0)) {
case 0:
break;
case 1:
x += mask;
break;
case 2:
y += mask;
break;
case 3:
x += mask;
y += mask;
break;
default:
throw new Error('Invalid Quadkey digit sequence');
}
});
return new Google({ x: x, y: y, zoom: zoom });
}

@@ -323,6 +427,27 @@ exports.quadkeyGoogle = quadkeyGoogle;

function bboxLatLngToMeters(bbox) {
return mercator.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];
}
exports.bboxLatLngToMeters = bboxLatLngToMeters;
/**
* Retrieve resolution based on zoom level
*
* @name resolution
* @param {number} zoom zoom level
* @returns {number} resolution
* @example
* const res = resolution(13)
* //=res
*/
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);
}
exports.resolution = resolution;
/**
* Validates TMS {@link Tile}.

@@ -370,14 +495,14 @@ *

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

@@ -671,205 +796,2 @@ throw new Error(message);

exports.LatLng = LatLng;
/**
* GlobalMercator
*
* @class GlobalMercator
* @property {number} [tileSize=256] Tile size dimension
*/
class GlobalMercator {
constructor(tileSize = 256) {
this.name = 'GlobalMercator';
this.bboxLatLngToMeters = (bbox) => {
const min = this.latLngToMeters({ lat: bbox[1], lng: bbox[0] });
const max = this.latLngToMeters({ lat: bbox[3], lng: bbox[2] });
return [min.mx, min.my, max.mx, max.my];
};
this.tileSize = tileSize;
this.initialResolution = 2 * Math.PI * 6378137 / this.tileSize;
this.originShift = 2 * Math.PI * 6378137 / 2.0;
}
Resolution(zoom) {
if (lodash_1.isUndefined(zoom)) {
const message = '<zoom> is required';
exports.debug.error(message);
throw new Error(message);
}
return this.initialResolution / Math.pow(2, zoom);
}
latLngToMeters(init) {
const { lat, lng, zoom } = new LatLng(init);
let mx = lng * this.originShift / 180.0;
let my = Math.log(Math.tan((90 + lat) * Math.PI / 360.0)) / (Math.PI / 180.0);
my = my * this.originShift / 180.0;
return new Meters({ mx, my, zoom });
}
metersToLatLng(init) {
const { mx, my, zoom } = new Meters(init);
let lng = (mx / this.originShift) * 180.0;
let lat = (my / this.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, lng, zoom });
}
metersToPixels(init) {
const { mx, my, zoom } = new Meters(init);
const res = this.Resolution(zoom);
const px = (mx + this.originShift) / res;
const py = (my + this.originShift) / res;
return new Pixels({ px, py, zoom });
}
latLngToTile(init) {
const meters = this.latLngToMeters(init);
const pixels = this.metersToPixels(meters);
return this.pixelsToTile(pixels);
}
latLngToGoogle(init) {
if (init.zoom === 0) {
return new Google({ x: 0, y: 0, zoom: 0 });
}
const tile = this.latLngToTile(init);
return this.tileGoogle(tile);
}
metersToTile(init) {
if (init.zoom === 0) {
return new Tile({ tx: 0, ty: 0, zoom: 0 });
}
const Pixels = this.metersToPixels(new Meters(init));
return this.pixelsToTile(Pixels);
}
pixelsToMeters(init) {
const { px, py, zoom } = new Pixels(init);
const res = this.Resolution(zoom);
const mx = px * res - this.originShift;
const my = py * res - this.originShift;
return new Meters({ mx, my, zoom });
}
pixelsToTile(init) {
if (init.zoom === 0) {
return new Tile({ tx: 0, ty: 0, zoom: 0 });
}
const { px, py, zoom } = new Pixels(init);
let tx = Math.ceil(px / this.tileSize) - 1;
let ty = Math.ceil(py / this.tileSize) - 1;
if (tx < 0) {
tx = 0;
}
if (ty < 0) {
ty = 0;
}
return new Tile({ tx, ty, zoom });
}
tileBbox(init) {
const { tx, ty, zoom } = new Tile(init);
let min = this.pixelsToMeters({ px: tx * this.tileSize, py: ty * this.tileSize, zoom });
let max = this.pixelsToMeters({ px: (tx + 1) * this.tileSize, py: (ty + 1) * this.tileSize, zoom });
return validateBbox([min.mx, min.my, max.mx, max.my]);
}
tileLatLngBbox(init) {
if (init.zoom === 0) {
return [-180, -85.05112877980659, 180, 85.05112877980659];
}
const { tx, ty, zoom } = new Tile(init);
const [mx1, my1, mx2, my2] = this.tileBbox({ tx, ty, zoom });
const min = this.metersToLatLng({ mx: mx1, my: my1, zoom });
const max = this.metersToLatLng({ mx: mx2, my: my2, zoom });
return validateBbox([min.lng, min.lat, max.lng, max.lat]);
}
googleBbox(init) {
const Tile = this.googleTile(init);
return this.tileBbox(Tile);
}
googleLatLngBbox(init) {
const Tile = this.googleTile(init);
return this.tileLatLngBbox(Tile);
}
tileGoogle(init) {
if (init.zoom === 0) {
return new Google({ x: 0, y: 0, zoom: 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 });
}
googleTile(init) {
const { x, y, zoom } = new Google(init);
const tx = x;
const ty = Math.pow(2, zoom) - y - 1;
return new Tile({ tx, ty, zoom });
}
googleQuadkey(init) {
const Tile = this.googleTile(init);
return this.tileQuadkey(Tile);
}
tileQuadkey(init) {
// Zoom 0 does not exist for Quadkey
if (init.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 => {
let digit = 0;
let mask = 1 << (i - 1);
if ((tx & mask) !== 0) {
digit += 1;
}
if ((ty & mask) !== 0) {
digit += 2;
}
quadkey = quadkey.concat(digit);
});
return quadkey;
}
quadkeyTile(quadkey) {
const Google = this.quadkeyGoogle(quadkey);
return this.googleTile(Google);
}
quadkeyGoogle(quadkey) {
let x = 0;
let y = 0;
const zoom = quadkey.length;
lodash_1.range(zoom, 0, -1).map(i => {
let mask = 1 << (i - 1);
switch (parseInt(quadkey[zoom - i], 0)) {
case 0:
break;
case 1:
x += mask;
break;
case 2:
y += mask;
break;
case 3:
x += mask;
y += mask;
break;
default:
throw new Error('Invalid Quadkey digit sequence');
}
});
return new Google({ x, y, zoom });
}
}
exports.GlobalMercator = GlobalMercator;
const mercator = new GlobalMercator();
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = {
metersToPixels,
metersToLatLng,
metersToTile,
pixelsToTile,
pixelsToMeters,
latLngToMeters,
latLngToGoogle,
tileBbox,
tileLatLngBbox,
tileGoogle,
tileQuadkey,
quadkeyGoogle,
quadkeyTile,
googleBbox,
googleLatLngBbox,
googleQuadkey,
};
/* istanbul ignore next */

@@ -876,0 +798,0 @@ if (require.main === module) {

@@ -10,2 +10,6 @@ import * as Debug from 'debug'

export const tileSize = 256
export const initialResolution = 2 * Math.PI * 6378137 / tileSize
export const originShift = 2 * Math.PI * 6378137 / 2.0
export interface InterfaceMeters {

@@ -55,3 +59,7 @@ mx: number

export function latLngToMeters(init: InterfaceLatLng) {
return mercator.latLngToMeters(init)
const { lat, lng, zoom } = new LatLng(init)
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 })
}

@@ -61,3 +69,3 @@

* Converts {@link Meters} coordinates to {@link LatLng} coordinates.
*
*
* @name metersToLatLng

@@ -73,3 +81,8 @@ * @param {number} mx Longitudes (Meridians) in meters

export function metersToLatLng(init: InterfaceMeters) {
return mercator.metersToLatLng(init)
const { mx, my, zoom } = new Meters(init)
let lng = (mx / originShift) * 180.0
let lat = (my / 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, lng, zoom })
}

@@ -79,3 +92,3 @@

* Converts {@link Meters} coordinates to {@link Pixels} coordinates.
*
*
* @name metersToPixels

@@ -91,3 +104,8 @@ * @param {number} mx Longitudes (Meridians) in meters

export function metersToPixels(init: InterfaceMeters) {
return mercator.metersToPixels(init)
const { mx, my, zoom } = new Meters(init)
const res = resolution(zoom)
const px = (mx + originShift) / res
const py = (my + originShift) / res
return new Pixels({ px, py, zoom })
}

@@ -97,3 +115,3 @@

* Converts {@link LatLng} coordinates to TMS {@link Tile}.
*
*
* @name latLngToTile

@@ -109,3 +127,5 @@ * @param {number} lat Latitude (Parallels) in decimal degrees

export function latLngToTile(init: InterfaceLatLng) {
return mercator.latLngToTile(init)
const meters = latLngToMeters(init)
const pixels = metersToPixels(meters)
return pixelsToTile(pixels)
}

@@ -115,3 +135,3 @@

* Converts {@link LatLng} coordinates to {@link Google} (XYZ) Tile.
*
*
* @name latLngToGoogle

@@ -127,3 +147,5 @@ * @param {number} lat Latitude (Parallels) in decimal degrees

export function latLngToGoogle(init: InterfaceLatLng) {
return mercator.latLngToGoogle(init)
if (init.zoom === 0) { return new Google({ x: 0, y: 0, zoom: 0 })}
const tile = latLngToTile(init)
return tileGoogle(tile)
}

@@ -133,3 +155,3 @@

* Converts {@link Meters} coordinates to TMS {@link Tile}.
*
*
* @name metersToTile

@@ -144,4 +166,6 @@ * @param {number} mx Longitudes (Meridians) in meters

*/
export function metersToTile(init: Meters) {
return mercator.metersToTile(init)
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)
}

@@ -151,3 +175,3 @@

* Converts {@link Pixels} coordinates to {@link Meters} coordinates.
*
*
* @name pixelsToMeters

@@ -162,4 +186,9 @@ * @param {number} px Pixels X

*/
export function pixelsToMeters(init: Pixels) {
return mercator.pixelsToMeters(init)
export function pixelsToMeters(init: InterfacePixels) {
const {px, py, zoom} = new Pixels(init)
const res = resolution(zoom)
const mx = px * res - originShift
const my = py * res - originShift
return new Meters({ mx, my, zoom })
}

@@ -169,3 +198,3 @@

* Converts {@link Pixels} coordinates to TMS {@link Tile}.
*
*
* @name pixelsToTile

@@ -180,4 +209,10 @@ * @param {number} px Pixels X

*/
export function pixelsToTile(init: Pixels) {
return mercator.pixelsToTile(init)
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)
let tx = Math.ceil(px / tileSize) - 1
let ty = Math.ceil(py / tileSize) - 1
if (tx < 0) { tx = 0 }
if (ty < 0) { ty = 0 }
return new Tile({ tx, ty, zoom })
}

@@ -187,3 +222,3 @@

* Converts TMS {@link Tile} to {@link bbox} in {@link Meters} coordinates.
*
*
* @name tileBbox

@@ -198,4 +233,8 @@ * @param {number} tx TMS Tile X

*/
export function tileBbox(init: Tile) {
return mercator.tileBbox(init)
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 })
return validateBbox([ min.mx, min.my, max.mx, max.my ])
}

@@ -205,3 +244,3 @@

* Converts TMS {@link Tile} to {@link bbox} in {@link LatLng} coordinates.
*
*
* @name tileLatLngBbox

@@ -216,4 +255,11 @@ * @param {number} tx TMS Tile X

*/
export function tileLatLngBbox(init: Tile) {
return mercator.tileLatLngBbox(init)
export function tileLatLngBbox(init: InterfaceTile) {
if (init.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 })
return validateBbox([ min.lng, min.lat, max.lng, max.lat ])
}

@@ -223,3 +269,3 @@

* Converts {@link Google} (XYZ) Tile to {@link bbox} in {@link Meters} coordinates.
*
*
* @name googleBbox

@@ -234,4 +280,5 @@ * @param {number} x Google (XYZ) Tile X

*/
export function googleBbox(init: Google) {
return mercator.googleBbox(init)
export function googleBbox(init: InterfaceGoogle) {
const Tile = googleTile(init)
return tileBbox(Tile)
}

@@ -241,3 +288,3 @@

* Converts {@link Google} (XYZ) Tile to {@link bbox} in {@link LatLng} coordinates.
*
*
* @name googleLatLngBbox

@@ -252,4 +299,5 @@ * @param {number} x Google (XYZ) Tile X

*/
export function googleLatLngBbox(init: Google) {
return mercator.googleLatLngBbox(init)
export function googleLatLngBbox(init: InterfaceGoogle) {
const Tile = googleTile(init)
return tileLatLngBbox(Tile)
}

@@ -259,3 +307,3 @@

* Converts TMS {@link Tile} to {@link Google} (XYZ) Tile.
*
*
* @name tileGoogle

@@ -270,4 +318,10 @@ * @param {number} tx TMS Tile X

*/
export function tileGoogle(init: Tile) {
return mercator.tileGoogle(init)
export function tileGoogle(init: InterfaceTile) {
if (init.zoom === 0) { return new Google({ x: 0, y: 0, zoom: 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 })
}

@@ -277,3 +331,3 @@

* Converts {@link Google} (XYZ) Tile to TMS {@link Tile}.
*
*
* @name googleTile

@@ -288,4 +342,8 @@ * @param {number} x Google (XYZ) Tile X

*/
export function googleTile(init: Google) {
return mercator.googleTile(init)
export function googleTile(init: InterfaceGoogle) {
const { x, y, zoom } = new Google(init)
const tx = x
const ty = Math.pow(2, zoom) - y - 1
return new Tile({ tx, ty, zoom })
}

@@ -295,3 +353,3 @@

* Converts {@link Google} (XYZ) Tile to {@link Quadkey}.
*
*
* @name googleQuadkey

@@ -306,4 +364,5 @@ * @param {number} x Google (XYZ) Tile X

*/
export function googleQuadkey(init: Google) {
return mercator.googleQuadkey(init)
export function googleQuadkey(init: InterfaceGoogle) {
const Tile = googleTile(init)
return tileQuadkey(Tile)
}

@@ -313,3 +372,3 @@

* Converts TMS {@link Tile} to {@link QuadKey}.
*
*
* @name tileQuadkey

@@ -324,4 +383,19 @@ * @param {number} tx TMS Tile X

*/
export function tileQuadkey(init: Tile) {
return mercator.tileQuadkey(init)
export function tileQuadkey(init: InterfaceTile) {
// Zoom 0 does not exist for Quadkey
if (init.zoom === 0) { return '' }
let { tx, ty, zoom } = new Tile(init)
let quadkey = ''
ty = (Math.pow(2, zoom) - 1) - ty
range(zoom, 0, -1).map(i => {
let digit: any = 0
let mask = 1 << (i - 1)
if ((tx & mask) !== 0) { digit += 1 }
if ((ty & mask) !== 0) { digit += 2 }
quadkey = quadkey.concat(digit)
})
return quadkey
}

@@ -331,3 +405,3 @@

* Converts {@link Quadkey} to TMS {@link Tile}.
*
*
* @name quadkeyTile

@@ -341,3 +415,4 @@ * @param {string} quadkey Microsoft's Quadkey schema

export function quadkeyTile(quadkey: string) {
return mercator.quadkeyTile(quadkey)
const Google = quadkeyGoogle(quadkey)
return googleTile(Google)
}

@@ -347,3 +422,3 @@

* Converts {@link Quadkey} to {@link Google} (XYZ) Tile.
*
*
* @name quadkeyGoogle

@@ -357,3 +432,27 @@ * @param {string} quadkey Microsoft's Quadkey schema

export function quadkeyGoogle(quadkey: string) {
return mercator.quadkeyGoogle(quadkey)
let x: number = 0
let y: number = 0
const zoom = quadkey.length
range(zoom, 0, -1).map(i => {
let mask = 1 << (i - 1)
switch (parseInt(quadkey[zoom - i], 0)) {
case 0:
break
case 1:
x += mask
break
case 2:
y += mask
break
case 3:
x += mask
y += mask
break
default:
throw new Error('Invalid Quadkey digit sequence')
}
})
return new Google({ x, y, zoom })
}

@@ -363,3 +462,3 @@

* Converts {@link bbox} from {@link LatLng} coordinates to {@link Meters} coordinates
*
*
* @name bboxLatLngToMeters

@@ -373,8 +472,29 @@ * @param {Array<number>} bbox extent in [minX, minY, maxX, maxY] order

export function bboxLatLngToMeters(bbox: number[]): number[] {
return mercator.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]
}
/**
* Retrieve resolution based on zoom level
*
* @name resolution
* @param {number} zoom zoom level
* @returns {number} resolution
* @example
* const res = resolution(13)
* //=res
*/
export function resolution(zoom: number) {
if (isUndefined(zoom)) {
const message = '<zoom> is required'
debug.error(message)
throw new Error(message)
}
return initialResolution / Math.pow(2, zoom)
}
/**
* Validates TMS {@link Tile}.
*
*
* @name validateTile

@@ -410,3 +530,3 @@ * @param {number} tx TMS Tile X

* Validates {@link Zoom} level.
*
*
* @name validateZoom

@@ -420,13 +540,13 @@ * @param {number} zoom Zoom level

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

@@ -440,3 +560,3 @@ throw new Error(message)

* Validates {@link Pixels} coordinates.
*
*
* @name validatePixels

@@ -472,3 +592,3 @@ * @param {Array<number>} Pixels coordinates

* Validates {@link Meters} coordinates.
*
*
* @name validateMeters

@@ -516,3 +636,3 @@ * @param {Array<number>} Meters coordinates

* Validates {@link LatLng} coordinates.
*
*
* @name validateLatLng

@@ -535,3 +655,3 @@ * @param {Array<number>} LatLng coordinates

* Validates {@link LngLat} coordinates.
*
*
* @name validateLngLat

@@ -578,3 +698,3 @@ * @param {Array<number>} LngLat coordinates

* Validates {@link bbox}.
*
*
* @name validateBbox

@@ -601,3 +721,3 @@ * @param {Array<number>} bbox extent in [minX, minY, maxX, maxY] order

* Assert undefined items within object.
*
*
* @name assertUndefined

@@ -627,3 +747,3 @@ * @param {Object} items

* {@link Google} (XYZ) Tile
*
*
* @class Google

@@ -638,2 +758,3 @@ * @property {number} x Google (XYZ) Tile X

public zoom: number
public z: number

@@ -651,3 +772,3 @@ constructor(init: InterfaceGoogle) {

* TMS {@link Tile}
*
*
* @class Tile

@@ -675,3 +796,3 @@ * @property {number} tx TMS Tile X

* {@link Pixels} coordinates
*
*
* @class Pixels

@@ -699,3 +820,3 @@ * @property {number} px Pixels X

* {@link Meters} coordinates
*
*
* @class Meters

@@ -723,3 +844,3 @@ * @property {number} mx Longitudes (Meridians) in meters

* {@link LatLng} coordinates
*
*
* @class LatLng

@@ -745,223 +866,2 @@ * @property {number} lat Latitude (Parallels) in decimal degrees

/**
* GlobalMercator
*
* @class GlobalMercator
* @property {number} [tileSize=256] Tile size dimension
*/
export class GlobalMercator {
public name: string = 'GlobalMercator'
private tileSize: number
private initialResolution: number
private originShift: number
constructor(tileSize: number = 256) {
this.tileSize = tileSize
this.initialResolution = 2 * Math.PI * 6378137 / this.tileSize
this.originShift = 2 * Math.PI * 6378137 / 2.0
}
public Resolution(zoom: number) {
if (isUndefined(zoom)) {
const message = '<zoom> is required'
debug.error(message)
throw new Error(message)
}
return this.initialResolution / Math.pow(2, zoom)
}
public latLngToMeters(init: InterfaceLatLng) {
const { lat, lng, zoom } = new LatLng(init)
let mx: number = lng * this.originShift / 180.0
let my: number = Math.log(Math.tan((90 + lat) * Math.PI / 360.0 )) / (Math.PI / 180.0)
my = my * this.originShift / 180.0
return new Meters({ mx, my, zoom })
}
public metersToLatLng(init: InterfaceMeters) {
const { mx, my, zoom } = new Meters(init)
let lng = (mx / this.originShift) * 180.0
let lat = (my / this.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, lng, zoom })
}
public metersToPixels(init: InterfaceMeters) {
const { mx, my, zoom } = new Meters(init)
const res = this.Resolution(zoom)
const px = (mx + this.originShift) / res
const py = (my + this.originShift) / res
return new Pixels({ px, py, zoom })
}
public latLngToTile(init: InterfaceLatLng) {
const meters = this.latLngToMeters(init)
const pixels = this.metersToPixels(meters)
return this.pixelsToTile(pixels)
}
public latLngToGoogle(init: InterfaceLatLng) {
if (init.zoom === 0) { return new Google({ x: 0, y: 0, zoom: 0 })}
const tile = this.latLngToTile(init)
return this.tileGoogle(tile)
}
public metersToTile(init: Meters) {
if (init.zoom === 0) { return new Tile({ tx: 0, ty: 0, zoom: 0 })}
const Pixels = this.metersToPixels(new Meters(init))
return this.pixelsToTile(Pixels)
}
public pixelsToMeters(init: Pixels) {
const {px, py, zoom} = new Pixels(init)
const res = this.Resolution(zoom)
const mx = px * res - this.originShift
const my = py * res - this.originShift
return new Meters({ mx, my, zoom })
}
public pixelsToTile(init: Pixels) {
if (init.zoom === 0) { return new Tile({ tx: 0, ty: 0, zoom: 0 })}
const {px, py, zoom} = new Pixels(init)
let tx = Math.ceil(px / this.tileSize) - 1
let ty = Math.ceil(py / this.tileSize) - 1
if (tx < 0) { tx = 0 }
if (ty < 0) { ty = 0 }
return new Tile({ tx, ty, zoom })
}
public tileBbox(init: Tile) {
const {tx, ty, zoom} = new Tile(init)
let min = this.pixelsToMeters({ px: tx * this.tileSize, py: ty * this.tileSize, zoom })
let max = this.pixelsToMeters({ px: (tx + 1) * this.tileSize, py: (ty + 1) * this.tileSize, zoom })
return validateBbox([ min.mx, min.my, max.mx, max.my ])
}
public tileLatLngBbox(init: Tile) {
if (init.zoom === 0) { return [ -180, -85.05112877980659, 180, 85.05112877980659 ] }
const {tx, ty, zoom} = new Tile(init)
const [mx1, my1, mx2, my2] = this.tileBbox({ tx, ty, zoom })
const min = this.metersToLatLng({ mx: mx1, my: my1, zoom })
const max = this.metersToLatLng({ mx: mx2, my: my2, zoom })
return validateBbox([ min.lng, min.lat, max.lng, max.lat ])
}
public googleBbox(init: Google) {
const Tile = this.googleTile(init)
return this.tileBbox(Tile)
}
public googleLatLngBbox(init: Google) {
const Tile = this.googleTile(init)
return this.tileLatLngBbox(Tile)
}
public bboxLatLngToMeters = (bbox: number[]): number[] => {
const min = this.latLngToMeters({lat: bbox[1], lng: bbox[0]})
const max = this.latLngToMeters({lat: bbox[3], lng: bbox[2]})
return [min.mx, min.my, max.mx, max.my]
}
public tileGoogle(init: Tile) {
if (init.zoom === 0) { return new Google({ x: 0, y: 0, zoom: 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 })
}
public googleTile(init: Google) {
const { x, y, zoom } = new Google(init)
const tx = x
const ty = Math.pow(2, zoom) - y - 1
return new Tile({ tx, ty, zoom })
}
public googleQuadkey(init: Google) {
const Tile = this.googleTile(init)
return this.tileQuadkey(Tile)
}
public tileQuadkey(init: Tile) {
// Zoom 0 does not exist for Quadkey
if (init.zoom === 0) { return '' }
let { tx, ty, zoom } = new Tile(init)
let quadkey = ''
ty = (Math.pow(2, zoom) - 1) - ty
range(zoom, 0, -1).map(i => {
let digit: any = 0
let mask = 1 << (i - 1)
if ((tx & mask) !== 0) { digit += 1 }
if ((ty & mask) !== 0) { digit += 2 }
quadkey = quadkey.concat(digit)
})
return quadkey
}
public quadkeyTile(quadkey: string) {
const Google = this.quadkeyGoogle(quadkey)
return this.googleTile(Google)
}
public quadkeyGoogle(quadkey: string) {
let x: number = 0
let y: number = 0
const zoom = quadkey.length
range(zoom, 0, -1).map(i => {
let mask = 1 << (i - 1)
switch (parseInt(quadkey[zoom - i], 0)) {
case 0:
break
case 1:
x += mask
break
case 2:
y += mask
break
case 3:
x += mask
y += mask
break
default:
throw new Error('Invalid Quadkey digit sequence')
}
})
return new Google({ x, y, zoom })
}
}
const mercator = new GlobalMercator()
export default {
metersToPixels,
metersToLatLng,
metersToTile,
pixelsToTile,
pixelsToMeters,
latLngToMeters,
latLngToGoogle,
tileBbox,
tileLatLngBbox,
tileGoogle,
tileQuadkey,
quadkeyGoogle,
quadkeyTile,
googleBbox,
googleLatLngBbox,
googleQuadkey,
}
/* istanbul ignore next */

@@ -968,0 +868,0 @@ if (require.main === module) {

{
"name": "global-mercator",
"version": "0.2.6",
"version": "0.3.0",
"description": "Global Mercator",

@@ -5,0 +5,0 @@ "main": "index.js",

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

```javascript
import * as mercator from 'global-mercator'
import { latLngToMeters } from 'global-mercator'

@@ -385,2 +384,19 @@ ```

# resolution
Retrieve resolution based on zoom level
**Parameters**
- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** zoom level
**Examples**
```javascript
const res = resolution(13)
//=res
```
Returns **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** resolution
# validateTile

@@ -424,5 +440,5 @@

validateZoom(-4)
//= Error: <zoom> cannot be less than 1
validateZoom(30)
//= Error: <zoom> cannot be greater than 23
//= Error: <zoom> cannot be less than 0
validateZoom(32)
//= Error: <zoom> cannot be greater than 30
```

@@ -606,9 +622,1 @@

- `zoom` **[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)** Zoom level
# GlobalMercator
GlobalMercator
**Properties**
- `tileSize` **\[[number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number)]** Tile size dimension
"use strict";
const ava_1 = require("ava");
const lodash_1 = require("lodash");
const mercator = require("./index");
const ava_1 = require('ava');
const lodash_1 = require('lodash');
const mercator = require('./index');
const TILE = { tx: 2389, ty: 5245, zoom: 13 };

@@ -22,3 +22,3 @@ const GOOGLE = { x: 2389, y: 2946, zoom: 13 };

const { lat, lng, zoom } = latlng;
t.deepEqual({ lat, lng, zoom }, LATLNG);
t.deepEqual({ lat: lat, lng: lng, zoom: zoom }, LATLNG);
});

@@ -133,4 +133,4 @@ ava_1.default('metersToPixels', t => {

ava_1.default('validateZoom', t => {
t.throws(() => mercator.validateZoom(-2), '<zoom> cannot be less than 1');
t.throws(() => mercator.validateZoom(25), '<zoom> cannot be greater than 23');
t.throws(() => mercator.validateZoom(-2), '<zoom> cannot be less than 0');
t.throws(() => mercator.validateZoom(35), '<zoom> cannot be greater than 30');
});

@@ -137,0 +137,0 @@ ava_1.default('validateTile', t => {

@@ -159,4 +159,4 @@ import test from 'ava'

test('validateZoom', t => {
t.throws(() => mercator.validateZoom(-2), '<zoom> cannot be less than 1')
t.throws(() => mercator.validateZoom(25), '<zoom> cannot be greater than 23')
t.throws(() => mercator.validateZoom(-2), '<zoom> cannot be less than 0')
t.throws(() => mercator.validateZoom(35), '<zoom> cannot be greater than 30')
})

@@ -163,0 +163,0 @@

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