Tworzenie mapy z danymi od użytkowników za pomocą PHP i Arkuszach Google

Pamela Fox, zespół interfejsu API Map Google
Listopad 2007 r.

Cel

W internecie jest wiele społeczności skupionych wokół lokalizacji geograficznych i zainteresowań: osób, które uwielbiają muzea, europejskie katedry, parki stanowe itp. Zawsze jest więc potrzeba, aby deweloper (taki jak Ty) stworzył system, w którym użytkownicy mogą dodawać do mapy miejsca z geotagami. Właśnie to zrobimy. Po przeczytaniu tego artykułu będziesz mieć system, w którym użytkownicy mogą się rejestrować, logować i dodawać miejsca z geotagami. System będzie używać AJAX-a do obsługi interfejsu, PHP do skryptów po stronie serwera, a Arkuszy Google do przechowywania danych. Jeśli do przechowywania danych używasz baz danych MySQL, możesz łatwo zmodyfikować ten kod, aby zamiast tego używać backendu bazy danych MySQL.

Ten artykuł jest podzielony na te kroki:


Konfigurowanie arkusza kalkulacyjnego

Do przechowywania wszystkich danych tego systemu będziemy używać Arkuszy Google. Musimy przechowywać 2 rodzaje danych: informacje o kontach użytkowników i miejsca dodane przez użytkowników. Utworzymy więc po jednym arkuszu dla każdego rodzaju danych. Będziemy wchodzić w interakcje z arkuszami za pomocą pliku danych listy, który opiera się na tym, że pierwszy wiersz arkusza zawiera etykiety kolumn, a każdy kolejny wiersz zawiera dane.

Otwórz docs.google.com i utwórz nowy arkusz kalkulacyjny. Zmień nazwę domyślnego arkusza na „Users” i utwórz kolumny o nazwach „user”, „password” i „session”. Następnie dodaj kolejny arkusz, zmień jego nazwę na „Locations” i utwórz kolumny o nazwach „user”, „status”, „lat”, „lng” i „date”. Jeśli nie chcesz wykonywać tych czynności ręcznie, pobierz ten szablon i zaimportuj go do Arkuszy Google za pomocą polecenia Plik –> Importuj.

Informacje o koncie użytkownika muszą być prywatne (widoczne tylko dla właściciela arkusza kalkulacyjnego – Ciebie), a miejsca dodane przez użytkownika będą wyświetlane na publicznie widocznej mapie. Na szczęście Arkusze Google umożliwiają selektywne decydowanie, które arkusze w arkuszu kalkulacyjnym mogą być publiczne, a które powinny pozostać prywatne (domyślnie). Aby opublikować arkusz „Lokalizacje”, kliknij kartę „Opublikuj”, a potem „Opublikuj teraz”. Zaznacz pole wyboru „Automatycznie publikuj ponownie”, a w menu „Które części?” wybierz „Tylko arkusz „Lokalizacje””. Prawidłowe opcje są widoczne na zrzucie ekranu poniżej:

Praca z Zend GData Framework

Google Spreadsheets API udostępnia interfejs HTTP do operacji CRUD, takich jak pobieranie, wstawianie, aktualizowanie i usuwanie wierszy. Zend Framework udostępnia otoczkę PHP dla interfejsu API (i innych interfejsów GData API), dzięki czemu nie musisz się martwić implementacją surowych operacji HTTP. Zend Framework wymaga PHP 5.

Jeśli nie masz jeszcze platformy Zend, pobierz ją i prześlij na serwer. Framework jest dostępny tutaj:http://framework.zend.com/download/gdata.

Zmodyfikuj ścieżkę include_path w PHP, aby uwzględnić bibliotekę Zend. Możesz to zrobić na kilka sposobów, w zależności od poziomu uprawnień administracyjnych na serwerze. Jednym ze sposobów jest dodanie tego wiersza powyżej instrukcji require w dowolnych plikach PHP korzystających z biblioteki:

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

Aby to sprawdzić, uruchom wersję demonstracyjną Arkuszy, wpisując w wierszu poleceń w folderze demos/Zend/Gdata:

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

Jeśli wszystko działa prawidłowo, powinna wyświetlić się lista Twoich arkuszy kalkulacyjnych. Jeśli pojawi się błąd, sprawdź, czy ścieżka dołączania jest prawidłowo ustawiona i czy masz zainstalowaną wersję PHP 5.

