Google Maps API 第2版文档

Google Maps API 第2版文档

Google Maps JavaScript API可以让您在自己的网页上使用Google地图.在使用API之前,您应该先申请一个API key,然后按照下面的说明来使用.

因为本API还没有开放多久,因此可能有一些问题,并且不如文档那么完美.所以请您在遇到问题的时候谅解我们并通知我们修正,加入到Maps API讨论组进行反馈和讨论.

本文档针对2006年4月3日推出的Maps API第2版,如果你使用的的API是第1版(例如你在2006年4月3日前开发的网站内容),您应该对您的网站进行升级.相关问题请看:
本文档由K_Reverter翻译并整理,您可以随意在网站上转载本文而不用通知劳烦本人。如果您遇到Google Maps API的相关问题,欢迎到本站来探讨,本站还将有一个关于Google Maps的文章和程序代码可供参考:

目录

谁更适合看本文档?

本文档针对比较熟悉JavaScript编程和面对对象的程序设计模式(OOP)的读者.您应该同时也比较熟悉Google Maps的使用.在网上有很多JavaScript教程可以参考.

介绍

Google Maps的"Hello World"程序

学习API最容易的方法是看看简单的使用范例.下面这个网页在页面上显示一个750x550的地图:

<!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=GB2312"/>
    <title>Google Maps JavaScript API范例1:基本范例</title>
    <script charset="utf-8" src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=abcdefg"
            type="text/javascript"></script>
    <script type="text/javascript">
    //<![CDATA[

    function load() {
      if (GBrowserIsCompatible()) {
        var map = new GMap2(document.getElementById("map"));
        map.setCenter(new GLatLng(36.94,106.08),4);
      }
    }

    //]]>
    </script>
  </head>
  <body onload="load()" onunload="GUnload()">
    <div id="map" style="width: 750px; height: 550px"></div>
  </body>
</html>

您可以下载本范例并修改和运行它,不过您必须先将其中的key替换成您自己Maps API key. (如果您为一个网站目录注册了一个key,它将同样可以运行在所有的子目录下.)

