mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-26 07:52:05 +03:00
some bug with previous commit messing up roundabout handling... quick detour to only have HashablePt2D for Pt2D, never for LonLat
This commit is contained in:
parent
114a76893a
commit
c545e5d86e
@ -68,7 +68,7 @@ pub fn split_up_roads(
|
||||
|
||||
// All of the roundabout points will just keep moving the intersection
|
||||
for (pt, id) in &pt_to_intersection {
|
||||
let point: Pt2D = (*pt).into();
|
||||
let point = pt.to_pt2d();
|
||||
map.intersections.insert(
|
||||
*id,
|
||||
raw_data::Intersection {
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{Bounds, Distance, GPSBounds, LonLat, Pt2D};
|
||||
use crate::{Bounds, Distance, Pt2D};
|
||||
use aabb_quadtree::geom::{Point, Rect};
|
||||
use aabb_quadtree::QuadTree;
|
||||
use geo;
|
||||
@ -28,14 +28,6 @@ where
|
||||
.insert_with_box(key, Bounds::from(pts).as_bbox());
|
||||
}
|
||||
|
||||
pub fn add_gps(&mut self, key: K, raw_pts: &Vec<LonLat>, gps_bounds: &GPSBounds) {
|
||||
let pts: Vec<Pt2D> = gps_bounds.must_convert(raw_pts);
|
||||
self.geometries
|
||||
.insert(key.clone(), pts_to_line_string(&pts));
|
||||
self.quadtree
|
||||
.insert_with_box(key, Bounds::from(&pts).as_bbox());
|
||||
}
|
||||
|
||||
// Finds the closest point on the existing geometry to the query pt.
|
||||
pub fn closest_pt(&self, query_pt: Pt2D, max_dist_away: Distance) -> Option<(K, Pt2D)> {
|
||||
let query_geom = geo::Point::new(query_pt.x(), query_pt.y());
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{Distance, HashablePt2D};
|
||||
use crate::Distance;
|
||||
use ordered_float::NotNan;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::f64;
|
||||
@ -43,10 +43,6 @@ impl LonLat {
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn to_hashable(&self) -> HashablePt2D {
|
||||
HashablePt2D::new(self.longitude, self.latitude)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for LonLat {
|
||||
|
@ -130,10 +130,10 @@ impl Polygon {
|
||||
|
||||
pub fn center(&self) -> Pt2D {
|
||||
// TODO dedupe just out of fear of the first/last point being repeated
|
||||
let mut pts: Vec<HashablePt2D> = self.points.iter().map(|pt| (*pt).into()).collect();
|
||||
let mut pts: Vec<HashablePt2D> = self.points.iter().map(|pt| pt.to_hashable()).collect();
|
||||
pts.sort();
|
||||
pts.dedup();
|
||||
Pt2D::center(&pts.iter().map(|pt| Pt2D::from(*pt)).collect())
|
||||
Pt2D::center(&pts.iter().map(|pt| pt.to_pt2d()).collect())
|
||||
}
|
||||
|
||||
pub fn rectangle(center: Pt2D, width: Distance, height: Distance) -> Polygon {
|
||||
|
@ -106,7 +106,7 @@ impl PolyLine {
|
||||
// TODO Measure the length of the thing being clipped out, to be sure this isn't
|
||||
// running amok.
|
||||
for (other_rev_idx, pt) in other_pts.iter().rev().enumerate() {
|
||||
if pl1.contains(&HashablePt2D::from(*pt)) {
|
||||
if pl1.contains(&pt.to_hashable()) {
|
||||
while self_pts.last().unwrap() != pt {
|
||||
self_pts.pop();
|
||||
}
|
||||
@ -675,5 +675,5 @@ fn check_angles(orig: &PolyLine, fixed: PolyLine) -> Warn<PolyLine> {
|
||||
}
|
||||
|
||||
fn to_set(pts: &[Pt2D]) -> HashSet<HashablePt2D> {
|
||||
pts.iter().map(|pt| HashablePt2D::from(*pt)).collect()
|
||||
pts.iter().map(|pt| pt.to_hashable()).collect()
|
||||
}
|
||||
|
@ -200,7 +200,10 @@ impl Pt2D {
|
||||
}
|
||||
|
||||
pub fn to_hashable(self) -> HashablePt2D {
|
||||
HashablePt2D::new(self.x(), self.y())
|
||||
HashablePt2D {
|
||||
x_nan: NotNan::new(self.x()).unwrap(),
|
||||
y_nan: NotNan::new(self.y()).unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,13 +213,7 @@ impl fmt::Display for Pt2D {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<HashablePt2D> for Pt2D {
|
||||
fn from(pt: HashablePt2D) -> Self {
|
||||
Pt2D::new(pt.x(), pt.y())
|
||||
}
|
||||
}
|
||||
|
||||
// This isn't opinionated about what the (x, y) represents -- could be lat/lon or world space.
|
||||
// This represents world space, NOT LonLat.
|
||||
// TODO So rename it HashablePair or something
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
|
||||
pub struct HashablePt2D {
|
||||
@ -225,24 +222,7 @@ pub struct HashablePt2D {
|
||||
}
|
||||
|
||||
impl HashablePt2D {
|
||||
pub fn new(x: f64, y: f64) -> HashablePt2D {
|
||||
HashablePt2D {
|
||||
x_nan: NotNan::new(x).unwrap(),
|
||||
y_nan: NotNan::new(y).unwrap(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn x(&self) -> f64 {
|
||||
self.x_nan.into_inner()
|
||||
}
|
||||
|
||||
pub fn y(&self) -> f64 {
|
||||
self.y_nan.into_inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Pt2D> for HashablePt2D {
|
||||
fn from(pt: Pt2D) -> Self {
|
||||
HashablePt2D::new(pt.x(), pt.y())
|
||||
pub fn to_pt2d(self) -> Pt2D {
|
||||
Pt2D::new(self.x_nan.into_inner(), self.y_nan.into_inner())
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ pub fn make_all_buildings(
|
||||
timer.start_iter("get building center points", input.len());
|
||||
for b in input {
|
||||
timer.next();
|
||||
let center: HashablePt2D = b.polygon.center().into();
|
||||
let center = b.polygon.center().to_hashable();
|
||||
center_per_bldg.push(center);
|
||||
query.insert(center);
|
||||
}
|
||||
@ -32,12 +32,12 @@ pub fn make_all_buildings(
|
||||
let sidewalk_pt = lanes[sidewalk_pos.lane().0]
|
||||
.dist_along(sidewalk_pos.dist_along())
|
||||
.0;
|
||||
if sidewalk_pt.epsilon_eq(bldg_center.into()) {
|
||||
if sidewalk_pt.epsilon_eq(bldg_center.to_pt2d()) {
|
||||
timer.warn("Skipping a building because front path has 0 length".to_string());
|
||||
continue;
|
||||
}
|
||||
let polygon = &input[idx].polygon;
|
||||
let line = trim_front_path(polygon, Line::new(bldg_center.into(), sidewalk_pt));
|
||||
let line = trim_front_path(polygon, Line::new(bldg_center.to_pt2d(), sidewalk_pt));
|
||||
|
||||
let id = BuildingID(results.len());
|
||||
results.push(Building {
|
||||
|
@ -20,7 +20,7 @@ pub fn make_bus_stops(
|
||||
for route in bus_routes {
|
||||
for gps in &route.stops {
|
||||
if let Some(pt) = Pt2D::from_gps(*gps, gps_bounds) {
|
||||
let hash_pt: HashablePt2D = pt.into();
|
||||
let hash_pt = pt.to_hashable();
|
||||
bus_stop_pts.insert(hash_pt);
|
||||
route_lookups
|
||||
.entry(route.name.clone())
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::make::initial::{Intersection, Road};
|
||||
use crate::raw_data::{StableIntersectionID, StableRoadID};
|
||||
use abstutil::{wraparound_get, Timer, Warn};
|
||||
use geom::{Distance, HashablePt2D, Line, PolyLine, Pt2D};
|
||||
use geom::{Distance, Line, PolyLine, Pt2D};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
|
||||
const DEGENERATE_INTERSECTION_HALF_LENGTH: Distance = Distance::const_meters(5.0);
|
||||
@ -51,7 +51,7 @@ pub fn intersection_polygon(
|
||||
|
||||
// Find the average of all road endpoints at the intersection. This is usually just a single
|
||||
// point, except for merged intersections.
|
||||
road_endpts.sort_by_key(|pt| HashablePt2D::from(*pt));
|
||||
road_endpts.sort_by_key(|pt| pt.to_hashable());
|
||||
road_endpts.dedup();
|
||||
let intersection_center = Pt2D::center(&road_endpts);
|
||||
|
||||
@ -286,7 +286,7 @@ fn generalized_trim_back(
|
||||
// around its center.
|
||||
let mut deduped = main_result.clone();
|
||||
deduped.pop();
|
||||
deduped.sort_by_key(|pt| HashablePt2D::from(*pt));
|
||||
deduped.sort_by_key(|pt| pt.to_hashable());
|
||||
deduped = Pt2D::approx_dedupe(deduped, Distance::meters(0.1));
|
||||
let center = Pt2D::center(&deduped);
|
||||
deduped.sort_by_key(|pt| pt.angle_to(center).normalized_degrees() as i64);
|
||||
|
@ -31,7 +31,8 @@ pub fn find_sidewalk_points(
|
||||
timer.start_iter("find closest sidewalk point", pts.len());
|
||||
for query_pt in pts {
|
||||
timer.next();
|
||||
if let Some((sidewalk, sidewalk_pt)) = closest.closest_pt(query_pt.into(), max_dist_away) {
|
||||
if let Some((sidewalk, sidewalk_pt)) = closest.closest_pt(query_pt.to_pt2d(), max_dist_away)
|
||||
{
|
||||
if let Some(dist_along) = lanes[sidewalk.0].dist_along_of_point(sidewalk_pt) {
|
||||
results.insert(query_pt, Position::new(sidewalk, dist_along));
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user