Google Maps JavaScript API V3的使用(四)

Google Maps JavaScript API V3 叠加层

叠加层概述

叠加层是地图上与纬度/经度坐标绑定的对象,会随您拖动或缩放地图而移动。叠加层表示的是“添加”到地图中以标明点、线、区域或对象集合的对象。

Google Maps API 包含以下几种叠加层:

  • 地图上的单个位置显示为标记。标记有时可显示自定义的图标图片,此时标记通常被称为“图标”。标记和图标是 Marker 类型的对象。(有关详细信息,请参见下面的标记和图标。)
  • 地图上的线显示为折线(表示一系列按顺序排列的位置)。线是 Polyline 类型的对象。(有关详细信息,请参见折线。)
  • 地图上的不规则形状区域显示为 多边形,多边形类似于折线。与折线相同的是,多边形也是由一系列按顺序排列的位置构成的;不同的是,多边形定义的是封闭区域。(有关详细信息,请参见下面的多边形。)
  • 地图图层可显示为叠加层地图类型。您可以通过创建自定义地图类型以创建自己的图块集,该自定义地图类型可取代基本地图图块集,或作为叠加层显示在现有基本地图图块集之上。(有关详细信息,请参见自定义地图类型。)
  • 信息窗口也是特殊类型的叠加层,用于在指定地图位置的一个弹出式气泡框内显示内容(通常是文字或图片)。(有关详细信息,请参见信息窗口。)
  • 您还可以实现自己的自定义叠加层。这些自定义叠加层会实现 OverlayView 接口。(有关详细信息,请参见自定义叠加层。)

添加叠加层

叠加层通常在构造时添加到地图中。所有叠加层都会定义构造中所用的 Options 对象,以指定应显示叠加层的地图。您也可以使用叠加层的 setMap() 方法,将其传递给要添加叠加层的地图,从而直接在地图上添加叠加层。

  var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
  var myOptions = {
    zoom: 4,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
  }
 var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    
 var marker = new google.maps.Marker({
      position: myLatlng,
      title:"Hello World!"
  });
  
  // To add the marker to the map, call setMap();
  marker.setMap(map);  

删除叠加层

要从地图上删除叠加层,可调用叠加层的 setMap() 方法,传递 null。请注意,调用此方法不会删除叠加层,而只是从地图上删除叠加层。如果您要删除叠加层,则应当从地图上删除叠加层,然后将叠加层设置为 null

如果您要管理一组叠加层,则应当创建一个数组以存储这些叠加层。使用数组后,只要您需要删除叠加层,就可以对数组中的每个叠加层调用 setMap()。(请注意,与第 2 版不同,该版本中未提供 clearOverlays() 方法。对于跟踪叠加层并在不需要时将其从地图中删除的任务,您需要自己执行。)要删除叠加层,您可以从地图上删除叠加层并将数组的length 设置为 0,但此操作会删除对叠加层的所有引用。

下面示例的效果是点击地图时将标记放在地图上,然后将标记放入数组中。叠加层稍后可以删除、显示或删除:

var map;
var markersArray = [];

function initialize() {
  var haightAshbury = new google.maps.LatLng(37.7699298, -122.4469157);
  var mapOptions = {
    zoom: 12,
    center: haightAshbury,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };
  map =  new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

  google.maps.event.addListener(map, 'click', function(event) {
    addMarker(event.latLng);
  });
}
  
function addMarker(location) {
  marker = new google.maps.Marker({
    position: location,
    map: map
  });
  markersArray.push(marker);
}

// Removes the overlays from the map, but keeps them in the array
function clearOverlays() {
  if (markersArray) {
    for (i in markersArray) {
      markersArray[i].setMap(null);
    }
  }
}

// Shows any overlays currently in the array
function showOverlays() {
  if (markersArray) {
    for (i in markersArray) {
      markersArray[i].setMap(map);
    }
  }
}

// Deletes all markers in the array by removing references to them
function deleteOverlays() {
  if (markersArray) {
    for (i in markersArray) {
      markersArray[i].setMap(null);
    }
    markersArray.length = 0;
  }
}

查看示例 (overlay-remove.html)

标记

标记用于标识地图上的位置。默认情况下,标记使用的是标准图标,但您可以在标记的构造函数中设置一个自定义图标,或者通过对标记调用 setIcon() 设置一个自定义图标。google.maps.Marker 构造函数采用的是用于指定标记初始属性的一个 Marker options 对象常量。以下字段特别重要,通常是在您构建标记时进行设置的:

  • position(必需),用于指定标识标记初始位置的 LatLng
  • map(可选),用于指定要在其上设置标记的 Map 对象。

请注意,您应在 Marker 构造函数指定要为哪个地图添加标记。如果您不指定此参数,那么,您只能创建标记,而无法将其附加到地图上(或在地图上显示)。稍后,您可以通过调用标记的 setMap() 方法添加该标记。要删除标记,请调用将 null 作为参数传递的 setMap() 方法。

标记设计为可交互。例如,默认情况下它们接收 'click' 事件,常用于在事件侦听器中打开信息窗口。

以下示例介绍了如何将一个简单的标记添加到澳大利亚中心区域的乌鲁鲁的地图上:

  var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
  var myOptions = {
    zoom: 4,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    
  var marker = new google.maps.Marker({
      position: myLatlng, 
      map: map, 
      title:"Hello World!"
  });   

此 Marker 标题将会以提示的形式显示。

如果您不想在标记的构造函数中传递任何 Marker options,那么,请在构造函数的最后一个参数中传递一个空对象 {}

查看示例 (marker-simple.html)

动画

您也可以对标记添加动画效果,以便它们在各种不同的环境中展现动态活动。为标记添加动画的方式可以在标记的 animation 属性(属于 google.maps.Animation 类型)内指定。系统目前支持以下 Animation 值:

  • DROP 表明标记在首次放置于地图上时,应当从地图顶端落到目标位置。当标记停止时动画也会立即结束,且 animation 将会还原为 null。通常,此类动画会在创建 Marker的过程中指定。
  • BOUNCE 表明标记应在相应的位置上“弹跳”。在您将弹跳标记的 animation 属性设置为 null 之前,该标记会不断弹跳。

您可以在 Marker 对象上调用 setAnimation(),以对现有标记添加动画效果。

以下示例在瑞典斯德哥尔摩市创建了一个采用 DROP 动画的标记。点击该标记可使其在 BOUNCE 动画和无动画之间切换:

var stockholm = new google.maps.LatLng(59.32522, 18.07002);
var parliament = new google.maps.LatLng(59.327383, 18.06747);
var marker;
var map;

function initialize() {
  var mapOptions = {
    zoom: 13,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    center: stockholm
  };

  map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);

  marker = new google.maps.Marker({
    map:map,
    draggable:true,
    animation: google.maps.Animation.DROP,
    position: parliament
  });
  google.maps.event.addListener(marker, 'click', toggleBounce);
}

function toggleBounce() {

  if (marker.getAnimation() != null) {
    marker.setAnimation(null);
  } else {
    marker.setAnimation(google.maps.Animation.BOUNCE);
  }
}

查看示例 (marker-animations.html)

请注意:如果您有很多标记,则不应让所有标记同时掉落到地图上。您可以利用 setTimeout(),使用某种模式(类似于以下示例中所示)来间隔显示标记的动画效果:

