OSM Abfragen

Hallo,

gibt es irgendeine Möglichkeit Abfragen an OSM zu schicken?

Ich meine folgendes:
–> Apotheken im Umkreis von X Kilometern zu einer Adresse
–> Weg… von Bis…
–> Nächster Supermarkt

Liebe Grüße

Unregistrierter

Nicht das ich wüsste, zumindest direkt über eine API-Schnittstelle von OSM. Wird aber bestimmt irgendwo das ein oder andere Projekt sein, dass dies ermöglicht.

Aber man kann sich über die API-Schnittstelle alle Daten in einem bestimmten Bereich holen. Längen/Breitengrad bis Längen/Breitengrad.

Da bekommt man dann XML zurück.

Dort kann man dann alle Punkte (Nodes) durchgehen und schauen, ob es dort eben einen Punkt gibt der mit Apotheke gekennzeichnet ist. Und schon hat man eine Apotheke.

Supermarkt könnte man genauso vorgehen.

Und für eine Navigation kann man die Daten zwar holen, muss sich aber wohl damit etwas selbst stricken, was dann doch etwas aufwendiger sein wird.

Aus den Daten eine Karte zeichnen geht auch mit relativ überschaubarem Aufwand und erstaunlichem Erfolg.

wiki.openstreetmap.org/wiki/API_v0.6

Hi,

Aber man kann sich über die API-Schnittstelle alle Daten in einem bestimmten Bereich holen. Längen/Breitengrad bis Längen/Breitengrad.

Wie würde man da vorgehen?

Liebe Grüße

Unregistrierter

Indem man sich mal die Api durchliest und dann mal das ganze ausprobiert.

Hab ja schonmal den Link zum wiki gepostet

Dann gibt man mal so einen Link ein und schaut was dabei rauskommt

http://api06.dev.openstreetmap.org/api/0.6/map?bbox=49,9,49.1,9.1

Dann schaut man sich das Format an und guckt was das ganze bedeuten könnte.

Hi,

vielen Dank für Deine Hilfe. Aber ich versteh es leider nicht. Ich habe noch nie eine Webseite geparst und osm ist recht kompliziert. Hättest Du mir vielleicht ein Muster?

Ich verstehe das leider nicht so richtig. Hast Du mir vielleicht einen Link zu einem Muster?

Nicht die Api benutzen, darum bittet (Siehe OSM)

Benutzen Sie dies nicht für Massenanfragen, weil dies ressourcenintensiv ist. Benutzen Sie bitte anstelle dessen Overpass API oder XAPI.

