Positioning Guide
The positioning package provides location tracking capabilities using various location sources. This section covers everything you need to know to get started with positioning.
How to Initialize Core SDK with Positioning
The Core SDK must be initialized before creating location sources, as location sources may depend on configuration data from the Core SDK (especially for VPS).
import { core } from '@wemap/core';
import { GnssWifiLocationSource } from '@wemap/positioning';
// Step 1: Initialize Core SDK first
await core.init({
emmid: 'your-map-id',
token: 'your-token',
});
// Step 2: Now you can create location sources
const locationSource = new GnssWifiLocationSource({
// Configuration options
});
Location Sources
A Location Source is a system used to track user position. Wemap provides two main location source types:
GnssWifiLocationSource
Geolocation based on GPS and WiFi positioning. This is the standard location source that works in most environments.
import { GnssWifiLocationSource } from '@wemap/positioning';
const gnssLocationSource = new GnssWifiLocationSource({
// Configuration options
});
// Start the location source
await gnssLocationSource.start();
// Listen for position updates
gnssLocationSource.onUpdate((pose) => {
console.log('Position:', pose.position);
console.log('Orientation:', pose.attitude.headingDegrees);
});
Check out the API reference for GnssWifiLocationSource →
VPSLocationSource (Visual Positioning System)
Geolocation based on visual positioning system. VPS uses camera input to provide highly accurate indoor positioning, especially useful in environments where GPS signals are weak or unavailable.
import { VPSLocationSource } from '@wemap/positioning';
const vpsLocationSource = new VPSLocationSource({
// Configuration options
});
Wemap VPS must be configured by the Wemap team. Please contact us if you are interested in using it.
For detailed information about VPS, including setup, camera configuration, and scan procedures, see the VPS Location Source guide.
How to Handle Authorization
Location sources require various browser permissions. The positioning package provides helper functions to request these permissions:
Camera Permissions (for VPS)
import { requestCameraPermissions } from '@wemap/camera';
const hasPermission = await requestCameraPermissions();
if (!hasPermission) {
throw new Error('Camera permission denied');
}
Location Permissions (for GNSS/WiFi)
import { requestLocationPermissions } from '@wemap/positioning';
const hasPermission = await requestLocationPermissions();
if (!hasPermission) {
throw new Error('Location permission denied');
}
Device Orientation Permissions (iOS)
On iOS, you need to request device orientation permission. This request needs to be triggered after a user interaction (click, tap, etc.).
import { requestSensorPermissions } from '@wemap/positioning';
const hasPermission = await requestSensorPermissions();
if (!hasPermission) {
throw new Error('Sensor permission denied');
}
How to handle Itinerary + Map Matching
Map matching projects your position onto a predefined route, providing more accurate navigation.
Step 1: Calculate a Route
import { Router } from '@wemap/routing';
const router = new Router();
// Calculate route from current position to destination
const itineraries = await router.directions(
{ lat: 48.8566, lon: 2.3522 }, // Origin
{ lat: 48.8606, lon: 2.3376 }, // Destination
'WALK', // Travel mode
);
// Use the first (usually best) itinerary
const itinerary = itineraries[0];
Step 2: Set Itinerary for Map Matching
import { MapMatching } from '@wemap/positioning';
// Set the itinerary for map matching
MapMatching.setItinerary(itinerary);
// Now all location sources will project positions onto this route
Step 3: Receive Map-Matched Positions
locationSource.onUpdate((pose) => {
// Position is automatically projected onto the route
if (pose.position) {
console.log('Map-matched position:', pose.position);
// Use this position for navigation display
}
});
Step 4: Clear Itinerary
MapMatching.clearItinerary();
Complete Map Matching Example
import { core } from '@wemap/core';
import { GnssWifiLocationSource, MapMatching } from '@wemap/positioning';
import { Router } from '@wemap/routing';
async function setupNavigationWithMapMatching() {
// 1. Initialize Core SDK
await core.init({ emmid: '...', token: '...' });
// 2. Create location source
const locationSource = new GnssWifiLocationSource();
// 3. Set up position updates
locationSource.onUpdate((pose) => {
console.log('Position update:', pose.position);
// Update your UI/map with the position
});
// 4. Start location source
await locationSource.start();
// 5. Calculate route
const router = new Router();
const itineraries = await router.directions(
origin,
destination,
'WALK'
);
// 6. Set itinerary for map matching
MapMatching.setItinerary(itineraries[0]);
// Now positions will be automatically projected onto the route
}
// To clear map matching later:
MapMatching.clearItinerary();
Map matching will not stricly project the position onto the route. It will project the position onto the route based on the maximum distance and minimum distance parameters.
Integrate Map Matching with your own itinerary routing system
Our map matching system is not stricly tied to the routing package. You can use it with your own itinerary routing system.
import { Itinerary, ItineraryInfoManager } from '@wemap/routing';
import { GnssWifiLocationSource, MapMatching, type Pose, Coordinates } from '@wemap/positioning';
const locationSource = new GnssWifiLocationSource();
await locationSource.start();
let userPosition: Coordinates | null = null;
locationSource.onUpdate((pose: Pose) => {
userPosition = pose.position;
});
/*
* Use your own itinerary routing system to get the itinerary
*/
const itinerary = await yourItineraryRoutingSystem.getItineraries(userPosition, destination);
const orderedCoordinates = itinerary.coords.map((point) => new Coordinates(point.lat, point.lon));
/**
* Transform your itinerary shape to the one expected by the map matching system
* You can also use the Itinerary.fromOrderedPointsArray method
*/
const transformedItinerary = Itinerary.fromOrderedCoordinates(orderedCoordinates, itinerary.origin, itinerary.destination);
MapMatching.setItinerary(transformedItinerary);