铸造坊 - 谷歌地图

作者:Reuven M. Lerner

在过去的几个月中,我们研究了许多 Web 服务。Web 服务是一个概括性术语,指的是互联网公司将其数据提供给公众的方式,以便在人们自己的应用程序中使用。因此,Amazon 使其产品目录可供我们创建在线商店和定价程序,eBay 允许我们搜索(和竞标)待售产品,而 Google 使其搜索结果可用于查看和操作。每家公司都限制了我们使用所提供数据的方式,但趋势似乎是朝着更大的开放性和可用性发展。

有时,这种开放性以一种与 Web 服务的标准形式略有不同的方式呈现。也就是说,一些公司使用专门的库来提供其数据,这些库为您调用服务,从而对您的应用程序隐藏调用的细节。其中一个最著名的例子,也是我们本月要研究的例子,就是 Google Maps。我发现 Google Maps 是目前最引人注目和功能强大的 Web 应用程序之一。巧合的是,Google Maps 是最早使用 Ajax 的应用程序之一,Ajax 是一个术语,描述了我们如何使用 JavaScript 和 XML 的组合从远程服务器获取数据,然后使用结果动态更新网页。

本月,我将解释使用 Google Maps API 创建地图是多么容易。我们将创建一些基本地图,甚至放置一些小标记来指示我们感兴趣的位置。这将作为构建我们自己的混搭应用的基石,混搭应用是越来越流行的术语,指的是使用 Google Maps 显示从单独数据库中收集的信息。

基础

Google Maps 像大多数 Web 应用程序一样,将工作分配给客户端(Web 浏览器)和服务器。然而,传统的分工相当不平等,几乎将所有的计算负担都放在服务器上,而浏览器只负责显示。Ajax 改变了这一点,它使用一个或多个 JavaScript 库,这些库知道如何以新的和有趣的方式操作正在显示的数据。

虽然 Google 可能会在未来发布一个 API,允许我们使用其地图信息创建我们自己的 Ajax 应用程序,但目前的版本要求我们安装并在单个软件包中使用所有内容。也就是说,Google 提供了一个 JavaScript 库——或者更准确地说,是一个指向位于 Google 服务器上的 JavaScript 库的链接——我们将其集成到我们的页面中,然后用它来创建地图。

为了显示地图,我们需要使用该 JavaScript 库。然而,为了跟踪谁在使用 API,并确保它按照规则使用,该库仅对密钥持有者开放。

现在,我们以前见过这种限制,无论是在 Amazon 的 Web 服务还是 Google 的主要 Web 服务(即,用于搜索结果)中。然而,Google Maps 中使用的密钥有些不同;它既与特定的人(拥有 Google 帐户)相关联,也与特定的 URL 相关联。这意味着在 http://www.example.com 上工作的地图密钥在 http://www.example.net 上也将无法工作。

使用 Google Maps API 的第一步是决定您想将地图放在哪个 URL 下。我决定在我的系统上创建一个新的 Apache 虚拟主机,我将其命名为 maps.lerner.co.il。然后我在 Google Maps API 页面 (www.google.com/apis/maps) 上注册,表明我的应用程序将在 URL maps.lerner.co.il 下。几秒钟后,我看到了一个页面,其中包含我的 API 密钥,以及一个可以显示地图的简单起始页。密钥是一个非常长的 ASCII 字符字符串,用空格分隔。

因为我们将基于 HTML 构建我们的应用程序,所以我们应该仔细看看它

<!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>
    <script
src="http://maps.google.com/maps?file=api&v=1&key=
↪ABQIAAAAQQK9JhAXQ9eq-G55qgu1ExScF-BH9Y-SIKcAjU8YFS_
↪uTREdFBSs2-11UWY0kXbUv6argoPyrx3YTg"
type="text/javascript"></script>
  </head>
  <body>
    <div id="map" style="width: 500px; height: 400px"><;/div>
    <script type="text/javascript">

    var map = new GMap(document.getElementById("map"));
    map.addControl(new GSmallMapControl());
    map.centerAndZoom(new GPoint(-122.1419, 37.4419), 4);

    </script>
  </body>
