Compute the max difference between actual and expected distances

This commit is contained in:
Austen Adler 2023-03-11 15:18:01 -05:00
parent c73b7eb99c
commit 4c8a73029b
4 changed files with 34 additions and 35 deletions

7
Cargo.lock generated
View File

@ -444,6 +444,12 @@ dependencies = [
"version_check",
]
[[package]]
name = "geoutils"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36d244a08113319b5ebcabad2b8b7925732d15eec46d7e7ac3c11734f3b7a6ad"
[[package]]
name = "getrandom"
version = "0.2.8"
@ -1813,6 +1819,7 @@ name = "xpin"
version = "0.1.0"
dependencies = [
"csv",
"geoutils",
"s2",
"serde",
"thiserror",

View File

@ -22,4 +22,5 @@ words = {path="./words"}
[dev-dependencies]
csv = "1.1"
geoutils = "0.5.1"
serde={version="1", features=["derive"]}

View File

@ -23,51 +23,36 @@ fn test_invalid_lat_lon() {
#[test]
fn test_decoding_lat_lon() {
let mut max = f64::MIN;
let mut min = f64::MAX;
let mut max_error_m = f64::MIN;
let mut min_error_m = f64::MAX;
for (idx, entry) in test_events().iter().enumerate() {
eprintln!("Testing row {idx}");
let addr = Address::from_lat_lon(entry.lat, entry.lon).unwrap();
let addr_latlon = addr.as_lat_lon();
let (lat_diff, lon_diff) = (
(entry.lat - addr_latlon.0).abs(),
(entry.lon - addr_latlon.1).abs(),
);
// The difference between the input lat/lon and the encoded-then-decoded lat/lon
// This distance is essentially the error
// If you pick a point on the map, this is how far off the encoded point actually represents
let difference_m = approx_geodetic_difference_m(addr_latlon, (entry.lat, entry.lon));
min = if lat_diff < min {
lat_diff
} else if lon_diff < min {
lon_diff
} else {
min
};
max = if lat_diff > max && lat_diff < 1_f64 {
lat_diff
} else if lon_diff > max && lon_diff < 1_f64 {
lon_diff
} else {
max
};
if lat_diff > 0.01_f64 || lon_diff > 0.01_f64 {
eprintln!(
"Uh oh: {lat_diff}, {lon_diff}, ({}, {}) => ({:?}) => ({:?})",
entry.lat, entry.lon, addr, addr_latlon
);
// Compute the max and min differences for fun
if difference_m > max_error_m {
eprintln!("Setting max to {difference_m}");
max_error_m = difference_m;
}
if difference_m < min_error_m {
min_error_m = difference_m;
}
eprintln!("Distance in meters: {:?}", difference_m);
// Ensure the distance is not more than the allowed distance
// assert!(
// approx_geodetic_difference_m(addr_latlon, (entry.lat, entry.lon))
// < ALLOWED_DISTANCE_ERROR_M
// );
assert!(difference_m <= ALLOWED_DISTANCE_ERROR_M);
// assert_eq!((entry.lat, entry.lon), (latlon.0, latlon.1));
}
eprintln!("Got max: {max} and min: {min}");
eprintln!("Got max: {max_error_m} and min: {min_error_m}");
}
#[test]

View File

@ -1,4 +1,5 @@
#![allow(dead_code)]
use geoutils::Location;
use std::fs::File;
use csv::ReaderBuilder;
@ -7,7 +8,9 @@ use serde::{Deserialize, Serialize};
/// The allowed error for encoding and decoding points, in meters
///
/// Due to the selected S2 level being 23, our error is expected to be under 2 meters
pub const ALLOWED_DISTANCE_ERROR_M: f64 = 0.0_f64;
///
/// With the encoding I selected, the max difference of my sample data actually fits in under 1 meter!
pub const ALLOWED_DISTANCE_ERROR_M: f64 = 1.0_f64;
// The earth's approximate latitude circumfrence
pub const EARTH_CIRCUMFERENCE_LAT: f64 = 0.0_f64;
// The earth's approximate longitude circumfrence
@ -62,7 +65,10 @@ pub struct TestEntry {
pub cellid: u64,
}
/// Gets the approximate geodetic difference in meters between two latlons
/// Gets the approximate geodetic difference in meters between two latlons in meters
pub fn approx_geodetic_difference_m((lat1, lon1): (f64, f64), (lat2, lon2): (f64, f64)) -> f64 {
1000.0_f64
Location::new(lat1, lon1)
.distance_to(&Location::new(lat2, lon2))
.unwrap()
.meters()
}