Bij AllTrails hebben we routesegmenten afgeleid van OpenStreetMap-gegevens en deze opgeslagen in een aparte afgeleide database, die wordt gebruikt bij het maken van ons AllTrails-kaarttype TileSet en onze tool voor het maken van aangepaste kaarten.
In dit document wordt de methode voor het aanbrengen van wijzigingen in de oorspronkelijke 'OSM-database' uitgelegd, zoals vereist conform de ODBL-licentie, sectie 4.6.b.
In tegenstelling tot de OSM-database, die is gebaseerd op punten en wegen, waarbij wegen staan voor hele wegen/paden en punten voor de eindpunten van deze wegen/paden, gaan wij uit van het idee van segmenten (d.w.z. afzonderlijke segmenten die een weg vormen en beginnen/eindigen op de kruispunten van wegen). De OSM-database bevatte vroeger segmenten, maar deze zijn in oktober 2007 verwijderd om het gegevensmodel te vereenvoudigen (volgens de volgende documentatie: https://wiki.openstreetmap.org/wiki/Segment).
Het algoritme om onze afgeleide database te maken, werkt als volgt:
1. De Overpass API wordt gebruikt om OSM-weggegevens te downloaden in tegels van 2x2 graden, tussen een breedtegraad van -58 en +72:
"http://www.overpass-api.de/api/xapi?way[highway=path|track|footway|steps|bridleway|cycleway][bbox=#{lng},#{lat},#{lng+TILE_DIM},#{lat+TILE_DIM}]"
De gegevens worden gedownload in .osm-formaat.
2. Elke tegel van 2x2 wordt geconverteerd van .osm naar .geojson met behulp van OsmToGeojson om ze eenvoudiger te kunnen verwerken.
3. De wegen in elke tegel worden geïtereerd, waarbij de weggegevens worden opgeslagen in een hash met als code de weg-ID (die is nodig omdat dezelfde weg in meerdere tegels van 2x2 kan voorkomen)
4. We itereren elke weg (A) die is gevonden in de hash aan de hand van de punten van alle andere wegen (B) en vergelijken de punten met de oorspronkelijke weg (A), totdat er een overeenkomst is gevonden. Voor het punt waar deze wegen overeenkomen, slaan we een invoer op in een andere hash, die ook is gecodeerd met een weg-ID, maar met een waarde die een array vertegenwoordigt van alle kruispunten van deze weg (A) met alle andere wegen (B).
5. We itereren nogmaals alle wegen (A), maar deze keer segmenteren we iedere weg op basis van de kruispunten die zijn gevonden en opgeslagen in de hash die bij de vorige stap is gemaakt.
6. We berekenen de totale afstand voor elk wegsegment door de cartesiaanse afstand tussen elk punt van het wegsegment te berekenen en de waarden vervolgens bij elkaar op te tellen.
7. We berekenen het begrenzingsvak van het wegsegment door de minimale en maximale breedte- en lengtegraden van alle punten in het wegsegment te vinden en vervolgens elke hoek van het begrenzingsvak te vormen als iedere unieke combinatie van de vier minimale en maximale waarden.
8. We exporteren ieder kruispunt en/of segment in Geojson-formaat of een ander bestandsformaat, en slaan daarbij unieke wegsegmentgegevens op waar nodig, zoals:
Kruispunten: ID (willekeurig, maar uniek), breedtegraad, lengtegraad
Wegsegmenten: originele OSM-weg-ID, points_data, intersection_start_id, intersection_end_id, distance_total, bounding_box, private_access (access=private, access=no), bicycle_accessible (bicycle=yes)