1/*
2    SPDX-FileCopyrightText: 2010 Scott A. Crosby. <scott@sacrosby.com>
3
4    SPDX-License-Identifier: MIT
5*/
6
7syntax = "proto2";
8option optimize_for = LITE_RUNTIME;
9option java_package = "crosby.binary";
10package OSMPBF;
11
12/* OSM Binary file format
13
14This is the master schema file of the OSM binary file format. This
15file is designed to support limited random-access and future
16extendability.
17
18A binary OSM file consists of a sequence of FileBlocks (please see
19fileformat.proto). The first fileblock contains a serialized instance
20of HeaderBlock, followed by a sequence of PrimitiveBlock blocks that
21contain the primitives.
22
23Each primitiveblock is designed to be independently parsable. It
24contains a string table storing all strings in that block (keys and
25values in tags, roles in relations, usernames, etc.) as well as
26metadata containing the precision of coordinates or timestamps in that
27block.
28
29A primitiveblock contains a sequence of primitive groups, each
30containing primitives of the same type (nodes, densenodes, ways,
31relations). Coordinates are stored in signed 64-bit integers. Lat&lon
32are measured in units <granularity> nanodegrees. The default of
33granularity of 100 nanodegrees corresponds to about 1cm on the ground,
34and a full lat or lon fits into 32 bits.
35
36Converting an integer to a lattitude or longitude uses the formula:
37$OUT = IN * granularity / 10**9$. Many encoding schemes use delta
38coding when representing nodes and relations.
39
40*/
41
42//////////////////////////////////////////////////////////////////////////
43//////////////////////////////////////////////////////////////////////////
44
45/* Contains the file header. */
46
47message HeaderBlock {
48  optional HeaderBBox bbox = 1;
49  /* Additional tags to aid in parsing this dataset */
50  repeated string required_features = 4;
51  repeated string optional_features = 5;
52
53  optional string writingprogram = 16;
54  optional string source = 17; // From the bbox field.
55
56  /* Tags that allow continuing an Osmosis replication */
57
58  // replication timestamp, expressed in seconds since the epoch,
59  // otherwise the same value as in the "timestamp=..." field
60  // in the state.txt file used by Osmosis
61  optional int64 osmosis_replication_timestamp = 32;
62
63  // replication sequence number (sequenceNumber in state.txt)
64  optional int64 osmosis_replication_sequence_number = 33;
65
66  // replication base URL (from Osmosis' configuration.txt file)
67  optional string osmosis_replication_base_url = 34;
68}
69
70
71/** The bounding box field in the OSM header. BBOX, as used in the OSM
72header. Units are always in nanodegrees -- they do not obey
73granularity rules. */
74
75message HeaderBBox {
76   required sint64 left = 1;
77   required sint64 right = 2;
78   required sint64 top = 3;
79   required sint64 bottom = 4;
80}
81
82
83///////////////////////////////////////////////////////////////////////
84///////////////////////////////////////////////////////////////////////
85
86
87message PrimitiveBlock {
88  required StringTable stringtable = 1;
89  repeated PrimitiveGroup primitivegroup = 2;
90
91  // Granularity, units of nanodegrees, used to store coordinates in this block
92  optional int32 granularity = 17 [default=100];
93  // Offset value between the output coordinates coordinates and the granularity grid in unites of nanodegrees.
94  optional int64 lat_offset = 19 [default=0];
95  optional int64 lon_offset = 20 [default=0];
96
97// Granularity of dates, normally represented in units of milliseconds since the 1970 epoch.
98  optional int32 date_granularity = 18 [default=1000];
99
100
101  // Proposed extension:
102  //optional BBox bbox = XX;
103}
104
105// Group of OSMPrimitives. All primitives in a group must be the same type.
106message PrimitiveGroup {
107  repeated Node     nodes = 1;
108  optional DenseNodes dense = 2;
109  repeated Way      ways = 3;
110  repeated Relation relations = 4;
111  repeated ChangeSet changesets = 5;
112}
113
114
115/** String table, contains the common strings in each block.
116 Note that we reserve index '0' as a delimiter, so the entry at that
117 index in the table is ALWAYS blank and unused.
118 */
119message StringTable {
120   repeated bytes s = 1;
121}
122
123/* Optional metadata that may be included into each primitive. */
124message Info {
125   optional int32 version = 1 [default = -1];
126   optional int64 timestamp = 2;
127   optional int64 changeset = 3;
128   optional int32 uid = 4;
129   optional uint32 user_sid = 5; // String IDs
130
131   // The visible flag is used to store history information. It indicates that
132   // the current object version has been created by a delete operation on the
133   // OSM API.
134   // When a writer sets this flag, it MUST add a required_features tag with
135   // value "HistoricalInformation" to the HeaderBlock.
136   // If this flag is not available for some object it MUST be assumed to be
137   // true if the file has the required_features tag "HistoricalInformation"
138   // set.
139   optional bool visible = 6;
140}
141
142/** Optional metadata that may be included into each primitive. Special dense format used in DenseNodes. */
143message DenseInfo {
144   repeated int32 version = 1 [packed = true];
145   repeated sint64 timestamp = 2 [packed = true]; // DELTA coded
146   repeated sint64 changeset = 3 [packed = true]; // DELTA coded
147   repeated sint32 uid = 4 [packed = true]; // DELTA coded
148   repeated sint32 user_sid = 5 [packed = true]; // String IDs for usernames. DELTA coded
149
150   // The visible flag is used to store history information. It indicates that
151   // the current object version has been created by a delete operation on the
152   // OSM API.
153   // When a writer sets this flag, it MUST add a required_features tag with
154   // value "HistoricalInformation" to the HeaderBlock.
155   // If this flag is not available for some object it MUST be assumed to be
156   // true if the file has the required_features tag "HistoricalInformation"
157   // set.
158   repeated bool visible = 6 [packed = true];
159}
160
161
162// THIS IS STUB DESIGN FOR CHANGESETS. NOT USED RIGHT NOW.
163// TODO:    REMOVE THIS?
164message ChangeSet {
165   required int64 id = 1;
166//
167//   // Parallel arrays.
168//   repeated uint32 keys = 2 [packed = true]; // String IDs.
169//   repeated uint32 vals = 3 [packed = true]; // String IDs.
170//
171//   optional Info info = 4;
172
173//   optional int64 created_at = 8;
174//   optional int64 closetime_delta = 9;
175//   optional bool open = 10;
176//   optional HeaderBBox bbox = 11;
177}
178
179
180message Node {
181   required sint64 id = 1;
182   // Parallel arrays.
183   repeated uint32 keys = 2 [packed = true]; // String IDs.
184   repeated uint32 vals = 3 [packed = true]; // String IDs.
185
186   optional Info info = 4; // May be omitted in omitmeta
187
188   required sint64 lat = 8;
189   required sint64 lon = 9;
190}
191
192/* Used to densly represent a sequence of nodes that do not have any tags.
193We represent these nodes columnwise as five columns: ID's, lats, and
194lons, all delta coded. When metadata is not omitted,
195We encode keys & vals for all nodes as a single array of integers
196containing key-stringid and val-stringid, using a stringid of 0 as a
197delimiter between nodes.
198   ( (<keyid> <valid>)* '0' )*
199 */
200
201message DenseNodes {
202   repeated sint64 id = 1 [packed = true]; // DELTA coded
203
204   //repeated Info info = 4;
205   optional DenseInfo denseinfo = 5;
206
207   repeated sint64 lat = 8 [packed = true]; // DELTA coded
208   repeated sint64 lon = 9 [packed = true]; // DELTA coded
209
210   // Special packing of keys and vals into one array. May be empty if all nodes in this block are tagless.
211   repeated int32 keys_vals = 10 [packed = true];
212}
213
214
215message Way {
216   required int64 id = 1;
217   // Parallel arrays.
218   repeated uint32 keys = 2 [packed = true];
219   repeated uint32 vals = 3 [packed = true];
220
221   optional Info info = 4;
222
223   repeated sint64 refs = 8 [packed = true];  // DELTA coded
224}
225
226message Relation {
227  enum MemberType {
228    NODE = 0;
229    WAY = 1;
230    RELATION = 2;
231  }
232   required int64 id = 1;
233
234   // Parallel arrays.
235   repeated uint32 keys = 2 [packed = true];
236   repeated uint32 vals = 3 [packed = true];
237
238   optional Info info = 4;
239
240   // Parallel arrays
241   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
242   repeated sint64 memids = 9 [packed = true]; // DELTA encoded
243   repeated MemberType types = 10 [packed = true];
244}
245