How to: Umkreissuche mit Google Maps erstellen

Eine Umkreissuche ist mit ein klein wenig PHP, MySQL und Javascript schnell umgesetzt.

Für die Berechnung der Orte in der Nähe selbst, ist eigentlich nur ein wenig MySQL erforderlich.

  • Wir möchten zusätzlich die Position des Benutzers auslesen.
  • Mithilfe eines Formulars soll die Position von Hand festlegt und der Suchradius geändert werden können.
  • Die Suchergebnisse mit der Entfernung zur aktuellen Position sollen ohne erneuten Seitenaufruf dargestellt werden.

Für unser Beispiel brauchen wir:

  • Ein PHP-Skript, das die Berechnung der Orte in der Nähe übernimmt.
  • Eine Datenbank mit Angaben zu Längen- und Breitengraden der zu durchsuchenden Datensätze.
  • Eine HTML-Seite mit jQuery und der Google Maps API.

Das Auslesen des Längen- und Breitengrades der aktuellen Position mit Javascript funktioniert wie folgt:

navigator.geolocation.getCurrentPosition(setgeoLoc);

function setgeoLoc(position) {
  lat = parseFloat(position.coords.latitude);
  lng = parseFloat(position.coords.longitude);
}

Das HTML Grundgerüst:

</pre>
<div class="address"></div>
<div class="position">
<select>
<option>5000m</option>
<option>100000m</option>
</select>

 <input type="text" name="address" />
 <input type="hidden" name="lat" value="" />
 <input type="hidden" name="lng" value="" />
 <a class="saveadd" href="#">Speichern</a>
 <a class="reset" href="#">Position zurücksetzen</a></div>
<div class="userdata"></div>
<pre>

Als nächstes definieren wir mittels jQuery, Aktionen die bei bestimmten User-Interaktionen durchgeführt werden sollen.

$(document).ready(function () {

# Wenn das Dokument geladen ist, wird die Position des Users ermitteln
# und an die Funktion setgeoLoc übergeben

	navigator.geolocation.getCurrentPosition(setgeoLoc);

# Wenn sich der Suchradius ändert, wird eine Suchanfrage gesendet

	$('#distance').bind('change', function(){
		lat = $('input[name="lat"]').val();
		lng = $('input[name="lng"]').val();
		getdata(lat, lng);
	});

# Wenn der "Speichern"-Link geklickt wird, werden die eingegebenen
# Adressdaten an eine Funktion übergeben, die Längen- und Breitengrad
# ermitteln soll

	$('.saveadd').bind('click', function(){
		address = $('input[name="address"]').val();
		setgeoLoc(false,address);
	});

# Wird der "Position zurücksetzen"-Link geklickt, wird erneut versucht
# die Position des Users zu ermitteln

	$('.reset').bind('click', function(){
		navigator.geolocation.getCurrentPosition(setgeoLoc);
	});
});

Zur Datenverarbeitung ist allerdings noch mehr Javascript erforderlich. Im Kern steht der Geocoder der Google Maps API. Mit ihm können wir anhand von Längen- und Breitengraden die dazugehörige Adresse ermitteln und auch umgekehrt.

Die Funktion „setgeoLoc“ wird aufgerufen, wenn versucht wird die Position des Users zu ermitteln oder er eine neue Position festlegt. Die übergebenen Daten werden an den Geocoder gesendet um die exakten Adressdaten zu ermitteln. Anschließend wird die genaue Adresse in <div class=“address“></div> und die Längen und Breitengrade in die versteckten Inputfelder geschrieben und an die nächste Funktion übergeben.

var geocoder;
geocoder = new google.maps.Geocoder();

function setgeoLoc(position,address) {
	if(address != undefined){
		geocoder.geocode( { 'address': address}, function(results, status) {
			if (status == google.maps.GeocoderStatus.OK) {
				$('.address').html(results[0].formatted_address);

				lat = results[0].geometry.location.Pa;
				lng = results[0].geometry.location.Qa;

				$('input[name="lat"]').val(lat);
				$('input[name="lng"]').val(lng);

				getdata(lat, lng);

			} else {
				alert("Geocoder failed due to: " + status);
			}
		});

	} else {

		lat = parseFloat(position.coords.latitude);
		lng = parseFloat(position.coords.longitude);

		latlng = new google.maps.LatLng(lat, lng);
		geocoder.geocode({'latLng': latlng}, function(results, status) {
		  if (status == google.maps.GeocoderStatus.OK) {
			if (results[0]) {
			  $('.address').html(results[0].formatted_address);
			  $('input[name="lat"]').val(lat);
			  $('input[name="lng"]').val(lng);

			  getdata(lat, lng);
			}
		  } else {
			alert("Geocoder failed due to: " + status);
		  }
		});
	}
}

Die nächste Funktion liest den angegebenen Suchradius aus dem Select-Feld aus, kürzt das „m“ am Schluss weg und ruft über GET-Parameter ein PHP-Script auf, das uns Ergebnisse im Umkreis liefern soll.

