mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 07:25:47 +03:00
make LonLat implement Eq
This commit is contained in:
parent
55e0d2a364
commit
65ef5d4149
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2048,6 +2048,7 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"serde 1.0.106 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -39,8 +39,8 @@ impl Elevation {
|
|||||||
// TODO assert the (lon, lat) match the offsets
|
// TODO assert the (lon, lat) match the offsets
|
||||||
// TODO not tons of confidence in any of this.
|
// TODO not tons of confidence in any of this.
|
||||||
// TODO interpolate from the 4 matching tiles?
|
// TODO interpolate from the 4 matching tiles?
|
||||||
let x = ((pt.longitude - self.lon_offset).abs() * (GRID_DIM as f64)) as usize;
|
let x = ((pt.x() - self.lon_offset).abs() * (GRID_DIM as f64)) as usize;
|
||||||
let y = ((pt.latitude - self.lat_offset).abs() * (GRID_DIM as f64)) as usize;
|
let y = ((pt.y() - self.lat_offset).abs() * (GRID_DIM as f64)) as usize;
|
||||||
let i = x + (y * GRID_DIM);
|
let i = x + (y * GRID_DIM);
|
||||||
Distance::meters(f64::from(self.data[i]))
|
Distance::meters(f64::from(self.data[i]))
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ geo-booleanop = "0.2.0"
|
|||||||
geo-offset = "0.1.0"
|
geo-offset = "0.1.0"
|
||||||
histogram = "0.6.9"
|
histogram = "0.6.9"
|
||||||
instant = "0.1.2"
|
instant = "0.1.2"
|
||||||
ordered-float = "1.0.1"
|
ordered-float = { version = "1.0.1", features=["serde"] }
|
||||||
polylabel = { git = "https://github.com/urschrei/polylabel-rs" }
|
polylabel = { git = "https://github.com/urschrei/polylabel-rs" }
|
||||||
serde = "1.0.98"
|
serde = "1.0.98"
|
||||||
serde_derive = "1.0.98"
|
serde_derive = "1.0.98"
|
||||||
|
@ -101,17 +101,17 @@ impl GPSBounds {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, pt: LonLat) {
|
pub fn update(&mut self, pt: LonLat) {
|
||||||
self.min_lon = self.min_lon.min(pt.longitude);
|
self.min_lon = self.min_lon.min(pt.x());
|
||||||
self.max_lon = self.max_lon.max(pt.longitude);
|
self.max_lon = self.max_lon.max(pt.x());
|
||||||
self.min_lat = self.min_lat.min(pt.latitude);
|
self.min_lat = self.min_lat.min(pt.y());
|
||||||
self.max_lat = self.max_lat.max(pt.latitude);
|
self.max_lat = self.max_lat.max(pt.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains(&self, pt: LonLat) -> bool {
|
pub fn contains(&self, pt: LonLat) -> bool {
|
||||||
pt.longitude >= self.min_lon
|
pt.x() >= self.min_lon
|
||||||
&& pt.longitude <= self.max_lon
|
&& pt.x() <= self.max_lon
|
||||||
&& pt.latitude >= self.min_lat
|
&& pt.y() >= self.min_lat
|
||||||
&& pt.latitude <= self.max_lat
|
&& pt.y() <= self.max_lat
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO cache this
|
// TODO cache this
|
||||||
|
@ -4,27 +4,35 @@ use serde_derive::{Deserialize, Serialize};
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
// longitude is x, latitude is y
|
// longitude is x, latitude is y
|
||||||
#[derive(Copy, Clone, PartialEq, Debug, Serialize, Deserialize)]
|
#[derive(Copy, Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
|
||||||
pub struct LonLat {
|
pub struct LonLat {
|
||||||
pub longitude: f64,
|
longitude: NotNan<f64>,
|
||||||
pub latitude: f64,
|
latitude: NotNan<f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LonLat {
|
impl LonLat {
|
||||||
pub fn new(lon: f64, lat: f64) -> LonLat {
|
pub fn new(lon: f64, lat: f64) -> LonLat {
|
||||||
LonLat {
|
LonLat {
|
||||||
longitude: lon,
|
longitude: NotNan::new(lon).unwrap(),
|
||||||
latitude: lat,
|
latitude: NotNan::new(lat).unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn x(self) -> f64 {
|
||||||
|
self.longitude.into_inner()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn y(self) -> f64 {
|
||||||
|
self.latitude.into_inner()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn gps_dist_meters(self, other: LonLat) -> Distance {
|
pub fn gps_dist_meters(self, other: LonLat) -> Distance {
|
||||||
// Haversine distance
|
// Haversine distance
|
||||||
let earth_radius_m = 6_371_000.0;
|
let earth_radius_m = 6_371_000.0;
|
||||||
let lon1 = self.longitude.to_radians();
|
let lon1 = self.x().to_radians();
|
||||||
let lon2 = other.longitude.to_radians();
|
let lon2 = other.x().to_radians();
|
||||||
let lat1 = self.latitude.to_radians();
|
let lat1 = self.y().to_radians();
|
||||||
let lat2 = other.latitude.to_radians();
|
let lat2 = other.y().to_radians();
|
||||||
|
|
||||||
let delta_lat = lat2 - lat1;
|
let delta_lat = lat2 - lat1;
|
||||||
let delta_lon = lon2 - lon1;
|
let delta_lon = lon2 - lon1;
|
||||||
@ -37,21 +45,17 @@ impl LonLat {
|
|||||||
|
|
||||||
// Pretty meaningless units, for comparing distances very roughly
|
// Pretty meaningless units, for comparing distances very roughly
|
||||||
pub fn fast_dist(self, other: LonLat) -> NotNan<f64> {
|
pub fn fast_dist(self, other: LonLat) -> NotNan<f64> {
|
||||||
NotNan::new(
|
NotNan::new((self.x() - other.x()).powi(2) + (self.y() - other.y()).powi(2)).unwrap()
|
||||||
(self.longitude - other.longitude).powi(2) + (self.latitude - other.latitude).powi(2),
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn approx_eq(self, other: LonLat) -> bool {
|
pub(crate) fn approx_eq(self, other: LonLat) -> bool {
|
||||||
let epsilon = 1e-8;
|
let epsilon = 1e-8;
|
||||||
(self.longitude - other.longitude).abs() < epsilon
|
(self.x() - other.x()).abs() < epsilon && (self.y() - other.y()).abs() < epsilon
|
||||||
&& (self.latitude - other.latitude).abs() < epsilon
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for LonLat {
|
impl fmt::Display for LonLat {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "LonLat({0}, {1})", self.longitude, self.latitude)
|
write!(f, "LonLat({0}, {1})", self.x(), self.y())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,10 +50,10 @@ impl Pt2D {
|
|||||||
(pt.x(), pt.y())
|
(pt.x(), pt.y())
|
||||||
};
|
};
|
||||||
|
|
||||||
let x = (gps.longitude - b.min_lon) / (b.max_lon - b.min_lon) * width;
|
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
|
// Invert y, so that the northernmost latitude is 0. Screen drawing order, not Cartesian
|
||||||
// grid.
|
// grid.
|
||||||
let y = height - ((gps.latitude - b.min_lat) / (b.max_lat - b.min_lat) * height);
|
let y = height - ((gps.y() - b.min_lat) / (b.max_lat - b.min_lat) * height);
|
||||||
Pt2D::new(x, y)
|
Pt2D::new(x, y)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,15 +49,11 @@ impl NeighborhoodBuilder {
|
|||||||
writeln!(f, "{}", self.name)?;
|
writeln!(f, "{}", self.name)?;
|
||||||
writeln!(f, "1")?;
|
writeln!(f, "1")?;
|
||||||
for gps in &self.points {
|
for gps in &self.points {
|
||||||
writeln!(f, " {} {}", gps.longitude, gps.latitude)?;
|
writeln!(f, " {} {}", gps.x(), gps.y())?;
|
||||||
}
|
}
|
||||||
// Have to repeat the first point
|
// Have to repeat the first point
|
||||||
{
|
{
|
||||||
writeln!(
|
writeln!(f, " {} {}", self.points[0].x(), self.points[0].y())?;
|
||||||
f,
|
|
||||||
" {} {}",
|
|
||||||
self.points[0].longitude, self.points[0].latitude
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
writeln!(f, "END")?;
|
writeln!(f, "END")?;
|
||||||
writeln!(f, "END")?;
|
writeln!(f, "END")?;
|
||||||
|
Loading…
Reference in New Issue
Block a user