Dieter: Kuriose Umkreissuche

Hallo,

wenn ich einmal davon ausgehe, das ich nicht einem grundsätzlichem Verständnisproblem aufgesessen bin und meine Mathematik-Kenntnisse nicht ganz falsch sind.... ....komme ich mit meiner Umkreissuche trotzdem nicht weiter. Mit dem nachfolgendem Code versuche ich eine Umkreissuche zu realisieren:


function getlatlang($location) {
	$geocode = file_get_contents('http://maps.google.com/maps/api/geocode/json?address='. urlencode($location) .'&sensor=false');
    $output= json_decode($geocode);
    return $output->results[0]->geometry->location;
}

if($search_Location!='') {
	$objlocation = getlatlang($search_Location);
	$latitude = $objlocation->lat;
	$longitude = $objlocation->lng;

	
	$range = $search_Distance;
	if($latitude != "" && $longitude != "") {
		$lat_range = $range/69.172;
		$lon_range = abs($range/(cos($latitude) * 69.172));
		$min_lat = number_format($latitude - $lat_range, "4", ".", "");
		$max_lat = number_format($latitude + $lat_range, "4", ".", "");
		$min_lon = number_format($longitude - $lon_range, "4", ".", "");
		$max_lon = number_format($longitude + $lon_range, "4", ".", "");
		$zusatzqu.=" AND (poslat BETWEEN '".$min_lat."' AND '".$max_lat."' AND poslon BETWEEN '".$min_lon."' AND '".$max_lon."')";
	}
}

Kurz zur Defination:

  • $search_Location enthält den Ort oder PLZ des Standortes.
  • $search_Distance ist der Radius für die Umkreissuche in km In de Datenbank stehen die DS mit Angaben deren Standorte (poslat/poslon). Die Grundquery wird um die $zusatzqu erweitert. So weit, so gut.

Jetzt kommt mein Problem (manch einer wird jetzt wohl "endlich" sagen): Die Umkreissuche funktioniert "manchmal", nämlich je nach Wert des Radius. Bleibe ich unter 100km funktioniert sie immer, zwischen 150-450 km gar nicht und darüber kommen wieder Ergebnisse (aber soweit ich sehen kann, nicht alle).

Konkrete Ausgaben der jw. Query ergaben offensichtlich "richtige" Min- bzw. Max-Werte aber trotzdem liefert die Abfrage null Ergebnisse.

Da ich mit meinem Latein ziemlich am Ende bin hoffe ich auf eure Hilfe. (Vielleicht habe ich da doch ein Denkfehler....)