上面范例之中用到的一个URL地址(http://maps.google.com/maps?file=api&v=2)是一个JavaScript文件的路径,这个文件之中包含所有在网页上显示地图所需要的组件.您的网页必须包含一个script标签指向到这个地址,并使用您申请到的API key.例如如果您的Maps API key是"abcdefg",你的script标签就应该是这样的:

<script charset="utf-8" src="http://maps.google.com/maps?file=api&v=2&key=abcdefg"
        type="text/javascript">
</script>

在网页上表示一个地图的类是GMap2.您可以在页面上通过创建该类的多个实例来在同一个页面上显示多幅地图(在页面上每一个GMap2实例对应一幅地图).当您创建一个地图实例的时候,您应该指定页面上的一个元素来包含地图,通常是一个div元素.如果您没有严格的定义地图的大小,地图使用该元素的大小作为默认的大小.

浏览器兼容性

Google Maps API支持所有和Google Local网站兼容的浏览器.因为不兼容的浏览器存在不同的行为,所以Maps API提供了一个全局函数(GBrowserIsCompatible())来检查浏览器的兼容性,并且在不兼容的浏览器上不会执行任何操作,而且脚本http://maps.google.com/maps?file=api&v=2能被几乎所有的浏览器解析,因此在检查浏览器兼容性之前您也可以安全的在页面上引用.

本文档的所有范例都没有进行浏览器兼容性的检查(除了上面的第一个例子),它们也没有对不兼容的浏览器给出任何的错误提示,明显最终的程序应该对不兼容的浏览器进行更加友好的处理,但是我们为了这些范例足够简单而忽略了这些检查.

大型的程序都将不可避免的遇到浏览器和平台的不一致带来的麻烦,这个问题确实不好解决,在Google Maps API讨论组quirksmode.org 上有这方面很好的参考资源.

XHTML和VML

我们建议您在包含地图的页面上使用标准(standards-compliant)的XHTML.当浏览器在页面源代码的顶端发现XHTML DOCTYPE , 它就会使用"standards compliance mode"来处理页面,这样将使浏览器的布局和行为有更好的跨浏览器兼容性.

如果您想要在您的地图上显示折线(例如驾驶路线),您需要在您的XHTML页面上导入VML命名空间和一些CSS代码以让折线在IE之中正常显示.您的XHTML文档开头应该是这样的:

<!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" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=GB2312"/>
    <title>我的Google Maps</title>
    <style type="text/css">
    v\:* {
      behavior:url(#default#VML);
    }
    </style>
    <script charset="utf-8" src="http://maps.google.com/maps?file=api&v=2&key=abcdefg"
             type="text/javascript"></script>
  </head>

API升级

在URLhttp://maps.google.com/maps?file=api&v=2之中的v=2代表使用API 的"第2版".假如我们将来对API有了重大的更新,我们将改变这个版本号,并在Google CodeMaps API 讨论组上发布公告.

在新版本发布后,我们将先同时运行新版和旧版一个月左右,然后,旧版将会被关闭,使用旧版的代码将不再能运行.

地图小组将经常更新API以修正Bug和改善性能.这些更新应该对API使用没有影响,但却可能中断一些API连接,请在这些问题出现时,到Maps API讨论组去报告您的问题.

地理编码和行程安排

Google Maps API现在并不包含地理编码和行程安排服务.不过,网上有很多提供免费地理编码的网站.

范例

以下的每一个范例都只显示了相关的JavaScript代码,而不是完整的HTML文件.您可以将这个JS代码插入到上面的HTML框架文件之中,或者您可以点击例子下面的链接来下载完整的HTML文件.

基本范例

这个范例创建一个地图并定位到中国的位置.

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(36.94,106.08),4);

查看范例(1.simple.html)

改变地图类型

这个范例在Google的原文件之中并不存在,我觉得这个比较重要,而Google的文档之中似乎就没有提及,因此就添加了一个说明.

GMap2和原来的GMap差不多,使用setMapType来改变地图类型,不过前往要注意的一点是,GMap2不支持在初始化地图之前设置地图的类型,也就是说,setMapType要在setCenter之后执行,否则会报错

Google集成支持的3种地图类型分别为:G_NORMAL_MAP,G_SATELLITE_MAP,G_HYBRID_MAP,还支持自定义地图类型.

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(36.94,106.08),4);
map.setMapType(G_SATELLITE_MAP);//修改地图类型

查看范例(1.setmaptype.html)

地图的移动和变换

下面的范例显示了一个地图,并在2秒之后变换到一个新的中心点.

panTo方法用来将地图变换到指定的中心点,如果指定点在地图上,则地图会平滑的移动到该位置,否则直接跳转到该位置.

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(34.45221847282654,127.28515625),4);
window.setTimeout(function() {
  map.panTo(new GLatLng(35.746512259918504,78.90625));
}, 2000);

查看范例(2.animate.html)

向地图上添加控件

您能够使用addControl方法向地图添加控件.在这个例子之中,我们添加了系统集成的GSmallMapControl控件和GMapTypeControl控件,第一个允许用户移动和缩放地图,第二个允许用户在地图类型之间切换.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(36.94,106.08),4);
map.setMapType(G_SATELLITE_MAP);//修改地图类型

查看范例(3.controls.html)

事件监视器

要注册一个事件监视器,请使用GEvent.addListener方法.传递给它一个地图对象,一个要监视的事件名称,和一个在指定事件发生时要运行的函数.在下面的范例代码之中,我们在用户拖动地图之后显示地图中心点的纬度和经度.

var map = new GMap2(document.getElementById("map"));
GEvent.addListener(map, "moveend", function() {
  var center = map.getCenter();
  document.getElementById("message").innerHTML = center.toString();
});
map.setCenter(new GLatLng(36.94,106.08),4);

