use of org.onebusaway.transit_data_federation.impl.shapes.PointAndIndex in project onebusaway-application-modules by camsys.
the class BlockGeospatialServiceImpl method getBestScheduledBlockLocationForLocation.
public ScheduledBlockLocation getBestScheduledBlockLocationForLocation(BlockInstance blockInstance, CoordinatePoint location, long timestamp, double blockDistanceFrom, double blockDistanceTo) {
BlockConfigurationEntry block = blockInstance.getBlock();
ProjectedPoint targetPoint = ProjectedPointFactory.forward(location);
List<AgencyAndId> shapePointIds = MappingLibrary.map(block.getTrips(), "trip.shapeId");
T2<List<XYPoint>, double[]> tuple = _projectedShapePointService.getProjectedShapePoints(shapePointIds, targetPoint.getSrid());
if (tuple == null) {
throw new IllegalStateException("block had no shape points: " + block.getBlock().getId());
}
List<XYPoint> projectedShapePoints = tuple.getFirst();
double[] distances = tuple.getSecond();
int fromIndex = 0;
int toIndex = distances.length;
if (blockDistanceFrom > 0) {
fromIndex = Arrays.binarySearch(distances, blockDistanceFrom);
if (fromIndex < 0) {
fromIndex = -(fromIndex + 1);
// Include the previous point if we didn't get an exact match
if (fromIndex > 0)
fromIndex--;
}
}
if (blockDistanceTo < distances[distances.length - 1]) {
toIndex = Arrays.binarySearch(distances, blockDistanceTo);
if (toIndex < 0) {
toIndex = -(toIndex + 1);
// Include the previous point if we didn't get an exact match
if (toIndex < distances.length)
toIndex++;
}
}
XYPoint xyPoint = new XYPoint(targetPoint.getX(), targetPoint.getY());
List<PointAndIndex> assignments = _shapePointsLibrary.computePotentialAssignments(projectedShapePoints, distances, xyPoint, fromIndex, toIndex);
Min<ScheduledBlockLocation> best = new Min<ScheduledBlockLocation>();
for (PointAndIndex index : assignments) {
double distanceAlongBlock = index.distanceAlongShape;
if (distanceAlongBlock > block.getTotalBlockDistance())
distanceAlongBlock = block.getTotalBlockDistance();
ScheduledBlockLocation blockLocation = _scheduledBlockLocationService.getScheduledBlockLocationFromDistanceAlongBlock(block, distanceAlongBlock);
if (blockLocation != null) {
int scheduledTime = blockLocation.getScheduledTime();
long scheduleTimestamp = blockInstance.getServiceDate() + scheduledTime * 1000;
double delta = Math.abs(scheduleTimestamp - timestamp);
best.add(delta, blockLocation);
}
}
return best.getMinElement();
}
use of org.onebusaway.transit_data_federation.impl.shapes.PointAndIndex in project onebusaway-application-modules by camsys.
the class DistanceAlongShapeLibrary method assignmentSanityCheck.
private void assignmentSanityCheck(ShapePoints shapePoints, List<StopTimeEntryImpl> stopTimes, List<List<PointAndIndex>> possibleAssignments) throws DistanceAlongShapeException {
int stIndex = 0;
for (List<PointAndIndex> assignments : possibleAssignments) {
if (assignments.isEmpty()) {
StopTimeEntry stopTime = stopTimes.get(stIndex);
throw new InvalidStopToShapeMappingException(stopTime.getTrip());
}
Min<PointAndIndex> m = new Min<PointAndIndex>();
for (PointAndIndex pindex : assignments) m.add(pindex.distanceFromTarget, pindex);
if (m.getMinValue() > _maxDistanceFromStopToShapePoint) {
StopTimeEntry stopTime = stopTimes.get(stIndex);
PointAndIndex pindex = m.getMinElement();
CoordinatePoint point = shapePoints.getPointForIndex(pindex.index);
throw new StopIsTooFarFromShapeException(stopTime, pindex, point);
}
stIndex++;
}
}
use of org.onebusaway.transit_data_federation.impl.shapes.PointAndIndex in project onebusaway-application-modules by camsys.
the class DistanceAlongShapeLibrary method constructError.
private void constructError(ShapePoints shapePoints, List<StopTimeEntryImpl> stopTimes, List<List<PointAndIndex>> possibleAssignments, UTMProjection projection) throws InvalidStopToShapeMappingException {
StopTimeEntryImpl first = stopTimes.get(0);
StopTimeEntryImpl last = stopTimes.get(stopTimes.size() - 1);
_log.error("We were attempting to compute the distance along a particular trip for each stop time of that trip by " + "snapping them to the shape for that trip. However, we could not find an assignment for each stop time " + "where the distance traveled along the shape for each stop time was strictly increasing (aka a stop time " + "seemed to travel backwards). For more information on errors of this kind, see:\n" + " https://github.com/OneBusAway/onebusaway-application-modules/wiki/Stop-to-Shape-Matching");
TripEntryImpl trip = first.getTrip();
_log.error("error constructing stop-time distances along shape for trip=" + trip.getId() + " shape=" + trip.getShapeId() + " firstStopTime=" + first.getId() + " lastStopTime=" + last.getId());
StringBuilder b = new StringBuilder();
int index = 0;
b.append("# potential assignments:\n");
b.append("# stopLat stopLon stopId\n");
b.append("# locationOnShapeLat locationOnShapeLon distanceAlongShape distanceFromShape shapePointIndex\n");
b.append("# ...\n");
double prevMaxDistanceAlongShape = Double.NEGATIVE_INFINITY;
for (List<PointAndIndex> possible : possibleAssignments) {
StopTimeEntryImpl stopTime = stopTimes.get(index);
StopEntryImpl stop = stopTime.getStop();
b.append(stop.getStopLat());
b.append(' ');
b.append(stop.getStopLon());
b.append(' ');
b.append(index);
b.append(' ');
b.append(stop.getId());
b.append('\n');
double maxDistanceAlongShape = Double.NEGATIVE_INFINITY;
double minDistanceAlongShape = Double.POSITIVE_INFINITY;
for (PointAndIndex pindex : possible) {
b.append(" ");
b.append(projection.reverse(pindex.point));
b.append(' ');
b.append(_errorFormatter.format(pindex.distanceAlongShape));
b.append(' ');
b.append(_errorFormatter.format(pindex.distanceFromTarget));
b.append(' ');
b.append(pindex.index);
b.append("\n");
maxDistanceAlongShape = Math.max(maxDistanceAlongShape, pindex.distanceAlongShape);
minDistanceAlongShape = Math.min(minDistanceAlongShape, pindex.distanceAlongShape);
}
if (minDistanceAlongShape < prevMaxDistanceAlongShape) {
b.append(" ^ potential problem here ^\n");
}
prevMaxDistanceAlongShape = maxDistanceAlongShape;
index++;
}
_log.error(b.toString());
if (_shapeIdsWeHavePrinted.add(trip.getShapeId())) {
b = new StringBuilder();
index = 0;
for (int i = 0; i < shapePoints.getSize(); i++) {
b.append(shapePoints.getLatForIndex(i));
b.append(' ');
b.append(shapePoints.getLonForIndex(i));
b.append(' ');
b.append(shapePoints.getDistTraveledForIndex(i));
b.append('\n');
}
_log.error("shape points:\n" + b.toString());
}
throw new InvalidStopToShapeMappingException(first.getTrip());
}
use of org.onebusaway.transit_data_federation.impl.shapes.PointAndIndex in project onebusaway-application-modules by camsys.
the class DistanceAlongShapeLibrary method getDistancesAlongShape.
public PointAndIndex[] getDistancesAlongShape(ShapePoints shapePoints, List<StopTimeEntryImpl> stopTimes) throws DistanceAlongShapeException {
PointAndIndex[] stopTimePoints = new PointAndIndex[stopTimes.size()];
UTMProjection projection = UTMLibrary.getProjectionForPoint(shapePoints.getLats()[0], shapePoints.getLons()[0]);
List<XYPoint> projectedShapePoints = _shapePointsLibrary.getProjectedShapePoints(shapePoints, projection);
double[] shapePointsDistTraveled = shapePoints.getDistTraveled();
List<List<PointAndIndex>> possibleAssignments = computePotentialAssignments(projection, projectedShapePoints, shapePointsDistTraveled, stopTimes);
pruneUnnecessaryAssignments(possibleAssignments);
assignmentSanityCheck(shapePoints, stopTimes, possibleAssignments);
double maxDistanceTraveled = shapePointsDistTraveled[shapePointsDistTraveled.length - 1];
List<PointAndIndex> bestAssignment = computeBestAssignment(shapePoints, stopTimes, possibleAssignments, projection, projectedShapePoints);
double last = Double.NEGATIVE_INFINITY;
for (int i = 0; i < stopTimePoints.length; i++) {
PointAndIndex pindex = bestAssignment.get(i);
if (pindex.distanceAlongShape > maxDistanceTraveled) {
int index = projectedShapePoints.size() - 1;
XYPoint point = projectedShapePoints.get(index);
StopEntryImpl stop = stopTimes.get(i).getStop();
XYPoint stopPoint = projection.forward(stop.getStopLocation());
double d = stopPoint.getDistance(point);
pindex = new PointAndIndex(point, index, d, maxDistanceTraveled);
}
if (last > pindex.distanceAlongShape) {
constructError(shapePoints, stopTimes, possibleAssignments, projection);
}
last = pindex.distanceAlongShape;
stopTimePoints[i] = pindex;
}
return stopTimePoints;
}
use of org.onebusaway.transit_data_federation.impl.shapes.PointAndIndex in project onebusaway-application-modules by camsys.
the class DistanceAlongShapeLibraryTest method test03.
@Test
public void test03() throws IOException, DistanceAlongShapeException {
ShapePoints shapePoints = readShapePoints("shapes-03.txt");
List<StopTimeEntryImpl> stopTimes = readStopTimes("stops-03.txt");
DistanceAlongShapeLibrary library = new DistanceAlongShapeLibrary();
PointAndIndex[] points = library.getDistancesAlongShape(shapePoints, stopTimes);
assertEquals(5, points.length);
// STOP A
assertEquals(67.9, points[0].distanceAlongShape, 0.1);
assertEquals(0, points[0].index);
// STOP B
assertEquals(446.0, points[1].distanceAlongShape, 0.1);
assertEquals(1, points[1].index);
// STOP C
assertEquals(852.7, points[2].distanceAlongShape, 0.1);
assertEquals(2, points[2].index);
// STOP D
assertEquals(1247.0, points[3].distanceAlongShape, 0.1);
assertEquals(3, points[3].index);
}
Aggregations