Mit PHP und Google Sheets eine von Nutzern erstellte Karte erstellen

Pamela Fox, Google Maps API-Team
November 2007

Ziel

Im Web gibt es viele Communities, die sich um geografische Orte und Interessen drehen: Menschen, die Museen, europäische Kathedralen, Nationalparks usw. lieben. Es besteht also immer Bedarf an einem Entwickler (wie Ihnen!), der ein System erstellt, in dem Nutzer geotaggte Orte auf einer Karte hinzufügen können. Genau das werden wir hier tun. Am Ende dieses Artikels haben Sie ein System, in dem sich Nutzer registrieren, anmelden und geotaggte Orte hinzufügen können. Das System verwendet AJAX für das Front-End, PHP für das Scripting auf der Serverseite und Google Text & Tabellen für die Speicherung. Wenn Sie es gewohnt sind, MySQL-Datenbanken für die Speicherung zu verwenden, können Sie den Code hier ganz einfach so ändern, dass stattdessen ein MySQL-Datenbank-Backend verwendet wird.

Dieser Artikel beschreibt die folgenden Schritte:


Tabelle einrichten

Wir verwenden Google Tabellen, um alle Daten für dieses System zu speichern. Wir müssen zwei Arten von Daten speichern: Nutzerkontoinformationen und von Nutzern hinzugefügte Orte. Daher erstellen wir für jeden Datentyp ein Arbeitsblatt. Wir interagieren mit den Arbeitsblättern über ihren Listenfeed. Dazu muss die erste Zeile eines Arbeitsblatts Spaltenlabels und jede nachfolgende Zeile Daten enthalten.

Rufen Sie docs.google.com auf und erstellen Sie eine neue Tabelle. Benennen Sie das Standardarbeitsblatt in „Users“ um und erstellen Sie die Spalten „user“, „password“ und „session“. Fügen Sie dann ein weiteres Tabellenblatt hinzu, benennen Sie es in „Standorte“ um und erstellen Sie Spalten mit den Namen „user“, „status“, „lat“, „lng“ und „date“. Wenn Sie sich die ganze manuelle Arbeit sparen möchten, können Sie diese Vorlage herunterladen und über den Befehl „Datei“ -> „Importieren“ in Google Tabellen importieren.

Die Nutzerkontoinformationen müssen vertraulich behandelt werden, d. h. sie dürfen nur für den Eigentümer der Tabelle (also für Sie) sichtbar sein, während die vom Nutzer hinzugefügten Standorte auf einer öffentlich sichtbaren Karte angezeigt werden. Glücklicherweise können Sie mit Google Text & Tabellen selektiv entscheiden, welches Arbeitsblatt in einer Tabelle öffentlich und welches vertraulich (Standard) behandelt werden soll. Wenn Sie das Arbeitsblatt „Standorte“ veröffentlichen möchten, klicken Sie auf den Tab „Veröffentlichen“, dann auf „Jetzt veröffentlichen“, setzen Sie ein Häkchen bei „Automatisch neu veröffentlichen“ und wählen Sie im Drop-down-Menü „Welche Teile?“ die Option „Nur Arbeitsblatt ‚Standorte‘“ aus. Die korrekten Optionen werden in dem folgenden Screenshot angezeigt:

Arbeiten mit dem Zend Google Data Framework

Das Google Text & Tabellen-API bietet eine HTTP-Schnittstelle für CRUD-Operationen, wie z. B. Abrufen von Zeilen, Einfügen von Zeilen, Aktualisieren von Zeilen und Löschen von Zeilen. Das Zend Framework bietet einen PHP-Wrapper für die API (und die anderen GData-APIs), sodass Sie sich nicht um die Implementierung der Roh-HTTP-Vorgänge kümmern müssen. Für Zend Framework ist PHP 5 erforderlich.

Wenn Sie das Zend Framework noch nicht haben, laden Sie es herunter und laden Sie es auf Ihren Server hoch. Das Framework ist hier verfügbar: http://framework.zend.com/download/gdata.

