Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 73 additions & 5 deletions src/groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,25 @@ pub struct SimpleNodes<'a> {
impl<'a> Iterator for SimpleNodes<'a> {
type Item = Node;
fn next(&mut self) -> Option<Node> {
self.iter.next().map(|n| Node {
id: NodeId(n.get_id()),
decimicro_lat: make_lat(n.get_lat(), self.block),
decimicro_lon: make_lon(n.get_lon(), self.block),
tags: make_tags(n.get_keys(), n.get_vals(), self.block),
self.iter.next().map(|n| {
let info = n.get_info();
let info_timestamp = if info.has_timestamp() {
Some(info.get_timestamp())
} else {
None
};
let info_visible = if info.has_visible() {
Some(info.get_visible())
} else {
None
};
Node {
id: NodeId(n.get_id()),
decimicro_lat: make_lat(n.get_lat(), self.block),
decimicro_lon: make_lon(n.get_lon(), self.block),
tags: make_tags(n.get_keys(), n.get_vals(), self.block),
info: make_info(info_timestamp, info_visible),
}
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
Expand All @@ -69,13 +83,22 @@ impl<'a> Iterator for SimpleNodes<'a> {

pub fn dense_nodes<'a>(group: &'a PrimitiveGroup, block: &'a PrimitiveBlock) -> DenseNodes<'a> {
let dense = group.get_dense();
let (dinfo_timestamp, dinfo_visible) = if dense.has_denseinfo() {
let dinfo = dense.get_denseinfo();
(dinfo.get_timestamp().iter(), dinfo.get_visible().iter())
} else {
([].iter(), [].iter())
};
DenseNodes {
block,
dids: dense.get_id().iter(),
dinfo_timestamp: dinfo_timestamp,
dinfo_visible: dinfo_visible,
dlats: dense.get_lat().iter(),
dlons: dense.get_lon().iter(),
keys_vals: dense.get_keys_vals().iter(),
cur_id: 0,
cur_info_timestamp: 0,
cur_lat: 0,
cur_lon: 0,
}
Expand All @@ -84,10 +107,13 @@ pub fn dense_nodes<'a>(group: &'a PrimitiveGroup, block: &'a PrimitiveBlock) ->
pub struct DenseNodes<'a> {
block: &'a PrimitiveBlock,
dids: slice::Iter<'a, i64>,
dinfo_timestamp: slice::Iter<'a, i64>,
dinfo_visible: slice::Iter<'a, bool>,
dlats: slice::Iter<'a, i64>,
dlons: slice::Iter<'a, i64>,
keys_vals: slice::Iter<'a, i32>,
cur_id: i64,
cur_info_timestamp: i64,
cur_lat: i64,
cur_lon: i64,
}
Expand Down Expand Up @@ -116,11 +142,17 @@ impl<'a> Iterator for DenseNodes<'a> {
tags.insert(k, v);
}
tags.shrink_to_fit();
let info_timestamp = self.dinfo_timestamp.next().map(|ts| *ts);
if let Some(ts) = info_timestamp {
self.cur_info_timestamp += ts;
}
let info_visible = self.dinfo_visible.next().map(|ts| *ts);
Some(Node {
id: NodeId(self.cur_id),
decimicro_lat: make_lat(self.cur_lat, self.block),
decimicro_lon: make_lon(self.cur_lon, self.block),
tags,
info: make_info(info_timestamp, info_visible),
})
}
}
Expand Down Expand Up @@ -150,10 +182,22 @@ impl<'a> Iterator for Ways<'a> {
NodeId(n)
})
.collect();
let info = w.get_info();
let info_timestamp = if info.has_timestamp() {
Some(info.get_timestamp())
} else {
None
};
let info_visible = if info.has_visible() {
Some(info.get_visible())
} else {
None
};
Way {
id: WayId(w.get_id()),
nodes,
tags: make_tags(w.get_keys(), w.get_vals(), self.block),
info: make_info(info_timestamp, info_visible),
}
})
}
Expand Down Expand Up @@ -196,10 +240,22 @@ impl<'a> Iterator for Relations<'a> {
}
})
.collect();
let info = rel.get_info();
let info_timestamp = if info.has_timestamp() {
Some(info.get_timestamp())
} else {
None
};
let info_visible = if info.has_visible() {
Some(info.get_visible())
} else {
None
};
Relation {
id: RelationId(rel.get_id()),
refs,
tags: make_tags(rel.get_keys(), rel.get_vals(), self.block),
info: make_info(info_timestamp, info_visible),
}
})
}
Expand Down Expand Up @@ -235,3 +291,15 @@ fn make_tags(keys: &[u32], vals: &[u32], b: &PrimitiveBlock) -> Tags {
tags.shrink_to_fit();
tags
}

fn make_info(timestamp: Option<i64>, visible: Option<bool>) -> Option<Info> {
if timestamp.is_some() || visible.is_some() {
Some(Info {
timestamp: timestamp,
// osmformat.proto somewhat sounds like true is a sensible default.
visible: visible.unwrap_or(true),
})
} else {
None
}
}
16 changes: 16 additions & 0 deletions src/objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ pub struct Node {
pub decimicro_lat: i32,
/// The longitude in decimicro degrees (10⁻⁷ degrees).
pub decimicro_lon: i32,
/// The info of the node.
pub info: Option<Info>,
}

impl Node {
Expand All @@ -219,6 +221,8 @@ pub struct Way {
pub tags: Tags,
/// The ordered list of nodes as id.
pub nodes: Vec<NodeId>,
/// The info of the way.
pub info: Option<Info>,
}

impl Way {
Expand Down Expand Up @@ -254,6 +258,18 @@ pub struct Relation {
pub tags: Tags,
/// Members of the relation.
pub refs: Vec<Ref>,
/// The info of the relation.
pub info: Option<Info>,
}

/// An Info object for storing metadate about a Node, Way or Relation.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash, Serialize, Deserialize)]
pub struct Info {
/// The timestamp when the object was introduced.
pub timestamp: Option<i64>,
/// Wether the object should be considered a currently valid object. Being false hints to it
/// being a historic version that is not uptodate anymore. Defaults to true.
pub visible: bool,
}

impl ::std::convert::From<NodeId> for OsmId {
Expand Down