From 4959b86e89db20463925786bcd256b4725e1fefe Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Mon, 18 Dec 2023 12:04:26 +0900 Subject: [PATCH] Improve Mercator API --- backend/src/lib.rs | 14 ++++---------- backend/src/mercator.rs | 22 ++++++++++++++++++---- backend/src/scrape.rs | 7 +++---- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/backend/src/lib.rs b/backend/src/lib.rs index dcaa627..c4fcce1 100644 --- a/backend/src/lib.rs +++ b/backend/src/lib.rs @@ -4,7 +4,7 @@ extern crate log; use std::fmt; use std::sync::Once; -use geo::{LineString, MapCoordsInPlace, Point}; +use geo::{LineString, Point}; use geojson::{Feature, GeoJson, Geometry}; use wasm_bindgen::prelude::*; @@ -91,18 +91,15 @@ impl MapModel { let mut nodes = Vec::new(); for i in &self.intersections { - nodes.push(self.mercator.to_wgs84(i.point.into())); + nodes.push(self.mercator.to_wgs84(&i.point).into()); } let mut edges = Vec::new(); for r in &self.roads { - let mut linestring = r.linestring.clone(); - linestring.map_coords_in_place(|c| self.mercator.to_wgs84(c)); - edges.push(Edge { node1: NodeID(r.src_i.0 as u32), node2: NodeID(r.dst_i.0 as u32), - geometry: linestring, + geometry: self.mercator.to_wgs84(&r.linestring), // Isn't serialized, doesn't matter length_meters: 0.0, name: r.tags.get("name").cloned(), @@ -128,10 +125,7 @@ impl MapModel { impl Road { fn to_gj(&self, mercator: &mercator::Mercator) -> Feature { - let mut linestring = self.linestring.clone(); - linestring.map_coords_in_place(|c| mercator.to_wgs84(c)); - - let mut f = Feature::from(Geometry::from(&linestring)); + let mut f = Feature::from(Geometry::from(&mercator.to_wgs84(&self.linestring))); f.set_property("id", self.id.0); f.set_property("way", self.way.to_string()); f.set_property("node1", self.node1.to_string()); diff --git a/backend/src/mercator.rs b/backend/src/mercator.rs index 2461e71..f19f7da 100644 --- a/backend/src/mercator.rs +++ b/backend/src/mercator.rs @@ -1,4 +1,4 @@ -use geo::{BoundingRect, Coord, HaversineLength, LineString, Rect}; +use geo::{BoundingRect, Coord, HaversineLength, LineString, MapCoords, MapCoordsInPlace, Rect}; /// Projects WGS84 points onto a Euclidean plane, using a Mercator projection. The top-left is (0, /// 0) and grows to the right and down (screen-drawing order, not Cartesian), with units of meters. @@ -31,7 +31,7 @@ impl Mercator { }) } - pub fn to_mercator(&self, pt: Coord) -> Coord { + pub fn pt_to_mercator(&self, pt: Coord) -> Coord { let x = self.width * (pt.x - self.wgs84_bounds.min().x) / self.wgs84_bounds.width(); // Invert y, so that the northernmost latitude is 0 let y = self.height @@ -39,12 +39,26 @@ impl Mercator { Coord { x, y } } - pub fn to_wgs84(&self, pt: Coord) -> Coord { + pub fn pt_to_wgs84(&self, pt: Coord) -> Coord { let x = self.wgs84_bounds.min().x + (pt.x / self.width * self.wgs84_bounds.width()); let y = self.wgs84_bounds.min().y + (self.wgs84_bounds.height() * (self.height - pt.y) / self.height); Coord { x, y } } - // TODO Take anything that can do mapcoords + pub fn to_mercator>(&self, geom: &G) -> G { + geom.map_coords(|pt| self.pt_to_mercator(pt)) + } + + pub fn to_wgs84>(&self, geom: &G) -> G { + geom.map_coords(|pt| self.pt_to_wgs84(pt)) + } + + pub fn to_mercator_in_place>(&self, geom: &mut G) { + geom.map_coords_in_place(|pt| self.pt_to_mercator(pt)); + } + + pub fn to_wgs84_in_place>(&self, geom: &mut G) { + geom.map_coords_in_place(|pt| self.pt_to_wgs84(pt)); + } } diff --git a/backend/src/scrape.rs b/backend/src/scrape.rs index 01d2255..ac5afcd 100644 --- a/backend/src/scrape.rs +++ b/backend/src/scrape.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use anyhow::Result; -use geo::{Coord, Geometry, GeometryCollection, LineString, MapCoordsInPlace, Point}; +use geo::{Coord, Geometry, GeometryCollection, LineString, Point}; use osm_reader::{Element, NodeID, WayID}; use crate::mercator::Mercator; @@ -49,11 +49,10 @@ pub fn scrape_osm(input_bytes: &[u8]) -> Result { .into(); let mercator = Mercator::from(collection).unwrap(); for r in &mut roads { - r.linestring - .map_coords_in_place(|pt| mercator.to_mercator(pt)); + mercator.to_mercator_in_place(&mut r.linestring); } for i in &mut intersections { - i.point.map_coords_in_place(|pt| mercator.to_mercator(pt)); + mercator.to_mercator_in_place(&mut i.point); } Ok(MapModel {