/**
* Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onebusaway.transit_data_federation.impl.tripplanner;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.onebusaway.collections.tuple.Pair;
import org.onebusaway.collections.tuple.Tuples;
import org.onebusaway.container.refresh.Refreshable;
import org.onebusaway.transit_data_federation.impl.RefreshableResources;
import org.onebusaway.transit_data_federation.impl.transit_graph.StopEntryImpl;
import org.onebusaway.transit_data_federation.services.transit_graph.BlockConfigurationEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.BlockEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.BlockStopTimeEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.StopEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.StopTimeEntry;
import org.onebusaway.transit_data_federation.services.transit_graph.TransitGraphDao;
import org.onebusaway.transit_data_federation.services.tripplanner.StopHop;
import org.onebusaway.transit_data_federation.services.tripplanner.StopHopService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class StopHopServiceImpl implements StopHopService {
private static final StopHopList EMPTY_HOPS = new StopHopList(
new ArrayList<StopHop>());
private TransitGraphDao _transitGraphDao;
@Autowired
public void setTransitGraphDao(TransitGraphDao transitGraphDao) {
_transitGraphDao = transitGraphDao;
}
@PostConstruct
@Refreshable(dependsOn = RefreshableResources.TRANSIT_GRAPH)
public void setup() throws IOException, ClassNotFoundException {
Map<Pair<StopEntry>, Integer> minTravelTimes = computeStopHopPairs();
Map<StopEntry, List<StopHop>> allHopsFromStop = new HashMap<StopEntry, List<StopHop>>();
Map<StopEntry, List<StopHop>> allHopsToStop = new HashMap<StopEntry, List<StopHop>>();
computeHops(minTravelTimes, allHopsFromStop, allHopsToStop);
for (StopEntry stop : _transitGraphDao.getAllStops()) {
List<StopHop> hopsFromStop = allHopsFromStop.get(stop);
List<StopHop> hopsToStop = allHopsToStop.get(stop);
StopEntryImpl stopEntry = (StopEntryImpl) stop;
stopEntry.setHops(new StopHops(hopsFromStop, hopsToStop));
}
}
private void computeHops(Map<Pair<StopEntry>, Integer> minTravelTimes,
Map<StopEntry, List<StopHop>> allHopsFromStop,
Map<StopEntry, List<StopHop>> allHopsToStop) {
for (Map.Entry<Pair<StopEntry>, Integer> entry : minTravelTimes.entrySet()) {
Pair<StopEntry> pair = entry.getKey();
StopEntry fromStop = pair.getFirst();
StopEntry toStop = pair.getSecond();
int minTravelTime = entry.getValue();
/**
* From Stop
*/
List<StopHop> hopsFromStop = allHopsFromStop.get(fromStop);
if (hopsFromStop == null) {
hopsFromStop = new ArrayList<StopHop>();
allHopsFromStop.put(fromStop, hopsFromStop);
}
hopsFromStop.add(new StopHop(toStop, minTravelTime));
/**
* To Stop
*/
List<StopHop> hopsToStop = allHopsToStop.get(toStop);
if (hopsToStop == null) {
hopsToStop = new ArrayList<StopHop>();
allHopsToStop.put(fromStop, hopsToStop);
}
hopsToStop.add(new StopHop(fromStop, minTravelTime));
}
for( Map.Entry<StopEntry, List<StopHop>> entry : allHopsFromStop.entrySet()) {
List<StopHop> value = entry.getValue();
value = new StopHopList(value);
entry.setValue(value);
}
for( Map.Entry<StopEntry, List<StopHop>> entry : allHopsToStop.entrySet()) {
List<StopHop> value = entry.getValue();
value = new StopHopList(value);
entry.setValue(value);
}
}
private Map<Pair<StopEntry>, Integer> computeStopHopPairs() {
Map<Pair<StopEntry>, Integer> minTravelTimes = new HashMap<Pair<StopEntry>, Integer>();
for (BlockEntry block : _transitGraphDao.getAllBlocks()) {
for (BlockConfigurationEntry blockConfig : block.getConfigurations()) {
List<BlockStopTimeEntry> stopTimes = blockConfig.getStopTimes();
BlockStopTimeEntry prevBlockStopTime = null;
for (BlockStopTimeEntry blockStopTime : stopTimes) {
if (prevBlockStopTime != null) {
StopTimeEntry from = prevBlockStopTime.getStopTime();
StopTimeEntry to = blockStopTime.getStopTime();
int time = to.getArrivalTime() - from.getDepartureTime();
StopEntry stopFrom = from.getStop();
StopEntry stopTo = to.getStop();
Pair<StopEntry> stopPair = Tuples.pair(stopFrom, stopTo);
Integer prevTime = minTravelTimes.get(stopPair);
if (prevTime == null || time < prevTime)
minTravelTimes.put(stopPair, time);
}
prevBlockStopTime = blockStopTime;
}
}
}
return minTravelTimes;
}
@Override
public List<StopHop> getHopsFromStop(StopEntry stop) {
StopEntryImpl impl = (StopEntryImpl) stop;
StopHops hops = impl.getHops();
if (hops == null || hops.getHopsFromStop() == null)
return EMPTY_HOPS;
return hops.getHopsFromStop();
}
@Override
public List<StopHop> getHopsToStop(StopEntry stop) {
StopEntryImpl impl = (StopEntryImpl) stop;
StopHops hops = impl.getHops();
if (hops == null || hops.getHopsToStop() == null)
return EMPTY_HOPS;
return hops.getHopsToStop();
}
}