adjacent method
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;
}