UNPKG

geonumber

Version:

Library for encoding geographic coordinates as single number with any number of bits

62 lines 2.23 kB
export function encodeNumber(value, bits) { const cleanBits = BigInt(bits); const max = Number(1n << cleanBits); return BigInt(Math.round(value * max)); } export function decodeNumber(encoded, bits) { const cleanBits = BigInt(bits); const max = Number(1n << cleanBits); return Number(encoded) / max; } export function merge(a, b, bits) { const cleanBits = BigInt(bits); let result = 0n; const oddBits = cleanBits & 1n; for (let dstBit = 0n; dstBit < cleanBits; dstBit++) { const srcBit = dstBit >> 1n; result |= (((((dstBit & 1n) != oddBits) ? a : b) >> srcBit) & 1n) << dstBit; } return result; } export function split(encoded, bits) { const cleanBits = BigInt(bits); let a = 0n; let b = 0n; const oddBits = cleanBits & 1n; for (let srcBit = 0n; srcBit < cleanBits; srcBit++) { const dstBit = srcBit >> 1n; if ((srcBit & 1n) == oddBits) { b |= ((encoded >> srcBit) & 1n) << dstBit; } else { a |= ((encoded >> srcBit) & 1n) << dstBit; } } return [a, b]; } export function encodeLocation({ lat, lon }, bits) { const cleanBits = BigInt(bits); const latBits = cleanBits >> 1n; const lonBits = cleanBits - latBits; const normalizedLat = (lat + 90) / 180; const normalizedLon = (lon + 180) / 360; const clearedLat = normalizedLat - Math.floor(normalizedLat); const clearedLon = normalizedLon - Math.floor(normalizedLon); const encodedLat = encodeNumber(clearedLat, latBits); const encodedLon = encodeNumber(clearedLon, lonBits); const merged = merge(encodedLon, encodedLat, cleanBits); return merged; } export function decodeLocation(number, bits) { const cleanNumber = BigInt(number); const cleanBits = BigInt(bits); const latBits = cleanBits >> 1n; const lonBits = cleanBits - latBits; const [encodedLon, encodedLat] = split(cleanNumber, cleanBits); const normalizedLat = decodeNumber(encodedLat, latBits); const normalizedLon = decodeNumber(encodedLon, lonBits); const lat = normalizedLat * 180 - 90; const lon = normalizedLon * 360 - 180; return { lat, lon }; } //# sourceMappingURL=index.js.map