Joah.: "NEAREST" Funktion

hallo Leute,

ich bin gerade dabei über eine Flash-Grafik von Baden-Württemberg, die x/y Punktkoordinaten zu bestimmen und an ein PHP Script weiterzugeben. Im PHP Script möchte ich nun über ein SQL Statement den naheliegendsten Ort, sprich an dem der Breiten- UND Längengrad am nächsten an meinen Parametern ist ermitteln.

In den Klammern stehen folgende Daten:

  • an erster Stelle: der Startbreiten- bzw. -längengrad,
  • an zweiter Stelle: der x bzw. y-Pixel Parameter
  • und an der dritten Stelle: das Verhältnis Längengrade/Pixel

SQL:

SELECT
(47.5785313+60*0.00524676) AS eingabeBreite,
(6.9237+125*0.00741005) AS eingabeLaenge,
name, breite, laenge, plz
FROM plzTabelle
WHERE
breite>(47.5785313+60*0.00524676) AND
laenge>(6.9237+125*0.00741005)
ORDER BY breite, laenge LIMIT 1;

+---------------+---------------+--------------+--------+--------+--------+
| eingabeBreite | eingabeLaenge | name         | breite | laenge | plz    |
+---------------+---------------+--------------+--------+--------+--------+
|   47.89333690 |    7.84995625 | Hinterzarten |   47.9 |    8.1 | 79856  |
+---------------+---------------+--------------+--------+--------+--------+

Die Werte sind ja eigentlich relativ nah an meinem gewünschten Ergebnis, doch sollte er nicht Hinterzarten sondern Freiburg liefern. Hat jemand eine Idee, wie ich das SQL Statement umbauen kann? Gibt es alternativ vielleicht eine einfachere Möglichkeit?

Freiburg hat beispielsweise folgende Koordinaten:
Breitengrad 48 , Längengrad 7,85

Vielen Dank für eure Hilfe.

Joah.

  1. Hallo,

    du solltest mit dem Satz des Pythagoras arbeiten und so den Abstand zu einem gegebenen Punkt ermitteln.

    Und im SQL dann entsprechend ein oberes Limit setzen.

    cu,
    Michael

    1. Hallo,

      du solltest mit dem Satz des Pythagoras arbeiten und so den Abstand zu einem gegebenen Punkt ermitteln.

      Und im SQL dann entsprechend ein oberes Limit setzen.

      cu,
      Michael

      Hi Michael,

      ich glaube du hast mein Problem nicht verstanden oder ich habe deinen Lösungsansatz nicht verstanden. Ich komme ja an den Punkt ran, es geht eigentlich um die doppelte Sortierung nach 2 versch. Kriterien eben laenge und breite. Dazu kommt dann dass ich mit der > ".." nur Punkte finde die größer sind, und keine die kleiner sind.

      Gruß
      Joah.

      1. Hallo,

        Hallo,

        du solltest mit dem Satz des Pythagoras arbeiten und so den Abstand zu einem gegebenen Punkt ermitteln.

        Und im SQL dann entsprechend ein oberes Limit setzen.

        cu,
        Michael

        Hi Michael,

        ich glaube du hast mein Problem nicht verstanden oder ich habe deinen Lösungsansatz nicht verstanden. Ich komme ja an den Punkt ran, es geht eigentlich um die doppelte Sortierung nach 2 versch. Kriterien eben laenge und breite. Dazu kommt dann dass ich mit der > ".." nur Punkte finde die größer sind, und keine die kleiner sind.

        Ich habe dich so verstanden, dass du den naheliegendsten Ort zu einem gegebenen Punkt x1/y1 suchst und das macht man nun mal über den Abstand.

        Ich weiss, das man das hier schön "setzen" kann, habe mich aber noch nicht damit beschäftigt:
        abstand = Wurzel ( delta(Längengrad)² + delta(Breitengrad)² )

        Den nächsten Punkt(Ort) bekommst du über SQL: MIN(abstand).
        Umliegende Ergebnisse mit SQL: WHERE abstand < $xy

        Den Abstand muß du in dem SQL-Query zu jedem Ort berechnen(aufwändig):

        Setze bitte im folgenden die gültige SQL-Syntax deiner DB ein:
        Select c.name, SQRT((c.laengengrad-$x1)^2-(c.breitengrad-$y1)^2) as abstand
        from city as c
        where abstand < $irgendwas

        oder eben: Select c.name, MIN(SQRT((c.laengengrad-$x1)^2-(c.breitengrad-$y1)^2)) as abstand ...

        cu,
        Michael

        1. Vielen Dank für deine Hilfe,

          ich habs inzwischen kapiert, funktioniert auch soweit.

          SELECT
          (47.5785313+60*0.00524676) AS eingabeBreite,
          (6.9237+125*0.00741005) AS eingabeLaenge,
          name, breite, laenge, plz
          ,sqrt(POW(breite-(47.5785313+60*0.00524676),2) + POW(laenge-(6.9237+125*0.00741005),2)) as entfernung
          FROM plz
          WHERE
          breite>(47.5785313+60*0.00524676) AND
          laenge>(6.9237+125*0.00741005)

          ORDER BY entfernung LIMIT 1

          Jetzt findet er korrekt, jedoch nicht ganz korrekt. Weil er ja als nächsten Ort nur Orte findet, die größer sind als die Längen- und Breitengrade.Dabei ist mir aufgefallen, dass ich die WHERE Clause komplett streichen kann.

          Gruß
          Joah.

          1. Hallo,

            Vielen Dank für deine Hilfe,

            gern geschehen. :-)

            Jetzt findet er korrekt, jedoch nicht ganz korrekt. Weil er ja als nächsten Ort nur Orte findet, die größer sind als die Längen- und Breitengrade.Dabei ist mir aufgefallen, dass ich die WHERE Clause komplett streichen kann.

            Genau so ist es. Ich hatte sie auch deshalb nicht erwähnt, denn die Entfernung beinhaltet diese Werte ja bereits.

            cu,
            Michael

        2. Hallo,

          Zu sagen wäre, dass Dein Vorschlag nur funktioniert, wenn die Orte nicht sehr weit auseinander liegen, insbesondere, wenn alle innerhalb von z.B. nördlicher Breite und östlicher Länge bleiben. Orte innerhalb von Deutschland sollten kein Problem sein, solche westlich des Nullmeridians dagegen schon und auch Orte südlich des Äquators.

          Ich weiss, das man das hier schön "setzen" kann, habe mich aber noch nicht damit beschäftigt:
          abstand = Wurzel ( delta(Längengrad)² + delta(Breitengrad)² )

          Wenn es nur auf die Suche nach dem kleinsten Abstand ankommt, kann man auch die Abstandsquadrate vergleichen. Das erspart das Radizieren.

          |       |
               |       |
               |       |
               |       |
          -----*P(x,y) |
                 \     |
                  \    |
                   a   |
                    \  |
                     \ |
                      |
          -------------*Pe(xe,ye)

          Pe(xe,ye) ist der eingegebene Punkt.

          Suche für alle Punkte P(x,y) das a²:

          a² = (xe-x)² + (ye-y)²

          Der nächste Punkt ist der mit dem kleinsten a².

          viele Grüße

          Axel