Image
Open inRegister an image in the map style for icons, symbols and patterns.
Usage
MglImage is a directive ([mglImage] or mgl-image). Add it inside mgl-map, then reference its id from a layer.
<mgl-map [mapStyle]="style" [center]="center" [zoom]="11"> @for (icon of icons(); track icon.id) { <mgl-image [id]="icon.id" [data]="icon.data" [options]="{ pixelRatio: 2 }" /> } <mgl-geojson-source id="places" [data]="places" /> <mgl-layer id="places" type="symbol" source="places" [layout]="{ 'icon-image': ['get', 'icon'], 'icon-size': 0.75 }" /></mgl-map> Because the directive does not render anything, the attribute selector also works on an ng-container:
<ng-container mglImage id="cafe" [data]="cafeIcon" />SVG icons
The example uses icons from @ng-icons/lucide as they are. They are SVG strings, while MapLibre style images are bitmaps. addImage does not parse SVG markup, and loadImage only supports PNG, JPEG and WebP. Use svgToImage from @elbe-ui/map/image to load the SVG into an HTMLImageElement that MapLibre can register.
import { lucideCoffee, lucideLandmark, lucideShoppingBag } from '@ng-icons/lucide';import { svgToImage } from '@elbe-ui/map/image';const ICONS = [ { id: 'cafe', icon: lucideCoffee }, { id: 'shop', icon: lucideShoppingBag }, { id: 'landmark', icon: lucideLandmark },];async function loadIcons() { return Promise.all( ICONS.map(async ({ id, icon }) => ({ id, data: await svgToImage(icon), })), );}Each GeoJSON feature references one of the registered image ids:
<mgl-layer id="places" type="symbol" source="places" [layout]="{ 'icon-image': ['get', 'icon'], 'icon-size': 0.75, 'icon-allow-overlap': true }"/><!-- GeoJSON feature -->{ "properties": { "name": "Café", "icon": "cafe" } }Data or URL
Use data for an image that is already available, or url to let MapLibre load it. The example uses data because the lucide icons are rendered in the browser.
<mgl-image id="cafe" [data]="cafeIcon" [options]="{ pixelRatio: 2 }"/>imageLoaded fires once the image is registered and imageError when a url cannot be loaded. Both outputs are optional and can be used for UI state or logging.
<mgl-image id="cafe" [data]="cafeIcon" (imageLoaded)="imageLoaded.set(true)" (imageError)="imageError.set($event)"/>Options
options maps to MapLibre's image metadata. Use pixelRatio for high-DPI images and sdf when the image is tinted through icon-color. Stretchable images also accept content, stretchX and stretchY.
<!-- Tintable SDF icon --><mgl-image id="dot" url="/assets/dot.png" [options]="{ sdf: true, pixelRatio: 2 }" /><!-- Stretchable image for icon-text-fit --><mgl-image id="frame" url="/assets/frame.png" [options]="{ content: [16, 16, 300, 384], stretchX: [[16, 584]], stretchY: [[16, 384]] }"/>Style reloads
Runtime images are cleared when the style changes. The directive listens for styledata and registers the image again, so switching between light and dark styles keeps the icons available.