ایجاد نقشه مشارکت کاربر با PHP و صفحات گسترده گوگل

پاملا فاکس، تیم Google Maps API
نوامبر 2007

هدف، واقعگرایانه

وب پر از جوامعی است که حول محورهای جغرافیایی و علایق متمرکز شده اند: افرادی که عاشق موزه ها، کلیساهای جامع اروپایی، پارک های دولتی و غیره هستند. بنابراین، همیشه نیاز به یک توسعه دهنده (مثل شما!) وجود دارد تا سیستمی ایجاد کند که در آن کاربران بتوانند مکان های دارای برچسب جغرافیایی را به اشتراک بگذارند. یک نقشه، و این دقیقاً همان کاری است که ما در اینجا انجام خواهیم داد. در پایان این مقاله، سیستمی خواهید داشت که کاربران می توانند ثبت نام کنند، وارد شوند و مکان های دارای برچسب جغرافیایی را اضافه کنند. این سیستم از AJAX برای قسمت جلویی، PHP برای اسکریپت نویسی سمت سرور و Google Spreadsheets برای ذخیره سازی استفاده خواهد کرد. اگر عادت به استفاده از پایگاه داده MySQL برای ذخیره سازی دارید، می توانید به راحتی کد را در اینجا تغییر دهید تا به جای آن از پایگاه داده MySQL استفاده کنید.

این مقاله به مراحل زیر تقسیم می شود:


تنظیم صفحه گسترده

ما از Google Spreadsheets برای ذخیره تمام داده های این سیستم استفاده خواهیم کرد. دو نوع داده وجود دارد که باید ذخیره کنیم: اطلاعات حساب کاربری و مکان های اضافه شده توسط کاربر، بنابراین برای هر نوع داده یک کاربرگ ایجاد می کنیم. ما با کاربرگ‌ها با استفاده از خوراک فهرست آن‌ها تعامل خواهیم داشت، که متکی به اولین ردیف در یک کاربرگ حاوی برچسب‌های ستون و هر ردیف بعدی حاوی داده است.

از docs.google.com دیدن کنید و یک صفحه گسترده جدید ایجاد کنید. کاربرگ پیش‌فرض را به «کاربران» تغییر نام دهید و ستون‌هایی با نام‌های «user»، «password» و «session» ایجاد کنید. سپس یک برگه دیگر اضافه کنید، نام آن را به "Locations" تغییر دهید و ستون هایی با نام های "user"، "status"، "lat"، "lng" و "date" ایجاد کنید. یا، اگر این همه کار دستی را دوست ندارید، این الگو را دانلود کنید و از طریق دستور File->Import آن را به صفحات گسترده Google وارد کنید.

اطلاعات حساب کاربری باید خصوصی نگه داشته شود (فقط برای مالک صفحه گسترده - شما قابل مشاهده است)، در حالی که مکان های اضافه شده توسط کاربر بر روی یک نقشه قابل مشاهده برای عموم نمایش داده می شوند. خوشبختانه، Google Spreadsheets به شما امکان می دهد به طور انتخابی تصمیم بگیرید که کدام کاربرگ ها در یک صفحه گسترده می توانند عمومی باشند و کدام باید خصوصی بماند (پیش فرض). برای انتشار کاربرگ «مکان‌ها»، روی برگه «انتشار» کلیک کنید، «اکنون منتشر شود»، کادر «انتشار مجدد خودکار» را علامت بزنید و سپس در قسمت «چه قسمت‌هایی؟» کلیک کنید. در منوی کشویی، «فقط «مکان‌ها» برگه را انتخاب کنید. گزینه های صحیح در تصویر زیر نشان داده شده است:

کار با چارچوب Zend GData

