Amenity & Specs Filtering
Relevant source files
The following files were used as context for generating this wiki page:
Amenity & Specs Filtering is a core system within the P4n Map project designed to refine Park4Night locations and OpenStreetMap (OSM) points of interest (POIs) based on user-defined criteria and route proximity. The system differentiates between "hard" filters, which exclude locations entirely (such as minimum ratings or private/off-road categories), and "soft" preferences, which influence the ranking and visual badging of results without hiding them.
This system operates across a "corridor" defined by the planned route, ensuring that all suggested stops are within a practical distance from the intended path. It also integrates specialized logic for dog-friendly planning, allowing users to find parking spots near dog parks or identify dog parks as independent waypoints along the journey.
Sources: README.md, src/lib/planner.ts:18-30, src/components/SpecsControls.tsx:11-17
Filtering Architecture & Data Flow
The filtering logic is split between persistent settings and trip-specific overrides. Persistent filters, such as minimum rating and primary service requirements (e.g., wifi, showers), are managed in the user's settings. Trip-specific toggles, specifically water and electricity, are surfaced during active planning as they often depend on the van's current state.
Filtering Logic Flow
The following diagram illustrates how the system processes candidate places against user specifications.
The system first applies hard exclusions based on place category and minimum rating before checking if the location falls within the defined maxKmFromRoad corridor.
Sources: src/lib/planner.ts:47-92, src/components/SpecsControls.tsx:18-24, src/app/settings/page.tsx:210-258
Specifications & Requirements
The system uses the Specs and CorridorSettings interfaces to define the filtering parameters.
| Parameter | Type | Description | File |
|---|---|---|---|
requiredServices | string[] | Codes for services that trigger badges and ranking boosts (e.g., wifi, water). | src/lib/types.ts:133 |
minRating | number | Minimum average rating threshold for a place to be included (0-5). | src/lib/types.ts:135 |
maxKmFromRoad | number | The maximum perpendicular distance (corridor) from the route polyline. | src/lib/types.ts:141 |
nearDogPark | boolean | When true, searches for OSM dog parks within range of the parking spot. | src/lib/types.ts:137 |
dogParkMaxKm | number | Max distance allowed between a parking spot and a dog park. | src/lib/types.ts:143 |
Hard vs Soft Filtering
The project employs a hybrid filtering model:
- Hard Filters: Locations categorized as "excluded" (private/off-road) or those falling below the
minRatingare purged from the dataset. - Soft Preferences: Services in
requiredServicesdo not hide non-matches. Instead, matches are granted a "preference bonus" in the ranking score and a visual badge in the UI.
Sources: src/lib/planner.ts:20-29, src/lib/planner.ts:107-123, src/components/Planner.tsx:936-953
Scoring & Ranking Engine
The ranking engine converts various attributes into a composite score where a lower value represents a better match. This ensures that the most relevant and highest-quality spots appear at the top of the list.
Scoring Factors
The score is calculated using the following components:
- Base Cost: The perpendicular distance (
kmFromRoad) from the road. - Rating Bonus: Up to -1.5 km-equivalent reduction for a 5-star rating.
- Service Bonus: Each matched service (e.g., water, electric) reduces the score by 0.4 km-equivalent.
- Dog Park Bonus: A soft bonus (up to -1.2 km) is applied if a dog park is within the specified proximity.
Sources: src/lib/planner.ts:125-144
The final result set is sorted by this composite score. In the event of a tie, the system defaults to progressKm to maintain travel order.
Sources: src/lib/planner.ts:101-103
Amenity Searching (OSM)
Independent of Park4Night locations, the system can search for specific amenities from OpenStreetMap (OSM) via the /api/amenities endpoint. This search is strictly bounded by the route corridor.
Supported Amenity Kinds
The system explicitly supports the following amenity types for en-route searching:
dog_parksupermarketfueltoiletsdrinking_water
Sources: src/app/api/amenities/route.ts:11-13, src/lib/types.ts:121
API Implementation
The findAmenities function (client-side) and the /api/amenities route (server-side) facilitate these corridor-constrained searches using Overpass.
// Example of amenity search parameters
export interface AmenityBody {
polyline: LngLat[];
kind: AmenityKind;
maxKmFromRoad: number;
window?: ProgressWindow | null;
}
Sources: src/app/api/amenities/route.ts:15-21, src/lib/client.ts:167-175
Dog-Specific Planning Features
The project places a high priority on dog-friendly travel, offering two distinct modes for integration:
- Proximity Filtering (
nearDogPark): This mode searches for OSM dog parks within a certain distance (dogParkMaxKm) of candidate Park4Night spots. If found, the dog park information is attached to theScoredPlaceobject and a badge is displayed. - En-route Waypoints (
dogParksEnRoute): This mode treats dog parks as standalone waypoints. Users can filter these bydogParkMinKmFromStartto avoid seeing parks too close to their departure point.
Sources: src/components/SpecsControls.tsx:64-110, src/lib/planner.ts:74-85, src/lib/types.ts:137-145
Summary
The Amenity & Specs Filtering system provides a flexible, two-tier approach to trip customization. By combining rigid geometric constraints (corridors and look-ahead windows) with soft ranking bonuses for user preferences, it ensures that planning results are both geographically feasible and tailored to the user's specific van setup and pet requirements. All logic is centralized in src/lib/planner.ts to ensure consistency between manual UI interactions and the voice-activated assistant.