Skip to content

Commit 63a80ba

Browse files
committed
Changed the distance calculation algorithm.
1 parent 6b48976 commit 63a80ba

File tree

1 file changed

+52
-13
lines changed

1 file changed

+52
-13
lines changed

src/main.rs

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use chrono::prelude::*;
2-
use geo::prelude::*;
32
use rayon::prelude::*;
43
use structopt::StructOpt;
54

@@ -26,7 +25,14 @@ struct GpxResult {
2625
time: Option<String>,
2726
}
2827

29-
fn analyze(path: &std::path::PathBuf, lon: f64, lat: f64, distance: f64) -> Vec<GpxResult> {
28+
fn analyze(
29+
path: &std::path::PathBuf,
30+
lon: f64,
31+
lat: f64,
32+
deg_lon_to_dist: f64,
33+
deg_lat_to_dist: f64,
34+
distance: f64,
35+
) -> Vec<GpxResult> {
3036
let mut reader = quick_xml::Reader::from_file(&path).unwrap();
3137
reader.trim_text(true);
3238
let mut buf = Vec::new();
@@ -43,7 +49,7 @@ fn analyze(path: &std::path::PathBuf, lon: f64, lat: f64, distance: f64) -> Vec<
4349
match reader.read_event(&mut buf) {
4450
Ok(quick_xml::events::Event::Start(ref e)) => {
4551
if e.name().eq(b"trkpt") {
46-
let pt = geo_types::Point::new(
52+
let (found_lon, found_lat) = (
4753
match e.attributes().find(|e| match e {
4854
Ok(attr) => attr.key == b"lon",
4955
Err(_) => false,
@@ -126,12 +132,30 @@ fn analyze(path: &std::path::PathBuf, lon: f64, lat: f64, distance: f64) -> Vec<
126132
},
127133
);
128134

129-
let dist = match last_point {
130-
Some(last_point) => {
131-
let line = geo_types::Line::new(last_point, pt);
132-
geo_types::Point::new(lon, lat).euclidean_distance(&line)
135+
let d_lon = found_lon - lon;
136+
let d_lat = found_lat - lat;
137+
let x = (d_lon) * deg_lon_to_dist;
138+
let y = (d_lat) * deg_lat_to_dist;
139+
140+
let dist = if let Some((last_x, last_y)) = last_point {
141+
let d_x = x - last_x;
142+
let d_y: f64 = y - last_y;
143+
144+
let a = d_y.atan2(d_x) * -1.0;
145+
146+
let dist = (-x * a.sin() + y * a.cos()).abs();
147+
148+
let last_t_x = last_x * a.cos() + last_y * a.sin();
149+
150+
let t_x = x * a.cos() + y * a.sin();
151+
152+
if (last_t_x >= 0.0 && t_x <= 0.0) || (last_t_x <= 0.0 && t_x >= 0.0) {
153+
dist
154+
} else {
155+
(x * x + y * y).sqrt()
133156
}
134-
None => geo_types::Point::new(lon, lat).haversine_distance(&pt),
157+
} else {
158+
(x * x + y * y).sqrt()
135159
};
136160

137161
if (nearest.is_none() || nearest.as_ref().unwrap().distance > dist)
@@ -161,7 +185,7 @@ fn analyze(path: &std::path::PathBuf, lon: f64, lat: f64, distance: f64) -> Vec<
161185
});
162186
searching_time_for = new_results.len() - 1;
163187
}
164-
last_point = Some(pt);
188+
last_point = Some((x, y));
165189
} else if e.name().eq(b"time") {
166190
in_time = true;
167191
}
@@ -334,6 +358,14 @@ fn main() {
334358
panic!("You must specify either --longitude and --latitude or --coordinates");
335359
};
336360

361+
let deg_lon_to_dist: f64 = 6_356_752.314_245 * 2.0 * std::f64::consts::PI / 360.0
362+
* (latitude * std::f64::consts::PI / 180.0).cos();
363+
364+
let deg_lat_to_dist: f64 = 6_378_137.0 * 2.0 * std::f64::consts::PI / 360.0
365+
* (longitude * std::f64::consts::PI / 180.0).cos();
366+
367+
println!("{}, {}", deg_lat_to_dist, deg_lon_to_dist);
368+
337369
println!("{}, {}", latitude, longitude);
338370
println!(
339371
"{} {}° {:.6} {} {}° {:.6}",
@@ -371,7 +403,16 @@ fn main() {
371403
let distance = opt.distance;
372404
let analysis_results = analyze_db
373405
.par_iter()
374-
.map(|gpx_file| analyze(gpx_file, longitude, latitude, distance))
406+
.map(|gpx_file| {
407+
analyze(
408+
gpx_file,
409+
longitude,
410+
latitude,
411+
deg_lon_to_dist,
412+
deg_lat_to_dist,
413+
distance,
414+
)
415+
})
375416
.collect::<Vec<_>>();
376417
let mut results = Vec::with_capacity(
377418
analysis_results
@@ -421,8 +462,6 @@ fn main() {
421462
std::mem::drop(filtered_results);
422463
print_result(results.first().unwrap());
423464
} else {
424-
println!(
425-
"Did not find any points."
426-
);
465+
println!("Did not find any points.");
427466
}
428467
}

0 commit comments

Comments
 (0)