Alex Plugaru avatar Alex Plugaru committed 11c7183

Don't skip empty nodes

Comments (0)

Files changed (1)

imposm/parser/pbf/parser.py

 # Copyright 2011 Omniscale GmbH & Co. KG
-# 
+#
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
-# 
+#
 #     http://www.apache.org/licenses/LICENSE-2.0
-# 
+#
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     """
     OSM PBF parser.
 
-    :param xxx_callback: 
+    :param xxx_callback:
         callback functions for coords, nodes, ways and relations.
         Each callback function gets called with a list of multiple elements.
-    
+
     :param xxx_filter:
         functions that can manipulate the tag dictionary.
         Nodes and relations without tags will not passed to the callback.
-    
+
     :param marshal:
         return the data as a marshaled string
     """
         self.ways_tag_filter = ways_tag_filter
         self.relations_tag_filter = relations_tag_filter
         self.marshal = marshal
-    
+
     def parse(self, filename, offset, size):
         """
         Parse primitive block from `filename`.
-        
+
         :param filename: path to PBF file
         :param offset: byte offset of the primitive block to parse
         :param size: size in bytes of the primitive block to parse
         """
         reader = PrimitiveBlockParser(filename, offset, size)
-        
+
         if self.nodes_callback or self.coords_callback:
             self.handle_nodes(reader)
         if self.ways_callback:
             self.handle_ways(reader)
         if self.relations_callback:
             self.handle_relations(reader)
-    
+
     def handle_nodes(self, reader):
         nodes = []
         coords = []
             if nodes_callback:
                 if self.nodes_tag_filter:
                     self.nodes_tag_filter(node[1])
-                if node[1]:
-                    if self.marshal:
-                        nodes.append((node[0], dumps((node[1], node[2]), 2)))
-                    else:
-                        nodes.append((node[0], node[1], node[2]))
+                if self.marshal:
+                    nodes.append((node[0], dumps((node[1], node[2]), 2)))
+                else:
+                    nodes.append((node[0], node[1], node[2]))
                 if len(nodes) >= 256:
                     nodes_callback(nodes)
                     nodes = []
 class PrimitiveBlockParser(object):
     """
     Low level PBF primitive block parser.
-    
+
     Parses a single primitive block and handles OSM PBF internals like
     dense nodes, delta encoding, stringtables, etc.
-    
+
     :param filename: path to PBF file
     :param offset: byte offset of the primitive block to parse
     :param size: size in bytes of the primitive block to parse
-    
+
     """
     def __init__(self, filename, blob_pos, blob_size):
         self.pos = filename, blob_pos, blob_size
         self.primitive_block.ParseFromString(data)
         self.primitivegroup = self.primitive_block.primitivegroup
         self.stringtable = decoded_stringtable(self.primitive_block.stringtable.s)
-    
+
     def __repr__(self):
         return '<PrimitiveBlockParser %r>' % (self.pos, )
-    
+
     def _get_tags(self, element, pos):
         tags = {}
         key = None
         value = None
         keyflag = False
         if pos >= len(element):
-            return {}, pos 
+            return {}, pos
         while True:
             key_val = element[pos]
             pos += 1
                 tags[self.stringtable[key]] = self.stringtable[value]
                 keyflag = False
         return tags, pos
-    
+
     def nodes(self):
         """
         Return an iterator for all *nodes* in this primitive block.
-        
+
         :rtype: iterator of ``(osm_id, tags, (lon, lat))`` tuples
         """
         for group in self.primitivegroup:
                     for i in xrange(len(keys)):
                         tags.append((self.stringtable[keys[i]], self.stringtable[vals[i]]))
                     yield (node.id, tags, (node.lon, node.lat))
-    
+
     def ways(self):
         """
         Return an iterator for all *ways* in this primitive block.
-        
+
         :rtype: iterator of ``(osm_id, tags, [ref1, ref2, ...])`` tuples
         """
         for group in self.primitivegroup:
                     keys = way.keys
                     vals = way.vals
                     delta_refs = way.refs
