Skip to content

Krombik/marker-cluster

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MarkerCluster

MarkerCluster is a lightweight, dependency-free library for clustering markers. This package provides both synchronous and asynchronous clustering of markers based on the zoom level and the viewport's geographic bounds.

Why should I use MarkerCluster?

  • it is really fast
  • it could leverage Worker to avoid freezing while clustering a large amount of points (browsers only)
  • it does not dictate supplied points format
  • format of returned points is customizable
  • flexible for use with various map libraries

Example

import MarkerCluster from "marker-cluster";

type Point = { lat: number; lng: number };

const points: Point[] = [
  { lat: -31.56391, lng: 147.154312 },
  { lat: -33.718234, lng: 150.363181 },
  { lat: -33.727111, lng: 150.371124 },
  { lat: -33.848588, lng: 151.209834 },
];

const markerCluster = new MarkerCluster<Point>((v) => [v.lng, v.lat], {
  radius: 75,
});

markerCluster.load(points);

// or

await markerCluster.loadAsync(points);

const currPoints = markerCluster
  .setZoom(2)
  .setBounds(-180, -85, 180, 85)
  .getPoints(
    (point, uniqueKey) => ({ point, uniqueKey }),
    (lng, lat, count, expandZoom, uniqueKey, clusterId) => ({
      lng,
      lat,
      count,
      expandZoom,
      uniqueKey,
      clusterId,
    })
  );

Class: MarkerCluster<T>

Methods

Properties

Constructor

constructor(getLngLat: (item: T) => [lng: number, lat: number], options: MarkerClusterOptions)

MarkerClusterOptions

Name Type Description Default
minZoom? number min zoom level to cluster the points on 0
maxZoom? number max zoom level to cluster the points on 16
radius? number cluster radius in pixels 60
extent? number size of the tile grid used for clustering 256
callback? () => void see callback

Methods

load

load(points: T[]): this

Loads the given points and clusters them for each zoom level

Parameters

Name Type Description
points T[] The points to be clustered

loadAsync

async loadAsync(points: T[]): Promise<this>

Loads the given points and asynchronously clusters them for each zoom level

Note: this method use Worker and fallbacks to load method if worker initializing was failed


setZoom

setZoom(zoom: number): this

Sets current zoom level for getPoints method


setBounds

setBounds(
  westLng: number,
  southLat: number,
  eastLng: number,
  northLat: number
): this

Sets current bounds for getPoints method


getPoints

getPoints<M, C>(
  markerMapper: (point: T, uniqueKey: number) => M,
  clusterMapper: (
    lng: number,
    lat: number,
    count: number,
    expandZoom: number,
    uniqueKey: number,
    clusterId: number
  ) => C,
  expand?: number
): (M | C)[];

Parameters

Name Type Description
expand? number for values in range (0..1) considered as percentage, otherwise as absolute pixels value to expand given bounds}

Returns

Array of mapped clusters and points for the given zoom and bounds


getChildren

getChildren<M, C>(
  clusterId: number,
  markerMapper: (point: T, uniqueKey: number) => M,
  clusterMapper: (
    lng: number,
    lat: number,
    count: number,
    expandZoom: number,
    uniqueKey: number,
    clusterId: number
  ) => C,
): (M | C)[];

Returns

Array with mapped children of cluster


cleanup

static cleanup(): void

if loadAsync was called, use this method to abandon worker if it needed


points

points?: T[]

points from last executed loadAsync or load method


isLoading

isLoading: boolean;

Indicates whether a loading operation is currently in progress


callback

callback: () => void;

Called once the loading operation has finished executing. The purpose of the method is to provide a way for developers to be notified when clustering is complete so that they can perform any additional processing or update the UI as needed.


worker

static worker?: Worker;

Worker instance, inits at first loadAsync call


Benchmark

marker-cluster x 915 ops/sec ±1.65% (91 runs sampled)
supercluster x 148 ops/sec ±1.12% (84 runs sampled)
Fastest in loading 1,000 points is marker-cluster

marker-cluster x 53.21 ops/sec ±0.97% (70 runs sampled)
supercluster x 16.70 ops/sec ±1.63% (45 runs sampled)
Fastest in loading 10,000 points is marker-cluster

marker-cluster x 2.18 ops/sec ±2.44% (10 runs sampled)
supercluster x 1.32 ops/sec ±1.22% (8 runs sampled)
Fastest in loading 100,000 points is marker-cluster

License

MIT © Krombik