Skip to content

Data Sources

Data sources provide the data for map layers. maplibre-yaml supports all MapLibre GL JS source types with enhanced features for dynamic data loading, real-time updates, and streaming.

TypeDescriptionUse Case
geojsonGeoJSON point, line, and polygon dataPrimary data source, supports real-time updates
vectorVector tiles (Mapbox Vector Tiles)Efficient large datasets, base maps
rasterRaster tile imagerySatellite imagery, hillshading
imageSingle image overlayMap overlays, floor plans
videoVideo overlayAnimated overlays

The primary data source type with comprehensive support for dynamic data loading.

StrategyDescriptionWhen to Use
runtime (default)Fetch when map loadsKeep bundle small, fresh data
buildFetch at build timeFaster load, static data
hybridBuild-time with runtime refreshBest of both: fast initial + updates
source:
type: geojson
url: "https://example.com/data.geojson"
fetchStrategy: runtime

One of these is required:

PropertyTypeDescription
urlstringURL to fetch GeoJSON data
dataobjectInline GeoJSON object
prefetchedDataobjectPre-fetched data from build time
source:
type: geojson
url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson"
source:
type: geojson
data:
type: FeatureCollection
features:
- type: Feature
geometry:
type: Point
coordinates: [-74.006, 40.7128]
properties:
name: "New York"
population: 8336817
- type: Feature
geometry:
type: Point
coordinates: [-118.2437, 34.0522]
properties:
name: "Los Angeles"
population: 3979576
source:
type: geojson
url: "https://example.com/static-data.geojson"
fetchStrategy: build

Periodically refresh data from a URL.

source:
type: geojson
url: "https://api.example.com/live-data"
refresh:
refreshInterval: 5000 # Fetch every 5 seconds
updateStrategy: replace # Replace all data
StrategyDescriptionUse Case
replaceReplace all dataComplete data refresh
mergeMerge by unique keyUpdate/add features
append-windowAppend with size/time limitsTime-series data
source:
type: geojson
url: "https://api.example.com/current-weather"
refresh:
refreshInterval: 300000 # 5 minutes
updateStrategy: replace

Update existing features by unique key:

source:
type: geojson
url: "https://api.example.com/vehicles"
refresh:
refreshInterval: 10000
updateStrategy: merge
updateKey: "vehicleId" # Required for merge

Keep only recent data:

source:
type: geojson
url: "https://api.example.com/events"
refresh:
refreshInterval: 15000
updateStrategy: append-window
windowSize: 100 # Max 100 features
windowDuration: 3600000 # Max 1 hour old
timestampField: "timestamp" # Feature property with timestamp

Real-time data via WebSocket or Server-Sent Events.

source:
type: geojson
stream:
type: websocket
url: "wss://api.example.com/stream"
reconnect: true
reconnectMaxAttempts: 10
reconnectDelay: 1000
reconnectMaxDelay: 30000
protocols: ["json", "v1"]
refresh:
updateStrategy: merge
updateKey: "id"
source:
type: geojson
stream:
type: sse
url: "https://api.example.com/events"
eventTypes: ["update", "delete", "create"]
reconnect: true
refresh:
updateStrategy: merge
updateKey: "id"
PropertyTypeDefaultDescription
type"websocket" | "sse"-Connection type
urlstring-Endpoint URL
reconnectbooleantrueAuto-reconnect on disconnect
reconnectMaxAttemptsnumber10Max reconnection attempts
reconnectDelaynumber1000Initial reconnect delay (ms)
reconnectMaxDelaynumber30000Max reconnect delay (ms)
eventTypesstring[]-SSE event types to listen for
protocolsstring | string[]-WebSocket sub-protocols

Automatically cluster nearby points at lower zoom levels.

source:
type: geojson
url: "https://example.com/points.geojson"
cluster: true
clusterRadius: 50
clusterMaxZoom: 14
clusterMinPoints: 2
PropertyTypeDefaultDescription
clusterbooleanfalseEnable clustering
clusterRadiusnumber50Cluster radius in pixels
clusterMaxZoomnumber-Max zoom to cluster
clusterMinPointsnumber2Min points to form cluster
clusterPropertiesobject-Aggregate cluster properties

