More
This commit is contained in:
parent
1f68ca0512
commit
3599803589
43 changed files with 3578 additions and 262 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { useCallback, useRef, useState, useMemo } from 'react';
|
||||
import { H3HexagonLayer } from '@deck.gl/geo-layers';
|
||||
import { GeoJsonLayer, IconLayer, TextLayer } from '@deck.gl/layers';
|
||||
import { GeoJsonLayer, IconLayer, TextLayer, ScatterplotLayer } from '@deck.gl/layers';
|
||||
import type { PickingInfo } from '@deck.gl/core';
|
||||
import type {
|
||||
HexagonData,
|
||||
|
|
@ -44,6 +44,10 @@ interface UseDeckLayersProps {
|
|||
theme: 'light' | 'dark';
|
||||
searchedPostcode?: SearchedPostcode | null;
|
||||
bounds?: Bounds | null;
|
||||
travelTimeEnabled?: boolean;
|
||||
travelTimeDestination?: [number, number] | null;
|
||||
travelTimeColorRange?: [number, number] | null;
|
||||
travelTimeRange?: [number, number] | null;
|
||||
}
|
||||
|
||||
export interface PopupInfo {
|
||||
|
|
@ -70,6 +74,10 @@ export function useDeckLayers({
|
|||
theme,
|
||||
searchedPostcode,
|
||||
bounds: viewportBounds,
|
||||
travelTimeEnabled = false,
|
||||
travelTimeDestination,
|
||||
travelTimeColorRange,
|
||||
travelTimeRange,
|
||||
}: UseDeckLayersProps) {
|
||||
const [popupInfo, setPopupInfo] = useState<PopupInfo | null>(null);
|
||||
const [hoverPosition, setHoverPosition] = useState<{ x: number; y: number } | null>(null);
|
||||
|
|
@ -99,6 +107,15 @@ export function useDeckLayers({
|
|||
const hoveredPostcodeRef = useRef(hoveredPostcode);
|
||||
hoveredPostcodeRef.current = hoveredPostcode;
|
||||
|
||||
const travelTimeEnabledRef = useRef(travelTimeEnabled);
|
||||
travelTimeEnabledRef.current = travelTimeEnabled;
|
||||
const travelTimeDestinationRef = useRef(travelTimeDestination);
|
||||
travelTimeDestinationRef.current = travelTimeDestination;
|
||||
const travelTimeColorRangeRef = useRef(travelTimeColorRange);
|
||||
travelTimeColorRangeRef.current = travelTimeColorRange;
|
||||
const travelTimeRangeRef = useRef(travelTimeRange);
|
||||
travelTimeRangeRef.current = travelTimeRange;
|
||||
|
||||
const colorFeatureMeta = useMemo(
|
||||
() => (viewFeature ? features.find((f) => f.name === viewFeature) || null : null),
|
||||
[viewFeature, features]
|
||||
|
|
@ -225,8 +242,9 @@ export function useDeckLayers({
|
|||
}, []);
|
||||
|
||||
// --- Color triggers ---
|
||||
const colorTrigger = `${viewFeature}|${colorRange?.[0]}|${colorRange?.[1]}|${filterRange?.[0]}|${filterRange?.[1]}|${countRange.min}|${countRange.max}|${selectedHexagonId}|${hoveredHexagonId}|${theme}`;
|
||||
const postcodeColorTrigger = `${viewFeature}|${colorRange?.[0]}|${colorRange?.[1]}|${filterRange?.[0]}|${filterRange?.[1]}|${postcodeCountRange.min}|${postcodeCountRange.max}|${selectedPostcode}|${hoveredPostcode}|${theme}`;
|
||||
const ttTrigger = `${travelTimeEnabled}|${travelTimeColorRange?.[0]}|${travelTimeColorRange?.[1]}|${travelTimeRange?.[0]}|${travelTimeRange?.[1]}|${travelTimeDestination?.[0]}`;
|
||||
const colorTrigger = `${viewFeature}|${colorRange?.[0]}|${colorRange?.[1]}|${filterRange?.[0]}|${filterRange?.[1]}|${countRange.min}|${countRange.max}|${selectedHexagonId}|${hoveredHexagonId}|${theme}|${ttTrigger}`;
|
||||
const postcodeColorTrigger = `${viewFeature}|${colorRange?.[0]}|${colorRange?.[1]}|${filterRange?.[0]}|${filterRange?.[1]}|${postcodeCountRange.min}|${postcodeCountRange.max}|${selectedPostcode}|${hoveredPostcode}|${theme}|${ttTrigger}`;
|
||||
|
||||
// --- Layers ---
|
||||
const hexLayer = useMemo(
|
||||
|
|
@ -236,11 +254,36 @@ export function useDeckLayers({
|
|||
data,
|
||||
getHexagon: (d) => d.h3,
|
||||
getFillColor: (d) => {
|
||||
const dark = isDarkRef.current;
|
||||
// Travel time coloring takes priority
|
||||
if (travelTimeEnabledRef.current && travelTimeDestinationRef.current) {
|
||||
const ttVal = d.travel_time;
|
||||
const ttClr = travelTimeColorRangeRef.current;
|
||||
if (ttVal == null) {
|
||||
return (dark ? [80, 70, 65, 80] : [128, 128, 128, 80]) as [number, number, number, number];
|
||||
}
|
||||
const ttFr = travelTimeRangeRef.current;
|
||||
if (ttFr && ((ttVal as number) < ttFr[0] || (ttVal as number) > ttFr[1])) {
|
||||
return (dark ? [60, 55, 50, 60] : [180, 180, 180, 60]) as [number, number, number, number];
|
||||
}
|
||||
if (ttClr) {
|
||||
return getFeatureFillColor(
|
||||
ttVal as number,
|
||||
ttVal as number,
|
||||
ttVal as number,
|
||||
ttClr,
|
||||
null,
|
||||
0,
|
||||
densityGradientRef.current,
|
||||
dark,
|
||||
255
|
||||
);
|
||||
}
|
||||
}
|
||||
const vf = viewFeatureRef.current;
|
||||
const clr = colorRangeRef.current;
|
||||
const fr = filterRangeRef.current;
|
||||
const cfm = colorFeatureMetaRef.current;
|
||||
const dark = isDarkRef.current;
|
||||
if (vf && clr && cfm) {
|
||||
const val = d[`avg_${vf}`] ?? d[`min_${vf}`];
|
||||
const minVal = d[`min_${vf}`] as number | undefined;
|
||||
|
|
@ -457,13 +500,30 @@ export function useDeckLayers({
|
|||
});
|
||||
}, [searchedPostcode, searchedPostcodeHasData]);
|
||||
|
||||
const destinationMarkerLayer = useMemo(() => {
|
||||
if (!travelTimeEnabled || !travelTimeDestination) return null;
|
||||
return new ScatterplotLayer({
|
||||
id: 'travel-time-destination',
|
||||
data: [{ position: [travelTimeDestination[1], travelTimeDestination[0]] }],
|
||||
getPosition: (d: { position: [number, number] }) => d.position,
|
||||
getRadius: 8,
|
||||
getFillColor: [239, 68, 68, 220],
|
||||
getLineColor: [255, 255, 255, 255],
|
||||
getLineWidth: 2,
|
||||
lineWidthUnits: 'pixels' as const,
|
||||
radiusUnits: 'pixels' as const,
|
||||
stroked: true,
|
||||
pickable: false,
|
||||
});
|
||||
}, [travelTimeEnabled, travelTimeDestination]);
|
||||
|
||||
const layers = useMemo(() => {
|
||||
const baseLayers = usePostcodeView
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const baseLayers: any[] = usePostcodeView
|
||||
? [postcodeLayer, postcodeLabelsLayer, poiLayer]
|
||||
: [hexLayer, poiLayer];
|
||||
if (searchedPostcodeHighlightLayer) {
|
||||
return [...baseLayers, searchedPostcodeHighlightLayer];
|
||||
}
|
||||
if (searchedPostcodeHighlightLayer) baseLayers.push(searchedPostcodeHighlightLayer);
|
||||
if (destinationMarkerLayer) baseLayers.push(destinationMarkerLayer);
|
||||
return baseLayers;
|
||||
}, [
|
||||
usePostcodeView,
|
||||
|
|
@ -472,6 +532,7 @@ export function useDeckLayers({
|
|||
postcodeLabelsLayer,
|
||||
poiLayer,
|
||||
searchedPostcodeHighlightLayer,
|
||||
destinationMarkerLayer,
|
||||
]);
|
||||
|
||||
const handleMouseLeave = useCallback(() => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue