polyfill method
List<BigInt>
polyfill({
- required List<
GeoCoord> coordinates, - required int resolution,
- List<
List< holes = const [],GeoCoord> >
override
Takes a given coordinates
and resolution
and returns hexagons that
are contained by them.
resolution
must be in the range 0, 15
.
This implementation traces the GeoJSON geofence(s) in cartesian space with hexagons, tests them and their neighbors to be contained by the geofence(s), and then any newly found hexagons are used to test again until no new hexagons are found.
final hexagons = h3.polyfill(
coordinates: const [
GeoCoord(lat: 37.813318999983238, lon: -122.4089866999972145),
GeoCoord(lat: 37.7866302000007224, lon: -122.3805436999997056),
GeoCoord(lat: 37.7198061999978478, lon: -122.3544736999993603),
GeoCoord(lat: 37.7076131999975672, lon: -122.5123436999983966),
GeoCoord(lat: 37.7835871999971715, lon: -122.5247187000021967),
GeoCoord(lat: 37.8151571999998453, lon: -122.4798767000009008),
],
resolution: 9,
)
Implementation
@override
List<BigInt> polyfill({
required List<GeoCoord> coordinates,
required int resolution,
List<List<GeoCoord>> holes = const [],
}) {
assert(resolution >= 0 && resolution < 16,
'Resolution must be in [0, 15] range');
return using((arena) {
// polygon outer boundary
final nativeCoordinatesPointer = arena<c.GeoCoord>(coordinates.length);
for (var i = 0; i < coordinates.length; i++) {
final pointer = Pointer<c.GeoCoord>.fromAddress(
nativeCoordinatesPointer.address + sizeOf<c.GeoCoord>() * i,
);
coordinates[i]
.toRadians(_geoCoordConverter)
.assignToNative(pointer.ref);
}
final polygon = arena<c.GeoPolygon>();
final outergeofence = arena<c.Geofence>();
// outer boundary
polygon.ref.geofence = outergeofence.ref;
polygon.ref.geofence.verts = nativeCoordinatesPointer;
polygon.ref.geofence.numVerts = coordinates.length;
// polygon holes
if (holes.isNotEmpty) {
final holesgeofencePointer = arena<c.Geofence>(holes.length);
for (var h = 0; h < holes.length; h++) {
final holeCoords = holes[h];
final singleHoleGFencePointer = Pointer<c.Geofence>.fromAddress(
holesgeofencePointer.address + sizeOf<c.Geofence>() * h,
);
final holeNativeCoordinatesPointer =
arena<c.GeoCoord>(holeCoords.length);
// assign the hole coord to holeptr
for (var i = 0; i < holeCoords.length; i++) {
final coordPointer = Pointer<c.GeoCoord>.fromAddress(
holeNativeCoordinatesPointer.address +
sizeOf<c.GeoCoord>() * i);
holeCoords[i]
.toRadians(_geoCoordConverter)
.assignToNative(coordPointer.ref);
}
singleHoleGFencePointer.ref.numVerts = holeCoords.length;
singleHoleGFencePointer.ref.verts = holeNativeCoordinatesPointer;
}
polygon.ref.numHoles = holes.length;
polygon.ref.holes = holesgeofencePointer;
} else {
polygon.ref.numHoles = 0;
polygon.ref.holes = Pointer.fromAddress(0);
}
final nbIndex = _h3c.maxPolyfillSize(polygon, resolution);
final out = arena<Uint64>(nbIndex);
_h3c.polyfill(polygon, resolution, out);
final list = out.asTypedList(nbIndex).toList();
return list.where((e) => e != 0).map((e) => e.toBigInt()).toList();
});
}