diff --git a/spatial-coordinate-systems/src/urls.rs b/spatial-coordinate-systems/src/urls.rs index dbfab59..d45c4ac 100644 --- a/spatial-coordinate-systems/src/urls.rs +++ b/spatial-coordinate-systems/src/urls.rs @@ -2,10 +2,15 @@ use crate::{Error, LatLon}; use std::str::FromStr; use url::Url; +// TODO: Set a reasonable OSM zoom level +const OPENSTREETMAP_ZOOM_LEVEL: u8 = 19; + #[derive(PartialEq, Debug, Clone)] pub struct CoordinateUrls { - google_maps: String, - latlon: LatLon, + // TODO: These should be getters only + pub google_maps: String, + pub openstreetmap: String, + pub latlon: LatLon, } impl CoordinateUrls { @@ -38,13 +43,23 @@ impl TryFrom for CoordinateUrls { type Error = Error; fn try_from(latlon: LatLon) -> Result { - let latlon_str = format!("{},{}", latlon.get_lat(), latlon.get_lon()); + let (lat, lon) = (latlon.get_lat(), latlon.get_lon()); + let latlon_str = format!("{lat},{lon}"); + + let openstreetmap = { + let mut ret = Url::parse("https://www.openstreetmap.org/")?; + + ret.set_fragment(Some(&format!("map={OPENSTREETMAP_ZOOM_LEVEL}/{lat}/{lon}"))); + + String::from(ret) + }; Ok(Self { google_maps: String::from(Url::parse_with_params( "https://www.google.com/maps/search/", &[("api", "1"), ("query", &latlon_str)], )?), + openstreetmap, latlon, }) } diff --git a/web-frontend/src/routes/app/CoordinateInfo.svelte b/web-frontend/src/routes/app/CoordinateInfo.svelte index 04c2b1a..c8052a6 100644 --- a/web-frontend/src/routes/app/CoordinateInfo.svelte +++ b/web-frontend/src/routes/app/CoordinateInfo.svelte @@ -4,6 +4,7 @@ export let xpin; let formats = ['dd', 'dms', 'dmm', 'utm', 'plus']; + let urlFormats = ['google_maps', 'openstreetmap']; onMount(() => { // TODO: Indicate that the data is copied @@ -25,4 +26,16 @@ {/each} + + {#each urlFormats as format} + + {format.toUpperCase()} + + Open in {format} + + + + {/each} diff --git a/xpin-wasm/src/lib.rs b/xpin-wasm/src/lib.rs index b38c428..5dd793e 100644 --- a/xpin-wasm/src/lib.rs +++ b/xpin-wasm/src/lib.rs @@ -47,6 +47,10 @@ pub struct EncodedAddress { pub address: String, /// The coordinates used to encode this address src_coords: Coordinate, + + #[wasm_bindgen(js_name = coordinateUrls)] + pub coordinate_urls: CoordinateUrls, + #[wasm_bindgen(js_name = latLon)] pub lat_lon: Box<[f64]>, @@ -173,12 +177,34 @@ impl TryFrom<&'_ Address<'_>> for EncodedAddress { address: addr.to_string(), lat_lon: Box::new([lat, lon]), src_coords, + coordinate_urls: spatial_coordinate_systems::urls::CoordinateUrls::try_from( + all_coordinates.latlon, + ) + .map_err(|e| e.to_string())? + .into(), decimal_degrees: format!("{}, {}", lat, lon), all_coordinates: Coordinates::from(&all_coordinates), }) } } +#[wasm_bindgen(getter_with_clone)] +#[derive(Debug, Clone)] +pub struct CoordinateUrls { + // TODO: These should be getters only + pub google_maps: String, + pub openstreetmap: String, +} + +impl From for CoordinateUrls { + fn from(value: spatial_coordinate_systems::urls::CoordinateUrls) -> Self { + Self { + google_maps: value.google_maps, + openstreetmap: value.openstreetmap, + } + } +} + #[cfg(test)] mod tests { use super::*;