UNPKG

atriusmaps-node-sdk

Version:

This project provides an API to Atrius Personal Wayfinder maps within a Node environment. See the README.md for more information

75 lines (72 loc) 2 kB
'use strict'; const BITS = [16, 8, 4, 2, 1]; const BASE32 = "0123456789bcdefghjkmnpqrstuvwxyz"; const NEIGHBORS = { right: { even: "bc01fg45238967deuvhjyznpkmstqrwx" }, left: { even: "238967debc01fg45kmstqrwxuvhjyznp" }, top: { even: "p0r21436x8zb9dcf5h7kjnmqesgutwvy" }, bottom: { even: "14365h7k9dcfesgujnmqp0r2twvyx8zb" } }; const BORDERS = { right: { even: "bcfguvyz" }, left: { even: "0145hjnp" }, top: { even: "prxz" }, bottom: { even: "028b" } }; NEIGHBORS.bottom.odd = NEIGHBORS.left.even; NEIGHBORS.top.odd = NEIGHBORS.right.even; NEIGHBORS.left.odd = NEIGHBORS.bottom.even; NEIGHBORS.right.odd = NEIGHBORS.top.even; BORDERS.bottom.odd = BORDERS.left.even; BORDERS.top.odd = BORDERS.right.even; BORDERS.left.odd = BORDERS.bottom.even; BORDERS.right.odd = BORDERS.top.even; function calculateAdjacent(srcHash, dir) { srcHash = srcHash.toLowerCase(); const lastChr = srcHash.charAt(srcHash.length - 1); const type = srcHash.length % 2 ? "odd" : "even"; let base = srcHash.substring(0, srcHash.length - 1); if (BORDERS[dir][type].indexOf(lastChr) !== -1) { base = calculateAdjacent(base, dir); } return base + BASE32[NEIGHBORS[dir][type].indexOf(lastChr)]; } function encode(latitude, longitude, precision = 12) { let isEven = true; const lat = [-90, 90]; const lng = [-180, 180]; let bit = 0; let ch = 0; let geohash = ""; while (geohash.length < precision) { let mid; if (isEven) { mid = (lng[0] + lng[1]) / 2; if (longitude > mid) { ch |= BITS[bit]; lng[0] = mid; } else { lng[1] = mid; } } else { mid = (lat[0] + lat[1]) / 2; if (latitude > mid) { ch |= BITS[bit]; lat[0] = mid; } else { lat[1] = mid; } } isEven = !isEven; if (bit < 4) { bit++; } else { geohash += BASE32[ch]; bit = 0; ch = 0; } } return geohash; } exports.calculateAdjacent = calculateAdjacent; exports.encode = encode;