My favorites | 中文(简体) | Sign in

Google 地图 API 专业版

除了同样具有功能强大的地图外,还包含 SLA、支持和广告控制。

服务

服务概述

Google 地图 API 会定期扩展,添加新的功能和特性,通常这些功能和特性会先在 ditu.google.cn 上发布。本部分讲述这些服务。注意:由于“服务”的定义在某种程度上较难懂,因此本部分会涉及的内容也较广。我们基本上将无法放到其他部分的内容都放到了本部分中。

XML 和数据解析

Google 地图 API 导出一种工厂方法,用于创建适用于各种浏览器的 XmlHttpRequest() 对象(在 Internet Explorer、Firefox 和 Safari 的最新版本中均可使用)。和所有的 XmlHttpRequest 一样,任何检索的文件都必须在本地域中。以下示例下载名为 myfile.txt 的文件,并使用 JavaScript alert() 显示其内容:

var request = GXmlHttp.create();
request.open("GET", "myfile.txt", true);
request.onreadystatechange = function() {
  if (request.readyState == 4) {
    alert(request.responseText);
  }
}
request.send(null);

该 API 还为典型的 HTTP GET 请求导出一种更简单的 GDownloadUrl() 方法,无需检查 XmlHttpRequest() readyState。上面的示例可以如下使用 GDownloadUrl() 重新编写:

GDownloadUrl("myfile.txt", function(data, responseCode) {
  alert(data);
});

可以使用静态方法 GXml.parse() 解析 XML 文档,该方法取 XML 的一个字符串作为其唯一的参数。此方法与多数流行的浏览器兼容,但如果浏览器本身不支持 XML 解析,它会抛出异常。

在此示例中,我们使用 "data.xml"GDownloadUrl 方法下载一个静态文件 (),它包含一个 XML 格式的经纬坐标列表。当下载完成后,我们使用 GXml 解析该 XML,并在 XML 文档中的每个点处创建一个标记符。

var map = new GMap2(document.getElementById("map_canvas"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(39.9493, 116.3975), 13);

// Download the data in data.xml and load it on the map. The format we
// expect is:
// <markers>
//   <marker lat="39.945" lng="116.375"/>
//   <marker lat="39.872" lng="116.423"/>
// </markers>
GDownloadUrl("data.xml", function(data, responseCode) {
  var xml = GXml.parse(data);
  var markers = xml.documentElement.getElementsByTagName("marker");
  for (var i = 0; i < markers.length; i++) {
    var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
                            parseFloat(markers[i].getAttribute("lng")));
    map.addOverlay(new GMarker(point));
  }
});

查看示例 (xhr-requests.html)。此示例使用外部 XML 数据文件 data.xml

有关详细信息,请参见 GXmlHttpGXml 类参考。

地址解析

地址解析是将地址(如“1600 Amphitheatre Parkway, Mountain View, CA”)转换为地理坐标(如经度 -122.083739 和纬度 37.423021)的过程,可以用于放置标记符或定位地图。Google 地图 API 包含地址解析服务,可以通过 HTTP 请求直接访问,也可以通过使用 GClientGeocoder 对象来访问。

请注意,地址解析是一种时间和资源密集型任务。尽量为您的地址预先进行地址解析(使用 HTTP 地址解析器或其它地址解析服务),并使用地址解析缓存存储您的结果。

地址解析对象

可以通过 GClientGeocoder 对象访问 Google 地图 API 地址解析服务。使用 GClientGeocoder.getLatLng() 将字符串地址转换为 GLatLng。此方法采用要转换的字符串地址以及在检索到地址后要执行的回调函数作为参数。该回调函数是必要的,因为地址解析涉及向 Google 的服务器发送请求,可能需要一些时间。

在此示例中,我们将对一个地址进行地址解析,在该点添加标记,并打开一个显示该地址的信息窗口。请注意,该回调函数作为函数显式声明传递。

var map = new GMap2(document.getElementById("map_canvas"));
var geocoder = new GClientGeocoder();

function showAddress(address) {
  geocoder.getLatLng(
    address,
    function(point) {
      if (!point) {
        alert("无法解析:" + address);
      } else {
        map.setCenter(point, 13);
        var marker = new GMarker(point);
        map.addOverlay(marker);
        marker.openInfoWindowHtml(address);
      }
    }
  );
}

查看示例 (geocoding-simple.html)