Tworzenie funkcji globalnych

Wszystkie skrypty PHP, które będziemy pisać na potrzeby Mapy społeczności, będą korzystać z tych samych plików dołączanych, zmiennych i funkcji, które umieścimy w jednym pliku.

Na początku pliku umieścimy niezbędne instrukcje dołączenia i załadowania biblioteki Zend, zaczerpnięte z przykładu Spreadsheets-ClientLogin.php.

Następnie zdefiniujemy stałe, które będą używane w plikach: klucz arkusza kalkulacyjnego i identyfikatory 2 arkuszy. Aby znaleźć informacje o arkuszu kalkulacyjnym, otwórz go, kliknij kartę „Publikuj” i wybierz „Więcej opcji publikowania”. Z listy Format pliku wybierz „ATOM” i kliknij „Wygeneruj URL”. Zobaczysz coś takiego:

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

Klucz arkusza kalkulacyjnego to długi ciąg alfanumeryczny po „/list/,”, a identyfikator arkusza to ciąg 3 znaków po nim. Aby znaleźć identyfikator innego arkusza, wybierz go z menu „Które arkusze?”.

Następnie utworzymy 3 funkcje: setupClient, getWkshtListFeed i printFeed. W funkcji setupClient ustawimy nazwę użytkownika i hasło Gmaila, uwierzytelnimy się za pomocą ClientLogin i zwrócimy obiekt Zend_Gdata_Spreadsheets. W funkcji getWkshtListFeed zwrócimy kanał listy Arkuszy kalkulacyjnych dla danego klucza arkusza kalkulacyjnego i identyfikatora arkusza, z opcjonalnym zapytaniem dotyczącym arkuszy kalkulacyjnych (link). Funkcja printFeed pochodzi z przykładu Spreadsheets-ClientLogin.php i może być przydatna do debugowania. Pobiera obiekt z pliku danych i wyświetla go na ekranie.

Kod PHP, który to robi, jest pokazany poniżej (communitymap_globals.php):

<?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++;
  }
}
 
?>

Rejestracja nowego użytkownika

Aby zarejestrować nowego użytkownika, potrzebujemy strony HTML widocznej dla użytkownika z polami tekstowymi i przyciskiem przesyłania oraz skryptu PHP na backendzie, który doda użytkownika do arkusza kalkulacyjnego.

W skrypcie PHP najpierw umieszczamy skrypt globalny, a potem pobieramy wartości nazwy użytkownika i hasła ze zmiennej GET. Następnie konfigurujemy klienta Arkuszy i wysyłamy żądanie do pliku danych listy użytkowników z ciągiem zapytania, aby ograniczyć wyniki tylko do wierszy, w których kolumna nazwy użytkownika jest równa nazwie użytkownika przekazanej do skryptu. Jeśli w wyniku pliku danych listy nie otrzymamy żadnych wierszy, możemy bezpiecznie kontynuować, wiedząc, że przekazana nazwa użytkownika jest unikalna. Przed wstawieniem wiersza do pliku danych listy tworzymy tablicę asocjacyjną wartości kolumn: nazwy użytkownika, zaszyfrowanego hasła za pomocą funkcji sha1 w PHP i znaku wypełniającego sesję. Następnie wywołujemy funkcję insertRow w kliencie arkuszy kalkulacyjnych, przekazując tablicę asocjacyjną, klucz arkuszy kalkulacyjnych i identyfikator arkusza. Jeśli zwrócony obiekt to ListFeedEntry, wyświetlamy komunikat Success! (Sukces!).

Kod PHP, który to robi, jest pokazany poniżej (communitymap_newuser.php):

<?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!";
}
?>

Na stronie rejestracji możemy uwzględnić interfejs Maps API, aby używać jego funkcji opakowującej XMLHttpRequest o nazwie GDownloadUrl. Gdy użytkownik kliknie przycisk przesyłania, pobierzemy nazwę użytkownika i hasło z pól tekstowych, utworzymy ciąg parametrów z ich wartości i wywołamy funkcję GDownloadUrl na adresie URL skryptu i parametrach. Ponieważ wysyłamy informacje poufne, używamy wersji HTTP POST funkcji GDownloadUrl (przekazując parametry jako trzeci argument zamiast dołączać je do adresu URL). W funkcji wywołania zwrotnego sprawdzimy, czy odpowiedź jest prawidłowa, i wyświetlimy odpowiedni komunikat dla użytkownika.