</html>

HTML 文档首先声明其 DOCTYPE,结果是严格的 XHTML。XHTML 是一个很棒的想法,它确保 HTML 按照所有严格的 XML 规则进行结构化。尽管如此,许多 HTML 页面并不遵守此标准,因此被认为是过渡性的(意味着,对 XHTML 采取宽松的态度)或根本不是 XHTML。由于 Google Maps 试图尽可能与多的浏览器兼容,因此严格遵守 XHTML 对其大有裨益。

在 <head> 标签中,我们看到有一个 <script> 标签,它从 Google 的服务器 maps.google.com 加载 JavaScript 源代码。这确保了最新版本的 JavaScript 库始终可供我们和我们的用户使用。Google 承诺,当它升级地图 API 时,它将提供一个月的宽限期,以便开发人员了解他们可能做出的不兼容更改。

在 HTML 文档的 body 中,我们然后有一个 div 标签,其 ID 为 map。这是我们将传递给 Google 的 JavaScript 库的节点。传递给 div 标签的 style 属性包含宽度和高度;这些决定了地图的大小。您的站点可以显示地图的任何宽度和高度组合,允许您为您的特定站点设计进行调整。

在 div 内部,我们终于进入了问题的核心,有三个调用。

首先,我们创建一个 GMap 对象的实例。正如您可能想象的那样,GMap 代表 Google Maps 世界中的特定地图。我们将 GMap 对象附加到 ID 为 map 的节点。(如果该元素不存在,则地图将不会出现在屏幕上。)顺便说一下,这意味着您可以在一个特定的网页上拥有多个地图——只需创建多个 <div> 标签,每个标签都有自己唯一的 ID 属性,并将 GMap 的不同实例附加到每个 <div>。

一旦我们创建了 GMap 的实例,我们就可以向其发送消息以控制其行为。例如,我们可以向其添加一个控件,允许我们放大和缩小。例如,在本文档中,我们通过调用 addControl() 方法添加一个小地图控件,并向其传递 GSmallMapControl 的新实例。GSmallMapControl 包含用于缩放的 +/– 按钮,以及用于移动地图而无需拖动鼠标的箭头按钮。

Google 还提供了另外两种控件类型,即 GSmallZoomControl(仅具有 +/– 缩放按钮)和 GLargeMapControl(包括 GSmallMapControl 所做的所有操作,以及允许您跳转到特定缩放级别的按钮)。控件始终出现在地图的左上角,并且无法阻止您实例化多个这些控件。这意味着如果您不小心,您可能会创建多个控件,从而导致地图和站点变得难看。

在创建我们的地图并向其添加控件后,我们然后指示地图向我们显示一个特定的点。Google 地图中的点用 GPoint 数据结构表示,该结构表示经度和纬度的单个点。经度和纬度可以用度数或浮点数表示;出于显而易见的原因,GPoint 使用后者构建。示例文档具有以下调用

map.centerAndZoom(new GPoint(-122.1419, 37.4419), 4);

上面的 JavaScript 行向地图对象发送一个 centerAndZoom 消息。它指示地图以 GPoint 描述的点为中心,并将地图显示在级别 4。最近的缩放级别是 1,最远的是 15,级别 16–18 显示不同类型的环绕。级别 4 允许您看到街道,并且是使用地图的人的良好起点。

重要的是要意识到 GPoint 对象是使用经度和纬度作为参数创建的,而不是相反。这可能是因为 Google 工程师从 x 和 y 坐标的角度考虑问题,这对于数学和科学领域的人来说更自然。然而,坐标通常以纬度、经度对的形式给出,而不是相反——因此在盲目将坐标输入程序之前,请务必检查它们的顺序和含义。

