org.opentripplanner.graph_builder.linking.SampleStopLinker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
package org.opentripplanner.graph_builder.linking;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
import org.opentripplanner.analyst.core.Sample;
import org.opentripplanner.analyst.request.SampleFactory;
import org.opentripplanner.common.geometry.GeometryUtils;
import org.opentripplanner.common.geometry.SphericalDistanceLibrary;
import org.opentripplanner.routing.edgetype.IntersectionTransitLink;
import org.opentripplanner.routing.edgetype.SimpleTransfer;
import org.opentripplanner.routing.graph.Graph;
import org.opentripplanner.routing.graph.Vertex;
import org.opentripplanner.routing.vertextype.OsmVertex;
import org.opentripplanner.routing.vertextype.TransitStop;
import java.util.Collection;
/**
* Link transit stops to the street network in a non-destructive manner; i.e. don't
* modify the street network. Being non-destructive is important in Analyst; new transit
* models should not affect the length of existing streets, even slightly (due to float
* roundoff from splits, etc.) An error of even a few seconds can be significant if it causes
* the router to miss a transit vehicle or transfer, or causes the stop to move just beyond a
* hard boundary.
*
* We do this by using the same linking code that is used
* for Analyst (the SampleFactory code) which additionally means that this code
* path is used and tested in multiple applications.
*
* This is not currently used. But it could be very useful for patching temporary transit lines in
* interactively generated scenarios.
*/
public class SampleStopLinker {
private Graph graph;
/** keep track of stops that are linked to the same vertices */
private Multimap links;
public SampleStopLinker (Graph graph) {
this.graph = graph;
}
/**
* Link all transit stops. If makeTransfers is true, create direct transfer
* edges between stops linked to the same pair of vertices. This is important
* e.g. for transit centers where there are many stops on the same street segment;
* we don't want to force the user to walk to the end of the street and back.
*
* If you're not generating transfers via the street network there is no need to make
* transfers at this stage. But if you're not generating transfers via the street network,
* why are you using this module at all?
*/
public void link (boolean makeTransfers) {
if (makeTransfers)
links = HashMultimap.create();
SampleFactory sf = graph.getSampleFactory();
for (TransitStop tstop : Iterables.filter(graph.getVertices(), TransitStop.class)) {
Sample s = sf.getSample(tstop.getLon(), tstop.getLat());
// TODO: stop unlinked annotation
if (s == null)
continue;
new IntersectionTransitLink(tstop, (OsmVertex) s.v0, s.d0);
new IntersectionTransitLink((OsmVertex) s.v0, tstop, s.d0);
new IntersectionTransitLink(tstop, (OsmVertex) s.v1, s.d1);
new IntersectionTransitLink((OsmVertex) s.v1, tstop, s.d1);
if (makeTransfers) {
// save the sample so we can make direct transfers between stops
VertexPair vp = new VertexPair(s.v0, s.v1);
links.put(vp, tstop);
}
}
if (makeTransfers) {
// make direct transfers between stops
for (Collection tss : links.asMap().values()) {
for (TransitStop ts0 : tss) {
for (TransitStop ts1 : tss) {
// make a geometry
GeometryFactory gf = GeometryUtils.getGeometryFactory();
LineString geom =
gf.createLineString(new Coordinate[] { ts0.getCoordinate(), ts1.getCoordinate() });
double dist =
SphericalDistanceLibrary.distance(ts0.getLat(), ts0.getLon(), ts1.getLat(), ts1.getLon());
// building unidirectional edge, we'll hit this again in the opposite direction
new SimpleTransfer(ts1, ts1, dist, geom);
}
}
}
}
}
/** represents an unordered pair of vertices from a sample */
private static class VertexPair {
private final int v1, v2;
public VertexPair(Vertex v1, Vertex v2) {
this.v1 = v1.getIndex();
this.v2 = v2.getIndex();
}
public int hashCode() {
// bidirectional hash code
return v1 + v2;
}
public boolean equals (Object other) {
if (other instanceof VertexPair) {
VertexPair vpo = (VertexPair) other;
// bidirectional comparison
return vpo.v1 == v1 && vpo.v2 == v2 || vpo.v2 == v1 && vpo.v1 == v2;
}
return false;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy