Google Maps mit PHP und Ajax nutzen Eine kurze Einführung vom Frank Staude <staude@trilos.de> vorgetragen beim Treffen der PHP Usergroup Hannover am 08.05.2008
Bevor wir mit Google-Maps loslegen können, benötigen wir einen API-Key. Den bekommt man auf der Seite http://www.google.com/apis/maps/signup.html nach dem man sich mit den Nutzungsbedingungen einverstanden erklärt hat. Außerdem benötigt man einen Google Account. Anschließend bekommt man seinen Schüssel und ein einfache Beispiel Seite. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>google Maps JavaScript API Example</title> <script src="http://maps.google.com/maps?file=api&v=2&key=dein_key" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ function load() { if (GBrowserIsCompatible()) { var map = new GMap2(document.getElementById("map")); map.setcenter(new GLatLng(37.4419, -122.1419), 13); //]]> </script> </head> <body onload="load()" onunload="gunload()"> <div id="map" style="width: 500px; height: 300px"></div> </body> </html> Das erzeugt eine einfache Karte, mit der man allerdings noch nichts anfangen kann.
Als erstes werden wir nun mal ausgeben, wo wir uns heute Abend treffen. Als erstes machen wir den Div-Container größer, in den die Karte hineingeladen wird. <div id="map" style="width: 800px; height: 600px"></div> Nun benötigen wir noch die Steuerelemente um in der Karte zu navigieren und um die Ansicht umschalten zu können. Dazu ergänzen wir den Javascipt Block folgendermaßen. function load() { if (GBrowserIsCompatible()) { var map = new GMap2(document.getElementById("map")); map.setcenter(new GLatLng(52.388466, 9.716529), 15); map.addcontrol(new GLargeMapControl()); map.addcontrol(new GMapTypeControl()); Mit setcenter wird die Kartenmitte und der Zoomfaktor festgelegt. Anschließend mit addcontrol die beiden Navigationselemente. Es gibt 5 verschiedene Navigationselemente die verwendet werden können.
GLargeMapControl() Dies ist das große Steuerelement zum Verschieben und Vergrößern der Karte wie im Beispiel und auch auf maps.google.com verwendet. GSmallMapControl(). Ein kleineres Steuerelement zur Verwendung in kleinen Karten. GScaleControl(). Zeigt die aktuelle Skalierung der Karte mit Kilometerangaben an. GSmallZoomControl(). Zwei einfache Schaltflächen zum ändern des Vergrößerungsfaktors. GMapTypeControl(). Umschalten der Ansicht zwischen Karten, Satelliten- und Hybriddarstellung. Als nächstes soll aber auch ein Marker auf der Karte gesetzt werden, denn wir wollen ja nicht raten wo der anvisierte Punkte sich auf der Karte befindet. Und wenn man den Marker anklickt erscheint ein Beschreibungstext.
Der Javascript Block sieht nun folgendermaßen aus. var map; function addmarker(lat, lang, desc) { var marker = new GMarker(new GLatLng(lat, lang)); GEvent.addListener(marker, 'click', function() { marker.openinfowindowhtml (desc) ); map.addoverlay(marker); function load() { if (GBrowserIsCompatible()) { map = new GMap2(document.getElementById("map")); map.setcenter(new GLatLng(52.388466, 9.716529), 15); map.addcontrol(new GLargeMapControl()); map.addcontrol(new GMapTypeControl()); addmarker(52.388466, 9.716529, "Gaststätte Kaiser");
Wir wären nicht die PHPUG Hannover, wenn nicht auch das Thema GPS/Geocaching vorkommen würde. Also nehmen wir als richtige Anwendung eine Karte wo jeder per Klick einen neuen Cache in die Karte eintragen kann. Und nach speichern erscheint ein neuer Marker auf der Karte. Speichern schickt die Daten an den Webserver, dort werden diese gespeichert, so dass auch beim neu laden der Karte die bereits eingetragenen Geocaches ausgegeben werden. Der Einfachheit halber werden die Daten in einer XML Datei gespeichert. Der Aufbau der XML Datei ist: <marker lat="52.3884610455" lng="9.71569061279" found="nix" left="bananen"/>
Dieses Beispiel ist aus dem recht guten Buch Google Maps Anwendungen mit PHP und Ajax von Michael Purvis, Jeffrey Sambells und Cameron Turner. Mitp Verlag, ISBN: 978-3-8266-1760-7 und natürlich auch in der TIB zum ausleihen. Beispiel Kapitel und auch die Codebeispiele gibt es unter: http://www.mitp.de/1760 Ich fand dieses Beispiel aber so passend für unsere PHPUG, dass ich mich entschieden habe es zu verwenden. Die beiden PHP Scripte sind. Zum Speichern: <?php header('content-type: text/xml;charset=utf-8'); $lat = (float)$_get['lat']; $lng = (float)$_get['lng']; $found = htmlspecialchars(strip_tags($_get['found'])); $left = htmlspecialchars(strip_tags($_get['left'])); //XML-Knoten erzeugen $marker = <<<MARKER <marker lat="$lat" lng="$lng" found="$found" left="$left"/>\n MARKER;
//data.xml öffnen und erweitern $f=@fopen('data.xml', 'a+'); if(!$f) die('<?xml version="1.0"?> <response type="error"><![cdata[konnte Datei data.xml nicht laden]]></response>'); //Knoten hinzufügen $w=@fwrite($f, $marker); if(!$w) die('<?xml version="1.0"?> <response type="error">![cdata[konnte nicht in Datei data.xml schreiben]]></response>'); @fclose($f); //Antwort zurückgeben $newmarkercontent = "<div><b>gefunden </b>$found</div> <div><b>versteckt </b>$left</div>"; echo <<<XML <?xml version="1.0"?> <response type="success"><![cdata[$newmarkercontent]]></response> XML;?> Und zum Lesen <?php header('content-type: text/xml;charset=utf-8'); $markers = file_get_contents('data.xml'); echo <<<XML <markers>$markers</markers> XML;?> Und der JavascriptCode dazu: var centerlatitude = 52.388466; var centerlongitude = 9.716529; var startzoom = 15; var map; function init() { if (GBrowserIsCompatible()) { map = new GMap2(document.getElementById("map")); retrievemarkers(); map.addcontrol(new GSmallMapControl()); map.addcontrol(new GMapTypeControl()); map.setcenter(new GLatLng(centerLatitude,centerLongitude), startzoom); GEvent.addListener(map, "click", function(overlay, latlng) { //Nur dann Klick ausführen, wenn das Fenster geschlossen ist //und der Klick direkt auf der Karte erfolgte if(!overlay) { //Ein DOM-Element im HTML-Formular erzeugen var inputform = document.createelement("form"); inputform.setattribute("action",""); inputform.onsubmit = function() {storemarker(); return false; //Länge und Breite des angeklickten Punkts ermitteln var lng = latlng.lng(); var lat = latlng.lat();
style="width:100%;" />' style="width:100%;" />' ); inputform.innerhtml = '<fieldset style="width:150px;">' + '<legend>neuer Marker</legend>' + '<label for="found">gefunden</label>' + '<input type="text" id="found" + '<label for="left">versteckt</label>' + '<input type="text" id="left" + '<input type="submit" value="speichern" />' + '<input type="hidden" id="longitude" value="' + lng + '"/>' + '<input type="hidden" id="latitude" value="' + lat + '"/>' + '</fieldset>'; map.openinfowindow (latlng,inputform); window.onload = init; window.onunload = GUnload; function storemarker(){ var lng = document.getelementbyid("longitude").value; var lat = document.getelementbyid("latitude").value; var getvars = "?found=" + document.getelementbyid("found").value + "&left=" + document.getelementbyid("left").value + "&lng=" + lng + "&lat=" + lat ; var request = GXmlHttp.create(); //Anforderung an storemarker.php auf dem Server request.open('get', 'storemarker.php' + getvars, true); request.onreadystatechange = function() { if (request.readystate == 4) { //Anforderung abgeschlossen var xmldoc = request.responsexml; //root-dokumentelement (response) übernehmen var responsenode = xmldoc.documentelement; //type-attribut des Knotens übernehmen var type = responsenode.getattribute("type"); //Inhalt von responsenode übernehmen var content = responsenode.firstchild.nodevalue; //Prüfung: Fehler oder Erfolg? if(type!='success') {alert(content); else { //Neuen Marker erzeugen und Info-Fenster //hinzufügen var latlng = new GLatLng(parseFloat(lat), parsefloat(lng)); var marker = createmarker(latlng, content); map.addoverlay(marker); map.closeinfowindow(); request.send(null);
return false; function createmarker(latlng, html) { var marker = new GMarker(latlng); GEvent.addListener(marker, 'click', function() { var markerhtml = html; marker.openinfowindowhtml(markerhtml); ); return marker; function retrievemarkers() { var request = GXmlHttp.create(); //request mitteilen, woher Daten übernommen werden request.open('get', 'retrievemarkers.php', true); //request mitteilen, was bei Statusänderung geschehen soll request.onreadystatechange = function() { if (request.readystate == 4) { var xmldoc = request.responsexml; var markers = xmldoc.documentelement.getelementsbytagname("marker"); for (var i = 0; i < markers.length; i++) { var lng = markers[i].getattribute("lng"); var lat = markers[i].getattribute("lat"); //lng und lat prüfen, damit MSIE keinen Fehler bei //parsefloat eines Nullwerts verursacht if(lng && lat) { var latlng = new GLatLng(parseFloat(lat), parsefloat(lng)); var html = '<div><b>gefunden</b> ' + markers[i].getattribute("found") + '</div><div><b>versteckt</b> ' + markers[i].getattribute("left") + '</div>'; //for //if //function request.send(null); var marker = createmarker(latlng, html); map.addoverlay(marker); Und wer es direkt ausprobieren möchte kann das Beispiel unter http://frankstaude.de/googlemaps/index.php aufrufen. Die wichtigste Infoquelle ist natürlich die Dokumentation der Api unter http://code.google.com/apis/maps/documentation/index.html und ebenfalls interessant ist das Maps API Blog unter http://googlemapsapi.blogspot.com/ Und wer nicht alles selber Coden möchte sollte sich unter http://gmapper.ajax-info.de/ mal die GMapper Klasse ansehen. Gmapper ist eine PHP Klasse, die den Einsatz von Google Maps in Websites stark vereinfacht. Gmapper bietet erweiterte Funktionen wie Polylines, Zoom to bounds, XML Support, Fahrtrichtungen und vieles mehr.