Umkreis um eine Koordinate berechnen und alle Koordinaten in DB suchen

Hallo Gonzzo,

ja aber an der Distanzüberprüfung scheitert es noch das habe ich nicht kapiert wie ich das machen soll - ausserdem soll ich ja dann jeweils den nächsten Ort ausgeben.

Wäre echt nett von dir wenn du mir das nochmals (für Doofe :suspekt: ) erklären würdest.

Also im Konkreten möchte ich einfach mal von folgenden Gegebenheiten ausgehen.

Ort 1 = Breite 48.45 und Länge 12.35
Ort 2 = Breite 48.3667 und Länge 12.25

Wie errechne ich jetzt die Entfernung in Km - ich weis das das irgendwie mit cos und sin und evtl. acos funktioniert aber wie ist bisher nicht zu mir durchgedrungen.

Ausserdem habe ich mir jetzt mal was gebastelt:
PHP:
$ursprungsbreite = 48.45;
$ursprungslaenge = 12.35;
$ursprungsbreite1 = 48.3667;
$ursprungslaenge1 = 12.25;

$e = (($ursprungsbreite1-$ursprungsbreite)+($ursprungslaenge-$ursprungslaenge1))*1000;
könnte es sein, das ich jetzt die Entfernung in Km bekomme? Nur eine (wahrscheinlich dumme) Vermutung. Das würde nämlich genau passen. Wenn ich das aber mit einer Koordinate weiter weg mache wo ich auch die ungefähren Km weiss klappt es nicht - also ist meine Vermutung nicht richtig
 
Zuletzt bearbeitet:
Hallo Leute,

ich bin jetzt selber auf die Lösung gekommen.
Nach ein bischen suchen und graue Zellen anstrengen.

Hier der Code wie ich es momentan gelöst habe:
PHP:
@mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_PASS) OR die("Keine Verbindung zur Datenbank.<br>Fehlermeldung: ".mysql_error());
@mysql_select_db(MYSQL_DATABASE) OR die("Konnte Datenbank nicht benutzen.<br>Fehlermeldung: ".mysql_error());

// Koordinaten des Ortes
$ort = "Velden";
$ursprungsbreite = 48.3667;
$ursprungslaenge = 12.25;

$entf = 40; // max. Km-Entfernung von Startort
echo "Folgende grössere Orte liegen im Radius von $entf km um $ort:<br><br>";

$alpha = 180*$entf/(6378137/1000*3.14159);

$geo1 = $ursprungsbreite-$alpha;
$geo2 = $ursprungsbreite+$alpha;
$geo3 = $ursprungslaenge-$alpha;
$geo4 = $ursprungslaenge+$alpha;


$abfrage = mysql_query("SELECT * FROM `$tabelle` WHERE (`breite` >= '$geo1') AND (`breite` <= '$geo2') AND (`laenge` >= '$geo3') AND (`laenge` <= '$geo4')");


$a = $ursprungsbreite/180*3.14159;
$b = $ursprungslaenge/180*3.14159;

$z = 1;

while($ds = mysql_fetch_assoc($abfrage)) {

$c = $ds['breite'];
$d = $ds['laenge'];
$c = $c/180*3.14159;
$d = $d/180*3.14159;

$e = sin($a)*sin($c);
$f = cos($a)*cos($c)*cos($d-$b);
$g = acos($e + $f);
$h = $g * 6378.137;
$ausgabe = sprintf("%01.2f", $h);
if($ausgabe > $entf) {
		continue;
	}
$ausgabe = str_replace(".", ",", $ausgabe);

echo "$z - Nach ".$ds['name_int']." sind es $ausgabe km.<br>";
$z++;
}
 
Hi dwex,

Glückwunsch, war doch eigentlich garnet so schwer, oder? Aber am Anfang stan dich auch erst mal so da :confused: . Hatte gestern leider keine Zeit mehr zum posten.
Hast du die Formel von www.koordinaten.de ?
Ich habe die Entfernungsberechnung wie gesagt über ein kartesisches Koordinatensystem durchgeführt, wie es mamphil vorgeschlagen hat, aber ich werd es auch noch mit dieser Funktion probieren, weil ich mit der Laufzeit bei großen Umkreisen noch etwas unzufrieden bin und ich stark annehme, dass die andere Lösung weniger rechenintensiv ist.
Ich werd dich auf dem Laufenden halten.
Viel Erfolg weiterhin.

MfG
Dr Gonzzo
 
Hi dwex,

hab die Algorithmen jetzt mal gegeneinander getestet und war erst mal :suspekt:
Ich habe wie gesagt schon vermutet, dass die direkte Abstandsberechnung schneller ist als der Umweg über die kartesischen Koordinaten, aber das Ergebnis ist schon :eek:

  • a1(50) = 7 sec
    a2(50) = 0 sec
  • a1(100) = 25 sec
    a2(100) = 0 sec
  • a1(200) = 106 sec
    a2(200) = 1 sec
  • a1(400) = 260 sec
    a2(400) = 2 sec
  • a1(1000) = 432 sec
    a2(1000) = 3 sec
a1 ist der alte Algorithmus mit den kartesischen Koordinaten
a2 ist der neue mit direkter Abstandsberechnung
Der Wert in Klammern ist der zu durchsuchende Umkreis.
Tja, ich glaub' ich muss nicht mehr dazu sagen, welche der beiden Lösungen ich jetzt verwenden werde... :)

