CoreLMPreparationHandler.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.routing.graphhopper.extensions.core;
import com.graphhopper.routing.lm.LMConfig;
import com.graphhopper.routing.lm.LMPreparationHandler;
import com.graphhopper.routing.lm.LandmarkSuggestion;
import com.graphhopper.routing.lm.PrepareLandmarks;
import com.graphhopper.storage.GraphHopperStorage;
import com.graphhopper.storage.RoutingCHGraph;
import org.apache.log4j.Logger;
import org.heigit.ors.routing.graphhopper.extensions.ORSGraphHopperConfig;
import org.heigit.ors.routing.graphhopper.extensions.ORSGraphHopperStorage;
import org.heigit.ors.routing.graphhopper.extensions.util.GraphUtils;
import org.heigit.ors.routing.graphhopper.extensions.util.ORSParameters.CoreLandmark;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* This class implements the A*, landmark and triangulation (ALT) decorator for Core.
* <p>
* This code is based on that from GraphHopper GmbH.
*
* @author Peter Karich
* @author Hendrik Leuschner
* @author Andrzej Oles
*/
public class CoreLMPreparationHandler extends LMPreparationHandler {
private static final Logger logger = Logger.getLogger(CoreLandmarkStorage.class);
private final CoreLMOptions coreLMOptions = new CoreLMOptions();
public CoreLMPreparationHandler() {
super();
PREPARE = CoreLandmark.PREPARE;
DISABLE = CoreLandmark.DISABLE;
COUNT = CoreLandmark.COUNT;
}
public void init(ORSGraphHopperConfig ghConfig) {
init(ghConfig, ghConfig.getCoreLMProfiles());
//Get the landmark sets that should be calculated
String coreLMSets = ghConfig.getString(CoreLandmark.LMSETS, "allow_all");
if (!coreLMSets.isEmpty() && !coreLMSets.equalsIgnoreCase("no")) {
List<String> tmpCoreLMSets = Arrays.asList(coreLMSets.split(";"));
coreLMOptions.setRestrictionFilters(tmpCoreLMSets);
}
}
@Override
protected void createPreparationsInternal(GraphHopperStorage ghStorage, List<LandmarkSuggestion> lmSuggestions) {
for (LMConfig lmConfig : getLMConfigs()) {
if (!(lmConfig instanceof CoreLMConfig coreLMConfig))
throw (new IllegalStateException("Expected instance of CoreLMConfig"));
if (!(ghStorage instanceof ORSGraphHopperStorage))
throw (new IllegalStateException("Expected instance of ORSGraphHopperStorage"));
String lmConfigName = coreLMConfig.getSuperName();
RoutingCHGraph core = ((ORSGraphHopperStorage) ghStorage).getCoreGraph(lmConfigName);
Map<Integer, Integer> coreNodeIdMap = createCoreNodeIdMap(core);
logger.info("Created core node ID map for " + coreLMConfig.getName() + " of size " + coreNodeIdMap.size());
Double maximumWeight = getMaximumWeights().get(lmConfigName);
if (maximumWeight == null)
throw new IllegalStateException("""
maximumWeight cannot be null. Default should be just negative. \
Couldn't find \
""" + lmConfigName + " in " + getMaximumWeights());
PrepareLandmarks tmpPrepareLM = new PrepareCoreLandmarks(ghStorage.getDirectory(), ghStorage,
coreLMConfig, getLandmarks(), coreNodeIdMap).
setLandmarkSuggestions(lmSuggestions).
setMaximumWeight(maximumWeight).
setLogDetails(getLogDetails());
if (getMinNodes() > 1)
tmpPrepareLM.setMinimumNodes(getMinNodes());
addPreparation(tmpPrepareLM);
}
}
/**
* This method creates a mapping of CoreNode ids to integers from 0 to numCoreNodes to save space.
* Otherwise we would have to store a lot of empty info
*/
public static HashMap<Integer, Integer> createCoreNodeIdMap(RoutingCHGraph core) {
HashMap<Integer, Integer> coreNodeIdMap = new HashMap<>();
int maxNode = GraphUtils.getBaseGraph(core).getNodes();
int coreNodeLevel = maxNode;
int index = 0;
for (int i = 0; i < maxNode; i++) {
if (core.getLevel(i) < coreNodeLevel)
continue;
coreNodeIdMap.put(i, index);
index++;
}
return coreNodeIdMap;
}
public CoreLMOptions getCoreLMOptions() {
return coreLMOptions;
}
}