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

View File

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

View File

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

View File

@ -1,4 +1,5 @@
#![allow(dead_code)] #![allow(dead_code)]
use geoutils::Location;
use std::fs::File; use std::fs::File;
use csv::ReaderBuilder; use csv::ReaderBuilder;
@ -7,7 +8,9 @@ use serde::{Deserialize, Serialize};
/// The allowed error for encoding and decoding points, in meters /// 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 /// 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 // The earth's approximate latitude circumfrence
pub const EARTH_CIRCUMFERENCE_LAT: f64 = 0.0_f64; pub const EARTH_CIRCUMFERENCE_LAT: f64 = 0.0_f64;
// The earth's approximate longitude circumfrence // The earth's approximate longitude circumfrence
@ -62,7 +65,10 @@ pub struct TestEntry {
pub cellid: u64, 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 { 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()
} }