/**
* This file is part of Relation Analyzer for OSM.
* Copyright (c) 2001 by Adrian Stabiszewski, as@grundid.de
*
* Relation Analyzer is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Relation Analyzer 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Relation Analyzer. If not, see <http://www.gnu.org/licenses/>.
*/
package org.osmtools.ra.traverse;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.osmtools.ra.data.Node;
import org.osmtools.ra.dijkstra.Dijkstra;
import org.osmtools.ra.dijkstra.Vertex;
import org.osmtools.ra.graph.Graph;
import org.osmtools.ra.graph.IntersectionNode;
import org.osmtools.ra.segment.ConnectableSegment;
import org.springframework.stereotype.Service;
@Service
public class TraverseService {
public List<Node> traverse(IntersectionNode startNode, IntersectionNode endNode) {
SingleRouteTraverser traverser = new SingleRouteTraverser(startNode, endNode);
return traverser.getPath();
}
public List<Node> traverse(Graph graph, IntersectionNode startNode, IntersectionNode endNode) {
Dijkstra dijkstraAlgorithm = new Dijkstra(graph.getEdges());
dijkstraAlgorithm.execute(startNode);
List<Vertex> path = dijkstraAlgorithm.getPath(endNode);
List<Node> result = new ArrayList<Node>();
for (Vertex vertex : path)
result.add(vertex.getNode());
return result;
}
public List<Node> fillInNodes(List<Node> path, Collection<ConnectableSegment> segments) {
if (path.isEmpty())
return path;
List<ConnectableSegment> modifyableSegments = new ArrayList<ConnectableSegment>(segments);
List<Node> result = new ArrayList<Node>();
Node startNode = path.get(0);
result.add(startNode);
for (int x = 1; x < path.size(); x++) {
Node currentNode = path.get(x);
fillInNodesBetweenNodes(modifyableSegments, result, startNode, currentNode);
startNode = currentNode;
}
return result;
}
public static void fillInNodesBetweenNodes(List<ConnectableSegment> modifyableSegments, List<Node> resultNodes,
Node startNode, Node currentNode) {
for (Iterator<ConnectableSegment> it = modifyableSegments.iterator(); it.hasNext();) {
ConnectableSegment connectableSegment = it.next();
if (connectableSegment.containsNodes(startNode, currentNode)) {
int prevSize = resultNodes.size();
connectableSegment.appendNodesBetween(resultNodes, startNode, currentNode);
// If the segment list is only 2 elements we must make sure
// that we not reuse the same segment again
// Scenario: A => B => A
if (modifyableSegments.size() <= 2) {
it.remove();
}
if (prevSize < resultNodes.size())
break;
}
}
}
}