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