还可以通过 GLatLngBounds 方法修改地图 API 地址解析器以指定解析结果在指定的视口内(视口是一个 GClientGeocoder.setViewport() 类型的矩形区域)。您可以使用 GClientGeocoder.setBaseCountryCode() 方法返回为特定地区(国家)定制的结果。可以对 Google 地图主应用程序提供地址解析的每个主要地区发送地址解析请求。例如,搜索“Toledo”将返回西班牙地区内(http://maps.google.es)由国家或地区代码“es”指定的不同结果,而不是默认的美国 (http://maps.google.com) 地区内的结果。

抽取结构化地址

如果要访问有关某个地址的结构化信息,GClientGeocoder 还提供了 getLocations() 方法,该方法返回包括以下信息的 JSON 对象:

  • Status
    • request - 请求类型。在本例中,始终是 geocode
    • code - 响应代码,类似于 HTTP 状态代码,指示地址解析请求是否成功。请参见状态代码完整列表
  • Placemark - 如果地址解析器发现多个匹配项,则可能返回多个地标。
    • address - 格式化良好,大小写正确的地址版本。
    • AddressDetails - 格式化为 xAL(或可扩展地址语言,一种地址格式化的国际标准)的地址。
      • Accuracy - 表示指定地址的地址解析所能达到的精确度的属性。请参见可能值列表
    • Point - 三维空间中的点。
      • coordinates - 地址的经度、纬度和海拔。在本例中,海拔始终设置为 0。

下面我们展示使用地址解析器解析 Google 总部地址返回的 JSON 对象:

{
  "name": "1600 Amphitheatre Parkway, Mountain View, CA, USA",
  "Status": {
    "code": 200,
    "request": "geocode"
  },
  "Placemark": [
    {
      "address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
      "AddressDetails": {
        "Country": {
          "CountryNameCode": "US",
          "AdministrativeArea": {
            "AdministrativeAreaName": "CA",
            "SubAdministrativeArea": {
              "SubAdministrativeAreaName": "Santa Clara",
              "Locality": {
                "LocalityName": "Mountain View",
                "Thoroughfare": {
                  "ThoroughfareName": "1600 Amphitheatre Pkwy"
                },
                "PostalCode": {
                  "PostalCodeNumber": "94043"
                }
              }
            }
          }
        },
        "Accuracy": 8
      },
      "Point": {
        "coordinates": [-122.083739, 37.423021, 0]
      }
    }
  ]
}

在此示例中,我们使用 getLocations() 方法对地址进行地址解析,从 JSON 抽取地址的良好格式化版本和两字母的国家或地区代码,并在信息窗口中显示。

var map;
var geocoder;

function addAddressToMap(response) {
  map.clearOverlays();
  if (!response || response.Status.code != 200) {
    alert("\"" + address + "\" not found");
  } else {
    place = response.Placemark[0];
    point = new GLatLng(place.Point.coordinates[1],
                        place.Point.coordinates[0]);
    marker = new GMarker(point);
    map.addOverlay(marker);
    marker.openInfoWindowHtml(place.address + '<br>' + 
      '<b>Country code:</b> ' + place.AddressDetails.Country.CountryNameCode);
  }
}

查看示例 (geocoding-extraction.html)

反向地址解析

术语“地址解析”通常是指将用户可阅读的地址转换成地图上的点。将地图上的点反向转换成用户可阅读的地址的过程称为“反向地址解析”。

GClientGeocoder.getLocations() 方法支持标准地址解析和反向地址解析。如果为此方法传递了一个 GLatLng 对象而不是 String 地址,地址解析器将执行反向查询并返回最接近的可寻址位置的结构化 JSON 对象。请注意,如果提供的 GLatLng 与任何可寻址位置都不完全匹配,那么,最接近的可寻址位置与查询的原始经度值和纬度值之间可能存在一段距离。

注意:反向地址解析不属于精密科学。地址解析器会试图在一定的偏差范围内查找最接近的可寻址位置;如果找不到匹配项,地址解析器通常会返回 G_GEO_UNKNOWN_ADDRESS (602) 状态代码。

var map;
var geocoder;
var address;

function initialize() {
  map = new GMap2(document.getElementById("map_canvas"));
  map.setCenter(new GLatLng(39.90822, 116.4055), 13);
  map.addControl(new GLargeMapControl);
  GEvent.addListener(map, "click", getAddress);
  geocoder = new GClientGeocoder();
}

function getAddress(overlay, latlng) {
  if (latlng != null) {
    address = latlng;
    geocoder.getLocations(latlng, showAddress);
  }
}

function showAddress(response) {
  map.clearOverlays();
  if (!response || response.Status.code != 200) {
    alert("Status Code:" + response.Status.code);
  } else {
    place = response.Placemark[0];
    point = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);
    marker = new GMarker(point);
    map.addOverlay(marker);
    marker.openInfoWindowHtml(
        '<b>orig latlng:</b>' + response.name + '<br/>' + 
        '<b>latlng:</b>' + place.Point.coordinates[0] + "," + place.Point.coordinates[1] + '<br>' +
        '<b>Status Code:</b>' + response.Status.code + '<br>' +
        '<b>Status Request:</b>' + response.Status.request + '<br>' +
        '<b>Address:</b>' + place.address + '<br>' +
        '<b>Accuracy:</b>' + place.AddressDetails.Accuracy + '<br>' +
        '<b>Country code:</b> ' + place.AddressDetails.Country.CountryNameCode);
  }
}

查看示例 (geocoding-reverse.html)

地址解析缓存

GClientGeocoder 默认配备有客户端缓存。该缓存存储地址解析器响应,当重新对地址进行地址解析时可以加快响应。可以通过执行 GClientGeocoder 对象的 setCache() 方法并传递一个 null 参数来关闭缓存。但我们建议保留缓存,因为它可以提高性能。要更改 GClientGeocoder 使用的缓存,请调用 setCache() 方法并传递一个新缓存作为参数。要清空当前缓存的内容,请对地址解析器或直接对缓存调用 reset() 方法。

