UNPKG

react-map-gl-supercluster

Version:

> The easiest way to get `react-map-gl` and `supercluster` to work together

138 lines 5.43 kB
import Supercluster, { ClusterFeature, PointFeature } from "supercluster"; //#region src/types.d.ts /** Plain GeoJSON properties object used by points and clusters. */ type GeoJsonProperties = Record<string, unknown>; /** * Point properties accepted by `useSupercluster`. * * The `cluster` key is reserved: generated clusters use it as a discriminator, * so input points must not define it. Use `isCluster` to tell features apart. * * @example * ```ts * type CityPoint = { name: string; population: number } // satisfies PointFeatureProperties * ``` */ type PointFeatureProperties = GeoJsonProperties & { cluster?: never; }; /** A feature returned from `useSupercluster`: either an original point or a generated cluster. */ type Cluster<TFeatureProperties extends GeoJsonProperties, TClusterProperties extends GeoJsonProperties> = PointFeature<TFeatureProperties> | ClusterFeature<TClusterProperties>; /** * Loaded `supercluster` instance returned by the hook. * * Use it for advanced reads such as leaves, children, and expansion zoom. * * @example * ```ts * const zoom = supercluster.getClusterExpansionZoom(clusterId) * ``` */ type SuperclusterInstance<TFeatureProperties extends GeoJsonProperties, TClusterProperties extends GeoJsonProperties> = Omit<Supercluster<TFeatureProperties, TClusterProperties>, 'load'>; /** * Maps point properties to the aggregate properties used by clusters. * * Mirrors `supercluster`'s `map` option. * * @example * ```ts * type City = { name: string; population: number } * type CityCluster = { population: number } * * const map: MapFeatureToCluster<City, CityCluster> = (point) => ({ * population: point.population, * }) * ``` */ type MapFeatureToCluster<TFeatureProperties extends GeoJsonProperties, TClusterProperties extends GeoJsonProperties> = (feature: TFeatureProperties) => TClusterProperties; /** * Merges aggregate properties while building clusters. * * Mirrors `supercluster`'s `reduce` option. * * @example * ```ts * const reduce: ReduceCluster<CityCluster> = (memo, point) => { * memo.population += point.population * } * ``` */ type ReduceCluster<TClusterProperties extends GeoJsonProperties> = (memo: TClusterProperties, feature: Readonly<TClusterProperties>) => void; /** * Options passed to the underlying `supercluster` index. * * Function options should be stable between renders. * * @example * ```ts * const options = { * radius: 60, * maxZoom: 18, * map, * reduce, * } * ``` */ type SuperclusterOptions<TFeatureProperties extends GeoJsonProperties, TClusterProperties extends GeoJsonProperties> = { minZoom?: number | undefined; maxZoom?: number | undefined; radius?: number | undefined; minPoints?: number | undefined; extent?: number | undefined; nodeSize?: number | undefined; generateId?: boolean | undefined; map?: MapFeatureToCluster<TFeatureProperties, TClusterProperties> | undefined; reduce?: ReduceCluster<TClusterProperties> | undefined; }; type LngLatBounds = { toArray(): number[][]; }; type MapEventListener = (...args: unknown[]) => void; /** Minimal structural contract satisfied by every `react-map-gl` `MapRef` flavor. */ type MapLike = { getBounds(): LngLatBounds | null; getZoom(): number; on(type: string, listener: MapEventListener): void; off(type: string, listener?: MapEventListener): void; }; //#endregion //#region src/use-supercluster.d.ts /** Values returned by `useSupercluster`. */ type UseSuperclusterReturnValue<TFeatureProperties extends GeoJsonProperties, TClusterProperties extends GeoJsonProperties> = { /** Clusters for the current — optionally padded — map bounds and rounded zoom. */ clusters: Array<Cluster<TFeatureProperties, TClusterProperties>>; /** Loaded index for advanced `supercluster` queries. */ supercluster: SuperclusterInstance<TFeatureProperties, TClusterProperties>; }; /** * Hook options. * * Pass `mapRef` when the map is outside `react-map-gl` context or when several maps are mounted. */ type UseSuperclusterOptions<MapRef extends MapLike, TFeatureProperties extends GeoJsonProperties, TClusterProperties extends GeoJsonProperties> = SuperclusterOptions<TFeatureProperties, TClusterProperties> & { mapRef?: MapRef | undefined | null; /** * Extra viewport fraction (per side) included when querying clusters. * * Markers near the edges don't pop in and out, and pans inside the padded * area at the same rounded zoom skip recomputation entirely. The queried * area grows as `(1 + 2 * padding)²`, so large values render more * off-screen markers. Non-positive values disable padding. * * @default 0 */ boundsPadding?: number | undefined; }; //#endregion //#region src/is-cluster.d.ts /** * Narrows a feature returned from `useSupercluster` to a generated cluster. * * @example * ```tsx * clusters.map((feature) => (isCluster(feature) ? renderCluster(feature) : renderPoint(feature))) * ``` */ declare function isCluster<TFeatureProperties extends PointFeatureProperties, TClusterProperties extends GeoJsonProperties>(feature: Cluster<TFeatureProperties, TClusterProperties>): feature is ClusterFeature<TClusterProperties>; //#endregion export { ClusterFeature as a, PointFeatureProperties as c, Cluster as i, SuperclusterInstance as l, UseSuperclusterOptions as n, GeoJsonProperties as o, UseSuperclusterReturnValue as r, PointFeature as s, isCluster as t };