1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// Copyright (c) 2014-2015 Guillaume Pinot <texitoi(a)texitoi.eu>
//
// This work is free. You can redistribute it and/or modify it under
// the terms of the Do What The Fuck You Want To Public License,
// Version 2, as published by Sam Hocevar. See the COPYING file for
// more details.

//! This crate provide an interface to easily read [OpenStreetMap PBF
//! files](http://wiki.openstreetmap.org/wiki/PBF_Format).  Its main
//! inspiration is
//! [libosmpbfreader](https://github.com/CanalTP/libosmpbfreader).
//!
//! # Getting objects and their dependencies
//!
//! Most of the time, you'll want a subset of the OSM objects and its
//! dependencies (i.e. the nodes inside a way, and not only the ids of
//! the nodes of this way).  For that, an easy to use function is
//! availlable.
//!
//! ```
//! 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();
//! for (id, obj) in &objs {
//!     println!("{:?}: {:?}", id, obj);
//! }
//! ```
//!
//! # Readding
//!
//! The easiest way to read a PBF file is to directly iterate on the
//! `OsmObj`.
//!
//! ```rust
//! use std::process::exit;
//! let mut pbf = osmpbfreader::OsmPbfReader::new(std::io::empty());
//! for obj in pbf.iter() {
//!     // error handling:
//!     let obj = obj.unwrap_or_else(|e| {println!("{:?}", e); exit(1)});
//!
//!     println!("{:?}", obj);
//! }
//! ```
//!
//! There is also a parallel version of this iterator. The file is
//! decoded in parallel.
//!
//! ```rust
//! use std::process::exit;
//! let mut pbf = osmpbfreader::OsmPbfReader::new(std::io::empty());
//! for obj in pbf.par_iter() {
//!     // error handling:
//!     let obj = obj.unwrap_or_else(|e| {println!("{:?}", e); exit(1)});
//!
//!     println!("{:?}", obj);
//! }
//! ```
//!
//! # Into the details
//!
//! This crate is build around basic iterators on different parts of
//! the structure of the PBF format.  Then, several higher level
//! iterator are proposed.  It is then possible to iterate on the file
//! using the low level iterators.
//!
//! ```rust
//! use osmpbfreader::{primitive_block_from_blob, groups};
//! let mut pbf = osmpbfreader::OsmPbfReader::new(std::io::empty());
//! for block in pbf.blobs().map(|b| primitive_block_from_blob(&b.unwrap())) {
//!     let block = block.unwrap();
//!     for group in block.get_primitivegroup().iter() {
//!         for node in groups::simple_nodes(&group, &block) {
//!             println!("{:?}", node);
//!         }
//!         for node in groups::dense_nodes(&group, &block) {
//!             println!("{:?}", node);
//!         }
//!         for way in groups::ways(&group, &block) {
//!             println!("{:?}", way);
//!         }
//!         for relation in groups::relations(&group, &block) {
//!             println!("{:?}", relation);
//!         }
//!     }
//! }
//! ```
//!
//! Notice that `primitive_block_from_blob` can be costy as it
//! uncompress the blob.  Using some kind of parallel map can then
//! improve the reading speed of the PBF file.

#![deny(missing_docs)]

extern crate protobuf;
extern crate flate2;
extern crate byteorder;
extern crate flat_map;
#[macro_use]
extern crate rental;
extern crate par_map;

pub use objects::*;
pub use error::Error;
pub use error::Result;
pub use reader::{OsmPbfReader, primitive_block_from_blob};

/// Abstract behind a tuple struct an iterator.
macro_rules! pub_iterator_type {
    ( #[$($attr:tt)*] $Name:ident [ $($NameParam:tt)* ] = $From:ty ) => {
        #[$($attr)*]
        pub struct $Name < $($NameParam)* > ( $From );
        impl< $($NameParam)* > Iterator for $Name < $($NameParam)* > {
            type Item = < $From as Iterator>::Item;
            fn next(&mut self) -> Option<Self::Item> {
                self.0.next()
            }
            fn size_hint(&self) -> (usize, Option<usize>) {
                self.0.size_hint()
            }
        }
    };
    ( #[$($attr:tt)*] $Name:ident [ $($NameParam:tt)* ] = $From:ty where $($w:tt)* ) => {
        #[$($attr)*]
        pub struct $Name < $($NameParam)* > ( $From ) where $($w)* ;
        impl< $($NameParam)* > Iterator for $Name < $($NameParam)* > where $($w)* {
            type Item = <$From as Iterator>::Item;
            fn next(&mut self) -> Option<Self::Item> {
                self.0.next()
            }
            fn size_hint(&self) -> (usize, Option<usize>) {
                self.0.size_hint()
            }
        }
    }
}

pub mod reader;
pub mod objects;
pub mod blobs;

#[allow(missing_docs)]
pub mod error;
#[allow(missing_docs)]
pub mod blocks;
#[allow(missing_docs)]
pub mod groups;

/// Generated from protobuf.
#[allow(non_snake_case, missing_docs)]
pub mod fileformat;

/// Generated from protobuf.
#[allow(missing_docs)]
pub mod osmformat;