use of org.opentripplanner.routing.graph.Vertex in project OpenTripPlanner by opentripplanner.
the class StreetUtils method pruneFloatingIslands.
public static void pruneFloatingIslands(Graph graph, int maxIslandSize, int islandWithStopMaxSize, String islandLogName) {
LOG.debug("pruning");
PrintWriter islandLog = null;
if (islandLogName != null && !islandLogName.isEmpty()) {
try {
islandLog = new PrintWriter(new File(islandLogName));
} catch (Exception e) {
LOG.error("Failed to write islands log file", e);
}
}
if (islandLog != null) {
islandLog.printf("%s\t%s\t%s\t%s\t%s\n", "id", "stopCount", "streetCount", "wkt", "hadRemoved");
}
Map<Vertex, Subgraph> subgraphs = new HashMap<Vertex, Subgraph>();
Map<Vertex, ArrayList<Vertex>> neighborsForVertex = new HashMap<Vertex, ArrayList<Vertex>>();
// RoutingRequest options = new RoutingRequest(new TraverseModeSet(TraverseMode.WALK, TraverseMode.TRANSIT));
RoutingRequest options = new RoutingRequest(new TraverseModeSet(TraverseMode.WALK));
for (Vertex gv : graph.getVertices()) {
if (!(gv instanceof StreetVertex)) {
continue;
}
State s0 = new State(gv, options);
for (Edge e : gv.getOutgoing()) {
Vertex in = gv;
if (!(e instanceof StreetEdge || e instanceof StreetTransitLink || e instanceof ElevatorEdge || e instanceof FreeEdge)) {
continue;
}
State s1 = e.traverse(s0);
if (s1 == null) {
continue;
}
Vertex out = s1.getVertex();
ArrayList<Vertex> vertexList = neighborsForVertex.get(in);
if (vertexList == null) {
vertexList = new ArrayList<Vertex>();
neighborsForVertex.put(in, vertexList);
}
vertexList.add(out);
vertexList = neighborsForVertex.get(out);
if (vertexList == null) {
vertexList = new ArrayList<Vertex>();
neighborsForVertex.put(out, vertexList);
}
vertexList.add(in);
}
}
ArrayList<Subgraph> islands = new ArrayList<Subgraph>();
/* associate each node with a subgraph */
for (Vertex gv : graph.getVertices()) {
if (!(gv instanceof StreetVertex)) {
continue;
}
Vertex vertex = gv;
if (subgraphs.containsKey(vertex)) {
continue;
}
if (!neighborsForVertex.containsKey(vertex)) {
continue;
}
Subgraph subgraph = computeConnectedSubgraph(neighborsForVertex, vertex);
if (subgraph != null) {
for (Iterator<Vertex> vIter = subgraph.streetIterator(); vIter.hasNext(); ) {
Vertex subnode = vIter.next();
subgraphs.put(subnode, subgraph);
}
islands.add(subgraph);
}
}
LOG.info(islands.size() + " sub graphs found");
/* remove all tiny subgraphs and large subgraphs without stops */
for (Subgraph island : islands) {
boolean hadRemoved = false;
if (island.stopSize() > 0) {
// for islands with stops
if (island.streetSize() < islandWithStopMaxSize) {
depedestrianizeOrRemove(graph, island);
hadRemoved = true;
}
} else {
// for islands without stops
if (island.streetSize() < maxIslandSize) {
depedestrianizeOrRemove(graph, island);
hadRemoved = true;
}
}
if (islandLog != null) {
WriteNodesInSubGraph(island, islandLog, hadRemoved);
}
}
if (graph.removeEdgelessVertices() > 0) {
LOG.warn("Removed edgeless vertices after pruning islands");
}
}
use of org.opentripplanner.routing.graph.Vertex in project OpenTripPlanner by opentripplanner.
the class WalkableAreaBuilder method buildWithVisibility.
public void buildWithVisibility(AreaGroup group, boolean platformEntriesLinking) {
Set<OSMNode> startingNodes = new HashSet<OSMNode>();
Set<Vertex> startingVertices = new HashSet<Vertex>();
Set<Edge> edges = new HashSet<Edge>();
// create polygon and accumulate nodes for area
for (Ring ring : group.outermostRings) {
AreaEdgeList edgeList = new AreaEdgeList();
// the points corresponding to concave or hole vertices
// or those linked to ways
ArrayList<VLPoint> visibilityPoints = new ArrayList<VLPoint>();
ArrayList<OSMNode> visibilityNodes = new ArrayList<OSMNode>();
HashSet<P2<OSMNode>> alreadyAddedEdges = new HashSet<P2<OSMNode>>();
// and to avoid the numerical problems that they tend to cause
for (Area area : group.areas) {
// parameter is true
if (platformEntriesLinking && "platform".equals(area.parent.getTag("public_transport"))) {
continue;
}
if (!ring.toJtsPolygon().contains(area.toJTSMultiPolygon())) {
continue;
}
// Add stops from public transit relations into the area
Collection<OSMNode> nodes = osmdb.getStopsInArea(area.parent);
if (nodes != null) {
for (OSMNode node : nodes) {
addtoVisibilityAndStartSets(startingNodes, visibilityPoints, visibilityNodes, node);
}
}
for (Ring outerRing : area.outermostRings) {
for (int i = 0; i < outerRing.nodes.size(); ++i) {
OSMNode node = outerRing.nodes.get(i);
createEdgesForRingSegment(edges, edgeList, area, outerRing, i, alreadyAddedEdges);
addtoVisibilityAndStartSets(startingNodes, visibilityPoints, visibilityNodes, node);
}
for (Ring innerRing : outerRing.holes) {
for (int j = 0; j < innerRing.nodes.size(); ++j) {
OSMNode node = innerRing.nodes.get(j);
createEdgesForRingSegment(edges, edgeList, area, innerRing, j, alreadyAddedEdges);
addtoVisibilityAndStartSets(startingNodes, visibilityPoints, visibilityNodes, node);
}
}
}
}
List<OSMNode> nodes = new ArrayList<OSMNode>();
List<VLPoint> vertices = new ArrayList<VLPoint>();
accumulateRingNodes(ring, nodes, vertices);
VLPolygon polygon = makeStandardizedVLPolygon(vertices, nodes, false);
accumulateVisibilityPoints(ring.nodes, polygon, visibilityPoints, visibilityNodes, false);
ArrayList<VLPolygon> polygons = new ArrayList<VLPolygon>();
polygons.add(polygon);
// holes
for (Ring innerRing : ring.holes) {
ArrayList<OSMNode> holeNodes = new ArrayList<OSMNode>();
vertices = new ArrayList<VLPoint>();
accumulateRingNodes(innerRing, holeNodes, vertices);
VLPolygon hole = makeStandardizedVLPolygon(vertices, holeNodes, true);
accumulateVisibilityPoints(innerRing.nodes, hole, visibilityPoints, visibilityNodes, true);
nodes.addAll(holeNodes);
polygons.add(hole);
}
Environment areaEnv = new Environment(polygons);
// areas to prevent way explosion
if (visibilityPoints.size() > MAX_AREA_NODES) {
LOG.warn("Area " + group.getSomeOSMObject() + " is too complicated (" + visibilityPoints.size() + " > " + MAX_AREA_NODES);
continue;
}
if (!areaEnv.is_valid(VISIBILITY_EPSILON)) {
LOG.warn("Area " + group.getSomeOSMObject() + " is not epsilon-valid (epsilon = " + VISIBILITY_EPSILON + ")");
continue;
}
edgeList.setOriginalEdges(ring.toJtsPolygon());
createNamedAreas(edgeList, ring, group.areas);
OSMWithTags areaEntity = group.getSomeOSMObject();
for (int i = 0; i < visibilityNodes.size(); ++i) {
OSMNode nodeI = visibilityNodes.get(i);
VisibilityPolygon visibilityPolygon = new VisibilityPolygon(visibilityPoints.get(i), areaEnv, VISIBILITY_EPSILON);
Polygon poly = toJTSPolygon(visibilityPolygon);
for (int j = 0; j < visibilityNodes.size(); ++j) {
OSMNode nodeJ = visibilityNodes.get(j);
P2<OSMNode> nodePair = new P2<OSMNode>(nodeI, nodeJ);
if (alreadyAddedEdges.contains(nodePair))
continue;
IntersectionVertex startEndpoint = __handler.getVertexForOsmNode(nodeI, areaEntity);
IntersectionVertex endEndpoint = __handler.getVertexForOsmNode(nodeJ, areaEntity);
Coordinate[] coordinates = new Coordinate[] { startEndpoint.getCoordinate(), endEndpoint.getCoordinate() };
GeometryFactory geometryFactory = GeometryUtils.getGeometryFactory();
LineString line = geometryFactory.createLineString(coordinates);
if (poly != null && poly.contains(line)) {
createSegments(nodeI, nodeJ, startEndpoint, endEndpoint, group.areas, edgeList, edges);
if (startingNodes.contains(nodeI)) {
startingVertices.add(startEndpoint);
}
if (startingNodes.contains(nodeJ)) {
startingVertices.add(endEndpoint);
}
}
}
}
}
pruneAreaEdges(startingVertices, edges);
}
use of org.opentripplanner.routing.graph.Vertex in project OpenTripPlanner by opentripplanner.
the class ElevationModule method assignMissingElevations.
/**
* Assign missing elevations by interpolating from nearby points with known
* elevation; also handle osm ele tags
*/
private void assignMissingElevations(Graph graph, List<StreetEdge> edgesWithElevation, HashMap<Vertex, Double> knownElevations) {
log.debug("Assigning missing elevations");
BinHeap<ElevationRepairState> pq = new BinHeap<ElevationRepairState>();
// elevation for each vertex (known or interpolated)
// knownElevations will be null if there are no ElevationPoints in the data
// for instance, with the Shapefile loader.)
HashMap<Vertex, Double> elevations;
if (knownElevations != null)
elevations = (HashMap<Vertex, Double>) knownElevations.clone();
else
elevations = new HashMap<Vertex, Double>();
HashSet<Vertex> closed = new HashSet<Vertex>();
// initialize queue with all vertices which already have known elevation
for (StreetEdge e : edgesWithElevation) {
PackedCoordinateSequence profile = e.getElevationProfile();
if (!elevations.containsKey(e.getFromVertex())) {
double firstElevation = profile.getOrdinate(0, 1);
ElevationRepairState state = new ElevationRepairState(null, null, e.getFromVertex(), 0, firstElevation);
pq.insert(state, 0);
elevations.put(e.getFromVertex(), firstElevation);
}
if (!elevations.containsKey(e.getToVertex())) {
double lastElevation = profile.getOrdinate(profile.size() - 1, 1);
ElevationRepairState state = new ElevationRepairState(null, null, e.getToVertex(), 0, lastElevation);
pq.insert(state, 0);
elevations.put(e.getToVertex(), lastElevation);
}
}
// back pointers through the region of unknown elevation, setting elevations via interpolation.
while (!pq.empty()) {
ElevationRepairState state = pq.extract_min();
if (closed.contains(state.vertex))
continue;
closed.add(state.vertex);
ElevationRepairState curState = state;
Vertex initialVertex = null;
while (curState != null) {
initialVertex = curState.vertex;
curState = curState.backState;
}
double bestDistance = Double.MAX_VALUE;
double bestElevation = 0;
for (Edge e : state.vertex.getOutgoing()) {
if (!(e instanceof StreetEdge)) {
continue;
}
StreetEdge edge = (StreetEdge) e;
Vertex tov = e.getToVertex();
if (tov == initialVertex)
continue;
Double elevation = elevations.get(tov);
if (elevation != null) {
double distance = e.getDistance();
if (distance < bestDistance) {
bestDistance = distance;
bestElevation = elevation;
}
} else {
// continue
ElevationRepairState newState = new ElevationRepairState(edge, state, tov, e.getDistance() + state.distance, state.initialElevation);
pq.insert(newState, e.getDistance() + state.distance);
}
}
for (Edge e : state.vertex.getIncoming()) {
if (!(e instanceof StreetEdge)) {
continue;
}
StreetEdge edge = (StreetEdge) e;
Vertex fromv = e.getFromVertex();
if (fromv == initialVertex)
continue;
Double elevation = elevations.get(fromv);
if (elevation != null) {
double distance = e.getDistance();
if (distance < bestDistance) {
bestDistance = distance;
bestElevation = elevation;
}
} else {
// continue
ElevationRepairState newState = new ElevationRepairState(edge, state, fromv, e.getDistance() + state.distance, state.initialElevation);
pq.insert(newState, e.getDistance() + state.distance);
}
}
// in the case of islands missing elevation (and some other cases)
if (bestDistance == Double.MAX_VALUE && state.distance > 2000) {
log.warn("While propagating elevations, hit 2km distance limit at " + state.vertex);
bestDistance = state.distance;
bestElevation = state.initialElevation;
}
if (bestDistance != Double.MAX_VALUE) {
// we have found a second vertex with elevation, so we can interpolate the elevation
// for this point
double totalDistance = bestDistance + state.distance;
// trace backwards, setting states as we go
while (true) {
// all the way out to edge lengths
if (totalDistance == 0)
elevations.put(state.vertex, bestElevation);
else {
double elevation = (bestElevation * state.distance + state.initialElevation * bestDistance) / totalDistance;
elevations.put(state.vertex, elevation);
}
if (state.backState == null)
break;
bestDistance += state.backEdge.getDistance();
state = state.backState;
if (elevations.containsKey(state.vertex))
break;
}
}
}
// do actual assignments
for (Vertex v : graph.getVertices()) {
Double fromElevation = elevations.get(v);
for (Edge e : v.getOutgoing()) {
if (e instanceof StreetWithElevationEdge) {
StreetWithElevationEdge edge = ((StreetWithElevationEdge) e);
Double toElevation = elevations.get(edge.getToVertex());
if (fromElevation == null || toElevation == null) {
if (!edge.isElevationFlattened() && !edge.isSlopeOverride())
log.warn("Unexpectedly missing elevation for edge " + edge);
continue;
}
if (edge.getElevationProfile() != null && edge.getElevationProfile().size() > 2) {
continue;
}
Coordinate[] coords = new Coordinate[2];
coords[0] = new Coordinate(0, fromElevation);
coords[1] = new Coordinate(edge.getDistance(), toElevation);
PackedCoordinateSequence profile = new PackedCoordinateSequence.Double(coords);
if (edge.setElevationProfile(profile, true)) {
log.trace(graph.addBuilderAnnotation(new ElevationFlattened(edge)));
}
}
}
}
}
use of org.opentripplanner.routing.graph.Vertex in project OpenTripPlanner by opentripplanner.
the class PlatformLinker method linkEntriesToPlatforms.
void linkEntriesToPlatforms() {
LOG.info("Start linking platforms");
List<OsmVertex> endpoints = graph.getVertices().stream().filter(OsmVertex.class::isInstance).map(OsmVertex.class::cast).filter(this::isEndpoint).collect(Collectors.toList());
LOG.info("Endpoints found: " + endpoints.size());
List<Area> platforms = osmdb.getWalkableAreas().stream().filter(area -> "platform".equals(area.parent.getTag("public_transport")) && "platform".equals(area.parent.getTag("railway"))).collect(Collectors.toList());
LOG.info("Platforms found: " + platforms.size());
for (Area area : platforms) {
List<OsmVertex> endpointsWithin = new ArrayList<>();
List<Ring> rings = area.outermostRings;
for (Ring ring : rings) {
endpointsWithin.addAll(endpoints.stream().filter(t -> contains(ring, t)).collect(Collectors.toList()));
for (OSMNode node : ring.nodes) {
Vertex vertexById = graph.getVertex("osm:node:" + node.getId());
if (vertexById != null) {
endpointsWithin.forEach(e -> makePlatformEdges(area, e, (OsmVertex) vertexById));
}
}
}
}
LOG.info("Done linking platforms");
}
use of org.opentripplanner.routing.graph.Vertex in project OpenTripPlanner by opentripplanner.
the class PlatformLinker method isEndpoint.
private boolean isEndpoint(OsmVertex ov) {
boolean isCandidate = false;
Vertex start = null;
for (Edge e : ov.getIncoming()) {
if (e instanceof StreetEdge && !(e instanceof AreaEdge)) {
StreetEdge se = (StreetEdge) e;
if (Arrays.asList(1, 2, 3).contains(se.getPermission().code)) {
isCandidate = true;
start = se.getFromVertex();
break;
}
}
}
if (isCandidate && start != null) {
boolean isEndpoint = true;
for (Edge se : ov.getOutgoing()) {
if (!se.getToVertex().getCoordinate().equals(start.getCoordinate()) && !(se instanceof AreaEdge)) {
isEndpoint = false;
}
}
return isEndpoint;
}
return false;
}
Aggregations