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);
}
|