Gruss Dieter

  1. Hi,

    wenn ich einmal davon ausgehe, das ich nicht einem grundsätzlichem Verständnisproblem aufgesessen bin und meine Mathematik-Kenntnisse nicht ganz falsch sind....

    das wäre noch zu hinterfragen. ;-)

    function getlatlang($location) {
    
    > 	$geocode = file_get_contents('http://maps.google.com/maps/api/geocode/json?address='. urlencode($location) .'&sensor=false');
    >     $output= json_decode($geocode);
    >     return $output->results[0]->geometry->location;
    > }
    > 
    > if($search_Location!='') {
    > 	$objlocation = getlatlang($search_Location);
    > 	$latitude = $objlocation->lat;
    > 	$longitude = $objlocation->lng;
    > 
    > 	
    > 	$range = $search_Distance;
    > 	if($latitude != "" && $longitude != "") {
    > 		$lat_range = $range/69.172;
    > 		$lon_range = abs($range/(cos($latitude) * 69.172));
    > 		$min_lat = number_format($latitude - $lat_range, "4", ".", "");
    > 		$max_lat = number_format($latitude + $lat_range, "4", ".", "");
    > 		$min_lon = number_format($longitude - $lon_range, "4", ".", "");
    > 		$max_lon = number_format($longitude + $lon_range, "4", ".", "");
    > 		$zusatzqu.=" AND (poslat BETWEEN '".$min_lat."' AND '".$max_lat."' AND poslon BETWEEN '".$min_lon."' AND '".$max_lon."')";
    > 	}
    > }
    
    

    Wofür  steht in diesem Codeauszug die magische Konstante 69.172? Abgesehen davon sieht dein Algorithmus os aus, als funktioniere er nur für bestimmte geographische Breiten. Für polnahe Bereiche jedenfalls nicht. Aber das ist vermutlich eine Einschränkung, die man in Kauf nehmen kann.

    Und trotzdem schreit deine Berechnung noch nach einer Erklärung.

    So long,  Martin

    --
    Es gibt Dinge, die sind sooo falsch, dass nicht einmal das Gegenteil stimmt. Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. Moin,

      Wofür  steht in diesem Codeauszug die magische Konstante 69.172?

      Auch wenn der Algo nicht direkt und komplett von mir ist.....

      Die magische CONST stammt aus meiner Faulheit (das ich sie noch nicht auf km umsetzt habe) und der eigentlichen Meinung das: 1 Latitude = 69.172 Meilen sind und 1 Longitude = cos(latitude)*69.172 sind.

      Oder habe ich das HIER falsch verstanden?

      Gibt es denn eines bessere Lösung?

      Gruss Dieter

      1. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

        ja!

        Die magische CONST stammt aus meiner Faulheit (das ich sie noch nicht auf km umsetzt habe) und der eigentlichen Meinung das: 1 Latitude = 69.172 Meilen sind und 1 Longitude = cos(latitude)*69.172 sind.

        BTW:

        Da der Abstand zweier Punkte auf einem Breitengrad zweier Längengrade vom Breitengrad abhängig ist, stimmt das ohnehin nur für kleine Distanzen.

        Es ist im Sinne der Abfragegeschwindigkeit allerdings schneller, wenn man zuerst nur die Treffer für ein (sphärisches) "Rechteck" aus der Datenbank ausliest (da sind dann nämlich nur simple Vergleiche notwendig) und erst anschließend berechnet, ob die (wenigen) Treffer der ersten Menge tatsächlich auch in den Um-KREIS gehören. Das Ganze funktioniert (bei MySQL) inzwischen  mit Subselect.

        Spirituelle Grüße Euer Robert

        --
        Möge der Forumsgeist wiederbelebt werden!
  2. Hi,

    $latitude = $objlocation->lat; $longitude = $objlocation->lng;

    in welcher Form liegen diese Werte vor? Grad oder Bogenmaß?

      $lat_range = $range/69.172;
    

    Was ist das für ein magischer Wert?

    cu, Andreas

    --
    Warum nennt sich Andreas hier MudGuard? O o ostern ... Fachfragen per Mail sind frech, werden ignoriert. Das Forum existiert.
  3. Hallo,

    mögliche Fehlerquellen, die ich sehe:

      $lat_range = $range/69.172;
    

    arbeitest du nun in Meilen oder in Km, wo rechnest du um?

      $lon_range = abs($range/(cos($latitude) * 69.172));
    

    PHP erwartet Bogenmaß, womit arbeitest du?

      $zusatzqu.=" AND (poslat BETWEEN '".$min_lat."' AND '".$max_lat."' AND poslon BETWEEN '".$min_lon."' AND '".$max_lon."')";
    

    fehlen hier Klammern?

    • $search_Distance ist der Radius für die Umkreissuche in km

    s.o.

    In de Datenbank stehen die DS mit Angaben deren Standorte (poslat/poslon). Die Grundquery wird um die $zusatzqu erweitert. So weit, so gut.

    was heißt DS?

    Bleibe ich unter 100km funktioniert sie immer, zwischen 150-450 km gar nicht und darüber kommen wieder Ergebnisse (aber soweit ich sehen kann, nicht alle).

    mir fällt auf, dass 69.172 * 2 ungefähr (bis sehr grob) 150 ergibt. Ist sicher nur Zufall.

    Konkrete Ausgaben der jw. Query ergaben offensichtlich "richtige" Min- bzw. Max-Werte aber trotzdem liefert die Abfrage null Ergebnisse.

    Beispiele?

    Gruß Kalk

  4. Hallo,

    	
    
    > 	$range = $search_Distance;
    > 	if($latitude != "" && $longitude != "") {
    > 		$lat_range = $range/69.172;
    
                                 ^^^^^^^^^^^^^^
    Hier rechnest Du Meilen in Grad um - OK.
    
    
    > 		$lon_range = abs($range/(cos($latitude) * 69.172));
    
                                             ^^^^^^^^^^^^^^^^^^^^^^^^
    Und hier rechnest Du eine Gradangabe wieder in Meilen um, willst aber eigentlich in Grad weiterrechnen!!!!
    
    
    > 		$min_lat = number_format($latitude - $lat_range, "4", ".", "");
    > 		$max_lat = number_format($latitude + $lat_range, "4", ".", "");
    > 		$min_lon = number_format($longitude - $lon_range, "4", ".", "");
    > 		$max_lon = number_format($longitude + $lon_range, "4", ".", "");
    > 		$zusatzqu.=" AND (poslat BETWEEN '".$min_lat."' AND '".$max_lat."' AND poslon BETWEEN '".$min_lon."' AND '".$max_lon."')";
    > 	}
    > }
    > 
    
    

    gruß peter

    1.   $lat_range = $range/69.172;
      

      ^^^^^^^^^^^^^^ Hier rechnest Du Meilen in Grad um - OK.

        $lon_range = abs($range/(cos($latitude) * 69.172));
      

      ^^^^^^^^^^^^^^^^^^^^^^^^ Und hier rechnest Du eine Gradangabe wieder in Meilen um, willst aber eigentlich in Grad weiterrechnen!!!!

      Sorry, das war wohl Quatsch. hatte da irgendwie nen Knick in der Optik.

      gruß  peter

    2. Hi,

      	$range = $search_Distance;
      
      > > 	if($latitude != "" && $longitude != "") {
      > > 		$lat_range = $range/69.172;
      
      

      ^^^^^^^^^^^^^^ Hier rechnest Du Meilen in Grad um - OK.

      nein, nicht OK. Mit dem Gradmaß fängt man bei Berechnungen nichts an. Benötigt wird stattdessen das Bogenmaß.

      Ciao,  Martin

      --
      Was du heute kannst besorgen, das geht sicher auch noch morgen. Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
  5. Tach!

    Da ich mit meinem Latein ziemlich am Ende bin hoffe ich auf eure Hilfe. (Vielleicht habe ich da doch ein Denkfehler....)

    Wo ist denn die konkrete Stelle, an der etwas anderes entsteht, als du dir vorgestellt hast? Wenn du den Verdacht hast, dass bei deinem Supermarkteinkauf die Abrechnung nicht stimmt, was machst du da? Ich nehme an, du gehst den Kassenzettel Zeile für Zeile durch und vergleichst mit dem was du aus deinen Einkaufstaschen holst. Genauso zeitaufwendig ist leider auch die Fehlersuche in Programmen. Vielleicht sieht ja einer einen offensichtlichen Fehler, den du betriebsblinderweise nicht erkennst. Aber wenn der Fehler sich versteckt, musst du etwas genauer werden. Also welche ist die Zeile, die ein abweichendes Ergebnis bringt?

    dedlfix.