-
Notifications
You must be signed in to change notification settings - Fork 5
UI Update; Editing mode Update; Bulk-Update-Page; Manual-Update-Page #103
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
Changes from all commits
22bae34
cd9dee0
406c776
9f2372e
c9545a4
b9042df
853a715
9571ed9
6214b41
9702dc2
ac037aa
fb87a90
8eaff68
05e6690
b002533
ba890fa
1e56a37
2d5b3f2
2b86381
5cd2b58
68e1be6
28fd804
2fee40c
c0625a3
7061144
51c9341
2b2133f
c19e980
c402787
040415a
88f4b8e
e722823
a207df0
86415df
ecd8d23
42af603
301142f
4e04bc5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| use std::collections::{BTreeMap, HashMap, HashSet}; | ||
|
|
||
| use anyhow::Result; | ||
| use geo::{Coord, Distance, Euclidean, LineString, Point}; | ||
| use geo::{Closest, ClosestPoint, Coord, Distance, Euclidean, LineString, Point}; | ||
| use osm_reader::{NodeID, WayID}; | ||
| use rstar::{RTree, primitives::GeomWithData}; | ||
| use serde::Serialize; | ||
|
|
@@ -26,11 +26,13 @@ pub struct Edits { | |
|
|
||
| #[derive(Clone, Serialize)] | ||
| pub enum UserCmd { | ||
| SetTags(WayID, Vec<(String, String)>), | ||
| SetTags(WayID, Vec<String>, Vec<(String, String)>), | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be useful to add a `/// Doc comment saying what these are; the Vec<(String, String)> was key/value pairs, and I'm guessing the new thing is keys to delete. Or switch to a struct for this case with named fields |
||
| MakeAllSidewalks(bool), | ||
| ConnectAllCrossings(bool), | ||
| AssumeTags(bool), | ||
| AddCrossings(Vec<Point>, Tags), | ||
| /// Add a crossing as a segment between two points; each point is snapped to the nearest road or sidewalk (closest line). | ||
| AddCrossingSegment(Point, Point, Tags), | ||
| } | ||
|
|
||
| pub enum TagCmd { | ||
|
|
@@ -52,16 +54,14 @@ impl Edits { | |
| pub fn apply_cmd(&mut self, cmd: UserCmd, model: &Speedwalk) -> Result<()> { | ||
| self.user_commands.push(cmd.clone()); | ||
| match cmd { | ||
| UserCmd::SetTags(way, replace) => { | ||
| UserCmd::SetTags(way, remove_keys, add_tags) => { | ||
| let cmds = self.change_way_tags.entry(way).or_insert_with(Vec::new); | ||
| // Clear old sidewalk tags first | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah good, the responsibility for this moves to the frontend then |
||
| for (k, _) in &model.derived_ways[&way].tags.0 { | ||
| if k.starts_with("sidewalk") { | ||
| cmds.push(TagCmd::Remove(k.clone())); | ||
| } | ||
| // First remove all tags in the removal list | ||
| for key in remove_keys { | ||
| cmds.push(TagCmd::Remove(key)); | ||
| } | ||
|
|
||
| for (k, v) in replace { | ||
| // Then add/set all tags in the addition list | ||
| for (k, v) in add_tags { | ||
| cmds.push(TagCmd::Set(k, v)); | ||
| } | ||
| } | ||
|
|
@@ -135,6 +135,51 @@ impl Edits { | |
| model, | ||
| ); | ||
| } | ||
| UserCmd::AddCrossingSegment(start_wgs84, end_wgs84, way_tags) => { | ||
| let start_pt = model.mercator.to_mercator(&start_wgs84); | ||
| let end_pt = model.mercator.to_mercator(&end_wgs84); | ||
| let closest_line = RTree::bulk_load( | ||
| model | ||
| .derived_ways | ||
| .iter() | ||
| .filter(|(_, way)| way.kind.is_road() || way.kind == Kind::Sidewalk) | ||
| .map(|(id, way)| GeomWithData::new(way.linestring.clone(), *id)) | ||
| .collect(), | ||
| ); | ||
| let snap_to_line = |pt: Coord| -> Result<(WayID, Coord)> { | ||
| let Some(obj) = closest_line.nearest_neighbor(&Point::from(pt)) else { | ||
| bail!("Couldn't find a line to snap to"); | ||
| }; | ||
| let snapped = match obj.geom().closest_point(&Point::from(pt)) { | ||
| Closest::Intersection(c) | Closest::SinglePoint(c) => c.into(), | ||
| Closest::Indeterminate => bail!("Couldn't snap point to line"), | ||
| }; | ||
| Ok((obj.data, snapped)) | ||
| }; | ||
| let (way_start, snapped_start) = snap_to_line(start_pt.into())?; | ||
| let (way_end, snapped_end) = snap_to_line(end_pt.into())?; | ||
| let node_tags = way_tags.clone(); | ||
| let mut insert_new_nodes: HashMap<WayID, Vec<(Coord, Tags)>> = HashMap::new(); | ||
| insert_new_nodes | ||
| .entry(way_start) | ||
| .or_default() | ||
| .push((snapped_start, node_tags.clone())); | ||
| insert_new_nodes | ||
| .entry(way_end) | ||
| .or_default() | ||
| .push((snapped_end, node_tags)); | ||
| let crossing_way = LineString::new(vec![snapped_start, snapped_end]); | ||
| let new_ways = vec![(crossing_way, way_tags)]; | ||
| self.create_new_geometry( | ||
| CreateNewGeometry { | ||
| new_ways, | ||
| new_kind: Kind::Crossing, | ||
| insert_new_nodes, | ||
| modify_existing_way_tags: HashMap::new(), | ||
| }, | ||
| model, | ||
| ); | ||
| } | ||
| } | ||
| Ok(()) | ||
| } | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor with
is_severance, except the service road case?