Skip to main content

Map Guide

The @wemap/map package is a thin, opinionated wrapper around maplibre-gl for Wemap livemaps. It reads your livemap configuration (style, bounds, zoom range, indoor settings, …) from @wemap/core and adds first-class helpers for camera control, event subscription, POI interaction, and multi-level / indoor display.

It is not a generic maplibre helper — always initialize @wemap/core before constructing a WemapMap. The raw maplibre instance stays available as map.maplibre for anything the wrapper doesn't cover.

Installation

maplibre-gl is a peer dependency — install it alongside the SDK:

npm install @wemap/core @wemap/map maplibre-gl

Create a map

The map renders into a container element you provide by id. Like maplibre, the container must have an explicit height — a bare <div> collapses to 0px and the map appears blank:

<div id="map"></div>

<style>
/* The container needs a height, or the map renders at 0px and stays blank. */
#map { position: absolute; inset: 0; }
/* or: #map { width: 100%; height: 100vh; } */
</style>
import { core } from '@wemap/core';
import { WemapMap } from '@wemap/map';
import 'maplibre-gl/dist/maplibre-gl.css';
import '@wemap/map/style.css'; // SDK marker / cluster / user-location styles

await core.init({ emmid: '31668', token: 'YOUR_TOKEN' });

const map = new WemapMap({ container: 'map' });
await map.whenReady(); // resolves once the style is ready — no race with on('load')

Snippet defaults (style, bounds, zoom range, pitch, bearing, indoor, …) apply automatically. Override any of them — plus all maplibre MapOptions — in the constructor:

const map = new WemapMap({ container: 'map', minZoom: 14, pitch: 0 });

autoResize (default true) attaches a ResizeObserver to the container and calls resize() when it changes size; detached on remove(). The attribution control is disabled by default — re-enable it with maplibre's attributionControl option when your data requires it.

The interaction option opts into the automatic POI userflow (click-to-select, search highlight/filter) — see POIs & search.

Coordinate conventions

Position inputs (setCenter, flyTo/easeTo centers, and marker / itinerary / user-location positions) accept any LatLngLike — a Coordinates from @wemap/geo, a { lat, lng, level? } / { latitude, longitude } object, or a [lat, lng, level?] tuple. All are latitude-first. Position outputs (getCenter(), the onPoiClick payload) return Coordinates, and bounds use BoundingBox. The raw map.maplibre instance uses maplibre's own [lng, lat] convention — if you work directly against it (including map.on('click') passthrough events), you own the conversion.

Control the camera

import { Coordinates, BoundingBox } from '@wemap/geo';

map.setCenter(new Coordinates(48.8566, 2.3522));
map.setZoom(16.5);
map.flyTo({ center: new Coordinates(48.85, 2.35), zoom: 19, duration: 1200 });
map.fitBounds(
new BoundingBox(new Coordinates(48.8618, 2.361), new Coordinates(48.8528, 2.343))
);

getCenter(), getZoom(), and getBounds() read the current camera state.

Listen to events

on / once / off are typed passthroughs to maplibre, chainable:

map.on('click', (e) => console.log(e.lngLat)); // map events
map.on('click', 'my-layer', (e) => console.log(e.features)); // layer-scoped

Clean up

Optional layers (UserLocationLayer, DomMarkerLayer, ItineraryLayer, ShapeLayer) register with the map but are not destroyed by map.remove() by default — call each layer's destroy() first, or cascade with { layers: true }:

map.remove({ layers: true });

Feature guides

  • Indoor & levels — multi-level display, automatic building selection, the LevelControl floor switcher, and level-aware custom layers.
  • POIs & content search — click, highlight, select and filter stylesheet pinpoints, viewport pinpoints, and content search.
  • Markers & clusteringDomMarkerLayer runtime pins and optional supercluster clustering.
  • Itineraries — draw multilevel routes with ItineraryLayer.
  • Shapes — draw GeoJSON lines and polygons with simplestyle-spec styling, hover and click.
  • User location — show the user from a positioning stream with UserLocationLayer.
  • Theming — brand the map with theme tokens and CSS variables.

For the full API, see the Map API reference.