function drop() {
  for (var i =0; i < markerArray.length; i++) {
    setTimeout(function() {
      addMarkerMethod();
    }, i * 200);
  }
}

查看示例 (marker-animations-iteration.html)

图标

标记可以定义要显示的图标,从而取代默认的图标。定义图标的过程中包含设置若干可定义标记视觉行为的属性。

简单图标

就最基本的情况而言,只需将标记的 icon 属性设置为某一图像的网址,图标便可指明要使用的图像(而非默认的 Google Maps 图钉图标)。在这种情况下,Google Maps API 将会自动调整图标的大小。

在以下示例中,我们会创建一个图标,用于标示澳大利亚悉尼的邦迪海滩的位置:

function initialize() {
  var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
  var myOptions = {
    zoom: 4,
    center: myLatlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

  var image = 'beachflag.png';
  var myLatLng = new google.maps.LatLng(-33.890542, 151.274856);
  var beachMarker = new google.maps.Marker({
      position: myLatLng,
      map: map,
      icon: image
  });
}

查看示例 (icon-simple.html)

复杂图标

较为复杂的图标可用于指定复杂的形状(表示用户可点击的区域)、添加阴影图像,以及指定这些形状与其他叠加层在显示时应采用的“堆叠顺序”。以这种方式指定的图标应当将自己的 icon 属性和 shadow 属性设置为 MarkerImage 类型的对象。

阴影图像通常应该和主图像成 45 度夹角(向右上方倾斜),并且阴影图像的左下角应与图标图像的左下角对齐。阴影图像应是半透明的 24 位 PNG 图像,这样图像边界便可以在地图上正确显示。

MarkerImage 对象不仅可以定义图像,还可定义图标的 size、图标的 origin(例如,在您所需的图像取自一张较大的拼合图像时)以及图标热点所应定位的 anchor(取决于原点)。

以下示例介绍了如何创建复杂的标记,以表示澳大利亚新南威尔士的悉尼附近的海滩。请注意,应当将 anchor 设置为 (0,32),从而与旗杆的基座相对应。

function initialize() {
  var myOptions = {
    zoom: 10,
    center: new google.maps.LatLng(-33.9, 151.2),
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var map = new google.maps.Map(document.getElementById("map_canvas"),
                                myOptions);

  setMarkers(map, beaches);
}

/**
 * Data for the markers consisting of a name, a LatLng and a zIndex for
 * the order in which these markers should display on top of each
 * other.
 */
var beaches = [
  ['Bondi Beach', -33.890542, 151.274856, 4],
  ['Coogee Beach', -33.923036, 151.259052, 5],
  ['Cronulla Beach', -34.028249, 151.157507, 3],
  ['Manly Beach', -33.80010128657071, 151.28747820854187, 2],
  ['Maroubra Beach', -33.950198, 151.259302, 1]
];

function setMarkers(map, locations) {
  // Add markers to the map

  // Marker sizes are expressed as a Size of X,Y
  // where the origin of the image (0,0) is located
  // in the top left of the image.

  // Origins, anchor positions and coordinates of the marker
  // increase in the X direction to the right and in
  // the Y direction down.
  var image = new google.maps.MarkerImage('images/beachflag.png',
      // This marker is 20 pixels wide by 32 pixels tall.
      new google.maps.Size(20, 32),
      // The origin for this image is 0,0.
      new google.maps.Point(0,0),
      // The anchor for this image is the base of the flagpole at 0,32.
      new google.maps.Point(0, 32));
  var shadow = new google.maps.MarkerImage('images/beachflag_shadow.png',
      // The shadow image is larger in the horizontal dimension
      // while the position and offset are the same as for the main image.
      new google.maps.Size(37, 32),
      new google.maps.Point(0,0),
      new google.maps.Point(0, 32));
      // Shapes define the clickable region of the icon.
      // The type defines an HTML <area> element 'poly' which
      // traces out a polygon as a series of X,Y points. The final
      // coordinate closes the poly by connecting to the first
      // coordinate.
  var shape = {
      coord: [1, 1, 1, 20, 18, 20, 18 , 1],
      type: 'poly'
  };
  for (var i = 0; i < locations.length; i++) {
    var beach = locations[i];
    var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
    var marker = new google.maps.Marker({
        position: myLatLng,
        map: map,
        shadow: shadow,
        icon: image,
        shape: shape,
        title: beach[0],
        zIndex: beach[3]
    });
  }
}

查看示例 (icon-complex.html)

折线

Polyline 类可定义地图上已连接线段的线叠加层。Polyline 对象包含一组 LatLng 位置,并绘制一系列线段,以便按顺序连接这些位置。

折线选项

Polyline 构造函数采用一组 Polyline options(用于指定线的 LatLng 坐标)和一组样式(用于调整折线的可视行为)。

Polyline 就是在地图上绘制的一系列直线段线。您可以在构造线时所用的 Polyline options 对象内指定线的笔触的自定义颜色、粗细和不透明度,或在构造之后更改这些属性。折线支持以下笔触样式:

  • strokeColor 指定 "#FFFFFF" 格式的十六进制 HTML 颜色。Polyline 类不支持颜色名称。
  • strokeOpacity 指定线的颜色不透明度,为 0.0 到 1.0(默认值)之间的小数值。
  • strokeWeight 指定线的笔触粗细(以像素为单位)。

以下代码段绘制一条粗细为 2 像素的红色折线,连接威廉·金斯福德·史密斯 (William Kingsford Smith) 从美国加利福尼亚州奥克兰到澳大利亚布里斯班的首次跨太平洋飞行路线。


function initialize() {
  var myLatLng = new google.maps.LatLng(0, -180);
  var myOptions = {
    zoom: 3,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      myOptions);
  var flightPlanCoordinates = [
    new google.maps.LatLng(37.772323, -122.214897),
    new google.maps.LatLng(21.291982, -157.821856),
    new google.maps.LatLng(-18.142599, 178.431),
    new google.maps.LatLng(-27.46758, 153.027892)
  ];
  var flightPath = new google.maps.Polyline({
    path: flightPlanCoordinates,
    strokeColor: "#FF0000",
    strokeOpacity: 1.0,
    strokeWeight: 2
  });

  flightPath.setMap(map);
}

查看示例 (polyline-simple.html)

折线数组

折线将一系列坐标指定为 LatLng 对象的数组。要检索这些坐标,可调用 Polyline 的 getPath(),它会传回 MVCArray 类型的数组。同样,您可以使用以下操作处理和检查数组:

  • getAt() 用于在指定的索引值(从零开始)处传回 LatLng
  • insertAt() 用于在指定索引值(从零开始)处插入所传递的 LatLng。注意,该索引值的所有现有坐标均向前移动。
  • removeAt() 用于在指定的索引值(从零开始)处删除 LatLng

注意:不能只是使用语法 mvcArray[i] 检索数组的第 i 个元素,而必须使用 mvcArray.getAt(i)

以下代码创建了一幅交互式地图,其中的折线是根据用户的点击构造的。请注意,只有当折线的 path 属性包含两个 LatLng 坐标时,折线才会显示。


var poly;
var map;

function initialize() {
  var chicago = new google.maps.LatLng(41.879535, -87.624333);
  var myOptions = {
    zoom: 7,
    center: chicago,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);

  var polyOptions = {
    strokeColor: '#000000',
    strokeOpacity: 1.0,
    strokeWeight: 3
  }
  poly = new google.maps.Polyline(polyOptions);
  poly.setMap(map);

  // Add a listener for the click event
  google.maps.event.addListener(map, 'click', addLatLng);
}

/**
 * Handles click events on a map, and adds a new point to the Polyline.
 * @param {MouseEvent} mouseEvent
 */
function addLatLng(event) {

  var path = poly.getPath();

  // Because path is an MVCArray, we can simply append a new coordinate
  // and it will automatically appear
  path.push(event.latLng);

  // Add a new marker at the new plotted point on the polyline.
  var marker = new google.maps.Marker({
    position: event.latLng,
    title: '#' + path.getLength(),
    map: map
  });
}

查看示例 (polyline-complex.html)

多边形

Polygon 对象类似于 Polyline 对象,都由一系列有序坐标构成。不过,多边形不像折线一样有两个端点,而是定义闭合区域。与折线类似的是,您可以定义影响多边形轮廓的笔触;不同的是,您还可以定义多边形内的填充区域。

此外,Polygon 还可以展示复杂形状,包括不连续形状(多个多边形定义为一个多边形)、“圆环”(多边形区域在多边形内显示为“岛”)以及一个或多个多边形的交叉。因此,单个多边形可指定多条路径。

多边形选项

与折线一样,您可以定义多边形边(“笔触”)的自定义颜色、粗细和不透明度,以及封闭区域(“填充”)的自定义颜色和不透明度。颜色应当采用十六进制数字的 HTML 样式。

由于多边形区域可能包括多条独立的路径,因此 Polygon 对象的 paths 属性指定“数组的数组”(每个都是 MVCArray 类型),其中每个数组分别定义一系列 LatLng 有序坐标。

但是,对于只包含一条路径的简单多边形,为方便起见,您可以采用单个 LatLng 坐标数组构造 Polygon。在将此简单数组存储到 Polygon 的 paths 属性时,Google Maps API 会在构造时将其转换为“数组的数组”。此外,该 API 还提供了简单的 getPath() 方法以构造只包含一条路径的简单多边形。

注意:如果采用此方式构造多边形,则仍需要将路径处理为 MVCArray,以便检索多边形的值。

以下代码段创建一个表示百慕大三角的多边形:


function initialize() {
  var myLatLng = new google.maps.LatLng(24.886436490787712, -70.2685546875);
  var myOptions = {
    zoom: 5,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var bermudaTriangle;

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      myOptions);

  var triangleCoords = [
    new google.maps.LatLng(25.774252, -80.190262),
    new google.maps.LatLng(18.466465, -66.118292),
    new google.maps.LatLng(32.321384, -64.75737),
    new google.maps.LatLng(25.774252, -80.190262)
  ];

  // Construct the polygon
  // Note that we don't specify an array or arrays, but instead just
  // a simple array of LatLngs in the paths property
  bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 2,
    fillColor: "#FF0000",
    fillOpacity: 0.35
  });

  bermudaTriangle.setMap(map);
}

