From 07ac288e726f4beb6505c8ace50becd2e2e37f11 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Tue, 10 Nov 2020 12:00:43 -0800 Subject: [PATCH] Refactor: rename Pt2D::from_gps to just gps.to_pt(bounds) --- convert_osm/src/parking.rs | 4 ++-- convert_osm/src/reader.rs | 12 +++++------- game/src/devtools/collisions.rs | 8 ++++---- game/src/devtools/polygon.rs | 7 ++----- geom/src/bounds.rs | 8 ++++---- geom/src/gps.rs | 16 +++++++++++++++- geom/src/pt.rs | 14 -------------- importer/src/soundcast/popdat.rs | 4 ++-- sim/src/make/external.rs | 21 ++++++++++----------- 9 files changed, 44 insertions(+), 50 deletions(-) diff --git a/convert_osm/src/parking.rs b/convert_osm/src/parking.rs index 023f27c65c..07ab22032d 100644 --- a/convert_osm/src/parking.rs +++ b/convert_osm/src/parking.rs @@ -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 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) { diff --git a/convert_osm/src/reader.rs b/convert_osm/src/reader.rs index 42e3659672..82384fbaf4 100644 --- a/convert_osm/src/reader.rs +++ b/convert_osm/src/reader.rs @@ -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::().unwrap(), - obj.attribute("lat").unwrap().parse::().unwrap(), - ), - &doc.gps_bounds, - ); + let pt = LonLat::new( + obj.attribute("lon").unwrap().parse::().unwrap(), + obj.attribute("lat").unwrap().parse::().unwrap(), + ) + .to_pt(&doc.gps_bounds); let tags = read_tags(obj); doc.nodes.insert(id, Node { pt, tags }); } diff --git a/game/src/devtools/collisions.rs b/game/src/devtools/collisions.rs index 29d51f741a..5c3e28193d 100644 --- a/game/src/devtools/collisions.rs +++ b/game/src/devtools/collisions.rs @@ -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()); diff --git a/game/src/devtools/polygon.rs b/game/src/devtools/polygon.rs index 92f168258b..36adf1a8bf 100644 --- a/game/src/devtools/polygon.rs +++ b/game/src/devtools/polygon.rs @@ -82,11 +82,8 @@ impl State 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; diff --git a/geom/src/bounds.rs b/geom/src/bounds.rs index 7cfd96f83b..74a5abc501 100644 --- a/geom/src/bounds.rs +++ b/geom/src/bounds.rs @@ -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) -> Option> { 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) -> Vec { - 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 diff --git a/geom/src/gps.rs b/geom/src/gps.rs index e581b559ca..a1009a805b 100644 --- a/geom/src/gps.rs +++ b/geom/src/gps.rs @@ -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; diff --git a/geom/src/pt.rs b/geom/src/pt.rs index 947a8b8acb..6166f32df8 100644 --- a/geom/src/pt.rs +++ b/geom/src/pt.rs @@ -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) = { diff --git a/importer/src/soundcast/popdat.rs b/importer/src/soundcast/popdat.rs index b76300d96f..01a6b52811 100644 --- a/importer/src/soundcast/popdat.rs +++ b/importer/src/soundcast/popdat.rs @@ -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)) diff --git a/sim/src/make/external.rs b/sim/src/make/external.rs index f06fb21e76..ef7b166ef6 100644 --- a/sim/src/make/external.rs +++ b/sim/src/make/external.rs @@ -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();