在此默认文档中创建的 GPoint 位于加利福尼亞州帕洛阿爾托,据推测指向 Google 的办公室。要查看地图上的另一个区域,只需替换一组不同的坐标。例如,要查看伊利諾伊州斯科基(我现在居住的地方),我只需替换一组不同的坐标

map.centerAndZoom(new GPoint(-87.740070, 42.037030), 4);

果然,当我重新加载我的页面时,我现在看到的是斯科基的地图,而不是帕洛阿爾托。

最后,Google 为我们提供了在三种不同视图之间切换的能力,即地图、卫星和混合。默认情况下,这些控件显示在右上角,并由于以下行而出现

    map.addControl(new
GMapTypeControl());

正如您可能猜到的那样,上面的行向我们的地图对象发送一个 addControl 消息,并向其传递 GMapTypeControl 的新实例。

标记

最后,让我们看看如何在我们的地图上创建一个标记,正如它所知的那样。标记让我们能够在地图上识别一个特定的点,并用用户识别的 Google Maps 图标之一显示它。此外,尽管我们今天看到了这个功能,但我们可以轻松地为我们的标记创建 JavaScript 处理程序——这样,点击标记会导致执行 JavaScript 函数,并可能以某种方式改变我们地图的外观。

要创建一个标记,我们创建一个 GMarker 的新实例,并向其传递一个 GPoint

var myMarker = new GMarker(new GPoint(-87.740000, 42.030000));

现在我们已经创建了我们的标记,我们可以将其显示在地图上

map.addOverlay(myMarker);

如果您在 HTML 文件的 <script> 部分中添加以上两行代码,您将立即看到屏幕上出现一个红色标记。

现在,真正的魔力开始了。到目前为止,我们所做的一切都是在 JavaScript 和 HTML 中完成的。这两者都由浏览器读取和处理,但它们是由服务器创建的。这意味着,如果我们不是将 HTML 文件创建为静态文件,而是动态地(即,从服务器端程序),我们就可以用 JavaScript 做各种巧妙的事情。

例如,我们可以创建多个 GMarker,只需将它们分配给不同的变量,然后将它们中的每一个附加到地图上即可。如果我们的 Google Maps 页面由 PHP 运行,我们可以编写一个简短的 PHP 程序,将适当的 JavaScript 代码插入到页面中。例如

<?php
$a = array(-87.740070, -87.730000);
 $count = 0;

foreach ($a as $v) {
    echo "var myMarker$count = new GMarker(new GPoint($v,
42.037030));\n";
    echo "map.addOverlay(myMarker$count);\n";
    $count++;
  }
?>

如果我们将上述代码放在我们页面的 <script> 部分中,并且如果我们将页面重命名为 index.php(而不是 index.html),我们将很快在页面上看到两个标记,它们的经度略有不同,纬度相同。

请注意上面的代码如何使用 PHP 的 echo 命令在执行时将文本插入到 HTML 文档中。另请注意,我们需要添加分号——一个用于结束 JavaScript 行(在引号内),另一个用于结束 PHP 行(在引号外)。当编写一个编写另一个程序的程序时,这类问题总是令人头疼。最后,请注意我们是如何必须创建任意的新变量名,以避免重复使用相同的变量,从而丢失除其中一个标记之外的所有标记。最简单的方法是使用 $count 变量,这样可以确保您为每个标记都有一个唯一的变量名。

结论

Google Maps 是一个出色的 Web 应用程序。但对于开发人员来说,它也是一个平台,我们可以在其上创建各种依赖于地图的新应用程序和服务。特别是,通过从编程语言动态创建 HTML 文档,我们可以插入 JavaScript 可以随后合并到地图中的数据。下个月,我们将看到我们如何做到这一点,创建我们自己的混搭应用——从一个数据源抓取信息,然后将其显示在 Google 地图上。

本文资源: /article/8939

Reuven M. Lerner,一位资深的 Web/数据库顾问,目前是伊利諾伊州埃文斯頓西北大學学习科学专业的博士生。他和他的妻子最近庆祝了他们的儿子 Amotz David 的出生。

加载 Disqus 评论