Google Spreadsheets API یک رابط HTTP برای عملیات CRUD مانند بازیابی ردیف ها، درج ردیف ها، به روز رسانی ردیف ها و حذف ردیف ها فراهم می کند. Zend Framework یک پوشش PHP در بالای API (و سایر APIهای GData) ارائه می‌کند تا دیگر نگران اجرای عملیات HTTP خام نباشید. چارچوب Zend به PHP 5 نیاز دارد.

اگر قبلاً آن را ندارید، فریمورک Zend را دانلود کرده و آن را در سرور خود آپلود کنید. چارچوب در اینجا موجود است: http://framework.zend.com/download/gdata .

شما باید PHP include_path خود را تغییر دهید تا کتابخانه Zend را شامل شود. روش های مختلفی برای انجام این کار وجود دارد، بسته به سطح حقوق مدیریتی که روی سرور خود دارید. یک راه این است که با استفاده از کتابخانه، این خط را در بالای دستورات مورد نیاز در هر فایل PHP اضافه کنید:

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

برای آزمایش آن، نسخه ی نمایشی صفحات گسترده را با وارد کردن این مورد در خط فرمان در پوشه demos/Zend/Gdata اجرا کنید:

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

اگر کار کرد، باید لیستی از صفحات گسترده خود را مشاهده کنید. اگر با خطا مواجه شدید، بررسی کنید که مسیر include شما به درستی تنظیم شده است و PHP 5 را نصب کرده اید.

ایجاد توابع جهانی

همه اسکریپت‌های PHP که ما برای Community Map می‌نویسیم از شامل، متغیرها و توابع مشترک استفاده می‌کنند که در یک فایل قرار می‌دهیم.

در ابتدای فایل، عبارات لازم برای گنجاندن و بارگذاری کتابخانه Zend را خواهیم داشت که از مثال Spreadsheets-ClientLogin.php گرفته شده است.

سپس ثابت هایی را تعریف می کنیم که در سراسر فایل ها استفاده می شوند: کلید صفحه گسترده و دو شناسه کاربرگ. برای پیدا کردن اطلاعات صفحه‌گسترده خود، آن را باز کنید، روی «انتشار برگه» کلیک کنید و روی «گزینه‌های انتشار بیشتر» کلیک کنید. "ATOM" را از لیست کشویی File Format انتخاب کنید و روی "Generate URL" کلیک کنید. چیزی شبیه این را خواهید دید:

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

کلید صفحه‌گسترده رشته الفبایی طولانی بعد از «/list/» است و شناسه کاربرگ رشته‌ای 3 نویسه‌ای پس از آن است. برای یافتن شناسه کاربرگ دیگر، برگه دیگر را از «چه برگه‌ها؟» انتخاب کنید. کشویی

سپس ما 3 تابع ایجاد خواهیم کرد: setupClient، getWkshtListFeed و printFeed. در setupClient، نام کاربری و رمز عبور GMail خود را تنظیم می کنیم، با ClientLogin احراز هویت می کنیم و یک شی Zend_Gdata_Spreadsheets را برمی گردانیم. در getWkshtListFeed، یک خوراک فهرست صفحات گسترده برای یک کلید صفحه گسترده و شناسه کاربرگ معین، با یک درخواست صفحه گسترده اختیاری (پیوند) را برمی گردانیم. تابع printFeed از مثال Spreadsheets-ClientLogin.php گرفته شده است و ممکن است برای اشکال زدایی برای شما مفید باشد. یک شی فید را می گیرد و روی صفحه چاپ می کند.

PHP که این کار را انجام می دهد در زیر نشان داده شده است ( 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++;
  }
}
 
?>

ثبت نام کاربر جدید

برای ثبت یک کاربر جدید، یک صفحه HTML رو به روی کاربر با فیلدهای متنی و یک دکمه ارسال و یک اسکریپت پشتیبان PHP برای اضافه کردن کاربر به صفحه گسترده می خواهیم.

در اسکریپت PHP ابتدا اسکریپت جهانی را وارد می کنیم و سپس مقادیر نام کاربری و رمز عبور را از متغیر GET دریافت می کنیم. سپس ما یک سرویس گیرنده صفحات گسترده راه اندازی می کنیم، و از فهرست فید برای کاربرگ کاربر با یک رشته پرس و جو درخواست می کنیم تا نتایج را فقط به ردیف هایی که ستون نام کاربری برابر با نام کاربری ارسال شده به اسکریپت است محدود کند. اگر هیچ ردیفی در نتیجه فید لیست دریافت نکردیم، می‌توانیم با خیال راحت ادامه دهیم و بدانیم که نام کاربری ارسال شده منحصر به فرد است. قبل از درج یک ردیف در خوراک لیست، یک آرایه انجمنی از مقادیر ستون ایجاد می کنیم: نام کاربری، رمزگذاری رمز عبور با استفاده از تابع sha1 PHP، و یک کاراکتر پرکننده برای جلسه. سپس insertRow را در سرویس گیرنده صفحات گسترده فراخوانی می کنیم که در آرایه انجمنی، کلید صفحات گسترده و شناسه کاربرگ ارسال می شود. اگر شی برگشتی یک ListFeedEntry باشد، یک خروجی Success می دهیم! پیام

PHP که این کار را انجام می دهد در زیر نشان داده شده است ( 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!";
}
?>

در صفحه ثبت نام، می‌توانیم Maps API را اضافه کنیم تا بتوانیم از تابع پوشش دهنده XMLHttpRequest به نام GDownloadUrl استفاده کنیم. هنگامی که کاربر روی دکمه ارسال کلیک می کند، نام کاربری و رمز عبور را از فیلدهای متنی دریافت می کنیم، رشته پارامترها را از مقادیر آنها می سازیم و GDownloadUrl را روی url و پارامترهای اسکریپت فراخوانی می کنیم. از آنجایی که ما اطلاعات حساسی را ارسال می کنیم، از نسخه HTTP POST GDownloadUrl استفاده می کنیم (با ارسال پارامترها به عنوان آرگومان سوم به جای اضافه کردن آنها به URL). در تابع callback، ما پاسخ موفقیت آمیز را بررسی می کنیم و یک پیام مناسب برای کاربر ارسال می کنیم.

یک اسکرین شات و کد برای نمونه صفحه ثبت نام در زیر نشان داده شده است ( 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>

ورود به سیستم یک کاربر

برای اینکه به کاربران اجازه ورود به سیستم ما را بدهیم، یک صفحه HTML رو به روی کاربر می‌خواهیم تا از آنها نام کاربری و رمز عبور خود را بخواهد - و یک اسکریپت PHP برای تأیید اطلاعات ورود، ایجاد یک شناسه جلسه و ارسال آن به ورود به سیستم. صفحه برای تنظیم یک کوکی کاربر از طریق کوکی جلسه در صفحات بعدی وارد سیستم خواهد شد.

در اسکریپت PHP ابتدا اسکریپت جهانی را وارد می کنیم و سپس مقادیر نام کاربری و رمز عبور را از متغیر GET دریافت می کنیم. سپس ما یک سرویس گیرنده صفحات گسترده راه اندازی می کنیم، و از فهرست فید برای کاربرگ کاربر با یک رشته پرس و جو درخواست می کنیم تا نتایج را فقط به ردیف هایی که ستون نام کاربری برابر با نام کاربری ارسال شده به اسکریپت است محدود کند.

در ردیفی که برگردانده شده است، بررسی می کنیم که هش رمز عبور ارسال شده با هش ذخیره شده در صفحه گسترده مطابقت داشته باشد. اگر اینطور باشد، با استفاده از توابع md5، uniqid و rand یک شناسه جلسه ایجاد می کنیم. سپس ردیف را در صفحه گسترده با جلسه به‌روزرسانی می‌کنیم و در صورت موفقیت آمیز بودن به‌روزرسانی ردیف، آن را به صفحه نمایش می‌دهیم.

PHP که این کار را انجام می دهد در زیر نشان داده شده است ( 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"];
    }
  }
}
?>

