Geo-Datenbank

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Geo-Datenbank

      Hi,

      ich habe leider nur kleine Kenntnisse in mySQL und deshalb wollte ich hier erstmal fragen bevor ich versuche etwas zu erstellen was so gar nicht funktionieren kann.

      Ich möchte auf meinem Webserver eine Geo-Datenbank aufsetzen, die zunächst mal nur aus den Tabelleneinträgen Longitude,Latitude und Name besteht. In meiner App möchte ich nun aus dieser Datenbank den, meiner aktuellen Position, am nächsten gelegenen Ort finden. Dazu müßte ich dann wohl aber zu jedem Datenbankeintrag eine Entfernung mit Pythagoras ausrechnen. Also

      Entfernung=sqrt( (latitudedb-latitudeApp)^2 + (longitudedb-longitudeApp)^2) (eigentlich viel komplexer siehe: kompf.de/gps/distcalc.html aber für hier reicht es erstmal)

      und davon dann den kleinsten Wert finden. Es kann aber ja irgendwie nicht Sinn der Datenbank sein, dass ich jeden Eintrag lesen und berechnen muss. Das kann ja dann auch beliebig langsam werden. Aber wie kann man das anders machen, so dass man eventuell schon vorfiltern kann oder so?

      Gruß

      Claus
      2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

      Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
    • Du kannst für Longitude und Latitude ja erst mal einen von-bis Bereich berechnen und dann alle Treffer aus der DB laden, welche sich in diesem Bereich befinden. Gibt es keine Treffer, dann musst Du den Bereich entsprechend vergrößern usw.

      Für die gefunden Treffer kannst Du dann die jeweiligen Entfernungen zur gesuchten Position berechnen und den Treffer mit der kürzesten Entfernung ermitteln.
    • gritsch schrieb:

      die berechnung kannst du ja auch direkt von der query erstellen lassen. falls es (irgendwann) zu langsam wird kannst dich ja dann drum kümmern.


      Das wäre interessant zu wissen wie man sowas macht. Hast du da irgendwie mal einen Link zu was einführendem ?

      Gruß

      Claus
      2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

      Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)
    • Zum Einen und in Hinblick aufs Gleitschirmfliegen: lass die Altitude nicht außer Acht. ;)

      Zum Anderen ist genau das die Funktionsweise von Datenbanken:
      nimm alles auf einmal und filtere dann Stück für Stück raus.

      Anders als Core Data (Core Data ist schließlich keine Datenbank) hast du keine definitiven Referenzen auf irgendwas.

      Quellcode

      1. select * from geodata g, location l where g.id=l.geoID and g.id < 10

      Nimmt also erst mal alle Geodata-Einträge und alle Location Einträge, ordnet die Ausgabe dann gemäß Geodata.ID > Location.geoID zu und dann wirft sie alles an Geodata weg, dessen ID > 9 ist.
      Das ist halt so™. Die Datenbanken sind dafür ausgelegt und machen das auch verdammt gut. Man sollte nur nicht an der Hardware sparen. ;)

      Je nach Datenbanksystem dauert das halt lange - oder eben nicht.
      Einen ordentlichen Oracle Datenbankserver kannst du damit selbst bei einer Milliarde Einträgen nicht hinterm Ofen hervorlocken - zumal du der auch nett Funktionen auf Datenbankebene hinterlegen kannst.
      Da läuft ein simples

      Quellcode

      1. select topTenGeodataForLocation(latitude,longitude,altitude);

      Und wer so richtig richtig gut mit Datenbankmanagementsystemen ist, der stellt sich ne IBM AS400 hin und macht schwarze Magie und Voodoo mit dem Teil.
      (auf 'meiner' hab ich ewig nix gemacht, fällt mir in dem Zusammenhang ein...)

      MySQL auf nem Webserver wird brauchen, da solltest du zusehen, dass die WebAPI einigermaßen klug und performant ist.
      Halt, Moment. Mit MySQL 5.1+ kannst du auch Prozeduren und Funktionen anlegen. Das wird dir Arbeit ersparen.

      Generell: je mehr das DBMS für dich erledigen kann, desto schneller und performanter ist das.
      Wenn du ein bisschen bei OpenStreetMap nachschaust und dort mit den richtigen Leuten kommunizierst bekommst du vielleicht ein paar wertvolle Tipps und Hinweise.
      Die Datenbank ist als OSM Datendatei schlappe 22GB groß und verhältnismäßig performant, die haben das also richtig gemacht. ^^
      «Applejack» "Don't you use your fancy mathematics to muddle the issue!"

      Iä-86! Iä-64! Awavauatsh fthagn!

      kmr schrieb:

      Ach, Du bist auch so ein leichtgläubiger Zeitgenosse, der alles glaubt, was irgendwelche Typen vor sich hin brabbeln. :-P
    • Du kannst das direkt in die Query reinschreiben, etwa so:

      SQL-Abfrage

      1. SELECT * FROM locations ORDER BY (lat-wantLat)*(lat-wantLat)+(lon-wantLon)*(lon-wantLon) LIMIT 1;

      Dabei natürlich Namen etc. der Anfrage anpassen und wantLat und wantLon durch den gewünschten Referenzpunkt ersetzen. Für die reine Sortierung kannst Du die Wurzel weglassen, kommt das gleiche raus. Eventuell kann man den Suchbereich noch per WHERE o.ä. eingrenzen.
      Multigrad - 360°-Produktfotografie für den Mac
    • mattik schrieb:

      Du kannst das direkt in die Query reinschreiben, etwa so:

      SQL-Abfrage

      1. SELECT * FROM locations ORDER BY (lat-wantLat)*(lat-wantLat)+(lon-wantLon)*(lon-wantLon) LIMIT 1;

      Dabei natürlich Namen etc. der Anfrage anpassen und wantLat und wantLon durch den gewünschten Referenzpunkt ersetzen. Für die reine Sortierung kannst Du die Wurzel weglassen, kommt das gleiche raus. Eventuell kann man den Suchbereich noch per WHERE o.ä. eingrenzen.


      im prinzip sollte man sich doch auch die multiplikation sparen können und einfach ein ABS verwenden oder nicht?
    • Thallius schrieb:

      Entfernung=sqrt( (latitudedb-latitudeApp)^2 + (longitudedb-longitudeApp)^2) (eigentlich viel komplexer siehe: kompf.de/gps/distcalc.html aber für hier reicht es erstmal)

      Der Pythagoras in der euklidischen Ebene wird aber dafür sehr schnell sehr ungenau, da Du nicht mit Abständen sondern mit Winkeln rechnest.

      In Postgres habe ich mir dafür eine Funktion geschrieben, die die Entfernung berechnet:

      Quellcode

      1. CREATE OR REPLACE FUNCTION geographical_distance(in_from POINT, in_to POINT) RETURNS DOUBLE PRECISION AS $_$
      2. BEGIN
      3. RETURN 6378.137 * ACOS(SIN(RADIANS(in_from[0])) * SIN(RADIANS(in_to[0])) + COS(RADIANS(in_from[0])) * COS(RADIANS(in_to[0])) * COS(RADIANS(in_from[1] - in_to[1])));
      4. END;
      5. $_$ LANGUAGE 'plpgsql' STABLE;

      die kannst Du auch in WHERE-Klauseln benutzen. Alternativ gibt's auch noch OpenGIS. Das lässt sich bei einigen Datenbanken nach installieren und stellt Geofunktionen bereit.
      „Meine Komplikation hatte eine Komplikation.“
    • gritsch schrieb:

      im prinzip sollte man sich doch auch die multiplikation sparen können und einfach ein ABS verwenden oder nicht?

      Dann hast Du die Manhattan-Metrik (knapp gesagt: Du suchst in einem Quadrat statt in einem Kreis, weil die Diagonalen anders bewertet werden). Die Ergebnisse werden etwas anders, aber wenn man schon mit der Metrik herumpfuscht könnte man das auch so machen. Oder gleich so wie Macmoonshine schreibt.
      Multigrad - 360°-Produktfotografie für den Mac
    • Hi,

      erstmal danke an alle für die rege produktive Teilnahme :)

      @Lukas, Höhe werde ich natürlich mit speichern so wie einige andere wichtige Parameter wie Startbare Windrichtungen und Linzenzbeschränkungen etc. Die sind aber für die Berechnung nicht relevant.

      @Mattik,Gritsch Das man das so einfach in den Query schreiben kann war mir neu. Das werde ich dann einfach mal so machen.

      @Mac Ich schrieb ja bereits das es eigentlich viel komplexer ist. Da ich aber eh nur Orte innerhalb des nächsten Kilometers suche, denke ich kann ich mit dem einfachen Pythagoras ganz gut leben.

      Danke

      Claus
      2 Stunden Try & Error erspart 10 Minuten Handbuchlesen.

      Pre-Kaffee-Posts sind mit Vorsicht zu geniessen :)