锁定老帖子 主题:Maps API中文同步文档
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-01-24
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&v=2&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 Code和Maps 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); 地图移动和动画下面的例子显示一个地图,然后等待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); 在地图上添加控件您可以用addControl方法在地图上添加控件。在这个例子里,我们加入GSmallMapControl和GMapTypeControl控件,这样我们分别可以移动/缩放地图以及在地图和卫星模式之间切换。 var map = new GMap2(document.getElementById("map")); map.addControl(new GSmallMapControl()); map.addControl(new GMapTypeControl()); map.setCenter(new GLatLng(37.4419, -122.1419), 13); 控件初始化大多数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); 想得到更多事件的信息,参看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")); 地图覆盖物这个例子在地图上显示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)); 点击事件处理要在用户点击地图的时候触发一个动作,就需要在您的GMap2实例上注册一个"click"事件的监听器。当事件被触发的时候,事件处理句柄将收到两个参数:被点击的标记(如果有),被点击点的GLatLng(经纬度)。如果没有标记被点击,那么第一个参数为null。 注意:标记是唯一支持"click"事件的内建覆盖对象。其他类型的覆盖对象,如GPolyline是不能被点击的。 在下面的例子里,当访客点击在地图上一个没有标记的点上时,我们在这个点上创建一个标记。当访客点击在一个标记上的时候,我们把它删除。 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)); } }); 想得到更多事件的信息,参看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)); } 想得到更多事件的信息,参看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); 创建图标这个例子创建一个新类型图标,采用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类在很多情况下,您的图标有很多不同的前景,但是有相同的形状和背景。实现这类行为的最简单的方式就是利用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)); } 可拖动的标记标记是可以点击和拖动到一个新位置的交互对象。在这个例子里,我们把一个可以拖动的标记放置在地图上,并监听它的几种简单事件。可拖动的标记支持四种事件click,dragstart, drag和dragend。缺省情况下,标记是可以点击的,但不能被拖动,所以他们需要用设置附加标记选项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); 编码折线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); 需要注意的两点是:
在地图上使用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); 定制地图覆盖物Maps API版本2引入了创建自定义的地图覆盖对象的能力,就像内建的GMarker和GPolyline对象,继承内建的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)); 地理译码示例您可以直接发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); } } ); } 展开结构化地址信息如果您想访问地址的结构化信息,GClientGeocoder提供getLocations方法返回一个JSON对象包含下列的信息。译注:JSON(JavaScript Object Notation),是一种轻量级的数据交换格式,详情请见http://json.org/
这是用地理译码器查询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); } } 缓存地理译码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()); HTTP请求方式想直接让服务器端脚本访问地理译码器,可以发请求到http://maps.google.com/maps/geo?,把如下参数加在地址里面:
在这个例子里,我们请求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格式的回 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
浏览 13830 次