Skip to content

Commit

Permalink
Improve tag api (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
GuillaumeGomez authored and TeXitoi committed Jan 10, 2020
1 parent bd575b8 commit 940c435
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 19 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "osmpbfreader"
version = "0.13.2"
version = "0.13.3"
authors = ["Guillaume Pinot <texitoi@texitoi.eu>"]
description = "Read OpenStreetMap PBF files in rust."
documentation = "https://docs.rs/osmpbfreader"
Expand Down
3 changes: 3 additions & 0 deletions src/blobs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,20 @@ rental! {

impl<'a> Iterator for rent::OsmObjs {
type Item = OsmObj;

fn next(&mut self) -> Option<Self::Item> {
self.rent_mut(|objs| objs.next())
}
}

/// An iterator on `Result<OsmObj>`.
pub struct OsmObjs(OsmObjsImpl);

enum OsmObjsImpl {
OkIter(iter::Map<rent::OsmObjs, fn(OsmObj) -> Result<OsmObj>>),
ErrIter(iter::Once<Result<OsmObj>>),
}

impl Iterator for OsmObjs {
type Item = Result<OsmObj>;
fn next(&mut self) -> Option<Self::Item> {
Expand Down
4 changes: 4 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub enum Error {
UnsupportedData,
InvalidData,
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Expand All @@ -28,6 +29,7 @@ impl fmt::Display for Error {
}
}
}

impl std::error::Error for Error {
fn description(&self) -> &str {
match *self {
Expand All @@ -45,11 +47,13 @@ impl std::error::Error for Error {
}
}
}

impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
Error::Io(err)
}
}

impl From<protobuf::ProtobufError> for Error {
fn from(err: protobuf::ProtobufError) -> Error {
Error::Pbf(err)
Expand Down
9 changes: 9 additions & 0 deletions src/groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub struct SimpleNodes<'a> {
iter: slice::Iter<'a, osmformat::Node>,
block: &'a PrimitiveBlock,
}

impl<'a> Iterator for SimpleNodes<'a> {
type Item = Node;
fn next(&mut self) -> Option<Node> {
Expand Down Expand Up @@ -76,6 +77,7 @@ pub fn dense_nodes<'a>(group: &'a PrimitiveGroup, block: &'a PrimitiveBlock) ->
cur_lon: 0,
}
}

pub struct DenseNodes<'a> {
block: &'a PrimitiveBlock,
dids: slice::Iter<'a, i64>,
Expand All @@ -86,6 +88,7 @@ pub struct DenseNodes<'a> {
cur_lat: i64,
cur_lon: i64,
}

impl<'a> Iterator for DenseNodes<'a> {
type Item = Node;
fn next(&mut self) -> Option<Node> {
Expand Down Expand Up @@ -125,10 +128,12 @@ pub fn ways<'a>(group: &'a PrimitiveGroup, block: &'a PrimitiveBlock) -> Ways<'a
block: block,
}
}

pub struct Ways<'a> {
iter: slice::Iter<'a, osmformat::Way>,
block: &'a PrimitiveBlock,
}

