Skip to main content
Build an interactive map interface that shows resource locations, floor plans, availability, and booking previews on a geographic or building map.

Concepts

Resource Locations

The core booking resources data layer used for:
  • Creating map markers
  • Displaying the resource booking card
  • Determining availability status
Fetch resource coordinates along with optional availability and viewport filters.

Resource Map Previews

Lightweight metadata for each building map, used for:
  • Resource map dropdown
  • Determining initial map position
  • Identifying maps within the current viewport
  • Referencing the GeoJSON URL for rendering

Resource Maps

Full GeoJSON + layer data for a single building floor plan. Only fetched when a map enters the viewport.

Booking Previews

Partially anonymized booking data used to:
  • Display user avatars on the map
  • Highlight resources booked by the current user

Viewport Filtering

A map-move event (throttled to 200ms) triggers viewport checks. Resource maps within the viewport are mounted; those outside are unmounted.

Marker Types


Initialization Flow

1

Fetch initial data

Fetch Resource Locations (without child resources), Resource Map Previews, and the initial bounding box for the active filters — location, availability, category, and context (community / organization / customer account). Do not apply viewport filtering at this stage.
2

Determine initial map position

3

Display the Resource Map Dropdown

with all available floor plans.
4

Initialize the map

with the position from step 2.
5

On map load:

  • Play the starting animation
  • Mount markers (see Mounting Markers)
  • Mount resource maps (see Resource Map Management) within the initial viewport
  • Apply any pre-selected resource features
  • Register all relevant events

Interaction Flow


Availability Filter Update Flow

On filter change:
  1. Fetch resource locations with map previews
  2. Update active markers
If mounted resource maps are included in the new previews:
  • Fetch availability data
  • Update resource feature states (section below)
Else:
  • Remove active resource maps
  • Re-run initialization flow from step 2

Mounting Markers

1. Add GeoJSON source:
2. Add layers:
  • Circle layer — clustered marker circles (maxzoom: 15)
  • Symbol layer — cluster count labels (maxzoom: 15)
  • Circle layer — markers for resources on a floor plan (maxzoom: 15)
  • Circle layer — standalone markers (all zoom levels)
3. Register events:
  • Hover events for all marker layers
  • Cluster click → decluster
  • Standalone marker click → zoom to level 21 → show resource popup
  • Floor-plan marker click → zoom to level 15.5

Viewport Filtering

Triggered by the map move event, throttled to 200ms. Store resource map previews in an R-Tree indexed by bounding box for fast spatial lookups. Update the R-Tree whenever resource map preview data changes. Flow:
  1. Get viewport bounds
  2. Get viewport center
  3. Search R-Tree for overlapping maps
  4. Mount maps newly within the viewport
  5. Unmount maps that left the viewport
  6. Sort overlapping maps by distance to viewport center
  7. Activate the layer control for the closest (focused) map

Resource Map Management

Mounting

  1. Add GeoJSON source (requires: GeoJSON data URL from map preview, resource map ID):
  1. Add style layers (minzoom: 15)
  2. Register events:
    • Hover events (mouseenter, mouseleave, mousemove) for live resource features
    • Click event → show resource popup
  3. Add Booking Preview data (see below)
  4. Fetch availability for all active resource features
  5. Update feature states using map.setFeatureState():

Unmounting

  1. Remove Booking Preview data
  2. Deregister events (map.off())
  3. Remove layers (map.removeLayer())
  4. Remove GeoJSON source (map.removeSource())

Updating Data

  1. Get the layer data source
  2. Get the data source (map.getSource())
  3. Update with source.setData(newData)

Shared maps (managed organizations)

A managing organization can publish a floor plan to every organization it manages. Sharing is stored on the map resource, not as a separate share object.

Enable or disable sharing

Set sharedWithManagedOrganizations to false to stop sharing. Linked managed organizations are detached, and the map disappears from their GET /api/v1/resource-maps index.

Who can see and edit a shared map

On the owner read, JSON:API meta.shared_organization_ids lists managed organization IDs that currently have resources assigned on the map. Managed organizations do not receive that meta.

Filter maps by the sharing flag

This filters the owner’s maps by the setting. It is not a way for a managed organization to opt in: shared maps already appear in that organization’s index.

Booking Previews on Maps

Fetch booking previews for the resources within a mounted floor plan and overlay avatar markers on the corresponding resource features. Use map.setFeatureState() to attach preview data to individual GeoJSON features for rendering. Refresh booking previews whenever a booking WebSocket event is received on the resources.{resourceId} channel.

API Endpoints Used