WayFy’s Accessibility Map is the core feature of the platform — an interactive Mapbox GL map that overlays real OpenStreetMap wheelchair-accessibility data on top of a location-aware map view. As you pan and zoom the map, data is streamed in progressively from the Overpass API across three query phases, filtered in real time by both accessibility level and place category. Community-submitted pins sit as a second data layer alongside OSM data, so travelers benefit from both authoritative tagging and lived experience.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/jhonyes04/new-wayfy/llms.txt
Use this file to discover all available pages before exploring further.
How the Map Works
The map is driven by theuseAccessibilityMap hook (hooks/useAccessibilityMap.jsx). On load it requests the browser’s geolocation, flies to the user’s coordinates at zoom level 14, and triggers the first Overpass data fetch. As the user pans or zooms, a 300 ms debounce fires a fresh fetch for the new bounding box. All in-flight requests are cancelled via AbortController when a new move event arrives, keeping the map responsive.
The map does not load OSM data below zoom level 14. If you zoom out past that threshold, the POI layer is cleared and a prompt asks you to zoom in closer.
Map Style Selector
TheMapStyleSelector component lets users switch between Mapbox base styles (Streets, Satellite, Outdoors, Light, Dark) without reloading any data. The style choice persists while the session is active.
Layer Architecture
The map registers four interactive Mapbox GL layer IDs ininteractiveLayerIds, all managed through the layers object returned by useAccessibilityMap:
clusters
Circle clusters that group nearby OSM points. Color steps from teal (≤9 points) → sky blue (10–49) → soft red (50+). Clicking a cluster zooms to its expansion level.
unclustered-point
Individual OSM wheelchair-tagged nodes. Color encodes the
wheelchair tag value: green (yes), amber (limited), red (no), grey (unknown/absent).community-approved
Community pins that have been approved by an admin. Rendered as solid purple circles (
#8b5cf6) with a white stroke.community-pending
The current user’s own pending community pins, shown at 45% opacity so they are visually distinct from approved data.
cluster-count, is also rendered as a symbol on top of each cluster circle showing the abbreviated point count in white DIN Offc Pro Medium text. It is not included in interactiveLayerIds because click events are handled by the clusters layer beneath it.
OSM Data Flow via Overpass API
Wheelchair data is fetched byfetchWheelchairPlacesProgressive in services/overpass.api.js. Each call fires three sequential Overpass QL queries and calls onPartialData after each one completes, so the map populates incrementally rather than waiting for all three to finish.
Query Phases
Phase 1 — Direct wheelchair tags
Fetches all OSM nodes, ways, and relations that carry a
wheelchair tag directly. This is the fastest phase and gives the clearest signal: the mapper explicitly evaluated the place.Phase 2 — Amenities, shops, and tourism with accessibility tags
Fetches all
amenity, shop, and tourism nodes in the bounding box, then filters to those carrying any of the following accessibility-related tags: wheelchair, wheelchair:description, wheelchair:access, entrance:wheelchair, door:width, door:automatic, door:bell, kerb, incline, tactile_paving, or toilets:wheelchair.Endpoint Failover
Each Overpass query is attempted against three endpoints in order, with a 10-second timeout per attempt:| Priority | Endpoint |
|---|---|
| 1 (primary) | https://overpass-api.de/api/interpreter |
| 2 (fallback) | https://overpass.kumi.systems/api/interpreter |
| 3 (fallback) | https://maps.mail.ru/osm/tools/overpass/api/interpreter |
Wheelchair Filter Values
TheactiveFilters array in global state holds the currently active set of wheelchair values. The filter panel (FilterAccessibility component) toggles these; at least one value is always active.
| Value | Meaning | Map Color |
|---|---|---|
yes | Fully accessible — no barriers for wheelchair users | Green #10b891 |
limited | Partially accessible — usable with difficulty or assistance | Amber #ffc108 |
no | Not accessible | Red #db3545 |
unknown | No accessibility tag present in OSM | Grey #93a2b8 |
Category Filters
TheactiveCategories array holds the active OSM category slugs. The FilterCategories component toggles them individually or clears all at once.
| Slug | Label | Icon |
|---|---|---|
alojamiento | Alojamientos | fa-bed |
gastronomia | Gastronomía | fa-utensils |
transporte | Transporte | fa-bus |
salud | Salud | fa-house-medical |
cultura_turismo | Turismo | fa-landmark-flag |
recreacion | Ocio | fa-champagne-glasses |
deporte | Deporte | fa-volleyball |
gobierno | Oficinas | fa-building-columns |
baños | Baños | fa-restroom |
dinero | Bancos | fa-money-bill-transfer |
tiendas | Tiendas | fa-bag-shopping |
Community Pins Workflow
Community pins are places submitted by logged-in WayFy users through theCustomPinPopup component. Clicking an empty spot on the map while authenticated drops a pin at that coordinate; the popup lets the user fill in a place name, sub-type, and label before submitting to POST /api/places.
User places a custom pin
A click on an empty map area sets
customPin state in useAccessibilityMap. The CustomPinPopup renders at the pin’s coordinates and the user fills in place details.Pin saved as pending
The backend creates a
Place record with status: 'pending'. The pin appears immediately in the community-pending layer (semi-transparent purple) for the submitting user.Admin review
An administrator reviews submitted places via
/admin/places. Approving a place sets status: 'approved'.Favorites on the Map
Saved favorites are rendered as<Marker> components with a heart icon rather than as a map layer. This means they are always visible regardless of the active wheelchair filters or category filters. The useFavorites hook provides addFavorite, removeFavorite, and isFavorite methods; the heart button inside AccessibilityDetails calls these while the map reflects the updated state.
Place Detail Panel
Clicking anyunclustered-point or community pin opens the AccessibilityDetails offcanvas panel. It is divided into three sections:
InfoSection
Name, address (reverse-geocoded via Nominatim), OSM type, opening hours, phone, website, and a direct link to the OSM element.
OsmAccessibilitySection
All OSM accessibility tags present on the feature: kerb type, incline, tactile paving, door width, automatic door, accessible toilets, and more — displayed with human-readable labels from
OSM_TRANSLATIONS.CommunityReviewSection
The community-sourced accessibility review for the place (wheelchair rating, ramp, elevator, accessible toilet, parking, automatic door, description, and photos). Opens
AccessibilityEditor for logged-in users.PhotoLightbox component, which opens inline within the AccessibilityDetails panel.
AI Assistant Integration
TheAIAssistant component sits in the bottom center of the map as a floating input bar. When a user submits a natural-language query (for example, “accessible hotels near Atocha”), the useAIAssistant hook calls fetchMapData, which posts to POST /api/ai/mapgpt and then geocodes the extracted location. On success it dispatches three global state updates simultaneously:
SET_SELECTED_LOCATION— flies the map to the geocoded coordinates at zoom 15SET_ACTIVE_FILTERS— applies the AI-extracted wheelchair filter valuesSET_ACTIVE_CATEGORIES— applies the AI-extracted category slugs
es-ES); the microphone icon in the input bar toggles listening mode.
See the AI Assistant page for full endpoint and prompt documentation.