Tháng 11 năm 2007
Mục tiêu
Web có rất nhiều cộng đồng tập trung vào địa lý và sở thích: những người yêu thích bảo tàng, nhà thờ lớn ở Châu Âu, công viên tiểu bang, v.v. Vì vậy, luôn có nhu cầu về một nhà phát triển (như bạn!) để tạo một hệ thống nơi người dùng có thể đóng góp những địa điểm được gắn thẻ địa lý vào bản đồ. Đó chính xác là những gì chúng ta sẽ làm ở đây. Khi đọc xong bài viết này, bạn sẽ có một hệ thống cho phép người dùng đăng ký, đăng nhập và thêm các địa điểm được gắn thẻ địa lý. Hệ thống sẽ sử dụng AJAX cho giao diện người dùng, PHP cho tập lệnh phía máy chủ và Google Trang tính để lưu trữ. Nếu quen sử dụng cơ sở dữ liệu MySQL để lưu trữ, bạn có thể dễ dàng sửa đổi mã ở đây để sử dụng một phần phụ trợ cơ sở dữ liệu MySQL.
Bài viết này được chia thành các bước sau:
- Thiết lập bảng tính
- Làm việc với Zend Gdata Framework
- Tạo hàm chung
- Đăng ký người dùng mới
- Đăng nhập người dùng
- Cho phép người dùng thêm địa điểm trên bản đồ
- Tạo bản đồ
- Lời kết
Thiết lập bảng tính
Chúng ta sẽ sử dụng Google Trang tính để lưu trữ tất cả dữ liệu cho hệ thống này. Có hai loại dữ liệu mà chúng ta cần lưu trữ: thông tin tài khoản người dùng và những địa điểm do người dùng thêm. Vì vậy, chúng ta sẽ tạo một trang tính cho mỗi loại dữ liệu. Chúng ta sẽ tương tác với các trang tính bằng nguồn cấp dữ liệu danh sách của chúng. Nguồn cấp dữ liệu này dựa vào hàng đầu tiên trong trang tính có chứa nhãn cột và mỗi hàng tiếp theo có chứa dữ liệu.
Truy cập vào docs.google.com rồi tạo một bảng tính mới. Đổi tên trang tính mặc định thành "Users" (Người dùng) và tạo các cột có tên "user" (người dùng), "password" (mật khẩu) và "session" (phiên). Sau đó, hãy thêm một trang tính khác, đổi tên thành "Locations" (Vị trí) rồi tạo các cột có tên "user" (người dùng), "status" (trạng thái), "lat" (vĩ độ), "lng" (kinh độ) và "date" (ngày). Hoặc nếu bạn không muốn làm tất cả những việc đó theo cách thủ công, hãy tải mẫu này xuống rồi nhập vào Google Trang tính thông qua lệnh Tệp->Nhập.
Thông tin tài khoản người dùng cần được giữ bí mật (chỉ chủ sở hữu bảng tính mới thấy được), trong khi những địa điểm do người dùng thêm sẽ xuất hiện trên bản đồ công khai. May mắn thay, Google Trang tính cho phép bạn chọn lọc để quyết định trang tính nào trong bảng tính có thể ở chế độ công khai và trang tính nào nên ở chế độ riêng tư (mặc định). Để xuất bản trang tính "Locations" (Vị trí), hãy nhấp vào thẻ "Publish" (Xuất bản), nhấp vào "Publish now" (Xuất bản ngay), đánh dấu vào hộp "Automatically re-publish" (Tự động xuất bản lại), rồi trong trình đơn thả xuống "What parts?" (Phần nào?), hãy chọn "Sheet 'Locations' only" (Chỉ trang tính "Locations"). Các lựa chọn chính xác được minh hoạ trong ảnh chụp màn hình bên dưới:
Làm việc với Zend GData Framework
Google Spreadsheets API cung cấp một giao diện HTTP cho các thao tác CRUD như truy xuất hàng, chèn hàng, cập nhật hàng và xoá hàng. Zend Framework cung cấp một trình bao bọc PHP trên API (và các API GData khác) để bạn không phải lo lắng về việc triển khai các thao tác HTTP thô. Zend Framework yêu cầu PHP 5.
Nếu bạn chưa có, hãy tải Zend Framework xuống và tải lên máy chủ của bạn. Khung này có tại đây: http://framework.zend.com/download/gdata.
Bạn nên sửa đổi include_path của PHP để thêm thư viện Zend. Có một số cách để thực hiện việc này, tuỳ thuộc vào cấp độ quyền quản trị mà bạn có trên máy chủ. Một cách là thêm dòng này phía trên các câu lệnh require trong mọi tệp PHP sử dụng thư viện:
ini_set("include_path", ".:/usr/lib/php:/usr/local/lib/php:../../../library/");
Để kiểm thử, hãy chạy bản minh hoạ Spreadsheets bằng cách nhập nội dung sau vào dòng lệnh trong thư mục demos/Zend/Gdata:
php Spreadsheet-ClientLogin.php --user=YourGMailUsername --pass=YourPassword
Nếu thành công, bạn sẽ thấy danh sách các bảng tính của mình. Nếu bạn gặp lỗi, hãy kiểm tra để đảm bảo bạn đã đặt đường dẫn include chính xác và đã cài đặt PHP 5.
Tạo hàm toàn cục
Tất cả các tập lệnh PHP mà chúng ta sẽ viết cho Bản đồ cộng đồng đều sử dụng các hàm, biến và nội dung bao gồm phổ biến. Chúng ta sẽ đặt các hàm, biến và nội dung này vào một tệp.
Ở đầu tệp, chúng ta sẽ có các câu lệnh cần thiết để đưa vào và tải thư viện Zend, lấy từ ví dụ Spreadsheets-ClientLogin.php.
Sau đó, chúng ta sẽ xác định các hằng số sẽ được dùng trong toàn bộ tệp: khoá bảng tính và hai mã nhận dạng trang tính. Để tìm thông tin về bảng tính, hãy mở bảng tính đó, nhấp vào "Thẻ xuất bản" rồi nhấp vào "Tuỳ chọn xuất bản khác". Chọn "ATOM" trong danh sách thả xuống Định dạng tệp rồi nhấp vào "Tạo URL". Bạn sẽ thấy nội dung như sau:
http://spreadsheets.google.com/feeds/list/o16162288751915453340.4016005092390554215/od6/public/basic
Khoá bảng tính là chuỗi dài gồm cả chữ và số sau "/list/" và mã nhận dạng trang tính là chuỗi dài gồm 3 ký tự sau đó. Để tìm mã nhận dạng của trang tính khác, hãy chọn trang tính đó trong trình đơn thả xuống "Trang tính nào?".
Sau đó, chúng ta sẽ tạo 3 hàm: setupClient, getWkshtListFeed và printFeed. Trong setupClient, chúng ta sẽ đặt tên người dùng và mật khẩu GMail, xác thực bằng ClientLogin và trả về một đối tượng Zend_Gdata_Spreadsheets. Trong getWkshtListFeed, chúng ta sẽ trả về một nguồn cấp dữ liệu danh sách Bảng tính cho một khoá bảng tính và mã nhận dạng trang tính nhất định, kèm theo một truy vấn bảng tính không bắt buộc (đường liên kết). Hàm printFeed được lấy từ ví dụ Spreadsheets-ClientLogin.php và có thể hữu ích cho bạn trong quá trình gỡ lỗi. Thao tác này sẽ lấy một đối tượng nguồn cấp dữ liệu và in đối tượng đó ra màn hình.
PHP thực hiện việc này được trình bày bên dưới (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++;
}
}
?>
Đăng ký người dùng mới
Để đăng ký người dùng mới, chúng ta sẽ cần một trang HTML dành cho người dùng có các trường văn bản và nút gửi, cùng một tập lệnh phụ trợ PHP để thêm người dùng vào bảng tính.
Trong tập lệnh PHP, trước tiên, chúng ta sẽ thêm tập lệnh chung, sau đó lấy các giá trị tên người dùng và mật khẩu từ biến GET. Sau đó, chúng ta thiết lập một ứng dụng Spreadsheets và yêu cầu nguồn cấp dữ liệu danh sách cho trang tính người dùng bằng một chuỗi truy vấn để chỉ giới hạn kết quả ở những hàng mà cột tên người dùng bằng với tên người dùng được truyền vào tập lệnh. Nếu không có hàng nào trong kết quả nguồn cấp dữ liệu danh sách, thì chúng ta có thể yên tâm tiếp tục vì biết rằng tên người dùng được truyền vào là duy nhất. Trước khi chèn một hàng vào nguồn cấp dữ liệu danh sách, chúng ta sẽ tạo một mảng kết hợp các giá trị cột: tên người dùng, một phiên bản mã hoá của mật khẩu bằng hàm sha1 của PHP và một ký tự thay thế cho phiên. Sau đó, chúng ta gọi insertRow trên ứng dụng bảng tính, truyền vào mảng kết hợp, khoá bảng tính và mã nhận dạng trang tính. Nếu đối tượng được trả về là ListFeedEntry, thì chúng ta sẽ xuất thông báo Thành công!
PHP thực hiện việc này được minh hoạ dưới đây (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!";
}
?>
Trên trang đăng ký, chúng ta có thể thêm Maps API để sử dụng hàm bao bọc XMLHttpRequest có tên là GDownloadUrl. Khi người dùng nhấp vào nút gửi, chúng ta sẽ lấy tên người dùng và mật khẩu từ các trường văn bản, tạo một chuỗi tham số từ các giá trị của chúng và gọi GDownloadUrl trên URL và các tham số của tập lệnh. Vì đang gửi thông tin nhạy cảm, nên chúng ta sẽ sử dụng phiên bản HTTP POST của GDownloadUrl (bằng cách gửi các tham số làm đối số thứ ba thay vì nối chúng vào URL). Trong hàm gọi lại, chúng ta sẽ kiểm tra phản hồi thành công và xuất một thông báo phù hợp cho người dùng.
Ảnh chụp màn hình và mã được trình bày bên dưới cho một trang đăng ký mẫu (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>
Đăng nhập người dùng
Để cho phép người dùng đăng nhập vào hệ thống của chúng tôi, chúng ta sẽ cần một trang HTML hướng đến người dùng để nhắc họ nhập tên người dùng và mật khẩu, đồng thời cần một tập lệnh PHP để xác minh thông tin đăng nhập, tạo mã nhận dạng phiên và truyền mã đó trở lại trang đăng nhập để đặt cookie. Người dùng sẽ vẫn đăng nhập thông qua cookie phiên trên các trang tiếp theo.
Trong tập lệnh PHP, trước tiên, chúng ta sẽ thêm tập lệnh chung, sau đó lấy các giá trị tên người dùng và mật khẩu từ biến GET. Sau đó, chúng ta thiết lập một ứng dụng Spreadsheets và yêu cầu nguồn cấp dữ liệu danh sách cho trang tính người dùng bằng một chuỗi truy vấn để chỉ giới hạn kết quả ở những hàng mà cột tên người dùng bằng với tên người dùng được truyền vào tập lệnh.
Trong hàng được trả về, chúng ta sẽ kiểm tra để đảm bảo rằng hàm băm của mật khẩu được truyền vào khớp với hàm băm được lưu trữ trong bảng tính. Nếu có, chúng tôi sẽ tạo mã phiên bằng các hàm md5, uniqid và rand. Sau đó, chúng ta sẽ cập nhật hàng trong bảng tính bằng phiên và xuất hàng đó ra màn hình nếu việc cập nhật hàng thành công.
PHP thực hiện việc đó được trình bày bên dưới (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"];
}
}
}
?>
Trên trang đăng nhập, chúng ta có thể thêm lại Maps API để có thể sử dụng hàm bao bọc XMLHttpRequest của API này có tên là GDownloadUrl. Khi người dùng nhấp vào nút gửi, chúng ta sẽ lấy tên người dùng và mật khẩu từ các trường văn bản, tạo URL tập lệnh bằng các tham số truy vấn và gọi GDownloadUrl trên URL tập lệnh. Trong hàm gọi lại, chúng ta sẽ đặt một cookie có mã phiên do tập lệnh trả về hoặc xuất thông báo lỗi nếu không có mã phiên nào được trả về. Hàm setCookie có trong cookies.js dựa trên hướng dẫn JavaScript của w3c: http://www.w3schools.com/js/js_cookies.asp.
Ảnh chụp màn hình và mã cho một trang đăng nhập mẫu (communitymap_login.htm) được minh hoạ bên dưới:
<!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>
Cho phép người dùng thêm địa điểm trên bản đồ
Để cho phép người dùng thêm địa điểm vào bản đồ của chúng tôi, chúng ta sẽ cần một trang HTML dành cho người dùng để họ cung cấp thông tin về vị trí và 2 tập lệnh PHP – một tập lệnh để kiểm tra xem họ đã đăng nhập hay chưa thông qua cookie mà chúng ta đặt và một tập lệnh khác để thêm vị trí vào trang tính vị trí.
Trong tập lệnh PHP đầu tiên kiểm tra xem người dùng đã đăng nhập hay chưa, trước tiên, chúng ta sẽ thêm tập lệnh chung rồi lấy giá trị phiên từ biến GET. Sau đó, chúng ta thiết lập một ứng dụng Bảng tính và yêu cầu nguồn cấp dữ liệu danh sách cho trang tính người dùng bằng một chuỗi truy vấn để chỉ giới hạn kết quả ở những hàng mà cột phiên bằng với giá trị phiên được truyền vào tập lệnh. Sau đó, chúng ta sẽ lặp lại các mục tuỳ chỉnh của nguồn cấp dữ liệu đó (các mục tương ứng với tiêu đề cột của chúng ta) và in tên người dùng tương ứng cho phiên đó nếu có.
PHP thực hiện việc đó được trình bày bên dưới (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();
}
}
}
?>
Trong tập lệnh PHP thứ hai cho phép người dùng thêm vị trí, trước tiên, chúng ta sẽ sao chép mã từ communitymap_checksession.php để đảm bảo người dùng vẫn đăng nhập và hợp lệ. Sau đó, khi nhận được tên người dùng hợp lệ từ trang tính người dùng, chúng ta sẽ nhận được các giá trị place, lat và lng từ biến GET. Chúng tôi đặt tất cả các giá trị đó vào một mảng kết hợp, đồng thời thêm giá trị "date" bằng hàm date() của PHP để biết thời điểm người dùng thêm địa điểm. Chúng ta sẽ truyền mảng kết hợp đó, hằng số khoá bảng tính và hằng số mã trang tính vị trí vào hàm insertRow. Sau đó, chúng tôi sẽ xuất ra "Thành công" nếu một hàng cho vị trí mới được thêm vào bảng tính. Nếu bạn gặp lỗi ở bước này, thì có thể là do tên tiêu đề cột không khớp. Các khoá trong mảng kết hợp phải khớp với tiêu đề cột trong trang tính do khoá bảng tính và mã trang tính chỉ định.
PHP thực hiện việc đó được minh hoạ bên dưới (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";
}
}
?>
Trên trang thêm vị trí, chúng ta có thể thêm lại Maps API để có thể sử dụng GDownloadUrl và tạo một bản đồ. Sau khi trang tải, chúng ta sẽ dùng hàm getCookie trong cookies.js để truy xuất giá trị phiên. Nếu chuỗi phiên là rỗng hoặc không có giá trị, chúng tôi sẽ xuất một thông báo lỗi. Nếu không, chúng tôi sẽ gọi GDownloadUrl trên map.checksession.php, gửi trong phiên. Nếu thao tác đó trả về tên người dùng thành công, chúng ta sẽ hiển thị thông điệp chào mừng cho người dùng, hiển thị biểu mẫu thêm vị trí và tải bản đồ. Biểu mẫu này bao gồm một trường văn bản địa chỉ, bản đồ và các trường văn bản cho tên địa điểm, vĩ độ và kinh độ. Nếu chưa biết vĩ độ/kinh độ của vị trí, người dùng có thể mã hoá địa lý bằng cách nhập địa chỉ của họ vào biểu mẫu rồi nhấn vào "gửi". Thao tác này sẽ gửi một lệnh gọi đến GClientGeocoder của Map API. Lệnh gọi này sẽ đặt một điểm đánh dấu trên bản đồ nếu tìm thấy địa chỉ và tự động điền sẵn các trường văn bản vĩ độ/kinh độ.
Khi hài lòng, người dùng có thể nhấn vào nút "thêm vị trí". Sau đó, trong JavaScript, chúng ta sẽ lấy các giá trị cho người dùng, địa điểm, vĩ độ và kinh độ, rồi gửi các giá trị đó đến tập lệnh communitymap_addlocation.php bằng GDownloadUrl.
Nếu tập lệnh đó trả về kết quả thành công, chúng tôi sẽ xuất một thông báo thành công lên màn hình.
Ảnh chụp màn hình và mã cho một trang mẫu thêm vị trí (communitymap_addlocation.htm) được minh hoạ bên dưới:
<!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>
Tạo bản đồ
Vì bạn đã công khai trang tính vị trí ở bước đầu tiên, nên bạn không cần lập trình phía máy chủ để tạo bản đồ cho các vị trí đó. Trên thực tế, bạn không cần phải lập trình. Bạn có thể sử dụng Trang tính -> Trình hướng dẫn về bản đồ. Trình hướng dẫn này sẽ tạo tất cả mã cần thiết cho bản đồ. Trình hướng dẫn tải các mục trong trang tính xuống trang bằng cách nối một thẻ tập lệnh trỏ đến đầu ra JSON cho nguồn cấp dữ liệu và chỉ định một hàm gọi lại được gọi sau khi JSON đã tải xuống. Bạn có thể xem thêm thông tin tại đây.
Bạn có thể xem mã HTML mẫu để thực hiện việc đó tại đây: mainmap.htm. Ảnh chụp màn hình dưới đây cho thấy:
Kết luận
Hy vọng rằng bạn hiện đã có hệ thống bản đồ do người dùng đóng góp của riêng mình chạy trên máy chủ. Bài viết này cung cấp mã cơ bản cần thiết cho các khía cạnh thiết yếu của hệ thống này. Tuy nhiên, giờ đây, khi đã quen thuộc với thư viện Zend Spreadsheets, bạn có thể mở rộng hệ thống để đáp ứng nhu cầu cụ thể của mình. Nếu gặp lỗi trong quá trình này, hãy nhớ rằng bạn có thể sử dụng lệnh echo trong PHP hoặc GLog.write() của Map API trong JavaScript để gỡ lỗi. Bạn cũng có thể đăng bài trong diễn đàn nhà phát triển Maps API hoặc Spreadsheets API để được trợ giúp thêm.