查看示例 (polygon-simple.html)

多边形自动完成

上例中的 Polygon 包含四个坐标,但第一个坐标和最后一个坐标为相同位置,从而定义了一个环路。不过,实际上由于多边形定义的就是封闭区域,因而无需定义这最后一个坐标。对于任意指定路径,Google Maps API 将通过绘制连接最后一个坐标与第一个坐标的笔触以自动“封闭”任何多边形。

下例除了省略最后一个坐标之外,其他与上例均相同。

查看示例 (polygon-autoclose.html)

多边形数组

多边形将其一系列坐标指定为数组的数组,其中每个数组都是 MVCArray 类型。每个子数组都是 LatLng 坐标的数组,用于指定单条路径。要检索这些坐标,可调用 Polygon 的getPaths() 方法。由于数组为 MVCArray,因此您需要使用以下操作处理和检查该数组:

  • getAt() 用于在指定的索引值(从零开始)处传回 LatLng
  • insertAt() 用于在指定索引值(从零开始)处插入所传递的 LatLng。注意,该索引值的所有现有坐标均向前移动。
  • removeAt() 用于在指定的索引值(从零开始)处删除 LatLng

注意:不能只是使用语法 mvcArray[i] 检索数组的第 i 个元素,而必须使用 mvcArray.getAt(i)

以下代码通过显示多边形的坐标信息,处理多边形的点击事件:


var map;
var infoWindow;

