# How to Integrate External Data Sources with GeoLibre: Overture Maps, Planetary Computer, and Earth Engine

> Integrate Overture Maps, Planetary Computer, and Earth Engine with GeoLibre by implementing the TimelapseProvider interface. Learn how to add external raster services.

- Repository: [Open Geospatial Solutions/GeoLibre](https://github.com/opengeos/GeoLibre)
- Tags: how-to-guide
- Published: 2026-08-03

---

**Integrate any external raster service into GeoLibre by implementing the `TimelapseProvider` interface, which converts remote tile URLs into map layers through the Zustand store and MapLibre sync layer.**

GeoLibre is architected as a **plugin‑driven, store‑driven application** where all map data flows through `GeoLibreLayer` records in the central Zustand store. This design makes it straightforward to bring in external imagery from sources like **Google Earth Engine**, **Microsoft Planetary Computer**, or **Overture Maps**. The integration pattern is consistent across providers: generate tile‑URL templates, wrap them in `TimelapseFrame` objects, and register a provider that the Timelapse control consumes automatically.

## Understanding the Layer Architecture

Every raster or vector layer that appears on the map originates as a `GeoLibreLayer` in the store. The [`packages/map/src/MapController.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/map/src/MapController.ts) file handles synchronizing these store records to actual MapLibre sources through its `syncLayers` method. For external raster services, you don't manipulate the store directly—instead, you implement a provider that generates frame objects containing tile URL templates.

The `TimelapseProvider` interface in [`packages/plugins/src/plugins/timelapse-providers.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/plugins/src/plugins/timelapse-providers.ts) defines the contract:

- **`id`** – unique provider identifier
- **`name`** – human‑readable label shown in the UI picker
- **`attribution`** – credit string rendered on the map
- **`listFrames()`** – async method returning `TimelapseFrame[]` with tile URLs, zoom limits, and metadata

When a user selects a frame, the Timelapse control instantiates a raster source using the `tileUrlTemplate` and adds it to the map through the standard store → `MapController` → MapLibre pipeline.

## Integrating Google Earth Engine

Earth Engine exposes raster data through `getMapId()` (or `getTileUrl()`), which returns a tile template string containing `{z}/{x}/{y}` placeholders. Your provider wraps these templates into frames.

```typescript
import { TimelapseProvider, TimelapseFrame } from "./timelapse-providers";
import { registerTimelapseProvider } from "./timelapse-providers";

/** Fetches a tile URL template for a specific year from EE. */
async function eeTileUrl(year: number): Promise<string> {
  const collection = ee.ImageCollection("MODIS/061/MOD13A2")
    .filter(ee.Filter.calendarRange(year, year, "year"));
  const image = collection.first();
  const { tileUrl } = image.getMap({ format: "png" });
  // Returns: "https://earthengine.googleapis.com/map/{mapid}/{z}/{x}/{y}?token=..."
  return tileUrl;
}

const earthEngineProvider: TimelapseProvider = {
  id: "ee-modis-ndvi",
  name: "Google Earth Engine NDVI",
  attribution: "© Google Earth Engine",
  async listFrames() {
    const years = [2018, 2019, 2020, 2021];
    const frames: TimelapseFrame[] = await Promise.all(
      years.map(async (y) => ({
        id: `ee-modis-${y}`,
        label: `${y}`,
        year: y,
        tileUrlTemplate: await eeTileUrl(y),
        attribution: `NDVI ${y} via Google Earth Engine`,
        minzoom: 0,
        maxzoom: 12,
      }))
    );
    return frames;
  },
};

registerTimelapseProvider(earthEngineProvider);

```

The [`earth-engine-auth.ts`](https://github.com/opengeos/GeoLibre/blob/main/earth-engine-auth.ts) file in the same directory handles OAuth authentication and reports availability to the UI, so your provider can assume an authenticated EE client is present when registered.

## Integrating Microsoft Planetary Computer

Planetary Computer serves imagery through its **STAC API**. You query for collections, extract asset URLs, and construct tile templates. The signed URLs returned by Planetary Computer typically include the `{z}/{x}/{y}` structure directly.

```typescript
import { TimelapseProvider, TimelapseFrame } from "./timelapse-providers";
import { registerTimelapseProvider } from "./timelapse-providers";

const PC_SEARCH_URL = "https://planetarycomputer.microsoft.com/api/stac/v1/search";

async function fetchPcMosaic(year: number): Promise<string> {
  const body = {
    collections: ["sentinel-2-l2a"],
    datetime: `${year}-01-01/${year}-12-31`,
    limit: 1,
    query: { "eo:cloud_cover": { lt: 0.1 } },
  };
  const resp = await fetch(PC_SEARCH_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });
  const json = await resp.json();
  const asset = json.features[0].assets["visual"];
  // Signed href contains z/x/y placeholders ready for MapLibre
  return asset.href;
}

const planetaryComputerProvider: TimelapseProvider = {
  id: "pc-sentinel2",
  name: "Planetary Computer Sentinel-2",
  attribution: "© Microsoft Planetary Computer",
  async listFrames() {
    const years = [2020, 2021, 2022];
    const frames: TimelapseFrame[] = await Promise.all(
      years.map(async (y) => ({
        id: `pc-s2-${y}`,
        label: `${y}`,
        year: y,
        tileUrlTemplate: await fetchPcMosaic(y),
        attribution: `Sentinel-2 ${y} via Planetary Computer`,
        minzoom: 0,
        maxzoom: 14,
      }))
    );
    return frames;
  },
};

registerTimelapseProvider(planetaryComputerProvider);

```

Because Planetary Computer returns signed URLs with embedded tokens, each frame carries a complete, authenticated tile template that requires no additional request headers.

## Integrating Overture Maps and Other Tile Sources

Overture Maps distributes vector tiles through AWS S3 or CDN endpoints. For raster‑style integration, you can:

- **Create a vector tile provider** – Implement a variant of `TimelapseProvider` that returns `vector` type sources instead of raster, pointing to Overture's `{z}/{x}/{y}.pbf` endpoints
- **Use a raster proxy** – Pre‑render Overture data into raster tiles, then follow the standard provider pattern above

The [`source-coop-api.ts`](https://github.com/opengeos/GeoLibre/blob/main/source-coop-api.ts) file demonstrates how to structure catalog‑based providers that query external APIs before generating frames. Adapt this pattern for Overture's partition‑based data layout:

1. Query Overture's release manifest for available themes (buildings, places, transportation)
2. Generate one `TimelapseFrame` per theme or version
3. Point `tileUrlTemplate` to the appropriate tile endpoint (e.g., `https://overturemaps-tiles.s3.amazonaws.com/2024-04-16/buildings/{z}/{x}/{y}.pbf`)

## Registering and Activating Your Provider

The provider lifecycle follows three stages:

1. **Import and register** – Your provider file imports `registerTimelapseProvider` from [`timelapse-providers.ts`](https://github.com/opengeos/GeoLibre/blob/main/timelapse-providers.ts) and calls it at module initialization
2. **UI discovery** – [`TimelapseControl.tsx`](https://github.com/opengeos/GeoLibre/blob/main/TimelapseControl.tsx) reads the `timelapseProviders` registry and populates the provider picker dropdown
3. **Frame activation** – On user selection, `listFrames()` executes, and the returned frames populate the year slider. Selecting a frame triggers [`MapController.ts`](https://github.com/opengeos/GeoLibre/blob/main/MapController.ts) → `syncLayers` to create the MapLibre raster source

Ensure your provider module is imported early—typically in [`packages/plugins/src/index.ts`](https://github.com/opengeos/GeoLibre/blob/main/packages/plugins/src/index.ts) or equivalent—to guarantee registration before the Timelapse UI mounts.

## Handling Custom Formats and Size Limits

Remote data integration must respect GeoLibre's format classification system. The [`remote-file-formats.ts`](https://github.com/opengeos/GeoLibre/blob/main/remote-file-formats.ts) file centralizes:

- **Format detection** – Mapping file extensions to processing strategies
- **Size limits** – Enforcing DuckDB and memory constraints for downloaded data

If your external source uses a non‑standard extension or URL pattern, extend the `RemoteFileFormat` union type and add detection logic in [`remote-file-formats.ts`](https://github.com/opengeos/GeoLibre/blob/main/remote-file-formats.ts). This ensures consistent behavior for size‑checking and streaming limits across all remote sources.

## Summary

- **Implement `TimelapseProvider`** – Define `id`, `name`, `attribution`, and `listFrames()` to generate tile‑URL templates for any external service
- **Wrap Earth Engine** – Use `getMap()` or `getTileUrl()` to obtain authenticated tile templates, then return them as `TimelapseFrame` objects
- **Query Planetary Computer** – Hit the STAC API, extract signed asset URLs, and convert to frames with appropriate zoom limits
- **Register early** – Call `registerTimelapseProvider()` at module load so [`TimelapseControl.tsx`](https://github.com/opengeos/GeoLibre/blob/main/TimelapseControl.tsx) discovers your source
- **Extend formats if needed** – Add new URL patterns to [`remote-file-formats.ts`](https://github.com/opengeos/GeoLibre/blob/main/remote-file-formats.ts) to maintain consistent size and streaming behavior

## Frequently Asked Questions

### What file should I modify to add a new external data provider?

Create a new TypeScript file in `packages/plugins/src/plugins/` that implements `TimelapseProvider`, then import and register it in the package index. The [`timelapse-providers.ts`](https://github.com/opengeos/GeoLibre/blob/main/timelapse-providers.ts) file defines the interface and registry, while [`source-coop-api.ts`](https://github.com/opengeos/GeoLibre/blob/main/source-coop-api.ts) provides a working template for API‑based providers.

### Does GeoLibre support vector tiles from Overture Maps?

Yes. The provider pattern accepts any MapLibre‑compatible source. For vector tiles, return a `TimelapseFrame` with a URL template pointing to `.pbf` endpoints and ensure your consuming code sets the source type to `vector`. You may need to extend [`MapController.ts`](https://github.com/opengeos/GeoLibre/blob/main/MapController.ts) logic if you require custom layer styling beyond the default raster handling.

### How does authentication work for Earth Engine?

The [`earth-engine-auth.ts`](https://github.com/opengeos/GeoLibre/blob/main/earth-engine-auth.ts) plugin manages OAuth flow and exposes an authenticated `ee` client globally. Your provider can assume this client is initialized when `listFrames()` is called. For production deployments, ensure the token refresh logic in [`earth-engine-auth.ts`](https://github.com/opengeos/GeoLibre/blob/main/earth-engine-auth.ts) remains active throughout the session.

### Can I combine multiple external sources in one provider?

Yes. A single `TimelapseProvider` can return frames from heterogeneous sources—mix Earth Engine, Planetary Computer, and custom endpoints. Each `TimelapseFrame` carries its own `tileUrlTemplate` and `attribution`, so the map renders them uniformly through the same `syncLayers` pipeline.