Files
TREK/client/src/components/Tours/paddle/paddlePaint.ts
T
Maurice 1bc82f97fd feat(tours): route paddle tours on the water, shaping points and auto-loaded regions
Paddle tours are planned on the water by TREK's own router: a water network
per paddle region, built from the same Geofabrik extract as the obstacles and
searched in a worker thread of the server (no sidecar). Rivers, canals and
lakes (direct or along the shore), portages round weirs, locks by policy,
whitewater by boat, gaps marked. Found portages and locks become points of
their own; an unplannable leg says why and offers a way out.

- Shaping points: a click on the line sets a point that steers the route
  without being a stop (hikes and paddle tours); recompute a single leg.
- Lake style direct/shore, suggested from the wind forecast.
- Regions load by themselves where a paddler plans (admin setting: automatic,
  on request, off; size cap and a daily count), with requests for the admins,
  a notification, and the load followed on the leg.
- Portage from the last point, portages follow footways via the walking
  router (or stay straight), "put in here" on slipways and put-ins.
- MCP plan_paddle_route with the REST route's rules.
2026-10-18 21:21:32 +00:00

56 lines
1.8 KiB
TypeScript

import type { PaddleObstacleKind } from '@trek/shared';
import { useMapPaint } from '../../Map/mapPaint';
/**
* The colours of paddle objects and carried stretches (styles/paddle.css):
* a kind of object has its colour, never one for safe or unsafe. Map paint
* reads them resolved (`usePaddlePaint`); markup on the page takes the CSS
* variable itself (`paddleKindCss`), which follows the theme on its own.
*/
const PADDLE_PAINT_TOKENS = {
obstacle: '--map-paddle-obstacle',
access: '--map-paddle-access',
landing: '--map-paddle-landing',
portage: '--map-portage',
rapids: '--map-paddle-rapids',
gap: '--map-paddle-gap',
disc: '--map-paddle-disc',
shadow: '--map-paddle-shadow',
} as const;
export type PaddlePaint = Record<keyof typeof PADDLE_PAINT_TOKENS, string>;
type Category = 'obstacle' | 'access' | 'landing' | 'portage';
const CATEGORY: Record<PaddleObstacleKind, Category> = {
weir: 'obstacle',
dam: 'obstacle',
lock: 'obstacle',
lock_gate: 'obstacle',
waterfall: 'obstacle',
rapids: 'obstacle',
hazard: 'obstacle',
access: 'access',
put_in: 'landing',
egress: 'landing',
slipway: 'landing',
portage: 'portage',
};
/** The resolved colour of a kind, for map paint. */
export function paddleKindPaint(kind: PaddleObstacleKind, paint: PaddlePaint): string {
return paint[CATEGORY[kind]];
}
/** The colour of a kind as a CSS variable, for markup on the page (the card, the route band). */
export function paddleKindCss(kind: PaddleObstacleKind): string {
return `var(${PADDLE_PAINT_TOKENS[CATEGORY[kind]]})`;
}
/** A carried stretch's brown, for markup on the page. */
export const PORTAGE_CSS_COLOR = `var(${PADDLE_PAINT_TOKENS.portage})`;
/** The paddle colours resolved for map paint, again whenever the theme changes. */
export function usePaddlePaint(): PaddlePaint {
return useMapPaint(PADDLE_PAINT_TOKENS);
}