DijkstraMatrixAlgorithm.java
/* This file is part of Openrouteservice.
*
* Openrouteservice is free software; you can redistribute it and/or modify it under the terms of the
* GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public License along with this library;
* if not, see <https://www.gnu.org/licenses/>.
*/
package org.heigit.ors.matrix.algorithms.dijkstra;
import com.graphhopper.GraphHopper;
import com.graphhopper.routing.SPTEntry;
import com.graphhopper.routing.util.AccessFilter;
import com.graphhopper.routing.util.FlagEncoder;
import com.graphhopper.routing.util.TraversalMode;
import com.graphhopper.routing.weighting.Weighting;
import com.graphhopper.storage.Graph;
import org.heigit.ors.matrix.*;
import org.heigit.ors.matrix.algorithms.AbstractMatrixAlgorithm;
import org.heigit.ors.routing.algorithms.DijkstraOneToManyAlgorithm;
public class DijkstraMatrixAlgorithm extends AbstractMatrixAlgorithm {
private PathMetricsExtractor pathMetricsExtractor;
@Override
public void init(MatrixRequest req, GraphHopper gh, Graph graph, FlagEncoder encoder, Weighting weighting) {
weighting = graph.wrapWeighting(weighting);
super.init(req, gh, graph, encoder, weighting);
pathMetricsExtractor = new PathMetricsExtractor(req.getMetrics(), this.graph, this.weighting, req.getUnits());
}
@Override
public MatrixResult compute(MatrixLocations srcData, MatrixLocations dstData, int metrics) throws Exception {
MatrixResult mtxResult = new MatrixResult(srcData.getLocations(), dstData.getLocations());
float[] times = null;
float[] distances = null;
float[] weights = null;
int tableSize = srcData.size() * dstData.size();
if (MatrixMetricsType.isSet(metrics, MatrixMetricsType.DURATION))
times = new float[tableSize];
if (MatrixMetricsType.isSet(metrics, MatrixMetricsType.DISTANCE))
distances = new float[tableSize];
if (MatrixMetricsType.isSet(metrics, MatrixMetricsType.WEIGHT))
weights = new float[tableSize];
if (!srcData.hasValidNodes() || !dstData.hasValidNodes()) {
for (int srcIndex = 0; srcIndex < srcData.size(); srcIndex++)
pathMetricsExtractor.setEmptyValues(srcIndex, dstData, times, distances, weights);
} else {
DijkstraOneToManyAlgorithm algorithm = new DijkstraOneToManyAlgorithm(graph, weighting, TraversalMode.NODE_BASED, true);
//TODO Refactoring : Check whether this access filter is unnecessary
algorithm.setEdgeFilter(AccessFilter.allEdges(this.encoder.getAccessEnc()));
algorithm.prepare(srcData.getNodeIds(), dstData.getNodeIds());
algorithm.setMaxVisitedNodes(this.maxVisitedNodes);
int sourceId = -1;
for (int srcIndex = 0; srcIndex < srcData.size(); srcIndex++) {
sourceId = srcData.getNodeId(srcIndex);
if (sourceId == -1) {
pathMetricsExtractor.setEmptyValues(srcIndex, dstData, times, distances, weights);
} else {
algorithm.reset();
SPTEntry[] targets = algorithm.calcPaths(sourceId, dstData.getNodeIds());
if (algorithm.getFoundTargets() != algorithm.getTargetsCount())
throw new Exception("Some target nodes could not be found.");
if (targets != null) {
pathMetricsExtractor.calcValues(srcIndex, targets, dstData, times, distances, weights);
}
}
}
}
if (MatrixMetricsType.isSet(metrics, MatrixMetricsType.DURATION))
mtxResult.setTable(MatrixMetricsType.DURATION, times);
if (MatrixMetricsType.isSet(metrics, MatrixMetricsType.DISTANCE))
mtxResult.setTable(MatrixMetricsType.DISTANCE, distances);
if (MatrixMetricsType.isSet(metrics, MatrixMetricsType.WEIGHT))
mtxResult.setTable(MatrixMetricsType.WEIGHT, weights);
return mtxResult;
}
}