πΊοΈ Navigation System Overview¶
The WebXR Gallery navigation system allows users to navigate between stages using interactive maps or floor plans, providing geographic context to immersive experiences.
Features¶
πΊοΈ Interactive Maps¶
- OpenStreetMap Integration - Free, open-source maps
- Multiple Tile Layers - Streets, satellite, terrain views
- Search & Geocoding - Find locations by address
- Drag-to-Place - Click and drag to position stages
- Auto-Centering - Focuses on current stage location
π’ Floor Plans¶
- SVG-Based Markers - Lightweight and scalable
- Multi-Floor Support - Switch between building levels
- Custom Images - Upload your own floor plan images
- Clickable Markers - Navigate by clicking stage locations
- Minimap Mode - Always-visible corner widget
π Unified Minimap¶
- 100x100px Widget - Fixed bottom-left corner
- Click-to-Expand - Opens full stage selector
- Current Stage Indicator - Pulsing marker animation
- Graceful Degradation - Hidden if no location data
Architecture¶
NavigationManager
βββ type: "map" | "floorplan" | "none"
βββ MapOverlay
β βββ Leaflet integration
β βββ Tile layer rendering
β βββ Marker placement
β βββ Geocoding service
βββ FloorPlanOverlay
βββ SVG marker rendering
βββ Image loading
βββ Floor switching
βββ Tooltip system
Configuration¶
Quick Start¶
// In your ExperienceConfig
{
"navigation": {
"type": "map", // or "floorplan" or "none"
"showMinimap": true, // Show corner widget
"markers": [
{
"stageId": "stage-1",
"label": "Lobby",
"geoPosition": { // For maps
"lat": 40.7128,
"lng": -74.0060
},
"floorPlanPosition": { // For floor plans
"x": 0.5, // 0-1 normalized
"y": 0.3
}
}
]
},
"stages": [
{
"id": "stage-1",
"name": "Lobby",
"location": { // Stage-level location (fallback)
"lat": 40.7128,
"lng": -74.0060
}
}
]
}
Navigation Types¶
1. Map Navigation¶
Best for: - Outdoor locations - City tours - Multi-building campuses - Geographic experiences
Configuration:
{
"navigation": {
"type": "map",
"showMinimap": true,
"mapConfig": {
"tileLayer": "streets", // streets, satellite, outdoors, dark
"initialZoom": 15,
"maxZoom": 18,
"minZoom": 10
},
"markers": [
{
"stageId": "times-square",
"label": "Times Square",
"icon": "star", // default, star, info, camera, etc.
"color": "#FF0000", // Custom marker color
"geoPosition": {
"lat": 40.7580,
"lng": -73.9855
}
}
]
}
}
Tile Layer Options: - streets - Default road map - satellite - Aerial imagery - outdoors - Topographic with trails - dark - Dark mode map - light - Minimal light theme
2. Floor Plan Navigation¶
Best for: - Indoor experiences - Museums and galleries - Office buildings - Multi-floor venues
Configuration:
{
"navigation": {
"type": "floorplan",
"showMinimap": true,
"floorPlans": [ // Multi-floor support
{
"floor": 1,
"name": "Ground Floor",
"imageUrl": "https://cdn.com/floor1.png"
},
{
"floor": 2,
"name": "Second Floor",
"imageUrl": "https://cdn.com/floor2.png"
}
],
"markers": [
{
"stageId": "lobby",
"label": "Main Lobby",
"floor": 1, // Which floor plan?
"floorPlanPosition": {
"x": 0.5, // Normalized 0-1 (50% from left)
"y": 0.3 // Normalized 0-1 (30% from top)
}
}
]
}
}
Floor Plan Image Requirements: - Format: PNG, JPG, or SVG - Aspect Ratio: Any (will scale to fit) - Resolution: 1920x1080+ recommended - File Size: <5MB for best performance
3. No Navigation¶
Disables geographic navigation entirely:
Marker Configuration¶
Each marker connects a stage to a geographic or floor plan location:
interface NavigationMarker {
stageId: string; // Which stage?
label?: string; // Display name (defaults to stage name)
// Geographic (for maps)
geoPosition?: {
lat: number; // Latitude (-90 to 90)
lng: number; // Longitude (-180 to 180)
};
// Floor plan (for floor plans)
floorPlanPosition?: {
x: number; // 0-1 (0=left, 1=right)
y: number; // 0-1 (0=top, 1=bottom)
};
floor?: number; // Which floor? (1-indexed)
// Visual customization
icon?: 'default' | 'star' | 'info' | 'camera' | 'video' | 'audio';
customIconUrl?: string; // URL to custom PNG icon
color?: string; // Hex color (e.g., "#FF0000")
// Metadata
placeName?: string; // Auto-filled by geocoding
}
Geocoding¶
The GeocodingService automatically converts addresses to coordinates and vice versa.
Reverse Geocoding (Coordinates β Address)¶
Automatically triggered when you set a stage location in the editor:
// User drags marker to (40.7128, -74.0060)
// Geocoding service automatically calls Nominatim API
// Result: "New York, NY, USA"
// Stored in marker.placeName
Forward Geocoding (Address β Coordinates)¶
Available in the Map Location Picker:
- User types "Empire State Building"
- Search suggestions appear in <300ms
- User clicks suggestion
- Map centers on location
- Marker placed automatically
Caching & Rate Limiting¶
To respect Nominatim's usage policy: - 15-minute cache for repeated lookups - 1 request/second rate limiting - 100-entry LRU cache to prevent memory bloat
Minimap Behavior¶
Visibility Rules¶
The minimap is shown when: - β
navigation.showMinimap === true (explicit) - β
navigation.type !== 'none' - β
At least one marker has valid location data
Hidden when: - β navigation.showMinimap === false - β All markers at (0, 0) or undefined - β Navigation type is 'none'
Interaction¶
- Click minimap: Opens full stage selector
- Hover marker: Shows tooltip with stage name
- Current stage: Pulsing animation
- Other stages: Static markers
Styling¶
Fixed at 100x100px, bottom-left corner:
.floor-plan-minimap {
position: fixed;
bottom: 80px;
left: 20px;
width: 100px;
height: 100px;
border-radius: 12px;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
cursor: pointer;
}
Editor Integration¶
Map Location Picker¶
Click "Set Location" in the stage editor to open:
- Search Bar - Type address or landmark
- Interactive Map - Drag to fine-tune position
- Coordinates Display - Lat/lng shown in real-time
- Place Name - Auto-filled from geocoding
- Confirm Button - Saves to stage config
Keyboard Shortcuts: - Enter - Confirm selection - Escape - Cancel and close - Tab - Focus next input
Floor Plan Editor¶
Position markers visually:
- Upload floor plan image
- Click on floor plan to place marker
- Drag to adjust position
- Coordinates auto-normalized (0-1 range)
Advanced Features¶
Multi-Floor Buildings¶
Support for complex venues with multiple floors:
{
"navigation": {
"type": "floorplan",
"floorPlans": [
{ "floor": 0, "name": "Basement", "imageUrl": "..." },
{ "floor": 1, "name": "Ground Floor", "imageUrl": "..." },
{ "floor": 2, "name": "Mezzanine", "imageUrl": "..." },
{ "floor": 3, "name": "Rooftop", "imageUrl": "..." }
]
}
}
Floor Switcher UI: - Appears in expanded floor plan view - Tabs for each floor - Current floor highlighted - Click to switch views
Custom Map Tiles¶
For enterprise customers, custom tile servers can be configured. Contact support for setup assistance.
Performance Considerations¶
Maps¶
- Leaflet CDN: Loaded on-demand (~40KB gzipped)
- Tile Caching: Browser caches tiles automatically
- Lazy Loading: Only loads visible tiles
Floor Plans¶
- Image Optimization: Compress images to <1MB
- SVG Markers: Lightweight vector graphics
- Debounced Rendering: Minimizes redraws
Troubleshooting¶
Map Not Showing¶
Check: 1. β
navigation.type === "map" 2. β
Markers have valid geoPosition (not 0,0) 3. β
Network allows access to unpkg.com (Leaflet CDN) 4. β
Network allows access to tile server (OpenStreetMap) 5. β
Browser console for errors
Common Fix:
// Ensure coordinates are numbers, not strings
"geoPosition": {
"lat": 40.7128, // β
number
"lng": -74.0060 // β
number
}
// NOT:
"geoPosition": {
"lat": "40.7128", // β string
"lng": "-74.0060" // β string
}
Floor Plan Not Showing¶
Check: 1. β
Floor plan image URL is publicly accessible 2. β
CORS headers allow loading from your domain 3. β
Image format is PNG or JPG (SVG not recommended for floor plans) 4. β
Markers have floorPlanPosition with values 0-1
Test Image:
curl -I https://your-cdn.com/floorplan.png
# Should return 200 OK
# Should include: Access-Control-Allow-Origin: *
Geocoding Not Working¶
Check: 1. β
Internet connection allows access to nominatim.openstreetmap.org 2. β
Rate limit not exceeded (max 1 req/second) 3. β
Search query is valid (not empty, not too short)
Fallback: If geocoding fails, you can manually set coordinates:
Next Steps¶
- Hotspots Guide - Add interactive elements
- Configuration Schema - Full config reference
- Self-Hosting - Export and host tours