fgb-vt - v1.0.4
    Preparing search index...

    fgb-vt - v1.0.4

    npm version license node types bundle size

    fgb-vt

    Native Node/TypeScript library for high-performance Vector Tile layering, encoding and serving - directly from FlatGeobuf files. Fully utilizes FlatGeobuf's Packed Hilbert R-tree for tile-sized byte-range reads over the main feature storage.

    fgb-vt attempts to conceptually close the gap between full tile pyramid creation on the backend, database-driven tile servers and processing static datasets on the client. It is specifically designed to access large, single-file objects on cloud storage via load-efficient (HTTP) Range Requests and stateless deployment (e.g. via AWS Lambda) - targeting highly dynamic geospatial big-data mapping requirements.

    Under the hood it's binary all the way down - no GeoJSON detour, no intermediate format, just FlatBuffers in and Protobuf out, with projection, clipping and simplification natively implemented at the lowest level the types allow.

    fgb-vt supports multi-layered tiles via concurrent access to different sources - even across different storage backends. It follows a slim, three-tier API layer approach for different use cases:

    • TileServer - a semi-stateful, lazy-caching tile server over an initially configured set of sources
    • TileClient - semi-stateful, connection-optimized tile client middleware with dynamic source selection
    • tile() - semi-stateless, request-scoped, one-off tile generation function, suitable for Lambda-driven setups

    and includes a Browser bundle for client-side HTTP(S) source access.

    Shipped with three concurrency-optimized connectors:

    • LocalConnector - for local filesystem access
    • HttpConnector - for HTTP(S) with Range Requests
    • S3Connector - for Amazon S3 / compatible storage backends with Byte Range reads
    npm install @geozelot/fgb-vt
    
    import { TileClient, LocalConnector } from '@geozelot/fgb-vt';

    // set up a client with a filesystem connector
    const client = new TileClient(new LocalConnector());

    // request tile z=4, x=4, y=6 - sources are passed per call
    const pbf = await client.tile(4, 4, 6, {
    name: 'counties',
    path: './data/us_counties.fgb',
    });

    // pbf is a ready-to-serve Uint8Array (MVT/PBF encoded)
    await client.close();


    ```bash
    npm install @geozelot/fgb-vt
    ```
    
    For S3 support, add the optional peer dependency:
    
    ```bash
    npm install @aws-sdk/client-s3
    ```
    

    Browser

    ```html
    <!-- UMD -->
    <script src="https://unpkg.com/@geozelot/fgb-vt/dist/fgb-vt.umd.min.js"></script>
    
    <!-- ESM -->
    <script type="module">
      import { tile, HttpConnector } from 'https://unpkg.com/@geozelot/fgb-vt/dist/fgb-vt.esm.min.js';
    </script>
    ```
    

    Note: Browser builds ship with HttpConnector only!


    Bind connectors and sources once; call tile() for the life of the process. Headers and spatial index metadata are lazily cached on first access - maximum throughput after warm-up.

    • Single connector:

      import { TileServer, LocalConnector } from '@geozelot/fgb-vt';

      const server = new TileServer({
      connector: new LocalConnector(),
      sources: { name: 'counties', path: './data/us_counties.fgb' },
      });

      const pbf = await server.tile(4, 4, 6);
      const meta = await server.tileJSON(); // TileJSON 3.0.0
      await server.close();
    • Multi source (layered tiles):

      const server = new TileServer({
      connector: new LocalConnector(),
      sources: [
      { name: 'buildings', path: './data/buildings.fgb' },
      { name: 'roads', path: './data/roads.fgb', options: { maxZoom: 16 } },
      ],
      });
    • Multi connector:

      const server = new TileServer([
      { connector: new LocalConnector(), sources: { name: 'local', path: './local.fgb' } },
      { connector: new HttpConnector(), sources: { name: 'remote', path: 'https://cdn.example.com/remote.fgb' } },
      ]);

    Connector bound at construction; sources provided per call. One connector, varying datasets - well suited for middleware or request-scoped source selection.

    • Single source:

      import { TileClient, HttpConnector } from '@geozelot/fgb-vt';

      const client = new TileClient(
      new HttpConnector({ headers: { Authorization: 'Bearer ...' } }),
      );

      const pbf = await client.tile(14, 8192, 5461, {
      name: 'parcels', path: 'https://data.example.com/parcels.fgb',
      });
      await client.close();
    • Multi source (layered tiles):

      const pbf = await client.tile(12, 2048, 1365, [
      { name: 'water', path: '/data/water.fgb' },
      { name: 'roads', path: '/data/roads.fgb' },
      ]);

    Everything per call - connector, coordinates, sources. No instance state beyond a module-level tile bounds cache. Drop it into a Lambda and call it a day.

    • Single source:

      import { tile, LocalConnector } from '@geozelot/fgb-vt';

      const connector = new LocalConnector();
      const pbf = await tile(connector, 14, 8192, 5461, {
      name: 'poi', path: './data/poi.fgb',
      });
      await connector.close();
    • Multi source:

      const pbf = await tile(connector, 14, 8192, 5461, [
      { name: 'buildings', path: './data/buildings.fgb' },
      { name: 'roads', path: './data/roads.fgb' },
      ]);

    Use the browser bundle to turn any hosted .fgb into a vector tile source - no tile server required:

    <script src="https://unpkg.com/@geozelot/fgb-vt/dist/fgb-vt.umd.min.js"></script>
    <script>
    const client = new fgbvt.TileClient(new fgbvt.HttpConnector());

    // generate tiles on demand, client-side
    const pbf = await client.tile(14, 8192, 5461, {
    name: 'counties', path: 'https://data.example.com/counties.fgb',
    });
    </script>

    Connectors abstract concurrent byte-range I/O across storage backends. Each implements the Connector interface.

    Connector Reads from Path format
    LocalConnector filesystem ./data/buildings.fgb
    HttpConnector HTTP(S) with Range Requests https://cdn.example.com/roads.fgb
    S3Connector Amazon S3 / compatible s3://bucket/key.fgb
    new LocalConnector({ maxOpenFiles: 64 })

    new HttpConnector({
    headers: { Authorization: 'Bearer ...' },
    timeout: 30_000,
    maxConcurrency: 6,
    retry: { attempts: 3, backoff: 200 },
    })

    new S3Connector({
    region: 'us-east-1',
    credentials: { accessKeyId: '...', secretAccessKey: '...' },
    maxConcurrency: 6,
    endpoint: 'http://localhost:9000' // for S3-compatible storage backends
    })

    Options cascade through three levels - source overrides tile-level defaults overrides built-in defaults:

    Option Default Description
    extent 4096 Tile coordinate extent
    buffer 64 Buffer around tile in tile-coordinate pixels
    tolerance 3 Douglas-Peucker simplification tolerance
    minZoom 0 Skip source below this zoom
    maxZoom 24 Skip source above this zoom
    const server = new TileServer(
    {
    connector: new LocalConnector(),
    sources: [
    { name: 'detail', path: './detail.fgb', options: { tolerance: 1 } }, // tolerance=1
    { name: 'overview', path: './overview.fgb' }, // tolerance=5 (from tile defaults)
    ],
    },
    { tolerance: 5, maxZoom: 18 }, // tile-level defaults
    );
    import type {
    Connector,
    Source, SourceOptions, TileOptions,
    TileServerLayer, TileJSON, BBox,
    LocalConnectorOptions, HttpConnectorOptions, S3ConnectorOptions,
    } from '@geozelot/fgb-vt';

    npm test
    

    Runs the full test suite via Vitest.

    npm run bench
    
    Stage Input Throughput
    Projection 1,000 coord pairs ~38k ops/s
    Clipping 50 polygons (20v) ~22k ops/s
    Simplification 200-point line ~91k ops/s
    MVT Encoding 100-point line ~1.6M ops/s
    PBF Encoding 100-feature layer ~17k ops/s
    Full Pipeline 100 mixed features ~2.6k ops/s

    MIT