encode method

  1. @override
int encode(
  1. double lat,
  2. double lon,
  3. int precision
)

Encode a latitude and longitude to a geohash string of given precision (that is, bit length). To match the precision of string-based geohashes, keep in mind that every character is 5 bits.

Given the integer precision in Dart is 64 bits, the limit here is 62 bits: we use the highest bit to track the precision. Note that for the web, the limit must be 50 bits due to the JavaScript number representation.

Implementation

@override
int encode(double lat, double lon, int precision) {
  if (precision > maxPrecision || precision < 1) {
    throw ArgumentError(
        'Precision should be between 1 and $maxPrecision bits');
  }

  if (lat < -90 || lat > 90) {
    throw ArgumentError('Latitude is out of bounds: $lat');
  }

  while (lon < -180) lon += 360;
  while (lon > 180) lon -= 360;

  double minLat = -90;
  double maxLat = 90;
  double minLon = -180;
  double maxLon = 180;

  int geohash = 1;
  for (int i = 0; i < precision; i++) {
    geohash <<= 1;
    if (i & 1 == 0) {
      final midLon = (minLon + maxLon) / 2;
      if (lon >= midLon) {
        geohash |= 1;
        minLon = midLon;
      } else {
        maxLon = midLon;
      }
    } else {
      final midLat = (minLat + maxLat) / 2;
      if (lat >= midLat) {
        geohash |= 1;
        minLat = midLat;
      } else {
        maxLat = midLat;
      }
    }
  }

  return geohash;
}