Ändern Sie den „include_path“ in Ihrem PHP-Code, um die Zend-Bibliothek aufzunehmen. Abhängig von der Stufe Ihrer Administratorrechte, die Sie auf Ihrem Server besitzen, können Sie diesen Schritt auf unterschiedliche Weise durchführen. Eine Möglichkeit besteht darin, diese Zeile in allen PHP-Dateien, in denen die Bibliothek verwendet wird, über den require-Anweisungen hinzuzufügen:

ini_set("include_path", ".:/usr/lib/php:/usr/local/lib/php:../../../library/");

Führen Sie die Demo von Google Text & Tabellen aus, indem Sie folgenden Code in die Befehlszeile im Ordner „demos/Zend/Gdata“ eingeben:

php Spreadsheet-ClientLogin.php --user=YourGMailUsername --pass=YourPassword

Wenn es funktioniert, sollte eine Liste Ihrer Tabellen angezeigt werden. Sollten Sie eine Fehlermeldung erhalten, stellen Sie sicher, dass Ihr Include-Pfad korrekt eingestellt ist und PHP 5 installiert ist.

Globale Funktionen erstellen

Für alle PHP-Scripts, die wir für die Community Map schreiben, werden allgemeine Includes, Variablen und Funktionen verwendet, die wir in einer Datei zusammenfassen.

Am Anfang der Datei stehen die erforderlichen Anweisungen zum Einbinden und Laden der Zend-Bibliothek, die aus dem Beispiel „Spreadsheets-ClientLogin.php“ stammen.

Anschließend definieren wir die Konstanten, die in den Dateien verwendet werden: den Tabellenschlüssel und die beiden Arbeitsblatt-IDs. Wenn Sie die Informationen für Ihr Tabellenblatt aufrufen möchten, öffnen Sie es, klicken Sie auf den Tab „Veröffentlichen“ und dann auf „Weitere Veröffentlichungsoptionen“. Wählen Sie in der Drop-down-Liste „Dateiformat“ die Option „ATOM“ aus und klicken Sie auf „URL generieren“. Die Ausgabe sollte in etwa so aussehen:

http://spreadsheets.google.com/feeds/list/o16162288751915453340.4016005092390554215/od6/public/basic

Der Tabellenschlüssel ist der lange alphanumerische String nach „/list/“ und die Arbeitsblatt-ID ist der dreistellige String danach. Wenn Sie die ID des anderen Arbeitsblatts herausfinden möchten, wählen Sie das andere Tabellenblatt im Drop-down-Menü „Welche Tabellenblätter?“ aus.

Anschließend erstellen wir drei Funktionen: setupClient, getWkshtListFeed und printFeed. In setupClient legen wir unseren Gmail-Nutzernamen und unser Passwort fest, authentifizieren uns mit ClientLogin und geben ein Zend_Gdata_Spreadsheets-Objekt zurück. In getWkshtListFeed wird ein Tabellenlistenfeed für einen bestimmten Tabellenschlüssel und eine bestimmte Arbeitsblatt-ID mit einer optionalen Tabellenabfrage (Link) zurückgegeben. Die Funktion „printFeed“ stammt aus dem Beispiel „Spreadsheets-ClientLogin.php“ und kann beim Debugging hilfreich sein. Sie nimmt ein Feed-Objekt auf und druckt es auf dem Bildschirm aus.

Der entsprechende PHP-Code (communitymap_globals.php) ist unten zu sehen:

<?php
ini_set("include_path", ".:/usr/lib/php:/usr/local/lib/php:../../../library/");
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Spreadsheets');
Zend_Loader::loadClass('Zend_Http_Client');

define("SPREADSHEET_KEY", "o16162288751915453340.4016005092390554215");
define("USER_WORKSHEET_ID", "od6");
define("LOC_WORKSHEET_ID", "od7");
 
function setupClient() {
  $email = "your.name@gmail.com";
  $password = "yourPassword";
  $client = Zend_Gdata_ClientLogin::getHttpClient($email, $password,
          Zend_Gdata_Spreadsheets::AUTH_SERVICE_NAME);
  $gdClient = new Zend_Gdata_Spreadsheets($client);
  return $gdClient;
}
 
