Options for this are:
1. A less flexible but easy to implement JSON config approach:
{ "4_wheel_car": {
"default": "car",
"allow": ["highway=track", "ford=yes", "access=private"],
"avoid": ["toll=yes", "route=ferry", "highway=motorway"],
"avoid_factor": [2, 10],
"prefer": ["highway=trunk"],
"urban_speeds": { "trunk":50, "primary":70 },
"width": 1.9,
"height": 1.4,
"consider_one_ways": "yes",
"crossing_country": "avoid",
"avoid_area": [41,42,3,4],
"consider_conditional_restrictions": "yes"
},
"my_bike": {
"default": "bike",
"prefer": ["route=bicycle"]
},
"ch": { "disable": "true" },
}
Here the problem is how to express that e.g. the speed should be 20 inner city and 50 elsewhere or use a certain speed set for country:de
and another set for country:ch
? Or should we allow just speed factors? Or specify that some tags are on ways (or on nodes like barriers) and others like route=bicycle
are on relations? We could find a solution but it might be more wise to avoid any new language and use the other options instead if this is necessary or allow some combination? Also our aim should be to use low level OSM tags but being able to apply this for other data sources and avoid the complexity e.g. merge some tags into a âsuper tagâ and always use the same units like for weight, height and speed.)
2. A more flexible JSON format similar to what ElasticSearch provides
where we could build boolean expression and combine with other queries.
{ "actions": [{
"and_conditions": [{ "highway": "primary" }, {"some_more": "condition"}],
"or_conditions": [{ "some_condition": "but or_conditions cannot exist at the same time as and_conditions" }],
"action": "use_values",
"speed": 60,
"priority": 1.55,
"time_offset": 5,
"speed_factor": 2.5
}, {
"action": "use_speed",
"and_conditions": [],
"highway": { "primary": 60, "secondary": 50 },
"comment": "'shortcut action' -> this is a kind of a shortcut for multiple use_values actions with different speed values"
}]}
The first action sets e.g. the speed to 60 for all highway=primary
tags
The second action sets the speed to 60 (for highway=primary
) and to 50 (for highway=secondary
). We can add here additional conditions like { "and_condition": "filter", "bbox": [1,2,3,4] }
to say something like âset the edges only within a certain boundary to the specified valuesâ.
The and_conditions
or or_conditions
are not allowed to have actions where values are modified, just âconditionsâ.
With this we can model lots of things already like avoiding streets via âpriorityâ changes (without affecting the times) but also changing speed due to traffic jams or completely blocking with (priority=0 or speed=0). Or another and_condition
forcing inner or outer city only. time_offset
will be useful for customizable turn costs. With some more âarea selectionâ conditions we could even integrate custom data, e.g. for routes depending on the direction of the wind, to make this more compact we could introduce further âshortcut actionsâ.
In the calcWeight method we have the following steps:
2.1. default speed from some alias (âcar aliasâ) from config json, if nothing set it is 0
2.2. use speed from request overwriting config json, via speed
. Here we can also apply the speed_factor
to just reduce (not set) the default speed defined elsewhere.
2.3. calculate time: t=s/v
, with important assert before v>0
2.4. add / remove time via time_offset
, with important assert afterwards that t>0
2.5. multiply priority t*=priority
, with assert that priority>0
2.6. return t; // in seconds?
Make speed=0
and priority=0
blocking the edge.
3. Offer a very flexible approach via allowing a script language
(#193, painless or janino) or even the scripting lang that brouter implements (I find it a bit too complex for the average dev like me ;)) and just allow this language in the JSON request. Here the Java API has to made very simple to be used and fast from the client side.
All these 3 options have advantages&disadvantages. At the moment I feel we should start with 1. and investigate 2&3 while we collect more requirements and also get a better understanding of what is necessary to keep this API simple, fast and powerful. The advantage of 1. is that we can transform this easier into the best performing expression e.g. "avoid"
is easily doable with landmarks but "prefer"
would need a 'negative avoid
â to make it workĂŹng for landmarks. And e.g. too big weight differences can lead to heavy performance degradations and with 1. we could limit these differences easier (e.g. allow max. factor 10)
While I thought about this it might be better to either rename our prefix pt.
into something else or rename the vehicle pt
into public_transit
or similar to avoid confusion.