查看范例(4.event.html)

要了解更多关于事件的信息,请看事件介绍.如果要查看GMap2的所有事件和事件创建的范例列表,请看GMap2.Events.

打开信息浮窗

要创建一个信息浮窗,您应该使用openInfoWindow方法,并传递给它一个位置和一个要显示的DOM标签. 下面的范例显示了一个信息浮窗指向地图的中心,内容为简单的"你好,中国"消息.

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(36.94,106.08),4);
map.openInfoWindow(map.getCenter(),
                   document.createTextNode("你好,中国"));

查看范例(5.infowindow.html)

地图标注

这个范例随机的在地图上显示了10个标记和由随机的5个点组成的1条折线.如果没有为GMarker指定图标,则会使用默认的Google Maps icon图标.在创建图标有一个使用自定义图标的范例.

记得您必须在您的HTML文档之中引入VML命名空间和CSS以让您的页面能够在IE浏览器之中显示折线.查看XHTML 和VML获得更多信息.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(36.94,106.08),4); 

//在地图上添加10个位置随机的标记
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 10; i++) {
  var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
                          southWest.lng() + lngSpan * Math.random());
  map.addOverlay(new GMarker(point));
}

//随机取五个点连成折线,5个点按照经度排序防止折线自身交叉.
var points = [];
for (var i = 0; i < 5; i++) {
  points.push(new GLatLng(southWest.lat() + latSpan * Math.random(),
                          southWest.lng() + lngSpan * Math.random()));
}
points.sort(function(p1, p2) {
  return p1.lng() - p2.lng();
});
map.addOverlay(new GPolyline(points));

查看范例(6.overlay.html)

单击事件句柄

要在用户点击地图的时候执行一些操作,请为您的GMap2实例的"click"事件注册一个事件监视器. 当事件被触发后,事件处理函数将接收到2个变量:被点击的标记(如果存在),和代表被点击点的GLatLng.如果用户并没有点击在标记上,第一个参数将会是null.

注意:Marker是唯一内建支持"click"事件的标注类型.其他类型的标记如GPolyline是不能被点击的.

在下面的范例之中,如果用户在地图上点击而并没有点击在标记上,我们将在用户点击的地方创建一个新的标记.如果用户在标记上点击,我们将相应的标记从地图上移除.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(36.94,106.08),4);

GEvent.addListener(map, "click", function(marker, point) {
  if (marker) {
    map.removeOverlay(marker);
  } else {
    map.addOverlay(new GMarker(point));
  }
});

查看范例(7.click.html)

要了解更多关于事件的信息,请看事件介绍.如果要查看GMap2的所有事件和事件创建的范例列表,请看GMap2.Events.

在标记上显示信息浮窗

在这个范例之中,我们监视每一个标记的点击事件,并在被点击之后在相应的标记上方显示一个自定义的信息浮窗,我们使用JavaScript函数引用的原理来为每一个标记显示不同的信息浮窗内容.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(36.94,106.08),4);

//在指定点以指定标签创建标记
function createMarker(point, number) {
  var marker = new GMarker(point);
  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml("Marker #<b>" + number + "</b>");
  });
  return marker;
}

//添加10个位置随机的标记
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 10; i++) {
  var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
                          southWest.lng() + lngSpan * Math.random());
  map.addOverlay(createMarker(point, i + 1));
}

查看范例(8.markerinfowindow.html)

要了解更多关于事件的信息,请看事件介绍.如果要查看GMarker的所有事件和事件创建的范例列表,请看GMarker.Events.

分标签的信息浮窗

API第2版提供了openInfoWindowTabs()GInfoWindowTab类来为信息浮窗提供多标签支持.下面的范例展示了一个显示在一个标记上的简单的分标签的信息浮窗.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(39.88174,116.40632),14);
map.setMapType(G_SATELLITE_MAP);//修改地图类型