function getWkshtListFeed($gdClient, $ssKey, $wkshtId, $queryString=null) {
  $query = new Zend_Gdata_Spreadsheets_ListQuery();
  $query->setSpreadsheetKey($ssKey);
  $query->setWorksheetId($wkshtId);
  if ($queryString !== null) {
    $query->setSpreadsheetQuery($queryString);
  }
  $listFeed = $gdClient->getListFeed($query);
  return $listFeed;
}
 
function printFeed($feed)
{
  print "printing feed";
  $i = 0;
  foreach($feed->entries as $entry) {
      if ($entry instanceof Zend_Gdata_Spreadsheets_CellEntry) {
         print $entry->title->text .' '. $entry->content->text . "\n";
      } else if ($entry instanceof Zend_Gdata_Spreadsheets_ListEntry) {
         print $i .' '. $entry->title->text .' '. $entry->content->text . "\n";
      } else {
         print $i .' '. $entry->title->text . "\n";
      }
      $i++;
  }
}
 
?>

Einen neuen Nutzer registrieren

Um einen neuen Nutzer zu registrieren, benötigen wir eine nutzerorientierte HTML-Seite mit Textfeldern und einer Schaltfläche zum Senden sowie ein PHP-Backend-Script, um den Nutzer der Tabelle hinzuzufügen.

Zunächst schließen wir ein globales Skript in das PHP-Skript ein und erhalten dann von der GET-Variablen die Werte für den Nutzernamen und das Passwort. Anschließend richten wir einen Client für Tabellen ein und fordern den Listen-Feed für die Arbeitsblätter der Nutzer mit einem Suchanfragen-String an, um die Ergebnisse auf Zeilen zu beschränken, in denen die Spalte „Nutzername“ mit dem Nutzernamen, der in das Skript übergeben wurde, übereinstimmt. Wenn wir keine Zeilen in den Ergebnissen des Listen-Feeds erhalten, können wir sicher fortfahren und wissen, dass der Nutzername eindeutig ist. Bevor wir eine Zeile in den Listenfeed einfügen, erstellen wir ein assoziatives Array der Spaltenwerte: den Nutzernamen, eine Verschlüsselung des Passworts mit der PHP-Funktion „sha1“ und ein Füllzeichen für die Sitzung. Dann rufen wir insertRow auf dem Client für Tabellen auf und übergeben den assoziativen Array, den Tabellenschlüssel und die Arbeitsblatt-ID. Wenn das zurückgegebene Objekt ein ListFeedEntry ist, geben wir die Meldung „Erfolg!“ aus.

Der entsprechende PHP-Code (communitymap_newuser.php) ist unten zu sehen:

<?php
 
require_once 'communitymap_globals.php';
 
$username = $_GET['username'];
$password = $_GET['password'];
 
$gdClient = setupClient();
 
$listFeed = getWkshtListFeed($gdClient, SPREADSHEET_KEY, USER_WORKSHEET_ID, ('user='.$username));
$totalResults = $listFeed->totalResults;
if ( $totalResults != "0") {
  // Username already exists
  exit;
}
 
$rowArray["user"] = $username;
$rowArray["password"] = sha1($password);
$rowArray["session"] = "a";
 
$entry = $gdClient->insertRow($rowArray, SPREADSHEET_KEY, USER_WORKSHEET_ID);
if ($entry instanceof Zend_Gdata_Spreadsheets_ListEntry) {
  echo "Success!";
}
?>

Auf der Registrierungsseite können wir die Maps API einbinden, damit wir die XMLHttpRequest-Wrapper-Funktion namens GDownloadUrl verwenden können. Wenn der Nutzer auf die Schaltfläche „Senden“ klickt, werden der Nutzername und das Passwort aus den Textfeldern abgerufen, ein Parameterstring aus den Werten erstellt und GDownloadUrl für die Skript-URL und die Parameter aufgerufen. Da wir vertrauliche Informationen senden, verwenden wir die HTTP POST-Version von GDownloadUrl. Die Parameter werden als drittes Argument gesendet, anstatt an die URL angehängt zu werden. In der Callback-Funktion prüfen wir, ob die Antwort erfolgreich war, und geben eine entsprechende Meldung an den Nutzer aus.

