getExtents static method

Rectangle<double> getExtents(
  1. String geohash
)

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);
}