Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve tag api #25

Merged
merged 3 commits into from
Jan 10, 2020
Merged
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
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>;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You must let this type alias, else it's a breaking change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't change the API, so from my point of view it isn't one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All codes using your crate won't break with this change.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will if someone use something like struct Data { tags: osmpbfreader::objects::TagsImpl }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Do you mind if we remove it then?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to keep it, but no strong feeling on it (I doubt someone is using it).

pub struct Tags(::flat_map::FlatMap<String, String>);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just not using the type alias here would be enough to have the documentation. Looks like a bug, no?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rust-lang/rust#68016

And the alias is useless, unless I'm missing something?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alias is more here for backcompatibility, before, this TagsImpl was a new type if I recall well.


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