use of org.onebusaway.collections.Min in project onebusaway-application-modules by camsys.
the class DistanceAlongShapeLibrary method computeBestAssignment.
private List<PointAndIndex> computeBestAssignment(ShapePoints shapePoints, List<StopTimeEntryImpl> stopTimes, List<List<PointAndIndex>> possibleAssignments, UTMProjection projection, List<XYPoint> projectedShapePoints) throws InvalidStopToShapeMappingException {
checkFirstAndLastStop(stopTimes, possibleAssignments, shapePoints, projection, projectedShapePoints);
int startIndex = 0;
int assingmentCount = 1;
/**
* We iterate over each stop, examining its possible assignments. If we find
* a region of stops where the first and last stop have a single assignment
* but the stops in-between have multiple assignments, we compute the best
* assignments for that section. We also handle the edge-cases where the
* multiple potential assignments occur at the start or end of the route.
*/
for (int index = 0; index < possibleAssignments.size(); index++) {
List<PointAndIndex> possibleAssignment = possibleAssignments.get(index);
int count = possibleAssignment.size();
if (count == 0) {
constructErrorForPotentialAssignmentCount(shapePoints, stopTimes, count);
}
boolean hasRegion = index > startIndex;
boolean hasSingleAssignmentFollowingMultipleAssignments = count == 1 && assingmentCount > 1;
boolean hasMultipleAssignmentsAndLastPoint = count > 1 && index == possibleAssignments.size() - 1;
if (hasRegion && (hasSingleAssignmentFollowingMultipleAssignments || hasMultipleAssignmentsAndLastPoint)) {
List<PointAndIndex> currentAssignment = new ArrayList<PointAndIndex>(index - startIndex + 1);
Min<Assignment> bestAssignments = new Min<Assignment>();
recursivelyConstructAssignments(possibleAssignments, currentAssignment, startIndex, startIndex, index + 1, bestAssignments);
if (bestAssignments.isEmpty()) {
constructError(shapePoints, stopTimes, possibleAssignments, projection);
} else {
List<PointAndIndex> bestAssignment = bestAssignments.getMinElement().assigment;
for (int bestIndex = 0; bestIndex < bestAssignment.size(); bestIndex++) {
possibleAssignments.set(startIndex + bestIndex, Arrays.asList(bestAssignment.get(bestIndex)));
}
}
}
if (count == 1) {
startIndex = index;
assingmentCount = 1;
} else {
assingmentCount *= count;
if (assingmentCount > _maximumNumberOfPotentialAssignments) {
constructErrorForPotentialAssignmentCount(shapePoints, stopTimes, assingmentCount);
}
}
}
List<PointAndIndex> bestAssignment = new ArrayList<PointAndIndex>();
for (List<PointAndIndex> possibleAssignment : possibleAssignments) {
if (possibleAssignment.size() != 1) {
String msg = "expected just one assignment at this point, found " + possibleAssignment.size() + "; " + "shapePoint=" + shapePoints.getShapeId() + ", " + "\npossibleAssignments=\n";
for (PointAndIndex pa : possibleAssignment) {
msg += "PointAndIndex(index=" + pa.index + ", point=" + pa.point + ", distanceAlongShape=" + pa.distanceAlongShape + ", distanceFromTarget=" + pa.distanceFromTarget + "), ";
}
msg += "\nstopTime=\n";
for (StopTimeEntryImpl st : stopTimes) {
msg += "StopTimeEntry(Stop(" + st.getStop().getId() + ":" + st.getStop().getStopLat() + ", " + st.getStop().getStopLon() + ")" + ", trip=" + st.getTrip().getId() + "), ";
}
_log.error(msg);
if (!_lenientStopShapeAssignment)
throw new IllegalStateException(msg);
}
bestAssignment.add(possibleAssignment.get(0));
}
return bestAssignment;
}
use of org.onebusaway.collections.Min in project onebusaway-application-modules by camsys.
the class StopsBeanServiceImpl method getStopsByBoundsAndQuery.
private StopsBean getStopsByBoundsAndQuery(SearchQueryBean queryBean) throws ServiceException {
CoordinateBounds bounds = queryBean.getBounds();
String query = queryBean.getQuery();
int maxCount = queryBean.getMaxCount();
CoordinatePoint center = SphericalGeometryLibrary.getCenterOfBounds(bounds);
SearchResult<AgencyAndId> stops;
try {
stops = _searchService.searchForStopsByCode(query, 10, MIN_SCORE);
} catch (ParseException e) {
throw new InvalidArgumentServiceException("query", "queryParseError");
} catch (IOException e) {
_log.error("error executing stop search: query=" + query, e);
e.printStackTrace();
throw new ServiceException();
}
Min<StopBean> closest = new Min<StopBean>();
List<StopBean> stopBeans = new ArrayList<StopBean>();
for (AgencyAndId aid : stops.getResults()) {
StopBean stopBean = _stopBeanService.getStopForId(aid);
if (bounds.contains(stopBean.getLat(), stopBean.getLon()))
stopBeans.add(stopBean);
double distance = SphericalGeometryLibrary.distance(center.getLat(), center.getLon(), stopBean.getLat(), stopBean.getLon());
closest.add(distance, stopBean);
}
boolean limitExceeded = BeanServiceSupport.checkLimitExceeded(stopBeans, maxCount);
// If nothing was found in range, add the closest result
if (stopBeans.isEmpty() && !closest.isEmpty())
stopBeans.add(closest.getMinElement());
return constructResult(stopBeans, limitExceeded);
}
use of org.onebusaway.collections.Min in project onebusaway-application-modules by camsys.
the class BlockCalendarServiceImpl method getClosestActiveBlocks.
@Override
public List<BlockInstance> getClosestActiveBlocks(AgencyAndId blockId, long time) {
Date timeAsDate = new Date(time);
Min<BlockInstance> m = new Min<BlockInstance>();
BlockEntry blockEntry = _transitGraphDao.getBlockEntryForId(blockId);
for (BlockConfigurationEntry blockConfig : blockEntry.getConfigurations()) {
List<Date> serviceDates = _calendarService.getDatesForServiceIdsAsOrderedList(blockConfig.getServiceIds());
int index = index(Collections.binarySearch(serviceDates, timeAsDate));
if (index > 0) {
BlockInstance instance = new BlockInstance(blockConfig, serviceDates.get(index - 1).getTime());
long delta = getTimeToBlockInstance(instance, time);
m.add(delta, instance);
}
if (index < serviceDates.size()) {
BlockInstance instance = new BlockInstance(blockConfig, serviceDates.get(index).getTime());
long delta = getTimeToBlockInstance(instance, time);
m.add(delta, instance);
}
}
return m.getMinElements();
}
use of org.onebusaway.collections.Min in project onebusaway-application-modules by camsys.
the class BlockLocationServiceImpl method getBestBlockForRecord.
private BlockInstance getBestBlockForRecord(AgencyAndId blockId, long serviceDate, long timeOfRecord) {
long timeFrom = timeOfRecord - _blockInstanceMatchingWindow;
long timeTo = timeOfRecord + _blockInstanceMatchingWindow;
List<BlockInstance> blocks = _blockCalendarService.getActiveBlocks(blockId, timeFrom, timeTo);
if (blocks.isEmpty())
return null;
else if (blocks.size() == 1)
return blocks.get(0);
Min<BlockInstance> m = new Min<BlockInstance>();
for (BlockInstance block : blocks) {
long delta = Math.abs(block.getServiceDate() - serviceDate);
m.add(delta, block);
}
return m.getMinElement();
}
use of org.onebusaway.collections.Min in project onebusaway-application-modules by camsys.
the class GtfsRealtimeTripLibrary method getBlockStopTimeForStopTimeUpdate.
private BlockStopTimeEntry getBlockStopTimeForStopTimeUpdate(MonitoredResult result, TripUpdate tripUpdate, StopTimeUpdate stopTimeUpdate, List<BlockStopTimeEntry> stopTimes, long serviceDate) {
if (stopTimeUpdate.hasStopSequence()) {
int stopSequence = stopTimeUpdate.getStopSequence();
Map<Integer, BlockStopTimeEntry> sequenceToStopTime = MappingLibrary.mapToValue(stopTimes, "stopTime.gtfsSequence");
if (sequenceToStopTime.containsKey(stopSequence)) {
BlockStopTimeEntry blockStopTime = sequenceToStopTime.get(stopSequence);
if (!stopTimeUpdate.hasStopId()) {
if (result != null) {
result.addMatchedStopId(blockStopTime.getStopTime().getStop().getId().getId());
}
return blockStopTime;
}
String stopTimeUpdateStopId = convertStopId(stopTimeUpdate.getStopId());
if (blockStopTime.getStopTime().getStop().getId().getId().equals(stopTimeUpdateStopId)) {
if (result != null) {
result.addMatchedStopId(blockStopTime.getStopTime().getStop().getId().getId());
}
return blockStopTime;
}
// The stop sequence and stop id didn't match, so we fall through to
// match by stop id if possible
// we do not log this as it still may match later
} else {
_log.debug("StopTimeSequence is out of bounds: stopSequence=" + stopSequence + " tripUpdate=\n" + tripUpdate);
// sadly we can't report an invalid stop sequence -- we need a stopId
}
}
if (stopTimeUpdate.hasStopId()) {
int time = getTimeForStopTimeUpdate(stopTimeUpdate, serviceDate);
String stopId = convertStopId(stopTimeUpdate.getStopId());
// There could be loops, meaning a stop could appear multiple times along
// a trip. To get around this.
Min<BlockStopTimeEntry> bestMatches = new Min<BlockStopTimeEntry>();
for (BlockStopTimeEntry blockStopTime : stopTimes) {
if (blockStopTime.getStopTime().getStop().getId().getId().equals(stopId)) {
StopTimeEntry stopTime = blockStopTime.getStopTime();
int departureDelta = Math.abs(stopTime.getDepartureTime() - time);
int arrivalDelta = Math.abs(stopTime.getArrivalTime() - time);
bestMatches.add(departureDelta, blockStopTime);
bestMatches.add(arrivalDelta, blockStopTime);
}
}
if (!bestMatches.isEmpty()) {
if (result != null) {
result.addMatchedStopId(convertStopId(stopId));
}
return bestMatches.getMinElement();
}
}
if (result != null) {
// if we are here, the stop did not fall on that block
result.addUnmatchedStopId(convertStopId(stopTimeUpdate.getStopId()));
}
return null;
}
Aggregations