Maps — Getting started
This guide walks through the minimum configuration needed to get a working map in OnSphere, then progressively adds the four supported layer types.
git checkout origin/osp-web-configuration .
git checkout origin/osp-maps-configuration .
git checkout origin/osp-mongo-configuration .
git checkout origin/example-remote-connector-basic .
Add the map module to your configuration
Every map layer needs three binding files:
File |
Purpose |
|---|---|
Declares the layer type, geometry type, and data sources. |
|
Binds the layer to an |
|
Exposes the layer to an |
layer.maps and layer.web follow the same minimal pattern for all layer types:
{
"moduleId": "modules.maps.maps-1"
}
{
"moduleId": "modules.web.web-1"
}
The moduleId values must match the module instance identifiers declared in your stack.
Choose your basemap: Mapbox or MapLibre
The Map widget renders one basemap library per widget instance. Choose based on your connectivity and token requirements:
Mapbox |
MapLibre + Protomaps |
|
|---|---|---|
Connectivity |
Online — requires internet access to Mapbox tile servers |
Offline-capable — tiles served from a local PMTiles archive |
API token |
Required |
Not required |
Satellite view |
Available via Mapbox Studio styles |
Not available |
Key config field |
|
|
Mapbox — set mapStyle in mapsWidgetSettings with light and dark style URLs:
{
"type": "Maps",
"mapsWidgetSettings": {
"mapStyle": {
"dark": "mapbox://styles/mapbox/dark-v11",
"light": "mapbox://styles/mapbox/light-v11"
}
}
}
See Get an API token for instructions on obtaining a Mapbox API token and placing it in module.web.
MapLibre — set library and protomapSource with the resource path to your PMTiles archive:
{
"type": "Maps",
"mapsWidgetSettings": {
"library": "MapLibre",
"protomapSource": "/osp/resources/tiles/world.pmtiles"
}
}
See MapLibre and Protomaps for instructions on generating a PMTiles archive and loading it as a resource.
Note
The rest of this guide applies to both basemaps. The basemap choice only affects mapStyle or protomapSource in Dashboard view.
Add a simple point from geo.maps
Layer type: STANDARD | Source type: STATIC
Static points inherit their geographic coordinates from a geo.maps file placed in the configuration tree. Every value nested below that file is linked to that location until another geo.maps is found deeper in the tree.
1. Create geo.maps
Declare one GeoJSON Point feature per location. Coordinates follow the order [longitude, latitude, altitude?].
{
"geoJsonString": {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [7.0567, 46.6195, 450]
},
"properties": {
"name": "Bulle city",
"label": {"name": "Bulle","text-color": "#F0FFFF", "text-anchor": "bottom"}
}
},
"moduleId": "modules.maps.maps-1"
}
The name property populates the click popup. The optional label property adds a text label anchored above or below the point. moduleId binds the file to an osp-maps instance.
2. Create layer.ospp
{
"name": "Example points layer",
"description": "",
"layerType": "STANDARD",
"valueType": "POINT",
"mapSources": [
{
"type": "STATIC",
"linkedValues": [
"root.site.bulle.value.variable",
"root.site.lausanne.value.variable"
]
}
]
}
layerType: STANDARD renders points coloured by their linked value. mapSources[].type: STATIC reads geometry from geo.maps. linkedValues lists the value ids that should appear on the map.
3. Register the layer in Dashboard view
{
"configuration": [
{
"id": "Lo-_-jGf",
"type": "Maps",
"title": "",
"mapsWidgetSettings": {
"layerOptions": [
{
"layerId": "root.layers.points",
"activatedByDefault": true
}
],
"mapStyle": {
"dark": "mapbox://styles/mapbox/dark-v11",
"light": "mapbox://styles/mapbox/light-v11"
},
"centerPosition": [
7.153656,
46.80603
],
"zoomLevel": 9
}
}
],
"layout": {
"lg": [
{
"w": 12,
"h": 6,
"x": 0,
"y": 0,
"i": "Lo-_-jGf"
}
]
},
"breakpoints": {
"lg": 1200,
"md": 996,
"sm": 768,
"xs": 480,
"xxs": 0
},
"cols": {
"lg": 12,
"md": 10,
"sm": 6,
"xs": 4,
"xxs": 2
},
"rowHeight": 150
}
layerOptions[].layerId must match the OnSphere id of the layer folder (for example root.layers.points). Set activatedByDefault: true to show the layer when the dashboard opens.
See also
Display standard points on map — full walkthrough including value and script configuration.
Add alarm-linked points from geo.maps
Layer type: SEVERITY | Source type: STATIC
Note
Requires osp-alarms.
Use this approach when you want to colour a geographic point by the highest alarm severity at that location. The geometry still comes from geo.maps; the severity and count values come from alarm aggregations already declared in the configuration tree.
Replace layer.ospp with a SEVERITY layer that references the alarm aggregation values for each site:
{
"name": "Alarm layer",
"description": "",
"layerType": "SEVERITY",
"valueType": "POINT",
"mapSources": [
{
"type": "STATIC",
"severityConfigurations": [
{
"severity": "root.site.bulle.alarms.highest_severity",
"count": "root.site.bulle.alarms.count",
"dashboard": "root.alarmGenerator"
},
{
"severity": "root.site.lausanne.alarms.highest_severity",
"count": "root.site.lausanne.alarms.count",
"dashboard": "root.alarmGenerator"
}
]
}
]
}
layerType: SEVERITY colours each point by alarm severity. severityConfigurations maps each site’s highest-severity and count value ids to a display entry. The optional dashboard field navigates to another dashboard when the user clicks the feature.
The geo.maps file and the layer.maps / layer.web binding files are identical to the previous step.
See also
Display alarm points on map — full walkthrough including alarm aggregation setup.
Add a live alarm-backed layer
Layer type: SEVERITY | Source type: ALARMS
Note
Requires osp-alarms.
Use this approach when alarms carry their own geographic coordinates (for example in additionalData.geometry). No geo.maps file is needed — osp-maps streams live alarms and extracts the geometry from the configured field path on each alarm document.
1. Declare an alarm view
The view controls which alarm fields osp-alarms projects. It must expose the geometry field and, for SEVERITY layers, also highestSeverity and count.
{
"name": "Live map alarms",
"description": "Alarm view for the offline live alarm map example",
"liveColumns": [
{
"name": "Serial",
"field": "serial"
},
{
"name": "Summary",
"field": "summary"
},
{
"name": "Source",
"field": "source"
},
{
"name": "Location",
"field": "location"
},
{
"name": "Severity",
"field": "severity"
},
{
"name": "Highest severity",
"field": "highestSeverity"
},
{
"name": "Count",
"field": "count"
},
{
"name": "Marker type",
"field": "additionalData.markerType"
},
{
"name": "Geometry",
"field": "additionalData.geometry"
},
{
"name": "Tags",
"field": "tags"
},
{
"name": "Last occurrence",
"field": "lastTimestamp"
}
],
"historyColumns": [
{
"name": "Serial",
"field": "serial"
},
{
"name": "Summary",
"field": "summary"
},
{
"name": "Source",
"field": "source"
},
{
"name": "Location",
"field": "location"
},
{
"name": "Severity",
"field": "severity"
},
{
"name": "Count",
"field": "count"
},
{
"name": "Marker type",
"field": "additionalData.markerType"
},
{
"name": "Geometry",
"field": "additionalData.geometry"
},
{
"name": "Operation time",
"field": "operationTime"
}
]
}
The additionalData.geometry entry in liveColumns is the field the layer will read as the GeoJSON geometry for each alarm.
2. Declare alarm filters
Each layer must declare at least one alarm filter id. The first declared filter id is used by default when the widget does not specify one.
{
"name": "Critical only",
"description": "Display alarms with a highest severity of major or above"
}
{
"moduleId": "modules.alarms.alarms-1",
"query": {
"highestSeverity": {
"$gte": 500
}
}
}
3. Create layer.ospp
{
"name": "Live alarm severity",
"description": "Live alarm severity points streamed directly from the alarms module",
"layerType": "SEVERITY",
"valueType": "POINT",
"clusteringType": "NONE",
"mapSources": [
{
"type": "ALARMS",
"geometry": "additionalData.geometry",
"view": "root.alarms.views.live_map",
"filter": [
"root.alarms.filters.all",
"root.alarms.filters.critical_only"
]
}
]
}
geometry is the dot-path to the GeoJSON object inside each alarm document. view is fixed at configuration time — the widget can only switch between the declared filter ids at runtime, not the view.
See also
Display offline live alarm layers on map — full walkthrough including alarm creation from the map.
Add a collection-backed layer
Layer type: STANDARD | Source type: COLLECTIONS
Note
Requires osp-collections.
Use this approach when map items are records in a collection schema. Each document must expose a GeoJSON object at a configured field path. osp-maps watches the collection and pushes geometry updates to the widget automatically.
1. Add a GeoJSON field to the collection schema
The schema must define a field that holds a valid GeoJSON object. In this example the GeoJSON is stored at map.geometry.
{
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"category": {
"type": "string",
"enum": [
"fire",
"maintenance"
]
},
"visibleOnMap": {
"type": "boolean"
},
"map": {
"type": "object",
"properties": {
"geometry": {
"type": "object",
"properties": {
"type": {
"type": "string",
"enum": [
"Point"
]
},
"coordinates": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"items": {
"type": "number"
}
}
},
"required": [
"type",
"coordinates"
]
}
},
"required": [
"geometry"
]
}
},
"required": [
"name",
"category",
"visibleOnMap",
"map"
]
},
"filters": [
{
"id": "visible_only",
"name": "Visible points only"
}
]
}
The filters array declares filter ids that the layer and the widget can reference. The actual MongoDB query for each filter id is implemented in schema.collections.
2. Create layer.ospp
{
"name": "Dynamic collection points",
"description": "Points streamed from the collections module",
"layerType": "STANDARD",
"valueType": "POINT",
"clusteringType": "NONE",
"mapSources": [
{
"type": "COLLECTIONS",
"collectionSource": "root.collections.dynamic_map_items",
"geometry": "map.geometry",
"filter": [
"visible_only"
]
}
]
}
collectionSource is the OnSphere id of the collection schema folder. geometry is the dot-path to the GeoJSON object in each document. filter lists the schema filter ids available to this layer.
See also
Display collection-backed layers on map — full walkthrough including filter reuse with a collection table.
What’s next
Layer and source model — full layer and source type reference
GeoJSON support — GeoJSON support and fixed properties (
label,linkedDashboard,icon-image)Display icons points on map — static and dynamic icon layers
Display floor-filtered mixed map sources — one floor selector across OnSphere, WMTS, and WMS layers
Display a WMTS source as a layer and Display a WMS source as an image — external raster overlays
Offline map display standard points on map — offline maps with Protomaps
Map context usage — map context methods and right-click menus