Skip to content

Commit

Permalink
Update route-snapper
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Nov 1, 2023
1 parent eb0c2ff commit 0f63a3d
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 68 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"js-cookie": "^3.0.5",
"maplibre-gl": "^3.5.1",
"read-excel-file": "^5.6.1",
"route-snapper": "^0.2.1",
"route-snapper": "^0.2.3",
"svelte": "^4.0.0",
"svelte-maplibre": "github:dabreegster/svelte-maplibre#changes_for_atip"
}
Expand Down
2 changes: 1 addition & 1 deletion src/lib/common/Alpha.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</a>
and
<a href="mailto:[email protected]">Pete</a>
with any feedback.
with any feedback.
</span>
</p>
</div>
37 changes: 10 additions & 27 deletions src/lib/draw/route/RouteControls.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { Checkbox, CheckboxGroup } from "lib/govuk";
import { routeTool, userSettings } from "stores";
import { routeTool, routeToolSnapMode, userSettings } from "stores";
// Start with this enabled or disabled, based on whether we're drawing a new
// route or editing an existing.
Expand All @@ -11,53 +11,36 @@
avoid_doubling_back: $userSettings.avoidDoublingBack,
extend_route: extendRoute,
});
// TODO It'd be nice to wire up reactivity to RouteTool directly.
let snapping = true;
function onKeyDown(e: KeyboardEvent) {
if (e.key == "Shift") {
// Don't stop propagation, so RouteTool can see this
snapping = false;
}
}
function onKeyUp(e: KeyboardEvent) {
if (e.key == "Shift") {
// Don't stop propagation, so RouteTool can see this
snapping = true;
}
}
</script>

<svelte:window on:keydown={onKeyDown} on:keyup={onKeyUp} />