در صفحه ورود، دوباره می‌توانیم Maps API را اضافه کنیم تا بتوانیم از تابع پوشش XMLHttpRequest به نام GDownloadUrl استفاده کنیم. هنگامی که کاربر روی دکمه ارسال کلیک می کند، نام کاربری و رمز عبور را از قسمت های متنی دریافت می کنیم، URL اسکریپت را با پارامترهای پرس و جو می سازیم و GDownloadUrl را در آدرس اسکریپت فراخوانی می کنیم. در تابع callback، یک کوکی با شناسه جلسه که توسط اسکریپت برگردانده می شود، تنظیم می کنیم، یا اگر هیچ کدام برگردانده نشد، یک پیام خطا را خروجی می دهیم. تابع setCookie از یک cookies.js است که بر اساس آموزش جاوا اسکریپت w3c است: http://www.w3schools.com/js/js_cookies.asp.

یک اسکرین شات و کد در زیر برای یک صفحه ورود نمونه نشان داده شده است ( 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>

امکان افزودن مکان‌های نقشه به کاربران

برای اینکه به کاربر اجازه دهیم مکان‌ها را به نقشه ما اضافه کند، یک صفحه HTML رو به روی کاربر می‌خواهیم که به او اجازه می‌دهد اطلاعاتی در مورد مکان ارائه دهد و دو اسکریپت PHP - یکی برای بررسی اینکه آیا از طریق کوکی‌ای که تنظیم کرده‌ایم وارد سیستم شده‌اند، و دیگری برای افزودن مکان به کاربرگ مکان‌ها.

در اولین اسکریپت PHP که بررسی می کند آیا کاربر وارد شده است یا خیر، ابتدا اسکریپت جهانی را اضافه می کنیم و سپس مقدار session را از متغیر GET دریافت می کنیم. سپس ما یک کلاینت صفحات گسترده راه اندازی می کنیم، و از فهرست فید برای کاربرگ کاربر با یک رشته پرس و جو درخواست می کنیم تا نتایج را فقط به ردیف هایی محدود کند که ستون جلسه برابر با مقدار جلسه ارسال شده به اسکریپت باشد. سپس از طریق ورودی های سفارشی آن فید (آنهایی که با سرفصل های ستون ما مطابقت دارند) را تکرار می کنیم و نام کاربری مربوطه را برای آن جلسه در صورت وجود چاپ می کنیم.

PHP که این کار را انجام می دهد در زیر نشان داده شده است ( 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();
    }
  }
}
?>

در اسکریپت دوم PHP که به کاربر اجازه می‌دهد یک مکان اضافه کند، ابتدا کد را از communitymap_checkession.php تکرار می‌کنیم تا مطمئن شویم کاربر هنوز وارد سیستم شده و معتبر است. سپس هنگامی که یک نام کاربری معتبر را از برگه کاربران برگردانیم، مقادیر place، lat و lng را از متغیر GET دریافت می کنیم. همه آن مقادیر را در یک آرایه انجمنی قرار می دهیم و همچنین با استفاده از تابع date() PHP یک مقدار "date" اضافه می کنیم تا بدانیم کاربر چه زمانی مکان را اضافه کرده است. آن آرایه انجمنی، ثابت کلید صفحات گسترده، و ثابت id کاربرگ مکان ها را به تابع insertRow منتقل می کنیم. سپس اگر یک ردیف برای مکان جدید به صفحه گسترده اضافه شود، "موفقیت" را خروجی می دهیم. اگر در این مرحله خطایی دریافت می‌کنید، احتمالاً به دلیل عدم تطابق در نام‌های سرصفحه ستون است. کلیدهای موجود در آرایه انجمنی باید با سرصفحه های ستون در کاربرگ مشخص شده توسط کلید صفحه گسترده و شناسه کاربرگ مطابقت داشته باشند.

