Einlesen der Daten:
Das System verwendet die Daten des OpenStreetMap-Projektes in Form einer osm.pbf-Datei ("Protocolbuffer Binary Format").
Diese beinhaltet die OSM-Entities in Binär-Form was einen schnelleren Zugriff erlaubt. Zusätzlich werden die Boundaries deutscher Städte und Landkreise aus einer Textdatei eingelesen.
Die osm.pbf Datei konnte mit Hilfe der
Osmosis-library eingelesen werden.
Entities, mit Tags (wie zum Beispiel: "shop=bakery"), welche in der zuvor erstellten Ontology File definiert wurden, werden herausgefiltert und in einem Index abgespeichert.
Zuordnung zu Städten / Orten:
Für jede zuvor eingelesene Boundary werden nun die geohashes berechnet, welche das Gebiet umfasst. Diese werden dann, auf die zugehörigen Orte abbildent (Geohash->Ort) gespeichert.
Nun wird für jede im Index gespeicherte Entity der zugehörige geohash berechnet und mit Hilfe der Geohash->Ort Zuordnung ist nun abrufbar wo sich die jeweilige Entitiy befindet.
Aufbau der Ontology:
Die Tags, welche zur grundlegenden Identifizierung der Entitiy Typen verwendet werden, wurden zuvor aus der osm.pbf-Datei extrahiert, beispielsweise alle Values( "bakery", "butcher",...) des keys "shop".
Diese wurden daraufhin zur Erstellung der Ontology verwendet. Die Ontology wurde in Form einer XML-Datei realisiert, welche aus zwei verschiedenen Typen besteht, nämlich einer Gruppen und einem Elementen.
Eine Gruppe besteht aus Elementen und/oder weiteren Untergruppen. Ein Element hat die Bestandteile key ("amenity",...) und value ("restaurant",...) und bildet die Voraussetzung für die Zugehörigkeit zu einer Gruppe.
Sehen wir uns dies anhand eines italienischen Restaurants an:
Die Obergruppe "places to eat" beinhaltet unter anderem die Gruppe "Restaurant" welche wiederum verschiedene Untergruppen(italienisch, französisch, ...) enthält.
Gruppe "Restaurant" enthält aber auch das Element mit den Attributen key="amenity" und value="restaurant", was dadurch zur Voraussetzung für die Zugehörigkeit zu dieser Gruppe und deren Untergruppen wird.
Die Gruppe "Italian Restaurant" beinhaltet nun unter anderem die Elemente mit den Attributen value="italian" key="cuisine" und value="italienisch" key="cuisine".
<list>
<group name="place to eat">
<group name="Bakery">
<element key="shop" value="bakery"></element>
</group>
<group name="Butcher">
<element key="shop" value="butcher"></element>
</group>
<group name="Restaurant">
<element key="amenity" value="restaurant"></element>
<group name="Italian Restaurant">
<element value="italian" key="cuisine"></element>
<element value="italienisch" key="cuisine"></element>
.
.
.
</group>
<group name="French Restaurant">
<element value="french" key="cuisine"></element>
<element value="crepe" key="cuisine"></element>
<element value="crepes" key="cuisine"></element>
.
.
.
</group>
.
.
.
Nach dem Speichern der Entities aus der osm.pbf-Datei in einem Index wird für jede Entitiy die Ontology durchlaufen und die Indexposition des Entities in der zugehörigen Gruppe in einem Baum im Format (Ort->Entities) gespeichert.
Server:
Der Server unterscheidet zwischen zwei Anfragen. Einer Boundary-Anfrage und einer Entity-Anfrage.
- Bei einer Boundary-Anfrage wird nur der Name des Orts übergeben und das zugehörige Poligon mit all seinen Punkten wird im XML-Format zurückgegeben.
- Bei einer Entity-Anfrage wird der Name der gesuchten Gruppe der Ontology übergeben (z.Bsp.: "places to eat"),
der Ort der Suche ("Freiburg im Breisgau"), der Faktor des Clusterings (siehe Clustering), und die Latitide- bzw. Longitude-Werte des Kartenausschnitts ( top, bottom, left, right). Näheres im Bereich Clustering
Anhand der Gruppe und des Ortes können nun alle relevanten Einträge herausgesucht werden, in dem der request an die zugehörige Gruppen-Objekte übergeben wird. Diese kann durch eine, zuvor erstellte, Gruppenliste schnell gefunden werden.
Die dabei erstellte Liste an passenden Einträge kann jedoch zu viele Einträge enthalten, sodass diese vom Client gar nicht dargestellt werden können. Es gibt zum Beispiel über 6000 "places to eat" in "Berlin" und über 16.000 in Baden-Württemberg.
Aus diesem Grunde wird ein Clustering durchgeführt. Es werden dann die geclusterten Enträge, welche sich im Kartenausschnitt befinden im XML-Format zurückgegeben.
Clustering, Kartenausschnitt:
Um das Übermitteln unnötiger Informationen zu verhindern, werden Einträge, welche sich außerhalb des Kartenausschnitts befinden, aussortiert.
Dabei werden alle geohashes innerhalb des Kartenausschnitt berechnet und dem clustering nur diejenigen Einträge übergeben, welche den gleichen Prefix besitzen.
Das Clustering wird mit Hilfe des geohashs erstellt. Dabei werden abhängig vom aktuellen Zoom dem Server bei der Anfrage die zu verwendende Länge des Geohashes übermittelt.
Bei einer gegebenen Länge von 4 wird dann jede Geohash-Position mit dem gleichen Prefix der Länge 4 zusammen in einen Cluster zusammengefasst und anschließend das Clusterzentrum berechnet.
Uhrzeit:
OpenStreetMaps unterstützt auch das hinterlegen von
Öffnungszeiten.
Diese werden bei einer Anfrage an den Server mit Hilfe des
OpeningHoursParsers
aus dem
Osmand Projekt geparst und der Antwort-XML beigefügt.
Die Webseite kann nun je nach Status verschiedene Icons(Android) anzeigen.
|
Geöffnet |
|
Geschlossen |
|
Status unbekannt |
Webseite / Benutzeroberfläche:
openlayers:
Die Karte wird mit Hilfe von Openlayers gerendert.
Screenshots der Benutzeroberfläche sind in der Sektion Screenshots zu sehen.
Statistiken:
- Ontology bestehend aus 319 Elementen
- 12982 Orte in Deutschland inklusive Bundesländer und Landkreise
- geohashes: 575912 für ganz Deutschland
- OSM-File: 2,1 GB, 491823 Nodes werden verwendet.
-
Diagramm:
Das OpenStreetMap Projekt ist ein freies Projekt zur Erfassung von Geodaten. Es verwendet die OpenDatabaseLicense und bietet damit einen leichten Zugriff auf die gesamten Daten.
Als Quellen für das Projekt dienen von Hand eingetragene oder aufgezeichnete Daten von Freiwilligen. Diese können zum Beispiel durch GPS-fähige Geräte aufgezeichnet und in das Projekt hochgeladen werden.
Anschließend werden die Daten von den Usern mit Tags (zum Beispiel: shop=bakery) versehen.
Ein geohash ist ein auf Latitude und Longitude basierendes Geocodesystem. Es handelt sich hierbei um eine hierarchische Datenstruktur welche den Raum in eine Gitterform aufteilt.
Meist haben naheliegende Orte gleiche Prefixe. Je länger der gemeinsame Prefix ist, je näher befinden sich die beiden Orte beieinander.
Wie in folgendem Bild zu sehen, beinhaltet der geohash "u0t9" unter anderen den geohash "u0t94", usw.
Folgende Tabelle zeigt die Genauigkeit der Geohashes:
GeoHash Länge
|
Gebiet Breite x Höhe
|
1
|
5,009.4km x 4,992.6km
|
2
|
1,252.3km x 624.1km
|
3
|
156.5km x 156km
|
4
|
39.1km x 19.5km
|
5
|
4.9km x 4.9km
|
6
|
1.2km x 609.4m
|
7
|
152.9m x 152.4m
|
8
|
38.2m x 19m
|
9
|
4.8m x 4.8m
|
10
|
1.2m x 59.5cm
|
11
|
14.9cm x 14.9cm
|
12
|
3.7cm x 1.9cm
|
Quelle:
elasticsearch.org