-                    
+
                     tags = {}
                     for i in xrange(len(keys)):
                         tags[self.stringtable[keys[i]]] = self.stringtable[vals[i]]
                         ref += delta
                         refs.append(ref)
                     yield (way.id, tags, refs)
-    
+
     def relations(self):
         """
         Return an iterator for all *relations* in this primitive block.
-        
+
         :rtype: iterator of ``(osm_id, tags, [(ref1, type, role), ...])`` tuples
-        
+
         """
         for group in self.primitivegroup:
             relations = group.relations
                     for i in xrange(len(keys)):
                         tags[self.stringtable[keys[i]]] = self.stringtable[vals[i]]
                     yield (relation.id, tags, members)
-                    
+
 class PBFHeader(object):
     def __init__(self, filename, blob_pos, blob_size):
         data = read_blob_zlib_data(filename, blob_pos, blob_size)
         self.header_block = OSMPBF.HeaderBlock()
         self.header_block.ParseFromString(data)
-        
+
     def required_features(self):
         return set(self.header_block.required_features)
 
     with open(filename, 'rb') as f:
         f.seek(blob_pos)
         blob_data = f.read(blob_size)
-        
+
     blob = OSMPBF.Blob()
     blob.ParseFromString(blob_data)
     return zlib.decompress(blob.zlib_data)
 class PBFFile(object):
     """
     OSM PBF file reader.
-    
+
     Parses the low-level file structure with header sizes,
     offsets and blob headers.
-    
+
     :param filename: path to the PBF file
     """
     def __init__(self, filename):
         header_offsets = self._skip_header()
         self.header = PBFHeader(self.filename, header_offsets['blob_pos'], header_offsets['blob_size'])
         self.check_features()
-    
+
     def check_features(self):
         missing_features = SUPPORTED_FEATURES.difference(self.header.required_features())
         if missing_features:
                 '%s requires features not implemented by this parser: %s' %
                 (self.filename, ', '.join(missing_features))
             )
-    
+
     def _skip_header(self):
         return self.blob_offsets().next()
-    
+
     def seek(self, pos):
         self.next_blob_pos = pos
-    
+
     def rewind(self):
         self.next_blob_pos = self.prev_blob_pos
-    
+
     def blob_offsets(self):
         """
         Returns an iterator of the blob offsets in this file.
-        
+
         Each offsets is stored in a dictionary with:
-        
+
         - `filename` the path of this PBF file.
         - `blob_pos` the byte offset
         - `blob_size` the size of this blob in bytes
         """
         while True:
             self.file.seek(self.next_blob_pos)
-            
+
             blob_header_size = self._blob_header_size()
             if not blob_header_size: break
-            
+
             blob_size = self._blob_size(self.file.read(blob_header_size))
             blob_pos = self.next_blob_pos + 4 + blob_header_size
             blob_header_pos=self.next_blob_pos,
                 blob_header_pos=blob_header_pos,
                 prev_blob_header_pos=prev_blob_header_pos,
                 filename=self.filename)
-    
+
     def primitive_block_parsers(self):
         """
         Returns an iterator of PrimitiveBlockParser.
         """
         for pos in self.blob_offsets():
             yield PrimitiveBlockParser(self.filename, pos['blob_pos'], pos['blob_size'])
-    
+
     def _blob_size(self, data):
         blob_header = OSMPBF.BlobHeader()
         blob_header.ParseFromString(data)
         return blob_header.datasize
-        
+
     def _blob_header_size(self):
         bytes = self.file.read(4)
-        if bytes: 
+        if bytes:
             return struct.unpack('!i', bytes)[0]
         return None
 
     times = t.repeat(r,n)
     avrg_times = []
     for time in times:
-        avrg_times.append(time/n)                  
+        avrg_times.append(time/n)
     print "avrg time/call: %f" %(min(avrg_times))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.