Skip to content

Commit

Permalink
Improve Mercator API
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Dec 18, 2023
1 parent 58561da commit 4959b86
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 18 deletions.
14 changes: 4 additions & 10 deletions backend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;

Expand Down Expand Up @@ -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(),
Expand All @@ -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());
Expand Down
22 changes: 18 additions & 4 deletions backend/src/mercator.rs
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -31,20 +31,34 @@ 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
- self.height * (pt.y - self.wgs84_bounds.min().y) / self.wgs84_bounds.height();
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<G: MapCoords<f64, f64, Output = G>>(&self, geom: &G) -> G {
geom.map_coords(|pt| self.pt_to_mercator(pt))
}

pub fn to_wgs84<G: MapCoords<f64, f64, Output = G>>(&self, geom: &G) -> G {
geom.map_coords(|pt| self.pt_to_wgs84(pt))
}

pub fn to_mercator_in_place<G: MapCoordsInPlace<f64>>(&self, geom: &mut G) {
geom.map_coords_in_place(|pt| self.pt_to_mercator(pt));
}

pub fn to_wgs84_in_place<G: MapCoordsInPlace<f64>>(&self, geom: &mut G) {
geom.map_coords_in_place(|pt| self.pt_to_wgs84(pt));
}
}
7 changes: 3 additions & 4 deletions backend/src/scrape.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -49,11 +49,10 @@ pub fn scrape_osm(input_bytes: &[u8]) -> Result<MapModel> {
.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 {
Expand Down

0 comments on commit 4959b86

Please sign in to comment.