Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

geokit

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

geokit - npm Package Compare versions

Comparing version 0.1.5 to 1.0.0

dist/functions/decode-hash.d.ts

14

CHANGELOG.md

@@ -0,1 +1,15 @@

## 1.0.0 (2020-06-21)
##### New Features
* **validateHash:** add geohash validation ([0bb5cd47](https://github.com/MichaelSolati/geokit/commit/0bb5cd47d8c39cdc48846e4fb5fe64631c5f7e73))
##### Bug Fixes
* fix docs build and deploy ([97b77f14](https://github.com/MichaelSolati/geokit/commit/97b77f146de164c3e898ea0dc82b0305c2b781db))
##### Refactors
* break out class into functions ([3f662fe0](https://github.com/MichaelSolati/geokit/commit/3f662fe0efc03ce292a1ab40121e1e50bfba49a1))
#### 0.1.5 (2020-06-11)

@@ -2,0 +16,0 @@

2

dist/geokit.js

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

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).window=t.window||{})}(this,(function(t){"use strict";function e(t,e){return(e[0]+e[1])/2>t?0:1}function n(t){return t*Math.PI/180}function o(t){const e=[];if(t.lat>90&&e.push("Your latitude is greater than 90°"),t.lat<-90&&e.push("Your latitude is less than -90°"),t.lng>180&&e.push("Your longitude is greater than 180°"),t.lng<-180&&e.push("Your longitude is less than -180°"),0!==e.length)return new Error(e.join(" "))}t.Geokit=class{static distance(t,e,r="km"){const s=o(t);if(s instanceof Error)throw new Error("Start coordinates: "+s.message);const a=o(e);if(a instanceof Error)throw new Error("End coordinates: "+a.message);const i="miles"===r.toLowerCase()?3963:6371,l=n(e.lat-t.lat),c=n(e.lng-t.lng),h=n(t.lat),u=n(e.lat),f=Math.sin(l/2)*Math.sin(l/2)+Math.sin(c/2)*Math.sin(c/2)*Math.cos(h)*Math.cos(u);return i*(2*Math.atan2(Math.sqrt(f),Math.sqrt(1-f)))}static hash(t,n=10){const r=o(t);if(r instanceof Error)throw r;let s="";const a=[-90,90],i=[-180,180];for(;s.length<n;){let n=0;for(let o=0;o<5;o++){const r=(5*s.length+o)%2==0,l=r?t.lng:t.lat,c=r?i:a,h=(c[0]+c[1])/2;n=(n<<1)+e(l,c),l>h?c[0]=h:c[1]=h}s+="0123456789bcdefghjkmnpqrstuvwxyz".charAt(n)}return s}static decodeHash(t){let e=!0;const n=[-90,90],o=[-180,180],r=t.split("");for(;r.length;){const t=(s=r.shift(),"0123456789bcdefghjkmnpqrstuvwxyz".indexOf(s.toLowerCase()));for(let r=0;r<5;r++){const s=[16,8,4,2,1][r],a=e?o:n,i=(a[0]+a[1])/2;a[t&s?0:1]=i,e=!e}}var s;return{lat:(n[0]+n[1])/2,lng:(o[0]+o[1])/2}}},Object.defineProperty(t,"__esModule",{value:!0})}));
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t=t||self).Geokit={})}(this,(function(t){"use strict";const n="0123456789bcdefghjkmnpqrstuvwxyz";function e(t,n){return(n[0]+n[1])/2>t?0:1}function o(t){return t*Math.PI/180}function r(t){const n=[];if(t.lat>90&&n.push("Your latitude is greater than 90°"),t.lat<-90&&n.push("Your latitude is less than -90°"),t.lng>180&&n.push("Your longitude is greater than 180°"),t.lng<-180&&n.push("Your longitude is less than -180°"),0!==n.length)return new Error(n.join(" "))}function s(t,e=!1){let o;if("string"!=typeof t)o="geohash must be a string";else if(0===t.length)o="geohash cannot be the empty string";else for(const e of t)-1===n.indexOf(e)&&(o="geohash cannot contain '"+e+"'");if(void 0===o||e)return!o;throw new Error("Invalid geohash '"+t+"': "+o)}t.decodeHash=function(t){s(t);let n=!0;const e=[-90,90],o=[-180,180],r=t.split("");for(;r.length;){const t=(a=r.shift(),"0123456789bcdefghjkmnpqrstuvwxyz".indexOf(a.toLowerCase()));for(let r=0;r<5;r++){const s=[16,8,4,2,1][r],a=n?o:e,i=(a[0]+a[1])/2;a[t&s?0:1]=i,n=!n}}var a;return{lat:(e[0]+e[1])/2,lng:(o[0]+o[1])/2}},t.distance=function(t,n,e="km"){const s=r(t);if(s instanceof Error)throw new Error("Start coordinates: "+s.message);const a=r(n);if(a instanceof Error)throw new Error("End coordinates: "+a.message);const i="miles"===e.toLowerCase()?3963:6371,h=o(n.lat-t.lat),f=o(n.lng-t.lng),l=o(t.lat),c=o(n.lat),u=Math.sin(h/2)*Math.sin(h/2)+Math.sin(f/2)*Math.sin(f/2)*Math.cos(l)*Math.cos(c);return i*(2*Math.atan2(Math.sqrt(u),Math.sqrt(1-u)))},t.hash=function(t,o=10){const s=r(t);if(s instanceof Error)throw s;let a="";const i=[-90,90],h=[-180,180];for(;a.length<o;){let o=0;for(let n=0;n<5;n++){const r=(5*a.length+n)%2==0,s=r?t.lng:t.lat,f=r?h:i,l=(f[0]+f[1])/2;o=(o<<1)+e(s,f),s>l?f[0]=l:f[1]=l}a+=n.charAt(o)}return a},t.validateHash=s,Object.defineProperty(t,"__esModule",{value:!0})}));

