use of org.locationtech.jts.linearref.LinearLocation in project OpenTripPlanner by opentripplanner.
the class MatchState method distanceAlongGeometry.
/* computes the distance, in meters, along a geometry */
protected static double distanceAlongGeometry(Geometry geometry, LinearLocation startIndex, LinearLocation endIndex) {
if (endIndex == null) {
endIndex = LinearLocation.getEndLocation(geometry);
}
double total = 0;
LinearIterator it = new LinearIterator(geometry, startIndex);
LinearLocation index = startIndex;
Coordinate previousCoordinate = startIndex.getCoordinate(geometry);
it.next();
index = it.getLocation();
while (index.compareTo(endIndex) < 0) {
Coordinate thisCoordinate = index.getCoordinate(geometry);
double distance = SphericalDistanceLibrary.fastDistance(previousCoordinate, thisCoordinate);
total += distance;
previousCoordinate = thisCoordinate;
if (!it.hasNext())
break;
it.next();
index = it.getLocation();
}
// now, last bit of last segment
Coordinate finalCoordinate = endIndex.getCoordinate(geometry);
total += SphericalDistanceLibrary.distance(previousCoordinate, finalCoordinate);
return total;
}
use of org.locationtech.jts.linearref.LinearLocation in project OpenTripPlanner by opentripplanner.
the class GeometryUtils method splitGeometryAtPoint.
/**
* Splits the input geometry into two LineStrings at the given point.
*/
public static P2<LineString> splitGeometryAtPoint(Geometry geometry, Coordinate nearestPoint) {
// An index in JTS can actually refer to any point along the line. It is NOT an array index.
LocationIndexedLine line = new LocationIndexedLine(geometry);
LinearLocation l = line.indexOf(nearestPoint);
LineString beginning = (LineString) line.extractLine(line.getStartIndex(), l);
LineString ending = (LineString) line.extractLine(l, line.getEndIndex());
return new P2<LineString>(beginning, ending);
}
use of org.locationtech.jts.linearref.LinearLocation in project OpenTripPlanner by opentripplanner.
the class TestHalfEdges method testHalfEdges.
@Test
public void testHalfEdges() {
// the shortest half-edge from the start vertex takes you down, but the shortest total path
// is up and over
int nVertices = graph.getVertices().size();
int nEdges = graph.getEdges().size();
RoutingRequest options = new RoutingRequest();
HashSet<Edge> turns = new HashSet<Edge>();
turns.add(left);
turns.add(leftBack);
TemporaryStreetLocation start = StreetVertexIndex.createTemporaryStreetLocation(graph, "start", new NonLocalizedString("start"), filter(turns, StreetEdge.class), new LinearLocation(0, 0.4).getCoordinate(left.getGeometry()), false);
HashSet<Edge> endTurns = new HashSet<Edge>();
endTurns.add(right);
endTurns.add(rightBack);
TemporaryStreetLocation end = StreetVertexIndex.createTemporaryStreetLocation(graph, "end", new NonLocalizedString("end"), filter(endTurns, StreetEdge.class), new LinearLocation(0, 0.8).getCoordinate(right.getGeometry()), true);
assertTrue(start.getX() < end.getX());
assertTrue(start.getY() < end.getY());
Collection<Edge> edges = end.getIncoming();
assertEquals(2, edges.size());
long startTime = TestUtils.dateInSeconds("America/New_York", 2009, 11, 1, 12, 34, 25);
options.dateTime = startTime;
options.setRoutingContext(graph, br, end);
options.setMaxWalkDistance(Double.MAX_VALUE);
ShortestPathTree spt1 = aStar.getShortestPathTree(options);
GraphPath pathBr = spt1.getPath(end, false);
assertNotNull("There must be a path from br to end", pathBr);
options.setRoutingContext(graph, tr, end);
ShortestPathTree spt2 = aStar.getShortestPathTree(options);
GraphPath pathTr = spt2.getPath(end, false);
assertNotNull("There must be a path from tr to end", pathTr);
assertTrue("path from bottom to end must be longer than path from top to end", pathBr.getWeight() > pathTr.getWeight());
options.setRoutingContext(graph, start, end);
ShortestPathTree spt = aStar.getShortestPathTree(options);
GraphPath path = spt.getPath(end, false);
assertNotNull("There must be a path from start to end", path);
// the bottom is not part of the shortest path
for (State s : path.states) {
assertNotSame(s.getVertex(), graph.getVertex("bottom"));
assertNotSame(s.getVertex(), graph.getVertex("bottomBack"));
}
options.setArriveBy(true);
options.setRoutingContext(graph, start, end);
spt = aStar.getShortestPathTree(options);
path = spt.getPath(start, false);
assertNotNull("There must be a path from start to end (looking back)", path);
// the bottom edge is not part of the shortest path
for (State s : path.states) {
assertNotSame(s.getVertex(), graph.getVertex("bottom"));
assertNotSame(s.getVertex(), graph.getVertex("bottomBack"));
}
// Number of vertices and edges should be the same as before after a cleanup.
options.cleanup();
assertEquals(nVertices, graph.getVertices().size());
assertEquals(nEdges, graph.getEdges().size());
/*
* Now, the right edge is not bikeable. But the user can walk their bike. So here are some tests that prove (a) that walking bikes works, but
* that (b) it is not preferred to riding a tiny bit longer.
*/
options = new RoutingRequest(new TraverseModeSet(TraverseMode.BICYCLE));
start = StreetVertexIndex.createTemporaryStreetLocation(graph, "start1", new NonLocalizedString("start1"), filter(turns, StreetEdge.class), new LinearLocation(0, 0.95).getCoordinate(top.getGeometry()), false);
end = StreetVertexIndex.createTemporaryStreetLocation(graph, "end1", new NonLocalizedString("end1"), filter(turns, StreetEdge.class), new LinearLocation(0, 0.95).getCoordinate(bottom.getGeometry()), true);
options.setRoutingContext(graph, start, end);
spt = aStar.getShortestPathTree(options);
path = spt.getPath(start, false);
assertNotNull("There must be a path from top to bottom along the right", path);
// the left edge is not part of the shortest path (even though the bike must be walked along the right)
for (State s : path.states) {
assertNotSame(s.getVertex(), graph.getVertex("left"));
assertNotSame(s.getVertex(), graph.getVertex("leftBack"));
}
// Number of vertices and edges should be the same as before after a cleanup.
options.cleanup();
assertEquals(nVertices, graph.getVertices().size());
assertEquals(nEdges, graph.getEdges().size());
start = StreetVertexIndex.createTemporaryStreetLocation(graph, "start2", new NonLocalizedString("start2"), filter(turns, StreetEdge.class), new LinearLocation(0, 0.55).getCoordinate(top.getGeometry()), false);
end = StreetVertexIndex.createTemporaryStreetLocation(graph, "end2", new NonLocalizedString("end2"), filter(turns, StreetEdge.class), new LinearLocation(0, 0.55).getCoordinate(bottom.getGeometry()), true);
options.setRoutingContext(graph, start, end);
spt = aStar.getShortestPathTree(options);
path = spt.getPath(start, false);
assertNotNull("There must be a path from top to bottom", path);
// the right edge is not part of the shortest path, e
for (State s : path.states) {
assertNotSame(s.getVertex(), graph.getVertex("right"));
assertNotSame(s.getVertex(), graph.getVertex("rightBack"));
}
// Number of vertices and edges should be the same as before after a cleanup.
options.cleanup();
assertEquals(nVertices, graph.getVertices().size());
assertEquals(nEdges, graph.getEdges().size());
}
use of org.locationtech.jts.linearref.LinearLocation in project OpenTripPlanner by opentripplanner.
the class TestHalfEdges method testStreetSplittingAlerts.
/**
* Test that alerts on split streets are preserved, i.e. if there are alerts on the street that is split the same alerts should be present on the
* new street.
*/
@Test
public void testStreetSplittingAlerts() {
HashSet<Edge> turns = new HashSet<Edge>();
turns.add(left);
turns.add(leftBack);
StreetNote alert = new StreetNote("This is the alert");
Set<StreetNote> alerts = new HashSet<>();
alerts.add(alert);
graph.streetNotesService.addStaticNote(left, alert, StreetNotesService.ALWAYS_MATCHER);
graph.streetNotesService.addStaticNote(leftBack, alert, StreetNotesService.ALWAYS_MATCHER);
TemporaryStreetLocation start = StreetVertexIndex.createTemporaryStreetLocation(graph, "start", new NonLocalizedString("start"), filter(turns, StreetEdge.class), new LinearLocation(0, 0.4).getCoordinate(left.getGeometry()), false);
// The alert should be preserved
// traverse the FreeEdge from the StreetLocation to the new IntersectionVertex
RoutingRequest req = new RoutingRequest();
req.setMaxWalkDistance(Double.MAX_VALUE);
State traversedOne = new State(start, req);
State currentState;
for (Edge e : start.getOutgoing()) {
currentState = e.traverse(traversedOne);
if (currentState != null) {
traversedOne = currentState;
break;
}
}
assertEquals(alerts, graph.streetNotesService.getNotes(traversedOne));
assertNotSame(left, traversedOne.getBackEdge().getFromVertex());
assertNotSame(leftBack, traversedOne.getBackEdge().getFromVertex());
// now, make sure wheelchair alerts are preserved
StreetNote wheelchairAlert = new StreetNote("This is the wheelchair alert");
Set<StreetNote> wheelchairAlerts = new HashSet<>();
wheelchairAlerts.add(wheelchairAlert);
graph.streetNotesService.removeStaticNotes(left);
graph.streetNotesService.removeStaticNotes(leftBack);
graph.streetNotesService.addStaticNote(left, wheelchairAlert, StreetNotesService.WHEELCHAIR_MATCHER);
graph.streetNotesService.addStaticNote(leftBack, wheelchairAlert, StreetNotesService.WHEELCHAIR_MATCHER);
req.setWheelchairAccessible(true);
start = StreetVertexIndex.createTemporaryStreetLocation(graph, "start", new NonLocalizedString("start"), filter(turns, StreetEdge.class), new LinearLocation(0, 0.4).getCoordinate(left.getGeometry()), false);
traversedOne = new State(start, req);
for (Edge e : start.getOutgoing()) {
currentState = e.traverse(traversedOne);
if (currentState != null) {
traversedOne = currentState;
break;
}
}
assertEquals(wheelchairAlerts, graph.streetNotesService.getNotes(traversedOne));
assertNotSame(left, traversedOne.getBackEdge().getFromVertex());
assertNotSame(leftBack, traversedOne.getBackEdge().getFromVertex());
}
use of org.locationtech.jts.linearref.LinearLocation in project OpenTripPlanner by opentripplanner.
the class TestHalfEdges method testRouteToSameEdgeBackwards.
@Test
public void testRouteToSameEdgeBackwards() {
RoutingRequest options = new RoutingRequest();
// Sits only on the leftmost edge, not on its reverse.
HashSet<Edge> turns = new HashSet<Edge>();
turns.add(left);
TemporaryStreetLocation start = StreetVertexIndex.createTemporaryStreetLocation(graph, "start", new NonLocalizedString("start"), filter(turns, StreetEdge.class), new LinearLocation(0, 0.8).getCoordinate(left.getGeometry()), false);
TemporaryStreetLocation end = StreetVertexIndex.createTemporaryStreetLocation(graph, "end", new NonLocalizedString("end"), filter(turns, StreetEdge.class), new LinearLocation(0, 0.4).getCoordinate(left.getGeometry()), true);
assertEquals(start.getX(), end.getX(), 0.001);
assertTrue(start.getY() > end.getY());
Collection<Edge> edges = end.getIncoming();
assertEquals(1, edges.size());
long startTime = TestUtils.dateInSeconds("America/New_York", 2009, 11, 1, 12, 34, 25);
options.dateTime = startTime;
options.setRoutingContext(graph, start, end);
options.setMaxWalkDistance(Double.MAX_VALUE);
ShortestPathTree spt = aStar.getShortestPathTree(options);
GraphPath path = spt.getPath(end, false);
assertNotNull("There must be a path from start to end", path);
assertTrue(path.edges.size() > 1);
options.cleanup();
}
Aggregations