function initialize() {
  var myLatLng = new google.maps.LatLng(24.886436490787712, -70.2685546875);
  var myOptions = {
    zoom: 5,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var bermudaTriangle;

  map = new google.maps.Map(document.getElementById("map_canvas"),
      myOptions);

  var triangleCoords = [
    new google.maps.LatLng(25.774252, -80.190262),
    new google.maps.LatLng(18.466465, -66.118292),
    new google.maps.LatLng(32.321384, -64.75737)
  ];

  bermudaTriangle = new google.maps.Polygon({
    paths: triangleCoords,
    strokeColor: "#FF0000",
    strokeOpacity: 0.8,
    strokeWeight: 3,
    fillColor: "#FF0000",
    fillOpacity: 0.35
  });

  bermudaTriangle.setMap(map);

  // Add a listener for the click event
  google.maps.event.addListener(bermudaTriangle, 'click', showArrays);

  infowindow = new google.maps.InfoWindow();
}

function showArrays(event) {

  // Since this Polygon only has one path, we can call getPath()
  // to return the MVCArray of LatLngs
  var vertices = this.getPath();

  var contentString = "<b>Bermuda Triangle Polygon</b><br />";
  contentString += "Clicked Location: <br />" + event.latLng.lat() + "," + event.latLng.lng() + "<br />";

  // Iterate over the vertices.
  for (var i =0; i < vertices.length; i++) {
    var xy = vertices.getAt(i);
    contentString += "<br />" + "Coordinate: " + i + "<br />" + xy.lat() +"," + xy.lng();
  }

  // Replace our Info Window's content and position
  infowindow.setContent(contentString);
  infowindow.setPosition(event.latLng);

  infowindow.open(map);
}

查看示例 (polygon-arrays.html)

圆形和矩形

除了普通的 Polygon 类之外,JavaScript Maps API 还包括面向 Circle 和 Rectangle 的特定类,用于简化其结构。

圆形

Circle 与 Polygon 类似,您可以自定义圆形(“笔触”)边缘的颜色、粗细和透明度,以及封闭区域(“填充”)的颜色和透明度。颜色应当采用十六进制数字的 HTML 样式。

与 Polygon 不同,您不应为 Circle 定义 paths;圆形有两个用于定义其形状的其他属性:

  • center 用于指定圆心的 google.maps.LatLng
  • radius 用于指定此圆的半径(以米为单位)。

下列代码段创建了用于表示美国人口的圆形:


// Create an object containing LatLng, population.
var citymap = {};
citymap['chicago'] = {
  center: new google.maps.LatLng(41.878113, -87.629798),
  population: 2842518
};
citymap['newyork'] = {
  center: new google.maps.LatLng(40.714352, -74.005973),
  population: 8143197
};
citymap['losangeles'] = {
  center: new google.maps.LatLng(34.052234, -118.243684),
  population: 3844829
}
var cityCircle;

function initialize() {
  var mapOptions = {
    zoom: 4,
    center: new google.maps.LatLng(37.09024, -95.712891),
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);
       
  for (var city in citymap) {
    // Construct the circle for each value in citymap. We scale population by 20.
    var populationOptions = {
      strokeColor: "#FF0000",
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: "#FF0000",
      fillOpacity: 0.35,
      map: map,
      center: citymap[city].center,
      radius: citymap[city].population / 20
    };
    cityCircle = new google.maps.Circle(populationOptions);
  }
}

查看示例 (circle-simple.html)

矩形

Rectangle 与 Polygon 类似,您可以自定义矩形(“笔触”)边缘的颜色、粗细和透明度,以及封闭区域(“填充”)的颜色和透明度。颜色应当采用十六进制数字的 HTML 样式。

与 Polygon 不同,您不应为 Rectangle 定义 paths;矩形有一个用于定义其形状的其他属性:

  • bounds 用于指定矩形的 google.maps.LatLngBounds

以下示例会在任何 'zoom_changed' 事件发生时基于前一个视口创建矩形:


function initialize() {

  var coachella = new google.maps.LatLng(33.6803003, -116.173894);
  var rectangle;

  var myOptions = {
    zoom: 11,
    center: coachella,
    mapTypeId: google.maps.MapTypeId.TERRAIN
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      myOptions);
        
  rectangle = new google.maps.Rectangle();

  google.maps.event.addListener(map, 'zoom_changed', function() {

    // Get the current bounds, which reflect the bounds before the zoom.
    var rectOptions = {
      strokeColor: "#FF0000",
      strokeOpacity: 0.8,
      strokeWeight: 2,
      fillColor: "#FF0000",
      fillOpacity: 0.35,
      map: map,
      bounds: map.getBounds()
    };
    rectangle.setOptions(rectOptions);
  });
}

查看示例 (rectangle-simple.html)

地面叠加层

多边形在表示不规则的区域时很有用,但不能显示图片。如果要在地图上放置一幅图片,可以使用 GroundOverlay 对象。 GroundOverlay 的构造函数采用图片的网址和LatLngBounds 作为参数。图片将渲染在地图上的指定边界内,并与地图的投影一致。

下面的示例将新泽西州纽瓦克的一幅老地图作为叠加层放在地图上:

var newark = new google.maps.LatLng(40.740, -74.18);
var imageBounds = new google.maps.LatLngBounds(
    new google.maps.LatLng(40.716216,-74.213393),
    new google.maps.LatLng(40.765641,-74.139235));

var myOptions = {
  zoom: 13,
  center: newark,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

var oldmap = new google.maps.GroundOverlay(
    "http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg",
    imageBounds);
oldmap.setMap(map);

查看示例 (groundoverlay-simple.html)

信息窗口

InfoWindow 在地图上方的浮动窗口中显示内容。信息窗口有点像漫画书上的文字气球,它有一个内容区域和锥形引线,引线的头位于地图的指定位置上。通过点击 Google Maps 上的商户标记,您可以看到活动的信息窗口。

InfoWindow 构造函数采用的是 InfoWindow options 对象,该对象指定了用于显示信息窗口的一组初始参数。在创建信息窗口的过程中,系统不会在地图上添加信息窗口。要显示信息窗口,您需要调用 InfoWindow 上的 open() 方法,向其传递要在其中打开信息窗口的 Map,以及向其传递用于锚定信息窗口的 Marker(可选)。(如果未提供任何标记,那么,会在其 position 属性上打开信息窗口)。

InfoWindow options 对象是包含以下字段的对象常量:

  • content 包含了信息窗口打开时,系统要在其中显示的文本字符串或 DOM 节点。
  • pixelOffset 包含了从信息窗口的顶部到信息窗口锚定位置的偏移量。实际上,您不应也无需修改此字段。
  • position 包含了此信息窗口锚定位置的 LatLng。请注意,在标记上执行打开信息窗口操作时,系统会自动使用一个新位置更新该值。
  • maxWidth 指定了信息窗口的最大宽度(以像素为单位)。默认情况下,信息窗口会根据其中包含的内容进行扩展,如果信息窗口随着地图的大小而扩展,那么,文本将会自动换行。如果您应用了 maxWidth,那么,信息窗口将自动换行以强制适应像素的宽度。如果屏幕的实际使用面积允许的话,信息窗口在达到最大宽度后仍可垂直扩展。

InfoWindow 的内容可以是文本字符串、HTML 代码段或 DOM 元素本身。要设置此内容,请在 InfoWindow options 构造函数中传递该内容,或者对信息窗口显式调用setContent()。如果想要显式调整内容的大小,您可以使用 <div> 进行此操作,如果您希望,还可以启用滚动功能。请注意,如果您没有启用滚动功能,而内容的大小又超过了信息窗口的可用空间,那么,内容可能会从信息窗口中“溢”出。

InfoWindow 可附加到 Marker 对象(在这种情况下,它们的位置取决于标记的位置)上,或附加到地图本身指定的 LatLng 位置上。如果您一次只想显示一个信息窗口(正如 Google Maps 上的相应行为),那么,您只需创建一个信息窗口,然后在地图事件(例如用户点击)执行过程中将此信息窗口重新分配到不同的位置或标记中。但与 Google Maps API 第 2 版中的相应行为不同的是,如果您选择进行上述操作,那么,地图可能会立即显示多个 InfoWindow 对象。

要更改信息窗口的位置,您可以对信息窗口调用 setPosition() 以显式的方式更改其位置,或者使用 InfoWindow.open() 方法将信息窗口附加到新标记上。请注意,如果您在没有传递标记的情况下调用了 open(),那么,InfoWindow 将会使用在构建过程中通过 InfoWindow options 对象指定的位置。

以下代码显示了澳大利亚中心位置的标记。点击该标记可显示信息窗口。

var myLatlng = new google.maps.LatLng(-25.363882,131.044922);
var myOptions = {
  zoom: 4,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

var contentString = '<div id="content">'+
    '<div id="siteNotice">'+
    '</div>'+
    '<h1 id="firstHeading" class="firstHeading">Uluru</h1>'+
    '<div id="bodyContent">'+
    '<p><b>Uluru</b>, also referred to as <b>Ayers Rock</b>, is a large ' +
    'sandstone rock formation in the southern part of the '+
    'Northern Territory, central Australia. It lies 335 km (208 mi) '+
    'south west of the nearest large town, Alice Springs; 450 km '+
    '(280 mi) by road. Kata Tjuta and Uluru are the two major '+
    'features of the Uluru - Kata Tjuta National Park. Uluru is '+
    'sacred to the Pitjantjatjara and Yankunytjatjara, the '+
    'Aboriginal people of the area. It has many springs, waterholes, '+
    'rock caves and ancient paintings. Uluru is listed as a World '+
    'Heritage Site.</p>'+
    '<p>Attribution: Uluru, <a href="http://en.wikipedia.org/w/index.php?title=Uluru&oldid=297882194">'+
    'http://en.wikipedia.org/w/index.php?title=Uluru</a> (last visited June 22, 2009).</p>'+
    '</div>'+
    '</div>';

var infowindow = new google.maps.InfoWindow({
    content: contentString
});

var marker = new google.maps.Marker({
    position: myLatlng,
    map: map,
    title:"Uluru (Ayers Rock)"
});

google.maps.event.addListener(marker, 'click', function() {
  infowindow.open(map,marker);
});

查看示例 (infowindow-simple.html)

以下显示了将信息窗口 maxWidth 设置为 200 像素的示例:

查看示例 (infowindow-simple-max.html)

图层概述

图层是地图上的对象,包含一个或多个单独项,但可作为一个整体进行操作。图层通常反映了您添加到地图上用于指定公共关联的对象集合。Maps API 会通过以下方法管理图层内对象的显示形式:将图层的组成项呈现在一个对象(通常为一个图块叠加层)中并根据地图视口的变化情况进行显示。图层还可以改变地图自身的展示图层,以符合图层样式的方式稍稍改变基本图块。请注意,系统将大部分图层设计为禁止通过其单个对象进行访问,而仅可将其作为一个整体来操作。

要在地图上添加图层,只需调用 setMap(),将图层传递给要在其中显示图层的地图对象。同样,要隐藏图层,可调用 setMap(),传递 null

Google Maps API 包含以下几种图层:

  • KmlLayer 对象会在 Maps API V3 图块叠加层中呈现 KML 和 GeoRSS 元素。
  • FusionTablesLayer 对象会呈现 Google Fusion Tables 中包含的数据。
  • TrafficLayer 对象会呈现描述交通状况的图层和表示路况的叠加层。
  • BicyclingLayer 对象会在公共图层中呈现自行车路径的图层和/或特定于自行车的叠加层。默认情况下,当请求旅行模式 BICYCLING 的路线时,该图层会在DirectionsRenderer 中返回。

下面将分别介绍这些图层。

KML 和 GeoRSS 图层

Google Maps API 支持采用 KML 和 GeoRSS 数据格式以显示地理信息。这些数据格式使用 KmlLayer 对象显示在地图上,其构造函数采用可公开访问的 KML 或 GeoRSS 文件的网址作为参数。

Maps API 会将提供的地理 XML 数据转换为 KML 表现形式,该表现形式可使用第 3 版图块叠加层显示在地图上。该 KML 在外观上与用户熟悉的第 3 版叠加层元素类似(两者在行为上也有几分类似)。KML <Placemark> 和 GeoRSS point 元素都呈现为标记(举例而言),<LineString> 元素会呈现为折线,而 <Polygon> 元素则呈现为多边形。同样地,<GroundOverlay> 元素会在地图上呈现为矩形图片。不过,这些对象都不是 Google Maps API MarkerPolylinePolygon 或 GroundOverlay,它们只是在地图上呈现为单个对象,这一点非常重要。

一旦设置 KmlLayer 对象的 map 属性,这些对象便会显示在地图上。(可以调用 setMap() 传递 null,从地图上删除这些对象。)KmlLayer 对象会通过自动检索地图指定边界的相应地图项来管理这些子叠加层的显示形式。随着边界的变化,当前可视区域中的地图项会自动渲染。

由于 KmlLayer 中的组件为按需渲染,因此您可以借助图层轻松管理成千上万个标记、折线和多边形的渲染。请注意:尽管这些组成对象都提供了点击事件,以返回这些单个对象的相关数据,但您无法直接访问这些对象。

KML 图层选项

KmlLayer() 构造函数可以有选择地传递以下多个 KmlLayerOptions

  • map 指定要在其上渲染 KmlLayer 的 Map。您可以在 setMap() 方法中将此值设置为 null,从而隐藏 KmlLayer
  • preserveViewport 指定在显示图层时不应当将地图调整到 KmlLayer 内容的边界。默认情况下,在显示 KmlLayer 时,会缩放并定位地图以完整地显示图层内容。
  • suppressInfoWindows 指定 KmlLayer 中的可点击地图项不应触发 InfoWindow 对象的显示。

此外,一旦渲染了 KmlLayer,它将包含不可改变的 metadata 属性,其 KmlLayerMetadata 对象文字中包括图层的名称、说明、摘要和作者。您可以使用 getMetadata() 方法检查此信息。由于 KmlLayer 对象的渲染需要与外部服务器异步通信,因此您需要侦听 metadata_changed 事件,该事件将指出属性已填充。

下例根据指定的 GeoRSS 供稿构造 KmlLayer

var myLatlng = new google.maps.LatLng(49.496675,-102.65625);
var myOptions = {
  zoom: 4,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  
var georssLayer = new google.maps.KmlLayer('http://api.flickr.com/services/feeds/geo/?g=322338@N20&lang=en-us&format=feed-georss');
georssLayer.setMap(map);

查看 GeoRSS 示例 (layer-georss.html)

下例根据指定的 KML 供稿构造 KmlLayer

var myLatlng = new google.maps.LatLng(41.875696,-87.624207);
var myOptions = {
  zoom: 11,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    
var ctaLayer = new google.maps.KmlLayer('http://gmaps-samples.googlecode.com/svn/trunk/ggeoxml/cta.kml');
ctaLayer.setMap(map);

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

KML 地图项详情

由于 KML 可能包括大量地图项,因此您可能无法直接访问 KmlLayer 对象的地图项数据。相反,系统在显示地图项时,会将其呈现为类似于可点击的 Maps API 叠加层。默认情况下,点击各个地图项会显示 InfoWindow,其中包含指定地图项的 KML <title> 和 <description> 信息。此外,点击 KML 地图项会生成 KmlMouseEvent,该事件将传递以下信息:

  • position 指出锚定此 KML 地图项的 InfoWindow 的纬度/经度坐标。对于多边形、折线和 GroundOverlay,该位置通常为点击位置,但是对于标记则为坐标原点。
  • pixelOffset 指出相对于上述 position 的偏移量,以锚定 InfoWindow 的“尾部”。对于多边形对象,该偏移通常为 0,0,但对于标记则会包含标记的高度。
  • featureData 包含 KmlFeatureData 的 JSON 结构。

以下显示了一个示例 KmlFeatureData 对象:

{
  author: {
    email: "[email protected]",
    name: "Mr Nobody",
    uri: "http://example.com"
  },
  description: "description",
  id: "id",
  infoWindowHtml: "html",
  name: "name",
  snippet: "snippet"
}

下例当点击 KML 地图项时在边 <div> 中显示 KML 地图项的 <Description> 文本:

var myLatlng = new google.maps.LatLng(40.65, -73.95);
var myOptions = {
  zoom: 12,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    
var nyLayer = new google.maps.KmlLayer('http://www.searcharoo.net/SearchKml/newyork.kml',
    {suppressInfoWindows: true});
nyLayer.setMap(map);
google.maps.event.addListener(nyLayer, 'click', function(kmlEvent) {
  var text = kmlEvent.featureData.description;
  showInDiv(text);
});
  
function showInDiv(text) {
  var sidediv = document.getElementById('contentWindow');
  sidediv.innerHTML = text;
}

查看 KML 示例 (layer-kml-features.html)

Fusion Table 图层(实验性)

Google Maps API 可让您使用 FusionTablesLayer 对象将 Google Fusion Tables 中包含的数据呈现为地图上的图层。Google Fusion Table 是一种数据库表格,其中每行都包含了特定地图项的相关数据;对于地理数据,Google Fusion Table 的每行还另外包含位置数据,保存了地图项的位置信息。该 FusionTablesLayer 提供了公开 Fusion Table 的界面,并支持自动呈现此位置数据,提供显示地图项其他数据的可点击叠加层。

下面提供了显示地理数据的 Fusion Table 示例:

Fusion Table 设置

Fusion Tables 是数据表格,可提供内置的地理数据支持。要了解 Fusion Tables 的完整文档,请查看 Fusion Tables 开发人员指南。对于要在 Google 地图上的 API 中显示数据的 Fusion Tables 图层,该表格必须满足以下标准:

  • 该表格必须设置为公开分享(建议设置为作为查看者)。
  • 该表格必须有一列或多列显示为 Location。在 Fusion Tables 中,选择编辑 > 修改列,然后选择要修改的列。

Location 列可以包含以下有效内容:

  • 纬度/经度坐标必须各自占用一列。
  • 地址必须先经过地址解析处理。在 Fusion Tables 网络界面中,选择文件 > 地址解析
  • 支持 KML 几何数据,如点、线和多边形。

构建 FusionTables 图层

FusionTablesLayer 构造函数会使用 Fusion Table 的唯一 ID 根据公开的该表创建一个图层。Fusion Table ID 位于 Fusion Table 网址的 dsrcid 参数中:

http://tables.googlelabs.com/DataSource?dsrcid=fusionTableID

要向地图添加 Fusion Tables 图层,请先创建图层,然后将正确的 ID 作为 query 参数的一部分向其传递,接着将图层的 map 设置为 Map 对象(与其他任何叠加层一样)。最多可向地图添加五个 Fusion Tables 图层。

以下示例使用公开的 Fusion Table 显示了 2009 年芝加哥发生的凶杀案件:

var chicago = new google.maps.LatLng(41.850033, -87.6500523);

map = new google.maps.Map(document.getElementById('map_canvas'), {
  center: chicago,
  zoom: 12,
  mapTypeId: 'roadmap'
});

var layer = new google.maps.FusionTablesLayer({
  query: {
    select: 'Geocodable address',
    from: '139529'
  },
});
layer.setMap(map);

查看 Fusion Table 示例 (layer-fusiontables-simple.html)

Fusion Table 查询

Fusion Tables 还可让您应用强大的查询功能,该功能可根据指定标准对结果进行限制。您可以使用 FusionTablesLayerOptions query 参数指定查询:

query: {
  select: locationColumn,
  from: fusionTableID,
  where: constraintClause
}

其中 locationColumn 是 Location 类型现有的经过地址解析的列。您必须指定特定的 locationColumn,且不得使用 select: '*'

Fusion Tables 文档中列出了支持的搜索运算符。

以下示例显示了芝加哥高速运输管理局 (CTA) 的红线地铁的沿线站点中,工作日的乘坐人数超过 5000 人次的站点:

var chicago = new google.maps.LatLng(41.948766, -87.691497);

map = new google.maps.Map(document.getElementById('map_canvas'), {
  center: chicago,
  zoom: 12,
  mapTypeId: 'roadmap'
});
 
var layer = new google.maps.FusionTablesLayer({
  query: {
    select: 'address',
    from: '198945',
    where: 'ridership > 5000'
  }
});
layer.setMap(map);

查看 Fusion Table 示例 (layer-fusiontables-query.html)

Fusion Table 样式

Fusion Tables 图层构造函数也接受 FusionTablesLayerOptions styles 参数,以便向标记和多边形应用颜色、笔触粗细和透明度。您也可以通过支持的地图标记或图标名称来指定标记图标。

在每张地图中,仅可将样式应用于一个 Fusion Tables 图层。您最多可向该图层应用五种样式。

styles 参数使用了以下语法:

styles: [{
  where: 'column_name condition',
  markerOptions: {
    iconName: "supported_icon_name"
  },
  polygonOptions: {
    fillColor: "#rrggbb",
    strokeColor: "#rrggbb",
    strokeWeight: "int"
  },
  polylineOptions: {
    strokeColor: "#rrggbb",
    strokeWeight: "int"  }
}, {
  where: ...
  ...
}]

样式会应用到 Fusion Tables 网络界面中指所定的任何样式之上。这些向图层构造函数提供的样式会按照它们所列出顺序进行应用,其中匹配多条规则的任意地图项会采用最后一条匹配样式。

要创建应用到所有地图项的默认样式,请创建不带 where 子句的样式:

styles: [{
  markerOptions: {
    iconName: "large_green"
  }
}]

以下示例显示了:

  • 默认样式,其中将所有多边形设为绿色,透明度级别设为 0.3。
  • 将“鸟类”列超过 300 的所有多边形设为蓝色,并保留默认样式设置的透明度级别。
  • 将“人口”列超过 5 的所有多边形的透明度级别设为 1.0,并保留其 fillColor 值。
var australia = new google.maps.LatLng(-25, 133);

map = new google.maps.Map(document.getElementById('map_canvas'), {
  center: australia,
  zoom: 4,
  mapTypeId: google.maps.MapTypeId.ROADMAP
});

layer = new google.maps.FusionTablesLayer({
  query: {
    select: 'geometry',
    from: '815230'
  },
  styles: [{
    polygonOptions: {
      fillColor: "#00FF00",
      fillOpacity: 0.3
    }
  }, {
    where: "birds > 300",
    polygonOptions: {
      fillColor: "#0000FF"
    }
  }, {
    where: "population > 5",
    polygonOptions: {
      fillOpacity: 1.0
    }
  }]
});
layer.setMap(map);

查看 Fusion Table 示例 (layer-fusiontables-styling.html)

Fusion Table 热图

Fusion Tables 还对热图提供一定的支持,并会以一组不同的颜色来表示匹配位置的密度。当前热图使用了红色(密集)到绿色(稀少)的渐变来表示关联位置的相对份额。要启用热图,请将图层的 FusionTablesLayerOptions heatmap 参数设置为 enabled: true

以下示例借助热图显示了巴西海岸的指定海滩:

var brazil = new google.maps.LatLng(-18.771115, -42.758789);

map = new google.maps.Map(document.getElementById('map_canvas'), {
  center: brazil,
  zoom: 5,
  mapTypeId: google.maps.MapTypeId.ROADMAP
});

layer = new google.maps.FusionTablesLayer({
  query: {
    select: 'LATITUDE',
    from: '136705'
  },
  heatmap: {
    enabled: true
  }
});
layer.setMap(map);

查看 Fusion Table 示例 (layer-fusiontables-heatmap.html)

路况图层

在 Google Maps API 中,您可以使用 TrafficLayer 对象在地图中添加实时路况信息(如果支持)。路况信息于提出请求时提供。要了解路况覆盖范围的支持情况,请查看此电子表格。

var myLatlng = new google.maps.LatLng(34.04924594193164, -118.24104309082031);
var myOptions = {
  zoom: 13,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);

查看路况示例 (layer-traffic.html)

自行车图层

在 Google Maps API 中,您可以使用 BicyclingLayer 对象在地图中添加自行车信息。BicyclingLayer 在指定地图上渲染自行车路径、建议的自行车路线以及针对自行车的其他叠加层的图层。此外,该图层会更改基本地图本身的样式,以突出显示支持自行车路线的街道,并弱化显示不适合骑自行车的街道。

下例在麻萨诸塞州剑桥的地图上显示支持的自行车图层:

var myLatlng = new google.maps.LatLng(42.3726399, -71.1096528);
var myOptions = {
  zoom: 14,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}

var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    
var bikeLayer = new google.maps.BicyclingLayer();
bikeLayer.setMap(map);

深绿色路线表示专用的自行车路线。浅绿色路线表示有专用“自行车车道”的街道。虚线路线表示不建议自行车行驶的街道或路径。

查看示例 (layer-bicycling.html)

Panoramio 图层(库)

本文档中的概念仅适用于在 google.maps.panoramio 库中提供的地图项。默认情况下,系统在加载 Maps JavaScript API 时不会加载该库,您必须使用 libraries 引导程序参数进行明确指定。 

有关详情,请参见 V3 Maps API 中的库。

使用 PanoramioLayer 对象

您可以使用 PanoramioLayer 对象将 Panoramio 中的照片添加为地图的图层。PanoramioLayer 会在地图上将 Panoramio 中的照片图标(已加注地理位置标签)的图层呈现为一系列不同尺寸的照片图标。

要向您的地图添加 PanoramioLayer,只需要创建该对象并设置其地图属性即可:

var panoramioLayer = new google.maps.panoramio.PanoramioLayer();
panoramioLayer.setMap(map);

默认情况下,点击 Panoramio 图层内的照片图标会弹出一个信息窗口,其中显示了较大尺寸的照片和更多信息。要删除该默认行为,您只需将图层的 suppressInfoWindows 属性设置为 true 即可。您也可以检查与单幅 Panoramio 照片相关联的元数据,方法是处理 PanoramioLayer 上的 'click' 事件,并检查 PanoramioMouseEvent 的 featureDetails 属性。请注意,如果您要实现自己的点击处理程序且不显示默认的信息窗口,则您对 Panoramio 照片的使用行为必须遵循 Panoramio API 服务条款,包括任何品牌塑造和版权归属要求。

以下示例显示了华盛顿州西雅图的 Panoramio 图层。您每点击一张照片,右侧面板中就会增加一个指向的 Panoramio 照片页的链接:

var fremont = new google.maps.LatLng(47.651743, -122.349243);
var myOptions = {
  zoom: 16,
  center: fremont,
  mapTypeId: google.maps.MapTypeId.ROADMAP
};

var map = new google.maps.Map(
    document.getElementById("map_canvas"),
    myOptions);

var panoramioLayer = new google.maps.panoramio.PanoramioLayer();

panoramioLayer.setMap(map);

google.maps.event.addListener(panoramioLayer, 'click', function(event) {
  var photoDiv = document.getElementById('photoPanel');
  var attribution = document.createTextNode(event.featureDetails.title + ": " + event.featureDetails.author);
  var br = document.createElement("br");
  var link = document.createElement("a");
  link.setAttribute("href", event.featureDetails.url);
  link.appendChild(attribution);
  photoDiv.appendChild(br);
  photoDiv.appendChild(link);
});

查看示例 (layer-panoramio.html)

按标记或用户 ID 限制照片

您可以对显示在 PanoramioLayer 上的照片组进行限制,以便仅显示与特定文本标记或特定用户相匹配的照片。

要仅显示与特定标记相匹配的照片,请在 PanoramioLayer 对象上调用 setTag()。系统会将图层更新为仅显示地图视口内与该标记相匹配的照片。要仅显示与特定用户相匹配的照片,请在 setUserId() 对象上调用 PanoramioLayer

以下示例显示了未经标记过滤的纽约港口的地图。在输入字段中输入文字,然后使用 setTag() 方法应用过滤器:

[verbatim]
var panoramioLayer;
function initialize() {
  var nyHarbor = new google.maps.LatLng(40.693134, -74.031028);
  var myOptions = {
    zoom: 15,
    center: nyHarbor,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  var map = new google.maps.Map(
      document.getElementById("map_canvas"),
      myOptions);

  panoramioLayer = new google.maps.panoramio.PanoramioLayer();

  panoramioLayer.setMap(map);
}

function getTaggedPhotos() {
  var tagFilter = document.getElementById('tag').value;
  panoramioLayer.setTag(tagFilter);
}

查看示例 (layer-panoramio-tags.html)

使用 Panoramio Widget API

您还可以使用 Panoramio Widget API 在 PanoramioWidget 对象内显示图像。要使用 Panoramio API,您需要通过脚本标记从 JavaScript API 中单独为该 API 加载 JavaScript 符号。

<script type="text/javascript" src="https://www.panoramio.com/wapi/wapi.js?v=1">
</script>

Panoramio PhotoWidget 的默认大小为 400x300 像素。如果您希望在信息窗口内显示 PhotoWidget,则可使用该默认大小,也可以在 PhotoWidget 的构造函数内明确设置大小。请注意,PhotoWidget 不会根据其容器(在此情况中即信息窗口)的大小来自动调整自身的大小。您需要明确设置该窗口小部件的宽度和高度。

以下示例借助 Panoramio Widget API 使用 Panoramio 图像填充了信息窗口。请注意,您可以轻松地配置该窗口小部件,以便显示多张图片。

// This example requires loading the Panoramio Widget API
// via http://www.panoramio.com/wapi/wapi.js?v=1

// The photoDiv defines the DIV within the info window for
// displaying the Panoramio photo within its PhotoWidget.
// We use the info window's maximum size of 640 px.
var photoDiv =  document.createElement("div");
photoDiv.style.width = '640px';
photoDiv.style.height = '500px';

// The PhotoWidget width and height are expressed as number values,
// not string values so we need to turn them into floats.
var photoWidgetOptions = {
  'width': parseFloat(photoDiv.style.width),
  'height': parseFloat(photoDiv.style.height)
};

// We construct a PhotoWidget here with a blank (null) request as we
// don't yet have a photo to populate it.
var photoWidget = new panoramio.PhotoWidget(photoDiv, null, photoWidgetOptions);

var monoLake = new google.maps.LatLng(37.973432, -119.093170);
var myOptions = {
  zoom: 11,
  center: monoLake,
  mapTypeId: google.maps.MapTypeId.ROADMAP
};

var map = new google.maps.Map(
    document.getElementById("map_canvas"),
    myOptions);

var photoWindow = new google.maps.InfoWindow();
var panoramioOptions = {
  suppressInfoWindows: true
}
var panoramioLayer = new google.maps.panoramio.PanoramioLayer(panoramioOptions);

panoramioLayer.setMap(map);

google.maps.event.addListener(panoramioLayer, 'click', function(event) {

  var photoRequestOptions = {
    ids: [{'photoId': event.featureDetails.photoId,
           'userId': event.featureDetails.userId}]
  }
  photoWidget.setRequest(photoRequestOptions);
  photoWidget.setPosition(0);

  photoWindow.setPosition(event.latLng);
  photoWindow.open(map);
  photoWindow.setContent(photoDiv);
});

查看示例 (layer-panoramio-widget.html)

有关使用该 API 的完整信息,请参考 Panoramio JavaScript API 文档。

自定义叠加层

Google Maps API 第 3 版提供了用于创建自定义叠加层的 OverlayView 类。OverlayView 是一个基类,提供了您在创建叠加层时必须实现的若干方法。该类还提供了一些方法,用于实现屏幕坐标和地图位置之间的转换。

要创建自定义叠加层,请执行以下操作:

  • 将自定义对象的 prototype 设置为 google.maps.OverlayView() 的新实例。这可以有效地实现叠加层类的“子类化”。
  • 为自定义叠加层创建构造函数,并将该构造函数中的所有初始化参数都设置为自定义属性。
  • 在原型中实现 onAdd() 方法,以将叠加层附加到地图上。当地图准备好附加叠加层后,系统将会调用 OverlayView.onAdd()
  • 在原型中实现 draw() 方法,以处理对象的视觉显示。同样,在对象首次显示后,系统将会调用 OverlayView.draw()
  • 您还应当实现 onRemove() 方法,以清理在叠加层中添加的所有元素。

我们将会在以下各部分中逐步介绍这些操作。

叠加层的子类化

我们将会使用 OverlayView 创建简单的图像叠加层(与第 2 版 API 中的 GGroundOverlay 相似)。我们还会创建一个 USGSOverlay 对象,它包含了相关区域的 USGS 图像以及图像的边界。

var overlay;

function initialize() {
  var myLatLng = new google.maps.LatLng(62.323907, -150.109291);
  var myOptions = {
    zoom: 11,
    center: myLatLng,
    mapTypeId: google.maps.MapTypeId.SATELLITE
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);

  var swBound = new google.maps.LatLng(62.281819, -150.287132);
  var neBound = new google.maps.LatLng(62.400471, -150.005608);
  var bounds = new google.maps.LatLngBounds(swBound, neBound);

  // Photograph courtesy of the U.S. Geological Survey
  var srcImage = 'images/talkeetna.png';
  overlay = new USGSOverlay(bounds, srcImage, map);
}

接下来,我们则会创建该类的一个构造函数,并将已传递的参数初始化为新对象的属性。此外,我们还需要显式地将 USGSOverlay 中的 OverlayView 子类化。我们可通过将新类的prototype 设置为父类的一个实例进行上述操作(由于我们不希望修改父类,因此,我们在此处将原型设置为实例,而非父类本身)。

function USGSOverlay(bounds, image, map) {

  // Now initialize all properties.
  this.bounds_ = bounds;
  this.image_ = image;
  this.map_ = map;

  // We define a property to hold the image's
  // div. We'll actually create this div
  // upon receipt of the add() method so we'll
  // leave it null for now.
  this.div_ = null;

  // Explicitly call setMap() on this overlay
  this.setMap(map);
}

USGSOverlay.prototype = new google.maps.OverlayView();

目前,我们还无法在叠加层的构造函数中将此叠加层附加到地图上。具体而言,我们需要确保所有的地图窗格(指定对象在地图上的显示顺序)都可用。API 提供了一种帮助程序方法,可以非常方便地表明是否执行了上述操作。我们将会在下一部分中介绍如何处理该方法。

初始化叠加层

当叠加层完成首次示例化并处于准备显示状态时,我们需要通过浏览器的 DOM 将其附加到地图。API 会通过显示表明:系统已通过调用叠加层的 onAdd() 方法将此叠加层添加到地图中。在处理此方法时,我们会创建一个用于保存图像的 <div>,添加一个 <img> 元素,将该元素附加到 <div>,最后将叠加层附加到地图的一个“窗格”(即 DOM 树中的节点)中。

一组 MapPanes 类型的窗格用于指定不同的层在地图上的堆叠顺序。您可以使用以下窗格,并且可以按照由下至上的堆叠顺序枚举这些窗格。

  • MapPanes.mapPane
  • MapPanes.overlayLayer
  • MapPanes.overlayShadow
  • MapPanes.overlayImage
  • MapPanes.floatShadow
  • MapPanes.overlayMouseTarget
  • MapPanes.floatPane

由于我们的图像为“地面叠加层”,因此,我们将会使用 overlayLayer 地图窗格。创建了此窗格后,我们会以子对象的形式将对象附加到窗格上。

USGSOverlay.prototype.onAdd = function() {

  // Note: an overlay's receipt of onAdd() indicates that
  // the map's panes are now available for attaching
  // the overlay to the map via the DOM.

  // Create the DIV and set some basic attributes.
  var div = document.createElement('DIV');
  div.style.border = "none";
  div.style.borderWidth = "0px";
  div.style.position = "absolute";

  // Create an IMG element and attach it to the DIV.
  var img = document.createElement("img");
  img.src = this.image_;
  img.style.width = "100%";
  img.style.height = "100%";
  div.appendChild(img);

  // Set the overlay's div_ property to this DIV
  this.div_ = div;

  // We add an overlay to a map via one of the map's panes.
  // We'll add this overlay to the overlayImage pane.
  var panes = this.getPanes();
  panes.overlayLayer.appendChild(div);
}

绘制叠加层

请注意,在上述操作中,我们实际上并未调用任何特殊的视觉显示。每当需要在地图上绘制叠加层时(其中包括首次添加叠加层时),API 都会对叠加层调用独立的 draw() 方法。

因此,我们将会实现此 draw() 方法,然后使用 getProjection() 检索叠加层的 MapCanvasProjection,并计算对象的右上角和左下角锚定点的准确坐标,以此重新调整 <div> 的大小;反之,此操作又可重新调整图像的大小,从而让图像与我们在叠加层的构造函数中所指定的范围相匹配。

USGSOverlay.prototype.draw = function() {

  // Size and position the overlay. We use a southwest and northeast
  // position of the overlay to peg it to the correct position and size.
  // We need to retrieve the projection from this overlay to do this.
  var overlayProjection = this.getProjection();

  // Retrieve the southwest and northeast coordinates of this overlay
  // in latlngs and convert them to pixels coordinates.
  // We'll use these coordinates to resize the DIV.
  var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest());
  var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());

  // Resize the image's DIV to fit the indicated dimensions.
  var div = this.div_;
  div.style.left = sw.x + 'px';
  div.style.top = ne.y + 'px';
  div.style.width = (ne.x - sw.x) + 'px';
  div.style.height = (sw.y - ne.y) + 'px';
}

删除叠加层

我们还会添加 onRemove() 方法,完全删除地图中的叠加层。如果我们曾经将叠加层的 map 属性设置为 null,那么,系统将会自动通过 API 调用此方法。

USGSOverlay.prototype.onRemove = function() {
  this.div_.parentNode.removeChild(this.div_);
  this.div_ = null;
}

查看示例 (overlay-simple.html)

隐藏和显示叠加层

如果您想要隐藏或显示叠加层,而不只是创建或删除叠加层,您可以实现 hide() 和 show() 方法,以调整叠加层的可见性。或者,您也可以将叠加层与地图的 DOM 分离,但这种操作的成本有些过高。请注意,如果您随后将叠加层重新附加到地图的 DOM 上,则系统会重新调用叠加层的 onAdd() 方法。

以下示例介绍了如何将 hide() 和 show() 方法添加到叠加层的原型中,这样可

你可能感兴趣的:(Google Maps JavaScript API V3的使用(四))