@@ -5,4 +5,5 @@ 'use strict';

const BASE32 = '0123456789bcdefghjkmnpqrstuvwxyz';
function base32(value) {
return '0123456789bcdefghjkmnpqrstuvwxyz'.charAt(value);
return BASE32.charAt(value);
}

@@ -38,63 +39,90 @@ function decimalChunk(value) {

class Geokit {
static distance(start, end, unit = 'km') {
const startValid = validateCoordinates(start);
if (startValid instanceof Error) {
throw new Error('Start coordinates: ' + startValid.message);
}
const endValid = validateCoordinates(end);
if (endValid instanceof Error) {
throw new Error('End coordinates: ' + endValid.message);
}
const radius = unit.toLowerCase() === 'miles' ? 3963 : 6371;
const dLat = toRad(end.lat - start.lat);
const dLon = toRad(end.lng - start.lng);
const lat1 = toRad(start.lat);
const lat2 = toRad(end.lat);
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return radius * c;
function validateHash(geohash, flag = false) {
let error;
if (typeof geohash !== 'string') {
error = 'geohash must be a string';
}
static hash(coordinates, precision = 10) {
const valid = validateCoordinates(coordinates);
if (valid instanceof Error) {
throw valid;
}
let hash = '';
const latRng = [-90, 90];
const lngRng = [-180, 180];
while (hash.length < precision) {
let temp = 0;
for (let i = 0; i < 5; i++) {
const even = (hash.length * 5 + i) % 2 === 0;
const coord = even ? coordinates.lng : coordinates.lat;
const range = even ? lngRng : latRng;
const middle = (range[0] + range[1]) / 2;
temp = (temp << 1) + getBit(coord, range);
coord > middle ? (range[0] = middle) : (range[1] = middle);
else if (geohash.length === 0) {
error = 'geohash cannot be the empty string';
}
else {
for (const letter of geohash) {
if (BASE32.indexOf(letter) === -1) {
error = "geohash cannot contain '" + letter + "'";
}
hash += base32(temp);
}
return hash;
}
static decodeHash(hash) {
let even = true;
const latRng = [-90, 90];
const lngRng = [-180, 180];
const hashChars = hash.split('');
while (hashChars.length) {
const chunk = decimalChunk(hashChars.shift());
for (let i = 0; i < 5; i++) {
const mask = [16, 8, 4, 2, 1][i];
const range = even ? lngRng : latRng;
const middle = (range[0] + range[1]) / 2;
range[chunk & mask ? 0 : 1] = middle;
even = !even;
}
if (typeof error !== 'undefined' && !flag) {
throw new Error("Invalid geohash '" + geohash + "': " + error);
}
else {
return !error;
}
}
function decodeHash(hash) {
validateHash(hash);
let even = true;
const latRng = [-90, 90];
const lngRng = [-180, 180];
const hashChars = hash.split('');
while (hashChars.length) {
const chunk = decimalChunk(hashChars.shift());
for (let i = 0; i < 5; i++) {
const mask = [16, 8, 4, 2, 1][i];
const range = even ? lngRng : latRng;
const middle = (range[0] + range[1]) / 2;
range[chunk & mask ? 0 : 1] = middle;
even = !even;
}
return { lat: (latRng[0] + latRng[1]) / 2, lng: (lngRng[0] + lngRng[1]) / 2 };
}
return { lat: (latRng[0] + latRng[1]) / 2, lng: (lngRng[0] + lngRng[1]) / 2 };
}
exports.Geokit = Geokit;
function distance(start, end, unit = 'km') {
const startValid = validateCoordinates(start);
if (startValid instanceof Error) {
throw new Error('Start coordinates: ' + startValid.message);
}
const endValid = validateCoordinates(end);
if (endValid instanceof Error) {
throw new Error('End coordinates: ' + endValid.message);
}
const radius = unit.toLowerCase() === 'miles' ? 3963 : 6371;
const dLat = toRad(end.lat - start.lat);
const dLon = toRad(end.lng - start.lng);
const lat1 = toRad(start.lat);
const lat2 = toRad(end.lat);
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return radius * c;
}
function hash(coordinates, precision = 10) {
const valid = validateCoordinates(coordinates);
if (valid instanceof Error) {
throw valid;
}
let hash = '';
const latRng = [-90, 90];
const lngRng = [-180, 180];
while (hash.length < precision) {
let temp = 0;
for (let i = 0; i < 5; i++) {
const even = (hash.length * 5 + i) % 2 === 0;
const coord = even ? coordinates.lng : coordinates.lat;
const range = even ? lngRng : latRng;
const middle = (range[0] + range[1]) / 2;
temp = (temp << 1) + getBit(coord, range);
coord > middle ? (range[0] = middle) : (range[1] = middle);
}
hash += base32(temp);
}
return hash;
}
exports.decodeHash = decodeHash;
exports.distance = distance;
exports.hash = hash;
exports.validateHash = validateHash;

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

export { Geokit } from './geokit';
export * from './definitions';
export * from './functions/decode-hash';
export * from './functions/distance';
export * from './functions/hash';
export * from './functions/validate-hash';

@@ -0,3 +1,4 @@

const BASE32 = '0123456789bcdefghjkmnpqrstuvwxyz';
function base32(value) {
return '0123456789bcdefghjkmnpqrstuvwxyz'.charAt(value);
return BASE32.charAt(value);
}

@@ -33,63 +34,87 @@ function decimalChunk(value) {

class Geokit {
static distance(start, end, unit = 'km') {
const startValid = validateCoordinates(start);
if (startValid instanceof Error) {
throw new Error('Start coordinates: ' + startValid.message);
}
const endValid = validateCoordinates(end);
if (endValid instanceof Error) {
throw new Error('End coordinates: ' + endValid.message);
}
const radius = unit.toLowerCase() === 'miles' ? 3963 : 6371;
const dLat = toRad(end.lat - start.lat);
const dLon = toRad(end.lng - start.lng);
const lat1 = toRad(start.lat);
const lat2 = toRad(end.lat);
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return radius * c;
function validateHash(geohash, flag = false) {
let error;
if (typeof geohash !== 'string') {
error = 'geohash must be a string';
}
static hash(coordinates, precision = 10) {
const valid = validateCoordinates(coordinates);
if (valid instanceof Error) {
throw valid;
}
let hash = '';
const latRng = [-90, 90];
const lngRng = [-180, 180];
while (hash.length < precision) {
let temp = 0;
for (let i = 0; i < 5; i++) {
const even = (hash.length * 5 + i) % 2 === 0;
const coord = even ? coordinates.lng : coordinates.lat;
const range = even ? lngRng : latRng;
const middle = (range[0] + range[1]) / 2;
temp = (temp << 1) + getBit(coord, range);
coord > middle ? (range[0] = middle) : (range[1] = middle);
else if (geohash.length === 0) {
error = 'geohash cannot be the empty string';
}
else {
for (const letter of geohash) {
if (BASE32.indexOf(letter) === -1) {
error = "geohash cannot contain '" + letter + "'";
}
hash += base32(temp);
}
return hash;
}
static decodeHash(hash) {
let even = true;
const latRng = [-90, 90];
const lngRng = [-180, 180];
const hashChars = hash.split('');
while (hashChars.length) {
const chunk = decimalChunk(hashChars.shift());
for (let i = 0; i < 5; i++) {
const mask = [16, 8, 4, 2, 1][i];
const range = even ? lngRng : latRng;
const middle = (range[0] + range[1]) / 2;
range[chunk & mask ? 0 : 1] = middle;
even = !even;
}
if (typeof error !== 'undefined' && !flag) {
throw new Error("Invalid geohash '" + geohash + "': " + error);
}
else {
return !error;
}
}
function decodeHash(hash) {
validateHash(hash);
let even = true;
const latRng = [-90, 90];
const lngRng = [-180, 180];
const hashChars = hash.split('');
while (hashChars.length) {
const chunk = decimalChunk(hashChars.shift());
for (let i = 0; i < 5; i++) {
const mask = [16, 8, 4, 2, 1][i];
const range = even ? lngRng : latRng;
const middle = (range[0] + range[1]) / 2;
range[chunk & mask ? 0 : 1] = middle;
even = !even;
}
return { lat: (latRng[0] + latRng[1]) / 2, lng: (lngRng[0] + lngRng[1]) / 2 };
}
return { lat: (latRng[0] + latRng[1]) / 2, lng: (lngRng[0] + lngRng[1]) / 2 };
}
export { Geokit };
function distance(start, end, unit = 'km') {
const startValid = validateCoordinates(start);
if (startValid instanceof Error) {
throw new Error('Start coordinates: ' + startValid.message);
}
const endValid = validateCoordinates(end);
if (endValid instanceof Error) {
throw new Error('End coordinates: ' + endValid.message);
}
const radius = unit.toLowerCase() === 'miles' ? 3963 : 6371;
const dLat = toRad(end.lat - start.lat);
const dLon = toRad(end.lng - start.lng);
const lat1 = toRad(start.lat);
const lat2 = toRad(end.lat);
const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return radius * c;
}
function hash(coordinates, precision = 10) {
const valid = validateCoordinates(coordinates);
if (valid instanceof Error) {
throw valid;
}
let hash = '';
const latRng = [-90, 90];
const lngRng = [-180, 180];
while (hash.length < precision) {
let temp = 0;
for (let i = 0; i < 5; i++) {
const even = (hash.length * 5 + i) % 2 === 0;
const coord = even ? coordinates.lng : coordinates.lat;
const range = even ? lngRng : latRng;
const middle = (range[0] + range[1]) / 2;
temp = (temp << 1) + getBit(coord, range);
coord > middle ? (range[0] = middle) : (range[1] = middle);
}
hash += base32(temp);
}
return hash;
}
export { decodeHash, distance, hash, validateHash };
{
"name": "geokit",
"version": "0.1.5",
"version": "1.0.0",
"description": "An assortment of geolocation related tools, all packaged in one easy to use kit.",
"scripts": {
"build": "rm -rf ./dist && rollup -c",
"docs": "typedoc --module node --target es5 --out docs/ src/",
"docs": "typedoc --out docs/ src/",
"coverage": "nyc report --reporter=text-lcov | coveralls",

@@ -9,0 +9,0 @@ "test": "nyc --reporter=html --reporter=text mocha --package package.json --exit",

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