Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Let the user display their own arbitrary GeoJSON file in browse #547

Merged
merged 2 commits into from
Nov 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/lib/browse/LayerControls.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import Stats19LayerControl from "./layers/points/Stats19.svelte";
import VehicleCountsLayerControl from "./layers/points/VehicleCounts.svelte";
import ProblemsLayerControl from "./layers/points/Problems.svelte";
import UserDataLayerControl from "./layers/points/UserData.svelte";
import SchemesLayer from "./schemes/SchemesLayer.svelte";
import { interactiveMapLayersEnabled, controls } from "./stores";
import { getRoadLayerNames } from "lib/maplibre";
Expand Down Expand Up @@ -75,6 +76,7 @@

<div bind:this={$controls}>
<SchemesLayer />

<CollapsibleCard label="Trip generators">
<CheckboxGroup small>
<EducationLayerControl />
Expand All @@ -83,6 +85,7 @@
<RailwayStationsLayerControl />
</CheckboxGroup>
</CollapsibleCard>

<CollapsibleCard label="Existing infrastructure">
<CheckboxGroup small>
<CyclePathsLayerControl />
Expand All @@ -94,13 +97,15 @@
<RightsOfWayLayerControl />
</CheckboxGroup>
</CollapsibleCard>

<CollapsibleCard label="Public transport">
<CheckboxGroup small>
<BusRoutesLayerControl />
<TramsLayerControl />
<BusStopsLayerControl />
</CheckboxGroup>
</CollapsibleCard>

<CollapsibleCard label="Boundaries">
<CheckboxGroup small>
<ParliamentaryConstituenciesLayerControl />
Expand All @@ -110,12 +115,14 @@
<LocalPlanningAuthoritiesLayerControl />
</CheckboxGroup>
</CollapsibleCard>

<CollapsibleCard label="Census">
<CheckboxGroup small>
<CensusOutputAreaLayerControl />
<ImdLayerControl />
</CheckboxGroup>
</CollapsibleCard>

<CollapsibleCard label="Other">
<CheckboxGroup small>
<VehicleCountsLayerControl />
Expand All @@ -130,8 +137,10 @@
{/if}
<PollutionLayerControl />
<RoadNoiseLayerControl />
<UserDataLayerControl />
</CheckboxGroup>
</CollapsibleCard>

<CollapsibleCard label="Tools">
<StreetViewTool {cfg} map={$map} bind:enabled={streetviewEnabled} />
<LineMeasureTool />
Expand Down
107 changes: 107 additions & 0 deletions src/lib/browse/layers/points/UserData.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<script lang="ts">
import LayerControl from "../LayerControl.svelte";
import { layerId } from "lib/maplibre";
import {
hoverStateFilter,
FillLayer,
LineLayer,
CircleLayer,
GeoJSON,
} from "svelte-maplibre";
import { showHideLayer } from "../url";
import { FileInput } from "govuk-svelte";
import UserDataPopup from "./UserDataPopup.svelte";

let name = "user_data";
let title = "Your own GeoJSON file";

let show = showHideLayer(name);

let data = {
type: "FeatureCollection" as const,
features: [],
};

function loadFile(filename: string, text: string) {
try {
data = JSON.parse(text);
} catch (err) {
window.alert(`Couldn't load ${filename} -- is it GeoJSON? ${err}`);
}
}
</script>

<LayerControl {name} {title} bind:show={$show}>
<span slot="help">
<p>This is your own GeoJSON file.</p>
</span>

<div slot="controls" style="border: 1px solid black; padding: 8px;">
<FileInput label="Load your own GeoJSON file" onLoad={loadFile} />
<p><i>Note this file doesn't leave your computer; it's not uploaded anywhere</i></p>
<p>Currently showing {data.features.length.toLocaleString()} features</p>
</div>
</LayerControl>

<GeoJSON {data} generateId>
<FillLayer
{...layerId("user_data_polygons")}
manageHoverState
filter={["==", ["geometry-type"], "Polygon"]}
paint={{
"fill-color": "blue",
"fill-opacity": hoverStateFilter(0.5, 1.0),
}}
layout={{
visibility: $show ? "visible" : "none",
}}
hoverCursor="pointer"
eventsIfTopMost
>
<UserDataPopup />
</FillLayer>
<LineLayer
{...layerId("user_data_polygons-outline")}
paint={{
"line-color": "black",
"line-width": 2.5,
}}
layout={{
visibility: $show ? "visible" : "none",
}}
/>

<LineLayer
{...layerId("user_data_lines")}
manageHoverState
filter={["==", ["geometry-type"], "LineString"]}
paint={{
"line-color": "green",
"line-width": hoverStateFilter(3, 5),
}}
layout={{
visibility: $show ? "visible" : "none",
}}
hoverCursor="pointer"
eventsIfTopMost
>
<UserDataPopup />
</LineLayer>

<CircleLayer
{...layerId("user_data_points")}
manageHoverState
filter={["==", ["geometry-type"], "Point"]}
paint={{
"circle-color": "red",
"circle-radius": hoverStateFilter(3, 5),
}}
layout={{
visibility: $show ? "visible" : "none",
}}
hoverCursor="pointer"
eventsIfTopMost
>
<UserDataPopup />
</CircleLayer>
</GeoJSON>
22 changes: 22 additions & 0 deletions src/lib/browse/layers/points/UserDataPopup.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<script lang="ts">
import { Popup } from "lib/common";
</script>

<Popup openOn="click" let:props>
<table>
<thead>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
</thead>
<tbody>
{#each Object.entries(props) as [key, value]}
<tr>
<td>{key}</td>
<td>{value}</td>
</tr>
{/each}
</tbody>
</table>
</Popup>
6 changes: 6 additions & 0 deletions src/lib/maplibre/zorder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ export let layerZorder = [
browse("imd-outline"),
browse("pollution"),
browse("road_noise"),
browse("user_data_polygons"),
browse("user_data_polygons-outline"),

// Then optional linear layers
browse("mrn"),
browse("srn"),
Expand All @@ -50,6 +53,8 @@ export let layerZorder = [
browse("gradient"),
browse("gradient_arrows"),
browse("rights_of_way"),
browse("user_data_lines"),

// Then small point/polygon layers on top
browse("education"),
browse("hospitals"),
Expand All @@ -60,6 +65,7 @@ export let layerZorder = [
browse("vehicle_counts"),
browse("stats19"),
browse("bus_stops"),
browse("user_data_points"),

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