Lithuanian Road Agency (LAKD) provides "Open Data" information in JSON format about temporary restrictions on state roads at http://restrictions.eismoinfo.lt . This software is to integrate that information into Open Street Maps--both public database and private snapshot. Intention is to make this process automatic as much as possible to do in safe way. When in doubt--prepare draft which should be checked and uploaded manually.
Software state: design.
This information source covers only Lithuanian state operated roads--i.e. no roads in cities, no local roads, no private roads. Time scope is from single day speed limit due to roadside barrier fixing, to several months diversions due to road reconstruction, to year+ speed or weight limitation due to damaged road. There are 100+ restrictions at any time.
Information about permanent restrictions, like low bridge, narrow tunnel or limited speed due to pedestrians crossing are in different database.
TODO: License of provided information?
| LAKD | OSM | Comments |
|---|---|---|
_id |
lakd:restriction:id |
used to remove information when restriction ends |
restrictions/[restrictionType=speedLimit] |
maxspeed |
Maximum speed allowed. TODO: What to do if several speed are provided? |
restrictions/[restrictionType=weightLimit] |
maxweight |
Maximum weight allowed. |
restrictions/[restrictionType=roadClosed] |
access:no |
|
restrictions/[restrictionType=*] |
No changes in OSM. Email maintainer about unknown information | |
restrictions/[transportType=All] |
default case | |
restrictions/[transportType=lorry] |
+:hgv |
|
restrictions/[transportType=*] |
No changes to OSM. Email maintainer about unhandled restriction | |
location/street |
ref |
First word in LAKD source states road number. Changes in OSM are only possible if ref attribute of the way contains this number |
location/polyline |
geographic information where restriction is in force' | |
location/[direction=BOTH_DIRECTIONS] |
Changes are possible | |
location/[direction=ONE_DIRECTION] |
TODO: how to reliably distinguish which direction we should add restriction to? Most likely adding should be done manually, removal can be performed automatically. | |
starttime |
Timestamp when restriction should start. Usually midnight local time. In 90%+ cases before creationtime. |
|
endtime |
Timestamp when restriction should end. Usually 23:00 local time. | |
updatetime |
Timestamp when information about restriction was updated. |
There are two possible ways to encode these restrictions. Which one (and when) to use is still to be decided.
- using :conditional modifier to indicate dates when restriction will be in force
-
- supported users will take into account routing date, so ended (not yet started) restrictions are not a problem;
-
- formal specification redirects to
opening_hoursformat description, which lacks support for years; TODO: should we skip year? what to do with restrictions longer than year?
- formal specification redirects to
- support in popular software:
- OsmAnd -- TODO
- use regular tags to indicate active restrictions now.
-
- universally supported
-
- if application's/ service's database is updated less frequently in comparison with restriction's lifetime, stale information about restriction can unfairly penalize some route. Update times of popular applications and services:
- OsmAnd - monthly; with OSM Live paid service even hourly updates are possible
- script should be run daily at the end of the day (23:xx). It should remove all restrictions which ends that day (or earlier) and insert/update restrictions which start/changes next day. Ideally this should happen before other tools updates their DB.
- script should get restriction information from LAKD, check if number of records changed more than usual (>5--10%). In that case it should mail maintainer differences. Maintainer can run script manually with overridden limit if he sees only legitimate changes. This step is to prevent most problems at LAKD affecting OSM database.
- remove expired restrictions: for every restriction r, which is listed in our database as present in OSM, but does not appear in downloaded list or appear in the list but have
endtimetoday or earlier: - find all ways in OSM with
lakd:restriction:idmatchingr._id - if we have old value for this way, restore it
- if we do not have old value, just remove restriction
- remove
lakd:restriction:id
‼️ if LAKD's information is late and some users have seen and added restriction manually, we have restored stale information; could happen at the begining of use of this system, later should be very rare.‼️ if some way had speed limit and that way was split during restriction with lowered speed limit period, new ways will not get old speed limit restored. TODO: should we store old value in OSM for it to be copied into new ways?
-
update changed restrictions: for every restiction r, which is listed in our database as present in OSM, appear in downloaded list but have different
updatetime: -
collect commands to remove r as per (3);
-
collect commands to add r as per (5);
-
remove commands which cancel one another
-
insert new restrictions: for every restriction r, which is present in downloaded list but according to our database is not present in OSM and have duration above set limit and have
starttimetomorrow or earlier and haveendtimetomorrow or later: -
collect all the ways w, what are at least partially present in the r's bounding box and have road number present in their
refattribute -
if
direction=BOTH_DIRECTIONS1. for every w1 in w, where all nodes of w1 are n meters (TODO: define n) around r'spolyline- if present store old restriction value
- add restriction
- add
lakd:restriction:id - mark for automatic upload
2. if sum of w1 lengths / length of r's polyline is within [0.95; 1.05] consider success and continue with next r; TODO: am I too optimistic?
3. otherwise mark that this r needs manual adjustment and for every w2 in w, where some but not all nodes of w2 are n meters around r's
polyline - if present store old restriction value
- add restriction
- add
lakd:restriction:id - mark for manual adjustment
-
if
direction=ONE_DIRECTIONfollow (c) above. TODO: can we go with (a) with reduced n?
This way ensures that changes in the OSM database are made only when that restriction changes in LAKD.
If someone have a good reason to override information coming from LAKD he could remove lakd:restriction:id attribute and this system will stop changing these ways. At least until LAKD will give another restriction _id. Should we have more powerful kill switch?