我们鼓励开发人员构建自己的客户端缓存。在此示例中,我们构造了一个缓存,包含对地址解析 API 所涵盖的国家或地区中的六个首都或首府城市的预先计算的地址解析器响应。首先,我们构建了一个地址解析响应数组。然后,我们创建了扩展标准 GeocodeCache 的自定义缓存。定义该缓存后,我们调用 setCache() 方法。对缓存中存储的对象没有严格检查,所以您也可以在缓存中存储其它信息(例如人口规模)。


// Builds an array of geocode responses for the 6 capitals
var city = [
  {
    name: "Washington, DC",
    Status: {
      code: 200,
      request: "geocode"
    },
    Placemark: [
      {
        address: "Washington, DC, USA",
        population: "0.563M",
        AddressDetails: {
          Country: {
            CountryNameCode: "US",
            AdministrativeArea: {
              AdministrativeAreaName: "DC",
              Locality: {
                LocalityName: "Washington"
              }
            }
          },
          Accuracy: 4          
        },
        Point: {
          coordinates: [-77.036667, 38.895000, 0]
        }
      }
    ]
  },
  ... // etc., and so on for other cities
];

  var map;
  var geocoder;

  // CapitalCitiesCache is a custom cache that extends the standard GeocodeCache.
  // We call apply(this) to invoke the parent's class constructor.
  function CapitalCitiesCache() {
    GGeocodeCache.apply(this);
  }

  // Assigns an instance of the parent class as a prototype of the
  // child class, to make sure that all methods defined on the parent
  // class can be directly invoked on the child class.
  CapitalCitiesCache.prototype = new GGeocodeCache();

  // Override the reset method to populate the empty cache with
  // information from our array of geocode responses for capitals.
  CapitalCitiesCache.prototype.reset = function() {
    GGeocodeCache.prototype.reset.call(this);
    for (var i in city) {
      this.put(city[i].name, city[i]);
    }
  }

  map = new GMap2(document.getElementById("map_canvas"));
  map.setCenter(new GLatLng(37.441944, -122.141944), 6);

  // Here we set the cache to use the UsCitiesCache custom cache.
  geocoder = new GClientGeocoder();
  geocoder.setCache(new CapitalCitiesCache());

查看示例 (geocoding-cache.html)

通过 HTTP 进行地址解析

还可以使用服务器端脚本来直接访问地图 API 地址解析器。使用客户端地址解析器时不建议使用这种方法,但该方法在进行调试时或 JavaScript GClientGeocoder 对象不可用时却很有用。

要访问地图 API 地址解析器,请访问 http://ditu.google.cn/maps/geo? 并在网址中添加以下参数:

  • q(必填)- 您要进行地址解析的地址。
  • key(必填)- 您的 API 密钥。
  • sensor(必填)- 指示地址解析请求是否来自装有位置传感器的设备。该值必须为 truefalse
  • output(必填)- 生成时输出应采用的格式。选项有 xmlkmlcsv 或默认选项 json
  • ll(可选)- 视口中心的 {经度,纬度},表示为以逗号分隔的字符串(例如“ll=-117.773438,40.479581”)。仅当将 spn 参数也传递给地址解析器时此参数才有意义。
  • spn(可选)- 视口的“范围”,表示为以逗号分隔的 {经度,纬度} 字符串(例如“spn=22.5,11.1873”)。仅当将 ll 参数也传递给地址解析器时此参数才有意义。
  • gl(可选)- 国家/地区代码,指定为 ccTLD(“顶级域”)双字符值。

注意:glspn,ll 视口参数只会影响地址解析器的结果,而不会完全限制其结果。

在以下示例中,我们请求 Google 总部的地理坐标:

http://ditu.google.cn/maps/geo?q=1600+Amphitheatre+Parkway,+Mountain+View,+CA&output=xml&sensor=true_or_false&key=abcdefg

本例中,我们将 sensor 参数用作变量“true_or_false”,用以强调您必须将该值显示设置为 truefalse

如果指定 json 作为输出,则响应会格式化为 JSON 对象。如果指定 xmlkml,则响应以 KML 格式返回。XML 和 KML 输出完全相同(对于 MIME 类型除外)。

例如,下面是地址解析器对“1600 amphitheatre mountain view ca”返回的响应。

<kml xmlns="http://earth.google.com/kml/2.0">
  <Response>
    <name>1600 amphitheatre mountain view ca</name>
    <Status>
      <code>200</code>
      <request>geocode</request>
    </Status>
    <Placemark>
      <address> 
        1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA
      </address>
      <AddressDetails Accuracy="8">
        <Country>
          <CountryNameCode>US</CountryNameCode>
 	  <AdministrativeArea>
            <AdministrativeAreaName>CA</AdministrativeAreaName>
           <SubAdministrativeArea>
             <SubAdministrativeAreaName>Santa Clara</SubAdministrativeAreaName>
             <Locality>
               <LocalityName>Mountain View</LocalityName>
    	       <Thoroughfare>
                 <ThoroughfareName>1600 Amphitheatre Pkwy</ThoroughfareName>
               </Thoroughfare>
               <PostalCode>
                 <PostalCodeNumber>94043</PostalCodeNumber>
               </PostalCode>
             </Locality>
           </SubAdministrativeArea>
         </AdministrativeArea>
       </Country>
     </AddressDetails>
     <Point>
       <coordinates>-122.083739,37.423021,0</coordinates>
     </Point>
   </Placemark>
  </Response>
