-
Notifications
You must be signed in to change notification settings - Fork 79
Expand file tree
/
Copy pathBinaryParser.java
More file actions
137 lines (112 loc) · 5.32 KB
/
BinaryParser.java
File metadata and controls
137 lines (112 loc) · 5.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/** Copyright (c) 2010 Scott A. Crosby. <scott@sacrosby.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package crosby.binary;
import java.io.UncheckedIOException;
import java.util.Date;
import java.util.List;
import com.google.protobuf.InvalidProtocolBufferException;
import crosby.binary.file.BlockReaderAdapter;
import crosby.binary.file.FileBlock;
import crosby.binary.file.FileBlockPosition;
import crosby.binary.file.FileFormatException;
public abstract class BinaryParser implements BlockReaderAdapter {
protected int granularity;
private long lat_offset;
private long lon_offset;
protected int date_granularity;
private String[] strings;
/** Take a Info protocol buffer containing a date and convert it into a java Date object */
protected Date getDate(Osmformat.Info info) {
if (info.hasTimestamp()) {
return new Date(date_granularity * info.getTimestamp());
} else
return NODATE;
}
public static final Date NODATE = new Date(-1);
/** Get a string based on the index used.
*
* Index 0 is reserved to use as a delimiter, therefore, index 1 corresponds to the first string in the table
* @param id the index
* @return the string at the given index
*/
protected String getStringById(int id) {
return strings[id];
}
@Override
public void handleBlock(FileBlock message) {
try {
if (message.getType().equals("OSMHeader")) {
Osmformat.HeaderBlock headerblock = Osmformat.HeaderBlock
.parseFrom(message.getData());
parse(headerblock);
} else if (message.getType().equals("OSMData")) {
Osmformat.PrimitiveBlock primblock = Osmformat.PrimitiveBlock
.parseFrom(message.getData());
parse(primblock);
}
} catch (InvalidProtocolBufferException e) {
throw new UncheckedIOException(new FileFormatException(e));
}
}
@Override
public boolean skipBlock(FileBlockPosition block) {
// System.out.println("Seeing block of type: "+block.getType());
if (block.getType().equals("OSMData"))
return false;
if (block.getType().equals("OSMHeader"))
return false;
System.out.println("Skipped block of type: " + block.getType());
return true;
}
/** Convert a latitude value stored in a protobuf into a double, compensating for granularity and latitude offset */
public double parseLat(long degree) {
// Support non-zero offsets. (We don't currently generate them)
return (granularity * degree + lat_offset) * .000000001;
}
/** Convert a longitude value stored in a protobuf into a double, compensating for granularity and longitude offset */
public double parseLon(long degree) {
// Support non-zero offsets. (We don't currently generate them)
return (granularity * degree + lon_offset) * .000000001;
}
/** Parse a Primitive block (containing a string table, other paramaters, and PrimitiveGroups */
public void parse(Osmformat.PrimitiveBlock block) {
Osmformat.StringTable stablemessage = block.getStringtable();
strings = new String[stablemessage.getSCount()];
for (int i = 0; i < strings.length; i++) {
strings[i] = stablemessage.getS(i).toStringUtf8();
}
granularity = block.getGranularity();
lat_offset = block.getLatOffset();
lon_offset = block.getLonOffset();
date_granularity = block.getDateGranularity();
for (Osmformat.PrimitiveGroup groupmessage : block
.getPrimitivegroupList()) {
// Exactly one of these should trigger on each loop.
parseNodes(groupmessage.getNodesList());
parseWays(groupmessage.getWaysList());
parseRelations(groupmessage.getRelationsList());
if (groupmessage.hasDense())
parseDense(groupmessage.getDense());
}
}
/** Parse a list of Relation protocol buffers and send the resulting relations to a sink. */
protected abstract void parseRelations(List<Osmformat.Relation> rels);
/** Parse a DenseNode protocol buffer and send the resulting nodes to a sink. */
protected abstract void parseDense(Osmformat.DenseNodes nodes);
/** Parse a list of Node protocol buffers and send the resulting nodes to a sink. */
protected abstract void parseNodes(List<Osmformat.Node> nodes);
/** Parse a list of Way protocol buffers and send the resulting ways to a sink. */
protected abstract void parseWays(List<Osmformat.Way> ways);
/** Parse a header message. */
protected abstract void parse(Osmformat.HeaderBlock header);
}