Bis denne
Dr. Gonzzo
 
Holla,

dann ist ja meine Lösung SUPER!

Was ich aber noch nicht kapiert habe ist das mit dem Viereck und dem Kreis um die Startkoordinate - momentan rechne ich ja das Viereck aus und nicht den Kreis.
Ausserdem ist mir aufgefallen, dass wenn ein Ort sagen wir mal er ist 31,7 km entfernt nicht aus der db gelesen wird wenn ich nach 35 km Umkreis suche. Wenn ich aber dann 40 km eingeben dann wird er gefunden. wenn ich dann über die einzelnen Koordinaten dann die Entfernungen ausrechne dann wird eben 31,7 km angezeigt.

Ich hoffe, dass war verständlich genug - wer hat eine Idee?
 
Hi dwex,

Kann das Problem nicht ganz nachvollziehen. Deine Abstandsberechnung sollte ja Stimmen, nehme ich jetzt mal an. Wenn er den Ort dann trotzdem nicht Anzeigt muss es demnach an deinem Vergleichsoperator liegen.
Was bewirkt der Befehl?
PHP:
$ausgabe = sprintf("%01.2f", $h);
.
$ausgabe ist ja deine Entfernung wenn ich recht verstehe. Damit müsste deine Abfrage
Code:
$ausgabe <= $entf
heißen und nicht
Code:
$ausgabe > $entf
Genau diese if- Abfrage macht aus deinem Quadrat einen Kreis (Bildlich gesehen).
Def. Kreis: Menge Aller Punkte, die genau den gleichen Abstand von einem gemeinsamen Ursprungspunkt besitzen.
Def. Scheibe: Menge Aller Punkte, die maximal den gleichen oder einen geringeren Abstand von einem gemeinsamen Ursprungspunkt besitzen.

  • $ausgabe = $entf (Kreis)
    Alle Punkte, die genau den gewünschten Abstand vom Ursprung haben. Liegen genau auf einem Kreisbogen um den Ursprung
  • $ausgabe < $entf (Scheibe)
    Alle Punkte innerhalb dieses Kreisbogens
  • $ausgabe > $entf (Quadrat mit ausgeschnittenem Innenkreis - die vier Ecken)
    Alle Punkte außerhalb dieses Kreisbogens

Schau dir deinen Code nochmal an. Liegt bestimmt an so ner Kleinigkeit

Dr. Gonzzo
 
Hi dwex,

ok, kann das Problem jetzt doch nachvollziehen. Ist bei mir ähnlich, habe es nur noch nicht bemerkt. Das Problem liegt meiner Meinung nach bei der Vorselektion, bzw. daran, dass es 180 Breitengrade und 360 Längengrade gibt. Probier mal
Code:
$geo1 = $ursprungsbreite-$alpha; 
$geo2 = $ursprungsbreite+$alpha; 
$geo3 = $ursprungslaenge-2*$alpha; 
$geo4 = $ursprungslaenge+2*$alpha;
Hat in meinem Fall geklappt

mfG
Dr. Gonzzo
 
Zuletzt bearbeitet:
Hi Gonnzo,

nein leider habe ich jetzt noch größere Ungenauigkeiten als vorher. Jetzt werden mir Orte welche über 50Km entfernt sind angezeigt. Das ganze habe ich mit einem Radius von 35Km probiert.

Edit: Zu deiner Frage was das sprintf mach - es kürzt mir meine Flieskommazahl (bei der Entfernungsberechnung) auf 2 Stellen hinter dem Komma.
 
Servus

Hääh, moment mal, von Ungenauigkeiten hast du bisher nichts geschrieben, sondern nur, dass dir Einträge bei der Abfrage "verloren" gehen. Meinst du mit ungenauigkeiten falsch berechnete Abstandswerte oder zu wenige/zu viele Treffer :confused:
Durch die erweiterung der Vorselektion solltest das andere Problem eigentlich machbar sein (hat bei mir zumindest geklappt)
Du hast doch nur bei den Längengraden den doppelten Winkel addiert bzw. subtrahiert. Nicht bei den Breitengraden
("Ok, im Prinzip ist es natürlich egal(s.u.), du könntest auch beides mit einem beliebigen Faktor multiplizieren um Sicherzustellen, dass deine Vorauswahl(die man ja wie gesagt nicht mal zwingend braucht) nicht zu eng ist").
Aber bei den Längengraden muss es sein, wenn meine Überlegungen nicht völliger Schwachsinn waren :)
Dadurch wird deine Vorselektion natürlich etwas größer (bei 35km Umkreis können durchaus Orte mit 50 km noch in der Vorauswahl vorkommen), die werden ja aber dann wieder durch deine Abstandsberechnung aussortiert.

Hoffe, es klappt
Dr. Gonzzo
 
Hallo,

ja das ist schon Richtig und die werden dann auch über die Abstandsberechnung aussortiert - nur kommt mir das doch sehr Spanisch vor - ich habe ein bischen getestet und festgestellt, dass wenn ich die Berechnung des Umkreises (also den KM-Wert - im Beispiel 35km) mit 1,45 Multipliziere dann klappt das ;)
 

Neue Beiträge

Zurück