Unten sehen Sie einen Screenshot und Code für eine Beispielregistrierungsseite (communitymap_register.htm):


<!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>
  <title> Community Map - Register/Login </title>

  <script src="http://maps.google.com/maps?file=api&v=2&key=abcdef"
      type="text/javascript"></script>
  <script type="text/javascript">

  function register() {
    var username = document.getElementById("username").value;
    var password = document.getElementById("password").value;
    var url = "communitymap_newuser.php?";
    var params = "username=" + username + "&password=" + password;
    GDownloadUrl(url, function(data, responseCode) {
      if (data.length > 1) {
        document.getElementById("message").innerHTML = "Successfully registered." + 
          "<a href='communitymap_login.htm'>Proceed to Login</a>.";
      } else {
        document.getElementById("message").innerHTML = "Username already exists. Try again.";
      }
    }, params);
  }

  </script>

  </head>
  <body>
  <h1>Register for Community Map</h1>
  <input type="text" id="username">
  <input type="password" id="password">

  <input type="button" onclick="register()" value="Register">
  <div id="message"></div>
  </body>
</html>

Einen Nutzer anmelden

Damit sich Nutzer in unserem System anmelden können, benötigen wir eine nutzerorientierte HTML-Seite, auf der sie nach ihrem Nutzernamen und Passwort gefragt werden, sowie ein PHP-Script, mit dem die Anmeldedaten überprüft, eine Sitzungs-ID erstellt und an die Anmeldeseite zurückgegeben wird, um ein Cookie zu setzen. Der Nutzer bleibt über das Sitzungs-Cookie auf nachfolgenden Seiten angemeldet.

Zunächst schließen wir ein globales Skript in das PHP-Skript ein und erhalten dann von der GET-Variablen die Werte für den Nutzernamen und das Passwort. Anschließend richten wir einen Client für Tabellen ein und fordern den Listen-Feed für die Arbeitsblätter der Nutzer mit einem Suchanfragen-String an, um die Ergebnisse auf Zeilen zu beschränken, in denen die Spalte „Nutzername“ mit dem Nutzernamen, der in das Skript übergeben wurde, übereinstimmt.

In der zurückgegebenen Zeile prüfen wir, ob der Hash des übergebenen Passworts mit dem in der Tabelle gespeicherten Hash übereinstimmt. Wenn ja, erstellen wir eine Sitzungs-ID mit den Funktionen „md5“, „uniqid“ und „rand“. Anschließend aktualisieren wir die Zeile in der Tabelle mit der Sitzung und geben sie auf dem Bildschirm aus, wenn die Zeilenaktualisierung erfolgreich ist.

Der entsprechende PHP-Code (communitymap_loginuser.php) ist unten zu sehen:

<?php
 
require_once 'communitymap_globals.php';
 
$username = $_POST['username'];
$password = $_POST['password'];
 
$gdClient = setupClient();
 
$listFeed = getWkshtListFeed($gdClient, SPREADSHEET_KEY, USER_WORKSHEET_ID, ('user='.$username));
 
$password_hash = sha1($password);
$row = $listFeed->entries[0];
$rowData = $row->getCustom();
foreach($rowData as $customEntry) {
  if ($customEntry->getColumnName()=="password" && $customEntry->getText()==$password_hash) {
    $updatedRowArray["user"] = $username;
    $updatedRowArray["password"] = sha1($password);
    $updatedRowArray["session"] = md5(uniqid(rand(), true));
    $updatedRow = $gdClient->updateRow($row, $updatedRowArray); 
    if ($updatedRow instanceof Zend_Gdata_Spreadsheets_ListEntry) {
      echo $updatedRowArray["session"];
    }
  }
}
?>

Auf der Anmeldeseite können wir die Maps API wieder einbinden, damit wir die XMLHttpRequest-Wrapper-Funktion namens GDownloadUrl verwenden können. Wenn der Nutzer auf die Schaltfläche „Senden“ klickt, werden der Nutzername und das Passwort aus den Textfeldern abgerufen, die Skript-URL mit den Abfrageparametern erstellt und GDownloadUrl für die Skript-URL aufgerufen. In der Callback-Funktion legen wir ein Cookie mit der Sitzungs-ID fest, die vom Script zurückgegeben wird, oder geben eine Fehlermeldung aus, wenn keine zurückgegeben wird. Die Funktion „setCookie“ stammt aus „cookies.js“, das auf dem W3C-JavaScript-Tutorial basiert: http://www.w3schools.com/js/js_cookies.asp.

