getExtents static method
Get the rectangle that covers the entire area of a geohash string.
Implementation
static Rectangle<double> getExtents(String geohash) {
final codeLength = geohash.length;
if (codeLength > 20 || (identical(1.0, 1) && codeLength > 12)) {
//Javascript can only handle 32 bit ints reliably.
throw ArgumentError('latitude and longitude are not precise enough to encode $codeLength characters');
}
var latitudeInt = 0;
var longitudeInt = 0;
var longitudeFirst = true;
for (final character in geohash.codeUnits.map(String.fromCharCode)) {
int? thisSequence;
try {
thisSequence = _base32CharToNumber[character];
} on Exception catch (_) {
throw ArgumentError('$geohash was not a geohash string');
}
final bigBits = ((thisSequence! & 16) >> 2) | ((thisSequence & 4) >> 1) | (thisSequence & 1);
final smallBits = ((thisSequence & 8) >> 2) | ((thisSequence & 2) >> 1);
if (longitudeFirst) {
longitudeInt = (longitudeInt << 3) | bigBits;
latitudeInt = (latitudeInt << 2) | smallBits;
} else {
longitudeInt = (longitudeInt << 2) | smallBits;
latitudeInt = (latitudeInt << 3) | bigBits;
}
longitudeFirst = !longitudeFirst;
}
final longitudeBits = (codeLength ~/ 2) * 5 + (codeLength % 2) * 3;
final latitudeBits = codeLength * 5 - longitudeBits;
if (identical(1.0, 1)) {
// Some of our intermediate numbers are STILL too big for javascript,
// so we use floating point math...
final longitudeDiff = pow(2.0, 52 - longitudeBits);
final latitudeDiff = pow(2.0, 52 - latitudeBits);
final latitudeFloat = latitudeInt.toDouble() * latitudeDiff;
final longitudeFloat = longitudeInt.toDouble() * longitudeDiff;
final latitude = latitudeFloat * (180 / pow(2.0, 52)) - 90;
final longitude = longitudeFloat * (360 / pow(2.0, 52)) - 180;
final num height = latitudeDiff * (180 / pow(2.0, 52));
final num width = longitudeDiff * (360 / pow(2.0, 52));
return Rectangle<double>(latitude, longitude, height.toDouble(), width.toDouble());
}
longitudeInt = longitudeInt << (52 - longitudeBits);
latitudeInt = latitudeInt << (52 - latitudeBits);
final longitudeDiff = 1 << (52 - longitudeBits);
final latitudeDiff = 1 << (52 - latitudeBits);
final latitude = latitudeInt.toDouble() * (180 / pow(2.0, 52)) - 90;
final longitude = longitudeInt.toDouble() * (360 / pow(2.0, 52)) - 180;
final height = latitudeDiff.toDouble() * (180 / pow(2.0, 52));
final width = longitudeDiff.toDouble() * (360 / pow(2.0, 52));
return Rectangle<double>(latitude, longitude, height, width);
}