in packages/geofire-common/src/index.ts [146:197]
export function geohashForLocation(location: Geopoint, precision: number = GEOHASH_PRECISION): Geohash {
validateLocation(location);
if (typeof precision !== 'undefined') {
if (typeof precision !== 'number' || isNaN(precision)) {
throw new Error('precision must be a number');
} else if (precision <= 0) {
throw new Error('precision must be greater than 0');
} else if (precision > 22) {
throw new Error('precision cannot be greater than 22');
} else if (Math.round(precision) !== precision) {
throw new Error('precision must be an integer');
}
}
const latitudeRange = {
min: -90,
max: 90
};
const longitudeRange = {
min: -180,
max: 180
};
let hash = '';
let hashVal = 0;
let bits = 0;
let even: number | boolean = 1;
while (hash.length < precision) {
const val = even ? location[1] : location[0];
const range = even ? longitudeRange : latitudeRange;
const mid = (range.min + range.max) / 2;
if (val > mid) {
hashVal = (hashVal << 1) + 1;
range.min = mid;
} else {
hashVal = (hashVal << 1) + 0;
range.max = mid;
}
even = !even;
if (bits < 4) {
bits++;
} else {
bits = 0;
hash += BASE32[hashVal];
hashVal = 0;
}
}
return hash;
}