1
0
Fork 0

preparing for interest points

master
frederic wagner 2022-07-21 11:17:57 +02:00
parent b70bebdbac
commit 2c410ecdfe
6 changed files with 515 additions and 13 deletions

View File

@ -1,12 +1,14 @@
- water points
---> we group them following path by groups of cst_size and record segments ids marking limits
- split on points with comments
- turn off gps when moving to next waypoint
- meters seem to be a bit too long
- buzzing does not work nicely
-> is_list seems fishy
-> is_lost seems fishy
- store several tracks
- display average speed

View File

@ -17,6 +17,23 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
dependencies = [
"getrandom",
"once_cell",
"version_check",
]
[[package]]
name = "anyhow"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704"
[[package]]
name = "assert_approx_eq"
version = "1.1.0"
@ -62,12 +79,39 @@ version = "3.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
name = "bzip2"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6afcd980b5f3a45017c57e57a2fcccbb351cc43a356ce117ef760ef8052b89b0"
dependencies = [
"bzip2-sys",
"libc",
]
[[package]]
name = "bzip2-sys"
version = "0.1.11+1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
dependencies = [
"cc",
"libc",
"pkg-config",
]
[[package]]
name = "cc"
version = "1.0.73"
@ -80,6 +124,19 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
dependencies = [
"libc",
"num-integer",
"num-traits",
"time 0.1.44",
"winapi",
]
[[package]]
name = "core-foundation"
version = "0.9.3"
@ -96,6 +153,81 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
[[package]]
name = "crc32fast"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
dependencies = [
"cfg-if",
]
[[package]]
name = "darling"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f2c43f534ea4b0b049015d00269734195e6d3f0f6635cb692251aca6f9f8b3c"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e91455b86830a1c21799d94524df0845183fa55bafd9aa137b01c7d1065fa36"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29b5acf0dea37a7f66f7b25d2c5e93fd46f8f6968b1a5d7a3e02e97768afc95a"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]]
name = "derive_builder"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d13202debe11181040ae9063d739fa32cfcaaebe2275fe387703460ae2365b30"
dependencies = [
"derive_builder_macro",
]
[[package]]
name = "derive_builder_core"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66e616858f6187ed828df7c64a6d71720d83767a7f19740b2d1b6fe6327b36e5"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "derive_builder_macro"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58a94ace95092c5acb1e97a7e846b310cfbd499652f72297da7493f618a98d73"
dependencies = [
"derive_builder_core",
"syn",
]
[[package]]
name = "either"
version = "1.6.1"
@ -121,6 +253,18 @@ dependencies = [
"version_check",
]
[[package]]
name = "fallible-iterator"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
[[package]]
name = "fallible-streaming-iterator"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
[[package]]
name = "fastrand"
version = "1.7.0"
@ -130,6 +274,16 @@ dependencies = [
"instant",
]
[[package]]
name = "flate2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "fnv"
version = "1.0.7"
@ -209,6 +363,17 @@ dependencies = [
"num-traits",
]
[[package]]
name = "getrandom"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [
"cfg-if",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "gimli"
version = "0.26.1"
@ -223,6 +388,7 @@ dependencies = [
"itertools",
"lazy_static",
"openstreetmap-api",
"osmio",
"tokio",
]
@ -236,7 +402,7 @@ dependencies = [
"error-chain",
"geo-types",
"thiserror",
"time",
"time 0.3.11",
"xml-rs",
]
@ -259,12 +425,30 @@ dependencies = [
"tracing",
]
[[package]]
name = "hashbrown"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
dependencies = [
"ahash",
]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashlink"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf"
dependencies = [
"hashbrown 0.11.2",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
@ -345,6 +529,12 @@ dependencies = [
"tokio-native-tls",
]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.2.3"
@ -363,7 +553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
dependencies = [
"autocfg",
"hashbrown",
"hashbrown 0.12.3",
]
[[package]]
@ -381,6 +571,12 @@ version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b"
[[package]]
name = "iter-progress"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97059d64dd4e3a8e16696f6c0be50c1d5da3a709983f39b73fd7f84f120c5cd4"
[[package]]
name = "itertools"
version = "0.10.3"
@ -417,6 +613,16 @@ version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836"
[[package]]
name = "libsqlite3-sys"
version = "0.22.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290b64917f8b0cb885d9de0f9959fe1f775d7fa12f1da2db9001c1c8ab60f89d"
dependencies = [
"pkg-config",
"vcpkg",
]
[[package]]
name = "lock_api"
version = "0.4.7"
@ -471,7 +677,7 @@ checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf"
dependencies = [
"libc",
"log",
"wasi",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys",
]
@ -493,6 +699,16 @@ dependencies = [
"tempfile",
]
[[package]]
name = "num-integer"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.15"
@ -597,6 +813,28 @@ dependencies = [
"urlencoding",
]
[[package]]
name = "osmio"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0db40ae840afac7f6c710abf757bb76c6b95b4a34a20d55811ef70d30b3ea24f"
dependencies = [
"anyhow",
"byteorder",
"bzip2",
"chrono",
"derive_builder",
"flate2",
"iter-progress",
"protobuf",
"quick-xml",
"rusqlite",
"separator",
"serde",
"serde_json",
"xml-rs",
]
[[package]]
name = "parking_lot"
version = "0.12.1"
@ -653,6 +891,12 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "protobuf"
version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70731852eec72c56d11226c8a5f96ad5058a3dab73647ca5f7ee351e464f2571"
[[package]]
name = "quick-xml"
version = "0.22.0"
@ -727,6 +971,21 @@ dependencies = [
"winreg",
]
[[package]]
name = "rusqlite"
version = "0.25.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c4b1eaf239b47034fb450ee9cdedd7d0226571689d8823030c4b6c2cb407152"
dependencies = [
"bitflags",
"fallible-iterator",
"fallible-streaming-iterator",
"hashlink",
"libsqlite3-sys",
"memchr",
"smallvec",
]
[[package]]
name = "rustc-demangle"
version = "0.1.21"
@ -778,11 +1037,20 @@ dependencies = [
"libc",
]
[[package]]
name = "separator"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f97841a747eef040fcd2e7b3b9a220a7205926e60488e673d9e4926d27772ce5"
[[package]]
name = "serde"
version = "1.0.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
@ -849,6 +1117,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "strsim"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
[[package]]
name = "syn"
version = "1.0.98"
@ -894,6 +1168,17 @@ dependencies = [
"syn",
]
[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
[[package]]
name = "time"
version = "0.3.11"
@ -1069,6 +1354,12 @@ dependencies = [
"try-lock",
]
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"

View File

@ -11,3 +11,4 @@ itertools="*"
openstreetmap-api="*"
tokio={version="1", features=["full"]}
lazy_static="*"
osmio="*"

View File

@ -0,0 +1,58 @@
This file documents the .gpc file format.
current version is version 2.
every number is encoded in little endian order.
# header
We start by a header of 5 16bytes unsigned ints.
- the first int is a marker with value 47490
- second int is version of this file format
- third int is **NP** the number of points composing the path
- fourth int is **IP** the number of interest points bordering the path
- fifth int is **LP** the number of interest points as encountered when looping through the path (higher than previous int since some points can be met several times)
# points
We continue with an array of **2 NP** f64 containing
for each point its x and y coordinate.
# interest points
After that comes the storage for interest points.
- we start by an array of **2 IP** f64 containing
the x and y coordinates of each interest point
- we continue with an **IP** u8 array named **IPOINTS** containing the id of the point's type.
you can see the `Interest` enum in `src/osm.rs` to know what int is what.
for example 0 is a Bakery and 1 is a water point.
Now we need to store the relationship between segments and points.
The idea is that in a display phase we don't want to loop on all interest points
to figure out if they should appear on the map or not.
We'll use the fact that we now the segments we want to display and therefore we should only
need to display the points bordering these segments.
- we store an array **LOOP** of **LP** u16 indices of interest points in **IPOINTS**
while this is a contiguous array it contains points along the path grouped in buckets of 5 points.
to figure out on which segments they are :
- we store an array **STARTS** of **ceil(LP/5)** u16 indices of groups of segments.
Segments are grouped by 3.
This array tells us on which group of segment is the first point of any bucket.
## display algorithm
If we want to display the interest points for the segments between 10 and 16 for example we proceed
as follows:
* segments are grouped by 3 so instead of segment indices of 10..=16 we will look at group indices 10/3 ..= 16/3 so 3..=5
* we do a binary search of the highest number below 3 in the **STARTS** array. we call *s* the obtained index
* we do a binary search of the smallest number above 5 in the **STARTS** array. we call *e* the obtained index
* we now loop on all buckets between *s* and *e* that is : on all indices *i* in `LOOP[(s*5)..=(e*5)]`
* display `IPOINTS[i]`

View File

@ -8,10 +8,10 @@ use gpx::read;
use gpx::Gpx;
mod osm;
use osm::InterestPoint;
use osm::{parse_osm_data, InterestPoint};
const KEY: u16 = 47490;
const FILE_VERSION: u16 = 1;
const FILE_VERSION: u16 = 2;
#[derive(Debug, PartialEq, Clone, Copy)]
pub struct Point {
@ -327,18 +327,57 @@ fn compress_coordinates(points: &[(i32, i32)]) -> Vec<(i16, i16)> {
xdiffs.zip(ydiffs).collect()
}
fn save_coordinates<P: AsRef<Path>>(path: P, points: &[Point]) -> std::io::Result<()> {
fn save_gpc<P: AsRef<Path>>(path: P, points: &[Point], buckets: &[Bucket]) -> std::io::Result<()> {
let mut writer = BufWriter::new(File::create(path)?);
eprintln!("saving {} points", points.len());
let mut unique_interest_points = Vec::new();
let mut correspondance = HashMap::new();
let interests_on_path = buckets
.iter()
.flat_map(|b| &b.points)
.map(|p| match correspondance.entry(*p) {
std::collections::hash_map::Entry::Occupied(o) => *o.get(),
std::collections::hash_map::Entry::Vacant(v) => {
let index = unique_interest_points.len();
unique_interest_points.push(*p);
v.insert(index);
index
}
})
.collect::<Vec<_>>();
writer.write_all(&KEY.to_le_bytes())?;
writer.write_all(&FILE_VERSION.to_le_bytes())?;
writer.write_all(&(points.len() as u16).to_le_bytes())?;
writer.write_all(&(unique_interest_points.len() as u16).to_le_bytes())?;
writer.write_all(&(interests_on_path.len() as u16).to_le_bytes())?;
points
.iter()
.flat_map(|p| [p.x, p.y])
.try_for_each(|c| writer.write_all(&c.to_le_bytes()))?;
unique_interest_points
.iter()
.flat_map(|p| [p.point.x, p.point.y])
.try_for_each(|c| writer.write_all(&c.to_le_bytes()))?;
unique_interest_points
.iter()
.map(|p| p.interest.into())
.try_for_each(|i: u8| writer.write_all(&i.to_le_bytes()))?;
interests_on_path
.iter()
.map(|i| *i as u16)
.try_for_each(|i| writer.write_all(&i.to_le_bytes()))?;
buckets
.iter()
.map(|b| b.start as u16)
.try_for_each(|i| writer.write_all(&i.to_le_bytes()))?;
Ok(())
}
@ -419,11 +458,11 @@ fn save_path<W: Write>(writer: &mut W, p: &[Point], stroke: &str) -> std::io::Re
Ok(())
}
fn save_svg<P: AsRef<Path>>(
fn save_svg<'a, P: AsRef<Path>, I: IntoIterator<Item = &'a InterestPoint>>(
filename: P,
p: &[Point],
rp: &[Point],
interest_points: &HashSet<InterestPoint>,
interest_points: I,
waypoints: &HashSet<Point>,
) -> std::io::Result<()> {
let mut writer = BufWriter::new(std::fs::File::create(filename)?);
@ -514,6 +553,58 @@ fn detect_waypoints(points: &[Point]) -> HashSet<Point> {
.collect::<HashSet<_>>()
}
pub struct Bucket {
points: Vec<InterestPoint>,
start: usize,
}
fn position_interests_along_path(
interests: &mut [InterestPoint],
path: &[Point],
d: f64,
buckets_size: usize, // final points are indexed in buckets
groups_size: usize, // how many segments are compacted together
) -> Vec<Bucket> {
interests.sort_unstable_by(|p1, p2| p1.point.x.partial_cmp(&p2.point.x).unwrap());
// first compute for each segment a vec containing its nearby points
let mut positions = Vec::new();
for segment in path.windows(2) {
let mut local_interests = Vec::new();
let x0 = segment[0].x;
let x1 = segment[1].x;
let (xmin, xmax) = if x0 <= x1 { (x0, x1) } else { (x1, x0) };
let i = interests.partition_point(|p| p.point.x < xmin - d);
let interests = &interests[i..];
let i = interests.partition_point(|p| p.point.x <= xmax + d);
let interests = &interests[..i];
for interest in interests {
if interest.point.distance_to_segment(&segment[0], &segment[1]) <= d {
local_interests.push(*interest);
}
}
positions.push(local_interests);
}
// fuse points on chunks of consecutive segments together
let grouped_positions = positions
.chunks(groups_size)
.map(|c| c.iter().flatten().unique().copied().collect::<Vec<_>>())
.collect::<Vec<_>>();
// now, group the points in buckets
let chunks = grouped_positions
.iter()
.enumerate()
.flat_map(|(i, points)| points.iter().map(move |p| (i, p)))
.chunks(buckets_size);
let mut buckets = Vec::new();
for bucket_points in &chunks {
let mut bucket_points = bucket_points.peekable();
let start = bucket_points.peek().unwrap().0;
let points = bucket_points.map(|(_, p)| *p).collect();
buckets.push(Bucket { points, start });
}
buckets
}
#[tokio::main]
async fn main() {
let input_file = std::env::args().nth(1).unwrap_or("m.gpx".to_string());
@ -529,8 +620,18 @@ async fn main() {
eprintln!("rdp would have had {}", rdp(&p, 0.00015).len());
eprintln!("rdp took {:?}", start.elapsed());
save_coordinates("test.gpc", &rp).unwrap();
let mut interests = parse_osm_data("isere.osm.pbf");
let buckets = position_interests_along_path(&mut interests, &rp, 0.0005, 5, 3);
// let i = get_openstreetmap_data(&rp).await;
let i = HashSet::new();
save_svg("test.svg", &p, &rp, &i, &waypoints).unwrap();
// let i = HashSet::new();
save_svg(
"test.svg",
&p,
&rp,
buckets.iter().flat_map(|b| &b.points),
&waypoints,
)
.unwrap();
save_gpc("test.gpc", &rp, &buckets).unwrap();
}

View File

@ -1,10 +1,14 @@
use super::Point;
use itertools::Itertools;
use lazy_static::lazy_static;
use openstreetmap_api::{
types::{BoundingBox, Credentials},
Openstreetmap,
};
use osmio::prelude::*;
use osmio::OSMObjBase;
use std::collections::{HashMap, HashSet};
use std::path::Path;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Interest {
@ -21,7 +25,24 @@ pub enum Interest {
Pharmacy,
}
#[derive(Debug, PartialEq, Eq, Hash)]
impl Into<u8> for Interest {
fn into(self) -> u8 {
match self {
Interest::Bakery => 0,
Interest::DrinkingWater => 1,
Interest::Toilets => 2,
Interest::BikeShop => 3,
Interest::ChargingStation => 4,
Interest::Bank => 5,
Interest::Supermarket => 6,
Interest::Table => 7,
Interest::Artwork => 8,
Interest::Pharmacy => 9,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct InterestPoint {
pub point: Point,
pub interest: Interest,
@ -128,3 +149,31 @@ async fn get_openstreetmap_data(points: &[(f64, f64)]) -> HashSet<InterestPoint>
}
interest_points
}
pub fn parse_osm_data<P: AsRef<Path>>(path: P) -> Vec<InterestPoint> {
let reader = osmio::read_pbf(path).ok();
reader
.map(|mut reader| {
let mut interests = Vec::new();
for obj in reader.objects() {
match obj {
osmio::obj_types::ArcOSMObj::Node(n) => {
n.lat_lon_f64().map(|(lat, lon)| {
for p in n.tags().filter_map(move |(k, v)| {
Interest::new(k, v).map(|i| InterestPoint {
point: Point { x: lon, y: lat },
interest: i,
})
}) {
interests.push(p);
}
});
}
osmio::obj_types::ArcOSMObj::Way(_) => {}
osmio::obj_types::ArcOSMObj::Relation(_) => {}
}
}
interests
})
.unwrap_or_default()
}