const BASE32 = "0123456789bcdefghjkmnpqrstuvwxyz"; export function encodeGeohash( coord: { latitude: number; longitude: number }, precision = 9 ): string { let minLat = -90; let maxLat = 90; let minLon = -180; let maxLon = 180; let hash = ""; let bits = 0; let ch = 0; let evenBit = true; while (hash.length < precision) { if (evenBit) { const mid = (minLon + maxLon) / 2; if (coord.longitude >= mid) { ch = (ch << 1) | 1; minLon = mid; } else { ch = ch << 1; maxLon = mid; } } else { const mid = (minLat + maxLat) / 2; if (coord.latitude >= mid) { ch = (ch << 1) | 1; minLat = mid; } else { ch = ch << 1; maxLat = mid; } } evenBit = !evenBit; bits++; if (bits === 5) { hash += BASE32[ch]; bits = 0; ch = 0; } } return hash; } export function decodeGeohash(hash: string): { latitude: number; longitude: number; } { let minLat = -90; let maxLat = 90; let minLon = -180; let maxLon = 180; let evenBit = true; for (const char of hash) { const idx = BASE32.indexOf(char); for (let i = 4; i >= 0; i--) { const bit = (idx >> i) & 1; if (evenBit) { const mid = (minLon + maxLon) / 2; if (bit === 1) { minLon = mid; } else { maxLon = mid; } } else { const mid = (minLat + maxLat) / 2; if (bit === 1) { minLat = mid; } else { maxLat = mid; } } evenBit = !evenBit; } } return { latitude: (minLat + maxLat) / 2, longitude: (minLon + maxLon) / 2, }; }