Skip to main content

User Location

UserLocationLayer displays the user on the map from a positioning stream. It accepts a UserLocationUpdate shape that is structurally compatible with Pose from @wemap/positioning (without importing it), so you can feed poses straight through. See the Positioning guide for the pose source.

The update's position accepts any LatLngLike (a Coordinates, a { lat, lng, level? } object, or a [lat, lng, level?] tuple); a malformed value is skipped rather than throwing, since a positioning stream must not break on one bad fix. A pose that arrives before the map style has loaded is buffered and replayed once it is ready, so the first fix during map init is never lost.

import { core } from '@wemap/core';
import { WemapMap, UserLocationLayer } from '@wemap/map';

await core.init({ emmid, token });
const map = new WemapMap({ container: 'map' });

const user = new UserLocationLayer(map, {
showHeading: true, // default true — heading cone when attitude is present
followOnFirstFix: false, // default false
});

locationSource.onUpdate((pose) => user.update(pose));

// later
user.destroy();

Options

  • showHeading (default true) — render a heading cone when the update carries attitude.

  • followOnFirstFix (default false) — when true, the camera flies to the first valid position once, preserving the current zoom. When false, the camera doesn't move on the first fix.

  • accuracyRing (default false) — draw a geographic accuracy circle (in metres, ground-anchored) from the update's accuracy. Pass true for themed defaults, or an AccuracyRingOptions object:

    • color — fill/outline colour. Defaults to the theme primary colour.
    • fillOpacity (default 0.15) — fill opacity, 01.
    • outlineOpacity (default 0.4) — outline opacity, 01.

Level sync

When indoor is enabled, the user marker participates in automatic level sync: a pose that reports a new floor moves the map to that floor when the pose is inside the active building and the level exists on it. The marker hides when its pose level does not match the displayed floor.

Clean up

UserLocationLayer is not destroyed by map.remove() by default — call user.destroy(), or cascade with map.remove({ layers: true }).

For the full API, see the UserLocationLayer reference.