GeoLibre Project Format¶
Projects are saved as .geolibre.json files.
Schema¶
| Field | Type | Description |
|---|---|---|
version |
string | Format version (0.1.0) |
name |
string | Project display name |
mapView |
object | center, zoom, bearing, pitch, optional bbox |
basemapStyleUrl |
string | MapLibre style JSON URL, or an empty string for a blank background |
basemapVisible |
boolean | Whether the Background layer is visible |
basemapOpacity |
number | Background layer opacity from 0 to 1 |
layers |
array | Layer definitions (see below) |
styles |
object | Map of layer id → LayerStyle |
plugins |
object | Optional external plugin manifest URLs, active plugin IDs, plugin map-control positions, and plugin settings |
legend |
object | Optional Print Layout legend customizations (title, grouping, ordering, per-item rename/hide) |
storymap |
object | Optional scroll-driven story map (chapters and presentation settings); omitted when there are no chapters |
widgets |
array | Optional Dashboard panel chart widgets (see below); omitted when there are none |
dashboardColumns |
number | Optional Dashboard widget-grid column count (1-6, default 2); omitted when default |
metadata |
object | Free-form project metadata |
Plugin state¶
{
"manifestUrls": ["https://example.com/plugins/example-plugin/plugin.json"],
"activePluginIds": ["maplibre-layer-control", "maplibre-gl-swipe"],
"mapControlPositions": {
"maplibre-layer-control": "top-right",
"maplibre-gl-swipe": "top-left"
},
"settings": {
"maplibre-gl-swipe": {
"orientation": "vertical",
"position": 50,
"collapsed": false,
"active": true,
"leftLayers": ["layer-a"],
"rightLayers": ["layer-b"]
}
}
}
Projects without a plugins section open with the built-in default plugin state.
Legend¶
The Print Layout legend is always derived from the visible layers' symbology; the
legend object stores only the user's edits layered on top, so customizations
survive layer additions and removals.
{
"title": "Legend",
"groupByLayer": true,
"order": ["layer-b", "layer-a"],
"overrides": {
"layer-a": { "label": "Roads" },
"layer-b::0": { "label": "Low" },
"layer-b::1": { "hidden": true }
}
}
title— heading drawn above the legend entries.groupByLayer— whentrue, graduated/categorized classes are grouped under a per-layer heading; whenfalse, classes are listed flat.order— top-level entry order by layer id (top-first); layers not listed keep their default order after the listed ones.overrides— per-itemlabelandhiddenedits keyed by a stable item key: a layer id for a whole entry, or${layerId}::${index}for an individual class within a graduated/categorized entry.
Projects without a legend section open with the default legend (auto-generated
from the layers, titled "Legend").
Story map¶
A story map turns the project into a scroll-driven narrative. Each chapter captures a camera view plus text, and can fade project layers in or out on enter/exit. The section is omitted entirely when the project has no chapters.
{
"title": "A Tour of Three Cities",
"subtitle": "Built with GeoLibre",
"byline": "By the GeoLibre team",
"footer": "Source: OpenStreetMap",
"theme": "dark",
"showMarkers": true,
"markerColor": "#3fb1ce",
"inset": false,
"insetPosition": "bottom-right",
"chapters": [
{
"id": "intro",
"title": "San Francisco",
"description": "A hilly city on the tip of a peninsula. <em>HTML allowed.</em>",
"image": "https://example.com/sf.jpg",
"alignment": "left",
"hidden": false,
"location": { "center": [-122.4194, 37.7749], "zoom": 11, "pitch": 45, "bearing": 0 },
"mapAnimation": "flyTo",
"rotateAnimation": false,
"onChapterEnter": [{ "layerId": "layer-a", "opacity": 1, "duration": 2000 }],
"onChapterExit": [{ "layerId": "layer-a", "opacity": 0 }]
}
]
}
alignment is one of left, center, right, full; mapAnimation is
flyTo, easeTo, or jumpTo. Layer opacity changes reference project layer
ids. Build and present story maps from Project → Story Map, or export a
self-contained HTML page for static hosting.
Dashboard widgets¶
{
"widgets": [
{ "id": "w1", "layerId": "layer-a", "type": "histogram", "field": "pop", "bins": 12 },
{ "id": "w2", "layerId": "layer-a", "type": "bar", "category": "kind", "aggregation": "sum", "valueField": "pop", "title": "Population by kind" }
]
}
Each widget binds a chart to a layer's attributes. type is one of histogram,
scatter, bar, line, box, or pie. Which other keys apply depends on the
type: field (histogram/line/box), xField/yField (scatter), category +
aggregation + valueField (bar/pie), bins (histogram). Bar aggregation is
count/sum/mean; pie is count/sum only. title is an optional label and
color an optional hex (#rgb/#rrggbb) for the chart's marks (the series
color for single-series charts; the base of a monochromatic ramp for bar/pie).
Unused keys are ignored. The Dashboard panel (Tools → Dashboard, or the
Dashboard button in the attribute table) also stores dashboardColumns, the
widget-grid column count (1-6, default 2), at the top level of the project.
Charts read from GeoJSON-backed vector layers and DuckDB query layers; widgets
bound to a missing or non-attribute layer are shown as empty.
Layer object¶
{
"id": "uuid",
"name": "My Layer",
"type": "geojson",
"source": { "type": "geojson" },
"visible": true,
"opacity": 1,
"style": {
"minZoom": 0,
"maxZoom": 24,
"fillColor": "#3b82f6",
"strokeColor": "#1e40af",
"strokeWidth": 2,
"strokeWidthUnit": "pixels",
"fillOpacity": 0.6,
"circleRadius": 6,
"rasterBrightnessMin": 0,
"rasterBrightnessMax": 1,
"rasterSaturation": 0,
"rasterContrast": 0,
"rasterHueRotate": 0
},
"metadata": {},
"geojson": { "type": "FeatureCollection", "features": [] },
"sourcePath": "/path/to/file.geojson"
}
For WFS GetFeature and GeoJSON URL layers, metadata.refresh can persist an
optional auto-refresh interval. intervalMs can be any positive interval in
milliseconds:
{
"metadata": {
"refresh": { "enabled": true, "intervalMs": 60000 }
}
}
Manual refresh uses the same saved source URL without requiring this metadata.
Layer types¶
| Type | v1.0 status |
|---|---|
geojson |
Supported for imported files and GeoJSON URLs |
xyz |
Supported for raster tile templates |
wms |
Supported as tiled WMS GetMap layers |
raster |
Supported for raster tile templates |
vector-tiles |
Supported for MapLibre vector tile sources |
mbtiles |
Supported in the desktop app through a local MapLibre protocol |
arcgis |
Supported for ArcGIS FeatureServer and VectorTileServer layers |
pmtiles |
Supported through the Components plugin |
cog |
Supported for COG and GeoTIFF raster layers |
flatgeobuf |
Supported through the Components plugin and imported as GeoJSON when loaded as a local vector file |
zarr |
Supported through the Components plugin |
lidar |
Supported through the Components plugin |
gaussian-splat |
Supported through the Components plugin |
geoparquet |
Imported as GeoJSON via DuckDB-WASM |
duckdb-query |
Supported for SQL query-result layers |
3d-tiles |
Supported through the maplibre-gl-3d-tiles plugin |
API¶
import {
createEmptyProject,
parseProject,
serializeProject,
} from "@geolibre/core";