//信息浮窗内容
var infoTabs = [
  new GInfoWindowTab("环境", "天坛公园很漂亮,祈年殿尤其不错"),
  new GInfoWindowTab("饮食", "仅次于一般")
];

//在地图的中心添加一个标记并自动打开其信息浮窗
var marker = new GMarker(map.getCenter());
GEvent.addListener(marker, "click", function() {
  marker.openInfoWindowTabsHtml(infoTabs);
});
map.addOverlay(marker);
marker.openInfoWindowTabsHtml(infoTabs);

查看范例(9.tabbedinfowindow.html)

创建图标

下面的范例创建了一个新的图标使用Google Ride Finder "mini"图标作为例子.我们必须指定前景图、阴影图、图标上用来指向地图的点和图标上被信息浮窗指向的点.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(36.94,106.08),4);

//创建小图标
var icon = new GIcon();
icon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
icon.iconSize = new GSize(12, 20);
icon.shadowSize = new GSize(22, 20);
icon.iconAnchor = new GPoint(6, 20);
icon.infoWindowAnchor = new GPoint(5, 1);

//随机的添加10个标记
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 10; i++) {
  var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
                          southWest.lng() + lngSpan * Math.random());
  map.addOverlay(new GMarker(point, icon));
}

查看范例(10.icon.html)

使用图标样式

在很多情况下,您的图标可能仅仅是前景图片不同,而形状和背景图都是一样的,这样要实现多个图标最简单的方法是从已有的GIcon类之中复制一个新的实例包含原有的所有属性,然后再进行自定义.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(36.94,106.08),4);

//创建一个图标模板,指定阴影等
var baseIcon = new GIcon();
baseIcon.shadow = "http://www.google.com/mapfiles/shadow50.png";
baseIcon.iconSize = new GSize(20, 34);
baseIcon.shadowSize = new GSize(37, 34);
baseIcon.iconAnchor = new GPoint(9, 34);
baseIcon.infoWindowAnchor = new GPoint(9, 2);
baseIcon.infoShadowAnchor = new GPoint(18, 25);

//创建用指定字母作为前景图的图标
function createMarker(point, index) {
  // Create a lettered icon for this point using our icon class
  var letter = String.fromCharCode("A".charCodeAt(0) + index);
  var icon = new GIcon(baseIcon);
  icon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";
  var marker = new GMarker(point, icon);

  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml("Marker <b>" + letter + "</b>");
  });
  return marker;
}

//随机添加10个标记
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 10; i++) {
  var point = new GLatLng(southWest.lat() + latSpan * Math.random(),
                          southWest.lng() + lngSpan * Math.random());
  map.addOverlay(createMarker(point, i));
}

查看范例(11.iconclass.html)

在地图上使用XML和异步请求(AJAX)

在这个范例之中,我们下载一个静态文件("12.data.xml"),它包含一系列XML各式的经纬度坐标,我们使用GDownloadUrl方法.当下载完成后,我们使用GXml解析XML文档并为其中包含的每一个经纬度坐标创建一个标记.

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(36.94,106.08),4);
map.setMapType(G_SATELLITE_MAP);//修改地图类型

// 下载在12.data.xml之中的数据并加载到地图
// XML的格式大致是这样的:
// <markers>
//   <marker lat="39.98629852076348" lng="116.3574438359872"/>
//   <marker lat="29.94176113301537" lng="112.6857368551186"/>
// </markers>
GDownloadUrl("12.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));
  }
});

查看范例(12.async.html).这个范例使用了这个外部的XML数据文件12.data.xml.

自定义地图控件

API第2版提供了创建自定义地图控件的功能,类似集成的导航和缩放等级控制的控件,方法是实现集成的GControl接口.在这个范例之中,我们创建了一个简单的缩放等级控件,这个控件使用文字链接来操作,而不是像集成的标准地图控件那样使用图标来操作.

