mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 09:24:26 +03:00
Refactor: rename Pt2D::from_gps to just gps.to_pt(bounds)
This commit is contained in:
parent
e3b9c42506
commit
07ac288e72
@ -1,5 +1,5 @@
|
||||
use abstutil::Timer;
|
||||
use geom::{Distance, FindClosest, PolyLine, Pt2D};
|
||||
use geom::{Distance, FindClosest, PolyLine};
|
||||
use kml::ExtraShapes;
|
||||
use map_model::osm;
|
||||
use map_model::raw::{OriginalRoad, RawMap};
|
||||
@ -149,7 +149,7 @@ fn use_offstreet_parking(map: &mut RawMap, path: String, timer: &mut Timer) {
|
||||
// TODO Another function just to use ?. Try blocks would rock.
|
||||
let mut handle_shape: Box<dyn FnMut(kml::ExtraShape) -> Option<()>> = Box::new(|s| {
|
||||
assert_eq!(s.points.len(), 1);
|
||||
let pt = Pt2D::from_gps(s.points[0], &map.gps_bounds);
|
||||
let pt = s.points[0].to_pt(&map.gps_bounds);
|
||||
let (id, _) = closest.closest_pt(pt, Distance::meters(50.0))?;
|
||||
// TODO Handle parking lots.
|
||||
if !map.buildings[&id].polygon.contains_pt(pt) {
|
||||
|
@ -91,13 +91,11 @@ pub fn read(
|
||||
if doc.nodes.contains_key(&id) {
|
||||
return Err(format!("Duplicate {}, your .osm is corrupt", id).into());
|
||||
}
|
||||
let pt = Pt2D::from_gps(
|
||||
LonLat::new(
|
||||
obj.attribute("lon").unwrap().parse::<f64>().unwrap(),
|
||||
obj.attribute("lat").unwrap().parse::<f64>().unwrap(),
|
||||
),
|
||||
&doc.gps_bounds,
|
||||
);
|
||||
let pt = LonLat::new(
|
||||
obj.attribute("lon").unwrap().parse::<f64>().unwrap(),
|
||||
obj.attribute("lat").unwrap().parse::<f64>().unwrap(),
|
||||
)
|
||||
.to_pt(&doc.gps_bounds);
|
||||
let tags = read_tags(obj);
|
||||
doc.nodes.insert(id, Node { pt, tags });
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use abstutil::{prettyprint_usize, Counter};
|
||||
use collisions::{CollisionDataset, Severity};
|
||||
use geom::{Circle, Distance, Duration, FindClosest, Pt2D};
|
||||
use geom::{Circle, Distance, Duration, FindClosest};
|
||||
use map_model::{IntersectionID, RoadID};
|
||||
use widgetry::{
|
||||
Btn, Checkbox, Choice, Color, Drawable, EventCtx, GeomBatch, GfxCtx, HorizontalAlignment, Line,
|
||||
@ -28,7 +28,7 @@ impl CollisionsViewer {
|
||||
);
|
||||
all.collisions.retain(|c| {
|
||||
map.get_boundary_polygon()
|
||||
.contains_pt(Pt2D::from_gps(c.location, map.get_gps_bounds()))
|
||||
.contains_pt(c.location.to_pt(map.get_gps_bounds()))
|
||||
});
|
||||
all
|
||||
});
|
||||
@ -175,7 +175,7 @@ impl Dataviz {
|
||||
let collision = &data.collisions[idx];
|
||||
// Search up to 10m away
|
||||
if let Some((id, _)) = closest.closest_pt(
|
||||
Pt2D::from_gps(collision.location, map.get_gps_bounds()),
|
||||
collision.location.to_pt(map.get_gps_bounds()),
|
||||
Distance::meters(10.0),
|
||||
) {
|
||||
match id {
|
||||
@ -224,7 +224,7 @@ impl Dataviz {
|
||||
for idx in indices {
|
||||
let collision = &data.collisions[idx];
|
||||
let circle = Circle::new(
|
||||
Pt2D::from_gps(collision.location, app.primary.map.get_gps_bounds()),
|
||||
collision.location.to_pt(app.primary.map.get_gps_bounds()),
|
||||
Distance::meters(5.0),
|
||||
);
|
||||
batch.push(Color::RED, circle.to_polygon());
|
||||
|
@ -82,11 +82,8 @@ impl State<App> for PolygonEditor {
|
||||
|
||||
if let Some(cursor) = ctx.canvas.get_cursor_in_map_space() {
|
||||
self.mouseover_pt = self.points.iter().position(|pt| {
|
||||
Circle::new(
|
||||
Pt2D::from_gps(*pt, gps_bounds),
|
||||
POINT_RADIUS / ctx.canvas.cam_zoom,
|
||||
)
|
||||
.contains_pt(cursor)
|
||||
Circle::new(pt.to_pt(gps_bounds), POINT_RADIUS / ctx.canvas.cam_zoom)
|
||||
.contains_pt(cursor)
|
||||
});
|
||||
} else {
|
||||
self.mouseover_pt = None;
|
||||
|
@ -166,18 +166,18 @@ impl GPSBounds {
|
||||
/// Convert all points to map-space, failing if any points are outside this boundary.
|
||||
pub fn try_convert(&self, pts: &Vec<LonLat>) -> Option<Vec<Pt2D>> {
|
||||
let mut result = Vec::new();
|
||||
for pt in pts {
|
||||
if !self.contains(*pt) {
|
||||
for gps in pts {
|
||||
if !self.contains(*gps) {
|
||||
return None;
|
||||
}
|
||||
result.push(Pt2D::from_gps(*pt, self));
|
||||
result.push(gps.to_pt(self));
|
||||
}
|
||||
Some(result)
|
||||
}
|
||||
|
||||
/// Convert all points to map-space. The points may be outside this boundary.
|
||||
pub fn convert(&self, pts: &Vec<LonLat>) -> Vec<Pt2D> {
|
||||
pts.iter().map(|pt| Pt2D::from_gps(*pt, self)).collect()
|
||||
pts.iter().map(|gps| gps.to_pt(self)).collect()
|
||||
}
|
||||
|
||||
/// Convert map-space points back to `LonLat`s. This is only valid if the `GPSBounds` used
|
||||
|
@ -6,7 +6,7 @@ use std::io::{BufRead, BufReader, Write};
|
||||
use ordered_float::NotNan;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::Distance;
|
||||
use crate::{Distance, GPSBounds, Pt2D};
|
||||
|
||||
/// Represents a (longitude, latitude) point.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
|
||||
@ -34,6 +34,20 @@ impl LonLat {
|
||||
self.latitude.into_inner()
|
||||
}
|
||||
|
||||
/// Transform this to a world-space point. Can go out of bounds.
|
||||
pub fn to_pt(self, b: &GPSBounds) -> Pt2D {
|
||||
let (width, height) = {
|
||||
let pt = b.get_max_world_pt();
|
||||
(pt.x(), pt.y())
|
||||
};
|
||||
|
||||
let x = (self.x() - b.min_lon) / (b.max_lon - b.min_lon) * width;
|
||||
// Invert y, so that the northernmost latitude is 0. Screen drawing order, not Cartesian
|
||||
// grid.
|
||||
let y = height - ((self.y() - b.min_lat) / (b.max_lat - b.min_lat) * height);
|
||||
Pt2D::new(x, y)
|
||||
}
|
||||
|
||||
/// Returns the Haversine distance to another point.
|
||||
pub(crate) fn gps_dist(self, other: LonLat) -> Distance {
|
||||
let earth_radius_m = 6_371_000.0;
|
||||
|
@ -37,20 +37,6 @@ impl Pt2D {
|
||||
self.dist_to(other) <= threshold
|
||||
}
|
||||
|
||||
/// Can go out of bounds.
|
||||
pub fn from_gps(gps: LonLat, b: &GPSBounds) -> Pt2D {
|
||||
let (width, height) = {
|
||||
let pt = b.get_max_world_pt();
|
||||
(pt.x(), pt.y())
|
||||
};
|
||||
|
||||
let x = (gps.x() - b.min_lon) / (b.max_lon - b.min_lon) * width;
|
||||
// Invert y, so that the northernmost latitude is 0. Screen drawing order, not Cartesian
|
||||
// grid.
|
||||
let y = height - ((gps.y() - b.min_lat) / (b.max_lat - b.min_lat) * height);
|
||||
Pt2D::new(x, y)
|
||||
}
|
||||
|
||||
/// Can go out of bounds.
|
||||
pub fn to_gps(self, b: &GPSBounds) -> LonLat {
|
||||
let (width, height) = {
|
||||
|
@ -3,7 +3,7 @@ use std::collections::{BTreeMap, HashMap, HashSet};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use abstutil::{prettyprint_usize, Counter, FileWithProgress, Timer};
|
||||
use geom::{Distance, Duration, FindClosest, LonLat, Pt2D, Time};
|
||||
use geom::{Distance, Duration, FindClosest, LonLat, Time};
|
||||
use kml::{ExtraShape, ExtraShapes};
|
||||
use map_model::{osm, Map};
|
||||
use sim::{OrigPersonID, TripMode, TripPurpose};
|
||||
@ -176,7 +176,7 @@ fn import_parcels(
|
||||
{
|
||||
timer.next();
|
||||
let gps = LonLat::new(x, y);
|
||||
let pt = Pt2D::from_gps(gps, bounds);
|
||||
let pt = gps.to_pt(bounds);
|
||||
let osm_building = if bounds.contains(gps) {
|
||||
closest_bldg
|
||||
.closest_pt(pt, Distance::meters(30.0))
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use geom::{Distance, FindClosest, LonLat, Pt2D, Time};
|
||||
use geom::{Distance, FindClosest, LonLat, Time};
|
||||
use map_model::Map;
|
||||
|
||||
use crate::{IndividTrip, PersonID, PersonSpec, SpawnTrip, TripEndpoint, TripMode, TripPurpose};
|
||||
@ -38,16 +38,15 @@ impl ExternalPerson {
|
||||
}
|
||||
let lookup_pt = |endpt| match endpt {
|
||||
ExternalTripEndpoint::TripEndpoint(endpt) => Ok(endpt),
|
||||
ExternalTripEndpoint::Position(gps) => match closest.closest_pt(
|
||||
Pt2D::from_gps(gps, map.get_gps_bounds()),
|
||||
Distance::meters(100.0),
|
||||
) {
|
||||
Some((x, _)) => Ok(x),
|
||||
None => Err(format!(
|
||||
"No building or border intersection within 100m of {}",
|
||||
gps
|
||||
)),
|
||||
},
|
||||
ExternalTripEndpoint::Position(gps) => {
|
||||
match closest.closest_pt(gps.to_pt(map.get_gps_bounds()), Distance::meters(100.0)) {
|
||||
Some((x, _)) => Ok(x),
|
||||
None => Err(format!(
|
||||
"No building or border intersection within 100m of {}",
|
||||
gps
|
||||
)),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let mut results = Vec::new();
|
||||
|
Loading…
Reference in New Issue
Block a user