Poniżej znajdziesz zrzut ekranu i kod przykładowej strony rejestracji (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>

Logowanie użytkownika

Aby umożliwić użytkownikom logowanie się w naszym systemie, potrzebujemy strony HTML, która będzie wyświetlać prośbę o podanie nazwy użytkownika i hasła, oraz skryptu PHP, który będzie weryfikować dane logowania, tworzyć identyfikator sesji i przekazywać go z powrotem na stronę logowania, aby ustawić plik cookie. Użytkownik pozostanie zalogowany na kolejnych stronach dzięki plikowi cookie sesji.

W skrypcie PHP najpierw umieszczamy skrypt globalny, a potem pobieramy wartości nazwy użytkownika i hasła ze zmiennej GET. Następnie konfigurujemy klienta Arkuszy i wysyłamy żądanie do pliku danych listy użytkowników z ciągiem zapytania, aby ograniczyć wyniki tylko do wierszy, w których kolumna nazwy użytkownika jest równa nazwie użytkownika przekazanej do skryptu.

W zwróconym wierszu sprawdzimy, czy skrót przekazanego hasła jest zgodny ze skrótem zapisanym w arkuszu kalkulacyjnym. Jeśli tak, utworzymy identyfikator sesji za pomocą funkcji md5, uniqid i rand. Następnie zaktualizujemy wiersz w arkuszu kalkulacyjnym o sesję i wyświetlimy go na ekranie, jeśli aktualizacja wiersza się powiedzie.

Poniżej znajdziesz kod PHP, który to robi (communitymap_loginuser.php):

<?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"];
    }
  }
}
?>

Na stronie logowania możemy ponownie uwzględnić interfejs Maps API, aby używać jego funkcji opakowującej XMLHttpRequest o nazwie GDownloadUrl. Gdy użytkownik kliknie przycisk przesyłania, pobierzemy nazwę użytkownika i hasło z pól tekstowych, utworzymy adres URL skryptu z parametrami zapytania i wywołamy funkcję GDownloadUrl na tym adresie. W funkcji wywołania zwrotnego ustawimy plik cookie z identyfikatorem sesji zwróconym przez skrypt lub wyświetlimy komunikat o błędzie, jeśli nie zostanie zwrócony żaden identyfikator. Funkcja setCookie pochodzi z pliku cookies.js, który jest oparty na samouczku JavaScript w3c: http://www.w3schools.com/js/js_cookies.asp.

Poniżej znajdziesz zrzut ekranu i kod przykładowej strony logowania (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>

Zezwalanie użytkownikom na dodawanie miejsc na mapie

Aby umożliwić użytkownikowi dodawanie miejsc do naszej mapy, potrzebujemy strony HTML widocznej dla użytkownika, na której będzie on mógł podać informacje o lokalizacji, oraz 2 skryptów PHP – jednego do sprawdzania, czy użytkownik jest zalogowany za pomocą ustawionego przez nas pliku cookie, a drugiego do dodawania lokalizacji do arkusza lokalizacji.

W pierwszym skrypcie PHP, który sprawdza, czy użytkownik jest zalogowany, najpierw dołączamy skrypt globalny, a następnie pobieramy wartość sesji ze zmiennej GET. Następnie konfigurujemy klienta Arkuszy kalkulacyjnych i wysyłamy żądanie do pliku danych listy dla arkusza użytkowników z ciągiem zapytania, aby ograniczyć wyniki tylko do tych wierszy, w których kolumna sesji jest równa wartości sesji przekazanej do skryptu. Następnie przechodzimy przez niestandardowe wpisy w tym pliku danych (odpowiadające nagłówkom kolumn) i wyświetlamy odpowiednią nazwę użytkownika dla danej sesji, jeśli taka istnieje.

Poniżej znajdziesz kod PHP, który to robi (communitymap_checksession.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") {
      echo $customEntry->getText();
    }
  }
}
?>

