Repository: qedus/osmpbf Branch: master Commit: e13705990962 Files: 20 Total size: 106.0 KB Directory structure: gitextract_2pfet2jd/ ├── .github/ │ ├── dependabot.yml │ └── workflows/ │ └── go.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── OSMPBF/ │ ├── Makefile │ ├── README.md │ ├── fileformat.pb.go │ ├── fileformat.proto │ ├── osmformat.pb.go │ └── osmformat.proto ├── README.md ├── decode.go ├── decode_data.go ├── decode_tag.go ├── decode_test.go ├── example_test.go ├── go.mod └── go.sum ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/dependabot.yml ================================================ --- version: 2 updates: - package-ecosystem: "gomod" directory: "/" schedule: interval: "monthly" - package-ecosystem: "github-actions" directory: "/" schedule: interval: "monthly" ================================================ FILE: .github/workflows/go.yml ================================================ --- name: Go on: push: branches: [master] pull_request: jobs: build: name: Build strategy: fail-fast: false matrix: go: [1.16.x] may-fail: [false] include: - go: tip may-fail: true runs-on: ubuntu-20.04 continue-on-error: ${{ matrix.may-fail }} steps: - name: Checkout code uses: actions/checkout@v3 - name: Setup Go v${{ matrix.go }} if: ${{ matrix.go != 'tip' }} uses: actions/setup-go@v2 with: go-version: ${{ matrix.go }} - name: Setup Go tip if: ${{ matrix.go == 'tip' }} run: | curl -OL https://github.com/AlekSi/golang-tip/releases/download/tip/master.linux-amd64.tar.gz sudo rm -rf /usr/local/go sudo tar -C /usr/local -xzf master.linux-amd64.tar.gz sudo ln -vsf /usr/local/go/bin/* /usr/bin/ sudo ln -vsf /usr/local/go/bin/* /bin/ - name: Run debug commands run: | env which -a go go version go env - name: Install tools run: make init - name: Test with race detector run: make race - name: Gather test coverage run: make cover - name: Upload test coverage report to coveralls.io uses: shogo82148/actions-goveralls@v1.5.1 with: path-to-profile: profile.cov ================================================ FILE: .gitignore ================================================ *.osm *.osm.bz2 *.osm.pbf *.md5 *.out *.test *.txt *.cov ================================================ FILE: CHANGELOG.md ================================================ # Changelog ## v1.2.0 (tagged 2021-05-10) * Converted to Go module. * Updated .proto files ([#35](https://github.com/qedus/osmpbf/pull/35) by Lucas). * Updated protobuf dependency. * Migrated CI to GitHub Actions. ## v1.1.0 (tagged 2018-03-29) * Added [`Decoder.Header()` method](https://pkg.go.dev/github.com/qedus/osmpbf#Decoder.Header) ([#24](https://github.com/qedus/osmpbf/pull/24) by Karsten Klompmaker). * Added support for non-dense Nodes ([#30](https://github.com/qedus/osmpbf/pull/30) by Clyde D'Cruz). * Minor optimizations. ## v1.0.0 (tagged 2017-03-15) * First release with stable public API. ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2014 qedus Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Makefile ================================================ export GORACE := halt_on_error=1 all: cover init: go install -v golang.org/x/perf/cmd/benchstat@latest race: go install -v -race go test -v -race cover: go install -v go test -v -coverprofile=profile.cov bench: env OSMPBF_BENCHMARK_BUFFER=1048576 go test -v -run=NONE -bench=. -benchmem -benchtime=10s -count=5 | tee 01.txt env OSMPBF_BENCHMARK_BUFFER=33554432 go test -v -run=NONE -bench=. -benchmem -benchtime=10s -count=5 | tee 32.txt benchstat 01.txt 32.txt ================================================ FILE: OSMPBF/Makefile ================================================ all: # sync version with ../go.mod go install -v google.golang.org/protobuf/cmd/protoc-gen-go@v1.26.0 rm *.go protoc --go_out=. \ --go_opt=paths=source_relative \ --go_opt=Mfileformat.proto=github.com/qedus/osmpbf/OSMPBF \ --go_opt=Mosmformat.proto=github.com/qedus/osmpbf/OSMPBF \ *.proto ================================================ FILE: OSMPBF/README.md ================================================ # Proto Files `*.proto` files were downloaded from https://github.com/scrosby/OSM-binary/tree/master/src and changed in following ways: ## Changes ### StringTable - **File**: `osmformat.proto` - **Reason**: To eliminate continuous conversions from `[]byte` to `string` - **Old code**: ```protobuf message StringTable { repeated bytes s = 1; } ``` - **New code**: ```protobuf message StringTable { repeated string s = 1; } ``` - **Comptatibility**: This change is expected to be fully compatible with all PBF files. ================================================ FILE: OSMPBF/fileformat.pb.go ================================================ //* Copyright (c) 2010 Scott A. Crosby. // //Permission is hereby granted, free of charge, to any person obtaining a copy of //this software and associated documentation files (the "Software"), to deal in //the Software without restriction, including without limitation the rights to //use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies //of the Software, and to permit persons to whom the Software is furnished to do //so, subject to the following conditions: // //The above copyright notice and this permission notice shall be included in all //copies or substantial portions of the Software. // //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE //SOFTWARE. // // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 // protoc v3.15.8 // source: fileformat.proto package OSMPBF import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) type Blob struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields RawSize *int32 `protobuf:"varint,2,opt,name=raw_size,json=rawSize" json:"raw_size,omitempty"` // When compressed, the uncompressed size // Types that are assignable to Data: // *Blob_Raw // *Blob_ZlibData // *Blob_LzmaData // *Blob_OBSOLETEBzip2Data // *Blob_Lz4Data // *Blob_ZstdData Data isBlob_Data `protobuf_oneof:"data"` } func (x *Blob) Reset() { *x = Blob{} if protoimpl.UnsafeEnabled { mi := &file_fileformat_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Blob) String() string { return protoimpl.X.MessageStringOf(x) } func (*Blob) ProtoMessage() {} func (x *Blob) ProtoReflect() protoreflect.Message { mi := &file_fileformat_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Blob.ProtoReflect.Descriptor instead. func (*Blob) Descriptor() ([]byte, []int) { return file_fileformat_proto_rawDescGZIP(), []int{0} } func (x *Blob) GetRawSize() int32 { if x != nil && x.RawSize != nil { return *x.RawSize } return 0 } func (m *Blob) GetData() isBlob_Data { if m != nil { return m.Data } return nil } func (x *Blob) GetRaw() []byte { if x, ok := x.GetData().(*Blob_Raw); ok { return x.Raw } return nil } func (x *Blob) GetZlibData() []byte { if x, ok := x.GetData().(*Blob_ZlibData); ok { return x.ZlibData } return nil } func (x *Blob) GetLzmaData() []byte { if x, ok := x.GetData().(*Blob_LzmaData); ok { return x.LzmaData } return nil } // Deprecated: Do not use. func (x *Blob) GetOBSOLETEBzip2Data() []byte { if x, ok := x.GetData().(*Blob_OBSOLETEBzip2Data); ok { return x.OBSOLETEBzip2Data } return nil } func (x *Blob) GetLz4Data() []byte { if x, ok := x.GetData().(*Blob_Lz4Data); ok { return x.Lz4Data } return nil } func (x *Blob) GetZstdData() []byte { if x, ok := x.GetData().(*Blob_ZstdData); ok { return x.ZstdData } return nil } type isBlob_Data interface { isBlob_Data() } type Blob_Raw struct { Raw []byte `protobuf:"bytes,1,opt,name=raw,oneof"` // No compression } type Blob_ZlibData struct { // Possible compressed versions of the data. ZlibData []byte `protobuf:"bytes,3,opt,name=zlib_data,json=zlibData,oneof"` } type Blob_LzmaData struct { // For LZMA compressed data (optional) LzmaData []byte `protobuf:"bytes,4,opt,name=lzma_data,json=lzmaData,oneof"` } type Blob_OBSOLETEBzip2Data struct { // Formerly used for bzip2 compressed data. Deprecated in 2010. // // Deprecated: Do not use. OBSOLETEBzip2Data []byte `protobuf:"bytes,5,opt,name=OBSOLETE_bzip2_data,json=OBSOLETEBzip2Data,oneof"` // Don't reuse this tag number. } type Blob_Lz4Data struct { // For LZ4 compressed data (optional) Lz4Data []byte `protobuf:"bytes,6,opt,name=lz4_data,json=lz4Data,oneof"` } type Blob_ZstdData struct { // For ZSTD compressed data (optional) ZstdData []byte `protobuf:"bytes,7,opt,name=zstd_data,json=zstdData,oneof"` } func (*Blob_Raw) isBlob_Data() {} func (*Blob_ZlibData) isBlob_Data() {} func (*Blob_LzmaData) isBlob_Data() {} func (*Blob_OBSOLETEBzip2Data) isBlob_Data() {} func (*Blob_Lz4Data) isBlob_Data() {} func (*Blob_ZstdData) isBlob_Data() {} type BlobHeader struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Type *string `protobuf:"bytes,1,req,name=type" json:"type,omitempty"` Indexdata []byte `protobuf:"bytes,2,opt,name=indexdata" json:"indexdata,omitempty"` Datasize *int32 `protobuf:"varint,3,req,name=datasize" json:"datasize,omitempty"` } func (x *BlobHeader) Reset() { *x = BlobHeader{} if protoimpl.UnsafeEnabled { mi := &file_fileformat_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *BlobHeader) String() string { return protoimpl.X.MessageStringOf(x) } func (*BlobHeader) ProtoMessage() {} func (x *BlobHeader) ProtoReflect() protoreflect.Message { mi := &file_fileformat_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use BlobHeader.ProtoReflect.Descriptor instead. func (*BlobHeader) Descriptor() ([]byte, []int) { return file_fileformat_proto_rawDescGZIP(), []int{1} } func (x *BlobHeader) GetType() string { if x != nil && x.Type != nil { return *x.Type } return "" } func (x *BlobHeader) GetIndexdata() []byte { if x != nil { return x.Indexdata } return nil } func (x *BlobHeader) GetDatasize() int32 { if x != nil && x.Datasize != nil { return *x.Datasize } return 0 } var File_fileformat_proto protoreflect.FileDescriptor var file_fileformat_proto_rawDesc = []byte{ 0x0a, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x22, 0xed, 0x01, 0x0a, 0x04, 0x42, 0x6c, 0x6f, 0x62, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x61, 0x77, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 0x61, 0x77, 0x12, 0x1d, 0x0a, 0x09, 0x7a, 0x6c, 0x69, 0x62, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x7a, 0x6c, 0x69, 0x62, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x09, 0x6c, 0x7a, 0x6d, 0x61, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x6c, 0x7a, 0x6d, 0x61, 0x44, 0x61, 0x74, 0x61, 0x12, 0x34, 0x0a, 0x13, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x62, 0x7a, 0x69, 0x70, 0x32, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x02, 0x18, 0x01, 0x48, 0x00, 0x52, 0x11, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x42, 0x7a, 0x69, 0x70, 0x32, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x7a, 0x34, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x7a, 0x34, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x09, 0x7a, 0x73, 0x74, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x7a, 0x73, 0x74, 0x64, 0x44, 0x61, 0x74, 0x61, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x5a, 0x0a, 0x0a, 0x42, 0x6c, 0x6f, 0x62, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x02, 0x28, 0x05, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x0f, 0x0a, 0x0d, 0x63, 0x72, 0x6f, 0x73, 0x62, 0x79, 0x2e, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, } var ( file_fileformat_proto_rawDescOnce sync.Once file_fileformat_proto_rawDescData = file_fileformat_proto_rawDesc ) func file_fileformat_proto_rawDescGZIP() []byte { file_fileformat_proto_rawDescOnce.Do(func() { file_fileformat_proto_rawDescData = protoimpl.X.CompressGZIP(file_fileformat_proto_rawDescData) }) return file_fileformat_proto_rawDescData } var file_fileformat_proto_msgTypes = make([]protoimpl.MessageInfo, 2) var file_fileformat_proto_goTypes = []interface{}{ (*Blob)(nil), // 0: OSMPBF.Blob (*BlobHeader)(nil), // 1: OSMPBF.BlobHeader } var file_fileformat_proto_depIdxs = []int32{ 0, // [0:0] is the sub-list for method output_type 0, // [0:0] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name } func init() { file_fileformat_proto_init() } func file_fileformat_proto_init() { if File_fileformat_proto != nil { return } if !protoimpl.UnsafeEnabled { file_fileformat_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Blob); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_fileformat_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BlobHeader); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } } file_fileformat_proto_msgTypes[0].OneofWrappers = []interface{}{ (*Blob_Raw)(nil), (*Blob_ZlibData)(nil), (*Blob_LzmaData)(nil), (*Blob_OBSOLETEBzip2Data)(nil), (*Blob_Lz4Data)(nil), (*Blob_ZstdData)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_fileformat_proto_rawDesc, NumEnums: 0, NumMessages: 2, NumExtensions: 0, NumServices: 0, }, GoTypes: file_fileformat_proto_goTypes, DependencyIndexes: file_fileformat_proto_depIdxs, MessageInfos: file_fileformat_proto_msgTypes, }.Build() File_fileformat_proto = out.File file_fileformat_proto_rawDesc = nil file_fileformat_proto_goTypes = nil file_fileformat_proto_depIdxs = nil } ================================================ FILE: OSMPBF/fileformat.proto ================================================ /** Copyright (c) 2010 Scott A. Crosby. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ syntax = "proto2"; option java_package = "crosby.binary"; package OSMPBF; //protoc --java_out=../.. fileformat.proto // // STORAGE LAYER: Storing primitives. // message Blob { optional int32 raw_size = 2; // When compressed, the uncompressed size oneof data { bytes raw = 1; // No compression // Possible compressed versions of the data. bytes zlib_data = 3; // For LZMA compressed data (optional) bytes lzma_data = 4; // Formerly used for bzip2 compressed data. Deprecated in 2010. bytes OBSOLETE_bzip2_data = 5 [deprecated=true]; // Don't reuse this tag number. // For LZ4 compressed data (optional) bytes lz4_data = 6; // For ZSTD compressed data (optional) bytes zstd_data = 7; } } /* A file contains an sequence of fileblock headers, each prefixed by their length in network byte order, followed by a data block containing the actual data. Types starting with a "_" are reserved. */ message BlobHeader { required string type = 1; optional bytes indexdata = 2; required int32 datasize = 3; } ================================================ FILE: OSMPBF/osmformat.pb.go ================================================ //* Copyright (c) 2010 Scott A. Crosby. // //Permission is hereby granted, free of charge, to any person obtaining a copy of //this software and associated documentation files (the "Software"), to deal in //the Software without restriction, including without limitation the rights to //use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies //of the Software, and to permit persons to whom the Software is furnished to do //so, subject to the following conditions: // //The above copyright notice and this permission notice shall be included in all //copies or substantial portions of the Software. // //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE //SOFTWARE. // // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.26.0 // protoc v3.15.8 // source: osmformat.proto package OSMPBF import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" ) const ( // Verify that this generated code is sufficiently up-to-date. _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) // Verify that runtime/protoimpl is sufficiently up-to-date. _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) type Relation_MemberType int32 const ( Relation_NODE Relation_MemberType = 0 Relation_WAY Relation_MemberType = 1 Relation_RELATION Relation_MemberType = 2 ) // Enum value maps for Relation_MemberType. var ( Relation_MemberType_name = map[int32]string{ 0: "NODE", 1: "WAY", 2: "RELATION", } Relation_MemberType_value = map[string]int32{ "NODE": 0, "WAY": 1, "RELATION": 2, } ) func (x Relation_MemberType) Enum() *Relation_MemberType { p := new(Relation_MemberType) *p = x return p } func (x Relation_MemberType) String() string { return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) } func (Relation_MemberType) Descriptor() protoreflect.EnumDescriptor { return file_osmformat_proto_enumTypes[0].Descriptor() } func (Relation_MemberType) Type() protoreflect.EnumType { return &file_osmformat_proto_enumTypes[0] } func (x Relation_MemberType) Number() protoreflect.EnumNumber { return protoreflect.EnumNumber(x) } // Deprecated: Do not use. func (x *Relation_MemberType) UnmarshalJSON(b []byte) error { num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) if err != nil { return err } *x = Relation_MemberType(num) return nil } // Deprecated: Use Relation_MemberType.Descriptor instead. func (Relation_MemberType) EnumDescriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{11, 0} } type HeaderBlock struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Bbox *HeaderBBox `protobuf:"bytes,1,opt,name=bbox" json:"bbox,omitempty"` // Additional tags to aid in parsing this dataset RequiredFeatures []string `protobuf:"bytes,4,rep,name=required_features,json=requiredFeatures" json:"required_features,omitempty"` OptionalFeatures []string `protobuf:"bytes,5,rep,name=optional_features,json=optionalFeatures" json:"optional_features,omitempty"` Writingprogram *string `protobuf:"bytes,16,opt,name=writingprogram" json:"writingprogram,omitempty"` Source *string `protobuf:"bytes,17,opt,name=source" json:"source,omitempty"` // From the bbox field. // Replication timestamp, expressed in seconds since the epoch, // otherwise the same value as in the "timestamp=..." field // in the state.txt file used by Osmosis. OsmosisReplicationTimestamp *int64 `protobuf:"varint,32,opt,name=osmosis_replication_timestamp,json=osmosisReplicationTimestamp" json:"osmosis_replication_timestamp,omitempty"` // Replication sequence number (sequenceNumber in state.txt). OsmosisReplicationSequenceNumber *int64 `protobuf:"varint,33,opt,name=osmosis_replication_sequence_number,json=osmosisReplicationSequenceNumber" json:"osmosis_replication_sequence_number,omitempty"` // Replication base URL (from Osmosis' configuration.txt file). OsmosisReplicationBaseUrl *string `protobuf:"bytes,34,opt,name=osmosis_replication_base_url,json=osmosisReplicationBaseUrl" json:"osmosis_replication_base_url,omitempty"` } func (x *HeaderBlock) Reset() { *x = HeaderBlock{} if protoimpl.UnsafeEnabled { mi := &file_osmformat_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *HeaderBlock) String() string { return protoimpl.X.MessageStringOf(x) } func (*HeaderBlock) ProtoMessage() {} func (x *HeaderBlock) ProtoReflect() protoreflect.Message { mi := &file_osmformat_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use HeaderBlock.ProtoReflect.Descriptor instead. func (*HeaderBlock) Descriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{0} } func (x *HeaderBlock) GetBbox() *HeaderBBox { if x != nil { return x.Bbox } return nil } func (x *HeaderBlock) GetRequiredFeatures() []string { if x != nil { return x.RequiredFeatures } return nil } func (x *HeaderBlock) GetOptionalFeatures() []string { if x != nil { return x.OptionalFeatures } return nil } func (x *HeaderBlock) GetWritingprogram() string { if x != nil && x.Writingprogram != nil { return *x.Writingprogram } return "" } func (x *HeaderBlock) GetSource() string { if x != nil && x.Source != nil { return *x.Source } return "" } func (x *HeaderBlock) GetOsmosisReplicationTimestamp() int64 { if x != nil && x.OsmosisReplicationTimestamp != nil { return *x.OsmosisReplicationTimestamp } return 0 } func (x *HeaderBlock) GetOsmosisReplicationSequenceNumber() int64 { if x != nil && x.OsmosisReplicationSequenceNumber != nil { return *x.OsmosisReplicationSequenceNumber } return 0 } func (x *HeaderBlock) GetOsmosisReplicationBaseUrl() string { if x != nil && x.OsmosisReplicationBaseUrl != nil { return *x.OsmosisReplicationBaseUrl } return "" } type HeaderBBox struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Left *int64 `protobuf:"zigzag64,1,req,name=left" json:"left,omitempty"` Right *int64 `protobuf:"zigzag64,2,req,name=right" json:"right,omitempty"` Top *int64 `protobuf:"zigzag64,3,req,name=top" json:"top,omitempty"` Bottom *int64 `protobuf:"zigzag64,4,req,name=bottom" json:"bottom,omitempty"` } func (x *HeaderBBox) Reset() { *x = HeaderBBox{} if protoimpl.UnsafeEnabled { mi := &file_osmformat_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *HeaderBBox) String() string { return protoimpl.X.MessageStringOf(x) } func (*HeaderBBox) ProtoMessage() {} func (x *HeaderBBox) ProtoReflect() protoreflect.Message { mi := &file_osmformat_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use HeaderBBox.ProtoReflect.Descriptor instead. func (*HeaderBBox) Descriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{1} } func (x *HeaderBBox) GetLeft() int64 { if x != nil && x.Left != nil { return *x.Left } return 0 } func (x *HeaderBBox) GetRight() int64 { if x != nil && x.Right != nil { return *x.Right } return 0 } func (x *HeaderBBox) GetTop() int64 { if x != nil && x.Top != nil { return *x.Top } return 0 } func (x *HeaderBBox) GetBottom() int64 { if x != nil && x.Bottom != nil { return *x.Bottom } return 0 } type PrimitiveBlock struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Stringtable *StringTable `protobuf:"bytes,1,req,name=stringtable" json:"stringtable,omitempty"` Primitivegroup []*PrimitiveGroup `protobuf:"bytes,2,rep,name=primitivegroup" json:"primitivegroup,omitempty"` // Granularity, units of nanodegrees, used to store coordinates in this block. Granularity *int32 `protobuf:"varint,17,opt,name=granularity,def=100" json:"granularity,omitempty"` // Offset value between the output coordinates and the granularity grid in units of nanodegrees. LatOffset *int64 `protobuf:"varint,19,opt,name=lat_offset,json=latOffset,def=0" json:"lat_offset,omitempty"` LonOffset *int64 `protobuf:"varint,20,opt,name=lon_offset,json=lonOffset,def=0" json:"lon_offset,omitempty"` // Granularity of dates, normally represented in units of milliseconds since the 1970 epoch. DateGranularity *int32 `protobuf:"varint,18,opt,name=date_granularity,json=dateGranularity,def=1000" json:"date_granularity,omitempty"` } // Default values for PrimitiveBlock fields. const ( Default_PrimitiveBlock_Granularity = int32(100) Default_PrimitiveBlock_LatOffset = int64(0) Default_PrimitiveBlock_LonOffset = int64(0) Default_PrimitiveBlock_DateGranularity = int32(1000) ) func (x *PrimitiveBlock) Reset() { *x = PrimitiveBlock{} if protoimpl.UnsafeEnabled { mi := &file_osmformat_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *PrimitiveBlock) String() string { return protoimpl.X.MessageStringOf(x) } func (*PrimitiveBlock) ProtoMessage() {} func (x *PrimitiveBlock) ProtoReflect() protoreflect.Message { mi := &file_osmformat_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use PrimitiveBlock.ProtoReflect.Descriptor instead. func (*PrimitiveBlock) Descriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{2} } func (x *PrimitiveBlock) GetStringtable() *StringTable { if x != nil { return x.Stringtable } return nil } func (x *PrimitiveBlock) GetPrimitivegroup() []*PrimitiveGroup { if x != nil { return x.Primitivegroup } return nil } func (x *PrimitiveBlock) GetGranularity() int32 { if x != nil && x.Granularity != nil { return *x.Granularity } return Default_PrimitiveBlock_Granularity } func (x *PrimitiveBlock) GetLatOffset() int64 { if x != nil && x.LatOffset != nil { return *x.LatOffset } return Default_PrimitiveBlock_LatOffset } func (x *PrimitiveBlock) GetLonOffset() int64 { if x != nil && x.LonOffset != nil { return *x.LonOffset } return Default_PrimitiveBlock_LonOffset } func (x *PrimitiveBlock) GetDateGranularity() int32 { if x != nil && x.DateGranularity != nil { return *x.DateGranularity } return Default_PrimitiveBlock_DateGranularity } // Group of OSMPrimitives. All primitives in a group must be the same type. type PrimitiveGroup struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Nodes []*Node `protobuf:"bytes,1,rep,name=nodes" json:"nodes,omitempty"` Dense *DenseNodes `protobuf:"bytes,2,opt,name=dense" json:"dense,omitempty"` Ways []*Way `protobuf:"bytes,3,rep,name=ways" json:"ways,omitempty"` Relations []*Relation `protobuf:"bytes,4,rep,name=relations" json:"relations,omitempty"` Changesets []*ChangeSet `protobuf:"bytes,5,rep,name=changesets" json:"changesets,omitempty"` } func (x *PrimitiveGroup) Reset() { *x = PrimitiveGroup{} if protoimpl.UnsafeEnabled { mi := &file_osmformat_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *PrimitiveGroup) String() string { return protoimpl.X.MessageStringOf(x) } func (*PrimitiveGroup) ProtoMessage() {} func (x *PrimitiveGroup) ProtoReflect() protoreflect.Message { mi := &file_osmformat_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use PrimitiveGroup.ProtoReflect.Descriptor instead. func (*PrimitiveGroup) Descriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{3} } func (x *PrimitiveGroup) GetNodes() []*Node { if x != nil { return x.Nodes } return nil } func (x *PrimitiveGroup) GetDense() *DenseNodes { if x != nil { return x.Dense } return nil } func (x *PrimitiveGroup) GetWays() []*Way { if x != nil { return x.Ways } return nil } func (x *PrimitiveGroup) GetRelations() []*Relation { if x != nil { return x.Relations } return nil } func (x *PrimitiveGroup) GetChangesets() []*ChangeSet { if x != nil { return x.Changesets } return nil } //* String table, contains the common strings in each block. // //Note that we reserve index '0' as a delimiter, so the entry at that //index in the table is ALWAYS blank and unused. // type StringTable struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields S []string `protobuf:"bytes,1,rep,name=s" json:"s,omitempty"` } func (x *StringTable) Reset() { *x = StringTable{} if protoimpl.UnsafeEnabled { mi := &file_osmformat_proto_msgTypes[4] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *StringTable) String() string { return protoimpl.X.MessageStringOf(x) } func (*StringTable) ProtoMessage() {} func (x *StringTable) ProtoReflect() protoreflect.Message { mi := &file_osmformat_proto_msgTypes[4] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use StringTable.ProtoReflect.Descriptor instead. func (*StringTable) Descriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{4} } func (x *StringTable) GetS() []string { if x != nil { return x.S } return nil } // Optional metadata that may be included into each primitive. type Info struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Version *int32 `protobuf:"varint,1,opt,name=version,def=-1" json:"version,omitempty"` Timestamp *int64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` Changeset *int64 `protobuf:"varint,3,opt,name=changeset" json:"changeset,omitempty"` Uid *int32 `protobuf:"varint,4,opt,name=uid" json:"uid,omitempty"` UserSid *uint32 `protobuf:"varint,5,opt,name=user_sid,json=userSid" json:"user_sid,omitempty"` // String IDs // The visible flag is used to store history information. It indicates that // the current object version has been created by a delete operation on the // OSM API. // When a writer sets this flag, it MUST add a required_features tag with // value "HistoricalInformation" to the HeaderBlock. // If this flag is not available for some object it MUST be assumed to be // true if the file has the required_features tag "HistoricalInformation" // set. Visible *bool `protobuf:"varint,6,opt,name=visible" json:"visible,omitempty"` } // Default values for Info fields. const ( Default_Info_Version = int32(-1) ) func (x *Info) Reset() { *x = Info{} if protoimpl.UnsafeEnabled { mi := &file_osmformat_proto_msgTypes[5] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Info) String() string { return protoimpl.X.MessageStringOf(x) } func (*Info) ProtoMessage() {} func (x *Info) ProtoReflect() protoreflect.Message { mi := &file_osmformat_proto_msgTypes[5] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Info.ProtoReflect.Descriptor instead. func (*Info) Descriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{5} } func (x *Info) GetVersion() int32 { if x != nil && x.Version != nil { return *x.Version } return Default_Info_Version } func (x *Info) GetTimestamp() int64 { if x != nil && x.Timestamp != nil { return *x.Timestamp } return 0 } func (x *Info) GetChangeset() int64 { if x != nil && x.Changeset != nil { return *x.Changeset } return 0 } func (x *Info) GetUid() int32 { if x != nil && x.Uid != nil { return *x.Uid } return 0 } func (x *Info) GetUserSid() uint32 { if x != nil && x.UserSid != nil { return *x.UserSid } return 0 } func (x *Info) GetVisible() bool { if x != nil && x.Visible != nil { return *x.Visible } return false } //* Optional metadata that may be included into each primitive. Special dense format used in DenseNodes. type DenseInfo struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Version []int32 `protobuf:"varint,1,rep,packed,name=version" json:"version,omitempty"` Timestamp []int64 `protobuf:"zigzag64,2,rep,packed,name=timestamp" json:"timestamp,omitempty"` // DELTA coded Changeset []int64 `protobuf:"zigzag64,3,rep,packed,name=changeset" json:"changeset,omitempty"` // DELTA coded Uid []int32 `protobuf:"zigzag32,4,rep,packed,name=uid" json:"uid,omitempty"` // DELTA coded UserSid []int32 `protobuf:"zigzag32,5,rep,packed,name=user_sid,json=userSid" json:"user_sid,omitempty"` // String IDs for usernames. DELTA coded // The visible flag is used to store history information. It indicates that // the current object version has been created by a delete operation on the // OSM API. // When a writer sets this flag, it MUST add a required_features tag with // value "HistoricalInformation" to the HeaderBlock. // If this flag is not available for some object it MUST be assumed to be // true if the file has the required_features tag "HistoricalInformation" // set. Visible []bool `protobuf:"varint,6,rep,packed,name=visible" json:"visible,omitempty"` } func (x *DenseInfo) Reset() { *x = DenseInfo{} if protoimpl.UnsafeEnabled { mi := &file_osmformat_proto_msgTypes[6] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *DenseInfo) String() string { return protoimpl.X.MessageStringOf(x) } func (*DenseInfo) ProtoMessage() {} func (x *DenseInfo) ProtoReflect() protoreflect.Message { mi := &file_osmformat_proto_msgTypes[6] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use DenseInfo.ProtoReflect.Descriptor instead. func (*DenseInfo) Descriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{6} } func (x *DenseInfo) GetVersion() []int32 { if x != nil { return x.Version } return nil } func (x *DenseInfo) GetTimestamp() []int64 { if x != nil { return x.Timestamp } return nil } func (x *DenseInfo) GetChangeset() []int64 { if x != nil { return x.Changeset } return nil } func (x *DenseInfo) GetUid() []int32 { if x != nil { return x.Uid } return nil } func (x *DenseInfo) GetUserSid() []int32 { if x != nil { return x.UserSid } return nil } func (x *DenseInfo) GetVisible() []bool { if x != nil { return x.Visible } return nil } // This is kept for backwards compatibility but not used anywhere. type ChangeSet struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Id *int64 `protobuf:"varint,1,req,name=id" json:"id,omitempty"` } func (x *ChangeSet) Reset() { *x = ChangeSet{} if protoimpl.UnsafeEnabled { mi := &file_osmformat_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *ChangeSet) String() string { return protoimpl.X.MessageStringOf(x) } func (*ChangeSet) ProtoMessage() {} func (x *ChangeSet) ProtoReflect() protoreflect.Message { mi := &file_osmformat_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use ChangeSet.ProtoReflect.Descriptor instead. func (*ChangeSet) Descriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{7} } func (x *ChangeSet) GetId() int64 { if x != nil && x.Id != nil { return *x.Id } return 0 } type Node struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Id *int64 `protobuf:"zigzag64,1,req,name=id" json:"id,omitempty"` // Parallel arrays. Keys []uint32 `protobuf:"varint,2,rep,packed,name=keys" json:"keys,omitempty"` // String IDs. Vals []uint32 `protobuf:"varint,3,rep,packed,name=vals" json:"vals,omitempty"` // String IDs. Info *Info `protobuf:"bytes,4,opt,name=info" json:"info,omitempty"` // May be omitted in omitmeta Lat *int64 `protobuf:"zigzag64,8,req,name=lat" json:"lat,omitempty"` Lon *int64 `protobuf:"zigzag64,9,req,name=lon" json:"lon,omitempty"` } func (x *Node) Reset() { *x = Node{} if protoimpl.UnsafeEnabled { mi := &file_osmformat_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Node) String() string { return protoimpl.X.MessageStringOf(x) } func (*Node) ProtoMessage() {} func (x *Node) ProtoReflect() protoreflect.Message { mi := &file_osmformat_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Node.ProtoReflect.Descriptor instead. func (*Node) Descriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{8} } func (x *Node) GetId() int64 { if x != nil && x.Id != nil { return *x.Id } return 0 } func (x *Node) GetKeys() []uint32 { if x != nil { return x.Keys } return nil } func (x *Node) GetVals() []uint32 { if x != nil { return x.Vals } return nil } func (x *Node) GetInfo() *Info { if x != nil { return x.Info } return nil } func (x *Node) GetLat() int64 { if x != nil && x.Lat != nil { return *x.Lat } return 0 } func (x *Node) GetLon() int64 { if x != nil && x.Lon != nil { return *x.Lon } return 0 } type DenseNodes struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Id []int64 `protobuf:"zigzag64,1,rep,packed,name=id" json:"id,omitempty"` // DELTA coded Denseinfo *DenseInfo `protobuf:"bytes,5,opt,name=denseinfo" json:"denseinfo,omitempty"` Lat []int64 `protobuf:"zigzag64,8,rep,packed,name=lat" json:"lat,omitempty"` // DELTA coded Lon []int64 `protobuf:"zigzag64,9,rep,packed,name=lon" json:"lon,omitempty"` // DELTA coded // Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless. KeysVals []int32 `protobuf:"varint,10,rep,packed,name=keys_vals,json=keysVals" json:"keys_vals,omitempty"` } func (x *DenseNodes) Reset() { *x = DenseNodes{} if protoimpl.UnsafeEnabled { mi := &file_osmformat_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *DenseNodes) String() string { return protoimpl.X.MessageStringOf(x) } func (*DenseNodes) ProtoMessage() {} func (x *DenseNodes) ProtoReflect() protoreflect.Message { mi := &file_osmformat_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use DenseNodes.ProtoReflect.Descriptor instead. func (*DenseNodes) Descriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{9} } func (x *DenseNodes) GetId() []int64 { if x != nil { return x.Id } return nil } func (x *DenseNodes) GetDenseinfo() *DenseInfo { if x != nil { return x.Denseinfo } return nil } func (x *DenseNodes) GetLat() []int64 { if x != nil { return x.Lat } return nil } func (x *DenseNodes) GetLon() []int64 { if x != nil { return x.Lon } return nil } func (x *DenseNodes) GetKeysVals() []int32 { if x != nil { return x.KeysVals } return nil } type Way struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Id *int64 `protobuf:"varint,1,req,name=id" json:"id,omitempty"` // Parallel arrays. Keys []uint32 `protobuf:"varint,2,rep,packed,name=keys" json:"keys,omitempty"` Vals []uint32 `protobuf:"varint,3,rep,packed,name=vals" json:"vals,omitempty"` Info *Info `protobuf:"bytes,4,opt,name=info" json:"info,omitempty"` Refs []int64 `protobuf:"zigzag64,8,rep,packed,name=refs" json:"refs,omitempty"` // DELTA coded // The following two fields are optional. They are only used in a special // format where node locations are also added to the ways. This makes the // files larger, but allows creating way geometries directly. // // If this is used, you MUST set the optional_features tag "LocationsOnWays" // and the number of values in refs, lat, and lon MUST be the same. Lat []int64 `protobuf:"zigzag64,9,rep,packed,name=lat" json:"lat,omitempty"` // DELTA coded, optional Lon []int64 `protobuf:"zigzag64,10,rep,packed,name=lon" json:"lon,omitempty"` // DELTA coded, optional } func (x *Way) Reset() { *x = Way{} if protoimpl.UnsafeEnabled { mi := &file_osmformat_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Way) String() string { return protoimpl.X.MessageStringOf(x) } func (*Way) ProtoMessage() {} func (x *Way) ProtoReflect() protoreflect.Message { mi := &file_osmformat_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Way.ProtoReflect.Descriptor instead. func (*Way) Descriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{10} } func (x *Way) GetId() int64 { if x != nil && x.Id != nil { return *x.Id } return 0 } func (x *Way) GetKeys() []uint32 { if x != nil { return x.Keys } return nil } func (x *Way) GetVals() []uint32 { if x != nil { return x.Vals } return nil } func (x *Way) GetInfo() *Info { if x != nil { return x.Info } return nil } func (x *Way) GetRefs() []int64 { if x != nil { return x.Refs } return nil } func (x *Way) GetLat() []int64 { if x != nil { return x.Lat } return nil } func (x *Way) GetLon() []int64 { if x != nil { return x.Lon } return nil } type Relation struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields Id *int64 `protobuf:"varint,1,req,name=id" json:"id,omitempty"` // Parallel arrays. Keys []uint32 `protobuf:"varint,2,rep,packed,name=keys" json:"keys,omitempty"` Vals []uint32 `protobuf:"varint,3,rep,packed,name=vals" json:"vals,omitempty"` Info *Info `protobuf:"bytes,4,opt,name=info" json:"info,omitempty"` // Parallel arrays RolesSid []int32 `protobuf:"varint,8,rep,packed,name=roles_sid,json=rolesSid" json:"roles_sid,omitempty"` // This should have been defined as uint32 for consistency, but it is now too late to change it Memids []int64 `protobuf:"zigzag64,9,rep,packed,name=memids" json:"memids,omitempty"` // DELTA encoded Types []Relation_MemberType `protobuf:"varint,10,rep,packed,name=types,enum=OSMPBF.Relation_MemberType" json:"types,omitempty"` } func (x *Relation) Reset() { *x = Relation{} if protoimpl.UnsafeEnabled { mi := &file_osmformat_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } func (x *Relation) String() string { return protoimpl.X.MessageStringOf(x) } func (*Relation) ProtoMessage() {} func (x *Relation) ProtoReflect() protoreflect.Message { mi := &file_osmformat_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) } return ms } return mi.MessageOf(x) } // Deprecated: Use Relation.ProtoReflect.Descriptor instead. func (*Relation) Descriptor() ([]byte, []int) { return file_osmformat_proto_rawDescGZIP(), []int{11} } func (x *Relation) GetId() int64 { if x != nil && x.Id != nil { return *x.Id } return 0 } func (x *Relation) GetKeys() []uint32 { if x != nil { return x.Keys } return nil } func (x *Relation) GetVals() []uint32 { if x != nil { return x.Vals } return nil } func (x *Relation) GetInfo() *Info { if x != nil { return x.Info } return nil } func (x *Relation) GetRolesSid() []int32 { if x != nil { return x.RolesSid } return nil } func (x *Relation) GetMemids() []int64 { if x != nil { return x.Memids } return nil } func (x *Relation) GetTypes() []Relation_MemberType { if x != nil { return x.Types } return nil } var File_osmformat_proto protoreflect.FileDescriptor var file_osmformat_proto_rawDesc = []byte{ 0x0a, 0x0f, 0x6f, 0x73, 0x6d, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x22, 0xa3, 0x03, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x26, 0x0a, 0x04, 0x62, 0x62, 0x6f, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x42, 0x6f, 0x78, 0x52, 0x04, 0x62, 0x62, 0x6f, 0x78, 0x12, 0x2b, 0x0a, 0x11, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x11, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x18, 0x10, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x42, 0x0a, 0x1d, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x20, 0x20, 0x01, 0x28, 0x03, 0x52, 0x1b, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x4d, 0x0a, 0x23, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x21, 0x20, 0x01, 0x28, 0x03, 0x52, 0x20, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x3f, 0x0a, 0x1c, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x22, 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x22, 0x60, 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x42, 0x6f, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x65, 0x66, 0x74, 0x18, 0x01, 0x20, 0x02, 0x28, 0x12, 0x52, 0x04, 0x6c, 0x65, 0x66, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x02, 0x28, 0x12, 0x52, 0x05, 0x72, 0x69, 0x67, 0x68, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x6f, 0x70, 0x18, 0x03, 0x20, 0x02, 0x28, 0x12, 0x52, 0x03, 0x74, 0x6f, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x02, 0x28, 0x12, 0x52, 0x06, 0x62, 0x6f, 0x74, 0x74, 0x6f, 0x6d, 0x22, 0xa3, 0x02, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x35, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x3e, 0x0a, 0x0e, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0e, 0x70, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x25, 0x0a, 0x0b, 0x67, 0x72, 0x61, 0x6e, 0x75, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 0x3a, 0x03, 0x31, 0x30, 0x30, 0x52, 0x0b, 0x67, 0x72, 0x61, 0x6e, 0x75, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x12, 0x20, 0x0a, 0x0a, 0x6c, 0x61, 0x74, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x3a, 0x01, 0x30, 0x52, 0x09, 0x6c, 0x61, 0x74, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x20, 0x0a, 0x0a, 0x6c, 0x6f, 0x6e, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x3a, 0x01, 0x30, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x2f, 0x0a, 0x10, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x75, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 0x3a, 0x04, 0x31, 0x30, 0x30, 0x30, 0x52, 0x0f, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x75, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x22, 0xe2, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x22, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x28, 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x44, 0x65, 0x6e, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x52, 0x05, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x77, 0x61, 0x79, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x57, 0x61, 0x79, 0x52, 0x04, 0x77, 0x61, 0x79, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x52, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x73, 0x22, 0x1b, 0x0a, 0x0b, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x01, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x3a, 0x02, 0x2d, 0x31, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x53, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x22, 0xc0, 0x01, 0x0a, 0x09, 0x44, 0x65, 0x6e, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x20, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x11, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x64, 0x18, 0x05, 0x20, 0x03, 0x28, 0x11, 0x42, 0x02, 0x10, 0x01, 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x53, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x07, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x08, 0x42, 0x02, 0x10, 0x01, 0x52, 0x07, 0x76, 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x1b, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x22, 0x8c, 0x01, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x12, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x0a, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x20, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x61, 0x74, 0x18, 0x08, 0x20, 0x02, 0x28, 0x12, 0x52, 0x03, 0x6c, 0x61, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x02, 0x28, 0x12, 0x52, 0x03, 0x6c, 0x6f, 0x6e, 0x22, 0x9e, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6e, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x12, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x09, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x44, 0x65, 0x6e, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x03, 0x6c, 0x61, 0x74, 0x18, 0x08, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6c, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x03, 0x6c, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6c, 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x56, 0x61, 0x6c, 0x73, 0x22, 0xab, 0x01, 0x0a, 0x03, 0x57, 0x61, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x0a, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x20, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x04, 0x72, 0x65, 0x66, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x72, 0x65, 0x66, 0x73, 0x12, 0x14, 0x0a, 0x03, 0x6c, 0x61, 0x74, 0x18, 0x09, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6c, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x03, 0x6c, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6c, 0x6f, 0x6e, 0x22, 0x8f, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x0a, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x20, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x1f, 0x0a, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x5f, 0x73, 0x69, 0x64, 0x18, 0x08, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x53, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x69, 0x64, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x69, 0x64, 0x73, 0x12, 0x35, 0x0a, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x42, 0x02, 0x10, 0x01, 0x52, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x22, 0x2d, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x57, 0x41, 0x59, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x4c, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x10, 0x02, 0x42, 0x0f, 0x0a, 0x0d, 0x63, 0x72, 0x6f, 0x73, 0x62, 0x79, 0x2e, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, } var ( file_osmformat_proto_rawDescOnce sync.Once file_osmformat_proto_rawDescData = file_osmformat_proto_rawDesc ) func file_osmformat_proto_rawDescGZIP() []byte { file_osmformat_proto_rawDescOnce.Do(func() { file_osmformat_proto_rawDescData = protoimpl.X.CompressGZIP(file_osmformat_proto_rawDescData) }) return file_osmformat_proto_rawDescData } var file_osmformat_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_osmformat_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_osmformat_proto_goTypes = []interface{}{ (Relation_MemberType)(0), // 0: OSMPBF.Relation.MemberType (*HeaderBlock)(nil), // 1: OSMPBF.HeaderBlock (*HeaderBBox)(nil), // 2: OSMPBF.HeaderBBox (*PrimitiveBlock)(nil), // 3: OSMPBF.PrimitiveBlock (*PrimitiveGroup)(nil), // 4: OSMPBF.PrimitiveGroup (*StringTable)(nil), // 5: OSMPBF.StringTable (*Info)(nil), // 6: OSMPBF.Info (*DenseInfo)(nil), // 7: OSMPBF.DenseInfo (*ChangeSet)(nil), // 8: OSMPBF.ChangeSet (*Node)(nil), // 9: OSMPBF.Node (*DenseNodes)(nil), // 10: OSMPBF.DenseNodes (*Way)(nil), // 11: OSMPBF.Way (*Relation)(nil), // 12: OSMPBF.Relation } var file_osmformat_proto_depIdxs = []int32{ 2, // 0: OSMPBF.HeaderBlock.bbox:type_name -> OSMPBF.HeaderBBox 5, // 1: OSMPBF.PrimitiveBlock.stringtable:type_name -> OSMPBF.StringTable 4, // 2: OSMPBF.PrimitiveBlock.primitivegroup:type_name -> OSMPBF.PrimitiveGroup 9, // 3: OSMPBF.PrimitiveGroup.nodes:type_name -> OSMPBF.Node 10, // 4: OSMPBF.PrimitiveGroup.dense:type_name -> OSMPBF.DenseNodes 11, // 5: OSMPBF.PrimitiveGroup.ways:type_name -> OSMPBF.Way 12, // 6: OSMPBF.PrimitiveGroup.relations:type_name -> OSMPBF.Relation 8, // 7: OSMPBF.PrimitiveGroup.changesets:type_name -> OSMPBF.ChangeSet 6, // 8: OSMPBF.Node.info:type_name -> OSMPBF.Info 7, // 9: OSMPBF.DenseNodes.denseinfo:type_name -> OSMPBF.DenseInfo 6, // 10: OSMPBF.Way.info:type_name -> OSMPBF.Info 6, // 11: OSMPBF.Relation.info:type_name -> OSMPBF.Info 0, // 12: OSMPBF.Relation.types:type_name -> OSMPBF.Relation.MemberType 13, // [13:13] is the sub-list for method output_type 13, // [13:13] is the sub-list for method input_type 13, // [13:13] is the sub-list for extension type_name 13, // [13:13] is the sub-list for extension extendee 0, // [0:13] is the sub-list for field type_name } func init() { file_osmformat_proto_init() } func file_osmformat_proto_init() { if File_osmformat_proto != nil { return } if !protoimpl.UnsafeEnabled { file_osmformat_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HeaderBlock); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_osmformat_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*HeaderBBox); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_osmformat_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PrimitiveBlock); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_osmformat_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*PrimitiveGroup); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_osmformat_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*StringTable); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_osmformat_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Info); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_osmformat_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DenseInfo); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_osmformat_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ChangeSet); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_osmformat_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Node); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_osmformat_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DenseNodes); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_osmformat_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Way); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } file_osmformat_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Relation); i { case 0: return &v.state case 1: return &v.sizeCache case 2: return &v.unknownFields default: return nil } } } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_osmformat_proto_rawDesc, NumEnums: 1, NumMessages: 12, NumExtensions: 0, NumServices: 0, }, GoTypes: file_osmformat_proto_goTypes, DependencyIndexes: file_osmformat_proto_depIdxs, EnumInfos: file_osmformat_proto_enumTypes, MessageInfos: file_osmformat_proto_msgTypes, }.Build() File_osmformat_proto = out.File file_osmformat_proto_rawDesc = nil file_osmformat_proto_goTypes = nil file_osmformat_proto_depIdxs = nil } ================================================ FILE: OSMPBF/osmformat.proto ================================================ /** Copyright (c) 2010 Scott A. Crosby. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ syntax = "proto2"; option java_package = "crosby.binary"; package OSMPBF; /* OSM Binary file format This is the master schema file of the OSM binary file format. This file is designed to support limited random-access and future extendability. A binary OSM file consists of a sequence of FileBlocks (please see fileformat.proto). The first fileblock contains a serialized instance of HeaderBlock, followed by a sequence of PrimitiveBlock blocks that contain the primitives. Each primitiveblock is designed to be independently parsable. It contains a string table storing all strings in that block (keys and values in tags, roles in relations, usernames, etc.) as well as metadata containing the precision of coordinates or timestamps in that block. A primitiveblock contains a sequence of primitive groups, each containing primitives of the same type (nodes, densenodes, ways, relations). Coordinates are stored in signed 64-bit integers. Lat&lon are measured in units nanodegrees. The default of granularity of 100 nanodegrees corresponds to about 1cm on the ground, and a full lat or lon fits into 32 bits. Converting an integer to a latitude or longitude uses the formula: $OUT = IN * granularity / 10**9$. Many encoding schemes use delta coding when representing nodes and relations. */ ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// /* Contains the file header. */ message HeaderBlock { optional HeaderBBox bbox = 1; /* Additional tags to aid in parsing this dataset */ repeated string required_features = 4; repeated string optional_features = 5; optional string writingprogram = 16; optional string source = 17; // From the bbox field. /* Tags that allow continuing an Osmosis replication */ // Replication timestamp, expressed in seconds since the epoch, // otherwise the same value as in the "timestamp=..." field // in the state.txt file used by Osmosis. optional int64 osmosis_replication_timestamp = 32; // Replication sequence number (sequenceNumber in state.txt). optional int64 osmosis_replication_sequence_number = 33; // Replication base URL (from Osmosis' configuration.txt file). optional string osmosis_replication_base_url = 34; } /** The bounding box field in the OSM header. BBOX, as used in the OSM header. Units are always in nanodegrees -- they do not obey granularity rules. */ message HeaderBBox { required sint64 left = 1; required sint64 right = 2; required sint64 top = 3; required sint64 bottom = 4; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// message PrimitiveBlock { required StringTable stringtable = 1; repeated PrimitiveGroup primitivegroup = 2; // Granularity, units of nanodegrees, used to store coordinates in this block. optional int32 granularity = 17 [default=100]; // Offset value between the output coordinates and the granularity grid in units of nanodegrees. optional int64 lat_offset = 19 [default=0]; optional int64 lon_offset = 20 [default=0]; // Granularity of dates, normally represented in units of milliseconds since the 1970 epoch. optional int32 date_granularity = 18 [default=1000]; } // Group of OSMPrimitives. All primitives in a group must be the same type. message PrimitiveGroup { repeated Node nodes = 1; optional DenseNodes dense = 2; repeated Way ways = 3; repeated Relation relations = 4; repeated ChangeSet changesets = 5; } /** String table, contains the common strings in each block. Note that we reserve index '0' as a delimiter, so the entry at that index in the table is ALWAYS blank and unused. */ message StringTable { repeated string s = 1; } /* Optional metadata that may be included into each primitive. */ message Info { optional int32 version = 1 [default = -1]; optional int64 timestamp = 2; optional int64 changeset = 3; optional int32 uid = 4; optional uint32 user_sid = 5; // String IDs // The visible flag is used to store history information. It indicates that // the current object version has been created by a delete operation on the // OSM API. // When a writer sets this flag, it MUST add a required_features tag with // value "HistoricalInformation" to the HeaderBlock. // If this flag is not available for some object it MUST be assumed to be // true if the file has the required_features tag "HistoricalInformation" // set. optional bool visible = 6; } /** Optional metadata that may be included into each primitive. Special dense format used in DenseNodes. */ message DenseInfo { repeated int32 version = 1 [packed = true]; repeated sint64 timestamp = 2 [packed = true]; // DELTA coded repeated sint64 changeset = 3 [packed = true]; // DELTA coded repeated sint32 uid = 4 [packed = true]; // DELTA coded repeated sint32 user_sid = 5 [packed = true]; // String IDs for usernames. DELTA coded // The visible flag is used to store history information. It indicates that // the current object version has been created by a delete operation on the // OSM API. // When a writer sets this flag, it MUST add a required_features tag with // value "HistoricalInformation" to the HeaderBlock. // If this flag is not available for some object it MUST be assumed to be // true if the file has the required_features tag "HistoricalInformation" // set. repeated bool visible = 6 [packed = true]; } // This is kept for backwards compatibility but not used anywhere. message ChangeSet { required int64 id = 1; } message Node { required sint64 id = 1; // Parallel arrays. repeated uint32 keys = 2 [packed = true]; // String IDs. repeated uint32 vals = 3 [packed = true]; // String IDs. optional Info info = 4; // May be omitted in omitmeta required sint64 lat = 8; required sint64 lon = 9; } /* Used to densly represent a sequence of nodes that do not have any tags. We represent these nodes columnwise as five columns: ID's, lats, and lons, all delta coded. When metadata is not omitted, We encode keys & vals for all nodes as a single array of integers containing key-stringid and val-stringid, using a stringid of 0 as a delimiter between nodes. ( ( )* '0' )* */ message DenseNodes { repeated sint64 id = 1 [packed = true]; // DELTA coded optional DenseInfo denseinfo = 5; repeated sint64 lat = 8 [packed = true]; // DELTA coded repeated sint64 lon = 9 [packed = true]; // DELTA coded // Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless. repeated int32 keys_vals = 10 [packed = true]; } message Way { required int64 id = 1; // Parallel arrays. repeated uint32 keys = 2 [packed = true]; repeated uint32 vals = 3 [packed = true]; optional Info info = 4; repeated sint64 refs = 8 [packed = true]; // DELTA coded // The following two fields are optional. They are only used in a special // format where node locations are also added to the ways. This makes the // files larger, but allows creating way geometries directly. // // If this is used, you MUST set the optional_features tag "LocationsOnWays" // and the number of values in refs, lat, and lon MUST be the same. repeated sint64 lat = 9 [packed = true]; // DELTA coded, optional repeated sint64 lon = 10 [packed = true]; // DELTA coded, optional } message Relation { enum MemberType { NODE = 0; WAY = 1; RELATION = 2; } required int64 id = 1; // Parallel arrays. repeated uint32 keys = 2 [packed = true]; repeated uint32 vals = 3 [packed = true]; optional Info info = 4; // Parallel arrays repeated int32 roles_sid = 8 [packed = true]; // This should have been defined as uint32 for consistency, but it is now too late to change it repeated sint64 memids = 9 [packed = true]; // DELTA encoded repeated MemberType types = 10 [packed = true]; } ================================================ FILE: README.md ================================================ # osmpbf [![Build Status](https://github.com/qedus/osmpbf/actions/workflows/go.yml/badge.svg?branch=master)](https://github.com/qedus/osmpbf/actions/workflows/go.yml) [![Coverage Status](https://coveralls.io/repos/github/qedus/osmpbf/badge.svg?branch=master)](https://coveralls.io/github/qedus/osmpbf?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/qedus/osmpbf)](https://goreportcard.com/report/github.com/qedus/osmpbf) [![Go Reference](https://pkg.go.dev/badge/github.com/qedus/osmpbf.svg)](https://pkg.go.dev/github.com/qedus/osmpbf) Package osmpbf is used to decode OpenStreetMap pbf files. ## Installation ```bash $ go get github.com/qedus/osmpbf ``` ## Usage Usage is similar to `json.Decoder`. ```Go f, err := os.Open("greater-london-140324.osm.pbf") if err != nil { log.Fatal(err) } defer f.Close() d := osmpbf.NewDecoder(f) // use more memory from the start, it is faster d.SetBufferSize(osmpbf.MaxBlobSize) // start decoding with several goroutines, it is faster err = d.Start(runtime.GOMAXPROCS(-1)) if err != nil { log.Fatal(err) } var nc, wc, rc uint64 for { if v, err := d.Decode(); err == io.EOF { break } else if err != nil { log.Fatal(err) } else { switch v := v.(type) { case *osmpbf.Node: // Process Node v. nc++ case *osmpbf.Way: // Process Way v. wc++ case *osmpbf.Relation: // Process Relation v. rc++ default: log.Fatalf("unknown type %T\n", v) } } } fmt.Printf("Nodes: %d, Ways: %d, Relations: %d\n", nc, wc, rc) ``` ## Documentation https://pkg.go.dev/github.com/qedus/osmpbf ## To Do The parseNodes code has not been tested as I can only find PBF files with DenseNode format. An Encoder still needs to be created to reverse the process. ================================================ FILE: decode.go ================================================ // Package osmpbf decodes OpenStreetMap (OSM) PBF files. // Use this package by creating a NewDecoder and passing it a PBF file. // Use Start to start decoding process. // Use Decode to return Node, Way and Relation structs. package osmpbf // import "github.com/qedus/osmpbf" import ( "bytes" "compress/zlib" "encoding/binary" "errors" "fmt" "io" "sync" "time" "github.com/qedus/osmpbf/OSMPBF" "google.golang.org/protobuf/proto" ) const ( maxBlobHeaderSize = 64 * 1024 initialBlobBufSize = 1 * 1024 * 1024 // MaxBlobSize is maximum supported blob size. MaxBlobSize = 32 * 1024 * 1024 ) var ( parseCapabilities = map[string]bool{ "OsmSchema-V0.6": true, "DenseNodes": true, } ) type BoundingBox struct { Left float64 Right float64 Top float64 Bottom float64 } type Header struct { BoundingBox *BoundingBox RequiredFeatures []string OptionalFeatures []string WritingProgram string Source string OsmosisReplicationTimestamp time.Time OsmosisReplicationSequenceNumber int64 OsmosisReplicationBaseUrl string } type Info struct { Version int32 Uid int32 Timestamp time.Time Changeset int64 User string Visible bool } type Node struct { ID int64 Lat float64 Lon float64 Tags map[string]string Info Info } type Way struct { ID int64 Tags map[string]string NodeIDs []int64 Info Info } type Relation struct { ID int64 Tags map[string]string Members []Member Info Info } type MemberType int const ( NodeType MemberType = iota WayType RelationType ) type Member struct { ID int64 Type MemberType Role string } type pair struct { i interface{} e error } // A Decoder reads and decodes OpenStreetMap PBF data from an input stream. type Decoder struct { r io.Reader serializer chan pair buf *bytes.Buffer // store header block header *Header // synchronize header deserialization headerOnce sync.Once // for data decoders inputs []chan<- pair outputs []<-chan pair } // NewDecoder returns a new decoder that reads from r. func NewDecoder(r io.Reader) *Decoder { d := &Decoder{ r: r, serializer: make(chan pair, 8000), // typical PrimitiveBlock contains 8k OSM entities } d.SetBufferSize(initialBlobBufSize) return d } // SetBufferSize sets initial size of decoding buffer. Default value is 1MB, you can set higher value // (for example, MaxBlobSize) for (probably) faster decoding, or lower value for reduced memory consumption. // Any value will produce valid results; buffer will grow automatically if required. func (dec *Decoder) SetBufferSize(n int) { dec.buf = bytes.NewBuffer(make([]byte, 0, n)) } // Header returns file header. func (dec *Decoder) Header() (*Header, error) { // deserialize the file header return dec.header, dec.readOSMHeader() } // Start decoding process using n goroutines. func (dec *Decoder) Start(n int) error { if n < 1 { n = 1 } if err := dec.readOSMHeader(); err != nil { return err } // start data decoders for i := 0; i < n; i++ { input := make(chan pair) output := make(chan pair) go func() { dd := new(dataDecoder) for p := range input { if p.e == nil { // send decoded objects or decoding error objects, err := dd.Decode(p.i.(*OSMPBF.Blob)) output <- pair{objects, err} } else { // send input error as is output <- pair{nil, p.e} } } close(output) }() dec.inputs = append(dec.inputs, input) dec.outputs = append(dec.outputs, output) } // start reading OSMData go func() { var inputIndex int for { input := dec.inputs[inputIndex] inputIndex = (inputIndex + 1) % n blobHeader, blob, err := dec.readFileBlock() if err == nil && blobHeader.GetType() != "OSMData" { err = fmt.Errorf("unexpected fileblock of type %s", blobHeader.GetType()) } if err == nil { // send blob for decoding input <- pair{blob, nil} } else { // send input error as is input <- pair{nil, err} for _, input := range dec.inputs { close(input) } return } } }() go func() { var outputIndex int for { output := dec.outputs[outputIndex] outputIndex = (outputIndex + 1) % n p := <-output if p.i != nil { // send decoded objects one by one for _, o := range p.i.([]interface{}) { dec.serializer <- pair{o, nil} } } if p.e != nil { // send input or decoding error dec.serializer <- pair{nil, p.e} close(dec.serializer) return } } }() return nil } // Decode reads the next object from the input stream and returns either a // pointer to Node, Way or Relation struct representing the underlying OpenStreetMap PBF // data, or error encountered. The end of the input stream is reported by an io.EOF error. // // Decode is safe for parallel execution. Only first error encountered will be returned, // subsequent invocations will return io.EOF. func (dec *Decoder) Decode() (interface{}, error) { p, ok := <-dec.serializer if !ok { return nil, io.EOF } return p.i, p.e } func (dec *Decoder) readFileBlock() (*OSMPBF.BlobHeader, *OSMPBF.Blob, error) { blobHeaderSize, err := dec.readBlobHeaderSize() if err != nil { return nil, nil, err } blobHeader, err := dec.readBlobHeader(blobHeaderSize) if err != nil { return nil, nil, err } blob, err := dec.readBlob(blobHeader) if err != nil { return nil, nil, err } return blobHeader, blob, err } func (dec *Decoder) readBlobHeaderSize() (uint32, error) { dec.buf.Reset() if _, err := io.CopyN(dec.buf, dec.r, 4); err != nil { return 0, err } size := binary.BigEndian.Uint32(dec.buf.Bytes()) if size >= maxBlobHeaderSize { return 0, errors.New("BlobHeader size >= 64Kb") } return size, nil } func (dec *Decoder) readBlobHeader(size uint32) (*OSMPBF.BlobHeader, error) { dec.buf.Reset() if _, err := io.CopyN(dec.buf, dec.r, int64(size)); err != nil { return nil, err } blobHeader := new(OSMPBF.BlobHeader) if err := proto.Unmarshal(dec.buf.Bytes(), blobHeader); err != nil { return nil, err } if blobHeader.GetDatasize() >= MaxBlobSize { return nil, errors.New("Blob size >= 32Mb") } return blobHeader, nil } func (dec *Decoder) readBlob(blobHeader *OSMPBF.BlobHeader) (*OSMPBF.Blob, error) { dec.buf.Reset() if _, err := io.CopyN(dec.buf, dec.r, int64(blobHeader.GetDatasize())); err != nil { return nil, err } blob := new(OSMPBF.Blob) if err := proto.Unmarshal(dec.buf.Bytes(), blob); err != nil { return nil, err } return blob, nil } func getData(blob *OSMPBF.Blob) ([]byte, error) { switch blob.Data.(type) { case *OSMPBF.Blob_Raw: return blob.GetRaw(), nil case *OSMPBF.Blob_ZlibData: r, err := zlib.NewReader(bytes.NewReader(blob.GetZlibData())) if err != nil { return nil, err } buf := bytes.NewBuffer(make([]byte, 0, blob.GetRawSize()+bytes.MinRead)) _, err = buf.ReadFrom(r) if err != nil { return nil, err } if buf.Len() != int(blob.GetRawSize()) { err = fmt.Errorf("raw blob data size %d but expected %d", buf.Len(), blob.GetRawSize()) return nil, err } return buf.Bytes(), nil default: return nil, fmt.Errorf("unhandled blob data type %T", blob.Data) } } func (dec *Decoder) readOSMHeader() error { var err error dec.headerOnce.Do(func() { var blobHeader *OSMPBF.BlobHeader var blob *OSMPBF.Blob blobHeader, blob, err = dec.readFileBlock() if err == nil { if blobHeader.GetType() == "OSMHeader" { err = dec.decodeOSMHeader(blob) } else { err = fmt.Errorf("unexpected first fileblock of type %s", blobHeader.GetType()) } } }) return err } func (dec *Decoder) decodeOSMHeader(blob *OSMPBF.Blob) error { data, err := getData(blob) if err != nil { return err } headerBlock := new(OSMPBF.HeaderBlock) if err := proto.Unmarshal(data, headerBlock); err != nil { return err } // Check we have the parse capabilities requiredFeatures := headerBlock.GetRequiredFeatures() for _, feature := range requiredFeatures { if !parseCapabilities[feature] { return fmt.Errorf("parser does not have %s capability", feature) } } // Read properties to header struct header := &Header{ RequiredFeatures: headerBlock.GetRequiredFeatures(), OptionalFeatures: headerBlock.GetOptionalFeatures(), WritingProgram: headerBlock.GetWritingprogram(), Source: headerBlock.GetSource(), OsmosisReplicationBaseUrl: headerBlock.GetOsmosisReplicationBaseUrl(), OsmosisReplicationSequenceNumber: headerBlock.GetOsmosisReplicationSequenceNumber(), } // convert timestamp epoch seconds to golang time structure if it exists if headerBlock.OsmosisReplicationTimestamp != nil { header.OsmosisReplicationTimestamp = time.Unix(*headerBlock.OsmosisReplicationTimestamp, 0) } // read bounding box if it exists if headerBlock.Bbox != nil { // Units are always in nanodegree and do not obey granularity rules. See osmformat.proto header.BoundingBox = &BoundingBox{ Left: 1e-9 * float64(*headerBlock.Bbox.Left), Right: 1e-9 * float64(*headerBlock.Bbox.Right), Bottom: 1e-9 * float64(*headerBlock.Bbox.Bottom), Top: 1e-9 * float64(*headerBlock.Bbox.Top), } } dec.header = header return nil } ================================================ FILE: decode_data.go ================================================ package osmpbf import ( "time" "github.com/qedus/osmpbf/OSMPBF" "google.golang.org/protobuf/proto" ) // Decoder for Blob with OSMData (PrimitiveBlock) type dataDecoder struct { q []interface{} } func (dec *dataDecoder) Decode(blob *OSMPBF.Blob) ([]interface{}, error) { dec.q = make([]interface{}, 0, 8000) // typical PrimitiveBlock contains 8k OSM entities data, err := getData(blob) if err != nil { return nil, err } primitiveBlock := &OSMPBF.PrimitiveBlock{} if err := proto.Unmarshal(data, primitiveBlock); err != nil { return nil, err } dec.parsePrimitiveBlock(primitiveBlock) return dec.q, nil } func (dec *dataDecoder) parsePrimitiveBlock(pb *OSMPBF.PrimitiveBlock) { for _, pg := range pb.GetPrimitivegroup() { dec.parsePrimitiveGroup(pb, pg) } } func (dec *dataDecoder) parsePrimitiveGroup(pb *OSMPBF.PrimitiveBlock, pg *OSMPBF.PrimitiveGroup) { dec.parseNodes(pb, pg.GetNodes()) dec.parseDenseNodes(pb, pg.GetDense()) dec.parseWays(pb, pg.GetWays()) dec.parseRelations(pb, pg.GetRelations()) } func (dec *dataDecoder) parseNodes(pb *OSMPBF.PrimitiveBlock, nodes []*OSMPBF.Node) { st := pb.GetStringtable().GetS() granularity := int64(pb.GetGranularity()) dateGranularity := int64(pb.GetDateGranularity()) latOffset := pb.GetLatOffset() lonOffset := pb.GetLonOffset() for _, node := range nodes { id := node.GetId() lat := node.GetLat() lon := node.GetLon() latitude := 1e-9 * float64((latOffset + (granularity * lat))) longitude := 1e-9 * float64((lonOffset + (granularity * lon))) tags := extractTags(st, node.GetKeys(), node.GetVals()) info := extractInfo(st, node.GetInfo(), dateGranularity) dec.q = append(dec.q, &Node{id, latitude, longitude, tags, info}) } } func (dec *dataDecoder) parseDenseNodes(pb *OSMPBF.PrimitiveBlock, dn *OSMPBF.DenseNodes) { st := pb.GetStringtable().GetS() granularity := int64(pb.GetGranularity()) latOffset := pb.GetLatOffset() lonOffset := pb.GetLonOffset() dateGranularity := int64(pb.GetDateGranularity()) ids := dn.GetId() lats := dn.GetLat() lons := dn.GetLon() di := dn.GetDenseinfo() tu := tagUnpacker{st, dn.GetKeysVals(), 0} var id, lat, lon int64 var state denseInfoState for index := range ids { id = ids[index] + id lat = lats[index] + lat lon = lons[index] + lon latitude := 1e-9 * float64((latOffset + (granularity * lat))) longitude := 1e-9 * float64((lonOffset + (granularity * lon))) tags := tu.next() info := extractDenseInfo(st, &state, di, index, dateGranularity) dec.q = append(dec.q, &Node{id, latitude, longitude, tags, info}) } } func (dec *dataDecoder) parseWays(pb *OSMPBF.PrimitiveBlock, ways []*OSMPBF.Way) { st := pb.GetStringtable().GetS() dateGranularity := int64(pb.GetDateGranularity()) for _, way := range ways { id := way.GetId() tags := extractTags(st, way.GetKeys(), way.GetVals()) refs := way.GetRefs() var nodeID int64 nodeIDs := make([]int64, len(refs)) for index := range refs { nodeID = refs[index] + nodeID // delta encoding nodeIDs[index] = nodeID } info := extractInfo(st, way.GetInfo(), dateGranularity) dec.q = append(dec.q, &Way{id, tags, nodeIDs, info}) } } // Make relation members from stringtable and three parallel arrays of IDs. func extractMembers(stringTable []string, rel *OSMPBF.Relation) []Member { memIDs := rel.GetMemids() types := rel.GetTypes() roleIDs := rel.GetRolesSid() var memID int64 members := make([]Member, len(memIDs)) for index := range memIDs { memID = memIDs[index] + memID // delta encoding var memType MemberType switch types[index] { case OSMPBF.Relation_NODE: memType = NodeType case OSMPBF.Relation_WAY: memType = WayType case OSMPBF.Relation_RELATION: memType = RelationType } role := stringTable[roleIDs[index]] members[index] = Member{memID, memType, role} } return members } func (dec *dataDecoder) parseRelations(pb *OSMPBF.PrimitiveBlock, relations []*OSMPBF.Relation) { st := pb.GetStringtable().GetS() dateGranularity := int64(pb.GetDateGranularity()) for _, rel := range relations { id := rel.GetId() tags := extractTags(st, rel.GetKeys(), rel.GetVals()) members := extractMembers(st, rel) info := extractInfo(st, rel.GetInfo(), dateGranularity) dec.q = append(dec.q, &Relation{id, tags, members, info}) } } func extractInfo(stringTable []string, i *OSMPBF.Info, dateGranularity int64) Info { info := Info{Visible: true} if i != nil { info.Version = i.GetVersion() millisec := time.Duration(i.GetTimestamp()*dateGranularity) * time.Millisecond info.Timestamp = time.Unix(0, millisec.Nanoseconds()).UTC() info.Changeset = i.GetChangeset() info.Uid = i.GetUid() info.User = stringTable[i.GetUserSid()] if i.Visible != nil { info.Visible = i.GetVisible() } } return info } type denseInfoState struct { timestamp int64 changeset int64 uid int32 userSid int32 } func extractDenseInfo(stringTable []string, state *denseInfoState, di *OSMPBF.DenseInfo, index int, dateGranularity int64) Info { info := Info{Visible: true} versions := di.GetVersion() if len(versions) > 0 { info.Version = versions[index] } timestamps := di.GetTimestamp() if len(timestamps) > 0 { state.timestamp = timestamps[index] + state.timestamp millisec := time.Duration(state.timestamp*dateGranularity) * time.Millisecond info.Timestamp = time.Unix(0, millisec.Nanoseconds()).UTC() } changesets := di.GetChangeset() if len(changesets) > 0 { state.changeset = changesets[index] + state.changeset info.Changeset = state.changeset } uids := di.GetUid() if len(uids) > 0 { state.uid = uids[index] + state.uid info.Uid = state.uid } usersids := di.GetUserSid() if len(usersids) > 0 { state.userSid = usersids[index] + state.userSid info.User = stringTable[state.userSid] } visibleArray := di.GetVisible() if len(visibleArray) > 0 { info.Visible = visibleArray[index] } return info } ================================================ FILE: decode_tag.go ================================================ package osmpbf // Make tags map from stringtable and two parallel arrays of IDs. func extractTags(stringTable []string, keyIDs, valueIDs []uint32) map[string]string { tags := make(map[string]string, len(keyIDs)) for index, keyID := range keyIDs { key := stringTable[keyID] val := stringTable[valueIDs[index]] tags[key] = val } return tags } type tagUnpacker struct { stringTable []string keysVals []int32 index int } // Make tags map from stringtable and array of IDs (used in DenseNodes encoding). func (tu *tagUnpacker) next() map[string]string { tags := make(map[string]string) for tu.index < len(tu.keysVals) { keyID := tu.keysVals[tu.index] tu.index++ if keyID == 0 { break } valID := tu.keysVals[tu.index] tu.index++ key := tu.stringTable[keyID] val := tu.stringTable[valID] tags[key] = val } return tags } ================================================ FILE: decode_test.go ================================================ package osmpbf import ( "fmt" "io" "net/http" "os" "reflect" "runtime" "strconv" "sync" "sync/atomic" "testing" "time" ) const ( // Test files are stored at https://gist.github.com/AlekSi/d4369aa13cf1fc5ddfac3e91b67b2f7b // 8604f36a7357adfbd6b5292c2ea4972d9d0bfd3d is the latest commit. GistURL = "https://gist.githubusercontent.com/AlekSi/d4369aa13cf1fc5ddfac3e91b67b2f7b/raw/8604f36a7357adfbd6b5292c2ea4972d9d0bfd3d/" // Originally downloaded from http://download.geofabrik.de/europe/great-britain/england/greater-london.html London = "greater-london-140324.osm.pbf" // Same file as above, but without 'DenseNodes'. This has been generated using the below command (using osmium-tool http://osmcode.org/osmium-tool/) // "osmium cat -o greater-london-140324-nondense.osm.pbf greater-london-140324.osm.pbf -f osm.pbf,pbf_dense_nodes=false" LondonNonDense = "greater-london-140324-nondense.osm.pbf" ) func parseTime(s string) time.Time { t, err := time.Parse(time.RFC3339, s) if err != nil { panic(err) } return t } var ( IDsExpectedOrder = []string{ // Start of dense nodes. "node/44", "node/47", "node/52", "node/58", "node/60", "node/79", // Just because way/79 is already there "node/2740703694", "node/2740703695", "node/2740703697", "node/2740703699", "node/2740703701", // End of dense nodes. // Start of ways. "way/73", "way/74", "way/75", "way/79", "way/482", "way/268745428", "way/268745431", "way/268745434", "way/268745436", "way/268745439", // End of ways. // Start of relations. "relation/69", "relation/94", "relation/152", "relation/245", "relation/332", "relation/3593436", "relation/3595575", "relation/3595798", "relation/3599126", "relation/3599127", // End of relations } IDs map[string]bool enc uint64 = 2729006 ewc uint64 = 459055 erc uint64 = 12833 eh = &Header{ BoundingBox: &BoundingBox{ Right: 0.335437, Left: -0.511482, Bottom: 51.28554, Top: 51.69344, }, OsmosisReplicationTimestamp: time.Date(2014, 3, 24, 22, 55, 2, 0, time.FixedZone("test", 3600)), RequiredFeatures: []string{ "OsmSchema-V0.6", "DenseNodes", }, WritingProgram: `Osmium (http:\/\/wiki.openstreetmap.org\/wiki\/Osmium)`, } en = &Node{ ID: 18088578, Lat: 51.5442632, Lon: -0.2010027, Tags: map[string]string{ "alt_name": "The King's Head", "amenity": "pub", "created_by": "JOSM", "name": "The Luminaire", "note": "Live music venue too", }, Info: Info{ Version: 2, Timestamp: parseTime("2009-05-20T10:28:54Z"), Changeset: 1260468, Uid: 508, User: "Welshie", Visible: true, }, } ew = &Way{ ID: 4257116, NodeIDs: []int64{ 21544864, 333731851, 333731852, 333731850, 333731855, 333731858, 333731854, 108047, 769984352, 21544864}, Tags: map[string]string{ "area": "yes", "highway": "pedestrian", "name": "Fitzroy Square", }, Info: Info{ Version: 7, Timestamp: parseTime("2013-08-07T12:08:39Z"), Changeset: 17253164, Uid: 1016290, User: "Amaroussi", Visible: true, }, } er = &Relation{ ID: 7677, Members: []Member{ {ID: 4875932, Type: WayType, Role: "outer"}, {ID: 4894305, Type: WayType, Role: "inner"}, }, Tags: map[string]string{ "created_by": "Potlatch 0.9c", "type": "multipolygon", }, Info: Info{ Version: 4, Timestamp: parseTime("2008-07-19T15:04:03Z"), Changeset: 540201, Uid: 3876, User: "Edgemaster", Visible: true, }, } ) func init() { IDs = make(map[string]bool) for _, id := range IDsExpectedOrder { IDs[id] = false } } func downloadTestOSMFile(fileName string, t *testing.T) { _, err := os.Stat(fileName) if err == nil { return } if !os.IsNotExist(err) { t.Fatal(err) } resp, err := http.Get(GistURL + fileName) if err != nil { t.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != 200 { t.Fatalf("expected 200, got %d", resp.StatusCode) } out, err := os.Create(fileName) if err != nil { t.Fatal(err) } defer out.Close() if _, err = io.Copy(out, resp.Body); err != nil { t.Fatal(err) } } func checkHeader(a *Header) bool { if a == nil || a.BoundingBox == nil || a.RequiredFeatures == nil { return false } // check bbox if a.BoundingBox.Right != eh.BoundingBox.Right || a.BoundingBox.Left != eh.BoundingBox.Left || a.BoundingBox.Top != eh.BoundingBox.Top || a.BoundingBox.Bottom != eh.BoundingBox.Bottom { return false } // check timestamp if !a.OsmosisReplicationTimestamp.Equal(eh.OsmosisReplicationTimestamp) { return false } // check writing program if a.WritingProgram != eh.WritingProgram { return false } // check features if len(a.RequiredFeatures) != len(eh.RequiredFeatures) || a.RequiredFeatures[0] != eh.RequiredFeatures[0] || a.RequiredFeatures[1] != eh.RequiredFeatures[1] { return false } return true } func decodePBF(PBFfileName string, t *testing.T) { downloadTestOSMFile(PBFfileName, t) f, err := os.Open(PBFfileName) if err != nil { t.Fatal(err) } defer f.Close() d := NewDecoder(f) d.SetBufferSize(1) header, err := d.Header() if err != nil { t.Fatal(err) } if checkHeader(header) { t.Errorf("\nExpected: %#v\nActual: %#v", eh, header) } err = d.Start(runtime.GOMAXPROCS(-1)) if err != nil { t.Fatal(err) } var n *Node var w *Way var r *Relation var nc, wc, rc uint64 var id string idsOrder := make([]string, 0, len(IDsExpectedOrder)) for { if v, err := d.Decode(); err == io.EOF { break } else if err != nil { t.Fatal(err) } else { switch v := v.(type) { case *Node: nc++ if v.ID == en.ID { n = v } id = fmt.Sprintf("node/%d", v.ID) if _, ok := IDs[id]; ok { idsOrder = append(idsOrder, id) } case *Way: wc++ if v.ID == ew.ID { w = v } id = fmt.Sprintf("way/%d", v.ID) if _, ok := IDs[id]; ok { idsOrder = append(idsOrder, id) } case *Relation: rc++ if v.ID == er.ID { r = v } id = fmt.Sprintf("relation/%d", v.ID) if _, ok := IDs[id]; ok { idsOrder = append(idsOrder, id) } default: t.Fatalf("unknown type %T", v) } } } if !reflect.DeepEqual(en, n) { t.Errorf("\nExpected: %#v\nActual: %#v", en, n) } if !reflect.DeepEqual(ew, w) { t.Errorf("\nExpected: %#v\nActual: %#v", ew, w) } if !reflect.DeepEqual(er, r) { t.Errorf("\nExpected: %#v\nActual: %#v", er, r) } if enc != nc || ewc != wc || erc != rc { t.Errorf("\nExpected %7d nodes, %7d ways, %7d relations\nGot %7d nodes, %7d ways, %7d relations.", enc, ewc, erc, nc, wc, rc) } if !reflect.DeepEqual(IDsExpectedOrder, idsOrder) { t.Errorf("\nExpected: %v\nGot: %v", IDsExpectedOrder, idsOrder) } } func TestDecodePBFWithDenseNodes(t *testing.T) { decodePBF(London, t) } func TestDecodePBFWithNodes(t *testing.T) { decodePBF(LondonNonDense, t) } func TestDecodeConcurrent(t *testing.T) { downloadTestOSMFile(London, t) f, err := os.Open(London) if err != nil { t.Fatal(err) } defer f.Close() d := NewDecoder(f) d.SetBufferSize(1) err = d.Start(runtime.GOMAXPROCS(-1)) if err != nil { t.Fatal(err) } header, err := d.Header() if err != nil { t.Fatal(err) } if checkHeader(header) { t.Errorf("\nExpected: %#v\nActual: %#v", eh, header) } var n *Node var w *Way var r *Relation var nc, wc, rc uint64 var wg sync.WaitGroup for i := 0; i < 4; i++ { wg.Add(1) go func() { defer wg.Done() for { if v, err := d.Decode(); err == io.EOF { return } else if err != nil { t.Error(err) return } else { switch v := v.(type) { case *Node: atomic.AddUint64(&nc, 1) if v.ID == en.ID { n = v } case *Way: atomic.AddUint64(&wc, 1) if v.ID == ew.ID { w = v } case *Relation: atomic.AddUint64(&rc, 1) if v.ID == er.ID { r = v } default: t.Errorf("unknown type %T", v) return } } } }() } wg.Wait() if !reflect.DeepEqual(en, n) { t.Errorf("\nExpected: %#v\nActual: %#v", en, n) } if !reflect.DeepEqual(ew, w) { t.Errorf("\nExpected: %#v\nActual: %#v", ew, w) } if !reflect.DeepEqual(er, r) { t.Errorf("\nExpected: %#v\nActual: %#v", er, r) } if enc != nc || ewc != wc || erc != rc { t.Errorf("\nExpected %7d nodes, %7d ways, %7d relations\nGot %7d nodes, %7d ways, %7d relations", enc, ewc, erc, nc, wc, rc) } } func BenchmarkDecode(b *testing.B) { file := os.Getenv("OSMPBF_BENCHMARK_FILE") if file == "" { file = London } f, err := os.Open(file) if err != nil { b.Fatal(err) } defer f.Close() fileInfo, err := f.Stat() if err != nil { b.Fatal(err) } blobBufferSize, _ := strconv.Atoi(os.Getenv("OSMPBF_BENCHMARK_BUFFER")) b.ResetTimer() for i := 0; i < b.N; i++ { if _, err = f.Seek(0, 0); err != nil { b.Fatal(err) } d := NewDecoder(f) if blobBufferSize > 0 { d.SetBufferSize(blobBufferSize) } err = d.Start(runtime.GOMAXPROCS(-1)) if err != nil { b.Fatal(err) } var nc, wc, rc uint64 start := time.Now() for { if v, err := d.Decode(); err == io.EOF { break } else if err != nil { b.Fatal(err) } else { switch v := v.(type) { case *Node: nc++ case *Way: wc++ case *Relation: rc++ default: b.Fatalf("unknown type %T", v) } } } b.Logf("Done in %.3f seconds. Nodes: %d, Ways: %d, Relations: %d\n", time.Since(start).Seconds(), nc, wc, rc) b.SetBytes(fileInfo.Size()) } } func BenchmarkDecodeConcurrent(b *testing.B) { file := os.Getenv("OSMPBF_BENCHMARK_FILE") if file == "" { file = London } f, err := os.Open(file) if err != nil { b.Fatal(err) } defer f.Close() fileInfo, err := f.Stat() if err != nil { b.Fatal(err) } blobBufferSize, _ := strconv.Atoi(os.Getenv("OSMPBF_BENCHMARK_BUFFER")) b.ResetTimer() for i := 0; i < b.N; i++ { if _, err = f.Seek(0, 0); err != nil { b.Fatal(err) } d := NewDecoder(f) if blobBufferSize > 0 { d.SetBufferSize(blobBufferSize) } err = d.Start(runtime.GOMAXPROCS(-1)) if err != nil { b.Fatal(err) } var nc, wc, rc uint64 start := time.Now() var wg sync.WaitGroup for i := 0; i < 4; i++ { wg.Add(1) go func() { defer wg.Done() for { if v, err := d.Decode(); err == io.EOF { return } else if err != nil { b.Error(err) return } else { switch v := v.(type) { case *Node: atomic.AddUint64(&nc, 1) case *Way: atomic.AddUint64(&wc, 1) case *Relation: atomic.AddUint64(&rc, 1) default: b.Errorf("unknown type %T", v) return } } } }() } wg.Wait() b.Logf("Done in %.3f seconds. Nodes: %d, Ways: %d, Relations: %d\n", time.Since(start).Seconds(), nc, wc, rc) b.SetBytes(fileInfo.Size()) } } ================================================ FILE: example_test.go ================================================ package osmpbf_test import ( "fmt" "io" "log" "os" "runtime" "github.com/qedus/osmpbf" ) // Don't forget to sync with README.md func Example() { f, err := os.Open("greater-london-140324.osm.pbf") if err != nil { log.Fatal(err) } defer f.Close() d := osmpbf.NewDecoder(f) // use more memory from the start, it is faster d.SetBufferSize(osmpbf.MaxBlobSize) // start decoding with several goroutines, it is faster err = d.Start(runtime.GOMAXPROCS(-1)) if err != nil { log.Fatal(err) } var nc, wc, rc uint64 for { if v, err := d.Decode(); err == io.EOF { break } else if err != nil { log.Fatal(err) } else { switch v := v.(type) { case *osmpbf.Node: // Process Node v. nc++ case *osmpbf.Way: // Process Way v. wc++ case *osmpbf.Relation: // Process Relation v. rc++ default: log.Fatalf("unknown type %T\n", v) } } } fmt.Printf("Nodes: %d, Ways: %d, Relations: %d\n", nc, wc, rc) // Output: // Nodes: 2729006, Ways: 459055, Relations: 12833 } ================================================ FILE: go.mod ================================================ module github.com/qedus/osmpbf go 1.16 require google.golang.org/protobuf v1.27.1 // sync version with OSMPBF/Makefile ================================================ FILE: go.sum ================================================ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=