Hallo Leute!
Irgendwie habe ich jetzt eine Denkfehler und komme nicht weiter...
Also, sagen wir, dass ich eine Tabelle "airports" habe, mit u.a. die Koordinaten (Latitude und Longitude) der Flugplätzen. Ich will den nächstgelegen Flugplatz einem Punkt suchen, von dem ich ebenso die Koordinaten habe.
Mir ist klar, dass um richtig genau zu sein, die Datenbank Funktionen enthalten muss, die die Entfernung zwischen zwei Punkte berechnen, und das haben die meisten DB-Engines nicht. Sicherlich nicht SQLite auf Android...
Aber für meine Zwecke würde es reichen, wenn ich den Flugplatz finde, bei dem die Differenz zwischen den eigenen Koordinaten und den Punktkoordinaten am kleinsten ist.
Irgendwie komme ich aber nicht klar...
Mit dieser Anfrage hole ich die Flugplatzdaten zusammen mit den Koordinatendifferenzen:
SELECT *, ABS(latitude - 51.04952025) AS latdiff, ABS(longitude - 13.68193347) AS lngdiff FROM airports;
Nun will ich den Datensatz finden, bei dem latdiff = MIN(latdiff) und lngdiff = MIN(lngdiff). So wäre meine Anfrage:
SELECT *, ABS(latitude - 51.04952025) AS latdiff, ABS(longitude - 13.68193347) AS lngdiff FROM airports GROUP BY id HAVING latdiff = min(latdiff) AND lngdiff = min(lngdiff);
Aber das gibt mir völlig flasche Ergebnisse, denn die Koordinaten, die ich hier nutze, sind in Dresden Cotta und der Flughafen Aachen ist deutlich weiter als den Flughafen Dresden, von mir gesehen...
Kann jemand mir sagen, wo mein Denkfehler liegt?
Danke Luca Bertoncello (lucabert@lucabert.de)
Moin,
Am 03.10.22 um 14:13 schrieb Luca Bertoncello:
Hallo Leute!
Irgendwie habe ich jetzt eine Denkfehler und komme nicht weiter...
Also, sagen wir, dass ich eine Tabelle "airports" habe, mit u.a. die Koordinaten (Latitude und Longitude) der Flugplätzen. Ich will den nächstgelegen Flugplatz einem Punkt suchen, von dem ich ebenso die Koordinaten habe.
Dein 'Denkfehler' ist offensichtlich die Nicht-Nutzung von PostGIS, welches exakt dafür eine indexbasierte Umkreissuche besitzt.
https://postgis.net/workshops/postgis-intro/knn.html
Andreas
Am 04.10.2022 08:34, schrieb Andreas Kretschmer:
Moin!
Dein 'Denkfehler' ist offensichtlich die Nicht-Nutzung von PostGIS, welches exakt dafür eine indexbasierte Umkreissuche besitzt.
PostGIS kenne ich, natürlich, läuft aber nicht auf Android... Und was ich machen muss, muss auf Android mit SQLite laufen...
Grüße Luca Bertoncello (lucabert@lucabert.de)
Am 03.10.22 um 14:13 schrieb Luca Bertoncello:
Irgendwie habe ich jetzt eine Denkfehler und komme nicht weiter... [...] Mit dieser Anfrage hole ich die Flugplatzdaten zusammen mit den Koordinatendifferenzen:
SELECT *, ABS(latitude - 51.04952025) AS latdiff, ABS(longitude - 13.68193347) AS lngdiff FROM airports;
Nun will ich den Datensatz finden, bei dem latdiff = MIN(latdiff) und lngdiff = MIN(lngdiff).
Ähh, nein. Diesen Flughafen gibt es wahrscheinlich nicht. Du willst nicht den künstlichen Flughafen, der aus dem minimalen horizontalen und minimal vertikalen Abstand zu einem Bezugspunkt besteht (das sind nämlich aller Wahrscheinlichkeit nach zwei verschiedene Flughäfen!), sondern den, bei dem die Summe der Quadrate beider Werte am kleinsten ist (Pythagoras, Hypotenuse und so).¹
So wäre meine Anfrage:
SELECT *, ABS(latitude - 51.04952025) AS latdiff, ABS(longitude - 13.68193347) AS lngdiff FROM airports GROUP BY id HAVING latdiff = min(latdiff) AND lngdiff = min(lngdiff);
Aber das gibt mir völlig flasche Ergebnisse, denn die Koordinaten, die ich hier nutze, sind in Dresden Cotta und der Flughafen Aachen ist deutlich weiter als den Flughafen Dresden, von mir gesehen...
Kann jemand mir sagen, wo mein Denkfehler liegt?
Mein SQL ist schon arg eingerostet, aber eventuell das (ungetestet!):
SELECT *, latitude - 51.04952025 AS latdiff, longitude - 13.68193347 AS lngdiff FROM airports ORDER BY latdiff*latdiff + lngdiff*lngdiff LIMIT 1;
Durch die Multiplikation können wir uns auch das ABS() sparen.
Viele Grüße, Mathias
¹ Ja, ich ignoriere wohl wissend, dass die Erde rund^Wbuckelig ist :P
Am 04.10.2022 09:32, schrieb Mathias Krause:
Hallo Mathias,
Ähh, nein. Diesen Flughafen gibt es wahrscheinlich nicht. Du willst nicht den künstlichen Flughafen, der aus dem minimalen horizontalen und minimal vertikalen Abstand zu einem Bezugspunkt besteht (das sind nämlich aller Wahrscheinlichkeit nach zwei verschiedene Flughäfen!), sondern den, bei dem die Summe der Quadrate beider Werte am kleinsten ist (Pythagoras, Hypotenuse und so).¹
Ach! Das war der Denkfehler! Ich probieren heute Abend...
Mein SQL ist schon arg eingerostet, aber eventuell das (ungetestet!):
SELECT *, latitude - 51.04952025 AS latdiff, longitude - 13.68193347 AS lngdiff FROM airports ORDER BY latdiff*latdiff + lngdiff*lngdiff LIMIT 1;
Durch die Multiplikation können wir uns auch das ABS() sparen.
Danke sehr!
¹ Ja, ich ignoriere wohl wissend, dass die Erde rund^Wbuckelig ist :P
Jup, es ist ein Geoid... Und ein Geoid ist, laut Definition, die Form der Erde... Ja, etwas rekursiv... Aber für meine Zwecke reicht die einfache Berechnung zu!
Danke Luca Bertoncello (lucabert@lucabert.de)
On Mon, Oct 3, 2022 at 2:35 PM Luca Bertoncello lucabert@lucabert.de wrote:
Hallo Leute!
Irgendwie habe ich jetzt eine Denkfehler und komme nicht weiter...
Also, sagen wir, dass ich eine Tabelle "airports" habe, mit u.a. die Koordinaten (Latitude und Longitude) der Flugplätzen. Ich will den nächstgelegen Flugplatz einem Punkt suchen, von dem ich ebenso die Koordinaten habe.
Mir ist klar, dass um richtig genau zu sein, die Datenbank Funktionen enthalten muss, die die Entfernung zwischen zwei Punkte berechnen, und das haben die meisten DB-Engines nicht. Sicherlich nicht SQLite auf Android...
Aber für meine Zwecke würde es reichen, wenn ich den Flugplatz finde, bei dem die Differenz zwischen den eigenen Koordinaten und den Punktkoordinaten am kleinsten ist.
Irgendwie komme ich aber nicht klar...
Mit dieser Anfrage hole ich die Flugplatzdaten zusammen mit den Koordinatendifferenzen:
SELECT *, ABS(latitude - 51.04952025) AS latdiff, ABS(longitude - 13.68193347) AS lngdiff FROM airports;
Nun will ich den Datensatz finden, bei dem latdiff = MIN(latdiff) und lngdiff = MIN(lngdiff). So wäre meine Anfrage:
SELECT *, ABS(latitude - 51.04952025) AS latdiff, ABS(longitude - 13.68193347) AS lngdiff FROM airports GROUP BY id HAVING latdiff = min(latdiff) AND lngdiff = min(lngdiff);
Aber das gibt mir völlig flasche Ergebnisse, denn die Koordinaten, die ich hier nutze, sind in Dresden Cotta und der Flughafen Aachen ist deutlich weiter als den Flughafen Dresden, von mir gesehen...
Kann jemand mir sagen, wo mein Denkfehler liegt?
Schau mal, vielleicht hilft dir das hier: https://git.osuv.de/m/dotfiles/src/branch/master/mariadb/distance.sql https://git.osuv.de/m/dotfiles/src/branch/master/mariadb/deg2rad.sql
Ob sqlite auch funktionen kann wie mariadb etc, ...keine ahnung.
Danke Luca Bertoncello (lucabert@lucabert.de)
Hi,
Nun will ich den Datensatz finden, bei dem latdiff = MIN(latdiff) und lngdiff = MIN(lngdiff).
[..]
ich hier nutze, sind in Dresden Cotta und der Flughafen Aachen ist deutlich weiter als den Flughafen Dresden, von mir gesehen...
Der Fehler mit MIN(). Richtung Aachen ist fast genau nach Westen: http://www.gcmap.com/mapui?P=DRS-AAH Wenn du das Land schon näherungsweise als eine Ebene behandelst, dann nimm Pythagoras! sqrt( latdiff * latdiff + lngdiff * lngdiff) und davon das Minimum.
Und sonst: SpatiaLite.
Andreas
lug-dd@mailman.schlittermann.de