</kml>

如果想要得到易于解析的较短响应,并且不需要特殊的特性(如多个结果或良好的格式),我们还提供一种 csv 输出。以 csv 格式返回的大幅包括四个数字,之间使用逗号分隔:

  1. HTTP 状态代码
  2. 精确度(请参见精确度常数
  3. 纬度
  4. 经度

以下示例按照准确性从低到高的顺序显示了对三个地址的回复:“State St, Troy, NY”、“2nd st & State St, Troy, NY”和“7 State St, Troy, NY”

200,6,42.730070,-73.690570
200,7,42.730210,-73.691800
200,8,42.730287,-73.692511

使用“街道视图”对象

使用“街道视图全景”对象需要客户端浏览器支持 Flash 插件。

小至指定道路,大至 Google 地图覆盖的整个区域,Google 街道视图均提供 360 度的全景视图。下面显示了一张示例街道视图图像。


Google 街道视图使用大部分浏览器支持的 Flash® 插件显示这些交互图像。现在,Google 地图 API 提供街道视图服务,可用于获取及处理在 Google 地图街道视图中使用的图像!

GStreetviewPanorama 对象

通过使用 GStreetviewPanorama 对象可支持街道视图图像,该对象可向街道视图 Flash® 查看器提供一个 API 接口。要将街道视图合并到地图 API 应用程序中,您需要遵循以下简单步骤:

  1. 创建一个容器(通常是 <div> 元素),来包含街道视图 Flash® 查看器。
  2. 创建一个 GStreetviewPanorama 对象,然后将其放入该容器中。
  3. 将街道视图对象初始化为引用一个特定位置并显示初始“视点”(POV)。
  4. 通过检查 603 错误值来处理不受支持的浏览器。

GStreetviewPanorama 对象要求其构造函数中有一个容器元素。您还可以使用 GStreetviewPanoramaOptions 参数设置该对象的位置(可选)。可以在构造函数调用结束后调用对象的 setLocationAndPOV() 方法来更改其位置和 POV。

有关容器和设置位置及视点的详细信息,将在下文中介绍。

街道视图容器

街道视图 Flash 查看器需要一个 DOM 容器节点,此节点用于显示查看器的内容(通常是 <div> 元素)。为使全景图像达到最佳显示效果,建议尺寸最小为 200 像素 x 200 像素。也不建议使用大查看器,因为大查看器可能导致 Flash 查看器消耗太多内存,并可能对浏览器的性能带来负面影响。

GStreetviewPanorama 构造函数需要一个 container 参数来确定初始容器元素,该容器元素中将显示街道视图 Flash 查看器。可以对 GStreetviewPanorama 对象应用 hide(),使其暂时不显示;也可以对该对象应用 show(),使其重新显示出来。

在任何时候,如果您想要更改街道视图 Flash 查看器的容器,请向容器发送 setContainer() 方法,从而向该容器传递其应当关联的新元素。如果调整了容器的大小,您可以向 GStreetviewPanorama 对象发送 checkResize() 方法,以强制它调整大小,从而适合其新尺寸。

如果想要从 DOM 中彻底删除街道视图 Flash 查看器并释放其内存,请向该对象传递 remove() 方法。如果想要从 DOM 中删除容器元素,则必须调用该方法,否则将导致客户端浏览器的内存泄漏。

街道视图位置

街道视图图像包含一个位置(对应于 GLatLng)和一个特定的方向 (GPov),二者共同标识图像显示的视图。这两个参数都可以在构造街道视图对象时使用 GStreetviewPanoramaOptions 可选参数来指定。

当前受支持的街景视图的城市列表可以从 Google 地图帮助中心获得。可通过三种基本方法来确定某个位置是否支持街道视图数据:

  • 可以存储已知有效的街道视图位置的 GLatLng
  • 可以检查 GStreetviewOverlay 图块叠加层,然后目测检查道路网络。支持街道视图的道路在叠加层上以蓝色高亮显示。然后您可以使用单击事件或地址解析逻辑将受支持的位置传递给 GStreetviewPanorama 对象。(请参见街道视图叠加层。)
  • 您可以使用 GStreetviewClient 对象,对指定了传递 GLatLng 的街道视图对象执行查询。GStreetviewClient 对象支持使用大量查询来查找全景数据。(请参见街道视图客户端查询。)

请注意,后两种方法是不精确的:在这些情况下,街道视图服务不需要(且通常不接收)精确的经度和纬度,而是搜索是否存在“接近”指定 GLatLng 的全景数据。

以下示例使用 GStreetviewPanoramaOptions 指定要用于街道视图的初始经度和纬度。POV 保留为空,表示使用默认视图朝向北方。

var fenwayPark = new GLatLng(42.345573,-71.098326);
panoramaOptions = { latlng:fenwayPark };
var myPano = new GStreetviewPanorama(document.getElementById("pano"), panoramaOptions);

查看示例 (streetview-simple.html)

街道视图错误处理

由于街道视图要求支持 Flash® 插件,因此您的代码应检查该插件在用户浏览器上是否可用。也可以通过注册一个对 GStreetviewPanorama 对象上的 error 事件进行侦听的事件侦听器,来在您的应用程序中进行此检查。error 事件可传递一个可以评估的错误代码

以下示例代码将对是否支持 Flash 插件执行快速检查,如果不支持 Flash 则显示一个警告对话框。

var fenwayPark = new GLatLng(42.345573,-71.098326);
panoramaOptions = { latlng:fenwayPark };
myPano = new GStreetviewPanorama(document.getElementById("pano"), panoramaOptions);
GEvent.addListener(myPano, "error", handleNoFlash);
    
function handleNoFlash(errorCode) {
  if (errorCode == 603) {
    alert("Error: Flash doesn't appear to be supported by your browser");
    return;
  }
}  

街道视图视点 (POV)

街道视图位置定义一个图像相机的放置位置,但是不定义该图像相机的方向。为了定义相机方向,GPov 对象常量定义了三个属性:

  • yaw 定义以相机位置为圆心相对于正北方向的旋转角度(以度为单位)。摆角按顺时针方向测量(90 度为正东方向)。
  • pitch 定义相对于相机初始默认倾斜度的“向上”或“向下”差值,默认倾斜度通常为(但不总是)平直水平。(例如,在山上拍摄的图像所表现出的默认倾斜度可能不是水平的。)测量倾斜角度时,向上看为负值(最大为 –90 度,竖直向上并与默认倾斜面垂直),向下看为正值(最大为 +90 度,竖直向下并与默认倾斜面垂直)。
  • zoom 定义此视图的缩放级别(有效地限制“视野”),0 表示完全缩小。不同的街道视图位置可能提供更高或更低的缩放级别。

默认情况下,这些值均为 0,所定义的视图为平直水平,方向为正北,且显示最宽的视野。

设置全景视图

如前文所述,可以在构造全景对象时使用 GStreetviewPanoramaOptions 参数设置该对象的位置和 GPov

fenwayPark = new GLatLng(42.345573,-71.098326);
myPOV = {yaw:370.64659986187695,pitch:-20};
svOpts = {latlng:fenwayPark, pov:myPOV};
var myPano = new GStreetviewPanorama(document.getElementById("pano"), svOpts);
在构造 GStreetviewPanorama 对象后,您还可以使用 setLocationAndPOV() 方法设置位置和 POV。在以下示例中,我们将创建一个 GStreetviewPanorama 对象,然后将其位置和 POV 设置为某个特定值。

var myPano = new GStreetviewPanorama(document.getElementById("pano"));
fenwayPark = new GLatLng(42.345573,-71.098326);
myPOV = {yaw:370.64659986187695,pitch:-20};
myPano.setLocationAndPOV(fenwayPark, myPOV);

查看示例 (streetview-object.html)

使用街道视图叠加层

确定道路是否支持街道视图的最简单方法是通过使用 GStreetviewOverlay 对象。只需创建一个此类型的叠加层,然后将其添加到地图中;包含街道视图数据的道路将使用蓝色边界在地图上高亮显示。

var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(39.9493, 116.3975), 13);
svOverlay = new GStreetviewOverlay();
map.addOverlay(svOverlay);

