Add per-POI travel time filtering and fix heatmap color stops
Replace the single global max travel time filter with per-POI filters. Each POI gets its own travel mode selector and max minutes input in the filter panel. Listings must satisfy ALL active filters (AND logic). Fix Mapbox "Input is not a number" error by ensuring color stops are always strictly monotonic (guard min === max) and always set (even when no valid metric values exist). Also filter Infinity values from the color scale computation. Widen the filter panel from w-64 to w-80.
This commit is contained in:
parent
81d31eaecf
commit
07d4fa5f84
5 changed files with 193 additions and 17 deletions
41
frontend/src/utils/poiUtils.ts
Normal file
41
frontend/src/utils/poiUtils.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import type { PropertyFeature, POIDistanceInfo } from '@/types';
|
||||
|
||||
/**
|
||||
* Build the flat property name used by the hexgrid heatmap to read
|
||||
* travel-time values directly from feature.properties.
|
||||
*/
|
||||
export function poiMetricPropertyName(poiId: number, travelMode: string): string {
|
||||
return `poi_travel_${poiId}_${travelMode}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shallow-copy every feature and inject a flat numeric property
|
||||
* (e.g. `poi_travel_7_TRANSIT = 1800`) so the heatmap can color by it.
|
||||
*
|
||||
* Features without matching POI distance data get `undefined` for that property,
|
||||
* which the heatmap will skip (same as a listing with no sqm value).
|
||||
*/
|
||||
export function injectPoiMetricProperty(
|
||||
features: PropertyFeature[],
|
||||
poiId: number,
|
||||
travelMode: string,
|
||||
): PropertyFeature[] {
|
||||
const propName = poiMetricPropertyName(poiId, travelMode);
|
||||
|
||||
return features.map((feature) => {
|
||||
const distances: POIDistanceInfo[] | undefined = feature.properties.poi_distances;
|
||||
const match = distances?.find(
|
||||
(d) => d.poi_id === poiId && d.travel_mode === travelMode,
|
||||
);
|
||||
|
||||
if (match === undefined) return feature;
|
||||
|
||||
return {
|
||||
...feature,
|
||||
properties: {
|
||||
...feature.properties,
|
||||
[propName]: match.duration_seconds,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue