PHP ve Google E-Tablolar ile Kullanıcı Tarafından Gönderilen Harita Oluşturma

Pamela Fox, Google Maps API Ekibi
Kasım 2007

Hedef

Web, coğrafi bölgeler ve ilgi alanları etrafında toplanan topluluklarla dolu: müzeleri, Avrupa katedrallerini, milli parkları vb. seven insanlar. Bu nedenle, kullanıcıların coğrafi etiketli yerleri bir haritaya ekleyebileceği bir sistem oluşturmak için her zaman bir geliştiriciye (sizin gibi!) ihtiyaç vardır ve burada tam olarak bunu yapacağız. Bu makalenin sonunda, kullanıcıların kaydolabileceği, giriş yapabileceği ve coğrafi etiketli yerler ekleyebileceği bir sisteminiz olacak. Sistem, ön uç için AJAX, sunucu tarafı komut dosyası oluşturma için PHP ve depolama için Google E-Tablolar'ı kullanacak. Depolama için MySQL veritabanlarını kullanmaya alışkınsanız buradaki kodu kolayca değiştirerek bunun yerine MySQL veritabanı arka ucu kullanabilirsiniz.

Bu makale aşağıdaki adımlara ayrılmıştır:


E-tabloyu ayarlama

Bu sistemdeki tüm verileri depolamak için Google E-Tablolar'ı kullanacağız. Saklamamız gereken iki tür veri vardır: kullanıcı hesabı bilgileri ve kullanıcı tarafından eklenen yerler. Bu nedenle, her veri türü için bir çalışma sayfası oluşturacağız. E-tablolarla, liste feed'lerini kullanarak etkileşim kuracağız. Liste feed'leri, sütun etiketlerini içeren bir e-tablonun ilk satırına ve verileri içeren sonraki her satıra dayanır.

docs.google.com adresine gidip yeni bir e-tablo oluşturun. Varsayılan çalışma sayfasını "Kullanıcılar" olarak yeniden adlandırın ve "kullanıcı", "şifre" ve "oturum" adlı sütunlar oluşturun. Ardından başka bir sayfa ekleyin, bu sayfayı "Konumlar" olarak yeniden adlandırın ve "user", "status", "lat", "lng" ve "date" adlı sütunlar oluşturun. Alternatif olarak, bu kadar çok manuel işlem yapmak istemiyorsanız bu şablonu indirip Dosya -> İçe aktar komutuyla Google E-Tablolar'a aktarın.

Kullanıcı hesabı bilgileri gizli tutulmalı (yalnızca e-tablo sahibi olan size görünür) ve kullanıcı tarafından eklenen yerler herkese açık bir haritada gösterilmelidir. Neyse ki Google E-Tablolar, bir e-tablodaki hangi çalışma sayfalarının herkese açık olabileceğine ve hangilerinin gizli kalması gerektiğine (varsayılan) seçici bir şekilde karar vermenize olanak tanır. "Konumlar" çalışma sayfasını yayınlamak için "Yayınla" sekmesini tıklayın, "Şimdi yayınla"yı tıklayın, "Otomatik olarak yeniden yayınla" onay kutusunu işaretleyin ve ardından "Hangi bölümler?" açılır listesinde "Yalnızca "Konumlar" sayfası"nı seçin. Doğru seçenekler aşağıdaki ekran görüntüsünde gösterilmiştir:

Zend GData Framework ile çalışma

Google Spreadsheets API, satırları alma, satır ekleme, satırları güncelleme ve satırları silme gibi CRUD işlemleri için bir HTTP arayüzü sağlar. Zend Framework, API'nin (ve diğer GData API'lerinin) üzerinde bir PHP sarmalayıcı sağlar. Böylece, ham HTTP işlemlerini uygulama konusunda endişelenmenize gerek kalmaz. Zend Framework için PHP 5 gerekir.

Henüz yapmadıysanız Zend Framework'ü indirip sunucunuza yükleyin. Çerçeveye şu adresten ulaşabilirsiniz: http://framework.zend.com/download/gdata.

Zend kitaplığını içerecek şekilde PHP include_path'inizi değiştirmeniz gerekir. Sunucunuzdaki yönetim haklarının düzeyine bağlı olarak bunu yapmanın çeşitli yolları vardır. Bunun bir yolu, kitaplığı kullanan tüm PHP dosyalarındaki require ifadelerinin üzerine şu satırı eklemektir:

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

