route-surface-breakdown (Phase 1): Planner-path surface/waytype bars
Synchronous path + rendering for the surface/waytype breakdown: - map-core `computeSurfaceBreakdown(coords, surfaces, highways)` → distance- weighted metres per surface + waytype category (unit-tested); - `SurfaceBreakdownSchema` in @trails-cool/api; - nullable `surfaceBreakdown` jsonb on routes + activities; - Planner `SaveToJournalButton` computes it from the BRouter waytags already in routeData and sends it; `api.save-to-journal` forwards it; the journal route callback validates + persists (journal is the authoritative validator); - `SurfaceBreakdown` component (stacked bars per dimension, map-core palettes, legend category · % · km largest-first, unknown → "other", hidden when empty) on route + activity detail; journal gains a @trails-cool/map-core dep; - i18n journal.surface.* (en + de). Phase 2 (async Overpass backfill + SSE for imports/uploads, and the e2e that seeds a breakdown) follows in a separate PR. Tests: computeSurfaceBreakdown unit (map-core 36); SurfaceBreakdown component (jsdom, journal 326). typecheck + lint green; verified in the browser. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
e1e3dc5c81
commit
3a1c34317d
21 changed files with 388 additions and 18 deletions
|
|
@ -42,6 +42,9 @@ export {
|
|||
type ComputeRouteRequest,
|
||||
} from "./routes.ts";
|
||||
|
||||
// Surface / waytype breakdown
|
||||
export { SurfaceBreakdownSchema, type SurfaceBreakdown } from "./surface-breakdown.ts";
|
||||
|
||||
// Activities
|
||||
export {
|
||||
ActivitySummarySchema, ActivityDetailSchema,
|
||||
|
|
|
|||
15
packages/api/src/surface-breakdown.ts
Normal file
15
packages/api/src/surface-breakdown.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* Distance-weighted surface/waytype breakdown (metres per category). Shared
|
||||
* wire shape for the planner→journal handoff and the route/activity read APIs.
|
||||
* Mirrors `SurfaceBreakdown` in `@trails-cool/map-core`.
|
||||
*/
|
||||
const MetresByCategory = z.record(z.string(), z.number().min(0));
|
||||
|
||||
export const SurfaceBreakdownSchema = z.object({
|
||||
surface: MetresByCategory,
|
||||
highway: MetresByCategory,
|
||||
});
|
||||
|
||||
export type SurfaceBreakdown = z.infer<typeof SurfaceBreakdownSchema>;
|
||||
Loading…
Add table
Add a link
Reference in a new issue