crosby.binary.OsmObjectFactory Maven / Gradle / Ivy
The newest version!
package crosby.binary;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.osmtools.pbf.data.MemberType;
import org.osmtools.pbf.data.Node;
import org.osmtools.pbf.data.Relation;
import org.osmtools.pbf.data.RelationMember;
import org.osmtools.pbf.data.Tag;
import org.osmtools.pbf.data.Way;
import crosby.binary.Osmformat.DenseInfo;
public class OsmObjectFactory {
private int granularity;
private long latOffset;
private long lonOffset;
private int dateGranularity;
private String strings[];
public OsmObjectFactory(int granularity, long latOffset, long lonOffset, int dateGranularity, String[] strings) {
this.granularity = granularity;
this.latOffset = latOffset;
this.lonOffset = lonOffset;
this.dateGranularity = dateGranularity;
this.strings = strings;
}
/**
* 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
* @return
*/
private String getStringById(int id) {
return strings[id];
}
/**
* Convert a latitude value stored in a protobuf into a double, compensating for granularity and latitude offset
*/
private double parseLat(long degree) {
// Support non-zero offsets. (We don't currently generate them)
return (granularity * degree + latOffset) * .000000001;
}
/**
* Convert a longitude value stored in a protobuf into a double, compensating for granularity and longitude offset
*/
private double parseLon(long degree) {
// Support non-zero offsets. (We don't currently generate them)
return (granularity * degree + lonOffset) * .000000001;
}
private OsmInfo createOsmInfo(boolean hasOsmInfo, Osmformat.Info info) {
OsmInfoReader osmInfoReader = hasOsmInfo ? new OsmInfoReader(info, dateGranularity) : new OsmInfoReader();
String userName = osmInfoReader.hasValidUserId() ? getStringById(osmInfoReader.getUserSid()) : "";
return new OsmInfo(osmInfoReader.getVersion(), osmInfoReader.getChangeset(), userName, osmInfoReader.getDate());
}
public Node createNode(Osmformat.Node pbfNode) {
OsmInfo osmInfo = createOsmInfo(pbfNode.hasInfo(), pbfNode.getInfo());
List tags = new ArrayList();
for (int j = 0; j < pbfNode.getKeysCount(); j++) {
tags.add(new Tag(getStringById(pbfNode.getKeys(j)), getStringById(pbfNode.getVals(j))));
}
long id = pbfNode.getId();
double latf = parseLat(pbfNode.getLat());
double lonf = parseLon(pbfNode.getLon());
return new Node(id, osmInfo.getVersion(), osmInfo.getChangesetId(), osmInfo.getTimestamp(),
osmInfo.getUsername(), tags, latf, lonf);
}
public List createNodes(Osmformat.DenseNodes pbfNodes) {
List nodes = new ArrayList();
long lastId = 0, lastLat = 0, lastLon = 0;
int j = 0; // Index into the keysvals array.
// Stuff for dense info
long lasttimestamp = 0, lastchangeset = 0;
int lastuserSid = 0, lastuid = 0;
DenseInfo di = null;
if (pbfNodes.hasDenseinfo()) {
di = pbfNodes.getDenseinfo();
}
for (int nodeCount = 0; nodeCount < pbfNodes.getIdCount(); nodeCount++) {
List tags = new ArrayList(0);
long lat = pbfNodes.getLat(nodeCount) + lastLat;
lastLat = lat;
long lon = pbfNodes.getLon(nodeCount) + lastLon;
lastLon = lon;
long id = pbfNodes.getId(nodeCount) + lastId;
lastId = id;
double latf = parseLat(lat), lonf = parseLon(lon);
// If empty, assume that nothing here has keys or vals.
if (pbfNodes.getKeysValsCount() > 0) {
while (pbfNodes.getKeysVals(j) != 0) {
int keyid = pbfNodes.getKeysVals(j++);
int valid = pbfNodes.getKeysVals(j++);
tags.add(new Tag(getStringById(keyid), getStringById(valid)));
}
j++; // Skip over the '0' delimiter.
}
// Handle dense info.
if (di != null) {
int uid = di.getUid(nodeCount) + lastuid;
lastuid = uid;
int userSid = di.getUserSid(nodeCount) + lastuserSid;
lastuserSid = userSid;
long timestamp = di.getTimestamp(nodeCount) + lasttimestamp;
lasttimestamp = timestamp;
int version = di.getVersion(nodeCount);
long changeset = di.getChangeset(nodeCount) + lastchangeset;
lastchangeset = changeset;
Date date = new Date(dateGranularity * timestamp);
String user;
if (uid < 0) {
user = "";
}
else {
user = getStringById(userSid);
}
nodes.add(new Node(id, version, changeset, date, user, tags, latf, lonf));
}
else {
nodes.add(new Node(id, -1, -1, new Date(-1), "", tags, latf, lonf));
}
}
return nodes;
}
public Way createWay(Osmformat.Way pbfWay) {
OsmInfo osmInfo = createOsmInfo(pbfWay.hasInfo(), pbfWay.getInfo());
List tags = new ArrayList();
for (int j = 0; j < pbfWay.getKeysCount(); j++) {
tags.add(new Tag(getStringById(pbfWay.getKeys(j)), getStringById(pbfWay.getVals(j))));
}
long lastId = 0;
List nodes = new ArrayList();
for (long ref : pbfWay.getRefsList()) {
long nodeId = ref + lastId;
nodes.add(Long.valueOf(nodeId));
lastId = nodeId;
}
long id = pbfWay.getId();
return new Way(id, osmInfo.getVersion(), osmInfo.getChangesetId(), osmInfo.getTimestamp(),
osmInfo.getUsername(), tags, nodes);
}
public Relation createRelation(Osmformat.Relation pbfRelation) {
OsmInfo osmInfo = createOsmInfo(pbfRelation.hasInfo(), pbfRelation.getInfo());
List tags = new ArrayList();
for (int j = 0; j < pbfRelation.getKeysCount(); j++) {
tags.add(new Tag(getStringById(pbfRelation.getKeys(j)), getStringById(pbfRelation.getVals(j))));
}
long id = pbfRelation.getId();
List members = convertMembers(pbfRelation);
Relation relation = new Relation(id, osmInfo.getVersion(), osmInfo.getChangesetId(), osmInfo.getTimestamp(),
osmInfo.getUsername(), tags, members);
return relation;
}
private List convertMembers(Osmformat.Relation pbfRelation) {
long lastMid = 0;
List nodes = new ArrayList();
for (int j = 0; j < pbfRelation.getMemidsCount(); j++) {
long mid = lastMid + pbfRelation.getMemids(j);
lastMid = mid;
String role = getStringById(pbfRelation.getRolesSid(j));
MemberType memberType = decideMemberType(pbfRelation.getTypes(j));
nodes.add(new RelationMember(mid, role, memberType));
}
return nodes;
}
private MemberType decideMemberType(Osmformat.Relation.MemberType memberType) {
MemberType etype = null;
if (memberType == Osmformat.Relation.MemberType.NODE) {
etype = MemberType.NODE;
}
else if (memberType == Osmformat.Relation.MemberType.WAY) {
etype = MemberType.WAY;
}
else if (memberType == Osmformat.Relation.MemberType.RELATION) {
etype = MemberType.RELATION;
}
else {
assert false; // TODO; Illegal file?
}
return etype;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy