adjacent method

  1. @override
String adjacent(
  1. String geohash,
  2. Direction direction
)

Returns a single neighbour of the given geohash in the direction. For diagonal directions, runs the processing twice.

Implementation

@override
String adjacent(String geohash, Direction direction) {
  if (geohash.isEmpty) {
    throw ArgumentError('Geohash cannot be empty');
  }

  // Support the diagonal directions.
  if (direction == Direction.northWest) {
    geohash = adjacent(geohash, Direction.north);
    direction = Direction.west;
  } else if (direction == Direction.northEast) {
    geohash = adjacent(geohash, Direction.north);
    direction = Direction.east;
  } else if (direction == Direction.southWest) {
    geohash = adjacent(geohash, Direction.south);
    direction = Direction.west;
  } else if (direction == Direction.southEast) {
    geohash = adjacent(geohash, Direction.south);
    direction = Direction.east;
  }

  // This implementation uses character matching. I have benchmarked it
  // against another implementation with decoding-encoding, and it was
  // 2.5 times faster.
  geohash = geohash.toLowerCase();
  final last = geohash.codeUnitAt(geohash.length - 1);
  String parent = geohash.substring(0, geohash.length - 1);
  final type = geohash.length % 2;

  final newLast = _kNeighbourUnits[direction]![type][last];
  if (newLast == null) {
    throw ArgumentError('Wrong characters in geohash "$geohash"');
  }

  if (_kBorderUnits[direction]![type].contains(last)) {
    if (parent.isNotEmpty) {
      parent = adjacent(parent, direction);
    } else if (direction == Direction.north || direction == Direction.south) {
      throw OutOfWorldBoundsException();
    }
  }

  return parent + newLast;
}