RPHASTMatrixAlgorithm.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.rphast;
import com.graphhopper.GraphHopper;
import com.graphhopper.routing.util.FlagEncoder;
import com.graphhopper.routing.util.TraversalMode;
import com.graphhopper.routing.weighting.Weighting;
import com.graphhopper.storage.RoutingCHGraph;
import org.heigit.ors.matrix.*;
import org.heigit.ors.matrix.algorithms.AbstractMatrixAlgorithm;
import org.heigit.ors.routing.algorithms.RPHASTAlgorithm;
import org.heigit.ors.routing.graphhopper.extensions.storages.MultiTreeSPEntry;
import java.util.ArrayList;
import java.util.List;
public class RPHASTMatrixAlgorithm extends AbstractMatrixAlgorithm {
private MultiTreeMetricsExtractor pathMetricsExtractor;
private RoutingCHGraph chGraph;
// @Override
public void init(MatrixRequest req, GraphHopper gh, RoutingCHGraph chGraph, FlagEncoder encoder, Weighting weighting) {
//TODO Refactoring : check if base graph necessary. Probably not.
super.init(req, gh, chGraph.getBaseGraph(), encoder, weighting);
this.chGraph = chGraph;
pathMetricsExtractor = new MultiTreeMetricsExtractor(req.getMetrics(), chGraph, this.encoder, 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 {
RPHASTAlgorithm algorithm = new RPHASTAlgorithm(chGraph, chGraph.getWeighting(), TraversalMode.NODE_BASED);
algorithm.setMaxVisitedNodes(this.maxVisitedNodes);
int[] srcIds = getValidNodeIds(srcData.getNodeIds());
int[] destIds = getValidNodeIds(dstData.getNodeIds());
if (graphHopper != null)
mtxResult.setGraphDate(graphHopper.getGraphHopperStorage().getProperties().get("datareader.import.date"));
algorithm.prepare(srcIds, destIds);
MultiTreeSPEntry[] destTrees = algorithm.calcPaths(srcIds, destIds);
MultiTreeSPEntry[] originalDestTrees = new MultiTreeSPEntry[dstData.size()];
int j = 0;
for (int i = 0; i < dstData.size(); i++) {
if (dstData.getNodeIds()[i] != -1) {
originalDestTrees[i] = destTrees[j];
++j;
} else {
originalDestTrees[i] = null;
}
}
pathMetricsExtractor.calcValues(originalDestTrees, srcData, 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;
}
private int[] getValidNodeIds(int[] nodeIds) {
List<Integer> nodeList = new ArrayList<>();
for (int dst : nodeIds) {
if (dst != -1)
nodeList.add(dst);
}
int[] res = new int[nodeList.size()];
for (int i = 0; i < nodeList.size(); i++)
res[i] = nodeList.get(i);
return res;
}
}