GeoJSON Source
A GeoJSON source is the data container that style layers read from. It holds a FeatureCollection of points, lines, or polygons, either inline in your Dart code or fetched from a URL.
Capital cities across the Americas rendered from an inline FeatureCollection. Circle radius scales with population.
Add sources and layers after the style loads
Every call below needs a loaded style. Run them from onStyleLoadedCallback,
not from onMapCreated, and run them there again after a style change: a new
style discards every source and layer you added. See
Constraints and gotchas.
The source + layer pattern
GeoJSON sources don't render anything by themselves. You always need at least one layer referencing the source:
// 1. Source: holds the data
await controller.addGeoJsonSource('capitals', featureCollection);
// 2. Layer: defines how to render the data
await controller.addCircleLayer(
'capitals', // source id
'capitals-dots', // layer id (must be unique)
CircleLayerProperties(...),
);
// Multiple layers can reference the same source
await controller.addSymbolLayer(
'capitals',
'capitals-labels',
SymbolLayerProperties(...),
);
Adding the source
Inline FeatureCollection
await controller.addGeoJsonSource('my-source', {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'id': 'f1', // optional, needed for setGeoJsonFeature()
'properties': {
'name': 'Paris',
'population': 2161000,
'country': 'France',
},
'geometry': {
'type': 'Point',
'coordinates': [2.3522, 48.8566], // [lng, lat]
},
},
],
});
Remote URL
await controller.addSource(
'rivers',
const GeojsonSourceProperties(
data: 'https://example.com/data/rivers.geojson',
),
);
A URL goes through addSource rather than addGeoJsonSource, which takes the GeoJSON itself. MapLibre fetches and caches the URL. CORS headers must be present when running on web.
With clustering enabled
await controller.addSource(
'events',
GeojsonSourceProperties(
data: featureCollection, // inline GeoJSON map, or a URL string
cluster: true,
clusterMaxZoom: 14, // stop clustering above zoom 14
clusterRadius: 50, // pixel radius for clustering
),
);
Pass the data when you create the source: a geojson source needs its data up front, and on web a source added without it fails validation, so the layers that depend on it never attach.
See Cluster for the full clustering setup.
Updating data
Replace all features
Use this for bulk updates: filtering, time-series playback, real-time data refresh.
Update a single feature
await controller.setGeoJsonFeature('my-source', {
'type': 'Feature',
'id': 'f1', // must match an existing feature id
'properties': {'status': 'active', 'name': 'Paris'},
'geometry': {
'type': 'Point',
'coordinates': [2.3522, 48.8566],
},
});
Updating a single feature is more efficient than replacing the whole FeatureCollection when only one feature changes (e.g. tracking a moving vehicle).
Filtering layers
Add a filter to a layer to show only features matching a condition:
await controller.addCircleLayer(
'events',
'events-active',
const CircleLayerProperties(circleColor: '#2ecc71'),
filter: ['==', ['get', 'status'], 'active'],
);
await controller.addCircleLayer(
'events',
'events-inactive',
const CircleLayerProperties(circleColor: '#95a5a6'),
filter: ['==', ['get', 'status'], 'inactive'],
);
Both layers use the same source but each shows a subset of features.
Removing a source
// Remove all layers referencing the source first
await controller.removeLayer('my-layer');
// Then remove the source
await controller.removeSource('my-source');
Key APIs
| Method | Description |
|---|---|
addGeoJsonSource(id, data) |
Add a source with inline GeoJSON data |
addSource(id, GeojsonSourceProperties(...)) |
Add a source from a URL, or with clustering options |
setGeoJsonSource(id, data) |
Replace all features |
setGeoJsonFeature(id, feature) |
Update one feature by id |
removeSource(id) |
Remove source (remove layers first) |
getSourceIds() |
List all source ids in the current style |
Related
- Working with GeoJSON: the data format explained
- Data-Driven Expressions: style by feature properties
- Cluster: group nearby points automatically