impl<'a> Iterator for Ways<'a> {
type Item = Way;
fn next(&mut self) -> Option<Way> {
Expand Down Expand Up @@ -164,6 +169,7 @@ pub struct Relations<'a> {
iter: slice::Iter<'a, osmformat::Relation>,
block: &'a PrimitiveBlock,
}

impl<'a> Iterator for Relations<'a> {
type Item = Relation;
fn next(&mut self) -> Option<Relation> {
Expand Down Expand Up @@ -202,14 +208,17 @@ impl<'a> Iterator for Relations<'a> {
fn make_string(k: usize, block: &osmformat::PrimitiveBlock) -> String {
String::from_utf8_lossy(&*block.get_stringtable().get_s()[k]).into_owned()
}

fn make_lat(c: i64, b: &osmformat::PrimitiveBlock) -> i32 {
let granularity = b.get_granularity() as i64;
((b.get_lat_offset() + granularity * c) / 100) as i32
}

fn make_lon(c: i64, b: &osmformat::PrimitiveBlock) -> i32 {
let granularity = b.get_granularity() as i64;
((b.get_lon_offset() + granularity * c) / 100) as i32
}

fn make_tags(keys: &[u32], vals: &[u32], b: &PrimitiveBlock) -> Tags {
let mut tags: Tags = keys
.iter()
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
//! the nodes of this way). For that, an easy to use function is
//! availlable.
//!
//! ```
//! ```rust
//! let mut pbf = osmpbfreader::OsmPbfReader::new(std::io::Cursor::new([]));
//! let objs = pbf.get_objs_and_deps(|obj| {
//! obj.is_way() && obj.tags().contains_key("highway")
//! })
//! .unwrap();
//! obj.is_way() && obj.tags().contains_key("highway")
//! })
//! .unwrap();
//! for (id, obj) in &objs {
//! println!("{:?}: {:?}", id, obj);
//! }
Expand Down
36 changes: 24 additions & 12 deletions src/objects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,33 @@ use std::ops::{Deref, DerefMut};
/// tags](http://wiki.openstreetmap.org/wiki/Tags) for more
/// information.
#[derive(Debug, Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct Tags(TagsImpl);
/// FlatMap representing the key-value pairs of the tags
pub type TagsImpl = ::flat_map::FlatMap<String, String>;
pub struct Tags(::flat_map::FlatMap<String, String>);

impl Tags {
/// Creates a new, empty `Tags` object.
pub fn new() -> Tags {
Tags(TagsImpl::new())
Tags(::flat_map::FlatMap::new())
}
/// Returns if contains the tag `(key, value)`.
/// Returns if it contains the a tag with the given `key` and `value`.
pub fn contains(&self, key: &str, value: &str) -> bool {
self.0.get(key).map_or(false, |v| v.as_str() == value)
}
}

impl Deref for Tags {
type Target = TagsImpl;
type Target = ::flat_map::FlatMap<String, String>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl DerefMut for Tags {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

impl FromIterator<(String, String)> for Tags {
fn from_iter<T: IntoIterator<Item = (String, String)>>(iter: T) -> Self {
Tags(iter.into_iter().collect())
Expand Down Expand Up @@ -69,6 +72,7 @@ pub enum OsmId {
/// The identifier of a relation
Relation(RelationId),
}

impl OsmId {
/// Returns `true` if the id is a node id.
pub fn is_node(&self) -> bool {
Expand All @@ -82,21 +86,21 @@ impl OsmId {
pub fn is_relation(&self) -> bool {
self.relation().is_some()
}
/// Returns the `NodeId` wrapped in an `Option`.
/// Returns the `NodeId` if it is a node, otherwise returns `None`.
pub fn node(&self) -> Option<NodeId> {
match *self {
OsmId::Node(id) => Some(id),
_ => None,
}
}
/// Returns the `WayId` wrapped in an `Option`.
/// Returns the `WayId` if it is a way, otherwise returns `None`.
pub fn way(&self) -> Option<WayId> {
match *self {
OsmId::Way(id) => Some(id),
_ => None,
}
}
/// Returns the `RelationId` wrapped in an `Option`.
/// Returns the `RelationId` if it is a relation, otherwise returns `None`.
pub fn relation(&self) -> Option<RelationId> {
match *self {
OsmId::Relation(id) => Some(id),
Expand All @@ -123,6 +127,7 @@ pub enum OsmObj {
/// A relation
Relation(Relation),
}

impl OsmObj {
/// Returns the tags of the object.
pub fn tags(&self) -> &Tags {
Expand Down Expand Up @@ -152,21 +157,21 @@ impl OsmObj {
pub fn is_relation(&self) -> bool {
self.relation().is_some()
}
/// Gets a reference to the node in an `Option`.
/// Returns a reference to the `Node` if `self` is a node, otherwise returns `None`.
pub fn node(&self) -> Option<&Node> {
match *self {
OsmObj::Node(ref n) => Some(n),
_ => None,
}
}
/// Gets a reference to the way in an `Option`.
/// Returns a reference to the `Way` if `self` is a way, otherwise returns `None`.
pub fn way(&self) -> Option<&Way> {
match *self {
OsmObj::Way(ref w) => Some(w),
_ => None,
}
}
/// Gets a reference to the relation in an `Option`.
/// Returns a reference to the `Relation` if `self` is a relation, otherwise returns `None`.
pub fn relation(&self) -> Option<&Relation> {
match *self {
OsmObj::Relation(ref r) => Some(r),
Expand All @@ -189,6 +194,7 @@ pub struct Node {
/// The longitude in decimicro degrees (10⁻⁷ degrees).
pub decimicro_lon: i32,
}

impl Node {
/// Returns the latitude of the node in degrees.
pub fn lat(&self) -> f64 {
Expand All @@ -212,6 +218,7 @@ pub struct Way {
/// The ordered list of nodes as id.
pub nodes: Vec<NodeId>,
}

impl Way {
/// Returns true if the way is
/// [open](http://wiki.openstreetmap.org/wiki/Way#Open_way).
Expand Down Expand Up @@ -252,26 +259,31 @@ impl ::std::convert::From<NodeId> for OsmId {
OsmId::Node(n)
}
}

impl ::std::convert::From<WayId> for OsmId {
fn from(w: WayId) -> Self {
OsmId::Way(w)
}
}

impl ::std::convert::From<RelationId> for OsmId {
fn from(r: RelationId) -> Self {
OsmId::Relation(r)
}
}

impl ::std::convert::From<Node> for OsmObj {
fn from(n: Node) -> Self {
OsmObj::Node(n)
}
}

impl ::std::convert::From<Way> for OsmObj {
fn from(w: Way) -> Self {
OsmObj::Way(w)
}
}

impl ::std::convert::From<Relation> for OsmObj {
fn from(r: Relation) -> Self {
OsmObj::Relation(r)
Expand Down
4 changes: 2 additions & 2 deletions src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ impl<R: io::Read> OsmPbfReader<R> {

/// Returns an iterator on the OsmObj of the pbf file.
///
/// #Example
/// # Example
///
/// ```
/// let mut pbf = osmpbfreader::OsmPbfReader::new(std::io::empty());
Expand All @@ -75,7 +75,7 @@ impl<R: io::Read> OsmPbfReader<R> {
/// CPU usage are guaranteed to be bounded even if the caller stop
/// consuming items.
///
/// #Example
/// # Example
///
/// ```
/// let mut pbf = osmpbfreader::OsmPbfReader::new(std::io::empty());
Expand Down

0 comments on commit 940c435

Please sign in to comment.