package com.opendoorlogistics.graphhopper;
import java.util.HashMap;
import com.graphhopper.routing.Path;
import com.graphhopper.routing.PathBidirRef;
import com.graphhopper.routing.ch.Path4CH;
import com.graphhopper.routing.util.FlagEncoder;
import com.graphhopper.storage.Graph;
/**
* CH path extractor with caching
*
* @author Phil
*
*/
public class CacheablePath4CH extends PathBidirRef {
private final Graph routingGraph;
private final HashMap<EdgeExpansionCacheKey, DistanceTime> expansionCache;
// private final EdgeExpansionCacheKey cacheKey = new EdgeExpansionCacheKey(-1, -1);
private final FlagEncoder encoder;
public CacheablePath4CH(Graph chGraph, FlagEncoder encoder, HashMap<EdgeExpansionCacheKey, DistanceTime> expansionCache) {
super(chGraph.getBaseGraph(), encoder);
this.routingGraph = chGraph;
this.expansionCache = expansionCache;
this.encoder = encoder;
}
@Override
protected final void processEdge(int tmpEdge, int endNode) {
DistanceTime dt = null;
if (expansionCache != null) {
// try getting from cache
EdgeExpansionCacheKey key = new EdgeExpansionCacheKey(tmpEdge, endNode, this.reverseOrder);
dt = expansionCache.get(key);
// calculate using a new instance without the cache if needed
if (dt == null) {
dt = unpackSingleEdge2DistTime(tmpEdge, endNode, this.reverseOrder);
expansionCache.put(key, dt);
}
} else {
DistanceTime dtTmp = unpackSingleEdge2DistTime(tmpEdge, endNode, this.reverseOrder);
dt = dtTmp;
}
distance += dt.getDistance();
time += dt.getMillis();
}
private DistanceTime unpackSingleEdge2DistTime(int tmpEdge, int endNode, boolean isReverseOrder) {
Path tmpPath = unpackSingleEdge(routingGraph, routingGraph.getBaseGraph(), encoder, tmpEdge, endNode,isReverseOrder);
DistanceTime dtTmp = new DistanceTime(tmpPath.getDistance(), tmpPath.getTime());
return dtTmp;
}
/**
* Unpack a single edge of graph (either CH edge or base edge)
*
* @param routingGraph
* @param baseGraph
* @param encoder
* @param edge
* @param endNode
* @return
*/
public static Path unpackSingleEdge(Graph routingGraph, Graph baseGraph, FlagEncoder encoder, int edge, int endNode, boolean isReverseOrder) {
class SingleEdgeUnpacker extends Path4CH {
public SingleEdgeUnpacker(Graph routingGraph, Graph baseGraph, FlagEncoder encoder) {
super(routingGraph, baseGraph, encoder);
this.reverseOrder = isReverseOrder;
}
/**
* Parameters are passed into the method explicity because if we just use the outer method
* parameters directly we accidentally get the endNode variable from the Path base class instead...
* @param tmpEdge
* @param endNode
*/
public void processSingleEdge(int tmpEdge, int endNode) {
// Access the protected method in the base class
super.processEdge(tmpEdge, endNode);
}
}
SingleEdgeUnpacker unpacker = new SingleEdgeUnpacker(routingGraph, baseGraph, encoder);
unpacker.processSingleEdge(edge, endNode);
return unpacker;
}
}