Skip to content

Commit

Permalink
Generate arrows manually. #68
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Jan 4, 2025
1 parent 3cee358 commit 19b6e2c
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 31 deletions.
95 changes: 89 additions & 6 deletions backend/src/geo_helpers.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use geo::{
BoundingRect, Contains, Coord, Distance, Euclidean, Intersects, Line, LineInterpolatePoint,
LineIntersection, LineLocatePoint, LineString, Point, Polygon, Rect,
BoundingRect, Contains, Coord, Distance, Euclidean, Intersects, Length, Line,
LineInterpolatePoint, LineIntersection, LineLocatePoint, LineString, Point, Polygon, Rect,
};
use rstar::AABB;
use utils::LineSplit;
Expand Down Expand Up @@ -125,8 +125,91 @@ pub fn limit_angle(a1: f64) -> f64 {

pub fn euclidean_destination(pt: Point, angle_degs: f64, dist_away_m: f64) -> Point {
let (sin, cos) = angle_degs.to_radians().sin_cos();
Point::new(
pt.x() + dist_away_m * cos,
pt.y() + dist_away_m * sin,
)
Point::new(pt.x() + dist_away_m * cos, pt.y() + dist_away_m * sin)
}

fn euclidean_destination_coord(pt: Coord, angle_degs: f64, dist_away_m: f64) -> Coord {
euclidean_destination(pt.into(), angle_degs, dist_away_m).into()
}

// If the line is too short for the thickness, give up
pub fn make_arrow(line: Line, thickness: f64, double_ended: bool) -> Option<Polygon> {
let head_size = thickness * 2.0;
let triangle_height = head_size / 2.0_f64.sqrt();
let angle = angle_of_line(line);
let length = line.length::<Euclidean>();

if length < triangle_height * 3.0 {
return None;
}

let mut pts = Vec::new();

let start_trimmed = euclidean_destination_coord(line.start, angle, triangle_height);
let end_trimmed = euclidean_destination_coord(line.start, angle, length - triangle_height);

if double_ended {
pts.push(line.start);
pts.push(euclidean_destination_coord(
start_trimmed,
angle + 90.0,
thickness * 1.5,
));
pts.push(euclidean_destination_coord(
start_trimmed,
angle + 90.0,
thickness * 0.5,
));
} else {
pts.push(euclidean_destination_coord(
line.start,
angle + 90.0,
thickness * 0.5,
));
}
pts.push(euclidean_destination_coord(
end_trimmed,
angle + 90.0,
thickness * 0.5,
));
pts.push(euclidean_destination_coord(
end_trimmed,
angle + 90.0,
thickness * 1.5,
));

pts.push(line.end);

pts.push(euclidean_destination_coord(
end_trimmed,
angle - 90.0,
thickness * 1.5,
));
pts.push(euclidean_destination_coord(
end_trimmed,
angle - 90.0,
thickness * 0.5,
));
if double_ended {
pts.push(euclidean_destination_coord(
start_trimmed,
angle - 90.0,
thickness * 0.5,
));
pts.push(euclidean_destination_coord(
start_trimmed,
angle - 90.0,
thickness * 1.5,
));
} else {
pts.push(euclidean_destination_coord(
line.start,
angle - 90.0,
thickness * 0.5,
));
}

pts.push(pts[0]);

Some(Polygon::new(LineString::new(pts), Vec::new()))
}
21 changes: 13 additions & 8 deletions backend/src/neighbourhood.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ use std::collections::{BTreeMap, BTreeSet};

use anyhow::Result;
use geo::{
Line, Area, Distance, Euclidean, Length, LineInterpolatePoint, LineLocatePoint, LineString, Point,
Polygon, PreparedGeometry, Relate,
Area, Distance, Euclidean, Length, Line, LineInterpolatePoint, LineLocatePoint, LineString,
Point, Polygon, PreparedGeometry, Relate,
};
use geojson::{Feature, FeatureCollection};
use web_time::Instant;

use crate::geo_helpers::{aabb, angle_of_line, buffer_aabb, clip_linestring_to_polygon, euclidean_destination};
use crate::geo_helpers::{
aabb, angle_of_line, buffer_aabb, clip_linestring_to_polygon, euclidean_destination, make_arrow,
};
use crate::render_cells::Color;
use crate::{Cell, Direction, IntersectionID, MapModel, RenderCells, RoadID, Shortcuts};

Expand Down Expand Up @@ -254,11 +256,14 @@ impl Neighbourhood {
std::mem::swap(&mut line.start, &mut line.end);
}

let mut f = map.mercator.to_wgs84_gj(&line);
// TODO Which cell?
f.set_property("kind", "border_arrow");
f.set_property("oneway", map.directions[r] != Direction::BothWays);
features.push(f);
let thickness = 6.0;
let double_ended = map.directions[r] == Direction::BothWays;
if let Some(polygon) = make_arrow(line, thickness, double_ended) {
let mut f = map.mercator.to_wgs84_gj(&polygon);
// TODO Which cell?
f.set_property("kind", "border_arrow");
features.push(f);
}
}
features
}
Expand Down
24 changes: 9 additions & 15 deletions web/src/RenderNeighbourhood.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
GeoJSON,
hoverStateFilter,
LineLayer,
SymbolLayer,
} from "svelte-maplibre";
import { layerId } from "./common";
import OneWayLayer from "./OneWayLayer.svelte";
Expand Down Expand Up @@ -95,27 +94,22 @@
}}
/>

<!--
<LineLayer
{...layerId("border-arrow-bases")}
<FillLayer
{...layerId("border-arrows")}
filter={["==", ["get", "kind"], "border_arrow"]}
paint={{
"line-width": 10,
"line-color": "cyan",
"fill-color": "cyan",
"fill-opacity": 0.5,
}}
/>
<SymbolLayer
{...layerId("border-arrows")}
<LineLayer
{...layerId("border-arrow-outlines")}
filter={["==", ["get", "kind"], "border_arrow"]}
layout={{
"icon-image": "oneway-arrow",
"icon-size": 1.0,
"symbol-placement": "line",
"icon-allow-overlap": true,
paint={{
"line-color": "black",
"line-width": 2,
}}
/>
-->

<LineLayer
{...layerId("interior-roads-outlines")}
Expand Down
6 changes: 4 additions & 2 deletions web/src/common/zorder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ const layerZorder = [
"cells",
"interior-roads-outlines",
"interior-roads",
"border-arrow-bases",
"border-arrows",

"compare-route",

Expand All @@ -114,6 +112,10 @@ const layerZorder = [
"boundary",
"neighbourhood-boundary",

// These're outside the neighbourhood-boundary, but don't fade them
"border-arrows",
"border-arrow-outlines",

"auto-boundaries-areas",
"auto-boundaries-severances",

Expand Down

0 comments on commit 19b6e2c

Please sign in to comment.