(見底部更新)無法解析在python一個協議緩衝區文件
Tilemaker是OpenStreetMap程序來生成Mapbox vector tiles(它們本身protocol buffers(PBF)文件)從OSM pbf數據文件。我編譯了它並用它創建了矢量圖塊的目錄。我無法用Python解析這些文件。
我創建的載體瓷磚:
tilemaker input.pbf --output=tiles/
然後,我創建了一個簡單的Python程序,以這種方式基於Google's Protocol Buffers Python Tutorial:
編譯.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
命令從協議型緩衝庫。我從Google的頁面(鏈接到Github)下載了最新版本(2.6.1),並編譯了&安裝它。該protoc調用就像Tilemaker Makefile does一樣。
發生了什麼事?我如何在python中讀取這個協議緩衝區文件?
UPDATE進一步的調查讓我覺得,我的假設之一可能是錯的。也就是說,tilemaker
命令生成了一個有效的protobuf文件。我有一些vector tiles from Mapzen,應該有相同的格式和非常相似的數據。 但是該格式與python pyread.py
命令以及protoc --decode_raw
和protoc --decode=vector_tile.Tile ./include/vector_tile.proto
一起使用。因此,我認爲問題出在我看到的文件上。
是否從OpenStreetMap的protobuffer具有相同的版本作爲protoc用於生成的.py? –
在這個例子中。 Tilemaker程序的Makefile在我的機器上調用'protoc'命令來生成一個'.proto'文件的C++文件。我使用相同的'protoc'二進制文件和相同的'.proto'文件來生成python文件,並且它不起作用。 – Rory
你在Windows上嗎?如果是這樣,您需要以二進制模式打開。 'open(filename,「rb」)'。 (這是在所有系統上執行此操作的好主意,但它只對Windows非常重要。) –