Özelliği test etmek için demos/Zend/Gdata klasöründeki komut satırına şunu girerek E-Tablolar demosunu çalıştırın:

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

Çalışıyorsa e-tablolarınızın listesini görürsünüz. Hata alırsanız include yolunuzun doğru ayarlandığından ve PHP 5'in yüklendiğinden emin olun.

Genel işlevler oluşturma

Topluluk Haritası için yazacağımız tüm PHP komut dosyaları, tek bir dosyaya yerleştireceğimiz ortak dahil etme işlemleri, değişkenler ve işlevler kullanacak.

Dosyanın başında, Spreadsheets-ClientLogin.php örneğinden alınan Zend kitaplığını dahil etmek ve yüklemek için gerekli ifadeler yer alır.

Ardından, dosyalar boyunca kullanılacak sabitleri (e-tablo anahtarı ve iki çalışma sayfası kimliği) tanımlayacağız. E-tablonuzla ilgili bilgileri bulmak için e-tablonuzu açın, "Yayınla" sekmesini ve "Diğer yayınlama seçenekleri"ni tıklayın. Dosya Biçimi açılır listesinden "ATOM"u seçin ve "URL Oluştur"u tıklayın. Şuna benzer bir ifade görürsünüz:

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

E-tablo anahtarı, "/list/," karakterlerinden sonra gelen uzun alfanümerik dizedir. Çalışma sayfası kimliği ise bundan sonra gelen 3 karakterlik dizedir. Diğer çalışma sayfası kimliğini bulmak için "Hangi sayfalar?" açılır listesinden diğer sayfayı seçin.

Ardından setupClient, getWkshtListFeed ve printFeed olmak üzere 3 işlev oluşturacağız. setupClient'ta Gmail kullanıcı adımızı ve şifremizi ayarlayacak, ClientLogin ile kimlik doğrulayacak ve bir Zend_Gdata_Spreadsheets nesnesi döndüreceğiz. getWkshtListFeed işlevinde, belirli bir e-tablo anahtarı ve çalışma sayfası kimliği için isteğe bağlı bir e-tablo sorgusu (bağlantı) içeren bir E-Tablolar liste feed'i döndürülür. printFeed işlevi, Spreadsheets-ClientLogin.php örneğinden alınmıştır ve hata ayıklama konusunda size yardımcı olabilir. Bir feed nesnesi alır ve ekrana yazdırır.

Bunu yapan PHP kodu aşağıda gösterilmiştir (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++;
  }
}
 
?>

Yeni kullanıcı kaydetme

Yeni bir kullanıcı kaydetmek için metin alanları ve bir gönder düğmesi içeren, kullanıcıya yönelik bir HTML sayfası ve kullanıcıyı elektronik tabloya eklemek için bir PHP arka uç komut dosyası gerekir.

PHP komut dosyasında önce genel komut dosyasını dahil ederiz, ardından kullanıcı adı ve şifre değerlerini GET değişkeninden alırız. Ardından bir E-Tablolar istemcisi oluşturup sonuçları yalnızca kullanıcı adı sütununun, komut dosyasına iletilen kullanıcı adıyla eşit olduğu satırlarla sınırlamak için bir sorgu dizesiyle kullanıcı çalışma sayfası için liste feed'ini isteriz. Liste feed'i sonucunda satır yoksa iletilen kullanıcı adının benzersiz olduğunu bilerek güvenle devam edebiliriz. Liste feed'ine bir satır eklemeden önce sütun değerlerinin bir ilişkisel dizisini oluştururuz: kullanıcı adı, PHP'nin sha1 işlevi kullanılarak şifrelenmiş parola ve oturum için bir doldurma karakteri. Ardından, ilişkisel diziyi, elektronik tablo anahtarını ve çalışma sayfası kimliğini ileterek elektronik tablo istemcisinde insertRow'u çağırırız. Döndürülen nesne bir ListFeedEntry ise Başarılı! mesajı verilir.

Bunu yapan PHP kodu aşağıda gösterilmiştir (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!";
}
?>

Kayıt sayfasında, GDownloadUrl adlı XMLHttpRequest sarmalayıcı işlevini kullanabilmek için Maps API'yi ekleyebiliriz. Kullanıcı gönder düğmesini tıkladığında, metin alanlarından kullanıcı adı ve şifreyi alırız, değerlerinden bir parametre dizesi oluştururuz ve komut dosyası URL'sinde ve parametrelerde GDownloadUrl'yi çağırırız. Hassas bilgiler gönderdiğimiz için GDownloadUrl'nin HTTP POST sürümünü kullanıyoruz (parametreleri URL'ye eklemek yerine üçüncü bağımsız değişken olarak göndererek). Geri çağırma işlevinde, başarılı bir yanıt olup olmadığını kontrol edip kullanıcıya uygun bir mesaj göndeririz.

Örnek bir kayıt sayfası (communitymap_register.htm) için ekran görüntüsü ve kod aşağıda gösterilmektedir:


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

Kullanıcının oturumunu açma

Kullanıcıların sistemimize giriş yapmasına izin vermek için onlardan kullanıcı adı ve şifrelerini girmelerini isteyen kullanıcıya yönelik bir HTML sayfası ve giriş bilgilerini doğrulayan, oturum kimliği oluşturan ve çerez ayarlamak için giriş sayfasına geri ileten bir PHP komut dosyası gerekir. Kullanıcı, sonraki sayfalarda oturum çerezi aracılığıyla oturumda kalır.

PHP komut dosyasında önce genel komut dosyasını dahil ederiz, ardından kullanıcı adı ve şifre değerlerini GET değişkeninden alırız. Ardından bir E-Tablolar istemcisi oluşturup sonuçları yalnızca kullanıcı adı sütununun, komut dosyasına iletilen kullanıcı adıyla eşit olduğu satırlarla sınırlamak için bir sorgu dizesiyle kullanıcı çalışma sayfası için liste feed'ini isteriz.

Döndürülen satırda, iletilen şifrenin karma değerinin e-tabloda depolanan karma değeriyle eşleşip eşleşmediğini kontrol ederiz. Bu durumda, md5, uniqid ve rand işlevlerini kullanarak bir oturum kimliği oluştururuz. Ardından, e-tablodaki satırı oturumla güncelleyip satır güncelleme işlemi başarılı olursa satırı ekrana yazarız.

Bunu yapan PHP kodu aşağıda gösterilmiştir (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"];
    }
  }
}
?>

Giriş sayfasında, GDownloadUrl adlı XMLHttpRequest sarmalayıcı işlevini kullanabilmek için Maps API'yi tekrar ekleyebiliriz. Kullanıcı gönder düğmesini tıkladığında, metin alanlarından kullanıcı adı ve şifre alınır, sorgu parametreleriyle komut dosyası URL'si oluşturulur ve komut dosyası URL'sinde GDownloadUrl çağrılır. Geri çağırma işlevinde, komut dosyası tarafından döndürülen oturum kimliğini içeren bir çerez ayarlarız veya döndürülen bir kimlik yoksa hata mesajı veririz. setCookie işlevi, w3c JavaScript eğitimine dayalı bir cookies.js dosyasından gelir: http://www.w3schools.com/js/js_cookies.asp.

Örnek bir giriş sayfası (communitymap_login.htm) için ekran görüntüsü ve kod aşağıda gösterilmektedir:


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

Kullanıcıların Harita Yerleri Eklemesine İzin Verme

Kullanıcıların haritamıza yer eklemesine izin vermek için kullanıcıya yönelik bir HTML sayfası oluşturmamız gerekir. Bu sayfa, kullanıcının konum hakkında bilgi vermesine olanak tanır. Ayrıca, iki PHP komut dosyası oluşturmamız gerekir. Bunlardan biri, belirlediğimiz çerez aracılığıyla oturum açıp açmadığını kontrol eder, diğeri ise konumu konumlar çalışma sayfasına ekler.

Kullanıcının oturum açıp açmadığını kontrol eden ilk PHP komut dosyasında önce genel komut dosyasını dahil ederiz, ardından oturum değerini GET değişkeninden alırız. Ardından, bir E-Tablolar istemcisi oluşturup sonuçları yalnızca oturum sütununun, komut dosyasına iletilen oturum değerine eşit olduğu satırlarla sınırlamak için bir sorgu dizesiyle kullanıcı çalışma sayfası için liste feed'i isteğinde bulunuruz. Ardından, bu feed'in özel girişlerini (sütun başlıklarımıza karşılık gelen girişler) yineler ve varsa bu oturum için karşılık gelen kullanıcı adını yazdırırız.

Bunu yapan PHP kodu aşağıda gösterilmiştir (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();
    }
  }
}
?>

