Na AllTrails, derivámos segmentos de trilhos a partir de dados do OpenStreetMap e armazenámo-los numa base de dados separada, utilizada na criação do nosso tipo de mapa AllTrails TileSet e na nossa ferramenta de criação de mapas personalizados.
Este documento disponibiliza publicamente o método para fazer alterações à "base de dados" original do OSM, conforme exigido pela licença ODBL na secção 4.6.b.
Ao contrário da base de dados do OSM, que depende de nós e caminhos, onde os caminhos representam estradas/caminhos completos e os nós representam as extremidades dessas estradas/caminhos, nós dependemos do conceito de segmentos (ou seja, segmentos individuais que compõem um caminho e começam/termina nas intersecções dos caminhos). Anteriormente, a base de dados do OSM incluía segmentos, mas estes foram removidos em outubro de 2007 para simplificar o modelo de dados (de acordo com a seguinte documentação: https://wiki.openstreetmap.org/wiki/Segment).
O algoritmo para criar a nossa base de dados derivada funciona da seguinte forma:
1. Utilize a API Overpass para descarregar dados de caminhos do OSM em mosaicos de 2x2 graus, com latitude de -58 a +72 graus:
"http://www.overpass-api.de/api/xapi?way[highway=path|track|footway|steps|bridleway|cycleway][bbox=#{lng},#{lat},#{lng+TILE_DIM},#{lat+TILE_DIM}]"
Os dados serão descarregados no formato .osm.
2. Converta cada mosaico de 2x2 do formato .osm para .geojson com a funcionalidade OsmToGeojson para facilitar a análise.
3. Faça uma iteração sobre os caminhos contidos em cada mosaico, o que armazena as informações do caminho num código hash que tem a chave do ID do caminho (necessário porque o mesmo caminho pode aparecer em vários mosaicos de 2x2)
4. Faça uma iteração sobre cada caminho (A) encontrado no código hash; para cada caminho (A), faça uma iteração sobre os pontos de todos os outros caminhos (B) e compare os pontos com o caminho original (A), até ser encontrada uma correspondência. No ponto em que estes caminhos coincidem, armazene uma entrada num outro código hash, que também tem a chave do ID do caminho, mas com um valor que representa um conjunto de todas as interseções deste caminho (A) com todos os outros caminhos (B).
5. Faça uma iteração sobre cada caminho (A) novamente, desta vez ao criar segmentos para cada caminho por cada interseção encontrada e armazenada no código hash criado no passo anterior.
6. Calcule a distância total de cada segmento de caminho ao calcular a distância cartesiana entre cada ponto do segmento de caminho e depois somar os valores.
7. Calcule a caixa delimitadora do segmento de caminho ao encontrar os valores mínimos e máximos de latitude e longitude de todos os pontos do segmento de caminho e, em seguida, ao formar cada canto da caixa delimitadora como cada combinação única dos quatro valores mínimos/máximos.
8. Envie cada interseção e/ou segmento para um ficheiro Geojson ou outro formato, armazenando dados de segmentos de forma única, conforme necessário, como por exemplo:
Interseções - ID (arbitrário, mas único), latitude, longitude
Segmentos de caminhos - ID original do caminho OSM, points_data, intersection_start_id, intersection_end_id, distance_total, bounding_box, private_access (access=private, access=no), bicycle_accessible (bicycle=yes)