function getdata(lat, lng) {
	var distance = $('#distance').val();
	distance = distance.substring(0,distance.length-1);
	var scriptPath = 'getdata.php?lat='+lat+'&lng='+lng+'&distance='+distance;

	$.ajax({
		type: 'GET',
		url: scriptPath,
		success: function(data) {
			$('.userdata').html(data);
		},
		error: function() {
			$('.userdata').html('</pre>
<div id="error">
Verbindung zum Server fehlgeschlagen.</div>
<pre>
');
		}
	});
}

Als nächstes muss eine neue PHP-Datei erstellt werden, die uns die Suchergebnisse liefern soll.

Das folgende PHP-Skript validiert die übermittelten Daten und bringt Sie falls notwendig in das richtige Format.

In der SQL-Abfrage werden Längen und Breitengrad selektiert und die Distanz der Datensätze zum aktuellen Standort errechnet. Es wird überprüft ob sich Datensätze im Suchradius befinden und diese werden dann nach Entfernung zum Standort geordnet.

Anschließend multiplizieren wir die Suchdistanz mit 1000 um wieder auf Meter zu kommen und lassen uns alle Datensätze im Suchradius ausgeben.

if(isset($_GET['lat']) && isset($_GET['lng']) && isset($_GET['distance'])) {
	$lat = floatval($_GET['lat']);
	$lat = str_replace(',', '.', $lat);
	$lng = floatval($_GET['lng']);
	$lng = str_replace(',', '.', $lng);
	$distance = intval($_GET['distance']);
	$distance = $distance * 0.001;
	$distance = str_replace(',', '.', $distance);
} else {
	echo 'keine Daten übermittelt';
	exit;
}

$sql = 'SELECT latitude AS lat, longitude AS lng,
			   ( 6371 * acos( cos( radians('.$lat.') ) * cos( radians(latitude ) ) * cos( radians(longitude ) - radians('.$lng.') ) + sin( radians('.$lat.') ) * sin( radians(latitude ) ) ) ) AS distance
		  FROM users
		HAVING distance < '.$distance.'
	      ORDER BY distance ASC';

$nearbyResults = mysql_query( $sql ) or die(mysql_error());
while($user = mysql_fetch_array($nearbyResults)) {
	$userdistance=round($user&#91;'distance'&#93;*1000);

	echo '</pre>
<div class="user">Breitengrad: '.$user['lat'].'

 Längengrad: '.$user['lng'].'

 Entfernung: '.$userdistance.'m</div>
<pre>
';
}

Wenn alles geklappt hat, könnte das Ganze so aussehen.

Wir freuen uns auf Kommentare, schreibt einfach!

Edit: Beispieltabelle Braunschweig – geo.sql

  • Diesen Beitrag weiterempfehlen:

12 Gedanken zu „How to: Umkreissuche mit Google Maps erstellen

  1. Pingback: Viktor kokott | Chemicalsalest

    1. Andreas Kokott Artikelautor

      Hi,
      für die Datenbank brauchst du eigentlich nur eine Tabelle mit id, Längengrad und Breitengrad. Damit du auch eine Ausgabe bekommst muss der Radius groß genug gewählt werden. Anbei, am Ende des Artikels der Downloadlink zu einer Beispiel Datenbanktabelle aus dem Raum Braunschweig.

      Antworten
  2. Christofer

    Super Tutorial … hat mir sehr geholfen!

    Einige Frage noch zum SQL-Query kann man dieses eventuell noch ein wenig tunen bzw. per stored procedure beschleunigen?

    Danke und beste Grüße

    Antworten
    1. Andreas Kokott Artikelautor

      Vielen Dank,
      deine Frage kann ich dir leider nicht beantworten, da ich mich mit stored procedures noch nicht befasst habe. Ich werde auf jeden Fall Möglichkeiten zur Beschleuningung testen und gegebenenfalls ein Update bzw. neues Posting machen.

      Antworten
  3. Timo

    Guten Tag dieses Tutorial sieht ganz gut aus,
    kannst du mir bitte einen zip Ordner schicken wo die Datenbank drine ist die funktioniert und die kompletten Dateien schon fertig geschrieben sind?

    Antworten
    1. Andreas Kokott Artikelautor

      Hallo Timo,
      Die Datenbank ist am Ende des Beitrags.
      Eigentlich sollte es kein Problem sein die Umkreissuche zum Laufen zu kriegen.
      Der gesamte Code den du brauchst befindet sich in diesem Howto.
      Ich würde dir jetzt ungern die ganze Arbeit beim Erstellen der Scripte abnehmen 😉
      Gibt es vielleicht Probleme bei denen ich dir behilflich sein kann?

      Antworten
  4. Lars

    Vielen Dank für dieses Tutorial. Hat mir sehr geholfen!!
    Vielleicht könntet ihr im HTML-Snippet noch das Script-Element korrigieren und die „distance id“ hinzufügen. Dann wäre es perfekt!

    Grüße aus Bielefeld

    Lars

    Antworten
  5. Alex

    Hi, super sache!! Ich bekomme es leider nur nicht zusammen gebastelt(bin fertig mit nerven)!! Kann wirklich niemand von euch als zip oder ähnliches hochladen? Danke im vorraus.
    MFG ALEX

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Lösen Sie bitte die Rechenaufgabe. *