{"version":3,"sources":["../../../src/utils/geohash.ts"],"sourcesContent":["import { v } from '../api'\n\nconst Base32Chars = '0123456789bcdefghjkmnpqrstuvwxyz'\nconst Base2Chars = '01'\n\nfunction base10ToBaseX(num: number, base: number, chars: string) {\n\tconst charsObj = Object.fromEntries(\n\t\tchars\n\t\t\t.toLowerCase()\n\t\t\t.split('')\n\t\t\t.map((value, index) => [index, value]),\n\t)\n\tconst bits: string[] = []\n\tif (num === 0) return '0'\n\twhile (num > 0) {\n\t\tbits.push(charsObj[num % base] ?? '')\n\t\tnum = Math.floor(num / base)\n\t}\n\treturn bits.reverse().join('')\n}\n\nfunction baseXToBase10(num: string, base: number, chars: string) {\n\tconst charsObj = Object.fromEntries(\n\t\tchars\n\t\t\t.toLowerCase()\n\t\t\t.split('')\n\t\t\t.map((value, index) => [value, index]),\n\t)\n\n\treturn num\n\t\t.toLowerCase()\n\t\t.split('')\n\t\t.reduce((acc, cur, index, arr) => {\n\t\t\tconst pos = charsObj[cur] ?? 0\n\t\t\treturn acc + pos * Math.pow(base, arr.length - index - 1)\n\t\t}, 0)\n}\n\nfunction dichotomy(min: number, max: number, bits: string) {\n\tconst res = bits\n\t\t.split('')\n\t\t.concat('')\n\t\t.reduce(\n\t\t\t(acc, cur) => {\n\t\t\t\tconst mid = (min + max) / 2\n\t\t\t\tconst error = (max - min) / 2\n\t\t\t\tacc.mid = mid\n\t\t\t\tacc.error = error\n\t\t\t\tif (cur === '1') min = mid\n\t\t\t\telse max = mid\n\t\t\t\treturn acc\n\t\t\t},\n\t\t\t{ mid: 0, error: 0 },\n\t\t)\n\tconst value = res.mid - res.error\n\treturn { value, interval: res.error * 2 }\n}\n\nfunction parseCoords(hash: string) {\n\thash = v.assert(v.string().pipe(v.min(1)), hash)\n\tconst base10 = baseXToBase10(hash, 32, Base32Chars)\n\tconst base2 = base10ToBaseX(base10, 2, Base2Chars).padStart(hash.length * 5, '0')\n\n\treturn base2.split('').reduce(\n\t\t(acc, cur, index) => {\n\t\t\tif (index % 2 === 0) acc.long += cur\n\t\t\telse acc.lat += cur\n\t\t\treturn acc\n\t\t},\n\t\t{ lat: '', long: '' },\n\t)\n}\n\nfunction wrap(num: number, base: number) {\n\tif (num < -base) num = num + base * 2\n\tif (num > +base) num = num - base * 2\n\treturn num\n}\n\nexport function decode(hash: string): [number, number] {\n\tconst coords = parseCoords(hash)\n\tconst lat = dichotomy(-90, 90, coords.lat).value\n\tconst long = dichotomy(-180, 180, coords.long).value\n\treturn [lat, long]\n}\n\nexport function encode(coords: [number, number]): string {\n\tcoords = v.assert(v.tuple([v.number(), v.number()]), coords)\n\n\tlet idx = 0,\n\t\tbit = 0,\n\t\tevenBit = true,\n\t\tgeohash = ''\n\tconst mins = [-90, -180],\n\t\tmaxs = [90, 180]\n\n\twhile (geohash.length < 18) {\n\t\tconst key = evenBit ? 1 : 0\n\t\tconst mid = (mins[key] + maxs[key]) / 2\n\t\tif (coords[key] >= mid) {\n\t\t\tidx = idx * 2 + 1\n\t\t\tmins[key] = mid\n\t\t} else {\n\t\t\tidx = idx * 2\n\t\t\tmaxs[key] = mid\n\t\t}\n\t\tevenBit = !evenBit\n\n\t\tbit += 1\n\t\tif (bit === 5) {\n\t\t\tgeohash += base10ToBaseX(idx, 32, Base32Chars)\n\t\t\tbit = idx = 0\n\t\t}\n\t}\n\treturn geohash.replace(/0+$/, '')\n}\n\nexport function neighbors(hash: string) {\n\tconst coords = parseCoords(hash)\n\tconst lat = dichotomy(-90, 90, coords.lat)\n\tconst long = dichotomy(-180, 180, coords.long)\n\tconst neighbors = [\n\t\t[lat.value - lat.interval, long.value - long.interval],\n\t\t[lat.value - lat.interval, long.value],\n\t\t[lat.value - lat.interval, long.value + long.interval],\n\n\t\t[lat.value, long.value - long.interval],\n\t\t[lat.value, long.value + long.interval],\n\n\t\t[lat.value + lat.interval, long.value - long.interval],\n\t\t[lat.value + lat.interval, long.value],\n\t\t[lat.value + lat.interval, long.value + long.interval],\n\t].map(([lat, long]) => encode([wrap(lat, 90), wrap(long, 180)]))\n\treturn {\n\t\tbl: neighbors[0],\n\t\tbc: neighbors[1],\n\t\tbr: neighbors[2],\n\t\tcl: neighbors[3],\n\t\tcr: neighbors[4],\n\t\ttl: neighbors[5],\n\t\ttc: neighbors[6],\n\t\ttr: neighbors[7],\n\t}\n}\n"],"mappings":"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","names":["neighbors","lat","long"]}