buildAMapClusters<T> function

List<AMapCluster<T>> buildAMapClusters<T>({
  1. required Iterable<T> items,
  2. required double zoom,
  3. required AMapClusterPositionResolver<T> positionOf,
  4. AMapClusterOptions options = const AMapClusterOptions(),
})

Implementation

List<AMapCluster<T>> buildAMapClusters<T>({
  required Iterable<T> items,
  required double zoom,
  required AMapClusterPositionResolver<T> positionOf,
  AMapClusterOptions options = const AMapClusterOptions(),
}) {
  if (!options.shouldClusterAtZoom(zoom)) {
    return items
        .map((item) {
          final LatLng position = positionOf(item);
          return AMapCluster<T>(
            items: <T>[item],
            center: position,
            cellKey: '${position.latitude}:${position.longitude}',
            isCluster: false,
          );
        })
        .toList(growable: false);
  }

  final Map<String, _AMapClusterBucket<T>> buckets =
      <String, _AMapClusterBucket<T>>{};

  for (final T item in items) {
    final LatLng position = positionOf(item);
    final _WorldPixel pixel = _toWorldPixel(
      lat: position.latitude,
      lng: position.longitude,
      zoom: zoom,
    );
    final int gridX = (pixel.x / options.gridSizePx).floor();
    final int gridY = (pixel.y / options.gridSizePx).floor();
    final String key = '$gridX:$gridY';
    final _AMapClusterBucket<T> bucket = buckets.putIfAbsent(
      key,
      () => _AMapClusterBucket<T>(),
    );
    bucket.add(item, position);
  }

  return buckets.entries.map((entry) {
    final _AMapClusterBucket<T> bucket = entry.value;
    final bool isCluster = bucket.count >= options.minClusterSize;
    if (!isCluster) {
      final T item = bucket.items.first;
      final LatLng position = bucket.positions.first;
      return AMapCluster<T>(
        items: <T>[item],
        center: position,
        cellKey: entry.key,
        isCluster: false,
      );
    }
    return AMapCluster<T>(
      items: List<T>.unmodifiable(bucket.items),
      center: bucket.center,
      cellKey: entry.key,
      isCluster: true,
    );
  }).toList(growable: false);
}