flatbush

repository·main·Indexed 22 days ago

https://github.com/mourner/flatbush

A high-performance, static spatial index for 2D points and rectangles in JavaScript using the packed Hilbert R-tree algorithm. Designed for datasets known upfront, it offers fast spatial queries and k-nearest-neighbor (KNN) searches with minimal memory overhead. The index is stored in a single ArrayBuffer, allowing for efficient transfer between threads or saving to a file. Version 4.6.2.

Tokens
2K
Snippets
5
Records
12
Agent score
32%

What's inside flatbush

  1. How Flatbush works: Static Spatial Indexing

    main

    Flatbush is a static spatial index for 2D points and rectangles using the packed Hilbert R-tree algorithm.

    Key Characteristics:

    • Static: You cannot add or remove items once the index is built. You must define the number of items upfront, add them, and then call .finish().
    • Performance: Optimized for fast indexing and searching with a low memory footprint.
    • Binary Storage: The index is stored in a single ArrayBuffer (accessible via index.data), making it easy to transfer between threads (e.g., via postMessage) or save to a file.

    Typical Workflow:

    1. Initialize with the total number of items.
    2. Add items using .add().
    3. Finalize the index with .finish().
    4. Perform queries using .search() or .neighbors().
    const index = new Flatbush(1000);
    for (const p of items) {
        index.add(p.minX, p.minY, p.maxX, p.maxY);
    }
    index.finish();
    
    const found = index.search(minX, minY, maxX, maxY).map((i) => items[i]);
  2. Install Flatbush

    main

    You can install Flatbush via NPM for Node.js environments or use it directly in the browser via CDN.

    NPM

    npm install flatbush

    Browser (ESM)

    Use jsDelivr to import as a module:

    <script type="module">
        import Flatbush from 'https://cdn.jsdelivr.net/npm/flatbush/+esm';
    </script>

    Browser (Global Variable)

    Use the standard script tag for a bundle with a Flatbush global:

    <script src="https://cdn.jsdelivr.net/npm/flatbush"></script>
    npm install flatbush
  3. Search for items in a bounding box

    main

    Returns an array of indices of items intersecting or touching a given bounding box. Item indices correspond to the values returned by index.add().

    Options:

    • filterFn: A callback function (i, x0, y0, x1, y1) => boolean. If provided, only items for which the function returns a truthy value are included. If you provide a callback with arguments, you can handle results directly inside the search call instead of receiving an array.

    Examples:

    Basic search:

    const ids = index.search(10, 10, 20, 20);

    Search with a filter:

    const ids = index.search(10, 10, 20, 20, (i) => items[i].foo === 'bar');

    Handling results via callback:

    index.search(10, 10, 20, 20, (i, x0, y0, x1, y1) => {
        console.log(`Item found: ${items[i]}, bbox: ${x0} ${y0} ${x1} ${y1}`);
    });
    index.search(minX, minY, maxX, maxY[, filterFn])
  4. Perform K-Nearest-Neighbors (KNN) queries

    main

    Returns an array of item indices ordered by distance from the given (x, y) coordinates.

    Options:

    • maxResults: Maximum number of neighbors to return (default: Infinity).
    • maxDistance: Maximum distance to search (default: Infinity).
    • filterFn: A callback function (i) => boolean to filter potential results. Unlike search, you should not use the callback to handle results; it is only for filtering.

    Example:

    const ids = index.neighbors(10, 10, 5); // returns 5 closest ids
    index.neighbors(x, y[, maxResults, maxDistance, filterFn])
  5. Reconstruct an index from an ArrayBuffer

    main

    Creates a new Flatbush instance from an existing ArrayBuffer or SharedArrayBuffer. This is the primary method for transferring an index from a Web Worker to the main thread or loading a saved index from a file.

    Example:

    // Reconstruct from data received in a message event
    const index = Flatbush.from(e.data);
    
    // Or transfer via postMessage
    postMessage(index.data, [index.data]);
    Flatbush.from(data[, byteOffset])
  6. Reference: Flatbush Properties

    main

    The following properties are available on a Flatbush instance:

    • data: The underlying array buffer holding the index.
    • minX, minY, maxX, maxY: The bounding box of the entire dataset.
    • numItems: Total number of stored items.
    • nodeSize: Number of items in a node tree.
    • ArrayType: The type used for internal coordinate storage.
    • IndexArrayType: The type used for internal item index storage.
  7. Initialize a Flatbush index

    main

    You can create a new Flatbush index by calling the Flatbush constructor. You must specify the number of items the index will hold. You can optionally configure the nodeSize, the ArrayType used for coordinate storage, and the ArrayBufferType used for the underlying data storage.

    Parameters:

    • numItems (number): The total number of rectangles to be added. Required.
    • nodeSize (number, default: 16): The size of the tree node. Must be between 2 and 65535.
    • ArrayType (TypedArrayConstructor, default: Float64Array): The typed array class used for coordinates.
    • ArrayBufferType (ArrayBufferConstructor | SharedArrayBufferConstructor, default: ArrayBuffer): The buffer type used to store data.
  8. Add rectangles to the index

    main

    Use the add method to insert rectangles into the index. Each rectangle is defined by its bounding box coordinates. The method returns a zero-based, incremental index representing the newly added rectangle, which you can use to retrieve the item later during searches.

    Parameters:

    • minX (number): Minimum X coordinate.
    • minY (number): Minimum Y coordinate.
    • maxX (number, default: minX): Maximum X coordinate.
    • maxY (number, default: minY): Maximum Y coordinate.

    Returns:

    • number: The zero-based index of the added rectangle.
  9. Recreate an index from raw data with from()

    main

    The static from() method allows you to recreate a Flatbush index from an existing ArrayBuffer or SharedArrayBuffer. This is highly efficient for loading pre-built indexes from disk or transferring them between workers.

    Parameters:

    • data (ArrayBufferLike): The buffer containing the serialized Flatbush data.
    • byteOffset (number, default: 0): The byte offset to the start of the Flatbush buffer. Must be 8-byte aligned.

    Returns:

    • Flatbush: A new index instance pointing to the provided data.

    Throws:

    • If byteOffset is not 8-byte aligned.
    • If data is not an ArrayBuffer or SharedArrayBuffer.
    • If the data does not contain the Flatbush magic number (0xfb).
    • If the version in the data does not match the current library version.
  10. Search the index by a bounding box

    main

    The search method performs a spatial query to find all items that intersect or touch a given bounding box.

    Parameters:

    • minX (number): Minimum X of the query box.
    • minY (number): Minimum Y of the query box.
    • maxX (number): Maximum X of the query box.
    • maxY (number): Maximum Y of the query box.
    • filterFn (function, optional): A callback function (index, x0, y0, x1, y1) => boolean. If provided, only items where this function returns true will be included in the results. The arguments represent the item's index and its bounding box coordinates.

    Returns:

    • number[]: An array of indices of the items found.
  11. Finalize the index with finish()

    main

    After adding all rectangles using add(), you must call finish() before performing any spatial queries. The finish() method performs the actual indexing (sorting items via Hilbert values and building the R-tree structure). If you attempt to search before calling finish(), an error will be thrown.

    Note: You must add exactly the number of items specified in the constructor, or finish() will throw an error.

  12. Find nearest neighbors

    main

    The neighbors method searches for items in order of their distance from a specific point $(x, y)$. This is useful for k-nearest-neighbor (k-NN) queries.

    Parameters:

    • x (number): The X coordinate of the point.
    • y (number): The Y coordinate of the point.
    • maxResults (number, default: Infinity): The maximum number of neighbors to return.
    • maxDistance (number, default: Infinity): The maximum distance to search within.
    • filterFn (function, optional): A callback function (index) => boolean used to filter results.

    Returns:

    • number[]: An array of indices of the items found, sorted by distance.