GTextualZoomControl类定义了2个实现GControl接口必需的方法: initialize()用来创建控件需要的DOM标签;getDefaultPosition()用来返回控件的默认显示位置.查看GControl类参考可以得到更多关于创建自定义控件时需要重写的方法信息.

所有的地图控件都将被添加到地图的container层,这个层可以通过地图GMap2getContainer() 方法获取到.

// A TextualZoomControl is a GControl that displays textual "Zoom In"
// and "Zoom Out" buttons (as opposed to the iconic buttons used in
// Google Maps).
function TextualZoomControl() {
}
TextualZoomControl.prototype = new GControl();

// Creates a one DIV for each of the buttons and places them in a container
// DIV which is returned as our control element. We add the control to
// to the map container and return the element for the map class to
// position properly.
TextualZoomControl.prototype.initialize = function(map) {
  var container = document.createElement("div");

  var zoomInDiv = document.createElement("div");
  this.setButtonStyle_(zoomInDiv);
  container.appendChild(zoomInDiv);
  zoomInDiv.appendChild(document.createTextNode("放大"));
  GEvent.addDomListener(zoomInDiv, "click", function() {
    map.zoomIn();
  });

  var zoomOutDiv = document.createElement("div");
  this.setButtonStyle_(zoomOutDiv);
  container.appendChild(zoomOutDiv);
  zoomOutDiv.appendChild(document.createTextNode("缩小"));
  GEvent.addDomListener(zoomOutDiv, "click", function() {
    map.zoomOut();
  });

  map.getContainer().appendChild(container);
  return container;
}

// By default, the control will appear in the top left corner of the
// map with 7 pixels of padding.
TextualZoomControl.prototype.getDefaultPosition = function() {
  return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(7, 7));
}

// Sets the proper CSS for the given button element.
TextualZoomControl.prototype.setButtonStyle_ = function(button) {
  button.style.textDecoration = "underline";
  button.style.color = "#0000cc";
  button.style.backgroundColor = "white";
  button.style.font = "small Arial";
  button.style.border = "1px solid black";
  button.style.padding = "2px";
  button.style.marginBottom = "3px";
  button.style.textAlign = "center";
  button.style.width = "6em";
  button.style.cursor = "pointer";
}

var map = new GMap2(document.getElementById("map"));
map.addControl(new TextualZoomControl());
map.setCenter(new GLatLng(36.94,106.08),4);

查看范例(13.customcontrol.html)

自定义标注

API第2版提供了创建自定义地图标注的功能,类似于GMarkerGPolyline标注,方法是实现集成的GOverlay接口.在这个范例之中,我们创建了一个Rectangle标注用来向地图上显示一个矩形框.

Rectangle类定义了4个实现GOverlay接口必需的方法: initialize()用来创建显示标注必需的DOM标签; remove()用来从地图上删除标注所创建的标签,; copy()用来生成一个当前标注的副本以在另一个地图实例之中使用;redraw()用来根据当前的地图坐标和缩放等级来定位和缩放标记.查看GOverlay类参考可以得到更多关于自定义标注时需要重写的方法的信息.

组成标注的每一个DOM标签都存在于map pane之中,并定义它显示的级别z-order. 例如,折线是平铺在地图之上的,因此,它显示在最下面G_MAP_MAP_PANE级别.标记将它们的阴影放在G_MAP_MARKER_SHADOW_PANE级别,他们的前景图片在G_MAP_MARKER_PANE级别.将您的自定义标注控件放在合适的级别以保证折线显示在标记阴影的下方,而信息窗口显示在所有标记的最上方. 在这个范例之中,我们的标记是平铺在地图之上的,因此,我们将它添加到最低的显示级别G_MAP_MAP_PANE,就和折线一样,查看类参考可以得到地图显示级别的完整列表.