查看示例 (streetview-layer.html)

当您知道某个地理区域支持街道视图后,可以通过填充 GStreetviewPanorama 对象在有效的街道视图道路上添加可响应单击操作的逻辑。

var myPano = new GStreetviewPanorama(document.getElementById("pano"));
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(42.345573,-71.098326), 14);
svOverlay = new GStreetviewOverlay();
map.addOverlay(svOverlay);
GEvent.addListener(map,"click", function(overlay,latlng) {
  myPano.setLocationAndPOV(latlng);
});

查看示例 (streetview-click.html)

如果您知道某个特定位置支持街道视图,则可以保存该位置信息和 POV 并将这些信息放入对象本身。

街道视图客户端查询

从用户角度而言,通过目测检查 GStreetviewOverlay 的方式来确定某条道路是否支持街道视图通常不太可行,也不可取。出于此原因,API 提供了一种以程序方式发出请求并检索街道视图数据的服务。此服务通过使用 GStreetviewClient 对象得到简化。

执行街道视图查找

GStreetviewClient 对象使用 Google 的街道视图服务执行全景数据查找。由于此种查找为异步进行,所以此类方法需要在接收数据时执行回调函数。如果未返回值,那么指定的所有回调都会传递 null,因此您应当检查您的回调函数中是否存在这种情况。

GStreetviewClient 方法 getNearestPanoramaLatLng() (其本身作为 GLatLng 传递)会从指定的位置检索邻近的全景图像的 GLatLng

getNearestPanorama()getPanoramaById() 反而会检索 GStreetviewData 对象,该对象存储关于特定全景对象的元数据。此类数据在下文中介绍。

处理客户端响应

GStreetviewData 对象的结构包含三种属性:locationcopyright(包含正显示的特定图像的信息),以及links(提供有关邻近全景对象的信息)。这些属性的结构如下所述:

# The location property uses the GStreetviewLocation object literal
location: {
  latlng: GLatLng, 
  pov: { 
    yaw: String, 
    pitch: String, 
    zoom: String
  }, 
  description: String, 
  panoId: String
}

copyright: String

# The links property uses the GStreetviewLink object literal
links[]: {
  yaw: String, 
  description: String, 
  panoId: String
}

GStreetviewLocationGStreetviewLink 对象常量的完整说明位于 地图 API 参考中)。

