在 Linux 上使用 Google Maps API Version 2、DB2/Informix、PHP 和 JMeter 创建地图
2009-11-17 00:00:00 来源:WEB开发网为什么要使用地图?
在这个信息时代,因特网承担着一项重要的工作:开发应用程序来处理大量信息并有效地显示信息。在处理地理数据时,最好的方法是用图形显示它。这种显示方式已经在计算机上存在多年了,比如地理信息系统(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 示例,它使用来自美国人口局的数据。
图 1. 首先装载的页面
PHP 和 JMeter 创建地图" border="0" onload="return imgzoom(this,550);" style="cursor:pointer;" onclick="javascript:window.open(this.src);"/>
图片看不清楚?请点击这里查看原图(大图)。
在这个页面顶部,有一个用于输入邮政编码的框。这个框的下面是地图,右边显示相关信息。
图 2. 邮政编码 02222 的搜索结果页面
PHP 和 JMeter 创建地图" border="0" onload="return imgzoom(this,550);" style="cursor:pointer;" onclick="javascript:window.open(this.src);"/>
图片看不清楚?请点击这里查看原图(大图)。
在搜索一个邮政编码时,地图会以这个邮政编码的位置为中心放大。它还会创建 “图钉” 标志来显示搜索的邮政编码和这个地区的其他邮政编码。用星号(*)突出显示的图钉表示搜索的邮政编码。不同颜色的标志表示每个邮政编码区域的人口密度。
数据
在这个应用程序中,邮政编码的数据来自美国人口局,美国人口局免费在线提供这些数据和其他地理信息。尽管这是地理数据,但是数据模式很简单。
清单 1. 应用程序的数据模式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 可以在网上找到。
缩放级别:在旧的 API 中,缩放级别 0 是视距最近的。现在,它是最远的。可以按照 newZoom = 17 - oldZoom 转换缩放级别。
大多数方法名已经简化了,例如 getZoomLevel() 现在是 getZoom(),getBoundsLatLang() 现在是 getBounds()。
地图类型名有微小变化。例如,G_HYBRID_TYPE 现在是 G_HYBRID_MAP。
Ajax
Ajax 代表 “异步 JavaScript 和 XML(Asynchronous JavaScript and XML)”。这是 Google Maps 幕后的主要组件之一,控制着应用程序的工作方式。在查看新信息时,大多数动态 Web 站点都要求用户重新装载页面,而 Ajax 允许在不重新装载页面的情况下更新页面上的信息。这就是实现地图拖放功能的方法 —— 在拖动地图时,服务器发送用户请求的地区的图像,地图立即装载它。对于我们的应用程序,使用 Ajax 自动地装载邮政编码数据,不需要刷新页面。
DB2 和 Informix
IBM 站点把 DB2 描述为 “一种提供灵活且经济有效的数据库平台的数据库管理系统,可以用来构建健壮的随需应变业务应用程序”,把 Informix 描述为一种 “为事务密集型环境提供卓越的应用程序性能” 的数据库。
mashup 使用的主要 DB2 特性是 REC2XML。可以使用这个特性查询一个常规表并返回经过格式化的 XML(在这里,使用人口普查数据和模式)。Informix 中的对应特性称为 genxml,在 代码示例 小节中提供了这两个特性的示例。
体系结构概述
图 3. 体系结构图
PHP 和 JMeter 创建地图" border="0" onload="return imgzoom(this,550);" style="cursor:pointer;" onclick="javascript:window.open(this.src);"/>
这个图展示创建和运行应用程序所需的各个组件之间的交互。最初的请求源自浏览器,用户在浏览器中输入邮政编码。邮政编码按照 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 能够与数据库通信。
代码示例
在这个应用程序中有三个脚本:
用户看到的页面,其中包含所有 JavaScript™、Ajax 和 API 调用。
调用的第一个 PHP 脚本,它返回与用户的邮政编码对应的经度/纬度。
调用的第二个 PHP 脚本,它返回用户看到的地图上所有邮政编码的相关信息。
可以从本文末尾下载这些脚本。下面讨论对新的 API 以及 REC2XML(DB2)和 genxml(Informix)最重要的代码。
清单 2. 更新地图的代码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 而不是小于。
清单 3. DB2 REC2XML 调用示例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() 函数和几个额外参数。这个调用返回以下输出:
清单 4. DB2 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 脚本相似。
清单 5. Informix genxml 查询示例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 元素来制作数据表。
图 4. JMeter HTTP 请求屏幕
PHP 和 JMeter 创建地图" border="0" onload="return imgzoom(this,550);" style="cursor:pointer;" onclick="javascript:window.open(this.src);"/>
使用一个 Summary Report Listener 并把 Thread Group 设置为每 10 秒 10 个用户,每个用户发送 25 个请求。下表给出 Informix 产生的结果:
表 1. JMeter 速度测试产生的数据
数据库 | 平均响应时间(ms) | 最小(ms) | 最大(ms) | KB/sec |
Informix | 109 ms | 15 ms | 2031 ms | 25.75 |
Google API Version 2 的其他特性
Google 不仅仅在速度和下载大小方面改进了新的 API,还增加了一些有用的新特性,它们对于某些应用程序很有帮助。新特性包括:
定制的地图控件:除了 Google 的 Map Controls 之外,现在还可以使用 Googles GControl 类创建定制的控件。
标志管理器:通过新的 API,可以有效地控制其中使用的任何标志。可以根据需要显示和隐藏标志;在比较高的缩放级别上还可以把标志 “聚合” 起来,从而避免屏幕过分拥挤。
移动方向:这个 API 允许每天最多 10,000 个移动方向请求,这些方向会在它们自己的地图站点上给出。
更多的缩放级别:这个 API 增加了两个缩放级别,可以为纽约、波士顿和洛杉矶这样的地区提供更高的分辨率。
接下来怎么做?
下面提供了这个应用程序的代码(DB2 和 Informix)。可以以此作为自己应用程序的起点,也可以根据本文或其他教程从头创建应用程序。您可以以任意方式使用这个应用程序。
本文示例源代码或素材下载
- ››linux下两台服务器文件实时同步方案设计和实现
- ››Linux文件描述符中的close on exec标志位
- ››Linux下管道使用的一些限制
- ››Linux 误删/usr/bin 解决方法
- ››linux 添加新用户并赋予sudo执行权限
- ››linux常用软件安装方法
- ››Linux的分区已经被你从Windows中删除,系统启动后...
- ››linux enable命令大全
- ››Linux实现基于Loopback的NVI(NAT Virtual Interfa...
- ››Linux远程访问windows时,出现"连接被对端重...
- ››linux中使用head命令和tail命令查看文件中的指定行...
- ››linux swap 分区调控(swap分区 lvm管理)
更多精彩
赞助商链接