Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
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,
};
}