Skip to content

Commit

Permalink
Work on neighbourhood clipping again
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Dec 18, 2023
1 parent 2c53cf1 commit 1687c18
Show file tree
Hide file tree
Showing 4 changed files with 263 additions and 14 deletions.
38 changes: 34 additions & 4 deletions backend/src/neighbourhood.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,47 @@
use std::collections::HashSet;

use anyhow::Result;
use geo::{Contains, Polygon};
use geojson::GeoJson;
use geo::{Contains, EuclideanDistance, Intersects, Polygon};
use geojson::{Feature, GeoJson, Geometry};

use crate::{MapModel, RoadID};
use crate::{IntersectionID, MapModel, RoadID};

pub struct Neighbourhood {
interior_roads: HashSet<RoadID>,
crosses: HashSet<RoadID>,
border_intersections: HashSet<IntersectionID>,
}

impl Neighbourhood {
pub fn new(map: &MapModel, boundary: Polygon) -> Result<Self> {
let mut interior_roads = HashSet::new();
let mut crosses = HashSet::new();
for r in &map.roads {
if boundary.contains(&r.linestring) {
interior_roads.insert(r.id);
} else if boundary.intersects(&r.linestring) {
crosses.insert(r.id);
}
}

let mut border_intersections = HashSet::new();
for i in &map.intersections {
// 0 if it's within...
let dist = i.point.euclidean_distance(&boundary);
if dist > 0.0 && dist < 5.0 {
border_intersections.insert(i.id);
}
}

if interior_roads.is_empty() {
bail!("No roads inside the boundary");
}

Ok(Self { interior_roads })
Ok(Self {
interior_roads,
crosses,
border_intersections,
})
}

pub fn to_gj(&self, map: &MapModel) -> GeoJson {
Expand All @@ -34,6 +52,18 @@ impl Neighbourhood {
f.set_property("kind", "interior_road");
features.push(f);
}
for r in &self.crosses {
let mut f = map.roads[r.0].to_gj(&map.mercator);
f.set_property("kind", "crosses");
features.push(f);
}
for i in &self.border_intersections {
let mut f = Feature::from(Geometry::from(
&map.mercator.to_wgs84(&map.intersections[i.0].point),
));
f.set_property("kind", "border_intersection");
features.push(f);
}

GeoJson::from(features)
}
Expand Down
209 changes: 208 additions & 1 deletion web/src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,212 @@
});
}
function devMode() {
mode = {
mode: "neighbourhood",
boundary: {
geometry: {
coordinates: [
[
[-2.582766, 51.455751],
[-2.582715, 51.455655],
[-2.582477, 51.455207],
[-2.582446, 51.455157],
[-2.582409, 51.455129],
[-2.582334, 51.455111],
[-2.58226, 51.455115],
[-2.582174, 51.455113],
[-2.582115, 51.455126],
[-2.581976, 51.454882],
[-2.581812, 51.454602],
[-2.582181, 51.454505],
[-2.582091, 51.454224],
[-2.582071, 51.454159],
[-2.582042, 51.454073],
[-2.581915, 51.453674],
[-2.581972, 51.453287],
[-2.581714, 51.45322],
[-2.58169, 51.453214],
[-2.581866, 51.452966],
[-2.581588, 51.45288],
[-2.581521, 51.45281],
[-2.581584, 51.452731],
[-2.581401, 51.452671],
[-2.581103, 51.452566],
[-2.579862, 51.452092],
[-2.579808, 51.452069],
[-2.579753, 51.452045],
[-2.579074, 51.451752],
[-2.578228, 51.45135],
[-2.578131, 51.451293],
[-2.578066, 51.451251],
[-2.577641, 51.450924],
[-2.577504, 51.450818],
[-2.577228, 51.450628],
[-2.576815, 51.450348],
[-2.576749, 51.450294],
[-2.576487, 51.450084],
[-2.57599, 51.449653],
[-2.575886, 51.449685],
[-2.575807, 51.449709],
[-2.575324, 51.44978],
[-2.574139, 51.449954],
[-2.573887, 51.450007],
[-2.573699, 51.450097],
[-2.573534, 51.450262],
[-2.573415, 51.450398],
[-2.573305, 51.45055],
[-2.573286, 51.450604],
[-2.573279, 51.450637],
[-2.573275, 51.45066],
[-2.57327, 51.450705],
[-2.573278, 51.450761],
[-2.573366, 51.451076],
[-2.573491, 51.451385],
[-2.573553, 51.451514],
[-2.573591, 51.451605],
[-2.573635, 51.451726],
[-2.573785, 51.451943],
[-2.573862, 51.452052],
[-2.574029, 51.452215],
[-2.574301, 51.452438],
[-2.573889, 51.452598],
[-2.572852, 51.452994],
[-2.57186, 51.453341],
[-2.571252, 51.453557],
[-2.571012, 51.45364],
[-2.570853, 51.453697],
[-2.5705, 51.453823],
[-2.570369, 51.45387],
[-2.570287, 51.453901],
[-2.570078, 51.453977],
[-2.569972, 51.454016],
[-2.569803, 51.454082],
[-2.569713, 51.454115],
[-2.569632, 51.454144],
[-2.569501, 51.454184],
[-2.569137, 51.454304],
[-2.568791, 51.454436],
[-2.568648, 51.454505],
[-2.568666, 51.454525],
[-2.568674, 51.454548],
[-2.56867, 51.454571],
[-2.568656, 51.454593],
[-2.568632, 51.454611],
[-2.568601, 51.454623],
[-2.568688, 51.454756],
[-2.568967, 51.454972],
[-2.569021, 51.455014],
[-2.568715, 51.455271],
[-2.568646, 51.455327],
[-2.568374, 51.455559],
[-2.568108, 51.455772],
[-2.567496, 51.456239],
[-2.567414, 51.456319],
[-2.567628, 51.456492],
[-2.567643, 51.456517],
[-2.567649, 51.456526],
[-2.567656, 51.456544],
[-2.567659, 51.456553],
[-2.567655, 51.456589],
[-2.56766, 51.456617],
[-2.567688, 51.456643],
[-2.567726, 51.456662],
[-2.567757, 51.456684],
[-2.567783, 51.456719],
[-2.567793, 51.456739],
[-2.567796, 51.456747],
[-2.56779, 51.456775],
[-2.567829, 51.456783],
[-2.567946, 51.456871],
[-2.568049, 51.456948],
[-2.568176, 51.457057],
[-2.568213, 51.457083],
[-2.568322, 51.45716],
[-2.568414, 51.457216],
[-2.56846, 51.457251],
[-2.568445, 51.457292],
[-2.567621, 51.457946],
[-2.567536, 51.457943],
[-2.567354, 51.458066],
[-2.567316, 51.458148],
[-2.567406, 51.458165],
[-2.567764, 51.458232],
[-2.568027, 51.458276],
[-2.568076, 51.458283],
[-2.568358, 51.458287],
[-2.568442, 51.45829],
[-2.568972, 51.458337],
[-2.56919, 51.458356],
[-2.569451, 51.458365],
[-2.569642, 51.458363],
[-2.569759, 51.458354],
[-2.570133, 51.458292],
[-2.570486, 51.458208],
[-2.570908, 51.458114],
[-2.571103, 51.458103],
[-2.57128, 51.458116],
[-2.571551, 51.458175],
[-2.571638, 51.458205],
[-2.571745, 51.458247],
[-2.571982, 51.45828],
[-2.572208, 51.458286],
[-2.573275, 51.458227],
[-2.573563, 51.458208],
[-2.573671, 51.458195],
[-2.573724, 51.458183],
[-2.573781, 51.458175],
[-2.573895, 51.458156],
[-2.573943, 51.458146],
[-2.576163, 51.457686],
[-2.576531, 51.457615],
[-2.576651, 51.457592],
[-2.576817, 51.457539],
[-2.57706, 51.4574],
[-2.577425, 51.457222],
[-2.577781, 51.457082],
[-2.578035, 51.456998],
[-2.578202, 51.456951],
[-2.578496, 51.456874],
[-2.578585, 51.456849],
[-2.578781, 51.456795],
[-2.579666, 51.456548],
[-2.579847, 51.456493],
[-2.579937, 51.456464],
[-2.580159, 51.456403],
[-2.580275, 51.456396],
[-2.580319, 51.456385],
[-2.580442, 51.456351],
[-2.580625, 51.456286],
[-2.580716, 51.456255],
[-2.580822, 51.456205],
[-2.580925, 51.45617],
[-2.581018, 51.456139],
[-2.581116, 51.456108],
[-2.581297, 51.456054],
[-2.581424, 51.456018],
[-2.581562, 51.455983],
[-2.581716, 51.455949],
[-2.581883, 51.455913],
[-2.582016, 51.455898],
[-2.582766, 51.455751],
],
],
type: "Polygon",
},
properties: {
waypoints: [
{ lat: 51.455751, lon: -2.582766, snapped: true },
{ lat: 51.449653, lon: -2.57599, snapped: true },
{ lat: 51.457083, lon: -2.568213, snapped: true },
{ lat: 51.455751, lon: -2.582766, snapped: true },
],
},
type: "Feature",
},
};
}
function reset() {
mode = {
mode: "network",
Expand All @@ -86,7 +292,8 @@
<div><button on:click={zoomToFit}>Zoom to fit</button></div>

{#if mode.mode == "network" && model}
<button on:click={setBoundaryMode}>Set boundary</button>
<div><button on:click={setBoundaryMode}>Set boundary</button></div>
<div><button on:click={devMode}>Quickset boundary (dev)</button></div>
{:else if mode.mode == "set-boundary"}
<p>Draw the boundary...</p>
{:else if mode.mode == "neighbourhood"}
Expand Down
3 changes: 3 additions & 0 deletions web/src/MapLoader.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
let resp = await fetch("/kowloon.pbf", { method: "HEAD" });
useLocalVite = resp.ok;
console.log("Using local cache, not od2net.org");
// For quicker dev
loadExample("bristol");
} catch (err) {}
});
Expand Down
27 changes: 18 additions & 9 deletions web/src/NeighbourhoodLayer.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script lang="ts">
import { MapModel } from "backend";
import type { Feature, Polygon } from "geojson";
import { FillLayer, GeoJSON, LineLayer, Popup } from "svelte-maplibre";
import { constructMatchExpression, PropertiesTable } from "./common";
import { CircleLayer, FillLayer, GeoJSON, LineLayer } from "svelte-maplibre";
import { constructMatchExpression, isLine, isPoint } from "./common";
export let model: MapModel;
export let boundary: Feature<Polygon>;
Expand All @@ -21,21 +21,30 @@

<GeoJSON data={details}>
<LineLayer
filter={isLine}
paint={{
"line-width": 5,
"line-color": constructMatchExpression(
["get", "kind"],
{
interior_road: "black",
crosses: "blue",
},
"red"
),
}}
on:click={(e) => window.open(e.detail.features[0].properties.way, "_blank")}
hoverCursor="pointer"
>
<Popup openOn="hover" let:data>
<PropertiesTable properties={data.properties} />
</Popup>
</LineLayer>
/>
<CircleLayer
filter={isPoint}
paint={{
"circle-radius": 15,
"circle-color": constructMatchExpression(
["get", "kind"],
{
border_intersection: "green",
},
"red"
),
}}
/>
</GeoJSON>

0 comments on commit 1687c18

Please sign in to comment.