浏览代码

Add PrimitiveBlock::elements method

Johannes Hofmann 8 年前
父节点
当前提交
632bf74fba
共有 3 个文件被更改,包括 143 次插入17 次删除
  1. 117
    0
      src/block.rs
  2. 23
    0
      src/dense.rs
  3. 3
    17
      src/reader.rs

+ 117
- 0
src/block.rs 查看文件

@@ -41,6 +41,11 @@ impl PrimitiveBlock {
41 41
         PrimitiveBlock { block: block }
42 42
     }
43 43
 
44
+    /// Returns an iterator over the elements in this `PrimitiveBlock`.
45
+    pub fn elements(&self) -> BlockElementsIter {
46
+        BlockElementsIter::new(&self.block)
47
+    }
48
+
44 49
     /// Returns an iterator over the groups in this `PrimitiveBlock`.
45 50
     pub fn groups(&self) -> GroupIter {
46 51
         GroupIter::new(&self.block)
@@ -113,6 +118,118 @@ impl<'a> PrimitiveGroup<'a> {
113 118
     }
114 119
 }
115 120
 
121
+/// An iterator over the elements in a `PrimitiveGroup`.
122
+#[derive(Clone, Debug)]
123
+pub struct BlockElementsIter<'a> {
124
+    block: &'a osmformat::PrimitiveBlock,
125
+    state: ElementsIterState,
126
+    groups: std::slice::Iter<'a, osmformat::PrimitiveGroup>,
127
+    dense_nodes: DenseNodeIter<'a>,
128
+    nodes: std::slice::Iter<'a, osmformat::Node>,
129
+    ways: std::slice::Iter<'a, osmformat::Way>,
130
+    relations: std::slice::Iter<'a, osmformat::Relation>,
131
+}
132
+
133
+#[derive(Copy, Clone, Debug)]
134
+enum ElementsIterState {
135
+    Group,
136
+    DenseNode,
137
+    Node,
138
+    Way,
139
+    Relation
140
+}
141
+
142
+impl<'a> BlockElementsIter<'a> {
143
+    fn new(block: &'a osmformat::PrimitiveBlock) -> BlockElementsIter<'a> {
144
+        BlockElementsIter {
145
+            block: block,
146
+            state: ElementsIterState::Group,
147
+            groups: block.get_primitivegroup().iter(),
148
+            dense_nodes: DenseNodeIter::empty(block),
149
+            nodes: [].iter(),
150
+            ways: [].iter(),
151
+            relations: [].iter(),
152
+        }
153
+    }
154
+
155
+    #[inline]
156
+    fn step(&mut self) -> Option<Option<Element<'a>>> {
157
+        match self.state {
158
+            ElementsIterState::Group => {
159
+                match self.groups.next() {
160
+                    Some(group) => {
161
+                        self.state = ElementsIterState::DenseNode;
162
+                        self.dense_nodes = DenseNodeIter::new(self.block, group.get_dense());
163
+                        self.nodes = group.get_nodes().iter();
164
+                        self.ways = group.get_ways().iter();
165
+                        self.relations = group.get_relations().iter();
166
+                        None
167
+                    },
168
+                    None => Some(None),
169
+                }
170
+            },
171
+            ElementsIterState::DenseNode => {
172
+                match self.dense_nodes.next() {
173
+                    Some(dense_node) => {
174
+                        Some(Some(Element::DenseNode(dense_node)))
175
+                    },
176
+                    None => {
177
+                        self.state = ElementsIterState::Node;
178
+                        None
179
+                    },
180
+                }
181
+            },
182
+            ElementsIterState::Node => {
183
+                match self.nodes.next() {
184
+                    Some(node) => {
185
+                        Some(Some(Element::Node(Node::new(self.block, node))))
186
+                    },
187
+                    None => {
188
+                        self.state = ElementsIterState::Way;
189
+                        None
190
+                    },
191
+                }
192
+            },
193
+            ElementsIterState::Way => {
194
+                match self.ways.next() {
195
+                    Some(way) => {
196
+                        Some(Some(Element::Way(Way::new(self.block, way))))
197
+                    },
198
+                    None => {
199
+                        self.state = ElementsIterState::Relation;
200
+                        None
201
+                    },
202
+                }
203
+            },
204
+            ElementsIterState::Relation => {
205
+                match self.relations.next() {
206
+                    Some(rel) => {
207
+                        Some(Some(Element::Relation(Relation::new(self.block, rel))))
208
+                    },
209
+                    None => {
210
+                        self.state = ElementsIterState::Group;
211
+                        None
212
+                    },
213
+                }
214
+            },
215
+        }
216
+    }
217
+}
218
+
219
+impl<'a> Iterator for BlockElementsIter<'a> {
220
+    type Item = Element<'a>;
221
+
222
+    #[inline]
223
+    fn next(&mut self) -> Option<Self::Item> {
224
+        loop {
225
+            if let Some(element) = self.step() {
226
+                return element;
227
+            }
228
+        }
229
+    }
230
+}
231
+
232
+
116 233
 /// An iterator over the groups in a `PrimitiveBlock`.
117 234
 #[derive(Clone, Debug)]
118 235
 pub struct GroupIter<'a> {

+ 23
- 0
src/dense.rs 查看文件

@@ -110,6 +110,29 @@ impl<'a> DenseNodeIter<'a> {
110 110
             keys_vals_index: 0,
111 111
         }
112 112
     }
113
+
114
+    pub(crate) fn empty(block: &'a osmformat::PrimitiveBlock) -> DenseNodeIter<'a> {
115
+        DenseNodeIter {
116
+            block: block,
117
+            dids: [].iter(),
118
+            cid: 0,
119
+            versions: [].iter(),
120
+            dtimestamps: [].iter(),
121
+            ctimestamp: 0,
122
+            dchangesets: [].iter(),
123
+            cchangeset: 0,
124
+            duids: [].iter(),
125
+            cuid: 0,
126
+            duser_sids: [].iter(),
127
+            cuser_sid: 0,
128
+            dlats: [].iter(),
129
+            clat: 0,
130
+            dlons: [].iter(),
131
+            clon: 0,
132
+            keys_vals_slice: &[],
133
+            keys_vals_index: 0,
134
+        }
135
+    }
113 136
 }
114 137
 
115 138
 

+ 3
- 17
src/reader.rs 查看文件

@@ -129,23 +129,9 @@ impl<R: Read> ElementReader<R> {
129 129
                     Ok(identity())
130 130
                 },
131 131
                 Ok(BlobDecode::OsmData(block)) => {
132
-                    let dnodes = block.groups()
133
-                         .flat_map(|g| g.dense_nodes())
134
-                         .map(|dn| map_op(Element::DenseNode(dn)));
135
-                    let nodes = block.groups()
136
-                         .flat_map(|g| g.nodes())
137
-                         .map(|n| map_op(Element::Node(n)));
138
-                    let ways = block.groups()
139
-                         .flat_map(|g| g.ways())
140
-                         .map(|w| map_op(Element::Way(w)));
141
-                    let rels = block.groups()
142
-                         .flat_map(|g| g.relations())
143
-                         .map(|r| map_op(Element::Relation(r)));
144
-
145
-                    Ok(dnodes.chain(nodes)
146
-                        .chain(ways)
147
-                        .chain(rels)
148
-                        .fold(identity(), |a, b| reduce_op(a, b)))
132
+                    Ok(block.elements()
133
+                            .map(|e| map_op(e))
134
+                            .fold(identity(), |a, b| reduce_op(a, b)))
149 135
                 },
150 136
                 Err(e) => Err(e),
151 137
             }