// A Rectangle is a simple overlay that outlines a lat/lng bounds on the
// map. It has a border of the given weight and color and can optionally
// have a semi-transparent background color.
function Rectangle(bounds, opt_weight, opt_color) {
  this.bounds_ = bounds;
  this.weight_ = opt_weight || 2;
  this.color_ = opt_color || "#888888";
}
Rectangle.prototype = new GOverlay();

// Creates the DIV representing this rectangle.
Rectangle.prototype.initialize = function(map) {
  // Create the DIV representing our rectangle
  var div = document.createElement("div");
  div.style.border = this.weight_ + "px solid " + this.color_;
  div.style.position = "absolute";

  // Our rectangle is flat against the map, so we add our selves to the
  // MAP_PANE pane, which is at the same z-index as the map itself (i.e.,
  // below the marker shadows)
  map.getPane(G_MAP_MAP_PANE).appendChild(div);

  this.map_ = map;
  this.div_ = div;
}

// Remove the main DIV from the map pane
Rectangle.prototype.remove = function() {
  this.div_.parentNode.removeChild(this.div_);
}

// Copy our data to a new Rectangle
Rectangle.prototype.copy = function() {
  return new Rectangle(this.bounds_, this.weight_, this.color_,
                       this.backgroundColor_, this.opacity_);
}

// Redraw the rectangle based on the current projection and zoom level
Rectangle.prototype.redraw = function(force) {
  // We only need to redraw if the coordinate system has changed
  if (!force) return;

  // Calculate the DIV coordinates of two opposite corners of our bounds to
  // get the size and position of our rectangle
  var c1 = this.map_.fromLatLngToDivPixel(this.bounds_.getSouthWest());
  var c2 = this.map_.fromLatLngToDivPixel(this.bounds_.getNorthEast());

  // Now position our DIV based on the DIV coordinates of our bounds
  this.div_.style.width = Math.abs(c2.x - c1.x) + "px";
  this.div_.style.height = Math.abs(c2.y - c1.y) + "px";
  this.div_.style.left = (Math.min(c2.x, c1.x) - this.weight_) + "px";
  this.div_.style.top = (Math.min(c2.y, c1.y) - this.weight_) + "px";
}

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(36.94,106.08),4);

// Display a rectangle in the center of the map at about a quarter of
// the size of the main map
var bounds = map.getBounds();
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngDelta = (northEast.lng() - southWest.lng()) / 4;
var latDelta = (northEast.lat() - southWest.lat()) / 4;
var rectBounds = new GLatLngBounds(
    new GLatLng(southWest.lat() + latDelta, southWest.lng() + lngDelta),
    new GLatLng(northEast.lat() - latDelta, northEast.lng() - lngDelta));
map.addOverlay(new Rectangle(rectBounds));

查看范例(14.customoverlay.html)

疑难解答

如果您的代码不能正常运行,下面是一些可能有用的建议:

其他资源

下面是一些附加的资源.注意这些网站并不是Google的官方站点.

  • Mapki是一个流行的关于Maps API信息的wiki网站, 包含一个FAQ页面.
  • Step1.cn是本文的中文翻译发布网站,上面还会有很多关于Google Maps API的范例程序和公开的代码.

API概述

API概述简单的介绍了Maps API的一些要点,如果要完整的API类和方法的参考,请查看Maps API类参考.

GMap2

GMap2的每一个实例代表页面上的一个地图.您可以在页面上创建多个地图(为每一个地图使用一个实例).在您创建一个地图实例的时候,需要指定一个页面上的命名元素作为参数(通常是一个div元素)用来包含地图.如果您没有明确的指定地图的大小,地图将使用您指定的包容器的大小作为它自己的大小.

GMap2类有一些方法用来操作地图的中心和缩放等级,或者添加或删除标注(例如GMarkerGPolyline的实例).它还有一个方法用来打开一个"信息浮窗",就是您能够在Google Maps网站看到的弹出的小窗口.查看信息浮窗获取更多信息.