PHP که این کار را انجام می دهد در زیر نشان داده شده است ( 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";
  }
}

?>

در صفحه افزودن مکان، می‌توانیم دوباره Maps API را اضافه کنیم تا بتوانیم از GDownloadUrl استفاده کنیم و یک نقشه ایجاد کنیم. پس از بارگیری صفحه، از تابع getCookie از cookies.js برای بازیابی مقدار جلسه استفاده می کنیم. اگر رشته جلسه خالی یا تهی باشد، یک پیام خطا ارسال می کنیم. اگر اینطور نیست، ما با GDownloadUrl در map.checkession.php تماس می گیریم و در جلسه ارسال می کنیم. اگر با موفقیت یک نام کاربری را برگرداند، یک پیام خوشامدگویی به کاربر نمایش می‌دهیم، فرم افزودن موقعیت مکانی را نشان می‌دهیم و نقشه را بارگیری می‌کنیم. این فرم شامل یک قسمت متن آدرس، نقشه و فیلدهای متنی برای نام مکان، عرض جغرافیایی ، و طول جغرافیایی اگر کاربر از قبل طول و عرض جغرافیایی مکان را نمی‌داند، می‌تواند با وارد کردن آدرس خود در فرم و فشار دادن «submit»، آن را به صورت جغرافیایی کدگذاری کند. این یک تماس با GClientGeocoder Map API ارسال می کند، که اگر آدرس را پیدا کند، نشانگری را روی نقشه قرار می دهد و فیلدهای متنی lat/lng را به صورت خودکار پر می کند.

هنگامی که کاربر راضی است، می تواند دکمه "افزودن مکان" را فشار دهد. سپس، در جاوا اسکریپت، مقادیر user، place، lat و lng را دریافت کرده و با GDownloadUrl به اسکریپت communitymap_addlocation.php ارسال می کنیم.

اگر آن اسکریپت موفقیت آمیز را بازگرداند، یک پیام موفقیت آمیز را روی صفحه نمایش می دهیم.

یک اسکرین شات و کد در زیر برای نمونه صفحه مکان افزودن نشان داده شده است ( 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>

ایجاد نقشه

از آنجایی که کاربرگ مکان ها را در مرحله اول عمومی کردید، برای ایجاد نقشه از آنها نیازی به برنامه نویسی سمت سرور نیست. در واقع اصلاً نیازی به برنامه نویسی نیست. می توانید از این صفحه گسترده -> جادوگر نقشه استفاده کنید و تمام کدهای مورد نیاز برای نقشه را تولید می کند. جادوگر ورودی‌های کاربرگ را در صفحه با اضافه کردن یک برچسب اسکریپت دانلود می‌کند که به خروجی JSON برای فید اشاره می‌کند، و یک تابع تماس را مشخص می‌کند که پس از دانلود JSON فراخوانی می‌شود. اطلاعات بیشتر در اینجا موجود است.

نمونه کد HTML برای انجام این کار در اینجا موجود است: mainmap.htm . یک اسکرین شات در زیر نشان داده شده است:

نتیجه

امیدواریم که اکنون سیستم نقشه خود را که توسط کاربر در سرور شما اجرا می شود، دارید. این مقاله کد بسیار اساسی مورد نیاز برای جنبه های ضروری این سیستم را ارائه می دهد، اما اکنون که با کتابخانه Zend Spreadsheets آشنا شدید، باید بتوانید سیستم را برای رفع نیازهای خاص خود گسترش دهید. اگر در طول مسیر با خطاهایی مواجه شدید، به یاد داشته باشید که می‌توانید از دستور echo در PHP یا از GLog.write() Map API در جاوا اسکریپت برای اشکال‌زدایی استفاده کنید، و همیشه می‌توانید در انجمن‌های توسعه‌دهنده Maps API یا Spreadsheets API پست کنید. کمک اضافی