注意:不应将 GStreetviewData.location 属性与 window.location 属性混淆。如果尝试从此对象的 location 属性中抽取数据,请确保您确实接收到了从街道视图服务器传回的响应(如下所示)。否则,location 属性将默认为 window.location,并且将发生意外行为。

如果对 GStreetviewClient 对象的请求成功,它会将 GLatLngGStreetviewData 对象传递给指定的回调函数。因为检索街道视图数据为异步进行,然而,客户端对象可能不检索这些数据对象,因此您的代码不应依赖于这些对象是否显示。相反,您应始终检查必定会返回的任何请求所返回的 code 值。以下代码段说明了此概念。

panoClient = new GStreetviewClient();
panoClient.getPanoramaById(panoData.location.panoId, processReturnedData);
    
function processReturnedData(panoData) {
  if (panoData.code != 200) {
    GLog.write('showPanoData: Server rejected with code: ' + panoData.code);
    return;
  }
  
  // Code to actually process the GStreetviewData object is contained here
  
}  

包含示例 GStreetviewData 结构的完整响应如下所示:

{
  location: {
    latlng: GLatLng("42.345566, -71.098354")
    pov: {
      yaw: "370.64659986187695"
      pitch: "-20"
      zoom: "1"
    }
    description: "Yawkey Way"
    panoId: "-KNGDaZvSQjMqug7ISM_CA"
  }
  copyright: "© 2008 Google"
  links:[ {
    yaw: "0"
    description: "Yawkey Way"
    panoId: "S142iWXa_4Fi7L7d8HKhuQ"
  },
  {
    yaw: "0"
    description: "Yawkey Way"
    panoId: "2vFI79AjOpHTAYJSCKquFg"
  }
  ]
}

以下样本应用程序将显示初始全景对象,抽取其 ID,然后存储返回的 GStreetviewData 对象中的链接全景对象,并显示与该街道视图对象相关的数据集。用户每次单击“下一步”时,该过程都会重复,允许用户“行进”过一组邻近全景对象。

var map;
var myPano;   
var panoClient;
var nextPanoId;

function initialize() {
  var fenwayPark = new GLatLng(42.345573,-71.098326);
  var fenwayPOV = {yaw:370.64659986187695,pitch:-20};
      
  panoClient = new GStreetviewClient();      
   
  map = new GMap2(document.getElementById("map_canvas"));
  map.setCenter(fenwayPark, 15);
  GEvent.addListener(map, "click", function(overlay,latlng) {
    panoClient.getNearestPanorama(latlng, showPanoData);
  });
      
  myPano = new GStreetviewPanorama(document.getElementById("pano"));
  myPano.setLocationAndPOV(fenwayPark, fenwayPOV);
  GEvent.addListener(myPano, "error", handleNoFlash);  
  panoClient.getNearestPanorama(fenwayPark, showPanoData);
}
    
