use of org.onebusaway.transit_data_federation.impl.shapes.PointAndIndex in project onebusaway-application-modules by camsys.
the class DistanceAlongShapeLibrary method pruneUnnecessaryAssignments.
/**
* The {@link ShapePointsLibrary} returns a number of potential assignments
* for a stop's position along a shape. While some of those potential
* assignments can help us correctly deal with cases where a shape loops back
* on itself or other weird configurations, many of the potential assignments
* are just local minimas that won't ultimately have much affect on the final
* assignment if they don't overlap with the previous or next stop. To help
* reduce the set of possible assignments that we'll have to explore, we just
* pick the best assignment and toss out the rest when the set of assignments
* for a stop don't overlap with the assignments of the previous or next stop.
*
* @param possibleAssignments
*/
private void pruneUnnecessaryAssignments(List<List<PointAndIndex>> possibleAssignments) {
double[] mins = new double[possibleAssignments.size()];
double[] maxs = new double[possibleAssignments.size()];
for (int i = 0; i < possibleAssignments.size(); ++i) {
double minScore = Double.POSITIVE_INFINITY;
double maxScore = Double.NEGATIVE_INFINITY;
for (PointAndIndex pi : possibleAssignments.get(i)) {
minScore = Math.min(minScore, pi.distanceAlongShape);
maxScore = Math.max(maxScore, pi.distanceAlongShape);
}
mins[i] = minScore;
maxs[i] = maxScore;
}
for (int i = 0; i < possibleAssignments.size(); i++) {
List<PointAndIndex> points = possibleAssignments.get(i);
// If there is only one possible assignment, there is nothing to prune
if (points.size() == 1)
continue;
double currentMin = mins[i];
double currentMax = maxs[i];
if (i > 0) {
double prevMax = maxs[i - 1];
if (currentMin < prevMax)
continue;
}
if (i + 1 < possibleAssignments.size()) {
double nextMin = mins[i + 1];
if (currentMax > nextMin)
continue;
}
Collections.sort(points, PointAndIndex.DISTANCE_FROM_TARGET_COMPARATOR);
while (points.size() > 1) points.remove(points.size() - 1);
}
}
use of org.onebusaway.transit_data_federation.impl.shapes.PointAndIndex in project onebusaway-application-modules by camsys.
the class DistanceAlongShapeLibrary method checkFirstAndLastStop.
/**
* Special check for an issue with start points where the first stop isn't all
* that near the start of the shape (the first stop being more of a layover
* point). If the shape is working against us, the closest point for the first
* stop can be a point further along the shape, which causes problems.
*/
private void checkFirstAndLastStop(List<StopTimeEntryImpl> stopTimes, List<List<PointAndIndex>> possibleAssignments, ShapePoints shapePoints, UTMProjection projection, List<XYPoint> projectedShapePoints) {
if (possibleAssignments.size() >= 2) {
PointAndIndex first = possibleAssignments.get(0).get(0);
PointAndIndex second = possibleAssignments.get(1).get(0);
if (first.distanceAlongShape > second.distanceAlongShape) {
StopTimeEntryImpl firstStopTime = stopTimes.get(0);
_log.warn("snapping first stop time id=" + firstStopTime.getId() + " to start of shape");
XYPoint point = projectedShapePoints.get(0);
StopEntryImpl stop = firstStopTime.getStop();
XYPoint stopPoint = projection.forward(stop.getStopLocation());
double d = stopPoint.getDistance(point);
possibleAssignments.get(0).add(new PointAndIndex(point, 0, d, 0.0));
}
int n = possibleAssignments.size();
PointAndIndex prev = possibleAssignments.get(n - 2).get(0);
PointAndIndex last = possibleAssignments.get(n - 1).get(0);
if (prev.distanceAlongShape > last.distanceAlongShape) {
}
}
if (possibleAssignments.size() > 0) {
/**
* We snap the last stop to the end of the shape and add it to the set of
* possible assignments. In the worst case, it will be a higher-scoring
* assignment and ignored, but it can help in cases where the stop was
* weirdly assigned.
*/
PointAndIndex lastSnapped = getLastStopSnappedToEndOfShape(stopTimes, shapePoints, projection, projectedShapePoints);
possibleAssignments.get(possibleAssignments.size() - 1).add(lastSnapped);
}
}
use of org.onebusaway.transit_data_federation.impl.shapes.PointAndIndex in project onebusaway-application-modules by camsys.
the class StopTimeEntriesFactory method ensureStopTimesHaveShapeDistanceTraveledSet.
/**
* We have to make sure shape distance traveled is set, even if we don't have
* shape information
*
* @param stopTimes
* @param shapePoints potentially null
*/
private void ensureStopTimesHaveShapeDistanceTraveledSet(List<StopTimeEntryImpl> stopTimes, ShapePoints shapePoints) {
boolean distanceTraveledSet = false;
// Do we have shape information?
if (shapePoints != null) {
try {
PointAndIndex[] stopTimePoints = _distanceAlongShapeLibrary.getDistancesAlongShape(shapePoints, stopTimes);
for (int i = 0; i < stopTimePoints.length; i++) {
PointAndIndex pindex = stopTimePoints[i];
StopTimeEntryImpl stopTime = stopTimes.get(i);
stopTime.setShapePointIndex(pindex.index);
stopTime.setShapeDistTraveled(pindex.distanceAlongShape);
}
distanceTraveledSet = true;
} catch (StopIsTooFarFromShapeException ex) {
StopTimeEntry stopTime = ex.getStopTime();
TripEntry trip = stopTime.getTrip();
StopEntry stop = stopTime.getStop();
AgencyAndId shapeId = trip.getShapeId();
CoordinatePoint point = ex.getPoint();
PointAndIndex pindex = ex.getPointAndIndex();
_log.warn("Stop is too far from shape: trip=" + trip.getId() + " stop=" + stop.getId() + " stopLat=" + stop.getStopLat() + " stopLon=" + stop.getStopLon() + " shapeId=" + shapeId + " shapePoint=" + point + " index=" + pindex.index + " distance=" + pindex.distanceFromTarget);
} catch (DistanceAlongShapeException ex) {
_invalidStopToShapeMappingExceptionCount++;
} catch (IllegalArgumentException iae) {
_log.warn("Stop has illegal coordinates along shapes=" + shapePoints);
}
}
if (!distanceTraveledSet) {
// Make do without
double d = 0;
StopTimeEntryImpl prev = null;
for (StopTimeEntryImpl stopTime : stopTimes) {
if (prev != null) {
CoordinatePoint from = prev.getStop().getStopLocation();
CoordinatePoint to = stopTime.getStop().getStopLocation();
d += SphericalGeometryLibrary.distance(from, to);
}
stopTime.setShapeDistTraveled(d);
prev = stopTime;
}
}
}
use of org.onebusaway.transit_data_federation.impl.shapes.PointAndIndex in project onebusaway-application-modules by camsys.
the class DistanceAlongShapeLibraryTest method test01.
@Test
public void test01() throws IOException, DistanceAlongShapeException {
ShapePoints shapePoints = readShapePoints("shapes-01.txt");
List<StopTimeEntryImpl> stopTimes = readStopTimes("stops-01.txt");
DistanceAlongShapeLibrary library = new DistanceAlongShapeLibrary();
PointAndIndex[] points = library.getDistancesAlongShape(shapePoints, stopTimes);
assertEquals(70, points.length);
// Let's check a few tricky ones, including the stops that appear multiple
// times
// STOP 1610
assertEquals(127.6, points[0].distanceAlongShape, 0.1);
assertEquals(2, points[0].index);
// STOP 9390
assertEquals(3074.4, points[10].distanceAlongShape, 0.1);
assertEquals(95, points[10].index);
// STOP 29952
assertEquals(13759.9, points[50].distanceAlongShape, 0.1);
assertEquals(452, points[50].index);
// STOP 29090
assertEquals(18015.3, points[68].distanceAlongShape, 0.1);
assertEquals(616, points[68].index);
// assertEquals(18046.3, points[69].distanceAlongShape, 0.1); // STOP 29952
assertEquals(618, points[69].index);
}
use of org.onebusaway.transit_data_federation.impl.shapes.PointAndIndex in project onebusaway-application-modules by camsys.
the class DistanceAlongShapeMain method run.
public void run(String shapeFile, String stopsFile) throws IOException, DistanceAlongShapeException {
ShapePoints shapePoints = readShapePoints(shapeFile);
List<StopTimeEntryImpl> stopTimes = readStopTimes(stopsFile);
DistanceAlongShapeLibrary library = new DistanceAlongShapeLibrary();
PointAndIndex[] points = library.getDistancesAlongShape(shapePoints, stopTimes);
System.out.println(points);
}
Aggregations