Skip to content

Commit

Permalink
Clearly split out 'plugin' code that should likely be edited by someone
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Aug 11, 2023
1 parent 4b4757a commit bbed56a
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 57 deletions.
36 changes: 8 additions & 28 deletions src/custom_routing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ use serde::{Deserialize, Serialize};

use super::input::{CostFunction, Filter};
use super::node_map::{deserialize_nodemap, NodeMap};
use super::osm2network::{Counts, Edge, Network, Position};
use super::osm2network::{Counts, Network, Position};
use super::plugins::route_cost;
use super::plugins::uptake;
use super::requests::Request;

// TODO Vary ch_path with CostFunction
Expand Down Expand Up @@ -100,7 +102,8 @@ fn handle_request(
}

if let Some(path) = path_calc.calc_path(&prepared_ch.ch, start, end) {
if let Some(max_dist) = filter.max_distance_meters {
// Optimization: don't calculate full route details unless needed
if filter.max_distance_meters.is_some() {
// fast_paths returns the total cost, but it's not necessarily the right unit.
// Calculate how long this route is.
let mut length = 0.0;
Expand All @@ -114,7 +117,8 @@ fn handle_request(
.unwrap();
length += edge.length_meters;
}
if length.round() as usize > max_dist {

if uptake::should_skip_trip(filter, length) {
counts.filtered_out += 1;
return;
}
Expand Down Expand Up @@ -170,7 +174,7 @@ fn build_ch(path: &str, network: &Network, cost: CostFunction) -> Result<Prepare
let node1 = node_map.get_or_insert(*node1);
let node2 = node_map.get_or_insert(*node2);

if let Some(cost) = edge_cost(edge, cost) {
if let Some(cost) = route_cost::edge_cost(edge, cost) {
// Everything bidirectional for now!
input_graph.add_edge(node1, node2, cost);
input_graph.add_edge(node2, node1, cost);
Expand All @@ -195,30 +199,6 @@ fn build_ch(path: &str, network: &Network, cost: CostFunction) -> Result<Prepare
Ok(result)
}

fn edge_cost(edge: &Edge, cost: CostFunction) -> Option<usize> {
let tags = edge.cleaned_tags();

// TODO Match the lts.ts definition
if tags.is("bicycle", "no") || tags.is("highway", "motorway") || tags.is("highway", "proposed")
{
return None;
}

let output = match cost {
CostFunction::Distance => edge.length_meters,
CostFunction::AvoidMainRoads => {
// TODO Match the LTS definitoins
let penalty = if tags.is("highway", "residential") || tags.is("highway", "cycleway") {
1.0
} else {
5.0
};
penalty * edge.length_meters
}
};
Some(output.round() as usize)
}

// fast_paths ID representing the OSM node ID as the data
// TODO We may be able to override the distance function? Does it work with WGS84?
type IntersectionLocation = GeomWithData<[f64; 2], usize>;
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod node_map;
mod od;
mod osm2network;
mod osrm;
mod plugins;
mod requests;
mod tags;

Expand Down
31 changes: 2 additions & 29 deletions src/osm2network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use indicatif::HumanCount;
use osmpbf::{Element, ElementReader};
use serde::{Deserialize, Serialize};

use super::plugins::lts;
use super::tags::Tags;

#[derive(Serialize, Deserialize)]
Expand Down Expand Up @@ -152,7 +153,7 @@ impl Edge {
properties.insert("count".to_string(), JsonValue::from(count));
properties.insert(
"lts".to_string(),
JsonValue::from(self.level_traffic_stress()),
JsonValue::from(lts::placeholder(self.cleaned_tags())),
);
Feature {
bbox: None,
Expand All @@ -170,34 +171,6 @@ impl Edge {
}
tags
}

// 1 suitable for kids, 4 high stress, 0 is unknown. Need to swap this out for something much
// better, and maybe make it directional!
fn level_traffic_stress(&self) -> usize {
// TODO Handle bicycle=no, on things like highway=footway

let tags = self.cleaned_tags();

if let Some(mph) = tags
.get("maxspeed")
.and_then(|x| x.trim_end_matches(" mph").parse::<usize>().ok())
{
if mph <= 20 {
return 2;
}
if mph >= 40 {
return 4;
}
// Between 20 and 40
return 3;
}

/*if tags.is("highway", "residential") {
return 1;
}*/

0 // TODO unknown
}
}

fn scrape_elements(path: &str) -> Result<(HashMap<i64, Position>, HashMap<i64, Way>)> {
Expand Down
27 changes: 27 additions & 0 deletions src/plugins/lts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::tags::Tags;

// 1 suitable for kids, 4 high stress, 0 is unknown. Need to swap this out for something much
// better, and maybe make it directional!
pub fn placeholder(tags: Tags) -> usize {
// TODO Handle bicycle=no, on things like highway=footway

if let Some(mph) = tags
.get("maxspeed")
.and_then(|x| x.trim_end_matches(" mph").parse::<usize>().ok())
{
if mph <= 20 {
return 2;
}
if mph >= 40 {
return 4;
}
// Between 20 and 40
return 3;
}

/*if tags.is("highway", "residential") {
return 1;
}*/

0 // TODO unknown
}
3 changes: 3 additions & 0 deletions src/plugins/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod lts;
pub mod route_cost;
pub mod uptake;
26 changes: 26 additions & 0 deletions src/plugins/route_cost.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
use crate::input::CostFunction;
use crate::osm2network::Edge;

pub fn edge_cost(edge: &Edge, cost: CostFunction) -> Option<usize> {
let tags = edge.cleaned_tags();

// TODO Match the lts.ts definition
if tags.is("bicycle", "no") || tags.is("highway", "motorway") || tags.is("highway", "proposed")
{
return None;
}

let output = match cost {
CostFunction::Distance => edge.length_meters,
CostFunction::AvoidMainRoads => {
// TODO Match the LTS definitoins
let penalty = if tags.is("highway", "residential") || tags.is("highway", "cycleway") {
1.0
} else {
5.0
};
penalty * edge.length_meters
}
};
Some(output.round() as usize)
}
9 changes: 9 additions & 0 deletions src/plugins/uptake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use crate::input::Filter;

pub fn should_skip_trip(filter: &Filter, total_distance_meters: f64) -> bool {
if let Some(max) = filter.max_distance_meters {
return total_distance_meters.round() as usize > max;
}

false
}

0 comments on commit bbed56a

Please sign in to comment.