TSM - OpenStreetMap, Open Data, Scripting What, Why, How?

Manuela Butuc - Map analyst @ Telenav

OpenStreetMap este un proiect colectiv, creat cu scopul de a oferi o hartă completă și actualizată permanent de către comunitate, fiind totodată gratuită pentru utilizatori de orice natură: site-uri web, aplicaţii mobile sau sisteme GPS. Compania Telenav își propune să folosească OpenStreetMap la cât mai multe proiecte interne, în mod special pentru sistemele de navigaţie auto prin GPS.

Pentru a obţine o hartă de calitate, este nevoie ca datele să fie revizuite și actualizate în mod constant, motiv pentru care, în cadrul companiei, există un departament destinat îmbunătăţirii datelor OSM. Echipa de Map-Analysts (cea mai numeroasă din companie) are ca sarcină îmbunătăţirea hărţii OSM utilizând date gratuite și diverse tooluri interne sau open-source.

Noțiunea de open data

Ideea din spatele datelor Open Source este aceea de a oferi gratis, pentru orice tip de utilizator, diferite tipuri de date, cum ar fi date demografice sau geografice. Pentru a fi considerate date deschise, acestea trebuie să respecte criteriile de disponibilitate, acces, reutilizare și participare universală.

Cu scopul de a putea fi folosite la îmbunătăţirea sau actualizarea hărților OpenStreetMap, aceste date trebuie să fie în format geospațial și să aibă anumite atribute pe care sistemele de navigație le folosesc, cum ar fi numele străzii, direcția de mers, limitări de viteză sau restricții de viraj.

În mare parte, aceste date sunt accesibile pe portalul data.gov al fiecărei țări, sau pe site-urile diferitelor orașe care dispun de aceste date, în mod special în Statele Unite și Canada. De exemplu, din aproximativ 50 orașe canadiene pe care lucrăm, o proporție de 80% dispun de date locale open-source, fără a lua în considerare datele Canvec și Geobase, date guvernamentale cu rețeaua de transport care oferă o acoperire de 100% pe teritoriul Canadei.

Open Data Inception - portal de date open-source

Scopul proiectului

Odată ce ai date gratuite la dispoziție, acestea trebuie folosite în cel mai eficient mod cu putință. Varianta de a extrage drumuri fără nume din baza de date OSM, a le suprapune și compara manual cu datele locale era o metodă mult prea lentă și cerea multă atenție. Așadar, ne-am gândit: "Deja avem un tool intern care compară geometrii și creează un fișier separat cu drumurile care lipsesc, cum ar fi să extindem ideea pentru atribute?". Atributele sunt niște date de tip cheie-valoare care descriu categoria de drum, viteza maximă admisă, numele, numărul de benzi, ș.a.m.d. . Dacă am putea compara atributele din OSM cu cele din datele locale, problema e aproape rezolvată (nu total, deoarece mai au nevoie și de validare).

Zis și făcut! Cu ajutorul departamentului Java, toolul Cygnus a devenit Cygnus+ și era capabil să compare atributele din OSM cu cele din datele open-source. Cu ajutorul acestui tool, maparea drumurilor a devenit un proces semi-automatizat, mult mai eficient atât din punct de vedere calitativ, cât și cantitativ.

Principiu de funcționare

Principiul de bază al acestui tool constă în compararea datelor geospațiale cu datele care există deja în OSM, pe baza atributelor și al unui buffer creat în jurul segmentelor de drumuri din zona de interes.

Cum era de așteptat, datele locale nu folosesc 'limbajul OSM', în sensul că atributele acestora nu au aceleași denumiri. De exemplu, pentru direcția de mers, atributul din Canvec se numește traffic flow direction, având valorile same direction, opposite direction sau both, în timp ce, în OSM, drumurile cu sens unic au atributul "oneway"="yes".

Pentru a 'traduce' atributele datelor locale în limbaj OSM, creăm un translation file (în limbaj Python) particularizat, în funcție de specificul și caracteristicile acestor date. Găsiți un exemplu în imaginile de mai jos:

