use of com.graphhopper.config.Profile in project graphhopper by graphhopper.
the class GraphHopper method loadOrPrepareLM.
/**
* For landmarks it is required to always call this method: either it creates the landmark data or it loads it.
*/
protected void loadOrPrepareLM(boolean closeEarly) {
for (LMProfile profile : lmPreparationHandler.getLMProfiles()) if (!getLMProfileVersion(profile.getProfile()).isEmpty() && !getLMProfileVersion(profile.getProfile()).equals("" + profilesByName.get(profile.getProfile()).getVersion()))
throw new IllegalArgumentException("LM preparation of " + profile.getProfile() + " already exists in storage and doesn't match configuration");
// we load landmark storages that already exist and prepare the other ones
List<LMConfig> lmConfigs = createLMConfigs(lmPreparationHandler.getLMProfiles());
List<LandmarkStorage> loaded = lmPreparationHandler.load(lmConfigs, ghStorage);
List<LMConfig> loadedConfigs = loaded.stream().map(LandmarkStorage::getLMConfig).collect(Collectors.toList());
List<LMConfig> configsToPrepare = lmConfigs.stream().filter(c -> !loadedConfigs.contains(c)).collect(Collectors.toList());
List<PrepareLandmarks> prepared = prepareLM(closeEarly, configsToPrepare);
// we map all profile names for which there is LM support to the according LM storages
landmarks = new LinkedHashMap<>();
for (LMProfile lmp : lmPreparationHandler.getLMProfiles()) {
// cross-querying
String prepProfile = lmp.usesOtherPreparation() ? lmp.getPreparationProfile() : lmp.getProfile();
Optional<LandmarkStorage> loadedLMS = loaded.stream().filter(lms -> lms.getLMConfig().getName().equals(prepProfile)).findFirst();
Optional<PrepareLandmarks> preparedLMS = prepared.stream().filter(pl -> pl.getLandmarkStorage().getLMConfig().getName().equals(prepProfile)).findFirst();
if (loadedLMS.isPresent() && preparedLMS.isPresent())
throw new IllegalStateException("LM should be either loaded or prepared, but not both: " + prepProfile);
else if (preparedLMS.isPresent()) {
setLMProfileVersion(lmp.getProfile(), profilesByName.get(lmp.getProfile()).getVersion());
landmarks.put(lmp.getProfile(), preparedLMS.get().getLandmarkStorage());
} else
loadedLMS.ifPresent(landmarkStorage -> landmarks.put(lmp.getProfile(), landmarkStorage));
}
}
use of com.graphhopper.config.Profile in project graphhopper by graphhopper.
the class GraphHopper method loadOrPrepareCH.
protected void loadOrPrepareCH(boolean closeEarly) {
for (CHProfile profile : chPreparationHandler.getCHProfiles()) if (!getCHProfileVersion(profile.getProfile()).isEmpty() && !getCHProfileVersion(profile.getProfile()).equals("" + profilesByName.get(profile.getProfile()).getVersion()))
throw new IllegalArgumentException("CH preparation of " + profile.getProfile() + " already exists in storage and doesn't match configuration");
// we load ch graphs that already exist and prepare the other ones
List<CHConfig> chConfigs = createCHConfigs(chPreparationHandler.getCHProfiles());
Map<String, RoutingCHGraph> loaded = chPreparationHandler.load(ghStorage, chConfigs);
List<CHConfig> configsToPrepare = chConfigs.stream().filter(c -> !loaded.containsKey(c.getName())).collect(Collectors.toList());
Map<String, PrepareContractionHierarchies.Result> prepared = prepareCH(closeEarly, configsToPrepare);
// we map all profile names for which there is CH support to the according CH graphs
chGraphs = new LinkedHashMap<>();
for (CHProfile profile : chPreparationHandler.getCHProfiles()) {
if (loaded.containsKey(profile.getProfile()) && prepared.containsKey(profile.getProfile()))
throw new IllegalStateException("CH graph should be either loaded or prepared, but not both: " + profile.getProfile());
else if (prepared.containsKey(profile.getProfile())) {
setCHProfileVersion(profile.getProfile(), profilesByName.get(profile.getProfile()).getVersion());
PrepareContractionHierarchies.Result res = prepared.get(profile.getProfile());
chGraphs.put(profile.getProfile(), ghStorage.createCHGraph(res.getCHStorage(), res.getCHConfig()));
} else if (loaded.containsKey(profile.getProfile())) {
chGraphs.put(profile.getProfile(), loaded.get(profile.getProfile()));
} else
throw new IllegalStateException("CH graph should be either loaded or prepared: " + profile.getProfile());
}
}
use of com.graphhopper.config.Profile in project graphhopper by graphhopper.
the class GraphHopper method buildEncodingManager.
private EncodingManager buildEncodingManager(GraphHopperConfig ghConfig) {
if (profilesByName.isEmpty())
throw new IllegalStateException("no profiles exist but assumed to create EncodingManager. E.g. provide them in GraphHopperConfig when calling GraphHopper.init");
String flagEncodersStr = ghConfig.getString("graph.flag_encoders", "");
Map<String, String> flagEncoderMap = new LinkedHashMap<>();
for (String encoderStr : flagEncodersStr.split(",")) {
String key = encoderStr.split("\\|")[0];
if (!key.isEmpty()) {
if (flagEncoderMap.containsKey(key))
throw new IllegalArgumentException("FlagEncoder " + key + " needs to be unique");
flagEncoderMap.put(key, encoderStr);
}
}
Map<String, String> implicitFlagEncoderMap = new HashMap<>();
for (Profile profile : profilesByName.values()) {
emBuilder.add(Subnetwork.create(profile.getName()));
if (!flagEncoderMap.containsKey(profile.getVehicle()) && // overwrite key in implicit map if turn cost support required
(!implicitFlagEncoderMap.containsKey(profile.getVehicle()) || profile.isTurnCosts()))
implicitFlagEncoderMap.put(profile.getVehicle(), profile.getVehicle() + (profile.isTurnCosts() ? "|turn_costs=true" : ""));
}
flagEncoderMap.putAll(implicitFlagEncoderMap);
flagEncoderMap.values().forEach(s -> emBuilder.addIfAbsent(flagEncoderFactory, s));
String encodedValueStr = ghConfig.getString("graph.encoded_values", "");
for (String tpStr : encodedValueStr.split(",")) {
if (!tpStr.isEmpty())
emBuilder.addIfAbsent(tagParserFactory, tpStr);
}
return emBuilder.build();
}
use of com.graphhopper.config.Profile in project graphhopper by graphhopper.
the class IsochroneResource method doGet.
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response doGet(@Context UriInfo uriInfo, @QueryParam("profile") String profileName, @QueryParam("buckets") @Range(min = 1, max = 20) @DefaultValue("1") IntParam nBuckets, @QueryParam("reverse_flow") @DefaultValue("false") boolean reverseFlow, @QueryParam("point") @NotNull GHPointParam point, @QueryParam("time_limit") @DefaultValue("600") LongParam timeLimitInSeconds, @QueryParam("distance_limit") @DefaultValue("-1") LongParam distanceLimitInMeter, @QueryParam("weight_limit") @DefaultValue("-1") LongParam weightLimit, @QueryParam("type") @DefaultValue("json") ResponseType respType, @QueryParam("tolerance") @DefaultValue("0") double toleranceInMeter, @QueryParam("full_geometry") @DefaultValue("false") boolean fullGeometry) {
StopWatch sw = new StopWatch().start();
PMap hintsMap = new PMap();
RouteResource.initHints(hintsMap, uriInfo.getQueryParameters());
hintsMap.putObject(Parameters.CH.DISABLE, true);
hintsMap.putObject(Parameters.Landmark.DISABLE, true);
if (Helper.isEmpty(profileName)) {
profileName = profileResolver.resolveProfile(hintsMap).getName();
removeLegacyParameters(hintsMap);
}
errorIfLegacyParameters(hintsMap);
Profile profile = graphHopper.getProfile(profileName);
if (profile == null)
throw new IllegalArgumentException("The requested profile '" + profileName + "' does not exist");
LocationIndex locationIndex = graphHopper.getLocationIndex();
Graph graph = graphHopper.getGraphHopperStorage();
Weighting weighting = graphHopper.createWeighting(profile, hintsMap);
BooleanEncodedValue inSubnetworkEnc = graphHopper.getEncodingManager().getBooleanEncodedValue(Subnetwork.key(profileName));
if (hintsMap.has(Parameters.Routing.BLOCK_AREA)) {
GraphEdgeIdFinder.BlockArea blockArea = GraphEdgeIdFinder.createBlockArea(graph, locationIndex, Collections.singletonList(point.get()), hintsMap, new FiniteWeightFilter(weighting));
weighting = new BlockAreaWeighting(weighting, blockArea);
}
Snap snap = locationIndex.findClosest(point.get().lat, point.get().lon, new DefaultSnapFilter(weighting, inSubnetworkEnc));
if (!snap.isValid())
throw new IllegalArgumentException("Point not found:" + point);
QueryGraph queryGraph = QueryGraph.create(graph, snap);
TraversalMode traversalMode = profile.isTurnCosts() ? EDGE_BASED : NODE_BASED;
ShortestPathTree shortestPathTree = new ShortestPathTree(queryGraph, queryGraph.wrapWeighting(weighting), reverseFlow, traversalMode);
double limit;
if (weightLimit.get() > 0) {
limit = weightLimit.get();
shortestPathTree.setWeightLimit(limit + Math.max(limit * 0.14, 2_000));
} else if (distanceLimitInMeter.get() > 0) {
limit = distanceLimitInMeter.get();
shortestPathTree.setDistanceLimit(limit + Math.max(limit * 0.14, 2_000));
} else {
limit = timeLimitInSeconds.get() * 1000;
shortestPathTree.setTimeLimit(limit + Math.max(limit * 0.14, 200_000));
}
ArrayList<Double> zs = new ArrayList<>();
double delta = limit / nBuckets.get();
for (int i = 0; i < nBuckets.get(); i++) {
zs.add((i + 1) * delta);
}
ToDoubleFunction<ShortestPathTree.IsoLabel> fz;
if (weightLimit.get() > 0) {
fz = l -> l.weight;
} else if (distanceLimitInMeter.get() > 0) {
fz = l -> l.distance;
} else {
fz = l -> l.time;
}
Triangulator.Result result = triangulator.triangulate(snap, queryGraph, shortestPathTree, fz, degreesFromMeters(toleranceInMeter));
ContourBuilder contourBuilder = new ContourBuilder(result.triangulation);
ArrayList<Geometry> isochrones = new ArrayList<>();
for (Double z : zs) {
logger.info("Building contour z={}", z);
MultiPolygon isochrone = contourBuilder.computeIsoline(z, result.seedEdges);
if (fullGeometry) {
isochrones.add(isochrone);
} else {
Polygon maxPolygon = heuristicallyFindMainConnectedComponent(isochrone, isochrone.getFactory().createPoint(new Coordinate(point.get().lon, point.get().lat)));
isochrones.add(isochrone.getFactory().createPolygon(((LinearRing) maxPolygon.getExteriorRing())));
}
}
ArrayList<JsonFeature> features = new ArrayList<>();
for (Geometry isochrone : isochrones) {
JsonFeature feature = new JsonFeature();
HashMap<String, Object> properties = new HashMap<>();
properties.put("bucket", features.size());
if (respType == geojson) {
properties.put("copyrights", ResponsePathSerializer.COPYRIGHTS);
}
feature.setProperties(properties);
feature.setGeometry(isochrone);
features.add(feature);
}
ObjectNode json = JsonNodeFactory.instance.objectNode();
sw.stop();
ObjectNode finalJson = null;
if (respType == geojson) {
json.put("type", "FeatureCollection");
json.putPOJO("features", features);
finalJson = json;
} else {
json.putPOJO("polygons", features);
final ObjectNode info = json.putObject("info");
info.putPOJO("copyrights", ResponsePathSerializer.COPYRIGHTS);
info.put("took", Math.round((float) sw.getMillis()));
finalJson = json;
}
logger.info("took: " + sw.getSeconds() + ", visited nodes:" + shortestPathTree.getVisitedNodes());
return Response.ok(finalJson).header("X-GH-Took", "" + sw.getSeconds() * 1000).build();
}
use of com.graphhopper.config.Profile 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;
}
Aggregations