如果要了解关于GMap2的更多信息,可以查看GMap2类参考.

事件

您能够通过使用事件监视器来为您的程序添加动态的元素.一个对象可能提供了一些指定的事件,您的程序能够使用静态方法GEvent.addListenerGEvent.bind来"监视"这些事件.例如,下面的代码在用户每次点击地图的时候弹出一个提示框:

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
GEvent.addListener(map, "click", function() {
  alert("You clicked the map.");
});

GEvent.addListener使用了一个函数作为它的第三个参数,这个函数是事件处理句柄的函数引用.如果您想绑定到一个类实例的某一个方法,您可以使用GEvent.bind.在下面的范例之中,一个程序类的实例将自己的方法绑定到地图的事件,在事件被触发时修改类的状态:

function MyApplication() {
  this.counter = 0;
  this.map = new GMap2(document.getElementById("map"));
  this.map.setCenter(new GLatLng(36.94,106.08),4);
  GEvent.bind(this.map, "click", this, this.onMapClick);
}

MyApplication.prototype.onMapClick = function() {
  this.counter++;
  alert("You have clicked the map " + this.counter + " " +
        (this.counter == 1 ?"time" : "times"));
}

var application = new MyApplication();

查看范例(15.bind.html)

信息浮窗

每一个地图只有一个"信息浮窗",用来在地图上使用浮动窗口的形式显示HTML内容.信息浮窗看起来有一点像一个文字气球;它有一个内容区域和一个箭头,指向地图上的指定点.您可以在Google地图上通过点击一个标注看到信息浮窗.

您不能够同时在地图上显示多个信息浮窗,但是您可以在需要的时候移动并改变信息浮窗的内容.

最简单的信息浮窗使用方法是openInfoWindow,它使用一个地理点和一个HTML DOM元素作为参数.HTML DOM元素将被添加到信息浮窗容器之中,信息浮窗的箭头指向给定地理点.

The openInfoWindowHtml方法是类似的,但是它使用HTML字符串作为第二个参数而不是一DOM元素.

要在一个标注(如标记marker)上显示一个信息浮窗,您需要传递第三个可选的参数来指定指定点和信息浮窗箭头所指点的像素距离.因此, 如果您的标记高度是10像素,您可以传递一个GSize(0, -10).

GMarker类已经提供了openInfoWindow方法考虑到了像素距离的值,因此通常您不需要在使用之中亲自计算图标的大小.

查看GMap2GMarker类参考可以获取更多信息.

标注

标注是地图上固定在经纬度坐标上的对象,因此在您移动地图或者更改地图大小或者切换地图坐标系统(例如从地图模式变为卫星图模式)的时候它们也跟随移动.

Maps API提供了2种标注:标记,地图上的图标,和折线,由许多点连成的折线

标记和图标

The GMarker构造函数使用一个图标和一个点作为参数,并提供一系列事件例如"click".查看6.overlay.html范例可以看到如何创建标记.

创建一个标记最困难的地方是是指定图标,它复杂在创建一个简单的Maps API图标需要多个不同的图片.

每一个图标都有一个前景图和一个阴影图.阴影图应该是前景图向右上45度角倾斜得到的,阴影图片的左下角必须和前景图片的左下角重合. 阴影图片应该是一个24位背景透明的PNG图片.

GIcon类需要您在初始化图标的时候指定那些图片的大小以便Maps PAI能够以合适的大小创建图片元素.下面是指定一个图标需要的最少的代码(这个范例之中的图标在Google Maps之中有使用):

var icon = new GIcon();
icon.image = "http://www.google.com/mapfiles/marker.png";
icon.shadow = "http://www.google.com/mapfiles/shadow50.png";
icon.iconSize = new GSize(20, 34);
icon.shadowSize = new GSize(37, 34);