Atributele datelor locale

Fișierul de translație:

def filterTags(attrs):
    with open("log.txt", "a") as log_file:
        log_file.write("called")
    if not attrs:
        with open("log.txt", "a") as log_file:
            log_file.write("no attributes")
        return
    tags = {}

    if "STREET_NAM" in attrs:
        tags["name"] = attrs["STREET_NAM"]

    if "REGIONAL_R" in attrs:
        tags["alt_name"] = attrs["REGIONAL_R"]

    if "LANES" in attrs:
        tags["lanes"] = attrs["LANES"]

    if 'SHOULDER' in attrs:
        if attrs['SHOULDER'].strip() == 'PAVED':
            tags['surface'] = 'paved'
        if attrs['SHOULDER'].strip() == 'GRAVEL':
            tags['surface'] = 'gravel'

    if "FLOW_DIREC" in attrs:
        if attrs["FLOW_DIREC"].strip() == "FromTo":
            tags["oneway"] = "yes"
        elif attrs["FLOW_DIREC"].strip() == "ToFrom":
            tags["oneway"] = "-1"

    if 'CARTO_CLAS' in attrs:
        if attrs['CARTO_CLAS'].strip() == 'Expressway / Highway':
            tags['highway'] = 'motorway'
        elif attrs['CARTO_CLAS'].strip() == 'Freeway':
            tags['highway'] = 'motorway'
        elif attrs['CARTO_CLAS'].strip() == 'Arterial':
            tags['highway'] = 'secondary'
        elif attrs['CARTO_CLAS'].strip() == 'Alleyway / Lane':
            tags['highway'] = 'service'
        elif attrs['CARTO_CLAS'].strip() == 'Collector':
            tags['highway'] = 'tertiary'
        elif attrs['CARTO_CLAS'].strip() == 'Local Street':
            tags['highway'] = 'residential'
        elif attrs['CARTO_CLAS'].strip() == 'Cul-de-Sac':
            tags['highway'] = 'residential'
            tags['noexit'] = 'yes'
        elif attrs['CARTO_CLAS'].strip() == 'Ramp':
            tags['highway'] = 'tertiary_link'
        elif attrs['CARTO_CLAS'].strip() == 'Private':
            tags['highway'] = 'service'
            tags['access'] = 'private'
        elif attrs['CARTO_CLAS'].strip() == 'Roundabout':
            tags['highway'] = 'residential'
            tags['junction'] = 'roundabout'

    return tags

Fișierul de translație creat va fi folosit împreună cu scriptul open-source ogr2osm.py, care convertește datele vectoriale de tip shapefile în date OSM XML. Acestea vor fi convertite, la rândul lor, în format osm.pbf, utilizând OSMconvert.

Toolul de comparare a atributelor acceptă ca input fișiere de tip graph, așa că e nevoie să convertim datele rezultate mai sus în acest format, utilizând un tool intern, numit graph-converter.

Odată ce am obținut fișierul de tip graph cu datele locale, acesta poate fi folosit împreună cu toolul de comparare a atributelor. Acesta creează un fișier în format xml care conține doar segmentele de drum ale căror atribute sunt diferite comparativ cu datele din OSM pentru zona respectivă.

Dacă pentru un anumit segment de drum, un atribut există în OSM, dar are altă valoare față de datele locale, în fișierul rezultat acel segment va avea următorul tag:

<tag k="telenav:cygnus-plus" v="CHANGED"/>. Dacă atributul lipsește din OSM, dar există în datele locale, segmentul de drum primește tagul <tag k="telenav:cygnus-plus" v="NEW"/> . Cu ajutorul acestor taguri putem prioritiza anumite etape de editare.

Procesul de convertire și comparare a datelor

Fișierul rezultat poate fi importat în JOSM (Java OpenStreetMap Editor) și folosit pentru a adăuga sau actualiza datele OSM.

Compararea atributelor de tip oneway (sens unic de circulație)

În concluzie, cu ajutorul acestui tool, putem semi-automatiza procesul de îmbunătațire a hărții utilizând date open-source.