ArrayList<Long> nodes = new ArrayList<Long>(way.getNodeRefs().size());
long last = -1;
double lastLat = -1, lastLon = -1;
String lastLevel = null;
for (long nodeId : way.getNodeRefs()) {
OSMNode node = osmdb.getNode(nodeId);
if (node == null)
continue WAY;
boolean levelsDiffer = false;
String level = node.getTag("level");
if (lastLevel == null) {
if (level != null) {
levelsDiffer = true;
}
} else {
if (!lastLevel.equals(level)) {
levelsDiffer = true;
}
}
if (nodeId != last
&& (node.lat != lastLat || node.lon != lastLon || levelsDiffer))
nodes.add(nodeId);
last = nodeId;
lastLon = node.lon;
lastLat = node.lat;
lastLevel = level;
}
IntersectionVertex startEndpoint = null, endEndpoint = null;
ArrayList<Coordinate> segmentCoordinates = new ArrayList<Coordinate>();
/*
* Traverse through all the nodes of this edge. For nodes which are not shared with any other edge, do not create endpoints -- just
* accumulate them for geometry and ele tags. For nodes which are shared, create endpoints and StreetVertex instances. One exception:
* if the next vertex also appears earlier in the way, we need to split the way, because otherwise we have a way that loops from a
* vertex to itself, which could cause issues with splitting.
*/
Long startNode = null;
// where the current edge should start
OSMNode osmStartNode = null;
for (int i = 0; i < nodes.size() - 1; i++) {
OSMNode segmentStartOSMNode = osmdb.getNode(nodes.get(i));
if (segmentStartOSMNode == null) {
continue;
}
Long endNode = nodes.get(i + 1);
if (osmStartNode == null) {
startNode = nodes.get(i);
osmStartNode = segmentStartOSMNode;
}
// where the current edge might end
OSMNode osmEndNode = osmdb.getNode(endNode);
if (osmStartNode == null || osmEndNode == null)
continue;
LineString geometry;
/*
* We split segments at intersections, self-intersections, nodes with ele tags, and transit stops;
* the only processing we do on other nodes is to accumulate their geometry
*/
if (segmentCoordinates.size() == 0) {
segmentCoordinates.add(getCoordinate(osmStartNode));
}
if (intersectionNodes.containsKey(endNode) || i == nodes.size() - 2
|| nodes.subList(0, i).contains(nodes.get(i))
|| osmEndNode.hasTag("ele")
|| osmEndNode.isStop()) {
segmentCoordinates.add(getCoordinate(osmEndNode));
geometry = GeometryUtils.getGeometryFactory().createLineString(
segmentCoordinates.toArray(new Coordinate[0]));
segmentCoordinates.clear();
} else {
segmentCoordinates.add(getCoordinate(osmEndNode));
continue;
}
/* generate endpoints */
if (startEndpoint == null) { // first iteration on this way
// make or get a shared vertex for flat intersections,
// one vertex per level for multilevel nodes like elevators
startEndpoint = getVertexForOsmNode(osmStartNode, way);
String ele = segmentStartOSMNode.getTag("ele");
if (ele != null) {
Double elevation = ElevationUtils.parseEleTag(ele);
if (elevation != null) {
elevationData.put(startEndpoint, elevation);
}
}
} else { // subsequent iterations
startEndpoint = endEndpoint;
}
endEndpoint = getVertexForOsmNode(osmEndNode, way);
String ele = osmEndNode.getTag("ele");
if (ele != null) {
Double elevation = ElevationUtils.parseEleTag(ele);
if (elevation != null) {
elevationData.put(endEndpoint, elevation);
}
}
P2<StreetEdge> streets = getEdgesForStreet(startEndpoint, endEndpoint,
way, i, osmStartNode.getId(), osmEndNode.getId(), permissions, geometry);
StreetEdge street = streets.first;
StreetEdge backStreet = streets.second;
applyWayProperties(street, backStreet, wayData, way);