use of org.opentripplanner.routing.vertextype.SplitterVertex in project OpenTripPlanner by opentripplanner.
the class LinkingTest method testSplitting.
/**
* Ensure that splitting edges yields edges that are identical in length for forward and back edges.
* StreetEdges have lengths expressed internally in mm, and we want to be sure that not only do they
* sum to the same values but also that they
*/
@Test
public void testSplitting() {
GeometryFactory gf = GeometryUtils.getGeometryFactory();
double x = -122.123;
double y = 37.363;
for (double delta = 0; delta <= 2; delta += 0.005) {
StreetVertex v0 = new IntersectionVertex(null, "zero", x, y);
StreetVertex v1 = new IntersectionVertex(null, "one", x + delta, y + delta);
LineString geom = gf.createLineString(new Coordinate[] { v0.getCoordinate(), v1.getCoordinate() });
double dist = SphericalDistanceLibrary.distance(v0.getCoordinate(), v1.getCoordinate());
StreetEdge s0 = new StreetEdge(v0, v1, geom, "test", dist, StreetTraversalPermission.ALL, false);
StreetEdge s1 = new StreetEdge(v1, v0, (LineString) geom.reverse(), "back", dist, StreetTraversalPermission.ALL, true);
// split it but not too close to the end
double splitVal = Math.random() * 0.95 + 0.025;
SplitterVertex sv0 = new SplitterVertex(null, "split", x + delta * splitVal, y + delta * splitVal, s0);
SplitterVertex sv1 = new SplitterVertex(null, "split", x + delta * splitVal, y + delta * splitVal, s1);
P2<StreetEdge> sp0 = s0.split(sv0, true);
P2<StreetEdge> sp1 = s1.split(sv1, true);
// distances expressed internally in mm so this epsilon is plenty good enough to ensure that they
// have the same values
assertEquals(sp0.first.getDistance(), sp1.second.getDistance(), 0.0000001);
assertEquals(sp0.second.getDistance(), sp1.first.getDistance(), 0.0000001);
assertFalse(sp0.first.isBack());
assertFalse(sp0.second.isBack());
assertTrue(sp1.first.isBack());
assertTrue(sp1.second.isBack());
}
}
use of org.opentripplanner.routing.vertextype.SplitterVertex in project OpenTripPlanner by opentripplanner.
the class SimpleStreetSplitter method split.
/**
* Split the street edge at the given fraction
*
* @param edge to be split
* @param ll fraction at which to split the edge
* @param temporarySplit if true this is temporary split at origin/destinations search and only temporary edges vertices are created
* @param endVertex if this is temporary edge this is true if this is end vertex otherwise it doesn't matter
* @return Splitter vertex with added new edges
*/
private SplitterVertex split(StreetEdge edge, LinearLocation ll, boolean temporarySplit, boolean endVertex) {
LineString geometry = edge.getGeometry();
// create the geometries
Coordinate splitPoint = ll.getCoordinate(geometry);
// every edge can be split exactly once, so this is a valid label
SplitterVertex v;
if (temporarySplit) {
v = new TemporarySplitterVertex(graph, "split from " + edge.getId(), splitPoint.x, splitPoint.y, edge, endVertex);
if (edge.isWheelchairAccessible()) {
((TemporarySplitterVertex) v).setWheelchairAccessible(true);
} else {
((TemporarySplitterVertex) v).setWheelchairAccessible(false);
}
} else {
v = new SplitterVertex(graph, "split from " + edge.getId(), splitPoint.x, splitPoint.y, edge);
}
// make the edges
// TODO this is using the StreetEdge implementation of split, which will discard elevation information
// on edges that have it
P2<StreetEdge> edges = edge.split(v, !temporarySplit);
if (destructiveSplitting) {
// update indices of new edges
idx.insert(edges.first.getGeometry(), edges.first);
idx.insert(edges.second.getGeometry(), edges.second);
// (no need to remove original edge, we filter it when it comes out of the index)
// remove original edge from the graph
edge.getToVertex().removeIncoming(edge);
edge.getFromVertex().removeOutgoing(edge);
}
return v;
}
use of org.opentripplanner.routing.vertextype.SplitterVertex in project OpenTripPlanner by opentripplanner.
the class SimpleStreetSplitter method link.
/**
* split the edge and link in the transit stop
*/
private void link(Vertex tstop, StreetEdge edge, double xscale, RoutingRequest options) {
// TODO: we've already built this line string, we should save it
LineString orig = edge.getGeometry();
LineString transformed = equirectangularProject(orig, xscale);
LocationIndexedLine il = new LocationIndexedLine(transformed);
LinearLocation ll = il.project(new Coordinate(tstop.getLon() * xscale, tstop.getLat()));
// street to use the same vertices. Otherwise the order the stops are loaded in will affect where they are snapped.
if (ll.getSegmentIndex() == 0 && ll.getSegmentFraction() < 1e-8) {
makeLinkEdges(tstop, (StreetVertex) edge.getFromVertex());
} else // past the last point
if (ll.getSegmentIndex() == orig.getNumPoints() - 1) {
makeLinkEdges(tstop, (StreetVertex) edge.getToVertex());
} else // nPoints - 2: -1 to correct for index vs count, -1 to account for fencepost problem
if (ll.getSegmentIndex() == orig.getNumPoints() - 2 && ll.getSegmentFraction() > 1 - 1e-8) {
makeLinkEdges(tstop, (StreetVertex) edge.getToVertex());
} else {
TemporaryVertex temporaryVertex = null;
boolean endVertex = false;
if (tstop instanceof TemporaryVertex) {
temporaryVertex = (TemporaryVertex) tstop;
endVertex = temporaryVertex.isEndVertex();
}
// It is only used in origin/destination linking since otherwise options is null
if (options != null) {
options.canSplitEdge(edge);
}
// split the edge, get the split vertex
SplitterVertex v0 = split(edge, ll, temporaryVertex != null, endVertex);
makeLinkEdges(tstop, v0);
}
}
Aggregations