GPS Blue Dot & Multi-Floor View (F63–F64)
GPS Blue Dot (F63)
GPSBlueDot renders a "you are here" indicator driven by the device GPS. It integrates with the GeolocationAdapter — the same RTLS adapter interface used for BLE/UWB — so the accuracy, smoothing, and floor-detection logic is shared.
Component form
import { SpatialProvider, SpatialMap, GPSBlueDot } from '@diginestai/core';
export function OutdoorMap() {
return (
<SpatialProvider>
<SpatialMap buildings={[building]}>
<GPSBlueDot
accuracy="high"
watchInterval={2000} // ms between Geolocation API polls
showAccuracyCircle // shows the uncertainty radius ring
/>
</SpatialMap>
</SpatialProvider>
);
}Plugin form
Use the plugin form when you need programmatic control over the blue dot lifecycle, or when combining with other RTLS adapters:
import { createGPSBlueDotPlugin, GeolocationAdapter } from '@diginestai/core';
const plugin = createGPSBlueDotPlugin({
adapter: new GeolocationAdapter({ accuracy: 'high' }),
onPositionUpdate: (pos) => console.log(pos.lat, pos.lng, pos.floorOrdinal),
});
// Register with SpatialProvider
<SpatialProvider plugins={[plugin]}>GeolocationAdapter
GeolocationAdapter wraps the browser navigator.geolocation API and implements RTLSAdapter:
import { GeolocationAdapter } from '@diginestai/rtls';
const adapter = new GeolocationAdapter({
accuracy: 'high', // 'high' | 'low' (maps to enableHighAccuracy)
timeout: 10_000, // ms before position is considered stale
maximumAge: 5_000, // ms to accept a cached position
});Permissions
The GeolocationAdapter calls navigator.geolocation.watchPosition. The browser will prompt for location permission on first use. Handle the denial case:
<GPSBlueDot
onPermissionDenied={() => showBanner('Location access denied')}
onError={(err) => console.error(err.message)}
/>Indoor limitations
GPS accuracy indoors is typically 5–30 m (versus ≤ 3 m outdoors). Key caveats:
- Floor detection uses altitude when available, falling back to the nearest building floor centroid. Altitude accuracy is ±10–20 m on most consumer devices.
- For indoor positioning precision, use an RTLS adapter (BLE, UWB, Wi-Fi) via
<RTLSBlueDot>instead. GPSBlueDotandRTLSBlueDotcannot be active simultaneously on the sameSpatialProvider; the last registered adapter wins.
Multi-Floor View (F64)
MultiFloorView renders two or more floor plans simultaneously in an "exploded" stack, useful for building directories, evacuation plans, and cross-floor wayfinding previews.
When to use
| Use case | Recommendation |
|---|---|
| Show route crossing multiple floors | MultiFloorView — user sees the full path |
| Navigation with active floor-switching | Standard SpatialMap + FloorSwitcher |
| Static directory or evacuation map | MultiFloorView |
| Performance-sensitive real-time RTLS | Standard SpatialMap (one floor rendered at a time) |
Basic usage
import { MultiFloorView } from '@diginestai/core';
export function BuildingDirectory({ building }) {
return (
<MultiFloorView
building={building}
floorOrdinals={[0, 1, 2]} // render ground + 2 upper floors
explodeGap={40} // vertical gap between floors in pixels
perspective="isometric" // 'flat' | 'isometric'
/>
);
}Exploded view options
| Prop | Type | Default | Description |
|---|---|---|---|
floorOrdinals | number[] | all floors | Which floors to render (ascending order) |
explodeGap | number | 30 | Pixel gap between adjacent floor planes |
perspective | 'flat' | 'isometric' | 'flat' | Camera projection |
tilt | number | 0 | Camera tilt angle in degrees (flat mode) |
onFloorClick | (ordinal: number) => void | — | Called when user clicks a floor plane |
Performance considerations
Each floor in MultiFloorView is a separate WebGL layer stack. Rendering more than 4–5 floors simultaneously may impact frame rate on low-end devices:
- Keep
floorOrdinalsto the floors relevant to the user's context. - Use
perspective="flat"(the default) for the lowest GPU cost. - Avoid combining
MultiFloorViewwith live RTLS updates — use standardSpatialMapfor that.
Highlighting a route across floors
import { MultiFloorView, SpaceHighlight } from '@diginestai/core';
<MultiFloorView building={building} floorOrdinals={[0, 1]}>
<SpaceHighlight unitIds={routeUnitIds} color="#2393d4" />
</MultiFloorView>