use of com.graphhopper.routing.weighting.custom.CustomProfile in project graphhopper by graphhopper.
the class GraphHopperManaged method resolveCustomModelFiles.
public static List<Profile> resolveCustomModelFiles(String customModelFolder, List<Profile> profiles) {
ObjectMapper yamlOM = Jackson.initObjectMapper(new ObjectMapper(new YAMLFactory()));
ObjectMapper jsonOM = Jackson.newObjectMapper();
List<Profile> newProfiles = new ArrayList<>();
for (Profile profile : profiles) {
if (!CustomWeighting.NAME.equals(profile.getWeighting())) {
newProfiles.add(profile);
continue;
}
Object cm = profile.getHints().getObject("custom_model", null);
if (cm != null) {
try {
// custom_model can be an object tree (read from config) or an object (e.g. from tests)
CustomModel customModel = jsonOM.readValue(jsonOM.writeValueAsBytes(cm), CustomModel.class);
newProfiles.add(new CustomProfile(profile).setCustomModel(customModel));
continue;
} catch (Exception ex) {
throw new RuntimeException("Cannot load custom_model from " + cm + " for profile " + profile.getName(), ex);
}
}
String customModelFileName = profile.getHints().getString("custom_model_file", "");
if (customModelFileName.isEmpty())
throw new IllegalArgumentException("Missing 'custom_model' or 'custom_model_file' field in profile '" + profile.getName() + "'. To use default specify custom_model_file: empty");
if ("empty".equals(customModelFileName))
newProfiles.add(new CustomProfile(profile).setCustomModel(new CustomModel()));
else {
if (customModelFileName.contains(File.separator))
throw new IllegalArgumentException("Use custom_model_folder for the custom_model_file parent");
// Somehow dropwizard makes it very hard to find out the folder of config.yml -> use an extra parameter for the folder
File file = Paths.get(customModelFolder).resolve(customModelFileName).toFile();
try {
CustomModel customModel = (customModelFileName.endsWith(".json") ? jsonOM : yamlOM).readValue(file, CustomModel.class);
newProfiles.add(new CustomProfile(profile).setCustomModel(customModel));
} catch (Exception ex) {
throw new RuntimeException("Cannot load custom_model from location " + customModelFileName + " for profile " + profile.getName(), ex);
}
}
}
return newProfiles;
}
use of com.graphhopper.routing.weighting.custom.CustomProfile in project graphhopper by graphhopper.
the class GraphHopperOSMTest method testLoadingCustomProfiles.
@Test
public void testLoadingCustomProfiles() {
CustomModel customModel = new CustomModel().setDistanceInfluence(123);
GraphHopper hopper = new GraphHopper().setGraphHopperLocation(ghLoc).setOSMFile(testOsm).setProfiles(new CustomProfile("car").setCustomModel(customModel));
hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("car"));
hopper.importOrLoad();
hopper.close();
// load without problem
hopper = new GraphHopper().setProfiles(new CustomProfile("car").setCustomModel(customModel));
hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("car"));
hopper.setGraphHopperLocation(ghLoc);
assertTrue(hopper.load());
hopper.close();
// do not load changed CustomModel
customModel.setDistanceInfluence(100);
hopper = new GraphHopper().setProfiles(new CustomProfile("car").setCustomModel(customModel));
hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("car"));
hopper.setGraphHopperLocation(ghLoc);
try {
assertFalse(hopper.load());
fail("load should fail");
} catch (Exception ex) {
assertEquals("LM preparation of car already exists in storage and doesn't match configuration", ex.getMessage());
} finally {
hopper.close();
}
}
use of com.graphhopper.routing.weighting.custom.CustomProfile in project graphhopper by graphhopper.
the class Measurement method createConfigFromArgs.
private GraphHopperConfig createConfigFromArgs(PMap args) {
GraphHopperConfig ghConfig = new GraphHopperConfig(args);
String encodingManagerString = args.getString("graph.flag_encoders", "car");
List<FlagEncoder> tmpEncoders = EncodingManager.create(encodingManagerString).fetchEdgeEncoders();
if (tmpEncoders.size() != 1) {
logger.warn("You configured multiple encoders, only the first one is used for the measurements");
}
vehicle = tmpEncoders.get(0).toString();
boolean turnCosts = tmpEncoders.get(0).supportsTurnCosts();
int uTurnCosts = args.getInt("measurement.u_turn_costs", 40);
String weighting = args.getString("measurement.weighting", "fastest");
boolean useCHEdge = args.getBool("measurement.ch.edge", true);
boolean useCHNode = args.getBool("measurement.ch.node", true);
boolean useLM = args.getBool("measurement.lm", true);
String customModelFile = args.getString("measurement.custom_model_file", "");
List<Profile> profiles = new ArrayList<>();
if (!customModelFile.isEmpty()) {
if (!weighting.equals(CustomWeighting.NAME))
throw new IllegalArgumentException("To make use of a custom model you need to set measurement.weighting to 'custom'");
// use custom profile(s) as specified in the given custom model file
CustomModel customModel = loadCustomModel(customModelFile);
profiles.add(new CustomProfile("profile_no_tc").setCustomModel(customModel).setVehicle(vehicle).setTurnCosts(false));
if (turnCosts)
profiles.add(new CustomProfile("profile_tc").setCustomModel(customModel).setVehicle(vehicle).setTurnCosts(true).putHint(U_TURN_COSTS, uTurnCosts));
} else {
// use standard profiles
profiles.add(new Profile("profile_no_tc").setVehicle(vehicle).setWeighting(weighting).setTurnCosts(false));
if (turnCosts)
profiles.add(new Profile("profile_tc").setVehicle(vehicle).setWeighting(weighting).setTurnCosts(true).putHint(U_TURN_COSTS, uTurnCosts));
}
ghConfig.setProfiles(profiles);
List<CHProfile> chProfiles = new ArrayList<>();
if (useCHNode)
chProfiles.add(new CHProfile("profile_no_tc"));
if (useCHEdge)
chProfiles.add(new CHProfile("profile_tc"));
ghConfig.setCHProfiles(chProfiles);
List<LMProfile> lmProfiles = new ArrayList<>();
if (useLM) {
lmProfiles.add(new LMProfile("profile_no_tc"));
if (turnCosts)
// no need for a second LM preparation, we can do cross queries here
lmProfiles.add(new LMProfile("profile_tc").setPreparationProfile("profile_no_tc"));
}
ghConfig.setLMProfiles(lmProfiles);
return ghConfig;
}
use of com.graphhopper.routing.weighting.custom.CustomProfile in project graphhopper by graphhopper.
the class DefaultWeightingFactory method createWeighting.
@Override
public Weighting createWeighting(Profile profile, PMap requestHints, boolean disableTurnCosts) {
// Merge profile hints with request hints, the request hints take precedence.
// Note that so far we do not check if overwriting the profile hints actually works with the preparation
// for LM/CH. Later we should also limit the number of parameters that can be used to modify the profile.
// todo: since we are not dealing with block_area here yet we cannot really apply any merging rules
// for it, see discussion here: https://github.com/graphhopper/graphhopper/pull/1958#discussion_r395462901
PMap hints = new PMap();
hints.putAll(profile.getHints());
hints.putAll(requestHints);
FlagEncoder encoder = encodingManager.getEncoder(profile.getVehicle());
TurnCostProvider turnCostProvider;
if (profile.isTurnCosts() && !disableTurnCosts) {
if (!encoder.supportsTurnCosts())
throw new IllegalArgumentException("Encoder " + encoder + " does not support turn costs");
int uTurnCosts = hints.getInt(Parameters.Routing.U_TURN_COSTS, INFINITE_U_TURN_COSTS);
turnCostProvider = new DefaultTurnCostProvider(encoder, ghStorage.getTurnCostStorage(), uTurnCosts);
} else {
turnCostProvider = NO_TURN_COST_PROVIDER;
}
String weightingStr = toLowerCase(profile.getWeighting());
if (weightingStr.isEmpty())
throw new IllegalArgumentException("You have to specify a weighting");
Weighting weighting = null;
if (CustomWeighting.NAME.equalsIgnoreCase(weightingStr)) {
if (!(profile instanceof CustomProfile))
throw new IllegalArgumentException("custom weighting requires a CustomProfile but was profile=" + profile.getName());
CustomModel queryCustomModel = requestHints.getObject(CustomModel.KEY, null);
CustomProfile customProfile = (CustomProfile) profile;
if (queryCustomModel != null)
queryCustomModel.checkLMConstraints(customProfile.getCustomModel());
queryCustomModel = CustomModel.merge(customProfile.getCustomModel(), queryCustomModel);
weighting = CustomModelParser.createWeighting(encoder, encodingManager, turnCostProvider, queryCustomModel);
} else if ("shortest".equalsIgnoreCase(weightingStr)) {
weighting = new ShortestWeighting(encoder, turnCostProvider);
} else if ("fastest".equalsIgnoreCase(weightingStr)) {
if (encoder.supports(PriorityWeighting.class))
weighting = new PriorityWeighting(encoder, hints, turnCostProvider);
else
weighting = new FastestWeighting(encoder, hints, turnCostProvider);
} else if ("curvature".equalsIgnoreCase(weightingStr)) {
if (encoder.supports(CurvatureWeighting.class))
weighting = new CurvatureWeighting(encoder, hints, turnCostProvider);
} else if ("short_fastest".equalsIgnoreCase(weightingStr)) {
weighting = new ShortFastestWeighting(encoder, hints, turnCostProvider);
}
if (weighting == null)
throw new IllegalArgumentException("Weighting '" + weightingStr + "' not supported");
return weighting;
}
use of com.graphhopper.routing.weighting.custom.CustomProfile in project graphhopper by graphhopper.
the class RoutingExample method customizableRouting.
public static void customizableRouting(String ghLoc) {
GraphHopper hopper = new GraphHopper();
hopper.setOSMFile(ghLoc);
hopper.setGraphHopperLocation("target/routing-custom-graph-cache");
hopper.setProfiles(new CustomProfile("car_custom").setCustomModel(new CustomModel()).setVehicle("car"));
// The hybrid mode uses the "landmark algorithm" and is up to 15x faster than the flexible mode (Dijkstra).
// Still it is slower than the speed mode ("contraction hierarchies algorithm") ...
hopper.getLMPreparationHandler().setLMProfiles(new LMProfile("car_custom"));
hopper.importOrLoad();
// ... but for the hybrid mode we can customize the route calculation even at request time:
// 1. a request with default preferences
GHRequest req = new GHRequest().setProfile("car_custom").addPoint(new GHPoint(42.506472, 1.522475)).addPoint(new GHPoint(42.513108, 1.536005));
GHResponse res = hopper.route(req);
if (res.hasErrors())
throw new RuntimeException(res.getErrors().toString());
assert Math.round(res.getBest().getTime() / 1000d) == 96;
// 2. now avoid primary roads and reduce maximum speed, see docs/core/custom-models.md for an in-depth explanation
// and also the blog posts https://www.graphhopper.com/?s=customizable+routing
CustomModel model = new CustomModel();
model.addToPriority(If("road_class == PRIMARY", MULTIPLY, 0.5));
// unconditional limit to 100km/h
model.addToPriority(If("true", LIMIT, 100));
req.setCustomModel(model);
res = hopper.route(req);
if (res.hasErrors())
throw new RuntimeException(res.getErrors().toString());
assert Math.round(res.getBest().getTime() / 1000d) == 165;
}
Aggregations