Skip to content

Commit

Permalink
Merge branch 'handle-relation-cycles'
Browse files Browse the repository at this point in the history
  • Loading branch information
mkulke committed Aug 11, 2020
2 parents 801e378 + d0979f0 commit 7389396
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "osm_pbf2json"
version = "0.2.1"
version = "0.2.2"
authors = ["magnus kulke <mkulke@gmail.com>"]
edition = "2018"
homepage = "https://github.com/mkulke/osm-pbf2json"
Expand Down
57 changes: 47 additions & 10 deletions src/lib/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use self::geo::get_compound_coordinates;
use self::items::{osm, AdminBoundary, Object, Street};
use admin::get_boundaries;
use filter::{Condition, Filter, Group};
use osmpbfreader::objects::{OsmId, OsmObj, Relation, Way};
use osmpbfreader::objects::{OsmId, OsmObj, Relation, RelationId, Way};
use osmpbfreader::OsmPbfReader;
use rstar::RTree;
use std::collections::BTreeMap;
Expand All @@ -25,6 +25,14 @@ trait OsmExt {
fn get_coordinates(&self, objs: &BTreeMap<OsmId, OsmObj>) -> Vec<(f64, f64)>;
}

trait OsmCycle {
fn get_coordinates(
&self,
objs: &BTreeMap<OsmId, OsmObj>,
visited: &mut Vec<RelationId>,
) -> Vec<(f64, f64)>;
}

impl OsmExt for Way {
fn get_coordinates(&self, objs: &BTreeMap<OsmId, OsmObj>) -> Vec<(f64, f64)> {
self.nodes
Expand All @@ -38,8 +46,16 @@ impl OsmExt for Way {
}
}

impl OsmExt for Relation {
fn get_coordinates(&self, objs: &BTreeMap<OsmId, OsmObj>) -> Vec<(f64, f64)> {
impl OsmCycle for Relation {
fn get_coordinates(
&self,
objs: &BTreeMap<OsmId, OsmObj>,
visited: &mut Vec<RelationId>,
) -> Vec<(f64, f64)> {
if visited.contains(&self.id) {
return vec![];
}
visited.push(self.id);
let coordinates = self
.refs
.iter()
Expand All @@ -48,7 +64,7 @@ impl OsmExt for Relation {
let coordinates = match obj {
OsmObj::Node(node) => vec![(node.lon(), node.lat())],
OsmObj::Way(way) => way.get_coordinates(objs),
OsmObj::Relation(rel) => rel.get_coordinates(objs),
OsmObj::Relation(rel) => rel.get_coordinates(objs, visited),
};
Some(coordinates)
})
Expand Down Expand Up @@ -208,7 +224,7 @@ pub fn objects(file: impl Seek + Read, groups: &[Group]) -> Result<Vec<Object>,
Object::Way(way)
}
OsmObj::Relation(obj) => {
let coordinates = obj.get_coordinates(&objs);
let coordinates = obj.get_coordinates(&objs, &mut vec![]);
let relation = osm::Relation::new(obj.id.0, obj.tags.clone(), &coordinates);
Object::Relation(relation)
}
Expand Down Expand Up @@ -274,7 +290,7 @@ mod get_coordinates {
let obj_map = BTreeMap::new();
let id = RelationId(42);
let rel = create_relation(id, vec![]);
let coordinates = rel.get_coordinates(&obj_map);
let coordinates = rel.get_coordinates(&obj_map, &mut vec![]);
assert_eq!(coordinates.len(), 0);
}

Expand All @@ -301,7 +317,7 @@ mod get_coordinates {

// we expect a closed triangle

let coordinates = rel.get_coordinates(&obj_map);
let coordinates = rel.get_coordinates(&obj_map, &mut vec![]);
assert_eq!(
coordinates,
vec![(9., 50.), (9., 51.), (10., 51.), (9., 50.)]
Expand All @@ -317,7 +333,7 @@ mod get_coordinates {
let id = RelationId(42);
let refs = create_refs(vec![node_id.into()]);
let rel = create_relation(id, refs);
let coordinates = rel.get_coordinates(&obj_map);
let coordinates = rel.get_coordinates(&obj_map, &mut vec![]);
assert_eq!(coordinates, vec![(5., 49.)]);
}

Expand All @@ -341,7 +357,7 @@ mod get_coordinates {
let id = RelationId(42);
let refs = create_refs(node_ids.into_iter().map(NodeId::into).collect());
let rel = create_relation(id, refs);
let coordinates = rel.get_coordinates(&obj_map);
let coordinates = rel.get_coordinates(&obj_map, &mut vec![]);

// We expect a simplified closed rectangle.
//
Expand Down Expand Up @@ -377,11 +393,32 @@ mod get_coordinates {
let refs = create_refs(vec![child_id.into(), node_id.into()]);
let parent_rel = create_relation(parent_id, refs);

let coordinates = parent_rel.get_coordinates(&obj_map);
let coordinates = parent_rel.get_coordinates(&obj_map, &mut vec![]);

assert_eq!(
coordinates,
vec![(6., 50.), (8., 52.), (6., 52.), (6., 50.)]
);
}

#[test]
fn nested_relations_with_cycle() {
let mut obj_map = BTreeMap::new();
let rel_id_1 = RelationId(42);
let rel_id_2 = RelationId(44);
let refs = create_refs(vec![rel_id_2.into()]);
let rel_1 = create_relation(rel_id_1, refs);
obj_map.insert(rel_id_1.into(), rel_1.into());

let node_id = NodeId(43);
let node = create_node(node_id, 8, 52);
obj_map.insert(node_id.into(), node.into());

let refs = create_refs(vec![rel_id_1.into(), node_id.into()]);
let rel_2 = create_relation(rel_id_2, refs);

let coordinates = rel_2.get_coordinates(&obj_map, &mut vec![]);

assert_eq!(coordinates, vec![(8., 52.)]);
}
}

0 comments on commit 7389396

Please sign in to comment.