MapLibre¶
MapLibre is an open-source library for rendering interactive vector maps with WebGL. Element supports Angular applications that use @maplibre/ngx-maplibre-gl with control styles, a theme-aware map style, and translated control labels.
Usage¶
MapLibre exposes its map, controls, sources, and layers as composable Angular components and directives. Applications remain responsible for configuring and composing the map.
When to use¶
- When direct access to MapLibre features, sources, and layers is required.
- When map controls and behavior need to be composed for a specific use case.
- When vector-map rendering and MapLibre's ecosystem are preferred.
- When 3D features such as pitched views, extruded buildings, or a globe are required.
- When the high-level Element Maps component does not provide enough flexibility.
Code¶
See the ngx-maplibre-gl documentation and the MapLibre GL JS documentation for the complete APIs and configuration options.Required Packages
npm install --save @siemens/element-ng @siemens/map-styles @siemens/element-translate-ng
npm install --save @maplibre/ngx-maplibre-gl maplibre-gl
Configure the MapLibre worker¶
MapLibre GL JS 6 loads its web worker from a separate file. Add the worker and its shared module to the application assets in angular.json:
{
"architect": {
"build": {
"options": {
"assets": [
{
"glob": "maplibre-gl-{worker,shared}.mjs",
"input": "node_modules/maplibre-gl/dist",
"output": "/assets/maplibre/"
}
]
}
}
}
}
Register the worker in the application configuration before creating a map:
import { ApplicationConfig } from '@angular/core';
import { provideMaplibreWorker } from '@maplibre/ngx-maplibre-gl/config';
export const appConfig: ApplicationConfig = {
providers: [provideMaplibreWorker('assets/maplibre/maplibre-gl-worker.mjs')]
};
Apply Element control styles¶
Import the Element MapLibre stylesheet in the application's global stylesheet. It provides the required MapLibre layout styles and applies Element styling to controls, popovers, markers, and other map UI.
@use '@siemens/element-ng/maplibre/styles';
Use this stylesheet instead of importing maplibre-gl/dist/maplibre-gl.css separately.
Apply the Element map style¶
injectSiMapStyle() creates a signal containing the Element MapLibre style. Pass a MapTiler API key to the function and bind the signal value to the map's mapStyle input. The style updates automatically when the Element theme changes.
The function must be called in an Angular injection context, such as a component field initializer.
import { Component } from '@angular/core';
import { MapComponent } from '@maplibre/ngx-maplibre-gl';
import { injectSiMapStyle } from '@siemens/element-ng/maplibre';
@Component({
selector: 'app-map',
imports: [MapComponent],
template: '<mgl-map class="h-100" [mapStyle]="mapStyle()" />'
})
export class AppMapComponent {
protected readonly mapStyle = injectSiMapStyle('REPLACE_WITH_YOUR_MAPTILER_KEY');
}
Apply translations¶
injectSiMapTranslations() creates a signal containing translated MapLibre locale strings. It uses the configured Element translation service and updates when the active language changes. Bind the signal value to the map's locale input:
import { Component } from '@angular/core';
import { MapComponent } from '@maplibre/ngx-maplibre-gl';
import { injectSiMapTranslations } from '@siemens/element-ng/maplibre';
@Component({
selector: 'app-map',
imports: [MapComponent],
template: '<mgl-map class="h-100" [locale]="mapTranslations()" />'
})
export class AppMapComponent {
protected readonly mapTranslations = injectSiMapTranslations();
}
MapLibre example¶
The following example combines the Element map style and translations with MapLibre controls.
Cluster example¶
The following example uses SiClusterSourceComponent to cluster GeoJSON points and SiStatusMarkerComponent for unclustered markers. Cluster markers show the number of contained points and their distribution by group or status.
3D buildings example¶
MapLibre GL renders maps with WebGL, so the camera can be pitched and vector-tile buildings can be extruded into 3D.
The example pitches the map and adds a fill-extrusion layer on the OpenMapTiles building source. Building height animates in between zoom 15 and 16 using the render_height and render_min_height properties from the tiles.
Custom cluster popover¶
Use an ng-template with siClusterPopoverTemplate to customize the list of loaded cluster features. This example displays each location's name, description, and status as a selectable list item. Selecting a location updates the status above the map and logs the feature.
The popover handles loading and error states for both default and custom content. The "Load more" button appears after the first batch is loaded. If a request fails, an alert appears at the end of the list and the same button becomes "Retry", preserving focus and already loaded locations. Retrying reloads only the failed batch.
The pageSize input controls how many locations are loaded initially and with each click. Loaded locations stay visible while the next batch loads, with feature actions temporarily disabled. New locations are appended to the list.
Both default and custom content scroll below the fixed header. The centered "Load more" button sits at the end of the scrolling content and moves below newly appended locations. By default, the close button receives initial focus. Focus stays on "Load more" while loading and after items are appended, keeping the button visible. When all locations are loaded and the button disappears, focus moves to the scrolling region, so pressing Enter again does not close the popover.
SiClusterSourceComponent API Documentation¶
si-cluster-sourceAdds a clustered GeoJSON source to a MapLibre map and renders interactive cluster markers.
Cluster markers display the number of contained points and their distribution by group. Status segments can be enabled for ungrouped points by providing statusProperty . Render individual, unclustered points separately with mgl-markers-for-clusters using the same source ID. Positive numeric groups always take precedence over status segments. Status segments apply only when the normalized group value is zero; points without a matching group or status use the ungrouped color.
Example:
<mgl-map [mapStyle]="mapStyle()">
<si-cluster-source
sourceId="locations"
statusProperty="status"
[data]="locations"
(clusterClick)="onClusterClick($event)"
/>
<mgl-markers-for-clusters source="locations">
<ng-template let-feature mglPoint>
<si-status-marker
[status]="feature.properties?.status"
/>
</ng-template>
</mgl-markers-for-clusters>
</mgl-map>
Input Properties¶
| Name | Type | Default | Description |
|---|---|---|---|
| clusterMaxZoom ¶ | number | undefined | Maximum zoom at which points are clustered. |
| clusterMinPoints ¶ | number | 2 | Minimum number of points required to form a cluster. |
| clusterRadius ¶ | number | 50 | Cluster radius in pixels. |
| data ¶ | FeatureCollection<Point, GeoJsonProperties> | EMPTY_DATA | Point feature collection to cluster. |
| groupColors ¶ | ClusterColors | 'status' | Built-in palette or exact colors indexed by group ID. The built-in 'status' palette contains four colors for numeric groups and is separate from status-based bucketing. |
| groupProperty ¶ | string | 'group' | Feature property containing the positive numeric group ID. |
| sourceId | string | ID used to register the generated GeoJSON source in MapLibre. | |
| statusProperty ¶ | string | undefined | Top-level feature property containing a MarkerStatus: link not resolved value. Status bucketing is disabled by default and only applies when the normalized group value is zero. Missing or unsupported status values, and groups that do not match a configured bucket, use the ungrouped color. Built-in colors match SiStatusMarkerComponent , with default using accent and unknown using neutral.See https://maplibre.org/maplibre-style-spec/sources/#clusterproperties |
Output Properties¶
| Name | Type | Description |
|---|---|---|
| clusterClick ¶ | ClusterPoint | Emits when a cluster marker is activated. |
Attributes and Methods¶
| Name | Type | Default | Description |
|---|---|---|---|
| getClusterLeaves(...) ¶ | (clusterId: number, limit: number, offset: number) => Promise<ClusterPoint[]> | Returns a page of original points belonging to a cluster. See https://maplibre.org/maplibre-gl-js/docs/API/classes/GeoJSONSource/#getclusterleaves Parameters |
SiClusterPopoverComponent API Documentation¶
si-cluster-popoverOptional popup with incrementally loaded locations projected into a si-cluster-source .
Input Properties¶
| Name | Type | Default | Description |
|---|---|---|---|
| closeOnMove ¶ | boolean | true | Whether the popup closes when the map moves. |
| descriptionProperty ¶ | string | 'description' | Feature property displayed as the description in the default list. |
| labelProperty ¶ | string | 'name' | Feature property displayed in the default list. |
| maxWidth ¶ | string | '320px' | Maximum width passed to the MapLibre popup. |
| pageSize ¶ | number | 8 | Number of locations loaded initially and with each "Load more" action. |
SiClusterPopoverTemplateDirective API Documentation¶
[siClusterPopoverTemplate]Template for custom location content inside si-cluster-popover .
Receives a ClusterPopoverContext: link not resolved with all locations loaded so far. Loading feedback, error recovery, and the "Load more" button are handled by the popover.
No API to document for this.
Except where otherwise noted, content on this site is licensed under MIT License.