Kullanıcının konum eklemesine olanak tanıyan ikinci PHP komut dosyasında, kullanıcının oturumunun hâlâ açık ve geçerli olduğundan emin olmak için önce communitymap_checksession.php dosyasındaki kodu kopyalarız. Ardından, kullanıcılar sayfasından geçerli bir kullanıcı adı aldığımızda GET değişkeninden yer, enlem ve boylam değerlerini alırız. Tüm bu değerleri ilişkisel bir diziye yerleştiririz. Ayrıca, kullanıcının yeri ne zaman eklediğini bilmek için PHP'nin date() işlevini kullanarak bir"tarih" değeri de ekleriz. Bu ilişkisel diziyi, e-tabloların anahtar sabitini ve konumlar çalışma sayfası kimliği sabitini insertRow işlevine iletiyoruz. Yeni konum için e-tabloya bir satır eklenirse "Başarılı" sonucunu veririz. Bu adımda hata alıyorsanız bunun nedeni büyük olasılıkla sütun başlığı adlarındaki uyuşmazlıktır. İlişkisel dizideki anahtarlar, e-tablo anahtarı ve çalışma sayfası kimliğiyle belirtilen çalışma sayfasındaki sütun başlıklarıyla eşleşmelidir.

Bunu yapan PHP kodu aşağıda gösterilmiştir (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";
  }
}

?>

Konum ekleme sayfasında, GDownloadUrl'yi kullanıp harita oluşturabilmek için Haritalar API'sini tekrar ekleyebiliriz. Sayfa yüklendikten sonra, oturum değerini almak için cookies.js dosyasındaki getCookie işlevini kullanırız. Oturum dizesi boşsa veya null ise hata mesajı veririz. Değilse oturumu göndererek map.checksession.php üzerinde GDownloadUrl'yi çağırırız. Bu işlem başarılı bir şekilde kullanıcı adı döndürürse kullanıcıya bir karşılama mesajı gösterir, konum ekleme formunu ortaya çıkarır ve haritayı yükleriz. Formda bir adres metin alanı, harita ve yer adı, enlem ve boylam için metin alanları bulunur. Kullanıcı, konumun enlem/boylamını bilmiyorsa adresi forma girip "Gönder"i tıklayarak coğrafi kodlama yapabilir. Bu işlem, Harita API'sinin GClientGeocoder'ına bir çağrı gönderir. GClientGeocoder, adresi bulursa haritaya bir işaretçi yerleştirir ve enlem/boylam metin alanlarını otomatik olarak doldurur.

Kullanıcı memnun kaldığında "konum ekle" düğmesine basabilir. Ardından, JavaScript'te kullanıcı, yer, enlem ve boylam değerlerini alıp GDownloadUrl ile communitymap_addlocation.php komut dosyasına göndereceğiz.

Bu komut dosyası başarılı olursa ekrana bir başarı mesajı yazdırırız.

Aşağıda örnek bir konum ekleme sayfası (communitymap_addlocation.htm) için ekran görüntüsü ve kod gösterilmektedir:

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

Haritayı oluşturma

Konumlar e-tablosunu ilk adımda herkese açık hale getirdiğiniz için bu konumların haritasını oluşturmak için sunucu taraflı programlama yapmanız gerekmez. Hatta hiç programlama yapmanız gerekmez. Bu E-Tablolar -> Harita sihirbazını kullanarak harita için gereken tüm kodu oluşturabilirsiniz. Sihirbaz, özet akışının JSON çıkışını işaret eden bir komut dosyası etiketi ekleyerek ve JSON indirildikten sonra çağrılan bir geri çağırma işlevi belirterek çalışma sayfası girişlerini sayfaya indirir. Daha fazla bilgiye buradan ulaşabilirsiniz.

Bunu yapmak için örnek HTML kodunu mainmap.htm adresinde bulabilirsiniz. Aşağıda bir ekran görüntüsü gösterilmektedir:

Sonuç

Artık sunucunuzda kendi kullanıcı katkılı harita sisteminizi çalıştırabilirsiniz. Bu makalede, sistemin temel yönleri için gereken en basit kod sağlanmaktadır. Ancak Zend Spreadsheets kitaplığına aşina olduğunuz için sistemi özel ihtiyaçlarınızı karşılayacak şekilde genişletebilirsiniz. Bu süreçte hatalarla karşılaşırsanız hata ayıklama için PHP'de echo komutunu veya JavaScript'te Haritalar API'sinin GLog.write() komutunu kullanabileceğinizi unutmayın. Ayrıca, ek yardım için Haritalar API'si veya E-Tablolar API'si geliştirici forumlarında her zaman yayın paylaşabilirsiniz.