Calculate aggregates for clusters:

source:
type: geojson
url: "https://example.com/earthquakes.geojson"
cluster: true
clusterRadius: 50
clusterMaxZoom: 14
clusterProperties:
maxMagnitude: ["max", ["get", "magnitude"]]
avgMagnitude: ["avg", ["get", "magnitude"]]
count: ["+", 1]

Configure loading indicators while data is fetching.

source:
type: geojson
url: "https://example.com/large-dataset.geojson"
loading:
enabled: true
message: "Loading earthquake data..."
showErrorOverlay: true
PropertyTypeDefaultDescription
enabledbooleanfalseShow loading overlay
messagestring-Custom loading message
showErrorOverlaybooleantrueShow errors in overlay

Control HTTP caching behavior.

source:
type: geojson
url: "https://example.com/data.geojson"
cache:
enabled: true
ttl: 300000 # 5 minutes
PropertyTypeDefaultDescription
enabledbooleantrueEnable HTTP caching
ttlnumber-Cache TTL in milliseconds

MapLibre GL JS GeoJSON options are supported:

PropertyTypeDescription
tolerancenumberSimplification tolerance
buffernumberTile buffer size
lineMetricsbooleanEnable line distance metrics
generateIdbooleanAuto-generate feature IDs
promoteIdstring | objectPromote property to feature ID
attributionstringAttribution text
source:
type: geojson
url: "https://example.com/lines.geojson"
lineMetrics: true
tolerance: 0.375
buffer: 128
attribution: "© Data Provider"

Vector tiles for efficient large dataset rendering.

source:
type: vector
url: "https://api.maptiler.com/tiles/v3/tiles.json?key=YOUR_KEY"

or

source:
type: vector
tiles:
- "https://tile.example.com/{z}/{x}/{y}.pbf"
minzoom: 0
maxzoom: 14
PropertyTypeRequiredDescription
urlstringOne of url/tilesTileJSON URL
tilesstring[]One of url/tilesTile URL templates
minzoomnumberNoMinimum zoom level
maxzoomnumberNoMaximum zoom level
boundsnumber[]NoBounds [west, south, east, north]
scheme"xyz" | "tms"NoTile coordinate scheme
attributionstringNoAttribution text
source:
type: vector
tiles:
- "https://demotiles.maplibre.org/tiles/{z}/{x}/{y}.pbf"
minzoom: 0
maxzoom: 14
bounds: [-180, -85, 180, 85]
attribution: "© MapLibre"

Raster tile imagery for satellite, terrain, etc.

source:
type: raster
tiles:
- "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
tileSize: 256
maxzoom: 19
attribution: "© OpenStreetMap contributors"
PropertyTypeDefaultDescription
urlstring-TileJSON URL
tilesstring[]-Tile URL templates
tileSizenumber512Tile size in pixels
minzoomnumber-Minimum zoom level
maxzoomnumber-Maximum zoom level
boundsnumber[]-Bounds [west, south, east, north]
scheme"xyz" | "tms"-Tile coordinate scheme
attributionstring-Attribution text
source:
type: raster
tiles:
- "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
tileSize: 256
maxzoom: 19
attribution: "Esri, Maxar, Earthstar Geographics"

Single image overlay anchored to geographic coordinates.

Four corner coordinates must be specified clockwise starting from top-left:

  1. Top-left
  2. Top-right
  3. Bottom-right
  4. Bottom-left
source:
type: image
url: "https://example.com/overlay.png"
coordinates:
- [-80.425, 46.437] # top-left
- [-71.516, 46.437] # top-right
- [-71.516, 37.936] # bottom-right
- [-80.425, 37.936] # bottom-left
PropertyTypeRequiredDescription
urlstringYesImage URL
coordinatesarrayYesFour corner coordinates [topLeft, topRight, bottomRight, bottomLeft]
- id: map-overlay
type: raster
source:
type: image
url: "https://example.com/historical-map-1890.png"
coordinates:
- [-80.425, 46.437]
- [-71.516, 46.437]
- [-71.516, 37.936]
- [-80.425, 37.936]
paint:
raster-opacity: 0.7