Unten sehen Sie einen Screenshot und Code für eine Beispielanmeldeseite (communitymap_login.htm):


<!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>

  <title>Community Map - Login</title>
      <script src="http://maps.google.com/maps?file=api&v=2&key=abcdef"
      type="text/javascript"></script>
  <script src="cookies.js" type="text/javascript"></script>
  <script type="text/javascript">

  function login() {
    var username = document.getElementById("username").value;
    var password = document.getElementById("password").value;
    var url = "communitymap_loginuser.php?username=" + username + "&password=" + password;
    GDownloadUrl(url, function(data, responseCode) {
      if (data.length > 1) {
        setCookie("session", data, 5);
      } else {
        document.getElementById("nessage").innerHTML = "Error. Try again.";
      }
    });
  }

  </script>
  </head>
  <body>

  <h1>Login for Community Map</h1>

  <input type="text" id="username">
  <input type="password" id="password">
  <input type="button" onclick="login()" value="Login">
  <div id="message"></div>
  </body>
</html>

Nutzer Kartenstandorte hinzufügen lassen

Damit ein Nutzer Orte auf unserer Karte hinzufügen kann, benötigen wir eine nutzerorientierte HTML-Seite, auf der er Informationen zum Ort eingeben kann, sowie zwei PHP-Skripts: eines, um zu prüfen, ob er über das von uns festgelegte Cookie angemeldet ist, und ein weiteres, um den Ort dem Arbeitsblatt „Orte“ hinzuzufügen.

In dem ersten PHP-Skript, das prüft, ob ein Nutzer angemeldet ist, schließen wir zunächst das globale Skript ein und erhalten dann den Sitzungswert von der GET-Variablen. Anschließend richten wir einen Client für Tabellen ein und fordern den Listen-Feed für die Arbeitsblätter der Nutzer mit einem Suchanfragen-String an, um die Ergebnisse nur auf die Zeilen zu beschränken, in denen die Spalte „Sitzung“ mit dem Sitzungswert, der in das Skript übergeben wurde, übereinstimmt. Dann gehen wir die benutzerdefinierten Einträge dieses Feeds, die mit unseren Spaltenüberschriften übereinstimmen, durch und drucken den entsprechenden Nutzernamen für diese Sitzung aus, falls einer vorhanden ist.

Der entsprechende PHP-Code (communitymap_checksession.php) ist unten zu sehen:

<?php

require_once 'communitymap_globals.php';

$session = $_GET['session'];

$gdClient = setupClient();

$listFeed = getWkshtListFeed($gdClient, SPREADSHEET_KEY, USER_WORKSHEET_ID, ('session='.$session));

if ( count($listFeed->entries) > 0) {
  $row = $listFeed->entries[0];
  $rowData = $row->getCustom();
  foreach($rowData as $customEntry) {
    if ($customEntry->getColumnName()=="user") {
      echo $customEntry->getText();
    }
  }
}
?>

In dem zweiten PHP-Skript, mit dem ein Nutzer einen Standort hinzufügen kann, replizieren wir zunächst den Code aus communitymap_checksession.php, um sicherzustellen, dass der Nutzer noch angemeldet ist und die Informationen gültig sind. Sobald wir einen gültigen Nutzernamen von dem Arbeitsblatt „Nutzer“ empfangen haben, erhalten wir den Standort sowie die Werte für Breite und Länge von der GET-Variablen. Wir fügen alle diese Werte in ein assoziatives Array ein und fügen mit der PHP-Funktion „date()“ auch einen „date“-Wert hinzu, damit wir wissen, wann der Nutzer den Ort hinzugefügt hat. Wir übergeben diesen assoziativen Array, die Konstante des Tabellenschlüssels sowie die Konstante der Arbeitsblatt-ID für die Standorte in die Funktion insertRow. Wir geben dann „Erfolg“ aus, wenn der Tabelle eine Zeile für den neuen Standort hinzugefügt wurde. Wenn Sie in diesem Schritt eine Fehlermeldung erhalten, liegt das wahrscheinlich an einer Nichtübereinstimmung der Spaltenüberschriften. Die Schlüssel in dem assoziativen Array müssen mit den Spaltenüberschriften in dem Arbeitsblatt, das von dem Tabellenschlüssel und der Arbeitsblatt-ID spezifiziert wurde, übereinstimmen.