{#if snapping}
<p>
Snapping to existing roads. Press <b>Shift</b>
{#if $routeToolSnapMode}
<p style="background: red; color: white; padding: 8px;">
Snapping to existing roads. Press <b>s</b>
to draw anywhere
</p>
{:else}
<p>
Drawing points anywhere. Release <b>Shift</b>
<p style="background: blue; color: white; padding: 8px;">
Drawing points anywhere. Press <b>s</b>
to snap to roads
</p>
{/if}

<ul>
<li>
<b>Click</b>
green points on the transport network to create snapped routes
the map to add points
</li>
<li>
Hold <b>Shift</b>
to draw a point anywhere
Press <b>s</b>
to switch between snapping points to existing roads and drawing anywhere
</li>
<li>
<b>Click and drag</b>
any point to move it
</li>
<li>
<b>Click</b>
a red waypoint to delete it
a waypoint to delete it
</li>
<li>
Press <b>Enter</b>
Expand Down
4 changes: 2 additions & 2 deletions src/lib/draw/route/RouteSnapperLoader.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { ErrorMessage } from "lib/govuk";
import init from "route-snapper";
import { map, routeTool } from "stores";
import { map, routeTool, routeToolSnapMode } from "stores";
import { onMount } from "svelte";
import { RouteTool } from "./route_tool";
Expand All @@ -18,7 +18,7 @@
console.log(`Grabbing ${url}`);
try {
const graphBytes = await fetchWithProgress(url);
routeTool.set(new RouteTool($map, graphBytes));
routeTool.set(new RouteTool($map, graphBytes, routeToolSnapMode));
progress = 100;
routeToolReady = true;
} catch (err) {
Expand Down
54 changes: 23 additions & 31 deletions src/lib/draw/route/route_tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
} from "lib/maplibre";
import type { GeoJSONSource, Map, MapMouseEvent } from "maplibre-gl";
import { JsRouteSnapper } from "route-snapper";
import { type Writable } from "svelte/store";

const source = "route-snapper";

Expand All @@ -30,8 +31,9 @@ export class RouteTool {
f: FeatureWithProps<LineString | Polygon>
) => void)[];
eventListenersFailure: (() => void)[];
snapMode: Writable<boolean>;

constructor(map: Map, graphBytes: Uint8Array) {
constructor(map: Map, graphBytes: Uint8Array, snapMode: Writable<boolean>) {
this.map = map;
console.time("Deserialize and setup JsRouteSnapper");
this.inner = new JsRouteSnapper(graphBytes);
Expand All @@ -40,6 +42,7 @@ export class RouteTool {
this.eventListenersSuccess = [];
this.eventListenersUpdated = [];
this.eventListenersFailure = [];
this.snapMode = snapMode;

// Rendering
overwriteSource(map, source, emptyGeojson());
Expand All @@ -50,22 +53,23 @@ export class RouteTool {
color: constructMatchExpression(
["get", "type"],
{
hovered: "green",
important: "red",
"snapped-waypoint": "red",
"free-waypoint": "blue",
},
"black"
),
opacity: ["case", ["has", "hovered"], 0.5, 1.0],
radius: constructMatchExpression(
["get", "type"],
{ unimportant: circleRadiusPixels / 2.0 },
{ node: circleRadiusPixels / 2.0 },
circleRadiusPixels
),
});
overwriteLineLayer(map, {
id: "route-lines",
source,
filter: isLine,
color: "black",
color: ["case", ["get", "snapped"], "red", "blue"],
width: 2.5,
});
overwritePolygonLayer(map, {
Expand All @@ -81,9 +85,8 @@ export class RouteTool {
this.map.on("dblclick", this.onDoubleClick);
this.map.on("dragstart", this.onDragStart);
this.map.on("mouseup", this.onMouseUp);
document.addEventListener("keypress", this.onKeypress);
document.addEventListener("keydown", this.onKeyDown);
document.addEventListener("keyup", this.onKeyUp);
document.addEventListener("keypress", this.onKeyPress);
}

tearDown() {
Expand All @@ -98,9 +101,8 @@ export class RouteTool {
this.map.off("dblclick", this.onDoubleClick);
this.map.off("dragstart", this.onDragStart);
this.map.off("mouseup", this.onMouseUp);
document.removeEventListener("keypress", this.onKeypress);
document.removeEventListener("keydown", this.onKeyDown);
document.removeEventListener("keyup", this.onKeyUp);
document.removeEventListener("keypress", this.onKeyPress);
}

onMouseMove = (e: MapMouseEvent) => {
Expand Down Expand Up @@ -163,37 +165,26 @@ export class RouteTool {
}
};

onKeypress = (e: KeyboardEvent) => {
if (!this.active) {
return;
}
if (e.key == "Enter") {
e.stopPropagation();
this.finish();
}
};

onKeyDown = (e: KeyboardEvent) => {
if (!this.active) {
return;
}
if (e.key == "Shift") {
// Don't stop propagation, so RouteControls can see this
this.inner.setSnapMode(false);
this.redraw();
} else if (e.key == "Escape") {
if (e.key == "Escape") {
e.stopPropagation();
this.cancel();
}
};

onKeyUp = (e: KeyboardEvent) => {
onKeyPress = (e: KeyboardEvent) => {
if (!this.active) {
return;
}
if (e.key == "Shift") {
// Don't stop propagation, so RouteControls can see this
this.inner.setSnapMode(true);
if (e.key == "Enter") {
e.stopPropagation();
this.finish();
} else if (e.key == "s") {
e.stopPropagation();
this.inner.toggleSnapMode();
this.redraw();
}
};
Expand Down Expand Up @@ -343,9 +334,10 @@ export class RouteTool {
}

private redraw() {
(this.map.getSource(source) as GeoJSONSource).setData(
JSON.parse(this.inner.renderGeojson())
);
let gj = JSON.parse(this.inner.renderGeojson());
(this.map.getSource(source) as GeoJSONSource).setData(gj);
this.map.getCanvas().style.cursor = gj.cursor;
this.snapMode.set(gj.snap_mode);
}

private dataUpdated() {
Expand Down
4 changes: 2 additions & 2 deletions src/lib/draw/snap_polygon/SnapPolygonControls.svelte
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<ul>
<li>
<b>Click</b>
green points on the transport network to create snapped routes
the map to add points
</li>
<li>
<b>Click and drag</b>
any point to move it
</li>
<li>
<b>Click</b>
a red waypoint to delete it
a waypoint to delete it
</li>
<li>
Press <b>Enter</b>
Expand Down
3 changes: 3 additions & 0 deletions src/stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ export const polygonTool: Writable<PolygonTool | null> = writable(null);
// A global singleton, with the route tool loaded for the current map. It's
// null before it's loaded.
export const routeTool: Writable<RouteTool | null> = writable(null);
// This is used to plumb state from inside RouteTool in a way that Svelte
// components can use reactively.
export const routeToolSnapMode: Writable<boolean> = writable(true);

// TODO Should we instead store a map from ID to feature?
export const gjScheme: Writable<Scheme> = writable(emptyGeojson() as Scheme);
Expand Down

0 comments on commit 0f63a3d

Please sign in to comment.