Sie empfehlen stattdessen die Overpass API (Siehe [url=http://wiki.openstreetmap.org/wiki/DE:Overpass_API[/URL). Wie Die Abfragen funktionieren kann man hier sehen: [Die entsprechende Beispielsammlung]Bad title - OpenStreetMap Wiki](http://wiki.openstreetmap.org/wiki/DE:Overpass_API/Beispielsammlung)

Die Abfrage der Overpass-API erfolgt mittels XML. Das folgende Beispiel zeigt Kinos in Karlsruhe:

[XML]
[out:json][timeout:25];
// fetch area “Karlsruhe” to search in
{{geocodeArea:Karlsruhe}}->.searchArea;
// gather results
(
// query part for: “Kino”
node"amenity"=“cinema”;
way"amenity"=“cinema”;
relation"amenity"=“cinema”;
);
// print results
out body;

;
out skel qt;
[/XML]

Allerdings ist das die Abfrage über den Browser. Und da Du ein Programm möchtest, kommt das wohl eher nicht in Frage. Zum Glück gibt es auch die Möglichkeit mittels eines direkten Links abzufragen

[<a href=http://overpass-turbo.eu/?Q=… >](<a href=http://overpass-turbo.eu/?Q=… >)

Nach dem ?Q= erfolgt die Abfrage. Beim URL-Encoding erhälst Du Hier weiteres Informationen.

Wenn Du erstmal raus hast wie man aus dem XML einen HTML-Link machst, hast Du die halbe miete. Dann musst Du nur noch wissen, wie man die Daten bekommt und Dich danach noch schnell in das Parsen einlesen.

  1. Auf overpass turbo die Abfrage im Wizard eingeben: bar around “Zoo Karlsruhe” dann auf Abfrage erstellen und ausführen klicken.

  2. Der Wizard erstellt einem sofort die folgende ausgabe:
    [XML]
    [out:json][timeout:25];
    // adjust the search radius (in meters) here
    {{radius=500}}
    // gather results
    (
    // query part for: “bar”
    node[“amenity”=“bar”](around:{{radius}},{{geocodeCoords:Zoo Karlsruhe}});
    way[“amenity”=“bar”](around:{{radius}},{{geocodeCoords:Zoo Karlsruhe}});
    relation[“amenity”=“bar”](around:{{radius}},{{geocodeCoords:Zoo Karlsruhe}});
    );
    // print results
    out body;

;
out skel qt;
[/XML]

  1. Auf Export --> Abfrage --> kompakte Variante

  2. Dort bekommst Du folgenden Link: [Inline][out:json][timeout:25];(node"amenity"=“bar”;way"amenity"=“bar”;relation"amenity"=“bar”;);out body;>;out skel qt;[/Inline]

  3. Sobald Du auf den Link klickst, landest Du hier:http://overpass-api.de/api/interpreter?data=%5Bout%3Ajson%5D%5Btimeout%3A25%5D%3B%28node%5B%22amenity%22%3D%22bar%22%5D%28around%3A500%2C48%2E9984077%2C8%2E40147472011927%29%3Bway%5B%22amenity%22%3D%22bar%22%5D%28around%3A500%2C48%2E9984077%2C8%2E40147472011927%29%3Brelation%5B%22amenity%22%3D%22bar%22%5D%28around%3A500%2C48%2E9984077%2C8%2E40147472011927%29%3B%29%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B%0A

  4. Jetzt musst Du nur noch verstehen wie sich der Link zusammensetzt und das ganze dann parsen.

Hi,

Danke für die Hilfe. Vielen Dank an alle. Aber ich komm nicht weiter. Wie parat man JSON. Ich check das nicht. Hat jemand ein Muster?

Was hast du denn bisher versucht?

Beispiel mit org.json:

public static void main (String [] args) throws URISyntaxException, MalformedURLException, IOException{
        
        String data = "https://overpass-api.de/api/interpreter?data=%5Bout%3Ajson%5D%5Btimeout%3A25%5D%3Barea%283600062518%29%2D%3E%2EsearchArea%3B%28node%5B%22amenity%22%3D%22fast%5Ffood%22%5D%28area%2EsearchArea%29%3Bway%5B%22amenity%22%3D%22fast%5Ffood%22%5D%28area%2EsearchArea%29%3Brelation%5B%22amenity%22%3D%22fast%5Ffood%22%5D%28area%2EsearchArea%29%3B%29%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B%0A";
        
        URI uri = new URI(data);
        JSONTokener tokener = new JSONTokener(uri.toURL().openStream());
        JSONObject root = new JSONObject(tokener);
        
        String out = root.toString();
        
        System.out.println(out);
        
    }

*** Edit ***

Nachtrag:

Mit obigem Skript kann man die Daten Parsen, wirklich verwenden kann man sie damit natürlich nicht. Dazu müsste man evtl. irgendeine Art von Liste erstellen. Objekte wären sicher die beste Lösung. Dann kann man die Daten auch auf vielfältige Weise sortieren.

Dazu ist die Generierung von solchen URLs nicht ernstlich zu empfehlen. Falls Du gezielt nach den gleichen Eingaben suchen willst (immer die aktuellsten Infos ob die Schnellimbisse noch da sind… usw.) geht das natürlich, ansonsten ist das nur schwer dynamisch zu ändern.

Auch ist die Such nicht wirklich eine gute Idee, wenn Du unterschiedliche Orte abfragen willst ist das ebenfalls eher unglücklich. Eine mögliche Lösung wäre es mit LAT und LONG im Umkreis zu suchen. Adressen kann man beispielsweise einfach mit Google’s GeoCoding API umrechnen. Man könnte dann noch was basteln, dass dort wo es keine konkrete Adresse gibt eine Adresse in der Stadtmitte geparst wird, oder der jeweilige Hauptbahnhof.

Hi,

vielen Dank. Dankeschön. Wie kann man ein Objekt aus der Abfrage machen? Gibt es dafür irgendwo Beispielcode?

OK, ich muss also erst Objekte erstellen:
int lat
int lon
String object ID
String strasse
String name

Wenn ich das samt getter erstellt habe, wie baue ich das ein. Gibt es dafuer ein Muster?

JAXB JSON POJO Serialization Example : Adam Bien’s Weblog

Weiß jemand wie man Objekte erstellen kann?

public static void main (String [] args) throws URISyntaxException, MalformedURLException, IOException{
        
        
               
        //Url
        String data = "https://overpass-api.de/api/interpreter?data=%5Bout%3Ajson%5D%5Btimeout%3A25%5D%3Barea%283600062518%29%2D%3E%2EsearchArea%3B%28node%5B%22amenity%22%3D%22fast%5Ffood%22%5D%28area%2EsearchArea%29%3Bway%5B%22amenity%22%3D%22fast%5Ffood%22%5D%28area%2EsearchArea%29%3Brelation%5B%22amenity%22%3D%22fast%5Ffood%22%5D%28area%2EsearchArea%29%3B%29%3Bout%20body%3B%3E%3Bout%20skel%20qt%3B%0A";
        URI uri = new URI(data);
        //Parsen
        JSONTokener tokener = new JSONTokener(uri.toURL().openStream());
        JSONObject res = new JSONObject(tokener); 
        
        
    }

Mit res.lenght() bekommt zumindest nicht die richtige Anzahl an Elementen. Auch Ansonsten bin ich ratlos. Wie kann man Objekte aus den Ausgaben erstellen?

Ist das nur bei mir so - oder funktionieren alle Example links bei XAPI und Overpass API für alle angegebenen Server mit Webbrowser und wget NICHT?!?! Ich wollte doppelt beschränkt eine relativ kleine Suchanfrage anfangen, bekomme aber nur 404-Status oder Navigationshilfe T-Online. Hab im de- und en-Wiki geschaut.

hätte ein .jar geschrieben, das eine (nicht immer gleiche) kleine Suchanfrage komplett zerpflückt und „aufbereitet“.

Wie es auch sei, für XML und json „handling“ gibt’s eigentlich 'ne eigene Vorlesung, wahrscheinlich wird es dir niemand aus dem Ärmel schütteln.

Und wenn ich den bisherigen Versuch sehe, dann müsstest du da anfangen, wie mein eine Lib. einbindet - also noch relativ weit vorne.

Edit: Also es ist einfacher, das Wetter in Buxtehude am genausten zu bestimmen, als eine Anfrage daran zu stellen! :wink:

Hier ne XML Variante.

[XML]

<?xml version="1.0" encoding="UTF-8"?> The data included in this document is from www.openstreetmap.org. The data is made available under ODbL. [/XML]
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.DOMException;
import org.xml.sax.SAXException;



public class ReadXMLFile {

  public static void main(String argv[]) {

    try {
        //Dateipfad
        String dateipfad = "HIER PFAD EINTRAGEN";        
	File fXmlFile = new File(dateipfad);
	DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
	DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
	Document doc = dBuilder.parse(fXmlFile);
	//Normalisieren
	doc.getDocumentElement().normalize();
        //Arten    
	NodeList nList = doc.getElementsByTagName("node");

	
        for (int temp = 0; temp < nList.getLength(); temp++) {

		Node nNode = nList.item(temp);

		if (nNode.getNodeType() == Node.ELEMENT_NODE) {

			Element eElement = (Element) nNode;
                        System.out.println("Id: " + eElement.getAttribute("id"));
                        System.out.println("Lat: " + eElement.getAttribute("lat"));
                        System.out.println("Lon: " + eElement.getAttribute("lon"));
                        System.out.println();     
		}
	}
    } catch (ParserConfigurationException | SAXException | IOException | DOMException e) {
    }
  }

}

Allerdings gibt es zwei Probleme:

  1. Der Name ist nicht auf die gleiche Weise zu erfragen
  2. ich weiß nicht wie man direkt auf die XML-Dateien kommt.

Vielleicht kann irgendwer hierbei helfen. Ich würde mich sehr freuen.

Hab ich mich missverständlich ausgedrückt? Das Parsen ist überhaupt kein Problem. Ich weiß nicht, wie sich die URL zusammensetzt. :sick:

Bis später, muss weg.

Hi,

hast Du mal die Links aus den Beispiel hier vetsucht? Zum Beispiel den im Java-Code von Post 15 (Zeile 7). Der fuehrt direkt zur JSON Ausgabe. Wenn man das “json” - das ist recht weit vorn in dem Link - durch “XML” ersetzt, bekommst Du eine XML Ausgabe.

Allen einen schönen Donnerstag.

@Fensterputzer:
Schau mal auf http://wiki.openstreetmap.org/wiki/DE:OSM_XML[\URL] vielleicht findest Du da Hilfe. Aber vetmutlich ist es auch trotzdem schwierig aud diesem Weg dynamische Abfragen zu generieren.

@CyborgBeta
Hast Du bezüglich der URL mal:

XML
http://overpass-api.de/api/interpreter?data=[out%3Axml][timeout%3A25]%3B(node["amenity"%3D"bar"](around%3A500%2C48.9984077%2C8.40147472011927)%3Bway["amenity"%3D"bar"](around%3A500%2C48.9984077%2C8.40147472011927)%3Brelation["amenity"%3D"bar"](around%3A500%2C48.9984077%2C8.40147472011927)%3B)%3Bout%20body%3B>%3Bout%20skel%20qt%3B

JSON
http://overpass-api.de/api/interpreter?data=[out%3Ajson][timeout%3A25]%3B(node["amenity"%3D"bar"](around%3A500%2C48.9984077%2C8.40147472011927)%3Bway["amenity"%3D"bar"](around%3A500%2C48.9984077%2C8.40147472011927)%3Brelation["amenity"%3D"bar"](around%3A500%2C48.9984077%2C8.40147472011927)%3B)%3Bout%20body%3B>%3Bout%20skel%20qt%3B

Die sollten eigentlich funktionieren.