package mil.nga.giat.geowave.cli.osm.parser;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.openstreetmap.osmosis.core.container.v0_6.EntityContainer;
import org.openstreetmap.osmosis.core.domain.v0_6.Entity;
import org.openstreetmap.osmosis.core.domain.v0_6.Node;
import org.openstreetmap.osmosis.core.domain.v0_6.Relation;
import org.openstreetmap.osmosis.core.domain.v0_6.RelationMember;
import org.openstreetmap.osmosis.core.domain.v0_6.Tag;
import org.openstreetmap.osmosis.core.domain.v0_6.Way;
import org.openstreetmap.osmosis.core.domain.v0_6.WayNode;
import org.openstreetmap.osmosis.core.task.v0_6.Sink;
import org.openstreetmap.osmosis.xml.common.CompressionMethod;
import org.openstreetmap.osmosis.xml.v0_6.XmlReader;
public class OsmXmlLoader implements
Sink
{
/** All nodes in this OSM XML */
protected final List<Node> nodes = new LinkedList<Node>();
/** All ways in this OSM XML */
protected final List<Way> ways = new LinkedList<Way>();
/** All relations in this OSM XML */
protected final List<Relation> relations = new LinkedList<Relation>();
/**
* Mapping: Node ID -> Node object. Useful to resolve Way -> Node
* dependencies
*/
protected Map<Long, Node> nodeById = new HashMap<Long, Node>();
// getters
public List<Node> getNodes() {
return nodes;
}
public List<Way> getWays() {
return ways;
}
public List<Relation> getRelations() {
return relations;
}
public Node getNodeById(
long id ) {
return nodeById.get(id);
}
public Node getNodeById(
WayNode wayNode ) {
return nodeById.get(wayNode.getNodeId());
}
public List<Node> getNodesById(
Way way )
throws IOException {
List<Node> wayNodes = new ArrayList<Node>(
way.getWayNodes().size());
for (WayNode wn : way.getWayNodes()) {
Node n = getNodeById(wn);
if (n == null) {
throw new IOException(
String
.format(
"Error while parsing OSM XML: Node %s in Way %s (length: %s) is not declared in the document!",
wn.getNodeId(),
way.getId(),
way.getWayNodes().size()));
}
wayNodes.add(n);
}
return wayNodes;
}
// Sink implementation
@Override
public void process(
EntityContainer entityContainer ) {
Entity entity = entityContainer.getEntity();
if (entity instanceof Node) {
Node node = (Node) entity;
this.nodes.add(node);
this.nodeById.put(
node.getId(),
node);
}
else if (entity instanceof Way) {
Way way = (Way) entity;
ways.add(way);
}
else if (entity instanceof Relation) {
Relation rel = (Relation) entity;
relations.add(rel);
}
}
protected void processRelations() {
/*
* // TODO add relation support or find a lib that handles this for
* (Relation rel : relations) { List<RelationMember> members =
* rel.getMembers(); members.get( 0).getMemberId(); }
*/
}
@Override
public void initialize(
Map<String, Object> metaData ) { /* unused */}
@Override
public void complete() { /* unused */}
@Override
public void release() { /* unused */}
// Instantiation
public static OsmXmlLoader readOsmXml(
File osmxml ) {
// Defines the interface for tasks consuming OSM data types.
OsmXmlLoader sink = new OsmXmlLoader();
// compression (if any)
CompressionMethod compression = CompressionMethod.None;
if (osmxml.getName().endsWith(
".gz")) {
compression = CompressionMethod.GZip;
}
else if (osmxml.getName().endsWith(
".bz2")) {
compression = CompressionMethod.BZip2;
}
// read source file (into sink)
XmlReader reader = new XmlReader(
osmxml,
false,
compression);
reader.setSink(sink);
reader.run(); // just run, no threading
return sink;
}
// print helpers
public static void print(
Node node ) {
System.out.format(
"%s: %10s (%-10s, %-10s), version %2s by %s%n",
"Node",
node.getId(),
node.getLatitude(),
node.getLongitude(),
String.valueOf(node.getVersion()),
node.getUser().getName());
printTags(node.getTags());
}
public static void print(
Way way ) {
System.out.format(
"%s: %10s, version %2s by %s with %s waypoints%n",
"Way",
way.getId(),
way.getVersion(),
way.getUser().getName(),
way.getWayNodes().size());
printTags(way.getTags());
}
public static void printTags(
Collection<Tag> tags ) {
if (tags.size() > 0) {
System.out.format(
"\tTags: %s%n",
formatTags(tags));
}
}
public static String formatTags(
Collection<Tag> tags ) {
StringBuilder sb = new StringBuilder(
tags.size() * 20);
for (Tag tag : tags) {
sb.append(", ");
sb.append(tag.getKey());
sb.append('=');
sb.append(tag.getValue());
}
if (sb.length() > 2) {
sb.delete(
0,
2);
}
return sb.toString();
}
}