/** * RouteLayer — the Route half of "Routing & Tracking" (spec, v0.6.7). * Expands into ordinary `PathLayer`/`IconLayer` instances, exactly the way * `BIMLayer` expands into a `Tile3DLayer` — see that file's own doc comment * for the pattern this mirrors (a `CompositeLayer` wrapping real deck.gl * layers, not a new rendering path). * * Two authoring paths, mutually exclusive (`geometry` wins if both are * present — validation.ts warns on the ambiguity): * * - `geometry` — an already-computed GeoJSON LineString. Resolves * SYNCHRONOUSLY, no provider round-trip. Distance is derived locally * (great-circle length); duration is left `NaN` — no speed model exists * client-side, and a provider-computed route supplies its own. * - `provider` + `origin` + `destination` (+ optional `waypoints`, * `profile`) — resolves ASYNCHRONOUSLY via `RoutingProvider.computeRoute` * (mirrors BIMLayer's `loadModel`: state, staleness checks, abort on * supersede/teardown, `raiseError` on failure — see that file). * * `onRouteResolved` is injected by the runtime (`schema.carriesRoute`, the * `onTilesetLoad`/`carriesTileset` precedent in runtime-core.ts) once a * route is ready — that's what drives `follow="fit-route"` camera behavior. * RouteLayer itself never touches the camera; camera side effects belong to * runtime-core, not a deck.gl layer subclass. */ import { CompositeLayer } from "@deck.gl/core"; import type { Layer } from "@deck.gl/core"; import { type Route, type RouteWaypoint } from "../providers"; export interface RouteBounds { bounds: [[number, number], [number, number]]; } type LineStringGeometry = { type: "LineString"; coordinates: [number, number][]; }; /** * Splits a polyline at the point on it nearest to `point` (spec: "Routing & * Tracking / tail modes"). Real GPS fixes sit OFF the line, so the split is a * projection onto the nearest segment, not an exact-vertex match. Longitudes * are scaled by cos(mid-latitude) before comparing distances — raw degrees * would overweight longitude away from the equator and can pick the wrong * segment on north–south routes. Both halves include the projected point, so * `taken` ends exactly where `remaining` begins. Pure and exported for * direct unit testing (the `lerpAngle` precedent). */ export declare function splitLineAtNearestPoint(coordinates: readonly (readonly [number, number])[], point: readonly [number, number]): { taken: [number, number][]; remaining: [number, number][]; }; export interface RouteLayerProps { geometry?: LineStringGeometry | string; origin?: [number, number] | string; destination?: [number, number] | string; waypoints?: RouteWaypoint[] | string; provider?: string; profile?: "driving" | "walking" | "cycling"; color?: string; casingColor?: string; /** * How the TRAVELED portion of the route renders, once `progress-from` * supplies a current position (spec: "Routing & Tracking / tail modes"): * "full" (default — whole route in `color`, the split is ignored), * "dim" (operator view — traveled portion darkened, remaining in `color`), * "none" (client view — only current position → destination renders, and * the origin pin is dropped too: a start marker with no line reaching it * reads as a stray point). */ tail?: "full" | "dim" | "none"; /** Dim-mode tail color override; default derives a darkened `color`. */ tailColor?: string; /** Id of the Tracking layer whose position splits this route — consumed by src/tracking-interpolation.ts (which patches `progressPosition` here per frame), not by this class directly. */ progressFrom?: string; /** Injected per frame by src/tracking-interpolation.ts — never authored. */ progressPosition?: [number, number]; /** Injected by runtime-core.ts (schema.carriesRoute) — never authored. */ onRouteResolved?: (route: Route & RouteBounds) => void; [prop: string]: unknown; } export declare class RouteLayer extends CompositeLayer { static layerName: string; static defaultProps: { color: string; casingColor: string; profile: string; }; state: { route: Route | null; loadingFor: string | null; destroyed: boolean; abort: AbortController | null; }; initializeState(): void; updateState({ props, oldProps }: { props: RouteLayerProps; oldProps: RouteLayerProps; }): void; finalizeState(): void; private resolveRoute; /** One casing-or-line `PathLayer` — the repeated shape of every stroke below. */ private strokeLayer; renderLayers(): Layer[]; } export {};