geohash.ts 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. /**
  2. * Function that decodes input geohash into latitude and longitude
  3. */
  4. export function decodeGeohash(geohash: string): [number, number] | undefined {
  5. if (!geohash?.length) {
  6. return undefined;
  7. }
  8. const BITS = [16, 8, 4, 2, 1];
  9. const BASE32 = '0123456789bcdefghjkmnpqrstuvwxyz';
  10. let isEven = true;
  11. const lat: number[] = [];
  12. const lon: number[] = [];
  13. lat[0] = -90.0;
  14. lat[1] = 90.0;
  15. lon[0] = -180.0;
  16. lon[1] = 180.0;
  17. let base32Decoded: number;
  18. geohash.split('').forEach((item: string) => {
  19. base32Decoded = BASE32.indexOf(item);
  20. BITS.forEach((mask) => {
  21. if (isEven) {
  22. refineInterval(lon, base32Decoded, mask);
  23. } else {
  24. refineInterval(lat, base32Decoded, mask);
  25. }
  26. isEven = !isEven;
  27. });
  28. });
  29. const latCenter = (lat[0] + lat[1]) / 2;
  30. const lonCenter = (lon[0] + lon[1]) / 2;
  31. return [lonCenter, latCenter];
  32. }
  33. function refineInterval(interval: any[], base32Decoded: number, mask: number) {
  34. /* tslint:disable no-bitwise*/
  35. if (base32Decoded & mask) {
  36. interval[0] = (interval[0] + interval[1]) / 2;
  37. } else {
  38. interval[1] = (interval[0] + interval[1]) / 2;
  39. }
  40. }