function showPanoData(panoData) {
  if (panoData.code != 200) {
    GLog.write('showPanoData: Server rejected with code: ' + panoData.code);
    return;
  }
  nextPanoId = panoData.links[[0[].panoId;
  var displayString = [[
    "Panorama ID: " + panoData.location.panoId,
    "LatLng: " + panoData.location.latlng,
    "Copyright: " + panoData.copyright,
    "Description: " + panoData.location.description,
    "Next Pano ID: " + panoData.links[[0[].panoId
  [].join("
"); map.openInfoWindowHtml(panoData.location.latlng, displayString); GLog.write('Viewer moved to' + panoData.location.latlng); myPano.setLocationAndPOV(panoData.location.latlng); } function next() { // Get the next panoId // Note that this is not sophisticated. At the end of the block, it will get stuck panoClient.getPanoramaById(nextPanoId, showPanoData); } function handleNoFlash(errorCode) { if (errorCode == 603) { alert("Error: Flash doesn't appear to be supported by your browser"); return; } }

查看示例 (streetview-data.html)

与 Google 地球插件集成

Google 地图 API 现在可让开发人员处理其地图 API 应用程序中的 Google 地球实例(需要通过单独安装 Google 地球插件)。Google 地球地图层通过外观和行为都像独立 Google 地球应用程序的单独 GMapType 显示,这样您就可以在浏览器中旋转视角、观看立体图以及查看 Google 地球 KML 信息。

注意:Google 地球插件必须安装在用户的计算机上才能使用该 Google 地球 GMapType。当前,此插件仅适用于 Microsoft Windows。有关完整的系统要求,请参见 Google 地球 API 开发人员指南

加载 Google 地球插件(仅适用于 Windows)

适用于 Windows 的 Google 地球插件可从以下网址获得:

http://earth.google.com/intl/zh-CN/

Google 地球插件可通过自己的 API 进行控制,它自己的 API 与 Google 地图 API 是互相独立的,也是不同的。有关使用该插件和 Google 地球 API 的详细信息,请参见 Google 地球 API 开发人员指南

也可在 Google 地图 API 中对 Google 地球插件进行实例化。

初始化 Google 地球插件

要将 Google 地球实例添加至您的地图,只需通过 GMap2.addmapType()G_SATELLITE_3D_MAP 添加至您的地图。然后,可以将地图设置为直接显示此地图类型(通过 GMap2.setMapType()),用户也可自己在 GMapTypeControl 中选择此地图类型(通过用 GMap2.addControl() 来添加一个地图类型控件)。

以下代码会将 G_SATELLITE_3D_MAP 地图类型添加到地图,然后显式地将地图设置为在地图中显示 Google 地球地图类型。(请注意,第一次点击此示例时,系统会提示您安装 Google 地球插件)。

var map = new GMap2(document.getElementById("map_canvas"),{ size: new GSize(640,480) } );
map.setCenter(new GLatLng(39.927, 116.407), 11);
map.addMapType(G_SATELLITE_3D_MAP);
var mapControl = new GMapTypeControl();
map.addControl(mapControl);
map.setMapType(G_SATELLITE_3D_MAP);

查看示例 (services-earth-plugin.html)

本地搜索

如果要向您的网站中添加本地搜索功能,可以使用 Google AJAX 搜索 API 在网站中嵌入本地搜索控件。此控件是 GControl 对象的一个子类,是一个很好的创建自定义控件的示例。

向您的地图 API 应用程序中添加此控件之前,需要添加 Google AJAX 搜索 API 的网址,并使用地图 API 密钥才能使用该服务。您还需要加载该控件对象的样式表,如下所示:

// Load the Code
<script src="http://www.google.cn/uds/api?file=uds.js&v=1.0&key=ABCDEF"
      type="text/javascript"></script>
<script src="http://www.google.cn/uds/solutions/localsearch/gmlocalsearch.js" 
      type="text/javascript"></script>

// Load the Style Sheets
<style type="text/css">
  @import url("http://www.google.cn/uds/css/gsearch.css");
  @import url("http://www.google.cn/uds/solutions/localsearch/gmlocalsearch.css");
</style>

或者可以使用 AJAX 加载器,通过公共加载器加载所有这些模块。

执行完这些准备任务之后,加载控件本身相对比较简单:

// create your map
var map = new GMap2(document.getElementById("map_canvas"));

// create a local search control and add it to your map
var lsc = new google.maps.LocalSearch(); 
map.addControl(new google.maps.LocalSearch());

查看示例 (control-localsearch.html)

关于本地搜索控件的详细信息,请参见 Google AJAX 搜索 API 参考

KML/GeoRSS 叠加层

Google 地图 API 支持用于显示地理信息的 KML 和 GeoRSS 数据格式。使用 GGeoXml 对象将这些数据格式添加到地图,该对象的构造函数采用可公开访问的 XML 文件的网址。GGeoXml 地标显示为 GMarker,而 GGeoXml 折线和多边形显示为 Google 地图 API 折线和多边形。KML 文件中的 <GroundOverlay> 元素显示为地图上的 GGroundOverlay 元素。

使用 addOverlay() 方法将 GGeoXml 对象添加到地图。(您可以使用 removeOverlay() 从地图中删除它们。)KML 和 GeoRSS XML 文件均受支持。请注意,GGeoXml 是 Google 地图 API 中的一个模块化对象,并且在首次使用后才会完全加载。因此,请仅当页面完全加载后再调用其构造函数。此操作通常通过在 <body>onload 处理程序中调用 GGeoXml 构造函数来完成。

// The GGeoXml constructor takes a URL pointing to a KML or GeoRSS file.
// You add the GGeoXml object to the map as an overlay, and remove it as an overlay as well.
// The Maps API determines implicitly whether the file is a KML or GeoRSS file.

var map;
var geoXml;

function initialize() {
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById("map_canvas")); 
    geoXml = new GGeoXml("http://mapgadgets.googlepages.com/cta.kml");
    map.addControl(new GLargeMapControl());
    map.setCenter(new GLatLng(39.917, 116.397), 11); 
    map.addControl(new GLargeMapControl());
    map.addOverlay(geoXml);
  }
} 

查看 GeoRSS 示例 (geoxml-rss.html)

查看 KML 示例 (geoxml-kml.html)

交通叠加层

Google 地图 API 可让您使用 GTrafficOverlay 对象(其应用 GOverlay 接口)向地图中添加交通信息。可以使用 GMap2.addOverlay() 方法向地图中添加交通信息。GTrafficOverlay 有两种方法(hide()show())用于切换是否显示交通叠加层。只有支持的城市才能显示交通信息。

也可以使用 GTrafficOverlayOptions 对象常量向 GTrafficOverlay 构造函数传递选项。

// The GTrafficOverlay is unique in that only one object of that type 
// should be added to a map. Adding multiple traffic overlays produces
// no added benefit.

var map;
var trafficInfo;

function initialize() {
  map = new GMap2(document.getElementById("map_canvas")); 
  map.setCenter(new GLatLng(49.496675,-102.65625), 3); 
  var trafficOptions = {incidents:true};
  trafficInfo = new GTrafficOverlay(trafficOptions);
  map.addOverlay(trafficInfo);
} 

查看交通示例 (trafficOverlay.html)

行车路线

您可以使用 GDirections 对象添加该功能来计算行车路线(使用各种交通方式)。GDirections 对象使用查询字符串(例如“New York, NY to Chicago, IL”)或提供的文字经度/纬度(例如“-73.967257, 40.712882 to -87.770677, 41.943181”)请求和接收行车路线结果。GDirections 对象还支持使用一系列路标的多段行车路线。行车路线可以在地图上显示为绘制路线的折线和/或 <div> 元素中的一系列文本描述(例如“向右转到 Williamsburg Bridge 斜道”)。

要在 Google 地图 API 中使用行车路线,请创建类型为 GDirections 的对象,并指定用于接收和显示结果的 GMap2 对象和/或 <div>。默认情况下,地图居中并且通过返回的路线限制边界(尽管可以在 GDirectionOptions 对象中使用参数进行更改)。

加载行车路线

行车路线使用 GDirections.load() 方法请求。此方法取查询字符串和一组可选的 GDirectionsOptions 参数。有以下选项可用:

  • locale 指定返回结果所使用的语言,以覆盖地图 API hl 参数(如果提供的话)。如果 localehl 参数都未指定,则使用浏览器的默认语言。
  • travelMode 指定计算结果时使用的交通方法。
  • avoidHighways 指定计算行车路线时应避开公路。
  • getPolyline 指定行车路线对象应返回折线数据,以绘制返回的行车路线。默认情况下,如果有地图对象显示折线数据,GDirections 对象会仅返回这些数据。如果将该值设置为 true 并且不提供地图,那么您应直接处理折线数据。
  • getSteps 指定行车路线对象应返回文字行车路线,即使未提供 <div> 面板来显示这些行车路线也是如此。如果将该值设置为 true 并且不提供面板,那么您应直接处理路段数据。
  • preserveViewport 指定地图不应自动居中并缩放到返回的行车路线的边界框;相反,地图会在当前视口中保持居中位置。

出行模式

默认情况下,行车路线会假定您是驾车行驶,但您可以通过在调用 Directions.load() 方法时传递 GTravelMode 来请求其他出行模式。支持以下出行方式:

  • G_TRAVEL_MODE_DRIVING 指示使用路网的标准行车路线
  • G_TRAVEL_MODE_WALKING 请求通过步行街和人行道(如果有)的步行路线。

注意:步行路线有时可能不包括畅通的步行街,因此步行路线仅当您在 GDirections 构造函数中提供了 <div> 时才受支持;此 <div> 用于在返回的分路段显示文字路线中向用户显示警告。如果没有此类 <div>,则在请求步行路线时就会返回错误。

处理返回的行车路线

如果 GDirections 对象使用提供的 GMap2 对象构建,则返回的行车路线将包含折线叠加层。如果使用提供的 <div> 元素构造 GDirections 对象,则返回的行车路线将包含一个 GRoute 对象,该对象包含一组 GStep 对象。(如果行车路线包括多点行车路线,则返回的行车路线将包含多个 GRoute 对象,其中每个都包含一系列的 GStep 对象。)

请注意行车路线对象不会立即填充此返回信息。因此,GDirections 对象定义了一个“load”事件,以截获该事件来确定此状态。

默认情况下,返回行车路线后,地图会显示一条显示路线的折线,而文字行车路线则会显示在为达到此目的而提供的 <div> 中。GDirections 对象还会内部存储您可以使用 GDirections.getPolyline() 和/或 GDirections.getRoute(i:Number) 方法检索的结果。可以使用 GRoute.getStep(i:Number) 方法检索路线中的路段,使用 GStep.getDescriptionHtml() 方法检索该路段的 HTML 摘要。(请参见下面的路线和路段。)

GDirections 对象还会触发您可以截获的三个事件:

  • load”:此事件在成功返回行车路线结果、但向地图/面板添加任何叠加层元素之前触发。
  • addoverlay”:在将折线和/或文本格式的行车路线组件添加到地图和/或 DIV 元素之后会触发此事件。
  • error”:如果行车路线请求导致错误,则触发此事件。调用者可以使用 GDirections.getStatus() 获取有关该错误的详细信息。
// Create a directions object and register a map and DIV to hold the 
// resulting computed directions

var map;
var directionsPanel;
var directions;

function initialize() {
  map = new GMap2(document.getElementById("map_canvas"));
  directionsPanel = document.getElementById("my_textual_div");
  map.setCenter(new GLatLng(49.496675,-102.65625), 3);
  directions = new GDirections(map, directionsPanel);
  directions.load("from: 500 Memorial Drive, Cambridge, MA to: 4 Yawkey Way, Boston, MA 02215 (Fenway Park)");
}

查看示例 (directions-simple.html)

以下示例与第一个示例相同,只是行车路线通过传递 G_TRAVEL_MODE_WALKING 调用:

查看示例 (directions-walking.html)

路线和路段

GDirections 对象还支持多点的行车路线,可以使用 GDirections.loadFromWaypoints() 方法构建。此方法取文本输入地址或文本经纬度点的数组。每个单独的沿途路标均计算为单独的路线并在单独的 GRoute 对象中返回,其中每个都包含一系列的 GStep 对象。

GRoute 对象存储路线的路段(类型为 GStep)数目、路线的起点和终点地址解析以及计算出的其他信息,如距离、历时和终点的精确经纬度(如果地址解析不依赖于路段,则可能与终点地址解析不同)。每个 GStep 对象还包含文本描述(例如“通过到 San Jose 的斜道驶上 US-101 S”)以及计算出的信息,包括距离、历时和精确经纬度。

有关行车路线 API 包中的各个对象、方法和事件的完整文档,请参见 API 参考

查看示例 (directions-advanced.html)