Skip to content

Commit

Permalink
Visualize steepness. #18
Browse files Browse the repository at this point in the history
Adapted from acteng/atip#475
  • Loading branch information
dabreegster committed Feb 23, 2024
1 parent 6f31e13 commit df0333e
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 52 deletions.
Binary file added viewer/assets/chevron.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions viewer/src/App.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script lang="ts">
import chevron from "../assets/chevron.png?url";
import init from "lts";
import type { Map as MapType } from "maplibre-gl";
import { FileSource, PMTiles } from "pmtiles";
Expand Down Expand Up @@ -85,6 +86,8 @@
standardControls
hash
bind:map
on:error={(e) => console.log(e.detail)}
images={[{ id: "chevron", url: chevron }]}
>
{#if outputMetadata}
{#key outputMetadata}
Expand Down
45 changes: 42 additions & 3 deletions viewer/src/Layers.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,24 @@
hoverStateFilter,
LineLayer,
type LayerClickInfo,
SymbolLayer,
} from "svelte-maplibre";
import { colorByLts, colors, type LayersControls } from "./common";
import {
slopeLimits,
slopeColors,
colorByLts,
colors,
type LayersControls,
makeColorRamp,
} from "./common";
import Popup from "./Popup.svelte";
import PropertiesTable from "./PropertiesTable.svelte";
import { showDestinations, showOrigins, showRouteNetwork } from "./stores";
import {
showSlope,
showDestinations,
showOrigins,
showRouteNetwork,
} from "./stores";
export let sourceOverride = {};
export let controls: LayersControls;
Expand Down Expand Up @@ -49,6 +62,12 @@
let id = e.detail.features[0].properties!.way;
window.open(`http://openstreetmap.org/way/${id}`, "_blank");
}
let colorBySlope = makeColorRamp(
["abs", ["get", "slope"]],
slopeLimits,
slopeColors,
);
</script>

<LineLayer
Expand All @@ -59,7 +78,7 @@
hoverCursor={enableControls ? "pointer" : undefined}
paint={{
"line-width": lineWidth,
"line-color": colorByLts,
"line-color": $showSlope ? colorBySlope : colorByLts,
"line-opacity": hoverStateFilter(1.0, 0.5),
}}
layout={{
Expand All @@ -75,6 +94,26 @@
{/if}
</LineLayer>

<SymbolLayer
id="slope-arrows"
{...sourceOverride}
filter={[
"all",
["==", ["geometry-type"], "LineString"],
[">", ["abs", ["get", "slope"]], 3],
]}
minzoom={12}
layout={{
"icon-image": "chevron",
"icon-size": 1.0,
"symbol-placement": "line",
"symbol-spacing": 50,
"icon-allow-overlap": true,
"icon-rotate": ["case", ["<", ["get", "slope"], 0], 180, 0],
visibility: $showSlope ? "visible" : "none",
}}
/>

<CircleLayer
id="origins-layer"
{...sourceOverride}
Expand Down
2 changes: 1 addition & 1 deletion viewer/src/Loader.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
async function pmtilesInfo(file: PMTiles): Promise<Info> {
let header = await file.getHeader();
let metadata = await file.getMetadata() as any;
let metadata = (await file.getMetadata()) as any;
return {
bounds: [header.minLon, header.minLat, header.maxLon, header.maxLat],
Expand Down
2 changes: 1 addition & 1 deletion viewer/src/PropertiesTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
{/if}
{#if properties.slope}
<div>
Slope: [{properties.slope.toFixed(2)}, {-properties.slope.toFixed(2)}]
Slope: {properties.slope.toFixed(2)}&percnt;
</div>
{/if}
<div>
Expand Down
102 changes: 64 additions & 38 deletions viewer/src/SidebarControls.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
<script lang="ts">
import type { Map } from "maplibre-gl";
import { colors, ltsNames, type LayersControls } from "./common";
import {
slopeLimits,
slopeColors,
colors,
ltsNames,
type LayersControls,
} from "./common";
import Legend from "./Legend.svelte";
import { showDestinations, showOrigins, showRouteNetwork } from "./stores";
import SequentialLegend from "./SequentialLegend.svelte";
import {
showSlope,
showDestinations,
showOrigins,
showRouteNetwork,
} from "./stores";
import StreetView from "./StreetView.svelte";
export let outputMetadata: any;
Expand Down Expand Up @@ -84,41 +96,55 @@
</label>
</div>

<hr />
<Legend
rows={[
[
`${ltsNames.lts1}: ${total(outputMetadata.total_meters_lts1)}`,
colors.lts1,
],
[
`${ltsNames.lts2}: ${total(outputMetadata.total_meters_lts2)}`,
colors.lts2,
],
[
`${ltsNames.lts3}: ${total(outputMetadata.total_meters_lts3)}`,
colors.lts3,
],
[
`${ltsNames.lts4}: ${total(outputMetadata.total_meters_lts4)}`,
colors.lts4,
],
// Shouldn't happen
[
`${ltsNames.lts_not_allowed}: ${total(
outputMetadata.total_meters_not_allowed,
)}`,
colors.lts_not_allowed,
],
]}
/>
<p>
Note: LTS model from <a
href="https://github.com/BikeOttawa/stressmodel/blob/master/stressmodel.js"
target="_blank"
>
BikeOttawa
</a>
</p>
{#if outputMetadata.config.elevation_geotiff}
<div>
<label>
<input type="checkbox" bind:checked={$showSlope} />
Visualize slope
</label>
</div>
{/if}

{#if $showSlope}
<SequentialLegend colorScale={slopeColors} limits={slopeLimits} />
{:else}
<hr />
<Legend
rows={[
[
`${ltsNames.lts1}: ${total(outputMetadata.total_meters_lts1)}`,
colors.lts1,
],
[
`${ltsNames.lts2}: ${total(outputMetadata.total_meters_lts2)}`,
colors.lts2,
],
[
`${ltsNames.lts3}: ${total(outputMetadata.total_meters_lts3)}`,
colors.lts3,
],
[
`${ltsNames.lts4}: ${total(outputMetadata.total_meters_lts4)}`,
colors.lts4,
],
// Shouldn't happen
[
`${ltsNames.lts_not_allowed}: ${total(
outputMetadata.total_meters_not_allowed,
)}`,
colors.lts_not_allowed,
],
]}
/>
<p>
Note: LTS model from <a
href="https://github.com/BikeOttawa/stressmodel/blob/master/stressmodel.js"
target="_blank"
>
BikeOttawa
</a>
</p>
{/if}

<hr />
<StreetView {map} bind:enabled={controls.streetviewOn} />
19 changes: 10 additions & 9 deletions viewer/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,13 @@ export let ltsNames = {
lts_not_allowed: "Cyclists not allowed",
};

// Hack around
// https://stackoverflow.com/questions/67336062/typescript-not-parsed-in-svelte-html-section
// until we're using Svelte 5
export function notNull<T>(x: T | null | undefined): T {
if (x == null || x == undefined) {
throw new Error("Oops, notNull given something null");
}
return x;
}
// Thanks to https://ropensci.github.io/slopes/articles/roadnetworkcycling.html
export let slopeLimits = [0, 3, 5, 8, 10, 20, 100];
export let slopeColors = [
"#267300",
"#70A800",
"#FFAA00",
"#E60000",
"#A80000",
"#730000",
];
1 change: 1 addition & 0 deletions viewer/src/stores.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ import { writable } from "svelte/store";
export let showRouteNetwork = writable(true);
export let showOrigins = writable(false);
export let showDestinations = writable(false);
export let showSlope = writable(false);

0 comments on commit df0333e

Please sign in to comment.