Video content overlay anchored to geographic coordinates.

source:
type: video
urls:
- "https://example.com/video.mp4"
- "https://example.com/video.webm"
coordinates:
- [-122.51596391201019, 37.56238816766053]
- [-122.51467645168304, 37.56410183312965]
- [-122.51309394836426, 37.563391708549425]
- [-122.51423120498657, 37.56161849366671]
PropertyTypeRequiredDescription
urlsstring[]YesVideo URLs for browser compatibility
coordinatesarrayYesFour corner coordinates [topLeft, topRight, bottomRight, bottomLeft]
- id: video-overlay
type: raster
source:
type: video
urls:
- "https://example.com/drone-footage.mp4"
- "https://example.com/drone-footage.webm"
coordinates:
- [-122.51596391201019, 37.56238816766053]
- [-122.51467645168304, 37.56410183312965]
- [-122.51309394836426, 37.563391708549425]
- [-122.51423120498657, 37.56161849366671]
paint:
raster-opacity: 0.85

Define sources once and reference them in layers.

sources:
earthquakeData:
type: geojson
url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson"
refresh:
refreshInterval: 300000
updateStrategy: replace
satelliteImagery:
type: raster
tiles:
- "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}"
tileSize: 256
maxzoom: 19
pages:
- path: "/"
title: "Home"
blocks:
- type: map
id: main-map
config:
center: [0, 0]
zoom: 2
mapStyle: "..."
layers:
- id: quakes
type: circle
source: "#/sources/earthquakeData"
paint:
circle-radius: 6
circle-color: "#e74c3c"
- id: vehicles
type: circle
source:
type: geojson
stream:
type: websocket
url: "wss://api.example.com/vehicles"
reconnect: true
refresh:
updateStrategy: merge
updateKey: "vehicleId"
loading:
enabled: true
message: "Connecting to vehicle stream..."
paint:
circle-radius: 8
circle-color:
- match
- ["get", "status"]
- "active"
- "#10b981"
- "idle"
- "#f59e0b"
- "#6b7280"
- id: events
type: circle
source:
type: geojson
url: "https://api.example.com/events"
refresh:
refreshInterval: 30000
updateStrategy: append-window
windowSize: 1000
windowDuration: 3600000
timestampField: "eventTime"
paint:
circle-radius: 6
circle-color: "#3b82f6"
circle-opacity:
- interpolate
- ["linear"]
- ["get", "age"]
- 0
- 1
- 3600000
- 0.2
- id: earthquakes
type: circle
source:
type: geojson
url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_week.geojson"
cluster: true
clusterRadius: 50
clusterMaxZoom: 12
clusterProperties:
maxMagnitude: ["max", ["get", "mag"]]
count: ["+", 1]
paint:
circle-radius:
- case
- ["has", "point_count"]
- ["step", ["get", "point_count"], 20, 10, 30, 50, 40]
- 8
circle-color:
- case
- ["has", "point_count"]
- ["interpolate", ["linear"], ["get", "maxMagnitude"], 0, "#fef3c7", 8, "#dc2626"]
- "#3b82f6"
import {
type GeoJSONSource,
type VectorSource,
type RasterSource,
type ImageSource,
type VideoSource,
type LayerSource,
type StreamConfig,
type RefreshConfig
} from '@maplibre-yaml/core/schemas';
const geojsonSource: GeoJSONSource = {
type: "geojson",
url: "https://example.com/data.geojson",
fetchStrategy: "runtime",
refresh: {
refreshInterval: 5000,
updateStrategy: "replace"
}
};
const streamConfig: StreamConfig = {
type: "websocket",
url: "wss://api.example.com/stream",
reconnect: true,
reconnectMaxAttempts: 10
};