Skip to content

Commit 71e08ab

Browse files
committed
Do not read useless nodes
This increases a bit the run time (+20%) but dramatically reduces memory consumption (divided by 5)
1 parent beb6af6 commit 71e08ab

File tree

1 file changed

+39
-18
lines changed

1 file changed

+39
-18
lines changed

src/osm4routing/reader.rs

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
extern crate osmpbfreader;
2-
use std::collections::HashMap;
2+
use std::collections::{HashMap, HashSet};
33
use models::*;
44
use categorize::*;
55
use std;
@@ -14,13 +14,15 @@ struct Way {
1414
struct Reader {
1515
nodes: HashMap<i64, Node>,
1616
ways: Vec<Way>,
17+
nodes_to_keep: HashSet<i64>,
1718
}
1819

1920
impl Reader {
2021
fn new() -> Reader {
2122
Reader {
2223
nodes: HashMap::new(),
2324
ways: Vec::new(),
25+
nodes_to_keep: HashSet::new(),
2426
}
2527
}
2628

@@ -72,41 +74,54 @@ impl Reader {
7274
result
7375
}
7476

75-
fn read(&mut self, filename: &str) -> Result<(), String> {
76-
let path = std::path::Path::new(filename);
77-
let r = try!(std::fs::File::open(&path).map_err(|e| e.to_string()));
78-
let mut pbf = osmpbfreader::OsmPbfReader::new(r);
77+
fn read_ways(&mut self, file: std::fs::File) {
78+
let mut pbf = osmpbfreader::OsmPbfReader::new(file);
7979
for obj in pbf.iter() {
8080
match obj {
81-
osmpbfreader::OsmObj::Node(node) => {
82-
let mut n = Node::new();
83-
n.id = node.id;
84-
n.coord = Coord {
85-
lon: node.lon,
86-
lat: node.lat,
87-
};
88-
self.nodes.insert(node.id, n);
89-
}
9081
osmpbfreader::OsmObj::Way(way) => {
9182
let mut properties = EdgeProperties::new();
9283
for (key, val) in way.tags {
9384
properties.update(key, val);
9485
}
9586
properties.normalize();
9687
if properties.accessible() {
88+
for node in &way.nodes {
89+
self.nodes_to_keep.insert(node.clone());
90+
}
9791
self.ways.push(Way {
9892
id: way.id,
9993
nodes: way.nodes,
10094
properties: properties,
101-
})
95+
});
96+
10297
}
10398
}
104-
osmpbfreader::OsmObj::Relation(_) => {}
99+
_ => {}
105100
}
106101
}
107-
Ok(())
108102
}
109103

104+
fn read_nodes(&mut self, file: std::fs::File) {
105+
let mut pbf = osmpbfreader::OsmPbfReader::new(file);
106+
self.nodes.reserve(self.nodes_to_keep.len());
107+
for obj in pbf.iter() {
108+
match obj {
109+
osmpbfreader::OsmObj::Node(node) => {
110+
if self.nodes_to_keep.contains(&node.id) {
111+
self.nodes_to_keep.remove(&node.id);
112+
let mut n = Node::new();
113+
n.id = node.id;
114+
n.coord = Coord {
115+
lon: node.lon,
116+
lat: node.lat,
117+
};
118+
self.nodes.insert(node.id, n);
119+
}
120+
}
121+
_ => {}
122+
}
123+
}
124+
}
110125

111126
fn nodes(self) -> Vec<Node> {
112127
self.nodes
@@ -124,7 +139,11 @@ impl Reader {
124139
// Read all the nodes and ways of the osm.pbf file
125140
pub fn read(filename: &str) -> Result<(Vec<Node>, Vec<Edge>), String> {
126141
let mut r = Reader::new();
127-
try!(r.read(filename));
142+
let path = std::path::Path::new(filename);
143+
let file = try!(std::fs::File::open(&path).map_err(|e| e.to_string()));
144+
r.read_ways(file);
145+
let file_nodes = try!(std::fs::File::open(&path).map_err(|e| e.to_string()));
146+
r.read_nodes(file_nodes);
128147
r.count_nodes_uses();
129148
let edges = r.edges();
130149
Ok((r.nodes(), edges))
@@ -151,6 +170,7 @@ fn test_count_nodes() {
151170
let mut r = Reader {
152171
ways: ways,
153172
nodes: nodes,
173+
nodes_to_keep: HashSet::new(),
154174
};
155175
r.count_nodes_uses();
156176
assert_eq!(2, r.nodes[&1].uses);
@@ -181,6 +201,7 @@ fn test_split() {
181201
let mut r = Reader {
182202
nodes: nodes,
183203
ways: ways,
204+
nodes_to_keep: HashSet::new(),
184205
};
185206
r.count_nodes_uses();
186207
let edges = r.edges();

0 commit comments

Comments
 (0)