`

Maps API中文同步文档

阅读更多

Google Maps API 2 文档

Google文档目录

Google Maps JavaScript API允许您把Google地图嵌入到您自己的网页内。要使用这个API,首先您需要申请一个API key,然后按照下面的指南操作。

这个API比较新,所以可能有一些Bug,文档也不够完美。请暂时忍受并等待我们的改进,请您加入Maps API讨论组给我们反馈,讨论关于API的问题。

本文档是Maps API 2的说明,Maps API 2启动于2006年4月3日。如果您还在使用Maps API 1,您应该升级您的网站,参考:

目录

读者

本文档适用于熟悉JavaScript和面向对象编程概念的人。另外您也应该很熟悉Google地图这个产品。网上有很多JavaScript指南可供参考。

简介

Google Maps上的Hello World

学习这个API最简单的方法就是看一个简单的例子。下面的网页显示一个500x300的地图,中心位于California,Palo Alto:

<!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=utf-8"/>
    <title>Google Maps JavaScript API Example</title>
    <script 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(37.4419, -122.1419), 13);
      }
    }

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

您可以下载这个例子修改并测试,但是您必须用您自己的API key代替文件中Key。(如果您注册了某个目录的API Key,那么您可以直接在这个目录的任何子目录下使用。

下面例子里面的地址(http://maps.google.com/maps?file=api&v=2)是在您的页面放置Google地图需要的所有的代码的JavaScript文件。您的页面必须包含指向这个地址的script标记,并加上您的API Key。如果您的API Key是"abcdefg",那么您的script标记看起来应该是这样的:

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

描绘地图的类是GMap2。这个类在页面上显示一个地图。您可以创建任意多个该类的实例(一个实例就是页面上的一个地图)。创建了地图实例之后,就可以指定一个页面元素(通常是div元素)来包含它。除非您明确的指定地图的尺寸,否则地图大小会取决于容器的尺寸。

浏览器兼容性

Google Maps API支持的浏览器种类与Google地图网站相同。因为不同的应用程序在遇到不兼容的浏览器的时候需要表现不同的行为,所以Maps API提供了一个全局方法(GBrowserIsCompatible())来检查兼容性,但是,发现一个不兼容的浏览器时,它不会自动采取任何措施。 http://maps.google.com/maps?file=api&v=2里面的脚本几乎可以在任何浏览器里面解析而不产生错误,所以您可以在检查浏览器兼容性之前就包含脚本文件。

文档中的例子都不会检查浏览器兼容性(除了上面的那第一个例子),他们在老的浏览器上面也不会显示错误信息。很明显真实的应用程序应该在遇到不兼容浏览器的时候最好做点什么以表现得更加友好,而为了让范例代码更好看(易懂),我们省略了这种检查。

非凡的应用总是会遇到浏览器和平台兼容性的问题。这种问题没有任何简单的解决方案,但是Google Maps API讨论组quirksmode.org应该可以找到些好的信息。

XHTML和VML

我们推荐您使用标准兼容的XHTML页面包含地图。当浏览器看到页面顶端的DOCTYPE,他们会用"标准兼容模式"来渲染页面,这样页面布局和行为在浏览器里的效果更有预见性。

如果您想在地图里面显示折线,您需要在您的XHTML文档里面包含VML命名空间和一些CSS代码,这样可以令它们在IE下面可以正常工作。XHTM文档的开头看起来就像这样:

<!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=UTF-8"/>
    <title>My Google Maps Hack</title>
    <style type="text/css">
    v\:* {
      behavior:url(#default#VML);
    }
    </style>
    <script src="http://maps.google.com/maps?file=api&v=2&key=abcdefg"
             type="text/javascript"></script>
  </head>

API升级

地址http://maps.google.com/maps?file=api&v=2中的v=2部分表明API的版本是2。当我们对API进行重大升级的时候,我们会改变版本号并在Google CodeMaps API讨论组发布相关信息。

一个新版本正式发布以后,我们会让新旧版本并行运行一个月。一个月以后,老版本会被关闭,而使用旧版本的代码将不能继续工作。

Maps API开发团队透明的升级API进行的Bug修正和性能改进。 这些Bug修正应该仅仅提高性能和修正Bug,但是我们可能会不经意的影响一些API用户的使用。请利用Maps API讨论组来报告这些问题。

地理译码/Geocoding

地理译码是把地址(如"1600 Amphitheatre Parkway, Mountain View, CA")转换为地理坐标(如经度-122.083739,纬度37.423021)的流程,您可以用它把数据库里面的街道地址或用户提供的地址信息标记在地图上。Google Maps API包含了可以通过HTTP请求和JavaScript来访问的地理译码器译注:到目前为止,这个地理译码器还没有足够的中国的本地化信息可以使用。

行程规划和本地搜索

现在Google Maps API不包含任何行程规划服务.然而现在Web上有很多免费的行程规划API。如果您希望为您的网站增加本地搜索能力,您可以使用Google AJAX搜索API来在您的网站上嵌入一个本地搜索模块

地图范例

下面的例子仅会显示主体相关的JavaScript代码,而不是完整的HTML文件。您可以把JavaScript代码嵌入到前面的骨架HTML文件,或者您可以直接下载每个例子下面的链接所引用的HTML文件。

基础

下面的例子创建一个地图并定位到Palo Alto, California。

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

显示范例 (simple.html)

地图移动和动画

下面的例子显示一个地图,然后等待2秒,然后平移到一个新的中心点.

panTo方法把地图的中心移动到一个指定点。如果指定点在地图的可见区域内,地图中心会平滑地平移到指定点,否则地图中心会直接跳到那个点。

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
window.setTimeout(function() {
  map.panTo(new GLatLng(37.4569, -122.1569));
}, 1000);

显示范例 (animate.html)

在地图上添加控件

您可以用addControl方法在地图上添加控件。在这个例子里,我们加入GSmallMapControlGMapTypeControl控件,这样我们分别可以移动/缩放地图以及在地图和卫星模式之间切换。

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

显示范例 (controls.html)

控件初始化

大多数Google Maps API的控件提供带有标准行为的简单控件。然而,有些控件需要特殊的初始化。例如,GHierarchicalMapTypeControl需要额外的初始化来保证菜单中的地图类型顺序正确。

例子中加入了地图类型G_PHYSICAL_MAP,一个交叉线的图层,然后创建了一个GHierarchicalMapTypeControl把这个图层和这个地图类型联系在一起。

// define the crosshair tile layer and its required functions
var crossLayer = new GTileLayer(new GCopyrightCollection(""), 0, 15);

crossLayer.getTileUrl =  function(tile, zoom) {
  return "./include/tile_crosshairs.png";
}
crossLayer.isPng = function() {return true;}

// Create a new map type incorporating the tile layer
var layerTerCross = [ G_PHYSICAL_MAP.getTileLayers()[0], crossLayer ];
var mtTerCross = new GMapType(layerTerCross,
  G_PHYSICAL_MAP.getProjection(), "Ter+");

var map = new GMap2(document.getElementById("map_canvas"), 
  { size: new GSize(640,320) } );
map.addMapType(G_PHYSICAL_MAP);
map.addMapType(mtTerCross);
map.setCenter(new GLatLng(37.4419, -122.1419), 4);
var mapControl = new GHierarchicalMapTypeControl();

// Set up map type menu relationships
mapControl.clearRelationships();
mapControl.addRelationship(G_SATELLITE_MAP, G_HYBRID_MAP, "Labels", false);
mapControl.addRelationship(G_PHYSICAL_MAP, mtTerCross, "Crosshairs");

// Add control after you've specified the relationships
map.addControl(mapControl);

map.addControl(new GLargeMapControl());

View example (control-initialization.html)

事件监听器

要注册一个事件监听器需要调用GEvent.addListener方法。把一个地图,一个需要监听的事件,一个事件发生时需要调用的函数传给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(37.4419, -122.1419), 13);

显示范例 (event.html)

想得到更多事件的信息,参看Events纵览。想得到GMap2对象的完整事件列表,参看GMap2.Events.

打开信息窗口

要创建一个信息窗口,调用openInfoWindow方法,传递给它一个位置和一个用来显示的DOM元素。下面的例子在地图中心显示一个包含"Hello, world"信息的窗口。

var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
map.openInfoWindow(map.getCenter(),
                   document.createTextNode("Hello, world"));

显示范例 (infowindow.html)

地图覆盖物

这个例子在地图上显示10个位置随机的标记和一个5个点连成的折线。如果不指定其他的图标,GMarker类会使用缺省的Google地图图标。自定义图标的例子请参看创建图标

记得您必须在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(37.4419, -122.1419), 13); 

// Add 10 markers in random locations on the map
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));
}

// Add a polyline with five random points. Sort the points by
// longitude so that the line does not intersect itself.
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));

显示范例 (overlay.html)

点击事件处理

要在用户点击地图的时候触发一个动作,就需要在您的GMap2实例上注册一个"click"事件的监听器。当事件被触发的时候,事件处理句柄将收到两个参数:被点击的标记(如果有),被点击点的GLatLng(经纬度)。如果没有标记被点击,那么第一个参数为null

在下面的例子里,当访客点击在地图上一个没有标记的点上时,我们在这个点上创建一个标记。当访客点击在一个标记上的时候,我们把它删除。

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

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

显示范例 (click.html)

想得到更多事件的信息,参看Events纵览。想得到GMap2对象的完整事件列表,参看GMap2.Events.

在标记上显示信息窗口

在这个例子里,我们通过监听每一个标记来在他们上面显示定制的信息窗口。借助Javascript函数闭包(closure)技术,我们可以定制每个标记的信息窗口的内容。

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

// Creates a marker at the given point with the given number label
function createMarker(point, number) {
  var marker = new GMarker(point);
  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml("Marker #<b>" + number + "</b>");
  });
  return marker;
}

// Add 10 markers to the map at random locations
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));
}

显示范例 (markerinfowindow.html)

想得到更多事件的信息,参看Events纵览。想得到GMap2对象的完整事件列表,参看GMap2.Events.

分页信息窗口

API版本2引入了openInfoWindowTabs()方法和GInfoWindowTab类用来支持信息窗口拥有多个命名的分页。下面的例子在一个标记上显示了一个简单的分页信息窗口。

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

// Our info window content
var infoTabs = [
  new GInfoWindowTab("Tab #1", "This is tab #1 content"),
  new GInfoWindowTab("Tab #2", "This is tab #2 content")
];

// Place a marker in the center of the map and open the info window
// automatically
var marker = new GMarker(map.getCenter());
GEvent.addListener(marker, "click", function() {
  marker.openInfoWindowTabsHtml(infoTabs);
});
map.addOverlay(marker);
marker.openInfoWindowTabsHtml(infoTabs);

显示范例 (tabbedinfowindow.html)

创建图标

这个例子创建一个新类型图标,采用Google Ride Finder里面的小标记图标做为例子。我们需要指定背景图片,影子图片和点本身的图片。

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

// Create our "tiny" marker icon
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);

// Add 10 markers to the map at random locations
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));
}

显示范例 (icon.html)

使用Icon类

在很多情况下,您的图标有很多不同的前景,但是有相同的形状和背景。实现这类行为的最简单的方式就是利用GIcon类的复制构造函数,它会把所有的属性复制给您想定制的新图标。

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

// Create a base icon for all of our markers that specifies the
// shadow, icon dimensions, etc.
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);

// Creates a marker whose info window displays the letter corresponding
// to the given index.
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;
}

// Add 10 markers to the map at random locations
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));
}

显示范例 (iconclass.html)

可拖动的标记

标记是可以点击和拖动到一个新位置的交互对象。在这个例子里,我们把一个可以拖动的标记放置在地图上,并监听它的几种简单事件。可拖动的标记支持四种事件clickdragstartdragdragend。缺省情况下,标记是可以点击的,但不能被拖动,所以他们需要用设置附加标记选项draggable为真的方式来初始化。可拖动的标记缺省情况下,会在放下的时候跳动。如果您不喜欢这个行为,把bouncy选项设置为假,他们就会在放下的时候老实些。

var map = new GMap2(document.getElementById("map"));
var center = new GLatLng(37.4419, -122.1419);
map.setCenter(center, 13);

var marker = new GMarker(center, {draggable: true});

GEvent.addListener(marker, "dragstart", function() {
  map.closeInfoWindow();
  });

GEvent.addListener(marker, "dragend", function() {
  marker.openInfoWindowHtml("Just bouncing along...");
  });

map.addOverlay(marker);

显示范例 (dragmarker.html)

编码折线

Google地图中的GPolyline对象表示的是一系列的点,简单易用但不够简洁。表示长且复杂的折线需要大量的内存,而且在描绘的时候会花费大量的时间。而且未经编码的折线会在Google地图的每个缩放级别中可见。

Google Maps API也允许你用编码折线来表现路径。编码折线用一个压缩格式的ASCII字符串来表现一系列的点。编码折线还允许你指定线段的可见缩放级别;这样你就可以指定折线在当前的缩放级别下细节如何表现。虽然用起来更加复杂,但是编码折线可以让你的地图描绘效率更高。

例如,有三个点的GPolyline对象通常表现为:

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

而具有相同点的编码GPolyline对象如下(请先不要去关心编码算法的细节)。

var encodedPolyline = new GPolyline.fromEncoded([
    color: "#FF0000",
    weight: 10,
    points: "yzocFzynhVq}@n}@o}@nzD",
    levels: "BBB",
    zoomLevel: 32,
    numLevels: 4
]);
map.addOverlay(encodedPolyline);

需要注意的两点是:

  1. 首先,编码折线用一系列ASCII字符来表现一系列点,就像基本GPolyline对象用一系列经纬度那样。创建这些点序列的编码ASCII值的算法文档在此。如果你需要在运行期间在服务器上面计算这些编码的话,那么你需要了解这个算法。然而,如果你仅仅需要把现有点的经纬度转换成编码,那么你可以使用我们的交互工具
  2. 其次,编码折线允许你指定每个线段的最高可见缩放级别。如果一个点在更高的缩放级别中不可见,那么折线会自动地连接上一个可见点和下一个可见点。注意,这个特性非编码折线并不支持,这一特性非常有利于加快在高缩放级别的折线绘制速度,因为折线的一些细节无需表现出来。例如,当地图放大到州级的时候,一条用于表现从纽约市到芝加哥驱车路线的编码折线,就不需要表现出麦哈顿的具体街道了。

显示范例(polylineencoding.html)

在地图上使用XML和异步远程调用(AJAX)

在这里例子里,我们下载一个静态文件("data.xml"),我们用GDownloadUrl方法下载这个包含一个经纬度列表的XML文件。当下载完成,我们用GXml类来解析,并为XML文档中的每一个点建立一个标记。

var map = new GMap2(document.getElementById("map"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4419, -122.1419), 13);

// Download the data in data.xml and load it on the map. The format we
// expect is:
// <markers>
//   <marker lat="37.441" lng="-122.141"/>
//   <marker lat="37.322" lng="-121.213"/>
// </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));
  }
});

显示范例 (async.html)。这个例子使用了一个外部的XML数据文件data.xml

定制地图控件

Maps API的版本2引入了创建定制地图空间的能力,就像内建的平移和缩放控件,继承内建类GControl即可。在这个例子里,我们创建了一个简单的缩放控件,基于文字链接而不是像标准的Google地图缩放控件那样基于图片。

GTextualZoomControl类定义了GControl接口中两个必须的方法:initialize(),用来创建我们用来表现我们的控件的DOM元素;getDefaultPosition(),用来返回一个GControlPosition用于设定在没有指定控件位置的情况下控件的放置位置。想得到关于创建您的自定义控件可以重载函数的更多信息请参看GControl类参考

所有的地图控件应该加入在地图的容器内,这个容器可以用GMap2类的getContainer()方法。

// 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("Zoom In"));
  GEvent.addDomListener(zoomInDiv, "click", function() {
    map.zoomIn();
  });

  var zoomOutDiv = document.createElement("div");
  this.setButtonStyle_(zoomOutDiv);
  container.appendChild(zoomOutDiv);
  zoomOutDiv.appendChild(document.createTextNode("Zoom Out"));
  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(37.441944, -122.141944), 13);

显示范例 (customcontrol.html)

定制地图覆盖物

Maps API版本2引入了创建自定义的地图覆盖对象的能力,就像内建的GMarkerGPolyline对象,继承内建的GOverlay类即可。在这个例子里,我们创建一个矩形对象用来在地图上面标记一个矩形区域。

Rectangle类定义了GOverlay接口中四个必须的方法:initialize(),用来创建我们用来表现覆盖对象的DOM元素;remove(),用于移除覆盖对象;copy(),用于复制覆盖对象;redraw(),用于在当前投影范围缩放级别下定位和调节覆盖对象的大小。想得到关于创建您的自定义覆盖对象可以重载函数的更多信息请参看GOverlay类参考

每个在地图上构成覆盖对象的DOM元素需要定义它绘制时的Z序。例如,折线浮在地图上,所以他们绘制在Z序最小的G_MAP_MAP_PANE层。标记的影子元素放置在G_MAP_MARKER_SHADOW_PANE层,他们的前景元素放置在G_MAP_MARKER_PANE层。放置您的覆盖元素在正确的层上,确保直线画在标记影子的下面,信息窗口在其他的覆盖对象之上。这个例子里,我们的覆盖对象负载地图上,所以,我们把它放置在Z序最小的G_MAP_MAP_PANE层,就像GPolyline。在类参考里面可以得到完整的地图层的列表。

// 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(37.4419, -122.1419), 13);

// 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));

显示范例 (customoverlay.html)

地理译码示例

您可以直接发HTTP请求的方式来访问Maps API的地理译码器,或者可以用GClientGeocoder对象在JavaScript下发送请求。这样您可以从您的服务器进行地理译码调用或者让用户的浏览器进行这个操作。如果您有一个相对稳定的地址数据库(待售房产的列表),我们建议您通过HTTP请求一次性获得地理译码信息,然后把这些地址缓存在您自己的数据库呢。这让对用户来说您的网站会更快,而且可以减少您对每日地理译码请求限额的消耗。如果您不能访问服务器段脚本,那么您可以用JavaScript来发送地理译码请求。

JavaScript下使用地理译码

在JavaScript下您可以用GClientGeocoder对象来访问地理译码器。getLatLng方法可以用来把地址转换为GLatLng(经纬度)。因为地理译码需要发送请求到Google的服务器,所以这可能会花点时间。为了避免您的脚本一直等待,您需要指定一个函数在回应后触发。在这个例子里,我们把一个地址地理译码,然后在这个点上加一个标记,然后打开一个信息窗口显示地址。

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

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

显示范例 (geocoder.html)

展开结构化地址信息

如果您想访问地址的结构化信息,GClientGeocoder提供getLocations方法返回一个JSON对象包含下列的信息。译注:JSON(JavaScript Object Notation),是一种轻量级的数据交换格式,详情请见http://json.org/

  • Status
    • request -- 请求类型,在这里永远是geocode
    • code -- 一个回应代码(近似于HTTP状态代码)指示地理译码是否成功。参看状态代码全列表
  • Placemark -- 如果地理译码器找到多个结果,那么会返回多个地点。
    • address -- 一个格式良好的地址。
    • AddressDetails -- 格式化为xAL(可扩充地址语言)格式的地址。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);
  }
}

显示范例 (geocoder2.html)

缓存地理译码

GClientGeocoder类默认情况下装备了一个客户端的缓存。这个缓存会保存地理译码回应,这样当相同的地址被查询的时候,回应会直接从客户端的缓存中返回而不用连接到Google的地理译码器。想关闭缓存机制,可以用参数null调用GClientGeocoder类的setCache方法。然而,我们推荐您保留缓存机制,因为这可以提高性能。要改变使用的缓存,可以用新缓存作为参数调用setCache方法。要清空当前的缓存,可以调用reset方法。

我们鼓励开发者创建它们自己的客户端缓存。在这个例子里,我们用计算好的六个国家的首都的信息构建了一个缓存。首先,我们创建地理译码回应的数组。然后我们创建一个定制的缓存。缓存定义好后,我们用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"));
  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());

显示范例 (geocodercache.html)

HTTP请求方式

想直接让服务器端脚本访问地理译码器,可以发请求到http://maps.google.com/maps/geo?,把如下参数加在地址里面:

  • q -- 你想地理译码的地址。
  • key -- 你的API key。
  • output -- 输出格式。选项是xmlkmlcsv或者json

在这个例子里,我们请求google总部的地理坐标。

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

如果你指定输出格式为json,那么回应就是格式化好的JSON对象,如上面的例子所示。如果你指定输出格式为xml或者kml,回应返回格式为XML或者VML。XML和VML这两种输出格式内容完全一致,唯一的不同只是MIME类型。

例如,这是地理译码器对"1600 amphitheatre mtn view ca"的回应。

<kml>
  <Response>
    <name>1600 amphitheatre mtn 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格式的回

分享到:
评论

相关推荐

    google-maps-documentation:同步化google.maps API v3文档的版本副本

    Google Maps Api v3文档同步发布版本副本这是什么? 此仓库反映了每次出现版本变更或文档“最新更新”日期与用户上次访问页面的时间不同时,都没有简便的方法来检查与先前版本的不同之处。 该项目会定期爬网文档页面...

    Spring中文帮助文档

    9.4. 使用资源同步的事务 9.4.1. 高层次方案 9.4.2. 低层次方案 9.4.3. TransactionAwareDataSourceProxy 9.5. 声明式事务管理 9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4...

    static-map:基于 Google.Maps 静态 API 的地图图像生成器

    提供Google 静态地图 API 文档。 如果您不熟悉服务要求和差异,请先阅读。 Maven 中央存储库中提供的静态地图库。 您可以使用以下方法获取它: dependencies { compile ' com.github.d-max:static-map:0.1+@aar ' ...

    Spring API

    9.4. 使用资源同步的事务 9.4.1. 高层次方案 9.4.2. 低层次方案 9.4.3. TransactionAwareDataSourceProxy 9.5. 声明式事务管理 9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4...

    static-map-url-builder:基于Google.Maps静态API的地图图像生成器

    提供Google 静态地图 API 文档。 如果您不熟悉服务要求和差异,请先阅读它。 Maven 中央存储库中提供的静态地图库。 您可以使用以下方法获取它: dependencies { compile ' ...

    app-coffeesync:咖啡同步演示

    要在Android上使用Google Maps API,您必须生成一个API密钥并将其添加到您的Android项目中。 有关请参见Xamarin文档。 按照这些说明进行操作之后,将API密钥粘贴到Properties/AndroidManifest.xml文件中(查看源...

    spring chm文档

    9.4. 使用资源同步的事务 9.4.1. 高层次方案 9.4.2. 低层次方案 9.4.3. TransactionAwareDataSourceProxy 9.5. 声明式事务管理 9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4...

    Spring-Reference_zh_CN(Spring中文参考手册)

    9.4. 使用资源同步的事务 9.4.1. 高层次方案 9.4.2. 低层次方案 9.4.3. TransactionAwareDataSourceProxy 9.5. 声明式事务管理 9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为...

    java开源包1

    利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth ...

    java开源包11

    利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth ...

    java开源包2

    利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth ...

    java开源包3

    利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth ...

    java开源包6

    利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth ...

    java开源包5

    利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth ...

    java开源包10

    利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth ...

    java开源包4

    利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth ...

    java开源包8

    利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth ...

    java开源包7

    利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth ...

    java开源包9

    利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth ...

    java开源包101

    利用Google:maps JSP标签库就能够在你的Web站点上实现GoogleMaps的所有功能而且不需要javascript或AJAX编程。它还能够与JSTL相结合生成数据库驱动的动态Maps。 OAuth 实现框架 Agorava Agorava 是一个实现了 OAuth ...

Global site tag (gtag.js) - Google Analytics