From 905cdc633db65e435e76a53d4a770acb634cc2fa Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Sat, 13 Jul 2024 13:50:43 +0100 Subject: [PATCH] Rename some types and vars --- src/lib/config.ts | 10 ++--- src/lib/draw/EditGeometryMode.svelte | 9 ++--- src/lib/draw/HoverLayer.svelte | 6 +-- src/lib/draw/InterventionLayer.svelte | 12 +++--- src/lib/draw/Toolbox.svelte | 6 +-- src/lib/draw/point/PointMode.svelte | 6 +-- src/lib/draw/polygon/PolygonMode.svelte | 6 +-- src/lib/draw/route/RouteMode.svelte | 6 +-- src/lib/draw/route/SplitRouteMode.svelte | 10 ++--- .../draw/snap_polygon/SnapPolygonMode.svelte | 6 +-- src/lib/draw/stores.ts | 23 ++++------- src/lib/draw/types.ts | 13 ++++--- src/lib/index.ts | 1 - src/lib/maplibre/zorder.ts | 1 - src/lib/sidebar/EditForm.svelte | 14 +++---- src/lib/sidebar/ListMode.svelte | 38 +++++++++---------- src/lib/sidebar/PerModeControls.svelte | 18 ++++----- src/lib/sidebar/PerSchemeControls.svelte | 35 +++++++---------- src/routes/+page.svelte | 12 +++--- src/routes/ExampleFeatureForm.svelte | 8 ++-- src/routes/ExampleSchemeForm.svelte | 8 ++-- 21 files changed, 114 insertions(+), 134 deletions(-) delete mode 100644 src/lib/index.ts diff --git a/src/lib/config.ts b/src/lib/config.ts index 3468b64..45a2ba7 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -1,6 +1,6 @@ import type { FeatureWithID, - SchemeCollection, + Schemes, SchemeData, FeatureProps, } from "$lib/draw/types"; @@ -21,7 +21,7 @@ export interface Config { schemeName: (s: SchemeData & S) => string; - backfill: (json: any) => SchemeCollection; + backfill: (json: any) => Schemes; initializeEmptyScheme: (scheme: SchemeData) => SchemeData & S; @@ -30,7 +30,7 @@ export interface Config { editFeatureForm: null | ComponentType< SvelteComponent<{ cfg: Config; - gjSchemeCollection: Writable>; + gjSchemes: Writable>; id: number; props: FeatureProps; }> @@ -38,12 +38,12 @@ export interface Config { editSchemeForm: null | ComponentType< SvelteComponent<{ - gjSchemeCollection: Writable>; + gjSchemes: Writable>; scheme_reference: string; }> >; - // Should assign any necessary properties. Runs inside a gjSchemeCollection + // Should assign any necessary properties. Runs inside a gjSchemes // update; the logic shouldn't look at anything in there. newPointFeature: (f: FeatureWithID) => void; newPolygonFeature: (f: FeatureWithID) => void; diff --git a/src/lib/draw/EditGeometryMode.svelte b/src/lib/draw/EditGeometryMode.svelte index 28402e9..95f64dd 100644 --- a/src/lib/draw/EditGeometryMode.svelte +++ b/src/lib/draw/EditGeometryMode.svelte @@ -1,7 +1,7 @@ diff --git a/src/lib/draw/InterventionLayer.svelte b/src/lib/draw/InterventionLayer.svelte index 02dc4eb..6bff7ce 100644 --- a/src/lib/draw/InterventionLayer.svelte +++ b/src/lib/draw/InterventionLayer.svelte @@ -23,13 +23,13 @@ Popup, type LayerClickInfo, } from "svelte-maplibre"; - import type { FeatureWithID, SchemeCollection } from "$lib/draw/types"; + import type { FeatureWithID, Schemes } from "$lib/draw/types"; import type { Writable } from "svelte/store"; export let cfg: Config; - export let gjSchemeCollection: Writable>; + export let gjSchemes: Writable>; - $: gj = addLineStringEndpoints($gjSchemeCollection); + $: gj = addLineStringEndpoints($gjSchemes); // TODO Maybe have a separate component for different modes. const hideWhileEditing: ExpressionSpecification = [ @@ -79,9 +79,9 @@ } } - $: colorInterventions = colorByScheme($gjSchemeCollection); + $: colorInterventions = colorByScheme($gjSchemes); function colorByScheme( - gj: SchemeCollection, + gj: Schemes, ): DataDrivenPropertyValueSpecification { return constructMatchExpression( ["get", "scheme_reference"], @@ -112,7 +112,7 @@ let feature = features[0] as FeatureWithID; let featureName = cfg.interventionName(feature); let schemeName = cfg.schemeName( - $gjSchemeCollection.schemes[feature.properties.scheme_reference], + $gjSchemes.schemes[feature.properties.scheme_reference], ); return `${featureName} (${schemeName})`; } diff --git a/src/lib/draw/Toolbox.svelte b/src/lib/draw/Toolbox.svelte index 698586f..fb0b0ba 100644 --- a/src/lib/draw/Toolbox.svelte +++ b/src/lib/draw/Toolbox.svelte @@ -9,15 +9,15 @@ import splitRouteIcon from "$lib/assets/split_route.svg"; import streetViewIcon from "$lib/assets/street_view.svg"; import HoverLayer from "./HoverLayer.svelte"; - import type { SchemeCollection } from "$lib/draw/types"; + import type { Schemes } from "$lib/draw/types"; import type { Writable } from "svelte/store"; import type { Config } from "$lib/config"; export let cfg: Config; - export let gjSchemeCollection: Writable>; + export let gjSchemes: Writable>; - +
; - export let gjSchemeCollection: Writable>; + export let gjSchemes: Writable>; onMount(() => { $pointTool!.start(); @@ -30,7 +30,7 @@ function onSuccess(feature: Feature) { feature.properties ||= {}; let f = feature as FeatureWithID; - gjSchemeCollection.update((gj) => { + gjSchemes.update((gj) => { f.id = newFeatureId(gj); f.properties.scheme_reference = getArbitrarySchemeRef(gj); cfg.newPointFeature(f); diff --git a/src/lib/draw/polygon/PolygonMode.svelte b/src/lib/draw/polygon/PolygonMode.svelte index dac5bb6..e06c213 100644 --- a/src/lib/draw/polygon/PolygonMode.svelte +++ b/src/lib/draw/polygon/PolygonMode.svelte @@ -11,11 +11,11 @@ import PolygonControls from "./PolygonControls.svelte"; import { type Config } from "$lib/config"; import type { FeatureWithID } from "$lib/draw/types"; - import type { SchemeCollection } from "$lib/draw/types"; + import type { Schemes } from "$lib/draw/types"; import type { Writable } from "svelte/store"; export let cfg: Config; - export let gjSchemeCollection: Writable>; + export let gjSchemes: Writable>; onMount(() => { $polygonTool!.startNew(); @@ -30,7 +30,7 @@ function onSuccess(feature: Feature) { feature.properties ||= {}; let f = feature as FeatureWithID; - gjSchemeCollection.update((gj) => { + gjSchemes.update((gj) => { f.id = newFeatureId(gj); f.properties.scheme_reference = getArbitrarySchemeRef(gj); cfg.newPolygonFeature(f); diff --git a/src/lib/draw/route/RouteMode.svelte b/src/lib/draw/route/RouteMode.svelte index 8770f60..1bd7055 100644 --- a/src/lib/draw/route/RouteMode.svelte +++ b/src/lib/draw/route/RouteMode.svelte @@ -10,11 +10,11 @@ import { onDestroy, onMount } from "svelte"; import RouteControls from "./RouteControls.svelte"; import { type Config } from "$lib/config"; - import type { FeatureWithID, SchemeCollection } from "$lib/draw/types"; + import type { FeatureWithID, Schemes } from "$lib/draw/types"; import type { Writable } from "svelte/store"; export let cfg: Config; - export let gjSchemeCollection: Writable>; + export let gjSchemes: Writable>; onMount(() => { $routeTool!.startRoute(); @@ -28,7 +28,7 @@ function onSuccess(feature: Feature) { let f = feature as FeatureWithID; - gjSchemeCollection.update((gj) => { + gjSchemes.update((gj) => { f.id = newFeatureId(gj); f.properties.scheme_reference = getArbitrarySchemeRef(gj); cfg.newLineStringFeature(f); diff --git a/src/lib/draw/route/SplitRouteMode.svelte b/src/lib/draw/route/SplitRouteMode.svelte index ba0891c..7f0d84c 100644 --- a/src/lib/draw/route/SplitRouteMode.svelte +++ b/src/lib/draw/route/SplitRouteMode.svelte @@ -13,11 +13,11 @@ import { onDestroy, onMount } from "svelte"; import { CircleLayer, GeoJSON, MapEvents } from "svelte-maplibre"; import splitIcon from "$lib/assets/split_route.svg"; - import type { FeatureWithID, SchemeCollection } from "$lib/draw/types"; + import type { FeatureWithID, Schemes } from "$lib/draw/types"; import type { Writable } from "svelte/store"; export let cfg: Config; - export let gjSchemeCollection: Writable>; + export let gjSchemes: Writable>; const circleRadiusPixels = 10; const snapDistancePixels = 30; @@ -65,7 +65,7 @@ // Are we snapped to anything? let candidates: [number, Position, number][] = []; - for (let [index, f] of $gjSchemeCollection.features.entries()) { + for (let [index, f] of $gjSchemes.features.entries()) { if (f.geometry.type == "LineString") { let snapped = nearestPointOnLine(f.geometry, cursor, { units: "kilometers", @@ -98,7 +98,7 @@ } let result = splitRoute( - $gjSchemeCollection.features[snappedIndex] as unknown as Feature< + $gjSchemes.features[snappedIndex] as unknown as Feature< LineString, RouteProps >, @@ -107,7 +107,7 @@ if (result != null) { let [piece1, piece2] = result; - gjSchemeCollection.update((gj) => { + gjSchemes.update((gj) => { // Keep the old ID for one, assign a new ID to the other piece1.id = gj.features[snappedIndex!].id; piece2.id = newFeatureId(gj); diff --git a/src/lib/draw/snap_polygon/SnapPolygonMode.svelte b/src/lib/draw/snap_polygon/SnapPolygonMode.svelte index b13f755..9938db9 100644 --- a/src/lib/draw/snap_polygon/SnapPolygonMode.svelte +++ b/src/lib/draw/snap_polygon/SnapPolygonMode.svelte @@ -11,11 +11,11 @@ import SnapPolygonControls from "./SnapPolygonControls.svelte"; import { type Config } from "$lib/config"; import type { FeatureWithID } from "$lib/draw/types"; - import type { SchemeCollection } from "$lib/draw/types"; + import type { Schemes } from "$lib/draw/types"; import type { Writable } from "svelte/store"; export let cfg: Config; - export let gjSchemeCollection: Writable>; + export let gjSchemes: Writable>; onMount(() => { $routeTool!.startArea(); @@ -30,7 +30,7 @@ function onSuccess(feature: Feature) { // We did startArea, so we know it's a Polygon let f = feature as FeatureWithID; - gjSchemeCollection.update((gj) => { + gjSchemes.update((gj) => { f.id = newFeatureId(gj); f.properties.scheme_reference = getArbitrarySchemeRef(gj); cfg.newPolygonFeature(f); diff --git a/src/lib/draw/stores.ts b/src/lib/draw/stores.ts index c9beee8..8a559ae 100644 --- a/src/lib/draw/stores.ts +++ b/src/lib/draw/stores.ts @@ -1,6 +1,6 @@ import { type Config } from "$lib/config"; import { writable, type Writable } from "svelte/store"; -import type { Mode, SchemeCollection } from "./types"; +import type { Mode, Schemes } from "./types"; import { PointTool } from "./point/point_tool"; import { PolygonTool } from "maplibre-draw-polygon"; import { RouteTool } from "route-snapper-ts"; @@ -37,7 +37,7 @@ export const mode: Writable = writable({ mode: "list" }); // NOTE! If you call this twice in a row in a `gjScheme.update` transaction // without adding one of the new features, then this'll return the same ID // twice! -export function newFeatureId(gj: SchemeCollection): number { +export function newFeatureId(gj: Schemes): number { let ids = new Set(); for (let f of gj.features) { ids.add(f.id); @@ -51,11 +51,11 @@ export function newFeatureId(gj: SchemeCollection): number { } export function deleteIntervention( - gjSchemeCollection: Writable>, + gjSchemes: Writable>, id: number, ) { console.log(`Deleting intervention ${id}`); - gjSchemeCollection.update((gj) => { + gjSchemes.update((gj) => { gj.features = gj.features.filter((f) => f.id != id); return gj; }); @@ -65,10 +65,8 @@ export function deleteIntervention( // When creating a new feature, arbitrarily assign it to the first scheme. The // user can change it later. -export function getArbitrarySchemeRef( - schemeCollection: SchemeCollection, -): string { - return Object.values(schemeCollection.schemes)[0].scheme_reference; +export function getArbitrarySchemeRef(gjSchemes: Schemes): string { + return Object.values(gjSchemes.schemes)[0].scheme_reference; } // Per https://datatracker.ietf.org/doc/html/rfc7946#section-11.2, 6 decimal @@ -105,9 +103,7 @@ function loadUserSettings(): UserSettings { return settings as UserSettings; } -export function emptyCollection( - cfg: Config, -): SchemeCollection { +export function emptySchemes(cfg: Config): Schemes { let gj = { type: "FeatureCollection" as const, features: [], @@ -117,10 +113,7 @@ export function emptyCollection( return gj; } -export function addEmptyScheme( - cfg: Config, - gj: SchemeCollection, -) { +export function addEmptyScheme(cfg: Config, gj: Schemes) { let scheme_reference = uuidv4(); let scheme = cfg.initializeEmptyScheme({ scheme_reference, diff --git a/src/lib/draw/types.ts b/src/lib/draw/types.ts index a3a24a4..01fba08 100644 --- a/src/lib/draw/types.ts +++ b/src/lib/draw/types.ts @@ -1,6 +1,7 @@ import type { Feature, Geometry } from "geojson"; import type { Waypoint } from "route-snapper-ts"; +// The tool is in one of these mutually exclusive modes. export type Mode = | { mode: "list"; @@ -21,7 +22,7 @@ export type Mode = | { mode: "set-image" } | { mode: "streetview" }; -// This library manages some properties, in addition to the generic user-specified ones. +// This library manages some per-feature properties, in addition to the generic user-specified ones. export type FeatureProps = F & { scheme_reference: string; @@ -34,21 +35,23 @@ export type FeatureProps = F & { waypoints?: Waypoint[]; }; -// TODO Rename +// Unlike the geojson Feature type, this satisfies more invariants. It's parameterized by user-specified properties. export type FeatureWithID = Feature & { + // The ID is always unique, numeric, and >0. id: number; properties: FeatureProps; }; -export interface SchemeCollection { +// All state managed by scheme-sketcher-lib is captured here. This is a GeoJSON FeatureCollection with additional invariants. +export interface Schemes { type: "FeatureCollection"; features: FeatureWithID[]; - // Keyed by scheme_reference, which doesn't change over the lifetime of the sketch tool + // Keyed by FeatureProps.scheme_reference, which doesn't change over the lifetime of the sketch tool schemes: { [reference: string]: SchemeData & S }; } export interface SchemeData { - // The key into SchemeCollection.schemes + // The key into Schemes.schemes scheme_reference: string; // For the sketch page; not important color: string; diff --git a/src/lib/index.ts b/src/lib/index.ts deleted file mode 100644 index a906c3f..0000000 --- a/src/lib/index.ts +++ /dev/null @@ -1 +0,0 @@ -// TODO Anything needed here? diff --git a/src/lib/maplibre/zorder.ts b/src/lib/maplibre/zorder.ts index 1e6506f..d5129e5 100644 --- a/src/lib/maplibre/zorder.ts +++ b/src/lib/maplibre/zorder.ts @@ -9,7 +9,6 @@ interface LayerProps { // Use this helper for every svelte-maplibre layer component. It sets the layer // ID, beforeId (for z-ordering between layers), and defaults to only using the // top-most layer for hovering/clicking. -// TODO Ahh kind of annoying to need to plumb this here export function layerId(cfg: Config, layerId: string): LayerProps { return { id: layerId, diff --git a/src/lib/sidebar/EditForm.svelte b/src/lib/sidebar/EditForm.svelte index 8462dcf..c07f9e8 100644 --- a/src/lib/sidebar/EditForm.svelte +++ b/src/lib/sidebar/EditForm.svelte @@ -10,18 +10,18 @@ import type { MapMouseEvent } from "maplibre-gl"; import { map, type Config } from "$lib/config"; import { onDestroy, onMount } from "svelte"; - import type { FeatureWithID, SchemeCollection } from "$lib/draw/types"; + import type { FeatureWithID, Schemes } from "$lib/draw/types"; import type { Writable } from "svelte/store"; export let cfg: Config; - export let gjSchemeCollection: Writable>; + export let gjSchemes: Writable>; export let id: number; - let feature = $gjSchemeCollection.features.find((f) => f.id == id)!; + let feature = $gjSchemes.features.find((f) => f.id == id)!; // Because of how properties are bound individually, updates to $gjScheme aren't seen. Force them. function featureUpdated(feature: FeatureWithID) { - $gjSchemeCollection = $gjSchemeCollection; + $gjSchemes = $gjSchemes; } $: featureUpdated(feature); @@ -64,7 +64,7 @@ } e.stopPropagation(); - deleteIntervention(gjSchemeCollection, id); + deleteIntervention(gjSchemes, id); } if (e.key == "e") { @@ -91,7 +91,7 @@ mode.set({ mode: "edit-geometry", id })}> Edit geometry - deleteIntervention(gjSchemeCollection, id)}> + deleteIntervention(gjSchemes, id)}> Delete @@ -101,7 +101,7 @@ diff --git a/src/lib/sidebar/ListMode.svelte b/src/lib/sidebar/ListMode.svelte index 9b4dd02..44ddf31 100644 --- a/src/lib/sidebar/ListMode.svelte +++ b/src/lib/sidebar/ListMode.svelte @@ -3,42 +3,40 @@ import { ErrorMessage, FileInput, SecondaryButton } from "govuk-svelte"; import PerSchemeControls from "./PerSchemeControls.svelte"; import { type Config } from "$lib/config"; - import type { SchemeCollection } from "$lib/draw/types"; + import type { Schemes } from "$lib/draw/types"; import type { Writable } from "svelte/store"; export let cfg: Config; - export let gjSchemeCollection: Writable>; + export let gjSchemes: Writable>; function newBlankScheme() { - addEmptyScheme(cfg, $gjSchemeCollection); - $gjSchemeCollection = $gjSchemeCollection; + addEmptyScheme(cfg, $gjSchemes); + $gjSchemes = $gjSchemes; } let errorFromFile = ""; function mergeSchemesFromFile(filename: string, text: string) { try { - let gj: SchemeCollection = cfg.backfill(JSON.parse(text)); + let gj: Schemes = cfg.backfill(JSON.parse(text)); for (let scheme of Object.values(gj.schemes)) { - if (scheme.scheme_reference in $gjSchemeCollection.schemes) { + if (scheme.scheme_reference in $gjSchemes.schemes) { throw new Error( "The file you're loading seems to contain duplicate data. Are you merging in the same file accidentally?", ); } - $gjSchemeCollection.schemes[scheme.scheme_reference] = scheme; + $gjSchemes.schemes[scheme.scheme_reference] = scheme; } - $gjSchemeCollection.features = $gjSchemeCollection.features.concat( - gj.features, - ); + $gjSchemes.features = $gjSchemes.features.concat(gj.features); // Make sure every feature ID is unique. It's fine to change existing // features, since no tool can be open and holding an ID. let i = 1; - $gjSchemeCollection.features.forEach((feature) => { + $gjSchemes.features.forEach((feature) => { feature.id = i++; }); - $gjSchemeCollection = $gjSchemeCollection; + $gjSchemes = $gjSchemes; errorFromFile = ""; } catch (err) { errorFromFile = `Couldn't load scheme from a file: ${err}`; @@ -47,7 +45,7 @@ function moveSchemeInList(scheme_reference: string, direction: number) { const currentSchemeOrder = JSON.parse( - JSON.stringify(Object.keys($gjSchemeCollection.schemes)), + JSON.stringify(Object.keys($gjSchemes.schemes)), ); const currentIndex = currentSchemeOrder.indexOf(scheme_reference); if ( @@ -61,10 +59,10 @@ ); const newSchemesObject = getReorderedSchemesObject( currentSchemeOrder, - $gjSchemeCollection.schemes, + $gjSchemes.schemes, ); - $gjSchemeCollection.schemes = newSchemesObject; - $gjSchemeCollection = $gjSchemeCollection; + $gjSchemes.schemes = newSchemesObject; + $gjSchemes = $gjSchemes; } } @@ -100,9 +98,9 @@
-{#each Object.keys($gjSchemeCollection.schemes) as scheme_reference, i (scheme_reference)} - - {#if Object.keys($gjSchemeCollection.schemes).length > 1} +{#each Object.keys($gjSchemes.schemes) as scheme_reference, i (scheme_reference)} + + {#if Object.keys($gjSchemes.schemes).length > 1} moveSchemeInList(scheme_reference, -1)} disabled={i == 0} @@ -111,7 +109,7 @@ moveSchemeInList(scheme_reference, 1)} - disabled={i == Object.keys($gjSchemeCollection.schemes).length - 1} + disabled={i == Object.keys($gjSchemes.schemes).length - 1} > Move down diff --git a/src/lib/sidebar/PerModeControls.svelte b/src/lib/sidebar/PerModeControls.svelte index 69cf7dc..831aa9e 100644 --- a/src/lib/sidebar/PerModeControls.svelte +++ b/src/lib/sidebar/PerModeControls.svelte @@ -1,6 +1,6 @@

- {cfg.schemeName($gjSchemeCollection.schemes[scheme_reference])} - + {cfg.schemeName($gjSchemes.schemes[scheme_reference])} + (showDeleteModal = true)}> Delete scheme Delete @@ -138,11 +135,7 @@

Show - + {#if numErrors == 1} @@ -153,7 +146,7 @@ {/if}
    - {#each $gjSchemeCollection.features.filter((f) => f.properties.scheme_reference == scheme_reference) as feature (feature.id)} + {#each $gjSchemes.features.filter((f) => f.properties.scheme_reference == scheme_reference) as feature (feature.id)} {@const warning = cfg.interventionWarning(feature)}
  1. diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index c1edbf3..dccaae3 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -8,7 +8,7 @@ import RouteSnapperLayer from "$lib/draw/route/RouteSnapperLayer.svelte"; import SplitRouteMode from "$lib/draw/route/SplitRouteMode.svelte"; import BoundaryLayer from "$lib/draw/BoundaryLayer.svelte"; - import { mode, emptyCollection } from "$lib/draw/stores"; + import { mode, emptySchemes } from "$lib/draw/stores"; import Toolbox from "$lib/draw/Toolbox.svelte"; import PerModeControls from "$lib/sidebar/PerModeControls.svelte"; import ExampleFeatureForm from "./ExampleFeatureForm.svelte"; @@ -130,12 +130,12 @@ ], }; - let gjSchemeCollection = writable(emptyCollection(cfg)); + let gjSchemes = writable(emptySchemes(cfg));
    - + {#if $mode.mode == "list"} - + {:else if $mode.mode == "split-route"} - + {/if} diff --git a/src/routes/ExampleFeatureForm.svelte b/src/routes/ExampleFeatureForm.svelte index 1278b69..9082618 100644 --- a/src/routes/ExampleFeatureForm.svelte +++ b/src/routes/ExampleFeatureForm.svelte @@ -1,14 +1,12 @@