Skip to content

Commit

Permalink
Start a layer for OS road widths and speeds
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Sep 20, 2023
1 parent 88cad1a commit b1e81ea
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/lib/browse/LayerControls.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script lang="ts">
import {
appVersion,
BaselayerSwitcher,
CollapsibleCard,
StreetViewController,
Expand All @@ -21,6 +22,8 @@
import ParliamentaryConstituenciesLayerControl from "./layers/ParliamentaryConstituenciesLayerControl.svelte";
import PctLayerControl from "./layers/PctLayerControl.svelte";
import RailwayStationsLayerControl from "./layers/RailwayStationsLayerControl.svelte";
import RoadSpeedsLayerControl from "./layers/RoadSpeedsLayerControl.svelte";
import RoadWidthsLayerControl from "./layers/RoadWidthsLayerControl.svelte";
import SchoolsLayerControl from "./layers/SchoolsLayerControl.svelte";
import SportsSpacesLayerControl from "./layers/SportsSpacesLayerControl.svelte";
import VehicleCountsLayerControl from "./layers/VehicleCountsLayerControl.svelte";
Expand Down Expand Up @@ -73,6 +76,10 @@
<CollapsibleCard label="Other">
<VehicleCountsLayerControl />
<PctLayerControl />
{#if appVersion() == "Private (development)" || true}
<RoadWidthsLayerControl />
<RoadSpeedsLayerControl />
{/if}
</CollapsibleCard>
<StreetViewController
bind:this={streetViewController}
Expand Down
110 changes: 110 additions & 0 deletions src/lib/browse/layers/RoadSpeedsLayerControl.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
<script lang="ts">
import { ExternalLink, HelpButton, InteractiveLayer } from "lib/common";
import { Checkbox, Radio } from "lib/govuk";
import {
hoveredToggle,
makeColorRamp,
overwriteLineLayer,
overwritePmtilesSource,
} from "lib/maplibre";
import type { MapGeoJSONFeature } from "maplibre-gl";
import { map } from "stores";
import { colors, denseLineWidth } from "../colors";
import SequentialLegend from "./SequentialLegend.svelte";
let name = "road_speeds";
let colorScale = colors.sequential_low_to_high;
let limits = [0, 20, 30, 40, 50, 90];
let showSpeed = "indicative_mph";
overwritePmtilesSource(
$map,
name,
`${import.meta.env.VITE_RESOURCE_BASE}/private_layers/v1/${name}.pmtiles`
);
overwriteLineLayer($map, {
id: name,
source: name,
sourceLayer: name,
color: makeColorRamp(["get", showSpeed], limits, colorScale),
width: denseLineWidth,
opacity: hoveredToggle(0.5, 1.0),
});
let show = false;
function tooltip(feature: MapGeoJSONFeature): string {
// @ts-ignore Trusting the input data has the correct form
let time = {
mf4to7: "Monday-Friday 4-7am",
mf7to9: "Monday-Friday 7-9am",
mf9to12: "Monday-Friday 9am-12pm",
mf12to14: "Monday-Friday 12-2pm",
mf14to16: "Monday-Friday 2-4pm",
mf16to19: "Monday-Friday 4-7pm",
mf19to22: "Monday-Friday 7-10pm",
mf22to4: "Monday-Friday 10pm-4am",
ss4to7: "Saturday-Sunday 4-7am",
ss7to10: "Saturday-Sunday 7-10am",
ss10to14: "Saturday-Sunday 10am-2pm",
ss14to19: "Saturday-Sunday 2-7pm",
ss19to22: "Saturday-Sunday 7-10pm",
ss22to4: "Saturday-Sunday 10pm-4am",
}[feature.properties.highest_description];
let x = `<p>Posted speed limit: ${feature.properties.indicative_mph} mph</p>`;
x += `<p>Highest average speed: ${feature.properties.highest_mph} mph (during ${time})</p>`;
return x;
}
function changeStyle() {
$map.setPaintProperty(
name,
"line-color",
makeColorRamp(["get", showSpeed], limits, colorScale)
);
}
</script>

<Checkbox id={name} bind:checked={show}>
OS Speeds
<span slot="right">
<HelpButton>
<p>
The average speed data is collected over a six-month period by <ExternalLink
href="https://basemap.co.uk/speed-data"
>
Basemap
</ExternalLink> from 135,000 vehicle telematic systems and provided through
Ordnance Survey. The averages are grouped by different time periods for weekdays
and weekends. This map shows the highest average.
</p>
<p>Data valid as of 1 September, 2023</p>
<p>
License: Contains OS data &copy; Crown copyright and database right
2023. Made available under the <ExternalLink
href="https://www.ordnancesurvey.co.uk/documents/licensing/psga-member-licence.pdf"
>
Public Sector Geospatial Agreement
</ExternalLink>.
</p>
</HelpButton>
</span>
</Checkbox>
{#if show}
<SequentialLegend {colorScale} {limits} />
<Radio
legend="Show speed types"
id="showSpeed"
choices={[
["indicative_mph", "Posted speed limit"],
["highest_mph", "Highest measured average speed"],
]}
bind:value={showSpeed}
on:change={changeStyle}
inlineSmall
/>
{/if}

<InteractiveLayer layer={name} {tooltip} {show} clickable={false} />
70 changes: 70 additions & 0 deletions src/lib/browse/layers/RoadWidthsLayerControl.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<script lang="ts">
import { ExternalLink, HelpButton, InteractiveLayer } from "lib/common";
import { Checkbox } from "lib/govuk";
import {
hoveredToggle,
makeColorRamp,
overwriteLineLayer,
overwritePmtilesSource,
} from "lib/maplibre";
import type { MapGeoJSONFeature } from "maplibre-gl";
import { map } from "stores";
import { colors, denseLineWidth } from "../colors";
import SequentialLegend from "./SequentialLegend.svelte";
let name = "road_widths";
let colorScale = colors.sequential_low_to_high;
let limits = [0, 5, 10, 15, 20, 100];
overwritePmtilesSource(
$map,
name,
`${import.meta.env.VITE_RESOURCE_BASE}/private_layers/v1/${name}.pmtiles`
);
overwriteLineLayer($map, {
id: name,
source: name,
sourceLayer: name,
color: makeColorRamp(["get", "average"], limits, colorScale),
// TODO Try showing the actual width, in meters and not pixels
width: denseLineWidth,
opacity: hoveredToggle(0.5, 1.0),
});
let show = false;
function tooltip(feature: MapGeoJSONFeature): string {
let x = `<p>Average width: ${feature.properties.average} meters</p>`;
x += `<p>Minimum width: ${feature.properties.minimum} meters</p>`;
return x;
}
</script>

<Checkbox id={name} bind:checked={show}>
OS Road widths
<span slot="right">
<HelpButton>
<p>
This is average and minimum road carriageway width (in meters) from
Ordnance Survey. The coloring shows the average width, and the line
thickness has no meaning. Be careful interpreting the data near dual
carriageways and crossing islands.
</p>
<p>Data valid as of 1 September, 2023</p>
<p>
License: Contains OS data &copy; Crown copyright and database right
2023. Made available under the <ExternalLink
href="https://www.ordnancesurvey.co.uk/documents/licensing/psga-member-licence.pdf"
>
Public Sector Geospatial Agreement
</ExternalLink>.
</p>
</HelpButton>
</span>
</Checkbox>
{#if show}
<SequentialLegend {colorScale} {limits} />
{/if}

<InteractiveLayer layer={name} {tooltip} {show} clickable={false} />
2 changes: 2 additions & 0 deletions src/lib/maplibre/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,8 @@ const layerZorder = [
"vehicle_counts",
"pct_commute",
"pct_school",
"road_widths",
"road_speeds",

// Polygons are bigger than lines, which're bigger than points. When geometry
// overlaps, put the smaller thing on top
Expand Down

0 comments on commit b1e81ea

Please sign in to comment.