Repository: graphhopper/graphhopper
Pull request #2249 (2021-03-08 11:38:15)

rename in_area_custom1 to in_custom1
rename to `in_` as it might be confusing when `area` is part of the area name. See e.g. https://github.com/graphhopper/graphhopper/pull/2201#discussion_r578242801


Patch:
diff --git a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java
index 0a59f591e..edbd21ac1 100644
--- a/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java
+++ b/core/src/main/java/com/graphhopper/routing/weighting/custom/CustomModelParser.java
@@ -44,7 +44,7 @@ import java.util.concurrent.atomic.AtomicLong;
 
 public class CustomModelParser {
     private static final AtomicLong longVal = new AtomicLong(1);
-    static final String IN_AREA_PREFIX = "in_area_";
+    static final String IN_AREA_PREFIX = "in_";
     private static final Set<String> allowedNames = new HashSet<>(Arrays.asList("edge", "Math"));
     private static final boolean JANINO_DEBUG = Boolean.getBoolean(Scanner.SYSTEM_PROPERTY_SOURCE_DEBUGGING_ENABLE);
     private static final String SCRIPT_FILE_DIR = System.getProperty(Scanner.SYSTEM_PROPERTY_SOURCE_DEBUGGING_DIR, "./src/main/java/com/graphhopper/routing/weighting/custom");
diff --git a/docs/core/profiles.md b/docs/core/profiles.md
index 901454dbb..aac22b4dd 100644
--- a/docs/core/profiles.md
+++ b/docs/core/profiles.md
@@ -328,13 +328,13 @@ to the `areas` section of in the custom model file. You can then use the name of
 the `if/else/else_if` statements we saw in the previous sections.
 
 In the following example we multiply the speed of all edges in an area called `custom1` with `0.7` and also limit it
-to `50km/h`. Note that each area's name needs to be prefixed with `in_area_`:
+to `50km/h`. Note that each area's name needs to be prefixed with `in_`:
 
 ```yaml
 speed:
-  - if: in_area_custom1
+  - if: in_custom1
     multiply_by: 0.7
-  - if: in_area_custom1
+  - if: in_custom1
     limit_to: 50
 
 areas:
@@ -410,7 +410,7 @@ same way:
 
 ```yaml
 priority:
-  - if: in_area_custom1
+  - if: in_custom1
     multiply_by: 0.7
 ```
 
@@ -419,7 +419,7 @@ in an area like this:
 
 ```yaml
 priority:
-  - if: road_class == MOTORWAY && in_area_custom1
+  - if: road_class == MOTORWAY && in_custom1
     multiply_by: 0.1
 ```
 
diff --git a/web-bundle/src/main/js/custom-model-editor/src/parse.js b/web-bundle/src/main/js/custom-model-editor/src/parse.js
index 2012d113f..4a178f920 100644
--- a/web-bundle/src/main/js/custom-model-editor/src/parse.js
+++ b/web-bundle/src/main/js/custom-model-editor/src/parse.js
@@ -41,7 +41,7 @@ function parse(expression, categories, areas) {
  *
  * expression -> comparison (logicOperator comparison)*
  * comparison -> enumCategory comparator value | numericCategory numericComparator number | boolean | booleanCategory |
- *               booleanCategory comparator boolean | 'in_area_' area | 'in_area_' area comparator boolean | value'(' expression ')'
+ *               booleanCategory comparator boolean | 'in_' area | 'in_' area comparator boolean | value'(' expression ')'
  * logicOperator -> '&&' | '||'
  * comparator -> '==' | '!='
  * numericComparator -> '>' | '<' | '>=' | '<=' | '==' | '!='
@@ -126,7 +126,7 @@ function parseComparison() {
     } else if (isInvalidAreaOperator()) {
         return parseInvalidAreaOperator();
     } else {
-        return error(`unexpected token '${_tokens[_idx]}'`, [_idx, _idx + 1], Object.keys(_categories).concat(_areas.map(a => 'in_area_' + a)).concat(['true', 'false']));
+        return error(`unexpected token '${_tokens[_idx]}'`, [_idx, _idx + 1], Object.keys(_categories).concat(_areas.map(a => 'in_' + a)).concat(['true', 'false']));
     }
 }
 
@@ -174,16 +174,16 @@ function parseBooleanComparison() {
 
 function parseArea() {
     const token = _tokens[_idx];
-    if (token.length < `in_area_`.length) {
-        console.error(`expected something like 'in_area_xyz', but got: '${token}'`);
+    if (token.length < `in_`.length) {
+        console.error(`expected something like 'in_xyz', but got: '${token}'`);
         return;
     }
-    const area = token.substring(`in_area_`.length)
+    const area = token.substring(`in_`.length)
     if (_areas.indexOf(area) < 0) {
-        return error(`unknown area: '${area}'`, [_idx, _idx + 1], _areas.map(a => 'in_area_' + a));
+        return error(`unknown area: '${area}'`, [_idx, _idx + 1], _areas.map(a => 'in_' + a));
     }
 
-    // rule: comparison -> 'in_area_' area
+    // rule: comparison -> 'in_' area
     if (_idx + 1 === _tokens.length) {
         _idx++;
         return valid();
@@ -191,7 +191,7 @@ function parseArea() {
         _idx++;
         return valid();
     }
-    // rule: comparison -> 'in_area_' area comparator boolean
+    // rule: comparison -> 'in_' area comparator boolean
     return parseTripleComparison(
         comparisonOperators,
         (category, operator, value) => isBoolean(value),
@@ -201,11 +201,11 @@ function parseArea() {
 
 function parseInvalidAreaOperator() {
     const token = _tokens[_idx];
-    if (token.substring(0, 8) === `in_area_`) {
+    if (token.substring(0, 3) === `in_`) {
         console.error(`${token} is a valid area operator and should have been detected earlier`);
         return;
     }
-    return error(`area names must be prefixed with 'in_area_'`, [_idx, _idx + 1], _areas.map(a => 'in_area_' + a));
+    return error(`area names must be prefixed with 'in_'`, [_idx, _idx + 1], _areas.map(a => 'in_' + a));
 }
 
 function parseTripleComparison(allowedComparators, isValid, getAllowedValues) {
@@ -272,13 +272,13 @@ function isBooleanLiteral() {
 
 function isArea() {
     const token = _tokens[_idx];
-    return typeof token === 'string' && token.substr(0, 8) === 'in_area_';
+    return typeof token === 'string' && token.substr(0, 3) === 'in_';
 }
 
 function isInvalidAreaOperator() {
     const token = _tokens[_idx];
-    // typing something like in_area might be a common error so we provide some support for it
-    return typeof token === 'string' && (token.substr(0, 3) === 'in_' || _areas.indexOf(token) >= 0);
+    // typing something like 'area12' might be a common error so we provide some support for it
+    return typeof token === 'string' && _areas.indexOf(token) >= 0;
 }
 
 function isCategory() {


Test patch:
diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java
index 8347e459f..7afab6a40 100644
--- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java
+++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomModelParserTest.java
@@ -224,8 +224,8 @@ class CustomModelParserTest {
                 new HashMap<>()));
         customModel.setAreas(areas);
 
-        customModel.addToSpeed(If("in_area_area_1", LIMIT, 100));
-        customModel.addToSpeed(If("!in_area_area_2", LIMIT, 25));
+        customModel.addToSpeed(If("in_area_1", LIMIT, 100));
+        customModel.addToSpeed(If("!in_area_2", LIMIT, 25));
         customModel.addToSpeed(Else(LIMIT, 15));
 
         // No exception is thrown during createWeightingParameters
@@ -236,9 +236,9 @@ class CustomModelParserTest {
         CustomModel customModel2 = new CustomModel();
         customModel2.setAreas(areas);
 
-        customModel2.addToSpeed(If("in_area_area_1", LIMIT, 100));
-        customModel2.addToSpeed(If("in_area_area_2", LIMIT, 25));
-        customModel2.addToSpeed(If("in_area_area_3", LIMIT, 150));
+        customModel2.addToSpeed(If("in_area_1", LIMIT, 100));
+        customModel2.addToSpeed(If("in_area_2", LIMIT, 25));
+        customModel2.addToSpeed(If("in_area_3", LIMIT, 150));
         customModel2.addToSpeed(Else(LIMIT, 15));
 
         assertThrows(IllegalArgumentException.class, () ->
diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java
index 5f4a9ea2f..3cd792509 100644
--- a/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java
+++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/CustomWeightingTest.java
@@ -219,7 +219,7 @@ class CustomWeightingTest {
 
         CustomModel vehicleModel = new CustomModel();
         vehicleModel.addToPriority(If("road_class == PRIMARY", MULTIPLY, 1.0));
-        vehicleModel.addToPriority(If("in_area_custom1", MULTIPLY, 0.5));
+        vehicleModel.addToPriority(If("in_custom1", MULTIPLY, 0.5));
 
         ObjectMapper om = new ObjectMapper().registerModule(new JtsModule());
         JsonFeature json = om.readValue("{ \"geometry\":{ \"type\": \"Polygon\", \"coordinates\": " +
diff --git a/core/src/test/java/com/graphhopper/routing/weighting/custom/ExpressionVisitorTest.java b/core/src/test/java/com/graphhopper/routing/weighting/custom/ExpressionVisitorTest.java
index 5fdeda7c5..0376f6269 100644
--- a/core/src/test/java/com/graphhopper/routing/weighting/custom/ExpressionVisitorTest.java
+++ b/core/src/test/java/com/graphhopper/routing/weighting/custom/ExpressionVisitorTest.java
@@ -72,8 +72,8 @@ public class ExpressionVisitorTest {
         assertEquals("toll == Toll.NO || road_class == RoadClass.NO", parseExpression("toll == NO || road_class == NO", validVariable, lookup).converted.toString());
 
         // convert in_area variable to function call:
-        assertEquals(CustomWeightingHelper.class.getSimpleName() + ".in(this.in_area_custom_1, edge)",
-                parseExpression("in_area_custom_1", validVariable, lookup).converted.toString());
+        assertEquals(CustomWeightingHelper.class.getSimpleName() + ".in(this.in_custom_1, edge)",
+                parseExpression("in_custom_1", validVariable, lookup).converted.toString());
 
         // no need to inject:
         assertNull(parseExpression("toll == Toll.NO", validVariable, lookup).converted);
diff --git a/web-bundle/src/main/js/custom-model-editor/src/complete.test.js b/web-bundle/src/main/js/custom-model-editor/src/complete.test.js
index db8922ef7..9b6421533 100644
--- a/web-bundle/src/main/js/custom-model-editor/src/complete.test.js
+++ b/web-bundle/src/main/js/custom-model-editor/src/complete.test.js
@@ -12,12 +12,12 @@ describe("complete", () => {
         test_complete('a == ', 5, ['a1a', 'a1b', 'a2a', 'a2b'], [5, 5]);
         test_complete('b == ', 5, ['b1', 'b2'], [5, 5]);
         test_complete('b ==       ', 5, ['b1', 'b2'], [5, 5]);
-        test_complete('', 12, ['a', 'b', 'c', 'in_area_pqr', 'in_area_xyz', 'true', 'false'], [12, 12]);
-        test_complete('  ', 12, ['a', 'b', 'c', 'in_area_pqr', 'in_area_xyz', 'true', 'false'], [12, 12]);
-        test_complete('\t\n', 12, ['a', 'b', 'c', 'in_area_pqr', 'in_area_xyz', 'true', 'false'], [12, 12]);
-        test_complete('    ', 0, ['a', 'b', 'c', 'in_area_pqr', 'in_area_xyz', 'true', 'false'], [0, 0]);
-        test_complete('    ', 1, ['a', 'b', 'c', 'in_area_pqr', 'in_area_xyz', 'true', 'false'], [1, 1]);
-        test_complete('    ', 2, ['a', 'b', 'c', 'in_area_pqr', 'in_area_xyz', 'true', 'false'], [2, 2]);
+        test_complete('', 12, ['a', 'b', 'c', 'in_pqr', 'in_xyz', 'true', 'false'], [12, 12]);
+        test_complete('  ', 12, ['a', 'b', 'c', 'in_pqr', 'in_xyz', 'true', 'false'], [12, 12]);
+        test_complete('\t\n', 12, ['a', 'b', 'c', 'in_pqr', 'in_xyz', 'true', 'false'], [12, 12]);
+        test_complete('    ', 0, ['a', 'b', 'c', 'in_pqr', 'in_xyz', 'true', 'false'], [0, 0]);
+        test_complete('    ', 1, ['a', 'b', 'c', 'in_pqr', 'in_xyz', 'true', 'false'], [1, 1]);
+        test_complete('    ', 2, ['a', 'b', 'c', 'in_pqr', 'in_xyz', 'true', 'false'], [2, 2]);
         test_complete('b == ', 4, ['b1', 'b2'], [4, 4]);
         test_complete('b ==', 4, ['b1', 'b2'], [4, 4]);
         test_complete('b ==', 9, ['b1', 'b2'], [9, 9]);
@@ -55,7 +55,7 @@ describe("complete", () => {
     });
 
     test("complete at token within expression", () => {
-        test_complete('a == a1a && b != b1', 0, ['a', 'b', 'c', 'in_area_pqr', 'in_area_xyz', 'true', 'false'], [0, 1]);
+        test_complete('a == a1a && b != b1', 0, ['a', 'b', 'c', 'in_pqr', 'in_xyz', 'true', 'false'], [0, 1]);
         test_complete('a == a1a && b != b2', 2, ['==', '!='], [2, 4]);
         test_complete('a == a1b && b == b1', 5, ['a1a', 'a1b', 'a2a', 'a2b'], [5, 8]);
         test_complete('a == a2a && b == b2', 6, ['a1a', 'a1b', 'a2a', 'a2b'], [5, 8]);
@@ -73,8 +73,8 @@ describe("complete", () => {
     });
 
     test("complete areas", () => {
-        test_complete('in_ && a == a1a', 2, ['in_area_pqr', 'in_area_xyz'], [0, 3]);
-        test_complete('in_area_x && a == a1a', 9, ['in_area_xyz'], [0, 9]);
+        test_complete('in_ && a == a1a', 2, ['in_pqr', 'in_xyz'], [0, 3]);
+        test_complete('in_x && a == a1a', 4, ['in_xyz'], [0, 4]);
     });
 
     test("complete update", () => {
diff --git a/web-bundle/src/main/js/custom-model-editor/src/parse.test.js b/web-bundle/src/main/js/custom-model-editor/src/parse.test.js
index 7bdabebc9..15afa60c3 100644
--- a/web-bundle/src/main/js/custom-model-editor/src/parse.test.js
+++ b/web-bundle/src/main/js/custom-model-editor/src/parse.test.js
@@ -9,7 +9,7 @@ const categories = {
     "bool2": {type: 'boolean'}
 }
 const areas = ["area1", "area2", "area3"];
-const allowedLefts = Object.keys(categories).concat(areas.map(a => 'in_area_' + a)).concat(['true', 'false']);
+const allowedLefts = Object.keys(categories).concat(areas.map(a => 'in_' + a)).concat(['true', 'false']);
 
 describe("parse", () => {
 
@@ -32,10 +32,10 @@ describe("parse", () => {
         test_parseTokens_valid(['(', 'a', '==', 'a1', ')']);
         test_parseTokens_valid(['(', 'a', '!=', 'a1', ')']);
         test_parseTokens_valid(['(', '(', 'a', '!=', 'a1', ')', ')']);
-        test_parseTokens_valid(['in_area_area1']);
-        test_parseTokens_valid(['(', 'in_area_area1', ')']);
-        test_parseTokens_valid(['in_area_area2', '==', 'true']);
-        test_parseTokens_valid(['(', 'in_area_area1', '!=', 'false', ')']);
+        test_parseTokens_valid(['in_area1']);
+        test_parseTokens_valid(['(', 'in_area1', ')']);
+        test_parseTokens_valid(['in_area2', '==', 'true']);
+        test_parseTokens_valid(['(', 'in_area1', '!=', 'false', ')']);
         test_parseTokens_valid(['true']);
         test_parseTokens_valid(['(', 'false', ')']);
         test_parseTokens_valid(['bool1']);
@@ -69,11 +69,10 @@ describe("parse", () => {
     });
 
     test("parse single comparison, invalid, area", () => {
-        test_parseTokens(['in_area_'], `unknown area: ''`, [0, 1], ['in_area_area1', 'in_area_area2', 'in_area_area3']);
-        test_parseTokens(['in_area_area404'], `unknown area: 'area404'`, [0, 1], ['in_area_area1', 'in_area_area2', 'in_area_area3']);
-        test_parseTokens(['in_area1'], `area names must be prefixed with 'in_area_'`, [0, 1], ['in_area_area1', 'in_area_area2', 'in_area_area3']);
-        test_parseTokens(['area2'], `area names must be prefixed with 'in_area_'`, [0, 1], ['in_area_area1', 'in_area_area2', 'in_area_area3']);
-        test_parseTokens(['in_area_area1', '<=', 'true'], `unexpected token '<='`, [1, 2], ['||', '&&']);
+        test_parseTokens(['in_'], `unknown area: ''`, [0, 1], ['in_area1', 'in_area2', 'in_area3']);
+        test_parseTokens(['in_area404'], `unknown area: 'area404'`, [0, 1], ['in_area1', 'in_area2', 'in_area3']);
+        test_parseTokens(['area2'], `area names must be prefixed with 'in_'`, [0, 1], ['in_area1', 'in_area2', 'in_area3']);
+        test_parseTokens(['in_area1', '<=', 'true'], `unexpected token '<='`, [1, 2], ['||', '&&']);
     });
 
     test("parse single comparison, invalid, numeric and boolean", () => {
@@ -88,9 +87,9 @@ describe("parse", () => {
         test_parseTokens_valid(['a', '==', 'a1', '&&', 'b', '==', 'b1']);
         test_parseTokens_valid(['a', '==', 'a1', '||', 'b', '==', 'b1', '&&', 'a', '!=', 'a2']);
         test_parseTokens_valid(['a', '==', 'a1', '||', '(', 'b', '==', 'b1', ')', '&&', 'a', '!=', 'a2']);
-        test_parseTokens_valid(['in_area_area3', '&&', 'a', '==', 'a1']);
-        test_parseTokens_valid(['b', '!=', 'b1', '||', 'in_area_area3']);
-        test_parseTokens_valid(['b', '!=', 'b1', '||', 'in_area_area2', '!=', 'true']);
+        test_parseTokens_valid(['in_area3', '&&', 'a', '==', 'a1']);
+        test_parseTokens_valid(['b', '!=', 'b1', '||', 'in_area3']);
+        test_parseTokens_valid(['b', '!=', 'b1', '||', 'in_area2', '!=', 'true']);
         test_parseTokens_valid(['bool1', '==', 'false', '&&', 'bool2', '||', 'bool1']);
     });
 
@@ -130,11 +129,11 @@ describe("parse", () => {
         test_parse_valid('( a==a1 ) || b != b1 && ( a==a2 ||\n b!=b1 && (a==a1 || b == b2)) && a == a1');
         test_parse_valid('num1 > 0.3 && bool1 != true || a == a2 && num2 > 0.5 || bool1 == false');
         test_parse_valid('num1>0.3 && num2<12 || num1>=0.5 && num2<=1.3');
-        test_parse_valid('num1>0.3 && in_area_area2 || num2<=1.3');
+        test_parse_valid('num1>0.3 && in_area2 || num2<=1.3');
         test_parse_valid('num1>0.3 && bool1');
-        test_parse_valid('a != a1 && (bool1 || (bool2 && in_area_area2))');
-        test_parse_valid('a != a1 && (bool1 != false || (in_area_area2 && bool2))');
-        test_parse_valid('a != a1 && (bool1 != false || ((in_area_area1 == false) && bool2))');
+        test_parse_valid('a != a1 && (bool1 || (bool2 && in_area2))');
+        test_parse_valid('a != a1 && (bool1 != false || (in_area2 && bool2))');
+        test_parse_valid('a != a1 && (bool1 != false || ((in_area1 == false) && bool2))');
     });
 
     test("parse, invalid", () => {
@@ -153,11 +152,11 @@ describe("parse", () => {
         test_parse(`a == a1 || bool2 == 'false'`, `invalid bool2: ''false''`, [20, 27], ['true', 'false']);
         test_parse(`b != b1 || num2 > 0.7 && bool1 != 'true'`, `invalid bool1: ''true''`, [34, 40], ['true', 'false']);
         test_parse('a == a2 && b <= b1', `invalid operator '<='`, [13, 15], ['==', '!=']);
-        test_parse('a == a1 || area1', `area names must be prefixed with 'in_area_'`, [11, 16], ['in_area_area1', 'in_area_area2', 'in_area_area3']);
+        test_parse('a == a1 || area1', `area names must be prefixed with 'in_'`, [11, 16], ['in_area1', 'in_area2', 'in_area3']);
         test_parse('a == a1 || area_1', `unexpected token 'area_1'`, [11, 17], allowedLefts);
         test_parse(' == bool1', `unexpected token '=='`, [1, 3], allowedLefts);
         test_parse('bool1 != a2', `invalid bool1: 'a2'`, [9, 11], ['true', 'false']);
-        test_parse('in_area_area1 == tru || a == a1', `invalid in_area_area1: 'tru'`, [17, 20], ['true', 'false']);
+        test_parse('in_area1 == tru || a == a1', `invalid in_area1: 'tru'`, [12, 15], ['true', 'false']);
     });
 
     function test_parse_valid(expression) {
diff --git a/web/src/test/java/com/graphhopper/http/resources/CustomWeightingRouteResourceTest.java b/web/src/test/java/com/graphhopper/http/resources/CustomWeightingRouteResourceTest.java
index 4414c0b6e..673f22d34 100644
--- a/web/src/test/java/com/graphhopper/http/resources/CustomWeightingRouteResourceTest.java
+++ b/web/src/test/java/com/graphhopper/http/resources/CustomWeightingRouteResourceTest.java
@@ -102,7 +102,7 @@ public class CustomWeightingRouteResourceTest {
         yamlQuery += "" +
                 "priority:\n" +
                 // a faster road (see #2021)? or maybe do both?
-                "  - if: in_area_custom1\n" +
+                "  - if: in_custom1\n" +
                 "    multiply_by: " + priority + "\n" +
                 "areas:\n" +
                 "  custom1:\n" +
diff --git a/web/src/test/resources/com/graphhopper/http/resources/truck.yml b/web/src/test/resources/com/graphhopper/http/resources/truck.yml
index fde62d51d..2fade4ff4 100644
--- a/web/src/test/resources/com/graphhopper/http/resources/truck.yml
+++ b/web/src/test/resources/com/graphhopper/http/resources/truck.yml
@@ -33,7 +33,7 @@ priority:
   - if: toll != NO
     multiply_by: 0.5
   # avoid a certain area
-  - if: in_area_custom1
+  - if: in_custom1
     multiply_by: 0.5
   - if: max_weight < 4.5
     multiply_by: 0