GIcon类还有一些其他的属性,您最好设置这些属性值以让您的图标拥有更多的功能和更好的浏览器兼容性.例如, the imageMap属性指定了图标前景图的不透明部分,如果您不指定这个属性,整个图标图片(包括透明的部分)也将在Firefox/Mozilla浏览器之中能够被点击.查看GIcon类参考获得更多信息.

折线

GPolyline类的构造函数使用一个地理点数组作为参数,并按照给定的顺序将这些点连接成为折线,你还可以指定折线的颜色、线宽和透明度,颜色必须是16位的HTML颜色值,例如使用#ff0000而不是red. GPolyline不支持根据颜色的名称来指定颜色.

下面的代码在两个点之间划了一条10像素宽的红色线条:

var polyline = new GPolyline([
  new GLatLng(37.4419, -122.1419),
  new GLatLng(37.4519, -122.1519)
], "#ff0000", 10);
map.addOverlay(polyline);

在IE浏览器之中,Google Maps使用VML来绘制折线(清参看XHTML和VML了解更多).在其他的浏览器之中,我们通过访问服务端的图片来实现显示折线,并在地图移动或缩放的时候刷新图片.

控件

要添加控件(例如缩放条)到地图,您可能需要用到addControl方法.Maps API已经在其中集成了一些常用的控件:

  • GLargeMapControl -一个在Google Local之中使用的大的移动缩放控件,显示在地图的左上角.
  • GSmallMapControl -一个在Google Local之中使用的小一点的移动缩放控件,显示在地图的左上角.
  • GSmallZoomControl -一个小的缩放控件,用在Google Local之中用来显示驾驶导航的小弹出地图上.
  • GScaleControl - 地图比例尺控件
  • GMapTypeControl - 让用户切换地图类型的按钮控件(例如地图模式和卫星图模式)
  • GOverviewMapControl New! - 一个可折叠的鹰眼地图,在地图的角落

例如,假如您要想地图上添加一个您在Google Maps上面见到的移动缩放控件,您可以将下面的代码写在地图初始化之后:

map.addControl(new GLargeMapControl());

addControl的第二个参数GControlPosition是一个可选的参数,用来指定控件在地图之中的显示位置,如果没有指定,则地图使用该控件自身默认的位置.下面的范例将地图类型控件添加到离地图的右下角10个像素的位置:

map.addControl(new GMapTypeControl(),
               new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(10, 10)));

查看GControlPosition类参考了解更多.

XML和异步请求

Google Maps API提供了一个方法用来创建XmlHttpRequest对象,能在目前流行的IE, Firefox和Safari之中运行.下面的范例演示如何下载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同时也提供了一个方法GDownloadUrl用来做简单的HTTP GET请求,使用这个方法不需要做XmlHttpRequest readyState检查.上面的例子也可以使用GDownloadUrl写成:

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

您能供使用静态方法GXml.parse来解析一个XML文档,该方法使用XML字符串作为参数.兼容大多数流行的浏览器,如果碰巧浏览器不能兼容,则它将抛出一个异常.

查看GXmlHttp and GXml类参考了解更多.

避免内存溢出

Google Maps API 大量的使用了函数引用function closures,而且API事件处理系统GEvent使用的将事件注册到DOM节点的方法基本上必然会在一些浏览器上造成内存溢出, 尤其是Internet ExplorerMaps API第二版使用了一个新的方法GUnload()用来删除几乎所有的造成内存溢出的循环引用.您应该在您的页面的unload事件发生时执行GUnload()方法来减少内存溢出对您的程序的影响:

<body onunload="GUnload()">

使用这个函数能够解决Google Maps在IE之中的内存溢出问题,但是您最好在您遇到内存消耗过多的问题时在您的网站上使用类似Drip的工具来做内存溢出的检查.

posted @ 2011-01-19 13:00  awp110  阅读(313)  评论(0编辑  收藏  举报