├── .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 /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: "gomod" 5 | directory: "/" 6 | schedule: 7 | interval: "monthly" 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "monthly" 12 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Go 3 | 4 | on: 5 | push: 6 | branches: [master] 7 | pull_request: 8 | 9 | jobs: 10 | build: 11 | name: Build 12 | 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | go: [1.16.x] 17 | may-fail: [false] 18 | include: 19 | - go: tip 20 | may-fail: true 21 | 22 | runs-on: ubuntu-20.04 23 | continue-on-error: ${{ matrix.may-fail }} 24 | 25 | steps: 26 | - name: Checkout code 27 | uses: actions/checkout@v3 28 | 29 | - name: Setup Go v${{ matrix.go }} 30 | if: ${{ matrix.go != 'tip' }} 31 | uses: actions/setup-go@v2 32 | with: 33 | go-version: ${{ matrix.go }} 34 | 35 | - name: Setup Go tip 36 | if: ${{ matrix.go == 'tip' }} 37 | run: | 38 | curl -OL https://github.com/AlekSi/golang-tip/releases/download/tip/master.linux-amd64.tar.gz 39 | sudo rm -rf /usr/local/go 40 | sudo tar -C /usr/local -xzf master.linux-amd64.tar.gz 41 | sudo ln -vsf /usr/local/go/bin/* /usr/bin/ 42 | sudo ln -vsf /usr/local/go/bin/* /bin/ 43 | 44 | - name: Run debug commands 45 | run: | 46 | env 47 | which -a go 48 | go version 49 | go env 50 | 51 | - name: Install tools 52 | run: make init 53 | 54 | - name: Test with race detector 55 | run: make race 56 | 57 | - name: Gather test coverage 58 | run: make cover 59 | 60 | - name: Upload test coverage report to coveralls.io 61 | uses: shogo82148/actions-goveralls@v1.5.1 62 | with: 63 | path-to-profile: profile.cov 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.osm 2 | *.osm.bz2 3 | *.osm.pbf 4 | *.md5 5 | *.out 6 | *.test 7 | *.txt 8 | *.cov 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## v1.2.0 (tagged 2021-05-10) 4 | 5 | * Converted to Go module. 6 | * Updated .proto files ([#35](https://github.com/qedus/osmpbf/pull/35) by Lucas). 7 | * Updated protobuf dependency. 8 | * Migrated CI to GitHub Actions. 9 | 10 | ## v1.1.0 (tagged 2018-03-29) 11 | 12 | * Added [`Decoder.Header()` method](https://pkg.go.dev/github.com/qedus/osmpbf#Decoder.Header) 13 | ([#24](https://github.com/qedus/osmpbf/pull/24) by Karsten Klompmaker). 14 | * Added support for non-dense Nodes 15 | ([#30](https://github.com/qedus/osmpbf/pull/30) by Clyde D'Cruz). 16 | * Minor optimizations. 17 | 18 | ## v1.0.0 (tagged 2017-03-15) 19 | 20 | * First release with stable public API. 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 qedus 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | export GORACE := halt_on_error=1 2 | 3 | all: cover 4 | 5 | init: 6 | go install -v golang.org/x/perf/cmd/benchstat@latest 7 | 8 | race: 9 | go install -v -race 10 | go test -v -race 11 | 12 | cover: 13 | go install -v 14 | go test -v -coverprofile=profile.cov 15 | 16 | bench: 17 | env OSMPBF_BENCHMARK_BUFFER=1048576 go test -v -run=NONE -bench=. -benchmem -benchtime=10s -count=5 | tee 01.txt 18 | env OSMPBF_BENCHMARK_BUFFER=33554432 go test -v -run=NONE -bench=. -benchmem -benchtime=10s -count=5 | tee 32.txt 19 | benchstat 01.txt 32.txt 20 | -------------------------------------------------------------------------------- /OSMPBF/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | # sync version with ../go.mod 3 | go install -v google.golang.org/protobuf/cmd/protoc-gen-go@v1.26.0 4 | 5 | rm *.go 6 | protoc --go_out=. \ 7 | --go_opt=paths=source_relative \ 8 | --go_opt=Mfileformat.proto=github.com/qedus/osmpbf/OSMPBF \ 9 | --go_opt=Mosmformat.proto=github.com/qedus/osmpbf/OSMPBF \ 10 | *.proto 11 | -------------------------------------------------------------------------------- /OSMPBF/README.md: -------------------------------------------------------------------------------- 1 | # Proto Files 2 | 3 | `*.proto` files were downloaded from https://github.com/scrosby/OSM-binary/tree/master/src and changed in following ways: 4 | 5 | ## Changes 6 | 7 | ### StringTable 8 | 9 | - **File**: `osmformat.proto` 10 | - **Reason**: To eliminate continuous conversions from `[]byte` to `string` 11 | - **Old code**: 12 | 13 | ```protobuf 14 | message StringTable { 15 | repeated bytes s = 1; 16 | } 17 | ``` 18 | 19 | - **New code**: 20 | 21 | ```protobuf 22 | message StringTable { 23 | repeated string s = 1; 24 | } 25 | ``` 26 | 27 | - **Comptatibility**: This change is expected to be fully compatible with all PBF files. 28 | -------------------------------------------------------------------------------- /OSMPBF/fileformat.pb.go: -------------------------------------------------------------------------------- 1 | //* Copyright (c) 2010 Scott A. Crosby. 2 | // 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | //this software and associated documentation files (the "Software"), to deal in 5 | //the Software without restriction, including without limitation the rights to 6 | //use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | //of the Software, and to permit persons to whom the Software is furnished to do 8 | //so, subject to the following conditions: 9 | // 10 | //The above copyright notice and this permission notice shall be included in all 11 | //copies or substantial portions of the Software. 12 | // 13 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | //SOFTWARE. 20 | // 21 | 22 | // Code generated by protoc-gen-go. DO NOT EDIT. 23 | // versions: 24 | // protoc-gen-go v1.26.0 25 | // protoc v3.15.8 26 | // source: fileformat.proto 27 | 28 | package OSMPBF 29 | 30 | import ( 31 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 32 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 33 | reflect "reflect" 34 | sync "sync" 35 | ) 36 | 37 | const ( 38 | // Verify that this generated code is sufficiently up-to-date. 39 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 40 | // Verify that runtime/protoimpl is sufficiently up-to-date. 41 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 42 | ) 43 | 44 | type Blob struct { 45 | state protoimpl.MessageState 46 | sizeCache protoimpl.SizeCache 47 | unknownFields protoimpl.UnknownFields 48 | 49 | RawSize *int32 `protobuf:"varint,2,opt,name=raw_size,json=rawSize" json:"raw_size,omitempty"` // When compressed, the uncompressed size 50 | // Types that are assignable to Data: 51 | // *Blob_Raw 52 | // *Blob_ZlibData 53 | // *Blob_LzmaData 54 | // *Blob_OBSOLETEBzip2Data 55 | // *Blob_Lz4Data 56 | // *Blob_ZstdData 57 | Data isBlob_Data `protobuf_oneof:"data"` 58 | } 59 | 60 | func (x *Blob) Reset() { 61 | *x = Blob{} 62 | if protoimpl.UnsafeEnabled { 63 | mi := &file_fileformat_proto_msgTypes[0] 64 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 65 | ms.StoreMessageInfo(mi) 66 | } 67 | } 68 | 69 | func (x *Blob) String() string { 70 | return protoimpl.X.MessageStringOf(x) 71 | } 72 | 73 | func (*Blob) ProtoMessage() {} 74 | 75 | func (x *Blob) ProtoReflect() protoreflect.Message { 76 | mi := &file_fileformat_proto_msgTypes[0] 77 | if protoimpl.UnsafeEnabled && x != nil { 78 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 79 | if ms.LoadMessageInfo() == nil { 80 | ms.StoreMessageInfo(mi) 81 | } 82 | return ms 83 | } 84 | return mi.MessageOf(x) 85 | } 86 | 87 | // Deprecated: Use Blob.ProtoReflect.Descriptor instead. 88 | func (*Blob) Descriptor() ([]byte, []int) { 89 | return file_fileformat_proto_rawDescGZIP(), []int{0} 90 | } 91 | 92 | func (x *Blob) GetRawSize() int32 { 93 | if x != nil && x.RawSize != nil { 94 | return *x.RawSize 95 | } 96 | return 0 97 | } 98 | 99 | func (m *Blob) GetData() isBlob_Data { 100 | if m != nil { 101 | return m.Data 102 | } 103 | return nil 104 | } 105 | 106 | func (x *Blob) GetRaw() []byte { 107 | if x, ok := x.GetData().(*Blob_Raw); ok { 108 | return x.Raw 109 | } 110 | return nil 111 | } 112 | 113 | func (x *Blob) GetZlibData() []byte { 114 | if x, ok := x.GetData().(*Blob_ZlibData); ok { 115 | return x.ZlibData 116 | } 117 | return nil 118 | } 119 | 120 | func (x *Blob) GetLzmaData() []byte { 121 | if x, ok := x.GetData().(*Blob_LzmaData); ok { 122 | return x.LzmaData 123 | } 124 | return nil 125 | } 126 | 127 | // Deprecated: Do not use. 128 | func (x *Blob) GetOBSOLETEBzip2Data() []byte { 129 | if x, ok := x.GetData().(*Blob_OBSOLETEBzip2Data); ok { 130 | return x.OBSOLETEBzip2Data 131 | } 132 | return nil 133 | } 134 | 135 | func (x *Blob) GetLz4Data() []byte { 136 | if x, ok := x.GetData().(*Blob_Lz4Data); ok { 137 | return x.Lz4Data 138 | } 139 | return nil 140 | } 141 | 142 | func (x *Blob) GetZstdData() []byte { 143 | if x, ok := x.GetData().(*Blob_ZstdData); ok { 144 | return x.ZstdData 145 | } 146 | return nil 147 | } 148 | 149 | type isBlob_Data interface { 150 | isBlob_Data() 151 | } 152 | 153 | type Blob_Raw struct { 154 | Raw []byte `protobuf:"bytes,1,opt,name=raw,oneof"` // No compression 155 | } 156 | 157 | type Blob_ZlibData struct { 158 | // Possible compressed versions of the data. 159 | ZlibData []byte `protobuf:"bytes,3,opt,name=zlib_data,json=zlibData,oneof"` 160 | } 161 | 162 | type Blob_LzmaData struct { 163 | // For LZMA compressed data (optional) 164 | LzmaData []byte `protobuf:"bytes,4,opt,name=lzma_data,json=lzmaData,oneof"` 165 | } 166 | 167 | type Blob_OBSOLETEBzip2Data struct { 168 | // Formerly used for bzip2 compressed data. Deprecated in 2010. 169 | // 170 | // Deprecated: Do not use. 171 | OBSOLETEBzip2Data []byte `protobuf:"bytes,5,opt,name=OBSOLETE_bzip2_data,json=OBSOLETEBzip2Data,oneof"` // Don't reuse this tag number. 172 | } 173 | 174 | type Blob_Lz4Data struct { 175 | // For LZ4 compressed data (optional) 176 | Lz4Data []byte `protobuf:"bytes,6,opt,name=lz4_data,json=lz4Data,oneof"` 177 | } 178 | 179 | type Blob_ZstdData struct { 180 | // For ZSTD compressed data (optional) 181 | ZstdData []byte `protobuf:"bytes,7,opt,name=zstd_data,json=zstdData,oneof"` 182 | } 183 | 184 | func (*Blob_Raw) isBlob_Data() {} 185 | 186 | func (*Blob_ZlibData) isBlob_Data() {} 187 | 188 | func (*Blob_LzmaData) isBlob_Data() {} 189 | 190 | func (*Blob_OBSOLETEBzip2Data) isBlob_Data() {} 191 | 192 | func (*Blob_Lz4Data) isBlob_Data() {} 193 | 194 | func (*Blob_ZstdData) isBlob_Data() {} 195 | 196 | type BlobHeader struct { 197 | state protoimpl.MessageState 198 | sizeCache protoimpl.SizeCache 199 | unknownFields protoimpl.UnknownFields 200 | 201 | Type *string `protobuf:"bytes,1,req,name=type" json:"type,omitempty"` 202 | Indexdata []byte `protobuf:"bytes,2,opt,name=indexdata" json:"indexdata,omitempty"` 203 | Datasize *int32 `protobuf:"varint,3,req,name=datasize" json:"datasize,omitempty"` 204 | } 205 | 206 | func (x *BlobHeader) Reset() { 207 | *x = BlobHeader{} 208 | if protoimpl.UnsafeEnabled { 209 | mi := &file_fileformat_proto_msgTypes[1] 210 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 211 | ms.StoreMessageInfo(mi) 212 | } 213 | } 214 | 215 | func (x *BlobHeader) String() string { 216 | return protoimpl.X.MessageStringOf(x) 217 | } 218 | 219 | func (*BlobHeader) ProtoMessage() {} 220 | 221 | func (x *BlobHeader) ProtoReflect() protoreflect.Message { 222 | mi := &file_fileformat_proto_msgTypes[1] 223 | if protoimpl.UnsafeEnabled && x != nil { 224 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 225 | if ms.LoadMessageInfo() == nil { 226 | ms.StoreMessageInfo(mi) 227 | } 228 | return ms 229 | } 230 | return mi.MessageOf(x) 231 | } 232 | 233 | // Deprecated: Use BlobHeader.ProtoReflect.Descriptor instead. 234 | func (*BlobHeader) Descriptor() ([]byte, []int) { 235 | return file_fileformat_proto_rawDescGZIP(), []int{1} 236 | } 237 | 238 | func (x *BlobHeader) GetType() string { 239 | if x != nil && x.Type != nil { 240 | return *x.Type 241 | } 242 | return "" 243 | } 244 | 245 | func (x *BlobHeader) GetIndexdata() []byte { 246 | if x != nil { 247 | return x.Indexdata 248 | } 249 | return nil 250 | } 251 | 252 | func (x *BlobHeader) GetDatasize() int32 { 253 | if x != nil && x.Datasize != nil { 254 | return *x.Datasize 255 | } 256 | return 0 257 | } 258 | 259 | var File_fileformat_proto protoreflect.FileDescriptor 260 | 261 | var file_fileformat_proto_rawDesc = []byte{ 262 | 0x0a, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x70, 0x72, 0x6f, 263 | 0x74, 0x6f, 0x12, 0x06, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x22, 0xed, 0x01, 0x0a, 0x04, 0x42, 264 | 0x6c, 0x6f, 0x62, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x61, 0x77, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 265 | 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x07, 0x72, 0x61, 0x77, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x12, 266 | 0x0a, 0x03, 0x72, 0x61, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x03, 0x72, 267 | 0x61, 0x77, 0x12, 0x1d, 0x0a, 0x09, 0x7a, 0x6c, 0x69, 0x62, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 268 | 0x03, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x7a, 0x6c, 0x69, 0x62, 0x44, 0x61, 0x74, 269 | 0x61, 0x12, 0x1d, 0x0a, 0x09, 0x6c, 0x7a, 0x6d, 0x61, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 270 | 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x6c, 0x7a, 0x6d, 0x61, 0x44, 0x61, 0x74, 0x61, 271 | 0x12, 0x34, 0x0a, 0x13, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x5f, 0x62, 0x7a, 0x69, 272 | 0x70, 0x32, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x02, 0x18, 273 | 0x01, 0x48, 0x00, 0x52, 0x11, 0x4f, 0x42, 0x53, 0x4f, 0x4c, 0x45, 0x54, 0x45, 0x42, 0x7a, 0x69, 274 | 0x70, 0x32, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x08, 0x6c, 0x7a, 0x34, 0x5f, 0x64, 0x61, 275 | 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x7a, 0x34, 0x44, 276 | 0x61, 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x09, 0x7a, 0x73, 0x74, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 277 | 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x08, 0x7a, 0x73, 0x74, 0x64, 0x44, 0x61, 278 | 0x74, 0x61, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x5a, 0x0a, 0x0a, 0x42, 0x6c, 279 | 0x6f, 0x62, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 280 | 0x18, 0x01, 0x20, 0x02, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1c, 0x0a, 0x09, 281 | 0x69, 0x6e, 0x64, 0x65, 0x78, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 282 | 0x09, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 283 | 0x74, 0x61, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x02, 0x28, 0x05, 0x52, 0x08, 0x64, 0x61, 284 | 0x74, 0x61, 0x73, 0x69, 0x7a, 0x65, 0x42, 0x0f, 0x0a, 0x0d, 0x63, 0x72, 0x6f, 0x73, 0x62, 0x79, 285 | 0x2e, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 286 | } 287 | 288 | var ( 289 | file_fileformat_proto_rawDescOnce sync.Once 290 | file_fileformat_proto_rawDescData = file_fileformat_proto_rawDesc 291 | ) 292 | 293 | func file_fileformat_proto_rawDescGZIP() []byte { 294 | file_fileformat_proto_rawDescOnce.Do(func() { 295 | file_fileformat_proto_rawDescData = protoimpl.X.CompressGZIP(file_fileformat_proto_rawDescData) 296 | }) 297 | return file_fileformat_proto_rawDescData 298 | } 299 | 300 | var file_fileformat_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 301 | var file_fileformat_proto_goTypes = []interface{}{ 302 | (*Blob)(nil), // 0: OSMPBF.Blob 303 | (*BlobHeader)(nil), // 1: OSMPBF.BlobHeader 304 | } 305 | var file_fileformat_proto_depIdxs = []int32{ 306 | 0, // [0:0] is the sub-list for method output_type 307 | 0, // [0:0] is the sub-list for method input_type 308 | 0, // [0:0] is the sub-list for extension type_name 309 | 0, // [0:0] is the sub-list for extension extendee 310 | 0, // [0:0] is the sub-list for field type_name 311 | } 312 | 313 | func init() { file_fileformat_proto_init() } 314 | func file_fileformat_proto_init() { 315 | if File_fileformat_proto != nil { 316 | return 317 | } 318 | if !protoimpl.UnsafeEnabled { 319 | file_fileformat_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 320 | switch v := v.(*Blob); i { 321 | case 0: 322 | return &v.state 323 | case 1: 324 | return &v.sizeCache 325 | case 2: 326 | return &v.unknownFields 327 | default: 328 | return nil 329 | } 330 | } 331 | file_fileformat_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 332 | switch v := v.(*BlobHeader); i { 333 | case 0: 334 | return &v.state 335 | case 1: 336 | return &v.sizeCache 337 | case 2: 338 | return &v.unknownFields 339 | default: 340 | return nil 341 | } 342 | } 343 | } 344 | file_fileformat_proto_msgTypes[0].OneofWrappers = []interface{}{ 345 | (*Blob_Raw)(nil), 346 | (*Blob_ZlibData)(nil), 347 | (*Blob_LzmaData)(nil), 348 | (*Blob_OBSOLETEBzip2Data)(nil), 349 | (*Blob_Lz4Data)(nil), 350 | (*Blob_ZstdData)(nil), 351 | } 352 | type x struct{} 353 | out := protoimpl.TypeBuilder{ 354 | File: protoimpl.DescBuilder{ 355 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 356 | RawDescriptor: file_fileformat_proto_rawDesc, 357 | NumEnums: 0, 358 | NumMessages: 2, 359 | NumExtensions: 0, 360 | NumServices: 0, 361 | }, 362 | GoTypes: file_fileformat_proto_goTypes, 363 | DependencyIndexes: file_fileformat_proto_depIdxs, 364 | MessageInfos: file_fileformat_proto_msgTypes, 365 | }.Build() 366 | File_fileformat_proto = out.File 367 | file_fileformat_proto_rawDesc = nil 368 | file_fileformat_proto_goTypes = nil 369 | file_fileformat_proto_depIdxs = nil 370 | } 371 | -------------------------------------------------------------------------------- /OSMPBF/fileformat.proto: -------------------------------------------------------------------------------- 1 | /** Copyright (c) 2010 Scott A. Crosby. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | 21 | */ 22 | 23 | syntax = "proto2"; 24 | 25 | option java_package = "crosby.binary"; 26 | package OSMPBF; 27 | 28 | //protoc --java_out=../.. fileformat.proto 29 | 30 | 31 | // 32 | // STORAGE LAYER: Storing primitives. 33 | // 34 | 35 | message Blob { 36 | optional int32 raw_size = 2; // When compressed, the uncompressed size 37 | 38 | oneof data { 39 | bytes raw = 1; // No compression 40 | 41 | // Possible compressed versions of the data. 42 | bytes zlib_data = 3; 43 | 44 | // For LZMA compressed data (optional) 45 | bytes lzma_data = 4; 46 | 47 | // Formerly used for bzip2 compressed data. Deprecated in 2010. 48 | bytes OBSOLETE_bzip2_data = 5 [deprecated=true]; // Don't reuse this tag number. 49 | 50 | // For LZ4 compressed data (optional) 51 | bytes lz4_data = 6; 52 | 53 | // For ZSTD compressed data (optional) 54 | bytes zstd_data = 7; 55 | } 56 | } 57 | 58 | /* A file contains an sequence of fileblock headers, each prefixed by 59 | their length in network byte order, followed by a data block 60 | containing the actual data. Types starting with a "_" are reserved. 61 | */ 62 | 63 | message BlobHeader { 64 | required string type = 1; 65 | optional bytes indexdata = 2; 66 | required int32 datasize = 3; 67 | } 68 | -------------------------------------------------------------------------------- /OSMPBF/osmformat.pb.go: -------------------------------------------------------------------------------- 1 | //* Copyright (c) 2010 Scott A. Crosby. 2 | // 3 | //Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | //this software and associated documentation files (the "Software"), to deal in 5 | //the Software without restriction, including without limitation the rights to 6 | //use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | //of the Software, and to permit persons to whom the Software is furnished to do 8 | //so, subject to the following conditions: 9 | // 10 | //The above copyright notice and this permission notice shall be included in all 11 | //copies or substantial portions of the Software. 12 | // 13 | //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | //SOFTWARE. 20 | // 21 | 22 | // Code generated by protoc-gen-go. DO NOT EDIT. 23 | // versions: 24 | // protoc-gen-go v1.26.0 25 | // protoc v3.15.8 26 | // source: osmformat.proto 27 | 28 | package OSMPBF 29 | 30 | import ( 31 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 32 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 33 | reflect "reflect" 34 | sync "sync" 35 | ) 36 | 37 | const ( 38 | // Verify that this generated code is sufficiently up-to-date. 39 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 40 | // Verify that runtime/protoimpl is sufficiently up-to-date. 41 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 42 | ) 43 | 44 | type Relation_MemberType int32 45 | 46 | const ( 47 | Relation_NODE Relation_MemberType = 0 48 | Relation_WAY Relation_MemberType = 1 49 | Relation_RELATION Relation_MemberType = 2 50 | ) 51 | 52 | // Enum value maps for Relation_MemberType. 53 | var ( 54 | Relation_MemberType_name = map[int32]string{ 55 | 0: "NODE", 56 | 1: "WAY", 57 | 2: "RELATION", 58 | } 59 | Relation_MemberType_value = map[string]int32{ 60 | "NODE": 0, 61 | "WAY": 1, 62 | "RELATION": 2, 63 | } 64 | ) 65 | 66 | func (x Relation_MemberType) Enum() *Relation_MemberType { 67 | p := new(Relation_MemberType) 68 | *p = x 69 | return p 70 | } 71 | 72 | func (x Relation_MemberType) String() string { 73 | return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) 74 | } 75 | 76 | func (Relation_MemberType) Descriptor() protoreflect.EnumDescriptor { 77 | return file_osmformat_proto_enumTypes[0].Descriptor() 78 | } 79 | 80 | func (Relation_MemberType) Type() protoreflect.EnumType { 81 | return &file_osmformat_proto_enumTypes[0] 82 | } 83 | 84 | func (x Relation_MemberType) Number() protoreflect.EnumNumber { 85 | return protoreflect.EnumNumber(x) 86 | } 87 | 88 | // Deprecated: Do not use. 89 | func (x *Relation_MemberType) UnmarshalJSON(b []byte) error { 90 | num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b) 91 | if err != nil { 92 | return err 93 | } 94 | *x = Relation_MemberType(num) 95 | return nil 96 | } 97 | 98 | // Deprecated: Use Relation_MemberType.Descriptor instead. 99 | func (Relation_MemberType) EnumDescriptor() ([]byte, []int) { 100 | return file_osmformat_proto_rawDescGZIP(), []int{11, 0} 101 | } 102 | 103 | type HeaderBlock struct { 104 | state protoimpl.MessageState 105 | sizeCache protoimpl.SizeCache 106 | unknownFields protoimpl.UnknownFields 107 | 108 | Bbox *HeaderBBox `protobuf:"bytes,1,opt,name=bbox" json:"bbox,omitempty"` 109 | // Additional tags to aid in parsing this dataset 110 | RequiredFeatures []string `protobuf:"bytes,4,rep,name=required_features,json=requiredFeatures" json:"required_features,omitempty"` 111 | OptionalFeatures []string `protobuf:"bytes,5,rep,name=optional_features,json=optionalFeatures" json:"optional_features,omitempty"` 112 | Writingprogram *string `protobuf:"bytes,16,opt,name=writingprogram" json:"writingprogram,omitempty"` 113 | Source *string `protobuf:"bytes,17,opt,name=source" json:"source,omitempty"` // From the bbox field. 114 | // Replication timestamp, expressed in seconds since the epoch, 115 | // otherwise the same value as in the "timestamp=..." field 116 | // in the state.txt file used by Osmosis. 117 | OsmosisReplicationTimestamp *int64 `protobuf:"varint,32,opt,name=osmosis_replication_timestamp,json=osmosisReplicationTimestamp" json:"osmosis_replication_timestamp,omitempty"` 118 | // Replication sequence number (sequenceNumber in state.txt). 119 | OsmosisReplicationSequenceNumber *int64 `protobuf:"varint,33,opt,name=osmosis_replication_sequence_number,json=osmosisReplicationSequenceNumber" json:"osmosis_replication_sequence_number,omitempty"` 120 | // Replication base URL (from Osmosis' configuration.txt file). 121 | OsmosisReplicationBaseUrl *string `protobuf:"bytes,34,opt,name=osmosis_replication_base_url,json=osmosisReplicationBaseUrl" json:"osmosis_replication_base_url,omitempty"` 122 | } 123 | 124 | func (x *HeaderBlock) Reset() { 125 | *x = HeaderBlock{} 126 | if protoimpl.UnsafeEnabled { 127 | mi := &file_osmformat_proto_msgTypes[0] 128 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 129 | ms.StoreMessageInfo(mi) 130 | } 131 | } 132 | 133 | func (x *HeaderBlock) String() string { 134 | return protoimpl.X.MessageStringOf(x) 135 | } 136 | 137 | func (*HeaderBlock) ProtoMessage() {} 138 | 139 | func (x *HeaderBlock) ProtoReflect() protoreflect.Message { 140 | mi := &file_osmformat_proto_msgTypes[0] 141 | if protoimpl.UnsafeEnabled && x != nil { 142 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 143 | if ms.LoadMessageInfo() == nil { 144 | ms.StoreMessageInfo(mi) 145 | } 146 | return ms 147 | } 148 | return mi.MessageOf(x) 149 | } 150 | 151 | // Deprecated: Use HeaderBlock.ProtoReflect.Descriptor instead. 152 | func (*HeaderBlock) Descriptor() ([]byte, []int) { 153 | return file_osmformat_proto_rawDescGZIP(), []int{0} 154 | } 155 | 156 | func (x *HeaderBlock) GetBbox() *HeaderBBox { 157 | if x != nil { 158 | return x.Bbox 159 | } 160 | return nil 161 | } 162 | 163 | func (x *HeaderBlock) GetRequiredFeatures() []string { 164 | if x != nil { 165 | return x.RequiredFeatures 166 | } 167 | return nil 168 | } 169 | 170 | func (x *HeaderBlock) GetOptionalFeatures() []string { 171 | if x != nil { 172 | return x.OptionalFeatures 173 | } 174 | return nil 175 | } 176 | 177 | func (x *HeaderBlock) GetWritingprogram() string { 178 | if x != nil && x.Writingprogram != nil { 179 | return *x.Writingprogram 180 | } 181 | return "" 182 | } 183 | 184 | func (x *HeaderBlock) GetSource() string { 185 | if x != nil && x.Source != nil { 186 | return *x.Source 187 | } 188 | return "" 189 | } 190 | 191 | func (x *HeaderBlock) GetOsmosisReplicationTimestamp() int64 { 192 | if x != nil && x.OsmosisReplicationTimestamp != nil { 193 | return *x.OsmosisReplicationTimestamp 194 | } 195 | return 0 196 | } 197 | 198 | func (x *HeaderBlock) GetOsmosisReplicationSequenceNumber() int64 { 199 | if x != nil && x.OsmosisReplicationSequenceNumber != nil { 200 | return *x.OsmosisReplicationSequenceNumber 201 | } 202 | return 0 203 | } 204 | 205 | func (x *HeaderBlock) GetOsmosisReplicationBaseUrl() string { 206 | if x != nil && x.OsmosisReplicationBaseUrl != nil { 207 | return *x.OsmosisReplicationBaseUrl 208 | } 209 | return "" 210 | } 211 | 212 | type HeaderBBox struct { 213 | state protoimpl.MessageState 214 | sizeCache protoimpl.SizeCache 215 | unknownFields protoimpl.UnknownFields 216 | 217 | Left *int64 `protobuf:"zigzag64,1,req,name=left" json:"left,omitempty"` 218 | Right *int64 `protobuf:"zigzag64,2,req,name=right" json:"right,omitempty"` 219 | Top *int64 `protobuf:"zigzag64,3,req,name=top" json:"top,omitempty"` 220 | Bottom *int64 `protobuf:"zigzag64,4,req,name=bottom" json:"bottom,omitempty"` 221 | } 222 | 223 | func (x *HeaderBBox) Reset() { 224 | *x = HeaderBBox{} 225 | if protoimpl.UnsafeEnabled { 226 | mi := &file_osmformat_proto_msgTypes[1] 227 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 228 | ms.StoreMessageInfo(mi) 229 | } 230 | } 231 | 232 | func (x *HeaderBBox) String() string { 233 | return protoimpl.X.MessageStringOf(x) 234 | } 235 | 236 | func (*HeaderBBox) ProtoMessage() {} 237 | 238 | func (x *HeaderBBox) ProtoReflect() protoreflect.Message { 239 | mi := &file_osmformat_proto_msgTypes[1] 240 | if protoimpl.UnsafeEnabled && x != nil { 241 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 242 | if ms.LoadMessageInfo() == nil { 243 | ms.StoreMessageInfo(mi) 244 | } 245 | return ms 246 | } 247 | return mi.MessageOf(x) 248 | } 249 | 250 | // Deprecated: Use HeaderBBox.ProtoReflect.Descriptor instead. 251 | func (*HeaderBBox) Descriptor() ([]byte, []int) { 252 | return file_osmformat_proto_rawDescGZIP(), []int{1} 253 | } 254 | 255 | func (x *HeaderBBox) GetLeft() int64 { 256 | if x != nil && x.Left != nil { 257 | return *x.Left 258 | } 259 | return 0 260 | } 261 | 262 | func (x *HeaderBBox) GetRight() int64 { 263 | if x != nil && x.Right != nil { 264 | return *x.Right 265 | } 266 | return 0 267 | } 268 | 269 | func (x *HeaderBBox) GetTop() int64 { 270 | if x != nil && x.Top != nil { 271 | return *x.Top 272 | } 273 | return 0 274 | } 275 | 276 | func (x *HeaderBBox) GetBottom() int64 { 277 | if x != nil && x.Bottom != nil { 278 | return *x.Bottom 279 | } 280 | return 0 281 | } 282 | 283 | type PrimitiveBlock struct { 284 | state protoimpl.MessageState 285 | sizeCache protoimpl.SizeCache 286 | unknownFields protoimpl.UnknownFields 287 | 288 | Stringtable *StringTable `protobuf:"bytes,1,req,name=stringtable" json:"stringtable,omitempty"` 289 | Primitivegroup []*PrimitiveGroup `protobuf:"bytes,2,rep,name=primitivegroup" json:"primitivegroup,omitempty"` 290 | // Granularity, units of nanodegrees, used to store coordinates in this block. 291 | Granularity *int32 `protobuf:"varint,17,opt,name=granularity,def=100" json:"granularity,omitempty"` 292 | // Offset value between the output coordinates and the granularity grid in units of nanodegrees. 293 | LatOffset *int64 `protobuf:"varint,19,opt,name=lat_offset,json=latOffset,def=0" json:"lat_offset,omitempty"` 294 | LonOffset *int64 `protobuf:"varint,20,opt,name=lon_offset,json=lonOffset,def=0" json:"lon_offset,omitempty"` 295 | // Granularity of dates, normally represented in units of milliseconds since the 1970 epoch. 296 | DateGranularity *int32 `protobuf:"varint,18,opt,name=date_granularity,json=dateGranularity,def=1000" json:"date_granularity,omitempty"` 297 | } 298 | 299 | // Default values for PrimitiveBlock fields. 300 | const ( 301 | Default_PrimitiveBlock_Granularity = int32(100) 302 | Default_PrimitiveBlock_LatOffset = int64(0) 303 | Default_PrimitiveBlock_LonOffset = int64(0) 304 | Default_PrimitiveBlock_DateGranularity = int32(1000) 305 | ) 306 | 307 | func (x *PrimitiveBlock) Reset() { 308 | *x = PrimitiveBlock{} 309 | if protoimpl.UnsafeEnabled { 310 | mi := &file_osmformat_proto_msgTypes[2] 311 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 312 | ms.StoreMessageInfo(mi) 313 | } 314 | } 315 | 316 | func (x *PrimitiveBlock) String() string { 317 | return protoimpl.X.MessageStringOf(x) 318 | } 319 | 320 | func (*PrimitiveBlock) ProtoMessage() {} 321 | 322 | func (x *PrimitiveBlock) ProtoReflect() protoreflect.Message { 323 | mi := &file_osmformat_proto_msgTypes[2] 324 | if protoimpl.UnsafeEnabled && x != nil { 325 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 326 | if ms.LoadMessageInfo() == nil { 327 | ms.StoreMessageInfo(mi) 328 | } 329 | return ms 330 | } 331 | return mi.MessageOf(x) 332 | } 333 | 334 | // Deprecated: Use PrimitiveBlock.ProtoReflect.Descriptor instead. 335 | func (*PrimitiveBlock) Descriptor() ([]byte, []int) { 336 | return file_osmformat_proto_rawDescGZIP(), []int{2} 337 | } 338 | 339 | func (x *PrimitiveBlock) GetStringtable() *StringTable { 340 | if x != nil { 341 | return x.Stringtable 342 | } 343 | return nil 344 | } 345 | 346 | func (x *PrimitiveBlock) GetPrimitivegroup() []*PrimitiveGroup { 347 | if x != nil { 348 | return x.Primitivegroup 349 | } 350 | return nil 351 | } 352 | 353 | func (x *PrimitiveBlock) GetGranularity() int32 { 354 | if x != nil && x.Granularity != nil { 355 | return *x.Granularity 356 | } 357 | return Default_PrimitiveBlock_Granularity 358 | } 359 | 360 | func (x *PrimitiveBlock) GetLatOffset() int64 { 361 | if x != nil && x.LatOffset != nil { 362 | return *x.LatOffset 363 | } 364 | return Default_PrimitiveBlock_LatOffset 365 | } 366 | 367 | func (x *PrimitiveBlock) GetLonOffset() int64 { 368 | if x != nil && x.LonOffset != nil { 369 | return *x.LonOffset 370 | } 371 | return Default_PrimitiveBlock_LonOffset 372 | } 373 | 374 | func (x *PrimitiveBlock) GetDateGranularity() int32 { 375 | if x != nil && x.DateGranularity != nil { 376 | return *x.DateGranularity 377 | } 378 | return Default_PrimitiveBlock_DateGranularity 379 | } 380 | 381 | // Group of OSMPrimitives. All primitives in a group must be the same type. 382 | type PrimitiveGroup struct { 383 | state protoimpl.MessageState 384 | sizeCache protoimpl.SizeCache 385 | unknownFields protoimpl.UnknownFields 386 | 387 | Nodes []*Node `protobuf:"bytes,1,rep,name=nodes" json:"nodes,omitempty"` 388 | Dense *DenseNodes `protobuf:"bytes,2,opt,name=dense" json:"dense,omitempty"` 389 | Ways []*Way `protobuf:"bytes,3,rep,name=ways" json:"ways,omitempty"` 390 | Relations []*Relation `protobuf:"bytes,4,rep,name=relations" json:"relations,omitempty"` 391 | Changesets []*ChangeSet `protobuf:"bytes,5,rep,name=changesets" json:"changesets,omitempty"` 392 | } 393 | 394 | func (x *PrimitiveGroup) Reset() { 395 | *x = PrimitiveGroup{} 396 | if protoimpl.UnsafeEnabled { 397 | mi := &file_osmformat_proto_msgTypes[3] 398 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 399 | ms.StoreMessageInfo(mi) 400 | } 401 | } 402 | 403 | func (x *PrimitiveGroup) String() string { 404 | return protoimpl.X.MessageStringOf(x) 405 | } 406 | 407 | func (*PrimitiveGroup) ProtoMessage() {} 408 | 409 | func (x *PrimitiveGroup) ProtoReflect() protoreflect.Message { 410 | mi := &file_osmformat_proto_msgTypes[3] 411 | if protoimpl.UnsafeEnabled && x != nil { 412 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 413 | if ms.LoadMessageInfo() == nil { 414 | ms.StoreMessageInfo(mi) 415 | } 416 | return ms 417 | } 418 | return mi.MessageOf(x) 419 | } 420 | 421 | // Deprecated: Use PrimitiveGroup.ProtoReflect.Descriptor instead. 422 | func (*PrimitiveGroup) Descriptor() ([]byte, []int) { 423 | return file_osmformat_proto_rawDescGZIP(), []int{3} 424 | } 425 | 426 | func (x *PrimitiveGroup) GetNodes() []*Node { 427 | if x != nil { 428 | return x.Nodes 429 | } 430 | return nil 431 | } 432 | 433 | func (x *PrimitiveGroup) GetDense() *DenseNodes { 434 | if x != nil { 435 | return x.Dense 436 | } 437 | return nil 438 | } 439 | 440 | func (x *PrimitiveGroup) GetWays() []*Way { 441 | if x != nil { 442 | return x.Ways 443 | } 444 | return nil 445 | } 446 | 447 | func (x *PrimitiveGroup) GetRelations() []*Relation { 448 | if x != nil { 449 | return x.Relations 450 | } 451 | return nil 452 | } 453 | 454 | func (x *PrimitiveGroup) GetChangesets() []*ChangeSet { 455 | if x != nil { 456 | return x.Changesets 457 | } 458 | return nil 459 | } 460 | 461 | //* String table, contains the common strings in each block. 462 | // 463 | //Note that we reserve index '0' as a delimiter, so the entry at that 464 | //index in the table is ALWAYS blank and unused. 465 | // 466 | type StringTable struct { 467 | state protoimpl.MessageState 468 | sizeCache protoimpl.SizeCache 469 | unknownFields protoimpl.UnknownFields 470 | 471 | S []string `protobuf:"bytes,1,rep,name=s" json:"s,omitempty"` 472 | } 473 | 474 | func (x *StringTable) Reset() { 475 | *x = StringTable{} 476 | if protoimpl.UnsafeEnabled { 477 | mi := &file_osmformat_proto_msgTypes[4] 478 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 479 | ms.StoreMessageInfo(mi) 480 | } 481 | } 482 | 483 | func (x *StringTable) String() string { 484 | return protoimpl.X.MessageStringOf(x) 485 | } 486 | 487 | func (*StringTable) ProtoMessage() {} 488 | 489 | func (x *StringTable) ProtoReflect() protoreflect.Message { 490 | mi := &file_osmformat_proto_msgTypes[4] 491 | if protoimpl.UnsafeEnabled && x != nil { 492 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 493 | if ms.LoadMessageInfo() == nil { 494 | ms.StoreMessageInfo(mi) 495 | } 496 | return ms 497 | } 498 | return mi.MessageOf(x) 499 | } 500 | 501 | // Deprecated: Use StringTable.ProtoReflect.Descriptor instead. 502 | func (*StringTable) Descriptor() ([]byte, []int) { 503 | return file_osmformat_proto_rawDescGZIP(), []int{4} 504 | } 505 | 506 | func (x *StringTable) GetS() []string { 507 | if x != nil { 508 | return x.S 509 | } 510 | return nil 511 | } 512 | 513 | // Optional metadata that may be included into each primitive. 514 | type Info struct { 515 | state protoimpl.MessageState 516 | sizeCache protoimpl.SizeCache 517 | unknownFields protoimpl.UnknownFields 518 | 519 | Version *int32 `protobuf:"varint,1,opt,name=version,def=-1" json:"version,omitempty"` 520 | Timestamp *int64 `protobuf:"varint,2,opt,name=timestamp" json:"timestamp,omitempty"` 521 | Changeset *int64 `protobuf:"varint,3,opt,name=changeset" json:"changeset,omitempty"` 522 | Uid *int32 `protobuf:"varint,4,opt,name=uid" json:"uid,omitempty"` 523 | UserSid *uint32 `protobuf:"varint,5,opt,name=user_sid,json=userSid" json:"user_sid,omitempty"` // String IDs 524 | // The visible flag is used to store history information. It indicates that 525 | // the current object version has been created by a delete operation on the 526 | // OSM API. 527 | // When a writer sets this flag, it MUST add a required_features tag with 528 | // value "HistoricalInformation" to the HeaderBlock. 529 | // If this flag is not available for some object it MUST be assumed to be 530 | // true if the file has the required_features tag "HistoricalInformation" 531 | // set. 532 | Visible *bool `protobuf:"varint,6,opt,name=visible" json:"visible,omitempty"` 533 | } 534 | 535 | // Default values for Info fields. 536 | const ( 537 | Default_Info_Version = int32(-1) 538 | ) 539 | 540 | func (x *Info) Reset() { 541 | *x = Info{} 542 | if protoimpl.UnsafeEnabled { 543 | mi := &file_osmformat_proto_msgTypes[5] 544 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 545 | ms.StoreMessageInfo(mi) 546 | } 547 | } 548 | 549 | func (x *Info) String() string { 550 | return protoimpl.X.MessageStringOf(x) 551 | } 552 | 553 | func (*Info) ProtoMessage() {} 554 | 555 | func (x *Info) ProtoReflect() protoreflect.Message { 556 | mi := &file_osmformat_proto_msgTypes[5] 557 | if protoimpl.UnsafeEnabled && x != nil { 558 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 559 | if ms.LoadMessageInfo() == nil { 560 | ms.StoreMessageInfo(mi) 561 | } 562 | return ms 563 | } 564 | return mi.MessageOf(x) 565 | } 566 | 567 | // Deprecated: Use Info.ProtoReflect.Descriptor instead. 568 | func (*Info) Descriptor() ([]byte, []int) { 569 | return file_osmformat_proto_rawDescGZIP(), []int{5} 570 | } 571 | 572 | func (x *Info) GetVersion() int32 { 573 | if x != nil && x.Version != nil { 574 | return *x.Version 575 | } 576 | return Default_Info_Version 577 | } 578 | 579 | func (x *Info) GetTimestamp() int64 { 580 | if x != nil && x.Timestamp != nil { 581 | return *x.Timestamp 582 | } 583 | return 0 584 | } 585 | 586 | func (x *Info) GetChangeset() int64 { 587 | if x != nil && x.Changeset != nil { 588 | return *x.Changeset 589 | } 590 | return 0 591 | } 592 | 593 | func (x *Info) GetUid() int32 { 594 | if x != nil && x.Uid != nil { 595 | return *x.Uid 596 | } 597 | return 0 598 | } 599 | 600 | func (x *Info) GetUserSid() uint32 { 601 | if x != nil && x.UserSid != nil { 602 | return *x.UserSid 603 | } 604 | return 0 605 | } 606 | 607 | func (x *Info) GetVisible() bool { 608 | if x != nil && x.Visible != nil { 609 | return *x.Visible 610 | } 611 | return false 612 | } 613 | 614 | //* Optional metadata that may be included into each primitive. Special dense format used in DenseNodes. 615 | type DenseInfo struct { 616 | state protoimpl.MessageState 617 | sizeCache protoimpl.SizeCache 618 | unknownFields protoimpl.UnknownFields 619 | 620 | Version []int32 `protobuf:"varint,1,rep,packed,name=version" json:"version,omitempty"` 621 | Timestamp []int64 `protobuf:"zigzag64,2,rep,packed,name=timestamp" json:"timestamp,omitempty"` // DELTA coded 622 | Changeset []int64 `protobuf:"zigzag64,3,rep,packed,name=changeset" json:"changeset,omitempty"` // DELTA coded 623 | Uid []int32 `protobuf:"zigzag32,4,rep,packed,name=uid" json:"uid,omitempty"` // DELTA coded 624 | UserSid []int32 `protobuf:"zigzag32,5,rep,packed,name=user_sid,json=userSid" json:"user_sid,omitempty"` // String IDs for usernames. DELTA coded 625 | // The visible flag is used to store history information. It indicates that 626 | // the current object version has been created by a delete operation on the 627 | // OSM API. 628 | // When a writer sets this flag, it MUST add a required_features tag with 629 | // value "HistoricalInformation" to the HeaderBlock. 630 | // If this flag is not available for some object it MUST be assumed to be 631 | // true if the file has the required_features tag "HistoricalInformation" 632 | // set. 633 | Visible []bool `protobuf:"varint,6,rep,packed,name=visible" json:"visible,omitempty"` 634 | } 635 | 636 | func (x *DenseInfo) Reset() { 637 | *x = DenseInfo{} 638 | if protoimpl.UnsafeEnabled { 639 | mi := &file_osmformat_proto_msgTypes[6] 640 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 641 | ms.StoreMessageInfo(mi) 642 | } 643 | } 644 | 645 | func (x *DenseInfo) String() string { 646 | return protoimpl.X.MessageStringOf(x) 647 | } 648 | 649 | func (*DenseInfo) ProtoMessage() {} 650 | 651 | func (x *DenseInfo) ProtoReflect() protoreflect.Message { 652 | mi := &file_osmformat_proto_msgTypes[6] 653 | if protoimpl.UnsafeEnabled && x != nil { 654 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 655 | if ms.LoadMessageInfo() == nil { 656 | ms.StoreMessageInfo(mi) 657 | } 658 | return ms 659 | } 660 | return mi.MessageOf(x) 661 | } 662 | 663 | // Deprecated: Use DenseInfo.ProtoReflect.Descriptor instead. 664 | func (*DenseInfo) Descriptor() ([]byte, []int) { 665 | return file_osmformat_proto_rawDescGZIP(), []int{6} 666 | } 667 | 668 | func (x *DenseInfo) GetVersion() []int32 { 669 | if x != nil { 670 | return x.Version 671 | } 672 | return nil 673 | } 674 | 675 | func (x *DenseInfo) GetTimestamp() []int64 { 676 | if x != nil { 677 | return x.Timestamp 678 | } 679 | return nil 680 | } 681 | 682 | func (x *DenseInfo) GetChangeset() []int64 { 683 | if x != nil { 684 | return x.Changeset 685 | } 686 | return nil 687 | } 688 | 689 | func (x *DenseInfo) GetUid() []int32 { 690 | if x != nil { 691 | return x.Uid 692 | } 693 | return nil 694 | } 695 | 696 | func (x *DenseInfo) GetUserSid() []int32 { 697 | if x != nil { 698 | return x.UserSid 699 | } 700 | return nil 701 | } 702 | 703 | func (x *DenseInfo) GetVisible() []bool { 704 | if x != nil { 705 | return x.Visible 706 | } 707 | return nil 708 | } 709 | 710 | // This is kept for backwards compatibility but not used anywhere. 711 | type ChangeSet struct { 712 | state protoimpl.MessageState 713 | sizeCache protoimpl.SizeCache 714 | unknownFields protoimpl.UnknownFields 715 | 716 | Id *int64 `protobuf:"varint,1,req,name=id" json:"id,omitempty"` 717 | } 718 | 719 | func (x *ChangeSet) Reset() { 720 | *x = ChangeSet{} 721 | if protoimpl.UnsafeEnabled { 722 | mi := &file_osmformat_proto_msgTypes[7] 723 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 724 | ms.StoreMessageInfo(mi) 725 | } 726 | } 727 | 728 | func (x *ChangeSet) String() string { 729 | return protoimpl.X.MessageStringOf(x) 730 | } 731 | 732 | func (*ChangeSet) ProtoMessage() {} 733 | 734 | func (x *ChangeSet) ProtoReflect() protoreflect.Message { 735 | mi := &file_osmformat_proto_msgTypes[7] 736 | if protoimpl.UnsafeEnabled && x != nil { 737 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 738 | if ms.LoadMessageInfo() == nil { 739 | ms.StoreMessageInfo(mi) 740 | } 741 | return ms 742 | } 743 | return mi.MessageOf(x) 744 | } 745 | 746 | // Deprecated: Use ChangeSet.ProtoReflect.Descriptor instead. 747 | func (*ChangeSet) Descriptor() ([]byte, []int) { 748 | return file_osmformat_proto_rawDescGZIP(), []int{7} 749 | } 750 | 751 | func (x *ChangeSet) GetId() int64 { 752 | if x != nil && x.Id != nil { 753 | return *x.Id 754 | } 755 | return 0 756 | } 757 | 758 | type Node struct { 759 | state protoimpl.MessageState 760 | sizeCache protoimpl.SizeCache 761 | unknownFields protoimpl.UnknownFields 762 | 763 | Id *int64 `protobuf:"zigzag64,1,req,name=id" json:"id,omitempty"` 764 | // Parallel arrays. 765 | Keys []uint32 `protobuf:"varint,2,rep,packed,name=keys" json:"keys,omitempty"` // String IDs. 766 | Vals []uint32 `protobuf:"varint,3,rep,packed,name=vals" json:"vals,omitempty"` // String IDs. 767 | Info *Info `protobuf:"bytes,4,opt,name=info" json:"info,omitempty"` // May be omitted in omitmeta 768 | Lat *int64 `protobuf:"zigzag64,8,req,name=lat" json:"lat,omitempty"` 769 | Lon *int64 `protobuf:"zigzag64,9,req,name=lon" json:"lon,omitempty"` 770 | } 771 | 772 | func (x *Node) Reset() { 773 | *x = Node{} 774 | if protoimpl.UnsafeEnabled { 775 | mi := &file_osmformat_proto_msgTypes[8] 776 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 777 | ms.StoreMessageInfo(mi) 778 | } 779 | } 780 | 781 | func (x *Node) String() string { 782 | return protoimpl.X.MessageStringOf(x) 783 | } 784 | 785 | func (*Node) ProtoMessage() {} 786 | 787 | func (x *Node) ProtoReflect() protoreflect.Message { 788 | mi := &file_osmformat_proto_msgTypes[8] 789 | if protoimpl.UnsafeEnabled && x != nil { 790 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 791 | if ms.LoadMessageInfo() == nil { 792 | ms.StoreMessageInfo(mi) 793 | } 794 | return ms 795 | } 796 | return mi.MessageOf(x) 797 | } 798 | 799 | // Deprecated: Use Node.ProtoReflect.Descriptor instead. 800 | func (*Node) Descriptor() ([]byte, []int) { 801 | return file_osmformat_proto_rawDescGZIP(), []int{8} 802 | } 803 | 804 | func (x *Node) GetId() int64 { 805 | if x != nil && x.Id != nil { 806 | return *x.Id 807 | } 808 | return 0 809 | } 810 | 811 | func (x *Node) GetKeys() []uint32 { 812 | if x != nil { 813 | return x.Keys 814 | } 815 | return nil 816 | } 817 | 818 | func (x *Node) GetVals() []uint32 { 819 | if x != nil { 820 | return x.Vals 821 | } 822 | return nil 823 | } 824 | 825 | func (x *Node) GetInfo() *Info { 826 | if x != nil { 827 | return x.Info 828 | } 829 | return nil 830 | } 831 | 832 | func (x *Node) GetLat() int64 { 833 | if x != nil && x.Lat != nil { 834 | return *x.Lat 835 | } 836 | return 0 837 | } 838 | 839 | func (x *Node) GetLon() int64 { 840 | if x != nil && x.Lon != nil { 841 | return *x.Lon 842 | } 843 | return 0 844 | } 845 | 846 | type DenseNodes struct { 847 | state protoimpl.MessageState 848 | sizeCache protoimpl.SizeCache 849 | unknownFields protoimpl.UnknownFields 850 | 851 | Id []int64 `protobuf:"zigzag64,1,rep,packed,name=id" json:"id,omitempty"` // DELTA coded 852 | Denseinfo *DenseInfo `protobuf:"bytes,5,opt,name=denseinfo" json:"denseinfo,omitempty"` 853 | Lat []int64 `protobuf:"zigzag64,8,rep,packed,name=lat" json:"lat,omitempty"` // DELTA coded 854 | Lon []int64 `protobuf:"zigzag64,9,rep,packed,name=lon" json:"lon,omitempty"` // DELTA coded 855 | // Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless. 856 | KeysVals []int32 `protobuf:"varint,10,rep,packed,name=keys_vals,json=keysVals" json:"keys_vals,omitempty"` 857 | } 858 | 859 | func (x *DenseNodes) Reset() { 860 | *x = DenseNodes{} 861 | if protoimpl.UnsafeEnabled { 862 | mi := &file_osmformat_proto_msgTypes[9] 863 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 864 | ms.StoreMessageInfo(mi) 865 | } 866 | } 867 | 868 | func (x *DenseNodes) String() string { 869 | return protoimpl.X.MessageStringOf(x) 870 | } 871 | 872 | func (*DenseNodes) ProtoMessage() {} 873 | 874 | func (x *DenseNodes) ProtoReflect() protoreflect.Message { 875 | mi := &file_osmformat_proto_msgTypes[9] 876 | if protoimpl.UnsafeEnabled && x != nil { 877 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 878 | if ms.LoadMessageInfo() == nil { 879 | ms.StoreMessageInfo(mi) 880 | } 881 | return ms 882 | } 883 | return mi.MessageOf(x) 884 | } 885 | 886 | // Deprecated: Use DenseNodes.ProtoReflect.Descriptor instead. 887 | func (*DenseNodes) Descriptor() ([]byte, []int) { 888 | return file_osmformat_proto_rawDescGZIP(), []int{9} 889 | } 890 | 891 | func (x *DenseNodes) GetId() []int64 { 892 | if x != nil { 893 | return x.Id 894 | } 895 | return nil 896 | } 897 | 898 | func (x *DenseNodes) GetDenseinfo() *DenseInfo { 899 | if x != nil { 900 | return x.Denseinfo 901 | } 902 | return nil 903 | } 904 | 905 | func (x *DenseNodes) GetLat() []int64 { 906 | if x != nil { 907 | return x.Lat 908 | } 909 | return nil 910 | } 911 | 912 | func (x *DenseNodes) GetLon() []int64 { 913 | if x != nil { 914 | return x.Lon 915 | } 916 | return nil 917 | } 918 | 919 | func (x *DenseNodes) GetKeysVals() []int32 { 920 | if x != nil { 921 | return x.KeysVals 922 | } 923 | return nil 924 | } 925 | 926 | type Way struct { 927 | state protoimpl.MessageState 928 | sizeCache protoimpl.SizeCache 929 | unknownFields protoimpl.UnknownFields 930 | 931 | Id *int64 `protobuf:"varint,1,req,name=id" json:"id,omitempty"` 932 | // Parallel arrays. 933 | Keys []uint32 `protobuf:"varint,2,rep,packed,name=keys" json:"keys,omitempty"` 934 | Vals []uint32 `protobuf:"varint,3,rep,packed,name=vals" json:"vals,omitempty"` 935 | Info *Info `protobuf:"bytes,4,opt,name=info" json:"info,omitempty"` 936 | Refs []int64 `protobuf:"zigzag64,8,rep,packed,name=refs" json:"refs,omitempty"` // DELTA coded 937 | // The following two fields are optional. They are only used in a special 938 | // format where node locations are also added to the ways. This makes the 939 | // files larger, but allows creating way geometries directly. 940 | // 941 | // If this is used, you MUST set the optional_features tag "LocationsOnWays" 942 | // and the number of values in refs, lat, and lon MUST be the same. 943 | Lat []int64 `protobuf:"zigzag64,9,rep,packed,name=lat" json:"lat,omitempty"` // DELTA coded, optional 944 | Lon []int64 `protobuf:"zigzag64,10,rep,packed,name=lon" json:"lon,omitempty"` // DELTA coded, optional 945 | } 946 | 947 | func (x *Way) Reset() { 948 | *x = Way{} 949 | if protoimpl.UnsafeEnabled { 950 | mi := &file_osmformat_proto_msgTypes[10] 951 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 952 | ms.StoreMessageInfo(mi) 953 | } 954 | } 955 | 956 | func (x *Way) String() string { 957 | return protoimpl.X.MessageStringOf(x) 958 | } 959 | 960 | func (*Way) ProtoMessage() {} 961 | 962 | func (x *Way) ProtoReflect() protoreflect.Message { 963 | mi := &file_osmformat_proto_msgTypes[10] 964 | if protoimpl.UnsafeEnabled && x != nil { 965 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 966 | if ms.LoadMessageInfo() == nil { 967 | ms.StoreMessageInfo(mi) 968 | } 969 | return ms 970 | } 971 | return mi.MessageOf(x) 972 | } 973 | 974 | // Deprecated: Use Way.ProtoReflect.Descriptor instead. 975 | func (*Way) Descriptor() ([]byte, []int) { 976 | return file_osmformat_proto_rawDescGZIP(), []int{10} 977 | } 978 | 979 | func (x *Way) GetId() int64 { 980 | if x != nil && x.Id != nil { 981 | return *x.Id 982 | } 983 | return 0 984 | } 985 | 986 | func (x *Way) GetKeys() []uint32 { 987 | if x != nil { 988 | return x.Keys 989 | } 990 | return nil 991 | } 992 | 993 | func (x *Way) GetVals() []uint32 { 994 | if x != nil { 995 | return x.Vals 996 | } 997 | return nil 998 | } 999 | 1000 | func (x *Way) GetInfo() *Info { 1001 | if x != nil { 1002 | return x.Info 1003 | } 1004 | return nil 1005 | } 1006 | 1007 | func (x *Way) GetRefs() []int64 { 1008 | if x != nil { 1009 | return x.Refs 1010 | } 1011 | return nil 1012 | } 1013 | 1014 | func (x *Way) GetLat() []int64 { 1015 | if x != nil { 1016 | return x.Lat 1017 | } 1018 | return nil 1019 | } 1020 | 1021 | func (x *Way) GetLon() []int64 { 1022 | if x != nil { 1023 | return x.Lon 1024 | } 1025 | return nil 1026 | } 1027 | 1028 | type Relation struct { 1029 | state protoimpl.MessageState 1030 | sizeCache protoimpl.SizeCache 1031 | unknownFields protoimpl.UnknownFields 1032 | 1033 | Id *int64 `protobuf:"varint,1,req,name=id" json:"id,omitempty"` 1034 | // Parallel arrays. 1035 | Keys []uint32 `protobuf:"varint,2,rep,packed,name=keys" json:"keys,omitempty"` 1036 | Vals []uint32 `protobuf:"varint,3,rep,packed,name=vals" json:"vals,omitempty"` 1037 | Info *Info `protobuf:"bytes,4,opt,name=info" json:"info,omitempty"` 1038 | // Parallel arrays 1039 | 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 1040 | Memids []int64 `protobuf:"zigzag64,9,rep,packed,name=memids" json:"memids,omitempty"` // DELTA encoded 1041 | Types []Relation_MemberType `protobuf:"varint,10,rep,packed,name=types,enum=OSMPBF.Relation_MemberType" json:"types,omitempty"` 1042 | } 1043 | 1044 | func (x *Relation) Reset() { 1045 | *x = Relation{} 1046 | if protoimpl.UnsafeEnabled { 1047 | mi := &file_osmformat_proto_msgTypes[11] 1048 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 1049 | ms.StoreMessageInfo(mi) 1050 | } 1051 | } 1052 | 1053 | func (x *Relation) String() string { 1054 | return protoimpl.X.MessageStringOf(x) 1055 | } 1056 | 1057 | func (*Relation) ProtoMessage() {} 1058 | 1059 | func (x *Relation) ProtoReflect() protoreflect.Message { 1060 | mi := &file_osmformat_proto_msgTypes[11] 1061 | if protoimpl.UnsafeEnabled && x != nil { 1062 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 1063 | if ms.LoadMessageInfo() == nil { 1064 | ms.StoreMessageInfo(mi) 1065 | } 1066 | return ms 1067 | } 1068 | return mi.MessageOf(x) 1069 | } 1070 | 1071 | // Deprecated: Use Relation.ProtoReflect.Descriptor instead. 1072 | func (*Relation) Descriptor() ([]byte, []int) { 1073 | return file_osmformat_proto_rawDescGZIP(), []int{11} 1074 | } 1075 | 1076 | func (x *Relation) GetId() int64 { 1077 | if x != nil && x.Id != nil { 1078 | return *x.Id 1079 | } 1080 | return 0 1081 | } 1082 | 1083 | func (x *Relation) GetKeys() []uint32 { 1084 | if x != nil { 1085 | return x.Keys 1086 | } 1087 | return nil 1088 | } 1089 | 1090 | func (x *Relation) GetVals() []uint32 { 1091 | if x != nil { 1092 | return x.Vals 1093 | } 1094 | return nil 1095 | } 1096 | 1097 | func (x *Relation) GetInfo() *Info { 1098 | if x != nil { 1099 | return x.Info 1100 | } 1101 | return nil 1102 | } 1103 | 1104 | func (x *Relation) GetRolesSid() []int32 { 1105 | if x != nil { 1106 | return x.RolesSid 1107 | } 1108 | return nil 1109 | } 1110 | 1111 | func (x *Relation) GetMemids() []int64 { 1112 | if x != nil { 1113 | return x.Memids 1114 | } 1115 | return nil 1116 | } 1117 | 1118 | func (x *Relation) GetTypes() []Relation_MemberType { 1119 | if x != nil { 1120 | return x.Types 1121 | } 1122 | return nil 1123 | } 1124 | 1125 | var File_osmformat_proto protoreflect.FileDescriptor 1126 | 1127 | var file_osmformat_proto_rawDesc = []byte{ 1128 | 0x0a, 0x0f, 0x6f, 0x73, 0x6d, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 1129 | 0x6f, 0x12, 0x06, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x22, 0xa3, 0x03, 0x0a, 0x0b, 0x48, 0x65, 1130 | 0x61, 0x64, 0x65, 0x72, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x26, 0x0a, 0x04, 0x62, 0x62, 0x6f, 1131 | 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 1132 | 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x42, 0x6f, 0x78, 0x52, 0x04, 0x62, 0x62, 0x6f, 1133 | 0x78, 0x12, 0x2b, 0x0a, 0x11, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x65, 1134 | 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x72, 0x65, 1135 | 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x2b, 1136 | 0x0a, 0x11, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 1137 | 0x72, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x6f, 0x70, 0x74, 0x69, 0x6f, 1138 | 0x6e, 0x61, 0x6c, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x77, 1139 | 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x18, 0x10, 0x20, 1140 | 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x72, 0x69, 0x74, 0x69, 0x6e, 0x67, 0x70, 0x72, 0x6f, 0x67, 1141 | 0x72, 0x61, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x11, 0x20, 1142 | 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x42, 0x0a, 0x1d, 0x6f, 1143 | 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 1144 | 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x20, 0x20, 0x01, 1145 | 0x28, 0x03, 0x52, 0x1b, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x69, 1146 | 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 1147 | 0x4d, 0x0a, 0x23, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 1148 | 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x5f, 1149 | 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x21, 0x20, 0x01, 0x28, 0x03, 0x52, 0x20, 0x6f, 0x73, 1150 | 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 1151 | 0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x3f, 1152 | 0x0a, 0x1c, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 1153 | 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x61, 0x73, 0x65, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x22, 1154 | 0x20, 0x01, 0x28, 0x09, 0x52, 0x19, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x69, 0x73, 0x52, 0x65, 0x70, 1155 | 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x73, 0x65, 0x55, 0x72, 0x6c, 0x22, 1156 | 0x60, 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x42, 0x6f, 0x78, 0x12, 0x12, 0x0a, 1157 | 0x04, 0x6c, 0x65, 0x66, 0x74, 0x18, 0x01, 0x20, 0x02, 0x28, 0x12, 0x52, 0x04, 0x6c, 0x65, 0x66, 1158 | 0x74, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x02, 0x28, 0x12, 1159 | 0x52, 0x05, 0x72, 0x69, 0x67, 0x68, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x6f, 0x70, 0x18, 0x03, 1160 | 0x20, 0x02, 0x28, 0x12, 0x52, 0x03, 0x74, 0x6f, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x6f, 0x74, 1161 | 0x74, 0x6f, 0x6d, 0x18, 0x04, 0x20, 0x02, 0x28, 0x12, 0x52, 0x06, 0x62, 0x6f, 0x74, 0x74, 0x6f, 1162 | 0x6d, 0x22, 0xa3, 0x02, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x42, 1163 | 0x6c, 0x6f, 0x63, 0x6b, 0x12, 0x35, 0x0a, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x74, 0x61, 1164 | 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x02, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 1165 | 0x42, 0x46, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x0b, 1166 | 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x3e, 0x0a, 0x0e, 0x70, 1167 | 0x72, 0x69, 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 1168 | 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x50, 0x72, 0x69, 1169 | 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x52, 0x0e, 0x70, 0x72, 0x69, 1170 | 0x6d, 0x69, 0x74, 0x69, 0x76, 0x65, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x25, 0x0a, 0x0b, 0x67, 1171 | 0x72, 0x61, 0x6e, 0x75, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x18, 0x11, 0x20, 0x01, 0x28, 0x05, 1172 | 0x3a, 0x03, 0x31, 0x30, 0x30, 0x52, 0x0b, 0x67, 0x72, 0x61, 0x6e, 0x75, 0x6c, 0x61, 0x72, 0x69, 1173 | 0x74, 0x79, 0x12, 0x20, 0x0a, 0x0a, 0x6c, 0x61, 0x74, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 1174 | 0x18, 0x13, 0x20, 0x01, 0x28, 0x03, 0x3a, 0x01, 0x30, 0x52, 0x09, 0x6c, 0x61, 0x74, 0x4f, 0x66, 1175 | 0x66, 0x73, 0x65, 0x74, 0x12, 0x20, 0x0a, 0x0a, 0x6c, 0x6f, 0x6e, 0x5f, 0x6f, 0x66, 0x66, 0x73, 1176 | 0x65, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x03, 0x3a, 0x01, 0x30, 0x52, 0x09, 0x6c, 0x6f, 0x6e, 1177 | 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x2f, 0x0a, 0x10, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x67, 1178 | 0x72, 0x61, 0x6e, 0x75, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x18, 0x12, 0x20, 0x01, 0x28, 0x05, 1179 | 0x3a, 0x04, 0x31, 0x30, 0x30, 0x30, 0x52, 0x0f, 0x64, 0x61, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 1180 | 0x75, 0x6c, 0x61, 0x72, 0x69, 0x74, 0x79, 0x22, 0xe2, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x69, 0x6d, 1181 | 0x69, 0x74, 0x69, 0x76, 0x65, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x22, 0x0a, 0x05, 0x6e, 0x6f, 1182 | 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 1183 | 0x42, 0x46, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x28, 1184 | 0x0a, 0x05, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 1185 | 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x44, 0x65, 0x6e, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 1186 | 0x73, 0x52, 0x05, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x77, 0x61, 0x79, 0x73, 1187 | 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 1188 | 0x57, 0x61, 0x79, 0x52, 0x04, 0x77, 0x61, 0x79, 0x73, 0x12, 0x2e, 0x0a, 0x09, 0x72, 0x65, 0x6c, 1189 | 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x4f, 1190 | 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x09, 1191 | 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x63, 0x68, 0x61, 1192 | 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 1193 | 0x4f, 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x53, 0x65, 0x74, 1194 | 0x52, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x73, 0x22, 0x1b, 0x0a, 0x0b, 1195 | 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x0c, 0x0a, 0x01, 0x73, 1196 | 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x01, 0x73, 0x22, 0xa7, 0x01, 0x0a, 0x04, 0x49, 0x6e, 1197 | 0x66, 0x6f, 0x12, 0x1c, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 1198 | 0x01, 0x28, 0x05, 0x3a, 0x02, 0x2d, 0x31, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 1199 | 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 1200 | 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 1201 | 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 1202 | 0x03, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x12, 0x10, 0x0a, 0x03, 1203 | 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x19, 1204 | 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 1205 | 0x52, 0x07, 0x75, 0x73, 0x65, 0x72, 0x53, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x69, 0x73, 1206 | 0x69, 0x62, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x76, 0x69, 0x73, 0x69, 1207 | 0x62, 0x6c, 0x65, 0x22, 0xc0, 0x01, 0x0a, 0x09, 0x44, 0x65, 0x6e, 0x73, 0x65, 0x49, 0x6e, 0x66, 1208 | 0x6f, 0x12, 0x1c, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x03, 1209 | 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 1210 | 0x20, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x03, 1211 | 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 1212 | 0x70, 0x12, 0x20, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x65, 0x74, 0x18, 0x03, 1213 | 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 1214 | 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x03, 0x28, 0x11, 1215 | 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x1d, 0x0a, 0x08, 0x75, 0x73, 0x65, 1216 | 0x72, 0x5f, 0x73, 0x69, 0x64, 0x18, 0x05, 0x20, 0x03, 0x28, 0x11, 0x42, 0x02, 0x10, 0x01, 0x52, 1217 | 0x07, 0x75, 0x73, 0x65, 0x72, 0x53, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x07, 0x76, 0x69, 0x73, 0x69, 1218 | 0x62, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x08, 0x42, 0x02, 0x10, 0x01, 0x52, 0x07, 0x76, 1219 | 0x69, 0x73, 0x69, 0x62, 0x6c, 0x65, 0x22, 0x1b, 0x0a, 0x09, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 1220 | 0x53, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x03, 0x52, 1221 | 0x02, 0x69, 0x64, 0x22, 0x8c, 0x01, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 1222 | 0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x12, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x04, 1223 | 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 1224 | 0x6b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x0a, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 1225 | 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x20, 0x0a, 0x04, 1226 | 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x4f, 0x53, 0x4d, 1227 | 0x50, 0x42, 0x46, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x10, 1228 | 0x0a, 0x03, 0x6c, 0x61, 0x74, 0x18, 0x08, 0x20, 0x02, 0x28, 0x12, 0x52, 0x03, 0x6c, 0x61, 0x74, 1229 | 0x12, 0x10, 0x0a, 0x03, 0x6c, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x02, 0x28, 0x12, 0x52, 0x03, 0x6c, 1230 | 0x6f, 0x6e, 0x22, 0x9e, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x6e, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 1231 | 0x73, 0x12, 0x12, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 1232 | 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x09, 0x64, 0x65, 0x6e, 0x73, 0x65, 0x69, 0x6e, 1233 | 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 0x42, 1234 | 0x46, 0x2e, 0x44, 0x65, 0x6e, 0x73, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x64, 0x65, 0x6e, 1235 | 0x73, 0x65, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x14, 0x0a, 0x03, 0x6c, 0x61, 0x74, 0x18, 0x08, 0x20, 1236 | 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6c, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x03, 1237 | 0x6c, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6c, 1238 | 0x6f, 0x6e, 0x12, 0x1f, 0x0a, 0x09, 0x6b, 0x65, 0x79, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x73, 0x18, 1239 | 0x0a, 0x20, 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6b, 0x65, 0x79, 0x73, 0x56, 1240 | 0x61, 0x6c, 0x73, 0x22, 0xab, 0x01, 0x0a, 0x03, 0x57, 0x61, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 1241 | 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x04, 0x6b, 1242 | 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x6b, 1243 | 0x65, 0x79, 0x73, 0x12, 0x16, 0x0a, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 1244 | 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x20, 0x0a, 0x04, 0x69, 1245 | 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x4f, 0x53, 0x4d, 0x50, 1246 | 0x42, 0x46, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x16, 0x0a, 1247 | 0x04, 0x72, 0x65, 0x66, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 1248 | 0x04, 0x72, 0x65, 0x66, 0x73, 0x12, 0x14, 0x0a, 0x03, 0x6c, 0x61, 0x74, 0x18, 0x09, 0x20, 0x03, 1249 | 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6c, 0x61, 0x74, 0x12, 0x14, 0x0a, 0x03, 0x6c, 1250 | 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x03, 0x6c, 0x6f, 1251 | 0x6e, 0x22, 0x8f, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 1252 | 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x02, 0x28, 0x03, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 1253 | 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 1254 | 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x12, 0x16, 0x0a, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x18, 0x03, 1255 | 0x20, 0x03, 0x28, 0x0d, 0x42, 0x02, 0x10, 0x01, 0x52, 0x04, 0x76, 0x61, 0x6c, 0x73, 0x12, 0x20, 1256 | 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x4f, 1257 | 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 1258 | 0x12, 0x1f, 0x0a, 0x09, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x5f, 0x73, 0x69, 0x64, 0x18, 0x08, 0x20, 1259 | 0x03, 0x28, 0x05, 0x42, 0x02, 0x10, 0x01, 0x52, 0x08, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x53, 0x69, 1260 | 0x64, 0x12, 0x1a, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x69, 0x64, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 1261 | 0x12, 0x42, 0x02, 0x10, 0x01, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x69, 0x64, 0x73, 0x12, 0x35, 0x0a, 1262 | 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x4f, 1263 | 0x53, 0x4d, 0x50, 0x42, 0x46, 0x2e, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 1264 | 0x65, 0x6d, 0x62, 0x65, 0x72, 0x54, 0x79, 0x70, 0x65, 0x42, 0x02, 0x10, 0x01, 0x52, 0x05, 0x74, 1265 | 0x79, 0x70, 0x65, 0x73, 0x22, 0x2d, 0x0a, 0x0a, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x54, 0x79, 1266 | 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 1267 | 0x57, 0x41, 0x59, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x52, 0x45, 0x4c, 0x41, 0x54, 0x49, 0x4f, 1268 | 0x4e, 0x10, 0x02, 0x42, 0x0f, 0x0a, 0x0d, 0x63, 0x72, 0x6f, 0x73, 0x62, 0x79, 0x2e, 0x62, 0x69, 1269 | 0x6e, 0x61, 0x72, 0x79, 1270 | } 1271 | 1272 | var ( 1273 | file_osmformat_proto_rawDescOnce sync.Once 1274 | file_osmformat_proto_rawDescData = file_osmformat_proto_rawDesc 1275 | ) 1276 | 1277 | func file_osmformat_proto_rawDescGZIP() []byte { 1278 | file_osmformat_proto_rawDescOnce.Do(func() { 1279 | file_osmformat_proto_rawDescData = protoimpl.X.CompressGZIP(file_osmformat_proto_rawDescData) 1280 | }) 1281 | return file_osmformat_proto_rawDescData 1282 | } 1283 | 1284 | var file_osmformat_proto_enumTypes = make([]protoimpl.EnumInfo, 1) 1285 | var file_osmformat_proto_msgTypes = make([]protoimpl.MessageInfo, 12) 1286 | var file_osmformat_proto_goTypes = []interface{}{ 1287 | (Relation_MemberType)(0), // 0: OSMPBF.Relation.MemberType 1288 | (*HeaderBlock)(nil), // 1: OSMPBF.HeaderBlock 1289 | (*HeaderBBox)(nil), // 2: OSMPBF.HeaderBBox 1290 | (*PrimitiveBlock)(nil), // 3: OSMPBF.PrimitiveBlock 1291 | (*PrimitiveGroup)(nil), // 4: OSMPBF.PrimitiveGroup 1292 | (*StringTable)(nil), // 5: OSMPBF.StringTable 1293 | (*Info)(nil), // 6: OSMPBF.Info 1294 | (*DenseInfo)(nil), // 7: OSMPBF.DenseInfo 1295 | (*ChangeSet)(nil), // 8: OSMPBF.ChangeSet 1296 | (*Node)(nil), // 9: OSMPBF.Node 1297 | (*DenseNodes)(nil), // 10: OSMPBF.DenseNodes 1298 | (*Way)(nil), // 11: OSMPBF.Way 1299 | (*Relation)(nil), // 12: OSMPBF.Relation 1300 | } 1301 | var file_osmformat_proto_depIdxs = []int32{ 1302 | 2, // 0: OSMPBF.HeaderBlock.bbox:type_name -> OSMPBF.HeaderBBox 1303 | 5, // 1: OSMPBF.PrimitiveBlock.stringtable:type_name -> OSMPBF.StringTable 1304 | 4, // 2: OSMPBF.PrimitiveBlock.primitivegroup:type_name -> OSMPBF.PrimitiveGroup 1305 | 9, // 3: OSMPBF.PrimitiveGroup.nodes:type_name -> OSMPBF.Node 1306 | 10, // 4: OSMPBF.PrimitiveGroup.dense:type_name -> OSMPBF.DenseNodes 1307 | 11, // 5: OSMPBF.PrimitiveGroup.ways:type_name -> OSMPBF.Way 1308 | 12, // 6: OSMPBF.PrimitiveGroup.relations:type_name -> OSMPBF.Relation 1309 | 8, // 7: OSMPBF.PrimitiveGroup.changesets:type_name -> OSMPBF.ChangeSet 1310 | 6, // 8: OSMPBF.Node.info:type_name -> OSMPBF.Info 1311 | 7, // 9: OSMPBF.DenseNodes.denseinfo:type_name -> OSMPBF.DenseInfo 1312 | 6, // 10: OSMPBF.Way.info:type_name -> OSMPBF.Info 1313 | 6, // 11: OSMPBF.Relation.info:type_name -> OSMPBF.Info 1314 | 0, // 12: OSMPBF.Relation.types:type_name -> OSMPBF.Relation.MemberType 1315 | 13, // [13:13] is the sub-list for method output_type 1316 | 13, // [13:13] is the sub-list for method input_type 1317 | 13, // [13:13] is the sub-list for extension type_name 1318 | 13, // [13:13] is the sub-list for extension extendee 1319 | 0, // [0:13] is the sub-list for field type_name 1320 | } 1321 | 1322 | func init() { file_osmformat_proto_init() } 1323 | func file_osmformat_proto_init() { 1324 | if File_osmformat_proto != nil { 1325 | return 1326 | } 1327 | if !protoimpl.UnsafeEnabled { 1328 | file_osmformat_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 1329 | switch v := v.(*HeaderBlock); i { 1330 | case 0: 1331 | return &v.state 1332 | case 1: 1333 | return &v.sizeCache 1334 | case 2: 1335 | return &v.unknownFields 1336 | default: 1337 | return nil 1338 | } 1339 | } 1340 | file_osmformat_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 1341 | switch v := v.(*HeaderBBox); i { 1342 | case 0: 1343 | return &v.state 1344 | case 1: 1345 | return &v.sizeCache 1346 | case 2: 1347 | return &v.unknownFields 1348 | default: 1349 | return nil 1350 | } 1351 | } 1352 | file_osmformat_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { 1353 | switch v := v.(*PrimitiveBlock); i { 1354 | case 0: 1355 | return &v.state 1356 | case 1: 1357 | return &v.sizeCache 1358 | case 2: 1359 | return &v.unknownFields 1360 | default: 1361 | return nil 1362 | } 1363 | } 1364 | file_osmformat_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { 1365 | switch v := v.(*PrimitiveGroup); i { 1366 | case 0: 1367 | return &v.state 1368 | case 1: 1369 | return &v.sizeCache 1370 | case 2: 1371 | return &v.unknownFields 1372 | default: 1373 | return nil 1374 | } 1375 | } 1376 | file_osmformat_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { 1377 | switch v := v.(*StringTable); i { 1378 | case 0: 1379 | return &v.state 1380 | case 1: 1381 | return &v.sizeCache 1382 | case 2: 1383 | return &v.unknownFields 1384 | default: 1385 | return nil 1386 | } 1387 | } 1388 | file_osmformat_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { 1389 | switch v := v.(*Info); i { 1390 | case 0: 1391 | return &v.state 1392 | case 1: 1393 | return &v.sizeCache 1394 | case 2: 1395 | return &v.unknownFields 1396 | default: 1397 | return nil 1398 | } 1399 | } 1400 | file_osmformat_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { 1401 | switch v := v.(*DenseInfo); i { 1402 | case 0: 1403 | return &v.state 1404 | case 1: 1405 | return &v.sizeCache 1406 | case 2: 1407 | return &v.unknownFields 1408 | default: 1409 | return nil 1410 | } 1411 | } 1412 | file_osmformat_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { 1413 | switch v := v.(*ChangeSet); i { 1414 | case 0: 1415 | return &v.state 1416 | case 1: 1417 | return &v.sizeCache 1418 | case 2: 1419 | return &v.unknownFields 1420 | default: 1421 | return nil 1422 | } 1423 | } 1424 | file_osmformat_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { 1425 | switch v := v.(*Node); i { 1426 | case 0: 1427 | return &v.state 1428 | case 1: 1429 | return &v.sizeCache 1430 | case 2: 1431 | return &v.unknownFields 1432 | default: 1433 | return nil 1434 | } 1435 | } 1436 | file_osmformat_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { 1437 | switch v := v.(*DenseNodes); i { 1438 | case 0: 1439 | return &v.state 1440 | case 1: 1441 | return &v.sizeCache 1442 | case 2: 1443 | return &v.unknownFields 1444 | default: 1445 | return nil 1446 | } 1447 | } 1448 | file_osmformat_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { 1449 | switch v := v.(*Way); i { 1450 | case 0: 1451 | return &v.state 1452 | case 1: 1453 | return &v.sizeCache 1454 | case 2: 1455 | return &v.unknownFields 1456 | default: 1457 | return nil 1458 | } 1459 | } 1460 | file_osmformat_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { 1461 | switch v := v.(*Relation); i { 1462 | case 0: 1463 | return &v.state 1464 | case 1: 1465 | return &v.sizeCache 1466 | case 2: 1467 | return &v.unknownFields 1468 | default: 1469 | return nil 1470 | } 1471 | } 1472 | } 1473 | type x struct{} 1474 | out := protoimpl.TypeBuilder{ 1475 | File: protoimpl.DescBuilder{ 1476 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 1477 | RawDescriptor: file_osmformat_proto_rawDesc, 1478 | NumEnums: 1, 1479 | NumMessages: 12, 1480 | NumExtensions: 0, 1481 | NumServices: 0, 1482 | }, 1483 | GoTypes: file_osmformat_proto_goTypes, 1484 | DependencyIndexes: file_osmformat_proto_depIdxs, 1485 | EnumInfos: file_osmformat_proto_enumTypes, 1486 | MessageInfos: file_osmformat_proto_msgTypes, 1487 | }.Build() 1488 | File_osmformat_proto = out.File 1489 | file_osmformat_proto_rawDesc = nil 1490 | file_osmformat_proto_goTypes = nil 1491 | file_osmformat_proto_depIdxs = nil 1492 | } 1493 | -------------------------------------------------------------------------------- /OSMPBF/osmformat.proto: -------------------------------------------------------------------------------- 1 | /** Copyright (c) 2010 Scott A. Crosby. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | 21 | */ 22 | 23 | syntax = "proto2"; 24 | 25 | option java_package = "crosby.binary"; 26 | package OSMPBF; 27 | 28 | /* OSM Binary file format 29 | 30 | This is the master schema file of the OSM binary file format. This 31 | file is designed to support limited random-access and future 32 | extendability. 33 | 34 | A binary OSM file consists of a sequence of FileBlocks (please see 35 | fileformat.proto). The first fileblock contains a serialized instance 36 | of HeaderBlock, followed by a sequence of PrimitiveBlock blocks that 37 | contain the primitives. 38 | 39 | Each primitiveblock is designed to be independently parsable. It 40 | contains a string table storing all strings in that block (keys and 41 | values in tags, roles in relations, usernames, etc.) as well as 42 | metadata containing the precision of coordinates or timestamps in that 43 | block. 44 | 45 | A primitiveblock contains a sequence of primitive groups, each 46 | containing primitives of the same type (nodes, densenodes, ways, 47 | relations). Coordinates are stored in signed 64-bit integers. Lat&lon 48 | are measured in units nanodegrees. The default of 49 | granularity of 100 nanodegrees corresponds to about 1cm on the ground, 50 | and a full lat or lon fits into 32 bits. 51 | 52 | Converting an integer to a latitude or longitude uses the formula: 53 | $OUT = IN * granularity / 10**9$. Many encoding schemes use delta 54 | coding when representing nodes and relations. 55 | 56 | */ 57 | 58 | ////////////////////////////////////////////////////////////////////////// 59 | ////////////////////////////////////////////////////////////////////////// 60 | 61 | /* Contains the file header. */ 62 | 63 | message HeaderBlock { 64 | optional HeaderBBox bbox = 1; 65 | 66 | /* Additional tags to aid in parsing this dataset */ 67 | repeated string required_features = 4; 68 | repeated string optional_features = 5; 69 | 70 | optional string writingprogram = 16; 71 | optional string source = 17; // From the bbox field. 72 | 73 | /* Tags that allow continuing an Osmosis replication */ 74 | 75 | // Replication timestamp, expressed in seconds since the epoch, 76 | // otherwise the same value as in the "timestamp=..." field 77 | // in the state.txt file used by Osmosis. 78 | optional int64 osmosis_replication_timestamp = 32; 79 | 80 | // Replication sequence number (sequenceNumber in state.txt). 81 | optional int64 osmosis_replication_sequence_number = 33; 82 | 83 | // Replication base URL (from Osmosis' configuration.txt file). 84 | optional string osmosis_replication_base_url = 34; 85 | } 86 | 87 | 88 | /** The bounding box field in the OSM header. BBOX, as used in the OSM 89 | header. Units are always in nanodegrees -- they do not obey 90 | granularity rules. */ 91 | 92 | message HeaderBBox { 93 | required sint64 left = 1; 94 | required sint64 right = 2; 95 | required sint64 top = 3; 96 | required sint64 bottom = 4; 97 | } 98 | 99 | 100 | /////////////////////////////////////////////////////////////////////// 101 | /////////////////////////////////////////////////////////////////////// 102 | 103 | 104 | message PrimitiveBlock { 105 | required StringTable stringtable = 1; 106 | repeated PrimitiveGroup primitivegroup = 2; 107 | 108 | // Granularity, units of nanodegrees, used to store coordinates in this block. 109 | optional int32 granularity = 17 [default=100]; 110 | 111 | // Offset value between the output coordinates and the granularity grid in units of nanodegrees. 112 | optional int64 lat_offset = 19 [default=0]; 113 | optional int64 lon_offset = 20 [default=0]; 114 | 115 | // Granularity of dates, normally represented in units of milliseconds since the 1970 epoch. 116 | optional int32 date_granularity = 18 [default=1000]; 117 | } 118 | 119 | // Group of OSMPrimitives. All primitives in a group must be the same type. 120 | message PrimitiveGroup { 121 | repeated Node nodes = 1; 122 | optional DenseNodes dense = 2; 123 | repeated Way ways = 3; 124 | repeated Relation relations = 4; 125 | repeated ChangeSet changesets = 5; 126 | } 127 | 128 | 129 | /** String table, contains the common strings in each block. 130 | 131 | Note that we reserve index '0' as a delimiter, so the entry at that 132 | index in the table is ALWAYS blank and unused. 133 | 134 | */ 135 | message StringTable { 136 | repeated string s = 1; 137 | } 138 | 139 | /* Optional metadata that may be included into each primitive. */ 140 | message Info { 141 | optional int32 version = 1 [default = -1]; 142 | optional int64 timestamp = 2; 143 | optional int64 changeset = 3; 144 | optional int32 uid = 4; 145 | optional uint32 user_sid = 5; // String IDs 146 | 147 | // The visible flag is used to store history information. It indicates that 148 | // the current object version has been created by a delete operation on the 149 | // OSM API. 150 | // When a writer sets this flag, it MUST add a required_features tag with 151 | // value "HistoricalInformation" to the HeaderBlock. 152 | // If this flag is not available for some object it MUST be assumed to be 153 | // true if the file has the required_features tag "HistoricalInformation" 154 | // set. 155 | optional bool visible = 6; 156 | } 157 | 158 | /** Optional metadata that may be included into each primitive. Special dense format used in DenseNodes. */ 159 | message DenseInfo { 160 | repeated int32 version = 1 [packed = true]; 161 | repeated sint64 timestamp = 2 [packed = true]; // DELTA coded 162 | repeated sint64 changeset = 3 [packed = true]; // DELTA coded 163 | repeated sint32 uid = 4 [packed = true]; // DELTA coded 164 | repeated sint32 user_sid = 5 [packed = true]; // String IDs for usernames. DELTA coded 165 | 166 | // The visible flag is used to store history information. It indicates that 167 | // the current object version has been created by a delete operation on the 168 | // OSM API. 169 | // When a writer sets this flag, it MUST add a required_features tag with 170 | // value "HistoricalInformation" to the HeaderBlock. 171 | // If this flag is not available for some object it MUST be assumed to be 172 | // true if the file has the required_features tag "HistoricalInformation" 173 | // set. 174 | repeated bool visible = 6 [packed = true]; 175 | } 176 | 177 | 178 | // This is kept for backwards compatibility but not used anywhere. 179 | message ChangeSet { 180 | required int64 id = 1; 181 | } 182 | 183 | 184 | message Node { 185 | required sint64 id = 1; 186 | 187 | // Parallel arrays. 188 | repeated uint32 keys = 2 [packed = true]; // String IDs. 189 | repeated uint32 vals = 3 [packed = true]; // String IDs. 190 | 191 | optional Info info = 4; // May be omitted in omitmeta 192 | 193 | required sint64 lat = 8; 194 | required sint64 lon = 9; 195 | } 196 | 197 | /* Used to densly represent a sequence of nodes that do not have any tags. 198 | 199 | We represent these nodes columnwise as five columns: ID's, lats, and 200 | lons, all delta coded. When metadata is not omitted, 201 | 202 | We encode keys & vals for all nodes as a single array of integers 203 | containing key-stringid and val-stringid, using a stringid of 0 as a 204 | delimiter between nodes. 205 | 206 | ( ( )* '0' )* 207 | */ 208 | 209 | message DenseNodes { 210 | repeated sint64 id = 1 [packed = true]; // DELTA coded 211 | 212 | optional DenseInfo denseinfo = 5; 213 | 214 | repeated sint64 lat = 8 [packed = true]; // DELTA coded 215 | repeated sint64 lon = 9 [packed = true]; // DELTA coded 216 | 217 | // Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless. 218 | repeated int32 keys_vals = 10 [packed = true]; 219 | } 220 | 221 | 222 | message Way { 223 | required int64 id = 1; 224 | 225 | // Parallel arrays. 226 | repeated uint32 keys = 2 [packed = true]; 227 | repeated uint32 vals = 3 [packed = true]; 228 | 229 | optional Info info = 4; 230 | 231 | repeated sint64 refs = 8 [packed = true]; // DELTA coded 232 | 233 | // The following two fields are optional. They are only used in a special 234 | // format where node locations are also added to the ways. This makes the 235 | // files larger, but allows creating way geometries directly. 236 | // 237 | // If this is used, you MUST set the optional_features tag "LocationsOnWays" 238 | // and the number of values in refs, lat, and lon MUST be the same. 239 | repeated sint64 lat = 9 [packed = true]; // DELTA coded, optional 240 | repeated sint64 lon = 10 [packed = true]; // DELTA coded, optional 241 | } 242 | 243 | message Relation { 244 | enum MemberType { 245 | NODE = 0; 246 | WAY = 1; 247 | RELATION = 2; 248 | } 249 | 250 | required int64 id = 1; 251 | 252 | // Parallel arrays. 253 | repeated uint32 keys = 2 [packed = true]; 254 | repeated uint32 vals = 3 [packed = true]; 255 | 256 | optional Info info = 4; 257 | 258 | // Parallel arrays 259 | 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 260 | repeated sint64 memids = 9 [packed = true]; // DELTA encoded 261 | repeated MemberType types = 10 [packed = true]; 262 | } 263 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # osmpbf 2 | 3 | [![Build Status](https://github.com/qedus/osmpbf/actions/workflows/go.yml/badge.svg?branch=master)](https://github.com/qedus/osmpbf/actions/workflows/go.yml) 4 | [![Coverage Status](https://coveralls.io/repos/github/qedus/osmpbf/badge.svg?branch=master)](https://coveralls.io/github/qedus/osmpbf?branch=master) 5 | [![Go Report Card](https://goreportcard.com/badge/github.com/qedus/osmpbf)](https://goreportcard.com/report/github.com/qedus/osmpbf) 6 | [![Go Reference](https://pkg.go.dev/badge/github.com/qedus/osmpbf.svg)](https://pkg.go.dev/github.com/qedus/osmpbf) 7 | 8 | Package osmpbf is used to decode OpenStreetMap pbf files. 9 | 10 | ## Installation 11 | 12 | ```bash 13 | $ go get github.com/qedus/osmpbf 14 | ``` 15 | 16 | ## Usage 17 | 18 | Usage is similar to `json.Decoder`. 19 | 20 | ```Go 21 | f, err := os.Open("greater-london-140324.osm.pbf") 22 | if err != nil { 23 | log.Fatal(err) 24 | } 25 | defer f.Close() 26 | 27 | d := osmpbf.NewDecoder(f) 28 | 29 | // use more memory from the start, it is faster 30 | d.SetBufferSize(osmpbf.MaxBlobSize) 31 | 32 | // start decoding with several goroutines, it is faster 33 | err = d.Start(runtime.GOMAXPROCS(-1)) 34 | if err != nil { 35 | log.Fatal(err) 36 | } 37 | 38 | var nc, wc, rc uint64 39 | for { 40 | if v, err := d.Decode(); err == io.EOF { 41 | break 42 | } else if err != nil { 43 | log.Fatal(err) 44 | } else { 45 | switch v := v.(type) { 46 | case *osmpbf.Node: 47 | // Process Node v. 48 | nc++ 49 | case *osmpbf.Way: 50 | // Process Way v. 51 | wc++ 52 | case *osmpbf.Relation: 53 | // Process Relation v. 54 | rc++ 55 | default: 56 | log.Fatalf("unknown type %T\n", v) 57 | } 58 | } 59 | } 60 | 61 | fmt.Printf("Nodes: %d, Ways: %d, Relations: %d\n", nc, wc, rc) 62 | ``` 63 | 64 | ## Documentation 65 | 66 | https://pkg.go.dev/github.com/qedus/osmpbf 67 | 68 | ## To Do 69 | 70 | The parseNodes code has not been tested as I can only find PBF files with DenseNode format. 71 | 72 | An Encoder still needs to be created to reverse the process. 73 | -------------------------------------------------------------------------------- /decode.go: -------------------------------------------------------------------------------- 1 | // Package osmpbf decodes OpenStreetMap (OSM) PBF files. 2 | // Use this package by creating a NewDecoder and passing it a PBF file. 3 | // Use Start to start decoding process. 4 | // Use Decode to return Node, Way and Relation structs. 5 | package osmpbf // import "github.com/qedus/osmpbf" 6 | 7 | import ( 8 | "bytes" 9 | "compress/zlib" 10 | "encoding/binary" 11 | "errors" 12 | "fmt" 13 | "io" 14 | "sync" 15 | "time" 16 | 17 | "github.com/qedus/osmpbf/OSMPBF" 18 | "google.golang.org/protobuf/proto" 19 | ) 20 | 21 | const ( 22 | maxBlobHeaderSize = 64 * 1024 23 | 24 | initialBlobBufSize = 1 * 1024 * 1024 25 | 26 | // MaxBlobSize is maximum supported blob size. 27 | MaxBlobSize = 32 * 1024 * 1024 28 | ) 29 | 30 | var ( 31 | parseCapabilities = map[string]bool{ 32 | "OsmSchema-V0.6": true, 33 | "DenseNodes": true, 34 | } 35 | ) 36 | 37 | type BoundingBox struct { 38 | Left float64 39 | Right float64 40 | Top float64 41 | Bottom float64 42 | } 43 | 44 | type Header struct { 45 | BoundingBox *BoundingBox 46 | RequiredFeatures []string 47 | OptionalFeatures []string 48 | WritingProgram string 49 | Source string 50 | OsmosisReplicationTimestamp time.Time 51 | OsmosisReplicationSequenceNumber int64 52 | OsmosisReplicationBaseUrl string 53 | } 54 | 55 | type Info struct { 56 | Version int32 57 | Uid int32 58 | Timestamp time.Time 59 | Changeset int64 60 | User string 61 | Visible bool 62 | } 63 | 64 | type Node struct { 65 | ID int64 66 | Lat float64 67 | Lon float64 68 | Tags map[string]string 69 | Info Info 70 | } 71 | 72 | type Way struct { 73 | ID int64 74 | Tags map[string]string 75 | NodeIDs []int64 76 | Info Info 77 | } 78 | 79 | type Relation struct { 80 | ID int64 81 | Tags map[string]string 82 | Members []Member 83 | Info Info 84 | } 85 | 86 | type MemberType int 87 | 88 | const ( 89 | NodeType MemberType = iota 90 | WayType 91 | RelationType 92 | ) 93 | 94 | type Member struct { 95 | ID int64 96 | Type MemberType 97 | Role string 98 | } 99 | 100 | type pair struct { 101 | i interface{} 102 | e error 103 | } 104 | 105 | // A Decoder reads and decodes OpenStreetMap PBF data from an input stream. 106 | type Decoder struct { 107 | r io.Reader 108 | serializer chan pair 109 | 110 | buf *bytes.Buffer 111 | 112 | // store header block 113 | header *Header 114 | // synchronize header deserialization 115 | headerOnce sync.Once 116 | 117 | // for data decoders 118 | inputs []chan<- pair 119 | outputs []<-chan pair 120 | } 121 | 122 | // NewDecoder returns a new decoder that reads from r. 123 | func NewDecoder(r io.Reader) *Decoder { 124 | d := &Decoder{ 125 | r: r, 126 | serializer: make(chan pair, 8000), // typical PrimitiveBlock contains 8k OSM entities 127 | } 128 | d.SetBufferSize(initialBlobBufSize) 129 | return d 130 | } 131 | 132 | // SetBufferSize sets initial size of decoding buffer. Default value is 1MB, you can set higher value 133 | // (for example, MaxBlobSize) for (probably) faster decoding, or lower value for reduced memory consumption. 134 | // Any value will produce valid results; buffer will grow automatically if required. 135 | func (dec *Decoder) SetBufferSize(n int) { 136 | dec.buf = bytes.NewBuffer(make([]byte, 0, n)) 137 | } 138 | 139 | // Header returns file header. 140 | func (dec *Decoder) Header() (*Header, error) { 141 | // deserialize the file header 142 | return dec.header, dec.readOSMHeader() 143 | } 144 | 145 | // Start decoding process using n goroutines. 146 | func (dec *Decoder) Start(n int) error { 147 | if n < 1 { 148 | n = 1 149 | } 150 | 151 | if err := dec.readOSMHeader(); err != nil { 152 | return err 153 | } 154 | 155 | // start data decoders 156 | for i := 0; i < n; i++ { 157 | input := make(chan pair) 158 | output := make(chan pair) 159 | go func() { 160 | dd := new(dataDecoder) 161 | for p := range input { 162 | if p.e == nil { 163 | // send decoded objects or decoding error 164 | objects, err := dd.Decode(p.i.(*OSMPBF.Blob)) 165 | output <- pair{objects, err} 166 | } else { 167 | // send input error as is 168 | output <- pair{nil, p.e} 169 | } 170 | } 171 | close(output) 172 | }() 173 | 174 | dec.inputs = append(dec.inputs, input) 175 | dec.outputs = append(dec.outputs, output) 176 | } 177 | 178 | // start reading OSMData 179 | go func() { 180 | var inputIndex int 181 | for { 182 | input := dec.inputs[inputIndex] 183 | inputIndex = (inputIndex + 1) % n 184 | 185 | blobHeader, blob, err := dec.readFileBlock() 186 | if err == nil && blobHeader.GetType() != "OSMData" { 187 | err = fmt.Errorf("unexpected fileblock of type %s", blobHeader.GetType()) 188 | } 189 | if err == nil { 190 | // send blob for decoding 191 | input <- pair{blob, nil} 192 | } else { 193 | // send input error as is 194 | input <- pair{nil, err} 195 | for _, input := range dec.inputs { 196 | close(input) 197 | } 198 | return 199 | } 200 | } 201 | }() 202 | 203 | go func() { 204 | var outputIndex int 205 | for { 206 | output := dec.outputs[outputIndex] 207 | outputIndex = (outputIndex + 1) % n 208 | 209 | p := <-output 210 | if p.i != nil { 211 | // send decoded objects one by one 212 | for _, o := range p.i.([]interface{}) { 213 | dec.serializer <- pair{o, nil} 214 | } 215 | } 216 | if p.e != nil { 217 | // send input or decoding error 218 | dec.serializer <- pair{nil, p.e} 219 | close(dec.serializer) 220 | return 221 | } 222 | } 223 | }() 224 | 225 | return nil 226 | } 227 | 228 | // Decode reads the next object from the input stream and returns either a 229 | // pointer to Node, Way or Relation struct representing the underlying OpenStreetMap PBF 230 | // data, or error encountered. The end of the input stream is reported by an io.EOF error. 231 | // 232 | // Decode is safe for parallel execution. Only first error encountered will be returned, 233 | // subsequent invocations will return io.EOF. 234 | func (dec *Decoder) Decode() (interface{}, error) { 235 | p, ok := <-dec.serializer 236 | if !ok { 237 | return nil, io.EOF 238 | } 239 | return p.i, p.e 240 | } 241 | 242 | func (dec *Decoder) readFileBlock() (*OSMPBF.BlobHeader, *OSMPBF.Blob, error) { 243 | blobHeaderSize, err := dec.readBlobHeaderSize() 244 | if err != nil { 245 | return nil, nil, err 246 | } 247 | 248 | blobHeader, err := dec.readBlobHeader(blobHeaderSize) 249 | if err != nil { 250 | return nil, nil, err 251 | } 252 | 253 | blob, err := dec.readBlob(blobHeader) 254 | if err != nil { 255 | return nil, nil, err 256 | } 257 | 258 | return blobHeader, blob, err 259 | } 260 | 261 | func (dec *Decoder) readBlobHeaderSize() (uint32, error) { 262 | dec.buf.Reset() 263 | if _, err := io.CopyN(dec.buf, dec.r, 4); err != nil { 264 | return 0, err 265 | } 266 | 267 | size := binary.BigEndian.Uint32(dec.buf.Bytes()) 268 | 269 | if size >= maxBlobHeaderSize { 270 | return 0, errors.New("BlobHeader size >= 64Kb") 271 | } 272 | return size, nil 273 | } 274 | 275 | func (dec *Decoder) readBlobHeader(size uint32) (*OSMPBF.BlobHeader, error) { 276 | dec.buf.Reset() 277 | if _, err := io.CopyN(dec.buf, dec.r, int64(size)); err != nil { 278 | return nil, err 279 | } 280 | 281 | blobHeader := new(OSMPBF.BlobHeader) 282 | if err := proto.Unmarshal(dec.buf.Bytes(), blobHeader); err != nil { 283 | return nil, err 284 | } 285 | 286 | if blobHeader.GetDatasize() >= MaxBlobSize { 287 | return nil, errors.New("Blob size >= 32Mb") 288 | } 289 | return blobHeader, nil 290 | } 291 | 292 | func (dec *Decoder) readBlob(blobHeader *OSMPBF.BlobHeader) (*OSMPBF.Blob, error) { 293 | dec.buf.Reset() 294 | if _, err := io.CopyN(dec.buf, dec.r, int64(blobHeader.GetDatasize())); err != nil { 295 | return nil, err 296 | } 297 | 298 | blob := new(OSMPBF.Blob) 299 | if err := proto.Unmarshal(dec.buf.Bytes(), blob); err != nil { 300 | return nil, err 301 | } 302 | return blob, nil 303 | } 304 | 305 | func getData(blob *OSMPBF.Blob) ([]byte, error) { 306 | switch blob.Data.(type) { 307 | case *OSMPBF.Blob_Raw: 308 | return blob.GetRaw(), nil 309 | 310 | case *OSMPBF.Blob_ZlibData: 311 | r, err := zlib.NewReader(bytes.NewReader(blob.GetZlibData())) 312 | if err != nil { 313 | return nil, err 314 | } 315 | buf := bytes.NewBuffer(make([]byte, 0, blob.GetRawSize()+bytes.MinRead)) 316 | _, err = buf.ReadFrom(r) 317 | if err != nil { 318 | return nil, err 319 | } 320 | if buf.Len() != int(blob.GetRawSize()) { 321 | err = fmt.Errorf("raw blob data size %d but expected %d", buf.Len(), blob.GetRawSize()) 322 | return nil, err 323 | } 324 | return buf.Bytes(), nil 325 | 326 | default: 327 | return nil, fmt.Errorf("unhandled blob data type %T", blob.Data) 328 | } 329 | } 330 | 331 | func (dec *Decoder) readOSMHeader() error { 332 | var err error 333 | dec.headerOnce.Do(func() { 334 | var blobHeader *OSMPBF.BlobHeader 335 | var blob *OSMPBF.Blob 336 | blobHeader, blob, err = dec.readFileBlock() 337 | if err == nil { 338 | if blobHeader.GetType() == "OSMHeader" { 339 | err = dec.decodeOSMHeader(blob) 340 | } else { 341 | err = fmt.Errorf("unexpected first fileblock of type %s", blobHeader.GetType()) 342 | } 343 | } 344 | }) 345 | 346 | return err 347 | } 348 | 349 | func (dec *Decoder) decodeOSMHeader(blob *OSMPBF.Blob) error { 350 | data, err := getData(blob) 351 | if err != nil { 352 | return err 353 | } 354 | 355 | headerBlock := new(OSMPBF.HeaderBlock) 356 | if err := proto.Unmarshal(data, headerBlock); err != nil { 357 | return err 358 | } 359 | 360 | // Check we have the parse capabilities 361 | requiredFeatures := headerBlock.GetRequiredFeatures() 362 | for _, feature := range requiredFeatures { 363 | if !parseCapabilities[feature] { 364 | return fmt.Errorf("parser does not have %s capability", feature) 365 | } 366 | } 367 | 368 | // Read properties to header struct 369 | header := &Header{ 370 | RequiredFeatures: headerBlock.GetRequiredFeatures(), 371 | OptionalFeatures: headerBlock.GetOptionalFeatures(), 372 | WritingProgram: headerBlock.GetWritingprogram(), 373 | Source: headerBlock.GetSource(), 374 | OsmosisReplicationBaseUrl: headerBlock.GetOsmosisReplicationBaseUrl(), 375 | OsmosisReplicationSequenceNumber: headerBlock.GetOsmosisReplicationSequenceNumber(), 376 | } 377 | 378 | // convert timestamp epoch seconds to golang time structure if it exists 379 | if headerBlock.OsmosisReplicationTimestamp != nil { 380 | header.OsmosisReplicationTimestamp = time.Unix(*headerBlock.OsmosisReplicationTimestamp, 0) 381 | } 382 | // read bounding box if it exists 383 | if headerBlock.Bbox != nil { 384 | // Units are always in nanodegree and do not obey granularity rules. See osmformat.proto 385 | header.BoundingBox = &BoundingBox{ 386 | Left: 1e-9 * float64(*headerBlock.Bbox.Left), 387 | Right: 1e-9 * float64(*headerBlock.Bbox.Right), 388 | Bottom: 1e-9 * float64(*headerBlock.Bbox.Bottom), 389 | Top: 1e-9 * float64(*headerBlock.Bbox.Top), 390 | } 391 | } 392 | 393 | dec.header = header 394 | 395 | return nil 396 | } 397 | -------------------------------------------------------------------------------- /decode_data.go: -------------------------------------------------------------------------------- 1 | package osmpbf 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/qedus/osmpbf/OSMPBF" 7 | "google.golang.org/protobuf/proto" 8 | ) 9 | 10 | // Decoder for Blob with OSMData (PrimitiveBlock) 11 | type dataDecoder struct { 12 | q []interface{} 13 | } 14 | 15 | func (dec *dataDecoder) Decode(blob *OSMPBF.Blob) ([]interface{}, error) { 16 | dec.q = make([]interface{}, 0, 8000) // typical PrimitiveBlock contains 8k OSM entities 17 | 18 | data, err := getData(blob) 19 | if err != nil { 20 | return nil, err 21 | } 22 | 23 | primitiveBlock := &OSMPBF.PrimitiveBlock{} 24 | if err := proto.Unmarshal(data, primitiveBlock); err != nil { 25 | return nil, err 26 | } 27 | 28 | dec.parsePrimitiveBlock(primitiveBlock) 29 | return dec.q, nil 30 | } 31 | 32 | func (dec *dataDecoder) parsePrimitiveBlock(pb *OSMPBF.PrimitiveBlock) { 33 | for _, pg := range pb.GetPrimitivegroup() { 34 | dec.parsePrimitiveGroup(pb, pg) 35 | } 36 | } 37 | 38 | func (dec *dataDecoder) parsePrimitiveGroup(pb *OSMPBF.PrimitiveBlock, pg *OSMPBF.PrimitiveGroup) { 39 | dec.parseNodes(pb, pg.GetNodes()) 40 | dec.parseDenseNodes(pb, pg.GetDense()) 41 | dec.parseWays(pb, pg.GetWays()) 42 | dec.parseRelations(pb, pg.GetRelations()) 43 | } 44 | 45 | func (dec *dataDecoder) parseNodes(pb *OSMPBF.PrimitiveBlock, nodes []*OSMPBF.Node) { 46 | st := pb.GetStringtable().GetS() 47 | granularity := int64(pb.GetGranularity()) 48 | dateGranularity := int64(pb.GetDateGranularity()) 49 | 50 | latOffset := pb.GetLatOffset() 51 | lonOffset := pb.GetLonOffset() 52 | 53 | for _, node := range nodes { 54 | id := node.GetId() 55 | lat := node.GetLat() 56 | lon := node.GetLon() 57 | 58 | latitude := 1e-9 * float64((latOffset + (granularity * lat))) 59 | longitude := 1e-9 * float64((lonOffset + (granularity * lon))) 60 | 61 | tags := extractTags(st, node.GetKeys(), node.GetVals()) 62 | info := extractInfo(st, node.GetInfo(), dateGranularity) 63 | 64 | dec.q = append(dec.q, &Node{id, latitude, longitude, tags, info}) 65 | } 66 | 67 | } 68 | 69 | func (dec *dataDecoder) parseDenseNodes(pb *OSMPBF.PrimitiveBlock, dn *OSMPBF.DenseNodes) { 70 | st := pb.GetStringtable().GetS() 71 | granularity := int64(pb.GetGranularity()) 72 | latOffset := pb.GetLatOffset() 73 | lonOffset := pb.GetLonOffset() 74 | dateGranularity := int64(pb.GetDateGranularity()) 75 | ids := dn.GetId() 76 | lats := dn.GetLat() 77 | lons := dn.GetLon() 78 | di := dn.GetDenseinfo() 79 | 80 | tu := tagUnpacker{st, dn.GetKeysVals(), 0} 81 | var id, lat, lon int64 82 | var state denseInfoState 83 | for index := range ids { 84 | id = ids[index] + id 85 | lat = lats[index] + lat 86 | lon = lons[index] + lon 87 | latitude := 1e-9 * float64((latOffset + (granularity * lat))) 88 | longitude := 1e-9 * float64((lonOffset + (granularity * lon))) 89 | tags := tu.next() 90 | info := extractDenseInfo(st, &state, di, index, dateGranularity) 91 | 92 | dec.q = append(dec.q, &Node{id, latitude, longitude, tags, info}) 93 | } 94 | } 95 | 96 | func (dec *dataDecoder) parseWays(pb *OSMPBF.PrimitiveBlock, ways []*OSMPBF.Way) { 97 | st := pb.GetStringtable().GetS() 98 | dateGranularity := int64(pb.GetDateGranularity()) 99 | 100 | for _, way := range ways { 101 | id := way.GetId() 102 | 103 | tags := extractTags(st, way.GetKeys(), way.GetVals()) 104 | 105 | refs := way.GetRefs() 106 | var nodeID int64 107 | nodeIDs := make([]int64, len(refs)) 108 | for index := range refs { 109 | nodeID = refs[index] + nodeID // delta encoding 110 | nodeIDs[index] = nodeID 111 | } 112 | 113 | info := extractInfo(st, way.GetInfo(), dateGranularity) 114 | 115 | dec.q = append(dec.q, &Way{id, tags, nodeIDs, info}) 116 | } 117 | } 118 | 119 | // Make relation members from stringtable and three parallel arrays of IDs. 120 | func extractMembers(stringTable []string, rel *OSMPBF.Relation) []Member { 121 | memIDs := rel.GetMemids() 122 | types := rel.GetTypes() 123 | roleIDs := rel.GetRolesSid() 124 | 125 | var memID int64 126 | members := make([]Member, len(memIDs)) 127 | for index := range memIDs { 128 | memID = memIDs[index] + memID // delta encoding 129 | 130 | var memType MemberType 131 | switch types[index] { 132 | case OSMPBF.Relation_NODE: 133 | memType = NodeType 134 | case OSMPBF.Relation_WAY: 135 | memType = WayType 136 | case OSMPBF.Relation_RELATION: 137 | memType = RelationType 138 | } 139 | 140 | role := stringTable[roleIDs[index]] 141 | 142 | members[index] = Member{memID, memType, role} 143 | } 144 | 145 | return members 146 | } 147 | 148 | func (dec *dataDecoder) parseRelations(pb *OSMPBF.PrimitiveBlock, relations []*OSMPBF.Relation) { 149 | st := pb.GetStringtable().GetS() 150 | dateGranularity := int64(pb.GetDateGranularity()) 151 | 152 | for _, rel := range relations { 153 | id := rel.GetId() 154 | tags := extractTags(st, rel.GetKeys(), rel.GetVals()) 155 | members := extractMembers(st, rel) 156 | info := extractInfo(st, rel.GetInfo(), dateGranularity) 157 | 158 | dec.q = append(dec.q, &Relation{id, tags, members, info}) 159 | } 160 | } 161 | 162 | func extractInfo(stringTable []string, i *OSMPBF.Info, dateGranularity int64) Info { 163 | info := Info{Visible: true} 164 | 165 | if i != nil { 166 | info.Version = i.GetVersion() 167 | 168 | millisec := time.Duration(i.GetTimestamp()*dateGranularity) * time.Millisecond 169 | info.Timestamp = time.Unix(0, millisec.Nanoseconds()).UTC() 170 | 171 | info.Changeset = i.GetChangeset() 172 | 173 | info.Uid = i.GetUid() 174 | 175 | info.User = stringTable[i.GetUserSid()] 176 | 177 | if i.Visible != nil { 178 | info.Visible = i.GetVisible() 179 | } 180 | } 181 | 182 | return info 183 | } 184 | 185 | type denseInfoState struct { 186 | timestamp int64 187 | changeset int64 188 | uid int32 189 | userSid int32 190 | } 191 | 192 | func extractDenseInfo(stringTable []string, state *denseInfoState, di *OSMPBF.DenseInfo, index int, dateGranularity int64) Info { 193 | info := Info{Visible: true} 194 | 195 | versions := di.GetVersion() 196 | if len(versions) > 0 { 197 | info.Version = versions[index] 198 | } 199 | 200 | timestamps := di.GetTimestamp() 201 | if len(timestamps) > 0 { 202 | state.timestamp = timestamps[index] + state.timestamp 203 | millisec := time.Duration(state.timestamp*dateGranularity) * time.Millisecond 204 | info.Timestamp = time.Unix(0, millisec.Nanoseconds()).UTC() 205 | } 206 | 207 | changesets := di.GetChangeset() 208 | if len(changesets) > 0 { 209 | state.changeset = changesets[index] + state.changeset 210 | info.Changeset = state.changeset 211 | } 212 | 213 | uids := di.GetUid() 214 | if len(uids) > 0 { 215 | state.uid = uids[index] + state.uid 216 | info.Uid = state.uid 217 | } 218 | 219 | usersids := di.GetUserSid() 220 | if len(usersids) > 0 { 221 | state.userSid = usersids[index] + state.userSid 222 | info.User = stringTable[state.userSid] 223 | } 224 | 225 | visibleArray := di.GetVisible() 226 | if len(visibleArray) > 0 { 227 | info.Visible = visibleArray[index] 228 | } 229 | 230 | return info 231 | } 232 | -------------------------------------------------------------------------------- /decode_tag.go: -------------------------------------------------------------------------------- 1 | package osmpbf 2 | 3 | // Make tags map from stringtable and two parallel arrays of IDs. 4 | func extractTags(stringTable []string, keyIDs, valueIDs []uint32) map[string]string { 5 | tags := make(map[string]string, len(keyIDs)) 6 | for index, keyID := range keyIDs { 7 | key := stringTable[keyID] 8 | val := stringTable[valueIDs[index]] 9 | tags[key] = val 10 | } 11 | return tags 12 | } 13 | 14 | type tagUnpacker struct { 15 | stringTable []string 16 | keysVals []int32 17 | index int 18 | } 19 | 20 | // Make tags map from stringtable and array of IDs (used in DenseNodes encoding). 21 | func (tu *tagUnpacker) next() map[string]string { 22 | tags := make(map[string]string) 23 | for tu.index < len(tu.keysVals) { 24 | keyID := tu.keysVals[tu.index] 25 | tu.index++ 26 | if keyID == 0 { 27 | break 28 | } 29 | 30 | valID := tu.keysVals[tu.index] 31 | tu.index++ 32 | 33 | key := tu.stringTable[keyID] 34 | val := tu.stringTable[valID] 35 | tags[key] = val 36 | } 37 | return tags 38 | } 39 | -------------------------------------------------------------------------------- /decode_test.go: -------------------------------------------------------------------------------- 1 | package osmpbf 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "net/http" 7 | "os" 8 | "reflect" 9 | "runtime" 10 | "strconv" 11 | "sync" 12 | "sync/atomic" 13 | "testing" 14 | "time" 15 | ) 16 | 17 | const ( 18 | // Test files are stored at https://gist.github.com/AlekSi/d4369aa13cf1fc5ddfac3e91b67b2f7b 19 | // 8604f36a7357adfbd6b5292c2ea4972d9d0bfd3d is the latest commit. 20 | GistURL = "https://gist.githubusercontent.com/AlekSi/d4369aa13cf1fc5ddfac3e91b67b2f7b/raw/8604f36a7357adfbd6b5292c2ea4972d9d0bfd3d/" 21 | 22 | // Originally downloaded from http://download.geofabrik.de/europe/great-britain/england/greater-london.html 23 | London = "greater-london-140324.osm.pbf" 24 | 25 | // Same file as above, but without 'DenseNodes'. This has been generated using the below command (using osmium-tool http://osmcode.org/osmium-tool/) 26 | // "osmium cat -o greater-london-140324-nondense.osm.pbf greater-london-140324.osm.pbf -f osm.pbf,pbf_dense_nodes=false" 27 | LondonNonDense = "greater-london-140324-nondense.osm.pbf" 28 | ) 29 | 30 | func parseTime(s string) time.Time { 31 | t, err := time.Parse(time.RFC3339, s) 32 | if err != nil { 33 | panic(err) 34 | } 35 | return t 36 | } 37 | 38 | var ( 39 | IDsExpectedOrder = []string{ 40 | // Start of dense nodes. 41 | "node/44", "node/47", "node/52", "node/58", "node/60", 42 | "node/79", // Just because way/79 is already there 43 | "node/2740703694", "node/2740703695", "node/2740703697", 44 | "node/2740703699", "node/2740703701", 45 | // End of dense nodes. 46 | 47 | // Start of ways. 48 | "way/73", "way/74", "way/75", "way/79", "way/482", 49 | "way/268745428", "way/268745431", "way/268745434", "way/268745436", 50 | "way/268745439", 51 | // End of ways. 52 | 53 | // Start of relations. 54 | "relation/69", "relation/94", "relation/152", "relation/245", 55 | "relation/332", "relation/3593436", "relation/3595575", 56 | "relation/3595798", "relation/3599126", "relation/3599127", 57 | // End of relations 58 | } 59 | 60 | IDs map[string]bool 61 | 62 | enc uint64 = 2729006 63 | ewc uint64 = 459055 64 | erc uint64 = 12833 65 | 66 | eh = &Header{ 67 | BoundingBox: &BoundingBox{ 68 | Right: 0.335437, 69 | Left: -0.511482, 70 | Bottom: 51.28554, 71 | Top: 51.69344, 72 | }, 73 | OsmosisReplicationTimestamp: time.Date(2014, 3, 24, 22, 55, 2, 0, time.FixedZone("test", 3600)), 74 | RequiredFeatures: []string{ 75 | "OsmSchema-V0.6", 76 | "DenseNodes", 77 | }, 78 | WritingProgram: `Osmium (http:\/\/wiki.openstreetmap.org\/wiki\/Osmium)`, 79 | } 80 | 81 | en = &Node{ 82 | ID: 18088578, 83 | Lat: 51.5442632, 84 | Lon: -0.2010027, 85 | Tags: map[string]string{ 86 | "alt_name": "The King's Head", 87 | "amenity": "pub", 88 | "created_by": "JOSM", 89 | "name": "The Luminaire", 90 | "note": "Live music venue too", 91 | }, 92 | Info: Info{ 93 | Version: 2, 94 | Timestamp: parseTime("2009-05-20T10:28:54Z"), 95 | Changeset: 1260468, 96 | Uid: 508, 97 | User: "Welshie", 98 | Visible: true, 99 | }, 100 | } 101 | 102 | ew = &Way{ 103 | ID: 4257116, 104 | NodeIDs: []int64{ 105 | 21544864, 333731851, 333731852, 333731850, 333731855, 106 | 333731858, 333731854, 108047, 769984352, 21544864}, 107 | Tags: map[string]string{ 108 | "area": "yes", 109 | "highway": "pedestrian", 110 | "name": "Fitzroy Square", 111 | }, 112 | Info: Info{ 113 | Version: 7, 114 | Timestamp: parseTime("2013-08-07T12:08:39Z"), 115 | Changeset: 17253164, 116 | Uid: 1016290, 117 | User: "Amaroussi", 118 | Visible: true, 119 | }, 120 | } 121 | 122 | er = &Relation{ 123 | ID: 7677, 124 | Members: []Member{ 125 | {ID: 4875932, Type: WayType, Role: "outer"}, 126 | {ID: 4894305, Type: WayType, Role: "inner"}, 127 | }, 128 | Tags: map[string]string{ 129 | "created_by": "Potlatch 0.9c", 130 | "type": "multipolygon", 131 | }, 132 | Info: Info{ 133 | Version: 4, 134 | Timestamp: parseTime("2008-07-19T15:04:03Z"), 135 | Changeset: 540201, 136 | Uid: 3876, 137 | User: "Edgemaster", 138 | Visible: true, 139 | }, 140 | } 141 | ) 142 | 143 | func init() { 144 | IDs = make(map[string]bool) 145 | for _, id := range IDsExpectedOrder { 146 | IDs[id] = false 147 | } 148 | } 149 | 150 | func downloadTestOSMFile(fileName string, t *testing.T) { 151 | _, err := os.Stat(fileName) 152 | if err == nil { 153 | return 154 | } 155 | if !os.IsNotExist(err) { 156 | t.Fatal(err) 157 | } 158 | 159 | resp, err := http.Get(GistURL + fileName) 160 | if err != nil { 161 | t.Fatal(err) 162 | } 163 | defer resp.Body.Close() 164 | 165 | if resp.StatusCode != 200 { 166 | t.Fatalf("expected 200, got %d", resp.StatusCode) 167 | } 168 | 169 | out, err := os.Create(fileName) 170 | if err != nil { 171 | t.Fatal(err) 172 | } 173 | defer out.Close() 174 | 175 | if _, err = io.Copy(out, resp.Body); err != nil { 176 | t.Fatal(err) 177 | } 178 | } 179 | 180 | func checkHeader(a *Header) bool { 181 | if a == nil || a.BoundingBox == nil || a.RequiredFeatures == nil { 182 | return false 183 | } 184 | 185 | // check bbox 186 | 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 { 187 | return false 188 | } 189 | 190 | // check timestamp 191 | if !a.OsmosisReplicationTimestamp.Equal(eh.OsmosisReplicationTimestamp) { 192 | return false 193 | } 194 | 195 | // check writing program 196 | if a.WritingProgram != eh.WritingProgram { 197 | return false 198 | } 199 | 200 | // check features 201 | if len(a.RequiredFeatures) != len(eh.RequiredFeatures) || a.RequiredFeatures[0] != eh.RequiredFeatures[0] || a.RequiredFeatures[1] != eh.RequiredFeatures[1] { 202 | return false 203 | } 204 | 205 | return true 206 | } 207 | 208 | func decodePBF(PBFfileName string, t *testing.T) { 209 | downloadTestOSMFile(PBFfileName, t) 210 | 211 | f, err := os.Open(PBFfileName) 212 | if err != nil { 213 | t.Fatal(err) 214 | } 215 | defer f.Close() 216 | 217 | d := NewDecoder(f) 218 | d.SetBufferSize(1) 219 | 220 | header, err := d.Header() 221 | if err != nil { 222 | t.Fatal(err) 223 | } 224 | if checkHeader(header) { 225 | t.Errorf("\nExpected: %#v\nActual: %#v", eh, header) 226 | } 227 | 228 | err = d.Start(runtime.GOMAXPROCS(-1)) 229 | if err != nil { 230 | t.Fatal(err) 231 | } 232 | 233 | var n *Node 234 | var w *Way 235 | var r *Relation 236 | var nc, wc, rc uint64 237 | var id string 238 | idsOrder := make([]string, 0, len(IDsExpectedOrder)) 239 | for { 240 | if v, err := d.Decode(); err == io.EOF { 241 | break 242 | } else if err != nil { 243 | t.Fatal(err) 244 | } else { 245 | switch v := v.(type) { 246 | case *Node: 247 | nc++ 248 | if v.ID == en.ID { 249 | n = v 250 | } 251 | id = fmt.Sprintf("node/%d", v.ID) 252 | if _, ok := IDs[id]; ok { 253 | idsOrder = append(idsOrder, id) 254 | } 255 | case *Way: 256 | wc++ 257 | if v.ID == ew.ID { 258 | w = v 259 | } 260 | id = fmt.Sprintf("way/%d", v.ID) 261 | if _, ok := IDs[id]; ok { 262 | idsOrder = append(idsOrder, id) 263 | } 264 | case *Relation: 265 | rc++ 266 | if v.ID == er.ID { 267 | r = v 268 | } 269 | id = fmt.Sprintf("relation/%d", v.ID) 270 | if _, ok := IDs[id]; ok { 271 | idsOrder = append(idsOrder, id) 272 | } 273 | default: 274 | t.Fatalf("unknown type %T", v) 275 | } 276 | } 277 | } 278 | 279 | if !reflect.DeepEqual(en, n) { 280 | t.Errorf("\nExpected: %#v\nActual: %#v", en, n) 281 | } 282 | if !reflect.DeepEqual(ew, w) { 283 | t.Errorf("\nExpected: %#v\nActual: %#v", ew, w) 284 | } 285 | if !reflect.DeepEqual(er, r) { 286 | t.Errorf("\nExpected: %#v\nActual: %#v", er, r) 287 | } 288 | if enc != nc || ewc != wc || erc != rc { 289 | t.Errorf("\nExpected %7d nodes, %7d ways, %7d relations\nGot %7d nodes, %7d ways, %7d relations.", 290 | enc, ewc, erc, nc, wc, rc) 291 | } 292 | if !reflect.DeepEqual(IDsExpectedOrder, idsOrder) { 293 | t.Errorf("\nExpected: %v\nGot: %v", IDsExpectedOrder, idsOrder) 294 | } 295 | } 296 | 297 | func TestDecodePBFWithDenseNodes(t *testing.T) { 298 | decodePBF(London, t) 299 | } 300 | 301 | func TestDecodePBFWithNodes(t *testing.T) { 302 | decodePBF(LondonNonDense, t) 303 | } 304 | 305 | func TestDecodeConcurrent(t *testing.T) { 306 | downloadTestOSMFile(London, t) 307 | 308 | f, err := os.Open(London) 309 | if err != nil { 310 | t.Fatal(err) 311 | } 312 | defer f.Close() 313 | 314 | d := NewDecoder(f) 315 | d.SetBufferSize(1) 316 | err = d.Start(runtime.GOMAXPROCS(-1)) 317 | if err != nil { 318 | t.Fatal(err) 319 | } 320 | 321 | header, err := d.Header() 322 | if err != nil { 323 | t.Fatal(err) 324 | } 325 | if checkHeader(header) { 326 | t.Errorf("\nExpected: %#v\nActual: %#v", eh, header) 327 | } 328 | 329 | var n *Node 330 | var w *Way 331 | var r *Relation 332 | var nc, wc, rc uint64 333 | var wg sync.WaitGroup 334 | for i := 0; i < 4; i++ { 335 | wg.Add(1) 336 | 337 | go func() { 338 | defer wg.Done() 339 | 340 | for { 341 | if v, err := d.Decode(); err == io.EOF { 342 | return 343 | } else if err != nil { 344 | t.Error(err) 345 | return 346 | } else { 347 | switch v := v.(type) { 348 | case *Node: 349 | atomic.AddUint64(&nc, 1) 350 | if v.ID == en.ID { 351 | n = v 352 | } 353 | case *Way: 354 | atomic.AddUint64(&wc, 1) 355 | if v.ID == ew.ID { 356 | w = v 357 | } 358 | case *Relation: 359 | atomic.AddUint64(&rc, 1) 360 | if v.ID == er.ID { 361 | r = v 362 | } 363 | default: 364 | t.Errorf("unknown type %T", v) 365 | return 366 | } 367 | } 368 | } 369 | }() 370 | } 371 | wg.Wait() 372 | 373 | if !reflect.DeepEqual(en, n) { 374 | t.Errorf("\nExpected: %#v\nActual: %#v", en, n) 375 | } 376 | if !reflect.DeepEqual(ew, w) { 377 | t.Errorf("\nExpected: %#v\nActual: %#v", ew, w) 378 | } 379 | if !reflect.DeepEqual(er, r) { 380 | t.Errorf("\nExpected: %#v\nActual: %#v", er, r) 381 | } 382 | if enc != nc || ewc != wc || erc != rc { 383 | t.Errorf("\nExpected %7d nodes, %7d ways, %7d relations\nGot %7d nodes, %7d ways, %7d relations", 384 | enc, ewc, erc, nc, wc, rc) 385 | } 386 | } 387 | 388 | func BenchmarkDecode(b *testing.B) { 389 | file := os.Getenv("OSMPBF_BENCHMARK_FILE") 390 | if file == "" { 391 | file = London 392 | } 393 | f, err := os.Open(file) 394 | if err != nil { 395 | b.Fatal(err) 396 | } 397 | defer f.Close() 398 | fileInfo, err := f.Stat() 399 | if err != nil { 400 | b.Fatal(err) 401 | } 402 | 403 | blobBufferSize, _ := strconv.Atoi(os.Getenv("OSMPBF_BENCHMARK_BUFFER")) 404 | 405 | b.ResetTimer() 406 | for i := 0; i < b.N; i++ { 407 | if _, err = f.Seek(0, 0); err != nil { 408 | b.Fatal(err) 409 | } 410 | 411 | d := NewDecoder(f) 412 | if blobBufferSize > 0 { 413 | d.SetBufferSize(blobBufferSize) 414 | } 415 | err = d.Start(runtime.GOMAXPROCS(-1)) 416 | if err != nil { 417 | b.Fatal(err) 418 | } 419 | 420 | var nc, wc, rc uint64 421 | start := time.Now() 422 | for { 423 | if v, err := d.Decode(); err == io.EOF { 424 | break 425 | } else if err != nil { 426 | b.Fatal(err) 427 | } else { 428 | switch v := v.(type) { 429 | case *Node: 430 | nc++ 431 | case *Way: 432 | wc++ 433 | case *Relation: 434 | rc++ 435 | default: 436 | b.Fatalf("unknown type %T", v) 437 | } 438 | } 439 | } 440 | 441 | b.Logf("Done in %.3f seconds. Nodes: %d, Ways: %d, Relations: %d\n", 442 | time.Since(start).Seconds(), nc, wc, rc) 443 | b.SetBytes(fileInfo.Size()) 444 | } 445 | } 446 | 447 | func BenchmarkDecodeConcurrent(b *testing.B) { 448 | file := os.Getenv("OSMPBF_BENCHMARK_FILE") 449 | if file == "" { 450 | file = London 451 | } 452 | f, err := os.Open(file) 453 | if err != nil { 454 | b.Fatal(err) 455 | } 456 | defer f.Close() 457 | fileInfo, err := f.Stat() 458 | if err != nil { 459 | b.Fatal(err) 460 | } 461 | 462 | blobBufferSize, _ := strconv.Atoi(os.Getenv("OSMPBF_BENCHMARK_BUFFER")) 463 | 464 | b.ResetTimer() 465 | for i := 0; i < b.N; i++ { 466 | if _, err = f.Seek(0, 0); err != nil { 467 | b.Fatal(err) 468 | } 469 | 470 | d := NewDecoder(f) 471 | if blobBufferSize > 0 { 472 | d.SetBufferSize(blobBufferSize) 473 | } 474 | err = d.Start(runtime.GOMAXPROCS(-1)) 475 | if err != nil { 476 | b.Fatal(err) 477 | } 478 | 479 | var nc, wc, rc uint64 480 | start := time.Now() 481 | var wg sync.WaitGroup 482 | for i := 0; i < 4; i++ { 483 | wg.Add(1) 484 | 485 | go func() { 486 | defer wg.Done() 487 | 488 | for { 489 | if v, err := d.Decode(); err == io.EOF { 490 | return 491 | } else if err != nil { 492 | b.Error(err) 493 | return 494 | } else { 495 | switch v := v.(type) { 496 | case *Node: 497 | atomic.AddUint64(&nc, 1) 498 | case *Way: 499 | atomic.AddUint64(&wc, 1) 500 | case *Relation: 501 | atomic.AddUint64(&rc, 1) 502 | default: 503 | b.Errorf("unknown type %T", v) 504 | return 505 | } 506 | } 507 | } 508 | }() 509 | } 510 | wg.Wait() 511 | 512 | b.Logf("Done in %.3f seconds. Nodes: %d, Ways: %d, Relations: %d\n", 513 | time.Since(start).Seconds(), nc, wc, rc) 514 | b.SetBytes(fileInfo.Size()) 515 | } 516 | } 517 | -------------------------------------------------------------------------------- /example_test.go: -------------------------------------------------------------------------------- 1 | package osmpbf_test 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "log" 7 | "os" 8 | "runtime" 9 | 10 | "github.com/qedus/osmpbf" 11 | ) 12 | 13 | // Don't forget to sync with README.md 14 | 15 | func Example() { 16 | f, err := os.Open("greater-london-140324.osm.pbf") 17 | if err != nil { 18 | log.Fatal(err) 19 | } 20 | defer f.Close() 21 | 22 | d := osmpbf.NewDecoder(f) 23 | 24 | // use more memory from the start, it is faster 25 | d.SetBufferSize(osmpbf.MaxBlobSize) 26 | 27 | // start decoding with several goroutines, it is faster 28 | err = d.Start(runtime.GOMAXPROCS(-1)) 29 | if err != nil { 30 | log.Fatal(err) 31 | } 32 | 33 | var nc, wc, rc uint64 34 | for { 35 | if v, err := d.Decode(); err == io.EOF { 36 | break 37 | } else if err != nil { 38 | log.Fatal(err) 39 | } else { 40 | switch v := v.(type) { 41 | case *osmpbf.Node: 42 | // Process Node v. 43 | nc++ 44 | case *osmpbf.Way: 45 | // Process Way v. 46 | wc++ 47 | case *osmpbf.Relation: 48 | // Process Relation v. 49 | rc++ 50 | default: 51 | log.Fatalf("unknown type %T\n", v) 52 | } 53 | } 54 | } 55 | 56 | fmt.Printf("Nodes: %d, Ways: %d, Relations: %d\n", nc, wc, rc) 57 | // Output: 58 | // Nodes: 2729006, Ways: 459055, Relations: 12833 59 | } 60 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/qedus/osmpbf 2 | 3 | go 1.16 4 | 5 | require google.golang.org/protobuf v1.27.1 // sync version with OSMPBF/Makefile 6 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= 2 | github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= 3 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 4 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= 5 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 6 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 7 | google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= 8 | google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 9 | --------------------------------------------------------------------------------