使用正确的.proto文件时,无法在python中解析协议缓冲区文件

时间:2016-02-12 16:40:14

标签: python openstreetmap protocol-buffers

(请参阅底部的更新)

Tilemaker是一个OpenStreetMap程序,用于从OSM pbf数据文件生成Mapbox vector tiles(它们本身是protocol buffers(pbf)文件)。我编译了它并用它来创建矢量切片目录。我无法用Python解析这些文件。

我创建了矢量图块:

tilemaker input.pbf --output=tiles/

然后我以这种方式基于Google's Protocol Buffers Python Tutorial创建了一个简单的python程序:

编译.proto个文件:

mkdir py
touch py/__init__.py
protoc --proto_path=include --python_out=./py ./include/osmformat.proto
protoc --proto_path=include --python_out=./py ./include/vector_tile.proto

这个python程序pyread.py不起作用:

import sys
import py.vector_tile_pb2

with open(sys.argv[1]) as fp:
    pbf_file_contents = fp.read()

tile = py.vector_tile_pb2.Tile()
tile.ParseFromString(pbf_file_contents)

尝试运行时出现错误:

$ python pyread.py ./tiles/13/3932/2588.pbf
Traceback (most recent call last):
  File "pyread.py", line 8, in <module>
    tile.ParseFromString(pbf_file_contents)
  File "/home/rory/.local/lib/python2.7/site-packages/google/protobuf/message.py", line 186, in ParseFromString
    self.MergeFromString(serialized)
  File "/home/rory/.local/lib/python2.7/site-packages/google/protobuf/internal/python_message.py", line 841, in MergeFromString
    if self._InternalParse(serialized, 0, length) != length:
  File "/home/rory/.local/lib/python2.7/site-packages/google/protobuf/internal/python_message.py", line 866, in InternalParse
    new_pos = local_SkipField(buffer, new_pos, end, tag_bytes)
  File "/home/rory/.local/lib/python2.7/site-packages/google/protobuf/internal/decoder.py", line 827, in SkipField
    return WIRETYPE_TO_SKIPPER[wire_type](buffer, pos, end)
  File "/home/rory/.local/lib/python2.7/site-packages/google/protobuf/internal/decoder.py", line 797, in _RaiseInvalidWireType
    raise _DecodeError('Tag had invalid wire type.')
google.protobuf.message.DecodeError: Tag had invalid wire type.

protoc命令来自protcol缓冲区库。我从Google的页面(链接到Github)下载了最新版本(2.6.1)并编译了&amp;安装它。 protoc调用就像Tilemaker Makefile does

一样

发生了什么?如何在python中读取此协议缓冲区文件?

更新进一步调查让我觉得我的一个假设可能是错误的。即,tilemaker命令生成了有效的protobuf文件。我得到了一些vector tiles from Mapzen,它应该具有相同的格式和非常相似的数据。 但是此格式适用于python pyread.py命令,以及protoc --decode_rawprotoc --decode=vector_tile.Tile ./include/vector_tile.proto。因此我认为问题在于我正在查看的文件。

1 个答案:

答案 0 :(得分:1)

我认为问题在于OpenStreetMap的.pbf格式不是原始protobuf。请参阅我对您的其他问题的回答:

https://stackoverflow.com/a/35384238/2686899