Der entsprechende PHP-Code ist unten zu sehen (communitymap_addlocation.php):

<?php

require_once 'communitymap_globals.php';

$session = $_GET['session'];

$gdClient = setupClient();

$listFeed = getWkshtListFeed($gdClient, SPREADSHEET_KEY, USER_WORKSHEET_ID, ('session='.$session));

if ( count($listFeed->entries) > 0) {
  $row = $listFeed->entries[0];
  $rowData = $row->getCustom();
  foreach($rowData as $customEntry) {
    if ($customEntry->getColumnName()=="user") {
      $user = $customEntry->getText();
    }
  }

  $place = $_GET['place'];
  $lat = $_GET['lat'];
  $lng = $_GET['lng'];
  $rowArray["user"] = $user;
  $rowArray["place"] = $place;
  $rowArray["lat"] = $lat;
  $rowArray["lng"] = $lng;
  $rowArray["date"] = date("F j, Y, g:i a");
  $entry = $gdClient->insertRow($rowArray, SPREADSHEET_KEY, LOC_WORKSHEET_ID);
  if ($entry instanceof Zend_Gdata_Spreadsheets_ListEntry) {
    echo "Success!\n";
  }
}

?>

Auf der Seite „Standort hinzufügen“ können wir das Google Maps-API erneut hinzufügen, um GDownloadUrl zu verwenden und eine Karte zu erstellen. Nach dem Laden der Seite verwenden wir die Funktion getCookie von cookies.js, um den Sitzungswert abzurufen. Ist der String der Sitzung Null oder leer, geben wir eine Fehlermeldung aus. Falls nicht, rufen wir GDownloadUrl für map.checksession.php auf und senden die Sitzung. Wird ein Nutzername erfolgreich zurückgegeben, zeigen wir dem Nutzer eine Begrüßungsseite an, geben das Formular zum Hinzufügen eines Standortes zur Ansicht frei und laden die Karte darin. Das Formular besteht aus einem Adresstextfeld, einer Karte und Textfeldern für den Standortnamen und den geografischen Breiten- und Längenangaben. Wenn der Nutzer den Breiten- und Längengrad des Standorts noch nicht kennt, kann er ihn ermitteln, indem er die Adresse in das Formular eingibt und auf „Senden“ klickt. Dadurch wird ein Aufruf an den GClientGeocoder der Map API gesendet. Wenn die Adresse gefunden wird, wird eine Markierung auf der Karte platziert und die Textfelder für Breiten- und Längengrad werden automatisch ausgefüllt.

Wenn der Nutzer zufrieden ist, kann er auf die Schaltfläche „Standort hinzufügen“ klicken. Anschließend rufen wir in JavaScript die Werte für „user“, „place“, „lat“ und „lng“ ab und senden sie mit GDownloadUrl an das Script „communitymap_addlocation.php“.

Wenn das Skript „success“ zurückgibt, wird eine Erfolgsmeldung auf dem Bildschirm angezeigt.

Unten sehen Sie einen Screenshot und Code für eine Beispielseite zum Hinzufügen eines Orts (communitymap_addlocation.htm):

