Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weighting support via yaml configuration #1841

Merged
merged 202 commits into from
May 1, 2020
Merged
Show file tree
Hide file tree
Changes from 188 commits
Commits
Show all changes
202 commits
Select commit Hold shift + click to select a range
919f38c
initial version with a basic Weighting support via yaml configuration
karussell Dec 30, 2019
63638b0
implement DelayFlexConfig
karussell Dec 30, 2019
40c2bbe
use flex model for CH preparation - yeah. Now questions like #1708 arise
karussell Jan 1, 2020
9589d63
reverse priority is logical
karussell Jan 2, 2020
aa6f23e
add more tests regarding common use cases like max_height and avoid t…
karussell Jan 2, 2020
674de1a
avoid special case of config after graphhopper.init
karussell Jan 2, 2020
1aa1e51
merge FlexResource into RouteResource
karussell Jan 2, 2020
93fe39b
avoid additional test classes
karussell Jan 3, 2020
f0e9723
Merge branch 'master' into issue_1776
karussell Jan 3, 2020
f63d3ca
add minor java docs
karussell Jan 4, 2020
1fd862e
Merge branch 'master' into issue_1776
karussell Jan 6, 2020
5624342
Merge branch 'master' into issue_1776
karussell Jan 6, 2020
6cb6eb2
minor fixes
karussell Jan 8, 2020
48c0561
added initial UI
karussell Jan 9, 2020
47b0938
replace min with max priority for proper A* heuristic. Range check al…
karussell Jan 9, 2020
07ce143
throw exception if encoded values like max_height does not exists
karussell Jan 9, 2020
c597c64
added todo to PR
karussell Jan 9, 2020
56d4a79
improve warning
karussell Jan 9, 2020
247cf2d
avoid calling edge.getDistance in weight twice -> we need this for al…
karussell Jan 9, 2020
4fc14bd
Merge branch 'master' into issue_1776
easbar Jan 15, 2020
1771bf8
Merge branch 'master' into issue_1776
easbar Jan 16, 2020
f54c726
Merge branch 'master' into issue_1776
easbar Jan 16, 2020
5c65d8b
Remove unused import
easbar Jan 16, 2020
f9f5ec9
Add EnumToValue#toString
easbar Jan 17, 2020
d68c04b
Merge branch 'master' into issue_1776
easbar Jan 18, 2020
1a8a4e9
rename FlexModelWeighting to CustomWeighting etc to avoid confusion w…
karussell Jan 19, 2020
577ca13
minor doc in config-example.yml
karussell Jan 19, 2020
f6ae26c
merged master
karussell Jan 19, 2020
14caa36
ensure that we currently just ignore URL parameters for POST /route r…
karussell Jan 19, 2020
2e4242e
merged master
karussell Jan 23, 2020
21e70fe
better description and examples
karussell Jan 25, 2020
253b9df
remove DelayCustomConfig for now as virtual edges would artifically d…
karussell Jan 25, 2020
1b0d20f
reduce default max prio should increase speed; introduce max speed an…
karussell Jan 26, 2020
223d9d1
properly pick max priority
karussell Jan 26, 2020
46a9f03
set default distance_factor to same like in ShortFastestWeighting ins…
karussell Jan 26, 2020
a9f8c1e
remove delay from CustomWeighting description
karussell Jan 27, 2020
1e440cb
change naming custom_models -> custom_profiles #493
karussell Jan 27, 2020
c9f7c56
fix tests
karussell Jan 27, 2020
a894593
merged master
karussell Jan 29, 2020
2fe3ad4
for now reduce time for routingLM8_custom
karussell Jan 29, 2020
f071db2
replaced the often not well working average_speed with max_speed map …
karussell Feb 1, 2020
75adc4e
merged master
karussell Feb 1, 2020
c6e207f
fix refactoring
karussell Feb 2, 2020
ca2dece
normalize priority and speed_factor so it always can be used for LM e…
karussell Feb 4, 2020
fd16781
merged master
karussell Feb 4, 2020
454fd70
apply max_speed after speed_factor; change order and document this in…
karussell Feb 4, 2020
9d8cfbe
merged master
karussell Feb 4, 2020
757bb8a
finally made custom models working with LM, also in Measurement
karussell Feb 5, 2020
8b329df
move custom again to separate /custom endpoint; also move 'model' to …
karussell Feb 8, 2020
28188c5
introduce speed_factor map
karussell Feb 8, 2020
80f966b
merged master
karussell Feb 8, 2020
f6b321d
make distance_factor map similar to the other factor maps (i.e. a hig…
karussell Feb 8, 2020
7fda98a
add missing distance factor in weight formula
karussell Feb 11, 2020
1db93e5
sum instead product for distance_term
karussell Feb 11, 2020
31cfa05
remove distance term for now (can be added later)
karussell Feb 11, 2020
6551385
fix flex UI to new /custom endpoint and level up the model
karussell Feb 11, 2020
339fad7
config-example.yml: usage of camel case is required due to https://gi…
karussell Feb 11, 2020
20ef817
enable usage of BooleanEncodedValue
karussell Feb 11, 2020
2fe47d7
implement avoid area
karussell Feb 12, 2020
a346a8a
avoid using block_area property for /custom endpoint
karussell Feb 12, 2020
dfba6a7
avoid subclassing and reusing CustomWeighting stuff
karussell Feb 13, 2020
3672378
demo: load yml from URL
karussell Feb 13, 2020
298d4f0
refactoring
karussell Feb 13, 2020
27e94aa
merged master
karussell Feb 13, 2020
2f2567b
avoid global snake case due to config.yml backward compatibility
karussell Feb 13, 2020
d622462
avoid problem due to recently more strict LM fallback and use our tes…
karussell Feb 13, 2020
bfb1d6a
normalizing the speed_factor makes no sense. Just use 1 as maximum.
karussell Feb 13, 2020
e57ca9d
AbstractFlagEncoder: removed newly introduced but unnecessary name pa…
karussell Feb 18, 2020
157e4f8
merged master
karussell Feb 18, 2020
dae2540
fix typo
karussell Feb 19, 2020
237f1b8
Merge branch 'master' into issue_1776
karussell Feb 21, 2020
a58e5d7
merged master
karussell Feb 21, 2020
59f6a14
changed formula and make distance_constant_term independent of priority
karussell Feb 24, 2020
50e78af
rename distance_term_constant to shorter distance_influence
karussell Feb 25, 2020
e7d507e
change unit of distance_influence to sec/km
karussell Feb 25, 2020
aa47605
merged master
karussell Feb 26, 2020
51e2dea
removed 'name' parameter from AbstractWeighting; introduced GHRequest…
karussell Feb 26, 2020
6d0a55c
merged master
karussell Mar 3, 2020
ee4a5e9
merged master
karussell Mar 4, 2020
38d1bf6
merged master
karussell Mar 6, 2020
f42e4fa
move CustomModel into ProfileConfig and auto-create profiles per Cust…
karussell Mar 7, 2020
83b6e3d
CustomModel is tightly coupled to ProfileConfig but should not be par…
karussell Mar 8, 2020
37c40f6
Merge branch 'master' into issue_1776
karussell Mar 8, 2020
943fac5
make GeoToValue more efficient; introduces quite a bit complexity
karussell Mar 10, 2020
2398a08
fix test
karussell Mar 10, 2020
6553e33
merged master, made area things much easier
karussell Mar 10, 2020
f1434b1
clean up, move TODO NOWs to later
karussell Mar 10, 2020
2dd2ad3
renamed ConfigMapEntry to EdgeToValueEntry
karussell Mar 11, 2020
515ac41
do kind of autocompletion and more documentation
karussell Mar 12, 2020
2aab9b3
merged master
karussell Mar 12, 2020
3fe90a2
help with root entries too
karussell Mar 12, 2020
5170770
make custom model usage more explicit (force profile creation) and li…
karussell Mar 13, 2020
8d10fdd
make things even more clear and introduce CustomProfileConfig to remo…
karussell Mar 13, 2020
0fa5a0d
fixed Measurement
karussell Mar 13, 2020
875ccf3
merged master
karussell Mar 13, 2020
1848008
test fix
karussell Mar 13, 2020
175b9a6
fix Measurement
karussell Mar 13, 2020
e1854dc
minor comment change
karussell Mar 14, 2020
bc934dd
Merge branch 'master' into issue_1776
karussell Mar 18, 2020
bae3fb9
merged master
karussell Mar 18, 2020
0562bcd
no need for CustomProfileConfig.customModel instead store in hints
karussell Mar 18, 2020
e5d961a
merged master
karussell Mar 30, 2020
cff8fa8
minor test fixes
karussell Mar 30, 2020
b289d3f
fix measurement
karussell Mar 30, 2020
ec76054
add preparation for truck and do timing for custom profile separate
karussell Mar 30, 2020
ad5b95e
introduce custom light to better compare speed and preparation time t…
karussell Mar 30, 2020
65f3fed
minor fix
karussell Mar 31, 2020
6c02d0a
make 'pure' custommodel with car faster
karussell Apr 1, 2020
a175abc
merged master
karussell Apr 1, 2020
2877e5e
add CH profile for custom weighting
karussell Apr 1, 2020
bef6632
try to make CustomWeighting identical to FastestWeighting
karussell Apr 1, 2020
a0c598e
make CustomModel.merge compatible or throw illegalarg
karussell Apr 1, 2020
af182ed
revert change in FastestWeighting
karussell Apr 1, 2020
aeff09c
fix hints usage
karussell Apr 2, 2020
402b3b2
Try to make curl error visible
easbar Apr 2, 2020
7d9ec58
fix bug: decouple queryCustomModel from merge too
karussell Apr 2, 2020
2aef61a
Try to print error response *and* fail the build
easbar Apr 3, 2020
1bcec45
fix again: fastest weighting has no default distance influence
karussell Apr 3, 2020
42ab0fc
measurement: allow multiple CH profile preps
karussell Apr 6, 2020
8b3a449
merged master
karussell Apr 17, 2020
7d15e45
no need to change ProfileResolver anymore
karussell Apr 17, 2020
115b337
truck profile should use distance influence as we have now car fastes…
karussell Apr 17, 2020
c07b888
Merge branch 'master' into issue_1776
karussell Apr 17, 2020
e8b0871
Merge branch 'master' into issue_1776
karussell Apr 17, 2020
b3ca9fb
fixed something that we cannot really test as parsing the config is r…
karussell Apr 17, 2020
3585d6b
fixed config-example.yml, related to #1987
karussell Apr 17, 2020
cb405c5
increase Xmx a bit due to DW 2.0.x seems to need 10MB more
karussell Apr 17, 2020
38b251c
Merge branch 'master' into issue_1776
easbar Apr 18, 2020
5caa3cd
Replace DropwizardAppRule
easbar Apr 18, 2020
7a95654
Fix import
easbar Apr 18, 2020
a9f37e6
Merge branch 'master' into issue_1776
easbar Apr 18, 2020
a62839b
Minor clean up
easbar Apr 18, 2020
71c6876
Merge branch 'master' into issue_1776
easbar Apr 18, 2020
dd778a8
revert changes in ProfileResolver
karussell Apr 18, 2020
7ba6396
Minor
easbar Apr 19, 2020
e85ef62
Merge branch 'master' into issue_1776
easbar Apr 20, 2020
fd300fd
Merge branch 'master' into issue_1776
easbar Apr 20, 2020
3bb51a9
Improve (hopefully) javadocs of EdgeToValueEntry
easbar Apr 20, 2020
679a798
Remove EncodedValueFactory#findValues
easbar Apr 20, 2020
5c7146a
Remove ugly ClassCastException catching
easbar Apr 20, 2020
29d0fbc
Minor rename
easbar Apr 20, 2020
112e86c
Merge branch 'master' into issue_1776
easbar Apr 20, 2020
af3d674
Remove gpx stuff from custom route endpoint
easbar Apr 20, 2020
977ff2b
better exception if boolean is not specified correctly
karussell Apr 20, 2020
25a49a5
Fix misleading javadocs, minor readability fix
easbar Apr 21, 2020
4e04cbb
no negative values will happen, makes it easier to understand intend
karussell Apr 21, 2020
a4ff4e7
hide CustomWeighting-specific helper methods
karussell Apr 21, 2020
f4b5c83
Setup measurements for custom profiles
easbar Apr 21, 2020
0fed492
Merge branch 'master' into issue_1776
easbar Apr 21, 2020
7a7f53c
Measurement failed, add debug output and try again
easbar Apr 22, 2020
775a119
Fix benchmark
easbar Apr 22, 2020
253bb52
Update/extend profiles.md
easbar Apr 22, 2020
87a91de
Some more profiles.md
easbar Apr 22, 2020
b8f01ab
Fix typo
easbar Apr 22, 2020
c512ef0
Continue with profiles.md
easbar Apr 22, 2020
841ec4f
More profiles.md: areas also for speed and allowed value ranges for s…
easbar Apr 23, 2020
b9ec45a
Fix typo
easbar Apr 23, 2020
f9c75f3
Fix explanation of distance_influence in the presence of priorities
easbar Apr 23, 2020
db38504
Fix measurement name
easbar Apr 23, 2020
fea0c74
Lets see how slow slow routing is
easbar Apr 23, 2020
94d95e8
Merge branch 'master' into issue_1776
easbar Apr 23, 2020
2970ba9
Rename Speed/PriorityCustomConfig to Speed/PriorityCalculator
easbar Apr 23, 2020
395a233
Enforce custom_model_file=empty for empty custom model
easbar Apr 22, 2020
73f20e6
Use AREA_PREFIX constant instead of key() function
easbar Apr 22, 2020
52b3ba7
add getAllShared to lookup
karussell Apr 23, 2020
cb16499
minor: avoid public constant. not sure if required
karussell Apr 23, 2020
0d894db
throw exception for geo and boolean too if too big speed
karussell Apr 23, 2020
33d1f6f
Merge branch 'master' into issue_1776
karussell Apr 23, 2020
71fa1a0
Keep slow routing, but for custom only use LM8 node-based
easbar Apr 23, 2020
ac271ea
a bit dirty fix regarding CustomModel usage via Java API
karussell Apr 23, 2020
8d82c58
Fix benchmark.sh
easbar Apr 24, 2020
a7d3fff
Move max_weight into priority and more refactorings (#2015)
karussell Apr 24, 2020
6241b61
Merge branch 'master' into issue_1776
easbar Apr 24, 2020
4c8d5ad
Update CustomWeighting java docs (even though it does not yet match t…
easbar Apr 24, 2020
49a8b36
Minor
easbar Apr 24, 2020
f60d304
Another fix for benchmark.sh...
easbar Apr 24, 2020
7c4136f
Fix model for measurement for new syntax
easbar Apr 25, 2020
a106107
... and another fix
easbar Apr 25, 2020
90870f8
... and another fix 2
easbar Apr 25, 2020
e548057
benchmark: include dijkstra on big map
easbar Apr 26, 2020
3231fd6
Merge branch 'master' into issue_1776
easbar Apr 28, 2020
6b5105b
Add a few tests for priority/speed calculator
easbar Apr 28, 2020
f173818
Update profiles.md
easbar Apr 28, 2020
c12100c
Some more cleanup, docs and testing
easbar Apr 29, 2020
9511a04
Remove todo
easbar Apr 29, 2020
cf96566
removed yaml endpoint and renamed to /route-custom
karussell Apr 29, 2020
db12bbd
accept JSON as custom profile on server side
karussell Apr 29, 2020
90e4898
Fix some of the remaining todos
easbar Apr 29, 2020
d9a54dc
Minor cleanup
easbar Apr 29, 2020
187897e
merge 'comparison keys' properly; added tests and docs for this
karussell Apr 29, 2020
b83df9e
Remove more todos
easbar Apr 29, 2020
1fc1152
Try removing local distance variable, is it slower?
easbar Apr 29, 2020
f6d9b2f
minor Xmx increase
karussell Apr 29, 2020
d6bf1dd
Minor fix in docs
easbar Apr 30, 2020
d20175a
Merge branch 'master' into issue_1776
easbar Apr 30, 2020
ebac0d4
Remove server side custom model inheritance from docs
easbar Apr 30, 2020
1d19ab0
revert changes in FlagEncoder constructor
karussell Apr 30, 2020
4b48883
add nice use case as test; add missing IntToValueEntry; remove furthe…
karussell Apr 30, 2020
79ab4e5
Trry storying distance in local variable is it faster?
easbar May 1, 2020
f662906
Re-enable all measurements, disable custom/astar measurements for now
easbar May 1, 2020
2bc997b
Add link to profiles.md
easbar May 1, 2020
1839b2a
Merge branch 'master' into issue_1776
easbar May 1, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
209 changes: 209 additions & 0 deletions api/src/main/java/com/graphhopper/routing/util/CustomModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
/*
* Licensed to GraphHopper GmbH under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*
* GraphHopper GmbH licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.graphhopper.routing.util;

import com.graphhopper.json.geo.JsonFeature;
import com.graphhopper.util.Parameters;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* This class is used in combination with CustomProfileConfig.
*/
public class CustomModel {

public static final String KEY = "custom_model";

static double DEFAULT_D_I = 70;
// optional:
private Double maxSpeedFallback;
private Double headingPenalty = Parameters.Routing.DEFAULT_HEADING_PENALTY;
// default value derived from the cost for time e.g. 25€/hour and for distance 0.5€/km, for trucks this is usually larger
private double distanceInfluence = DEFAULT_D_I;
private Map<String, Object> speedFactor = new HashMap<>();
private Map<String, Object> maxSpeed = new HashMap<>();
private Map<String, Object> priorityMap = new HashMap<>();
karussell marked this conversation as resolved.
Show resolved Hide resolved
private Map<String, JsonFeature> areas = new HashMap<>();

public CustomModel() {
}

public CustomModel(CustomModel toCopy) {
this.maxSpeedFallback = toCopy.maxSpeedFallback;
this.headingPenalty = toCopy.headingPenalty;
this.distanceInfluence = toCopy.distanceInfluence;

speedFactor = deepCopy(toCopy.getSpeedFactor());
maxSpeed = deepCopy(toCopy.getMaxSpeed());
priorityMap = deepCopy(toCopy.getPriority());

areas.putAll(toCopy.getAreas());
}

private <T> T deepCopy(T originalObject) {
if (originalObject instanceof List) {
List<Object> newList = new ArrayList<>(((List) originalObject).size());
for (Object item : (List) originalObject) {
newList.add(deepCopy(item));
}
return (T) newList;
} else if (originalObject instanceof Map) {
Map copy = new HashMap<>(((Map) originalObject).size());
for (Object o : ((Map) originalObject).entrySet()) {
Map.Entry entry = (Map.Entry) o;
copy.put(entry.getKey(), deepCopy(entry.getValue()));
}
return (T) copy;
} else {
return originalObject;
}
}

public Map<String, Object> getSpeedFactor() {
return speedFactor;
}

public Map<String, Object> getMaxSpeed() {
return maxSpeed;
}

public CustomModel setMaxSpeedFallback(Double maxSpeedFallback) {
this.maxSpeedFallback = maxSpeedFallback;
return this;
}

public Double getMaxSpeedFallback() {
return maxSpeedFallback;
}

public Map<String, Object> getPriority() {
return priorityMap;
}

public CustomModel setAreas(Map<String, JsonFeature> areas) {
this.areas = areas;
return this;
}

public Map<String, JsonFeature> getAreas() {
return areas;
}

public CustomModel setDistanceInfluence(double distanceFactor) {
this.distanceInfluence = distanceFactor;
return this;
}

public double getDistanceInfluence() {
return distanceInfluence;
}

public void setHeadingPenalty(double headingPenalty) {
this.headingPenalty = headingPenalty;
}

public double getHeadingPenalty() {
return headingPenalty;
}

@Override
public String toString() {
return "CustomModel{" +
"distanceInfluence=" + distanceInfluence +
", speedFactor=" + speedFactor +
", maxSpeed=" + maxSpeed +
", maxSpeedFallback=" + maxSpeedFallback +
", priorityMap=" + priorityMap +
", #areas=" + areas.size() +
'}';
}

/**
* This method assumes that this object is a per-request object so we can apply the changes and keep baseCustomModel
* unchanged.
*/
public static CustomModel merge(CustomModel baseModel, CustomModel queryModel) {
// avoid changing the specified CustomModel via deep copy otherwise query-CustomModel would be modified
CustomModel mergedCM = new CustomModel(baseModel);
if (queryModel.maxSpeedFallback != null) {
if (mergedCM.maxSpeedFallback != null && mergedCM.maxSpeedFallback > queryModel.maxSpeedFallback)
throw new IllegalArgumentException("CustomModel in query can only use max_speed_fallback bigger or equal to " + mergedCM.maxSpeedFallback);
mergedCM.maxSpeedFallback = queryModel.maxSpeedFallback;
}
if (Math.abs(queryModel.distanceInfluence - CustomModel.DEFAULT_D_I) > 0.01) {
if (mergedCM.distanceInfluence > queryModel.distanceInfluence)
throw new IllegalArgumentException("CustomModel in query can only use distance_influence bigger or equal to " + mergedCM.distanceInfluence);
mergedCM.distanceInfluence = queryModel.distanceInfluence;
}

// example
// max_speed: { road_class: { secondary : 0.4 } }
// or
// priority: { max_weight: { "<3.501": 0.7 } }
for (Map.Entry<String, Object> queryEntry : queryModel.getMaxSpeed().entrySet()) {
Object value = mergedCM.maxSpeed.get(queryEntry.getKey());
applyChange(mergedCM.maxSpeed, value, queryEntry);
}
for (Map.Entry<String, Object> queryEntry : queryModel.getSpeedFactor().entrySet()) {
Object value = mergedCM.speedFactor.get(queryEntry.getKey());
applyChange(mergedCM.speedFactor, value, queryEntry);
}
for (Map.Entry<String, Object> queryEntry : queryModel.getPriority().entrySet()) {
Object value = mergedCM.priorityMap.get(queryEntry.getKey());
applyChange(mergedCM.priorityMap, value, queryEntry);
}
for (Map.Entry<String, JsonFeature> entry : queryModel.getAreas().entrySet()) {
if (mergedCM.areas.containsKey(entry.getKey()))
throw new IllegalArgumentException("area " + entry.getKey() + " already exists");
mergedCM.areas.put(entry.getKey(), entry.getValue());
}

return mergedCM;
}

private static void applyChange(Map<String, Object> mergedSuperMap,
Object mergedObj, Map.Entry<String, Object> querySuperEntry) {
if (mergedObj == null) {
// no need for a "merge"
mergedSuperMap.put(querySuperEntry.getKey(), querySuperEntry.getValue());
return;
}
if (!(mergedObj instanceof Map))
throw new IllegalArgumentException("entry is not a map: " + mergedObj);
Object queryObj = querySuperEntry.getValue();
if (!(queryObj instanceof Map))
throw new IllegalArgumentException("query entry is not a map: " + queryObj);

// TODO NOW how to merge different ranges of DecimalEncodedValue => if range size is decreased => it is fine
Map<Object, Object> mergedMap = (Map) mergedObj;
Map<Object, Object> queryMap = (Map) queryObj;
for (Map.Entry queryEntry : queryMap.entrySet()) {
Object mergedValue = mergedMap.get(queryEntry.getKey());
if (mergedValue == null) {
mergedMap.put(queryEntry.getKey(), queryEntry.getValue());
} else if (queryEntry.getValue() instanceof Number && mergedValue instanceof Number) {
mergedMap.put(queryEntry.getKey(), ((Number) queryEntry.getValue()).doubleValue() * ((Number) mergedValue).doubleValue());
} else {
throw new IllegalArgumentException("Cannot merge value " + queryEntry.getValue() + " for key " + queryEntry.getKey() + ", merged value: " + mergedValue);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.graphhopper.routing.util;

import org.junit.jupiter.api.Test;

import java.util.HashMap;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.*;

public class CustomModelTest {

// TODO NOW
// @Test
// public void testMergeLimits() {
// CustomModel truck = new CustomModel().setVehicleWidth(3.);
// CustomModel car = new CustomModel().setVehicleWidth(2.);
// CustomModel bike = new CustomModel().setVehicleWeight(0.02);
//
// assertEquals(2, CustomModel.merge(bike, car).getVehicleWidth(), .1);
// assertNull(bike.getVehicleWidth());
// assertNull(car.getVehicleWeight());
//
// assertEquals(3, CustomModel.merge(car, truck).getVehicleWidth(), .1);
// try {
// CustomModel.merge(truck, car);
// fail("car is incompatible with truck as base");
// } catch (Exception ex) {
// }
// }

@Test
public void testMergeEmptyModel() {
CustomModel emptyCar = new CustomModel();
CustomModel car = new CustomModel();
car.getPriority().put("road_class", createMap("primary", 2.0, "tertiary", 1.2));
// empty entries means "extend base" profile, i.e. primary=1
Map map = (Map) CustomModel.merge(emptyCar, car).getPriority().get("road_class");
assertEquals(2.0, map.get("primary"));
assertEquals(1.2, map.get("tertiary"));

map = (Map) CustomModel.merge(car, emptyCar).getPriority().get("road_class");
assertEquals(2.0, map.get("primary"));
assertEquals(1.2, map.get("tertiary"));
}

@Test
public void testMergeMap() {
CustomModel truck = new CustomModel();
truck.getPriority().put("road_class", createMap("primary", 1.5, "secondary", 2.0));
CustomModel car = new CustomModel();
car.getPriority().put("road_class", createMap("primary", 2.0, "tertiary", 1.2));

Map map = (Map) CustomModel.merge(truck, car).getPriority().get("road_class");
assertEquals(1.5 * 2.0, map.get("primary"));
assertEquals(2.0, map.get("secondary"));
assertEquals(1.2, map.get("tertiary"));

// do not change argument of merge method
assertEquals(1.5, (Double) ((Map) truck.getPriority().get("road_class")).get("primary"), .1);

truck.getPriority().put("road_class", createMap("primary", "incompatible"));
try {
CustomModel.merge(car, truck);
fail("we cannot merge this");
} catch (Exception ex) {
}
}

Map createMap(Object... objects) {
Map map = new HashMap();
for (int i = 0; i < objects.length; i += 2) {
map.put(objects[i], objects[i + 1]);
}
return map;
}
}