Google 新的 Maps API Version 2 支持創建更高級的 mashup 應用程序。在本文中,將以本系列 第 1 部分 中講解的基本 mashup 開發為基礎,學習更高級的開發方法,並了解如何使用 DB2® REC2XML 函數減少 PHP:Hypertext Preprocessor(PHP)腳本中的代碼行。學習如何用 DB2 或 Informix® Dynamic Server(IDS)實現這個解決方案,如何把當前的地圖從 Maps API Version 1 升級到 Version 2,如何用新的 API 實現有用的特性。
為什麼要使用地圖?
在這個信息時代,網際網路承擔著一項重要的工作:開發應用程序來處理大量信息並有效地顯示信息。在處理地理數據時,最好的方法是用圖形顯示它。這種顯示方式已經在計算機上存在多年了,比如地理信息系統(GIS)和 Mapquest 等網站。但是,Google Maps 通過簡單易用的介面徹底革新了在線地圖的編程模型,使用戶能夠快速輕鬆地找到信息。通過使用 Google Maps,可以拖放和實時更新地圖,而不需要重新裝載 Web 頁面。現在,其他地圖站點(包括 Mapquest、Yahoo! 和 Microsoft)也開始採用 Google Maps 創建的模型了。
本文的目的
儘管目前有許許多多 Web 站點都在討論 Google Maps,但是本文主要關注如何結合使用 Google Maps 與 DB2 或 Informix。如果在 Google 上搜索 “google maps api php”,會得到超過 3000 萬個結果,而 本系列的第 1 部分 排在前 10 位之內。
應用程序
除了 Terms of Use 中提到的一些限制之外,對於如何使用 Google Maps 應用程序編程介面(API)沒有其他限制。大量站點以不同的方式使用 Google Maps 向各種各樣的用戶顯示不同的信息。這些基於 Google Maps 的頁面被稱為 “mashup”。在本文中,我們將開發一個簡單的 mashup 示例,它使用來自美國人口局的數據。
在這個頁面頂部,有一個用於輸入郵政編碼的框。這個框的下面是地圖,右邊顯示相關信息。
在搜索一個郵政編碼時,地圖會以這個郵政編碼的位置為中心放大。它還會創建 “圖釘” 標誌來顯示搜索的郵政編碼和這個地區的其他郵政編碼。用星號(*)突出顯示的圖釘表示搜索的郵政編碼。不同顏色的標誌表示每個郵政編碼區域的人口密度。
數據
在這個應用程序中,郵政編碼的數據來自美國人口局,美國人口局免費在線提供這些數據和其他地理信息。儘管這是地理數據,但是數據模式很簡單。
Column name Type state char(2) zip char(5) longitude decimal(16) latitude decimal(16) population integer housingunits integer sqmeters int8 |
Google Maps API Version 2、JavaScript 和 Ajax
Google 的 Maps API 工具集允許任何人創建自己的在線地圖。原來的版本(Version 1)是在幾年前發布的,Version 2 是在 2006 年 4 月 3 日發布的。這個升級版重新設計了 API 的基礎部分,減小了下載包,改進了功能。這個升級版具有 99% 的向後兼容性,但是也有一些不兼容的地方。
為了幫助用戶切換到新版本,Google 提供了一個升級指南並列出兩個版本之間的不兼容之處。下面是一些重點(方法名、常量名等等)。完整的 API Upgrade Guide 可以在網上找到。
Ajax
Ajax 代表 “非同步 JavaScript 和 XML(Asynchronous JavaScript and XML)”。這是 Google Maps 幕後的主要組件之一,控制著應用程序的工作方式。在查看新信息時,大多數動態 Web 站點都要求用戶重新裝載頁面,而 Ajax 允許在不重新裝載頁面的情況下更新頁面上的信息。這就是實現地圖拖放功能的方法 —— 在拖動地圖時,伺服器發送用戶請求的地區的圖像,地圖立即裝載它。對於我們的應用程序,使用 Ajax 自動地裝載郵政編碼數據,不需要刷新頁面。
DB2 和 Informix
IBM 站點把 DB2 描述為 “一種提供靈活且經濟有效的資料庫平台的資料庫管理系統,可以用來構建健壯的隨需應變業務應用程序”,把 Informix 描述為一種 “為事務密集型環境提供卓越的應用程序性能” 的資料庫。
mashup 使用的主要 DB2 特性是 REC2XML。可以使用這個特性查詢一個常規表並返回經過格式化的 XML(在這裡,使用人口普查數據和模式)。Informix 中的對應特性稱為 genxml,在 代碼示例 小節中提供了這兩個特性的示例。
體系結構概述
這個圖展示創建和運行應用程序所需的各個組件之間的交互。最初的請求源自瀏覽器,用戶在瀏覽器中輸入郵政編碼。郵政編碼按照 Ajax 方式發送到 Apache 伺服器,在伺服器上用 PHP 和 Open Database Connectivity(ODBC) 創建並執行一個查詢。然後,PHP 用 DB2 或 Informix 返回的數據創建格式化的 XML,用 Ajax 接收並用 JavaScript 解析這個 XML 文檔。當 JavaScript 得到信息之後,它就可以調用 API 來裝載這個地區的地圖。然後,重複這個過程,使用另一個 PHP 和 Ajax 腳本裝載圖釘標誌。
在使用 DB2 的 REC2XML 時,這個過程略有不同。因為 PHP 不再需要創建格式化的 XML,只需把它傳輸到客戶端。
PHP 和 ODBC
PHP 是一種常用的 Web 腳本語言。在這個應用程序中,PHP 實際上是一個 “中間人”,它在資料庫和瀏覽器之間傳遞數據。ODBC 使 PHP 能夠與資料庫通信。ODBC 可以訪問 Informix 或 DB2,在本文的 參考資料 中可以找到關於如何配置 ODBC 的教程。
代碼示例
在這個應用程序中有三個腳本:
可以從本文末尾下載這些腳本。下面討論對新的 API 以及 REC2XML(DB2)和 genxml(Informix)最重要的代碼。
var maxZoom=12;// this is the farthest out they can zoom while still seeing markers. //event listener for movement takes care of refreshing GEvent.addListener(map, 'moveend', function() { var center = map.getCenterLatLng(); var latLngStr = "Long/Lat of map center: "; latLngStr += '(' + Math.round(center.y*10000)/10000 + ', ' + Math.round(center.x*10000)/10000 + ')'; document.getElementById("longlat").innerHTML = latLngStr; var zoomstring="Zoom Level: "; zoomstring +=map.getZoom(); var divZoom = document.getElementById("zoomlev").innerHTML = zoomstring; if (map.getZoom() >= maxZoom) getZips(); else { document.getElementById("searchstatus").innerHTML = ""; document.getElementById("ziplist").innerHTML = ""; document.getElementById("zipstatus").innerHTML = "<b>Zoom in closer to see the zip code list</b>"; map.clearOverlays(); } }); |
這段代碼定義一個 GEvent.addListener ,它監聽所有地圖運動(拖、放、縮放、搖移、地圖類型切換)並定義相應的操作。代碼的一部分定義是否應該根據地圖的縮放級別更新郵政編碼。因為新的 API 顛倒了放大/縮小的方向,所以修改了所有常量和算式來反映這一點。maxZoom 過去是 6,現在是 12。另外,Zoom 必須大於 maxZoom 而不是小於。
select rec2xml(1.0, 'COLATTVAL',' Zip', zip, state, longitude, latitude, population, sqmeters) from census_data where longitude > -71.2928581237793 and longitude < -71.1723518371582 and latitude > 42.291532494305976 and latitude < 42.35511892873107 fetch first 200 rows only |
這個查詢示例調用 REC2XML 函數。這與常規的選擇查詢非常相似,惟一的差異是使用了 rec2xml() 函數和幾個額外參數。這個調用返回以下輸出:
<Zip> <column name="ZIP">02458</column> <column name="STATE">MA</column> <column name="LONGITUDE">-0071.188092</column> <column name="LATITUDE">0042.354727</column> <column name="POPULATION">12150</column> <column name="SQMETERS">4872457</column> </Zip> <Zip> <column name="ZIP">02459</column> <column name="STATE">MA</column> <column name="LONGITUDE">-0071.193009</column> <column name="LATITUDE">0042.321197</column> <column name="POPULATION">17856</column> <column name="SQMETERS">12598371</column> </Zip> <Zip> <column name="ZIP">02460</column> <column name="STATE">MA</column> <column name="LONGITUDE">-0071.209073</column> <column name="LATITUDE">0042.352996</column> <column name="POPULATION">9143</column> <column name="SQMETERS">3700602</column> </Zip> ... |
在 REC2XML 調用返回的 XML 中只有三個郵政編碼。這個 XML 的格式與我們編寫的 PHP 採用的 XML 格式有點不一樣。另外,其中沒有根元素標記,也沒有在頂部指定 XML version 1.0。因此,PHP 在轉發 XML 之前需要添加這兩項內容。
Informix 函數 genxml 使用一種稍微不同的查詢語法,代碼與第一個實現中使用的 PHP 腳本相似。
execute function genxmlquery("Zip", "select * from census_data where ... "); |
這是 genxml 函數的基本語法。但是,與 REC2XML 不同,整個選擇查詢和子句都放在 genxmlquery() 函數中。另外,它返回格式更正確的 XML,其中有一個根結果集標記。
JMeter 速度對比
JMeter 是 Apache Jakarta 提供的一種簡潔的工具(參見 參考資料)。對於這個應用程序,可以使用它測試資料庫的速度。在這兩種資料庫的 PHP 腳本上運行數百個請求,然後使用 JMeter 度量返回數據所用的時間。為此,在一個 Thread Group 中添加兩個 HTTP Request 元素並把它們指向 returnMarkers 文件(其中包含相同的經度/緯度變數)。另外,需要添加一個 Listener 元素來製作數據表。
使用一個 Summary Report Listener 並把 Thread Group 設置為每 10 秒 10 個用戶,每個用戶發送 25 個請求。下表給出 Informix 產生的結果:
資料庫 | 平均響應時間(ms) | 最小(ms) | 最大(ms) | KB/sec |
---|---|---|---|---|
Informix | 109 ms | 15 ms | 2031 ms | 25.75 |
Google API Version 2 的其他特性
Google 不僅僅在速度和下載大小方面改進了新的 API,還增加了一些有用的新特性,它們對於某些應用程序很有幫助。新特性包括:
接下來怎麼做?
下面提供了這個應用程序的代碼(DB2 和 Informix)。可以以此作為自己應用程序的起點,也可以根據本文或其他教程從頭創建應用程序。您可以以任意方式使用這個應用程序。(責任編輯:A6)
[火星人 ] DB2 和開放源代碼,第 2 部分: 在 Linux 上使用 Google Maps API Version 2、DB2/Informix、PHP 和 JMet已經有659次圍觀