W drugim skrypcie PHP, który umożliwia użytkownikowi dodanie lokalizacji, najpierw powielamy kod ze skryptu communitymap_checksession.php, aby mieć pewność, że użytkownik jest nadal zalogowany i ma prawidłowe uprawnienia. Gdy z arkusza użytkowników otrzymamy prawidłową nazwę użytkownika, pobieramy wartości miejsca, szerokości i długości geograficznej ze zmiennej GET. Wszystkie te wartości umieszczamy w tablicy asocjacyjnej, a także dodajemy wartość „date” za pomocą funkcji date() w PHP, aby wiedzieć, kiedy użytkownik dodał miejsce. Do funkcji insertRow przekazujemy tablicę asocjacyjną, stałą klucza arkuszy kalkulacyjnych i stałą identyfikatora arkusza lokalizacji. Jeśli do arkusza zostanie dodany wiersz z nową lokalizacją, wyświetlimy komunikat „Success” (Sukces). Jeśli na tym etapie pojawi się błąd, prawdopodobnie przyczyną jest niezgodność nazw nagłówków kolumn. Klucze w tablicy asocjacyjnej muszą być zgodne z nagłówkami kolumn w arkuszu określonym przez klucz arkusza kalkulacyjnego i identyfikator arkusza.

Kod PHP, który to robi, jest pokazany poniżej (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";
  }
}

?>

Na stronie dodawania lokalizacji możemy ponownie uwzględnić interfejs Maps API, aby użyć funkcji GDownloadUrl i utworzyć mapę. Po wczytaniu strony używamy funkcji getCookie z pliku cookies.js, aby pobrać wartość sesji. Jeśli ciąg sesji jest pusty lub ma wartość null, wyświetlamy komunikat o błędzie. Jeśli nie, wywołujemy GDownloadUrl w pliku map.checksession.php, wysyłając sesję. Jeśli zwróci ona nazwę użytkownika, wyświetlimy mu wiadomość powitalną, pokażemy formularz dodawania lokalizacji i wczytamy mapę. Formularz składa się z pola tekstowego adresu, mapy oraz pól tekstowych nazwy miejsca, szerokości i długości geograficznej. Jeśli użytkownik nie zna szerokości i długości geograficznej lokalizacji, może ją geokodować, wpisując adres w formularzu i klikając „Prześlij”. Spowoduje to wysłanie wywołania do interfejsu Map API GClientGeocoder, który umieści na mapie marker, jeśli znajdzie adres, i automatycznie wypełni pola tekstowe szerokości i długości geograficznej.

Gdy użytkownik będzie zadowolony, może nacisnąć przycisk „Dodaj lokalizację”. Następnie w JavaScript uzyskamy wartości dla użytkownika, miejsca, szerokości i długości geograficznej i wyślemy je do skryptu communitymap_addlocation.php za pomocą GDownloadUrl.

Jeśli skrypt zwróci wartość wskazującą powodzenie, wyświetlimy na ekranie komunikat o powodzeniu.

Poniżej znajdziesz zrzut ekranu i kod przykładowej strony dodawania lokalizacji (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>

Tworzenie mapy

Ponieważ w pierwszym kroku arkusz lokalizacji został udostępniony publicznie, do utworzenia mapy nie jest wymagane programowanie po stronie serwera. W rzeczywistości nie musisz niczego programować. Możesz użyć tego kreatora Arkusze –> Mapa, który wygeneruje cały kod potrzebny do utworzenia mapy. Kreator pobiera wpisy z arkusza do strony, dodając tag skryptu, który wskazuje dane wyjściowe JSON pliku danych, i określa funkcję wywołania zwrotnego, która jest wywoływana po pobraniu pliku JSON. Więcej informacji znajdziesz tutaj.

Przykładowy kod HTML, który to umożliwia, znajdziesz tutaj: mainmap.htm. Poniżej znajdziesz zrzut ekranu:

Podsumowanie

Mamy nadzieję, że na Twoim serwerze działa już system map tworzonych przez użytkowników. W tym artykule znajdziesz podstawowy kod potrzebny do działania najważniejszych elementów tego systemu. Teraz, gdy znasz już bibliotekę Zend Spreadsheets, możesz rozbudować system, aby spełniał Twoje konkretne potrzeby. Jeśli napotkasz błędy, pamiętaj, że do debugowania możesz użyć polecenia echo w PHP lub polecenia GLog.write() w interfejsie Map API w JavaScript. Zawsze możesz też opublikować posta na forum dla programistów interfejsu Maps API lub interfejsu Spreadsheets API, aby uzyskać dodatkową pomoc.