<!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>Community Map - Add a Place!</title>

    <script src="http://maps.google.com/maps?file=api&v=2.x&key=abcdef" type="text/javascript"></script>
    <script src="cookies.js" type="text/javascript"></script>
    <script type="text/javascript">
    //<![CDATA[

    var map = null;
    var geocoder = null; 
    var session = null;

    function load() {
      session = getCookie('session');
      if (session != null && session != "") {
        url = "communitymap_checksession.php?session=" + session;
        GDownloadUrl(url, function(data, responseCode) {
          if (data.length > 0) {
            document.getElementById("message").innerHTML = "Welcome " + data;
            document.getElementById("content").style.display = "block";
            map = new GMap2(document.getElementById("map"));
            map.setCenter(new GLatLng(37.4419, -122.1419), 13);
            geocoder = new GClientGeocoder();
          }
        });
      } else {
        document.getElementById("message").innerHTML = "Error: Not logged in.";
      }
    }

    function addLocation() {
      var place = document.getElementById("place").value;
      var lat = document.getElementById("lat").value;
      var lng = document.getElementById("lng").value;

      var url = "communitymap_addlocation.php?session=" + session + "&place=" + place +
                "&lat=" + lat + "&lng=" + lng;
      GDownloadUrl(url, function(data, responseCode) {
        GLog.write(data);
        if (data.length > 0) {
          document.getElementById("message").innerHTML = "Location added.";
        }
      });
    }

    function showAddress(address) {
      if (geocoder) {
        geocoder.getLatLng(
          address,
          function(point) {
            if (!point) {
              alert(address + " not found");
            } else {
              map.setCenter(point, 13);
              var marker = new GMarker(point, {draggable:true});
              document.getElementById("lat").value = marker.getPoint().lat().toFixed(6);
              document.getElementById("lng").value = marker.getPoint().lng().toFixed(6);

              map.addOverlay(marker);
              GEvent.addListener(marker, "dragend", function() {
                document.getElementById("lat").value = marker.getPoint().lat().toFixed(6);
                document.getElementById("lng").value = marker.getPoint().lng().toFixed(6);
	      });
            }
          }
        );
      }
    }
    //]]>

    </script>

  </head>

  <body onload="load()" onunload="GUnload()">
   <div id="message"></div>
   <div id="content" style="display:none">

   <form action="#" onsubmit="showAddress(this.address.value); return false">
        <p>
        <input type="text" size="60" name="address" value="1600 Amphitheatre Pky, Mountain View, CA" />
        <input type="submit" value="Geocode!" />

    </form>
      </p>

      <div id="map" style="width: 500px; height: 300px"></div>
 
 	Place name: <input type="text" size="20" id="place" value="" />
	<br/>
 	Lat: <input type="text" size="20" id="lat" value="" />
	<br/>

 	Lng: <input type="text" size="20" id="lng" value="" />

        <br/>
	<input type="button" onclick="addLocation()" value="Add a location" />
    </form>
    </div>

  </body>
</html>

Die Karte erstellen

Da Sie das Arbeitsblatt im ersten Schritt veröffentlicht haben, ist keine serverseitige Programmierung erforderlich, um eine Karte hieraus zu erstellen. In der Tat ist überhaupt keine Programmierung erforderlich. Sie können den Tabellen -> Kartenassistenten verwenden, um den gesamten Code für die Karte zu generieren. Der Assistent lädt die Einträge des Arbeitsblattes auf die Seite herunter, indem er ein Skript-Tag, das auf die JSON-Ausgabe für den Feed verweist, anhängt, und spezifiziert eine Callback-Funktion, die aufgerufen wird, sobald der JSON heruntergeladen wurde. Weitere Informationen

mainmap.htm finden Sie Beispiel-HTML-Code dafür. Nachfolgend finden Sie einen Screenshot:

Fazit

Hoffentlich läuft auf Ihrem Server nun Ihr ganz persönliches Kartensystem mit Nutzerteilnahme. In diesem Artikel finden Sie den grundlegenden Code für die wesentlichen Aspekte dieses Systems. Da Sie jetzt aber mit der Zend Spreadsheets-Bibliothek vertraut sind, sollten Sie das System an Ihre speziellen Anforderungen anpassen können. Wenn Sie auf dem Weg dorthin auf Fehler gestoßen sind, können Sie zum Debuggen den Befehl echo in PHP oder GLog.write() der Maps API in JavaScript verwenden. Außerdem können Sie jederzeit in den Entwicklerforen der Maps API oder Spreadsheets API posten, um zusätzliche Hilfe zu erhalten.