Google Map apiv3叠加层


  1. 叠加层概述

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

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

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

添加叠加层

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

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

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()。(请注意,与 V2 不同,该版本中未提供 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)

符号

Symbol 是基于矢量的图片,可显示在 Marker 或 Polyline 对象上。符号是通过路径(使用 SVG 路径表示法)和一些用于控制符号显示方式的选项来定义的。一些预定义符号可通过 SymbolPath 类提供。 path 是唯一必需的属性,而 Symbol 类支持多种属性,可让您自定义显示方面的设置(例如笔触、填充颜色和粗细)。

要详细了解如何在线段上显示符号或为符号添加动画效果,请参阅关于折线上的符号的文档。要详细了解如何使用符号作为标记图片,请参阅下面关于矢量图片的文档。

Symbol 类支持以下属性。请注意,显示在标记和折线上的 Symbol 的行为会略有不同。

  • path必填),表示用于定义符号形状的路径。您可以使用 google.maps.SymbolPath 中预定义的某个路径,也可以使用 SVG 路径表示法定义自定义路径。注意:折线上的矢量路径不得超过 22x22 像素的方形范围。如果您的路径中包含超出此范围的点,那么您必须将 scale 属性调整为分数值(如 0.2),以使调整后的点处于该方形范围内。
  • anchor,表示符号相对于标记或折线的位置。符号路径的坐标分别由锚定点的 x 坐标和 y 坐标向左和向上进行转换。默认情况下,符号锚定在 (0, 0)。表示该位置的坐标系与符号路径的坐标系相同。
  • fillColor,表示符号的填充色。支持所有 CSS3 颜色,扩展命名的颜色除外。对于符号标记,默认颜色为“黑色”。对于折线上的符号,默认颜色为相应折线的笔触颜色。
  • fillOpacity,以 0 到 1 之间的数字表示符号填充的透明度。默认值为 0。
  • rotation,以顺时针的读数表示旋转符号的角度。默认情况下,符号标记的旋转角度为 0,而折线上的符号按其所在一边的角度旋转。设置折线上符号的旋转会固定符号的旋转,这样符号就不会再沿着曲线移动了。
  • scale,表示符号大小缩放的数值。对于符号标记,默认值为 1;符号在缩放后可能为任意大小。对于折线上的符号,默认值为折线的笔触粗细;经过缩放后,符号必须位于 22x22 像素的方形范围内(以符号的锚定点为中心)。
  • strokeColor,表示符号的笔触颜色。支持所有 CSS3 颜色,扩展命名的颜色除外。对于符号标记,默认颜色为“黑色”。对于折线上的符号,默认颜色为折线的笔触颜色。
  • strokeOpacity,以 0 到 1 之间的数字表示符号笔触的透明度。对于符号标记,默认值为 1。对于折线上的符号,默认透明度为折线的透明度。
  • strokeWeight,表示符号的笔触粗细。默认值为符号的 scale

以下示例创建了一个星行符号,填充颜色为淡黄色,边框为深黄色。

var goldStar = {
  path: 'M 125,5 155,90 245,90 175,145 200,230 125,180 50,230 75,145 5,90 95,90 z',
  fillColor: "yellow",
  fillOpacity: 0.8,
  scale: 1,
  strokeColor: "gold",
  strokeWeight: 14
};

var marker = new google.maps.Marker({
  position: new google.maps.LatLng(-25.363, 131.044),
  icon: goldStar,
  map: map
});

预定义路径

Google Maps JavaScript API 提供了一些内置符号,可在标记或折线上显示。默认符号包含一个圆形和两种箭头。由于折线上符号的方向是固定的,因此向前和向后的箭头都可以使用。向前是指折线的终点方向。包含的符号如下:

名称 说明 示例
google.maps.SymbolPath.CIRCLE 圆形。
google.maps.SymbolPath.BACKWARD_CLOSED_ARROW 各边封闭的向后箭头。
google.maps.SymbolPath.FORWARD_CLOSED_ARROW 各边封闭的向前箭头。
google.maps.SymbolPath.BACKWARD_OPEN_ARROW 一边开放的向后箭头。
google.maps.SymbolPath.FORWARD_OPEN_ARROW 一边开放的向前箭头。

您可以使用任意默认符号选项修改预定义符号的笔触或填充。

标记

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

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

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

标记为可交互式。例如在默认情况下,标记可接收 'click' 事件,且通常用于在事件监听器打开信息窗口。将某个标记的 draggable 属性设为 true 可使该标记在地图上供用户修改。

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

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

  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 地图图钉图标)。在这种情况下,Google Maps API 会自动调整图标的大小。

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

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

  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 度夹角(向右上方倾斜),并且阴影图片的左下角应与图标图片的左下角对齐。阴影图片应该采用具有 alpha 透明度的 24 位 PNG 图片,以便图片边界可正确显示在地图上。

MarkerImage 对象不仅可定义图片,还可定义图标的 size 和 origin(例如,如果您所需的图片是较大的拼合图片的一部分),以及应用于定位图标热点的 anchor(基于原点)。

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

function initialize() {
  var mapOptions = {
    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"),
                                mapOptions);

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

矢量图标

标记支持光栅图片和矢量路径的显示,称为 Symbols。要显示矢量路径,请将带有所需路径的 Symbol 对象常量传递到标记的 icon 属性。您可以使用 google.maps.SymbolPath 中预定义的某个路径,也可以使用 SVG 路径表示法定义自定义路径。

有关 Google Maps JavaScript API 中矢量图片的详情,请参阅关于符号的文档。

以下示例介绍了如何使用某个预定义的矢量路径创建图标。有关更详细的示例,请参阅关于符号的文档。

marker = new google.maps.Marker({
  position: new google.maps.LatLng(-25.363882, 131.044922),
  icon: {
    path: google.maps.SymbolPath.CIRCLE,
    scale: 10
  },
  draggable: true,
  map: map
});

折线

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

折线选项

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

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

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

此外,折线的 editable 属性用于定义此形状是否在地图上为用户可修改的。

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


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

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);
  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

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

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


var poly;
var map;

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

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

  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)

折线上的符号

您可以采用符号的形式将基于矢量的图片添加到折线。要在折线上显示符号,请设置 PolylineOptions 对象的 icons[] 属性。icons[] 数组采用一个或多个 IconSequence 对象常量,定义如下:

  • icon必填),表示要在线上呈现的图标。要详细了解如何自定义符号,请参阅关于符号的文档。
  • offset,表示与要呈现图标所在的线起点的距离。此距离可表示为线长度的百分比(例如“50%”)或像素(例如“50 像素”)。默认值为“100%”。
  • repeat,表示线上连续图标之间的距离。此距离可表示为线长度的百分比(例如“50%”)或像素(例如“50 像素”)。要停用重复图标,请将距离指定为“0”。默认值为“0”。

如果您的折线是测地线,那么对于偏移和重复所指定的距离在默认情况下均以米为单位来计算。如果将偏移或重复设为像素值,就会按屏幕上的像素来计算距离。

借助符号与 PolylineOptions 类的组合,您可以对地图上折线的外观进行充分的控制。下面是您可以应用的一些自定义示例。

JS演示

箭头

使用 IconSequence.offset 属性可对折线的起点或终点添加箭头。在此示例中,将偏移设为 100% 可在线的终点放置箭头。

var lineCoordinates = [
  new google.maps.LatLng(22.291, 153.027),
  new google.maps.LatLng(18.291, 153.027)
];

var lineSymbol = {
  path: google.maps.SymbolPath.FORWARD_CLOSED_ARROW
};

var line = new google.maps.Polyline({
  path: lineCoordinates,
  icons: [{
    icon: lineSymbol,
    offset: '100%'
  }],
  map: map
});
JS演示

虚线

您可以将折线的透明度设为 0%,然后按有规律间隔绘制不透明的符号,从而实现虚线效果。

var lineCoordinates = [
  new google.maps.LatLng(22.291, 153.027),
  new google.maps.LatLng(18.291, 153.027)
];

var lineSymbol = {
  path: 'M 0,-1 0,1',
  strokeOpacity: 1,
  scale: 4
};

var line = new google.maps.Polyline({
  path: lineCoordinates,
  strokeOpacity: 0,
  icons: [{
    icon: lineSymbol,
    offset: '0',
    repeat: '20px'
  }],
  map: map
});
JS演示

自定义路径

自定义符号可让您向折线添加多种不同的形状。

var lineCoordinates = [
  new google.maps.LatLng(22.291, 153.027),
  new google.maps.LatLng(18.291, 153.027)
];

var symbolOne = {
  path: 'M -2,0 0,-2 2,0 0,2 z',
  strokeColor: '#F00',
  fillColor: '#F00',
  fillOpacity: 1
};

var symbolTwo = {
  path: 'M -2,-2 2,2 M 2,-2 -2,2',
  strokeColor: '#292',
  strokeWeight: 4
};

var symbolThree = {
  path: 'M -1,0 A 1,1 0 0 0 -3,0 1,1 0 0 0 -1,0M 1,0 A 1,1 0 0 0 3,0 1,1 0 0 0 1,0M -3,3 Q 0,5 3,3',
  strokeColor: '#00F',
  rotation: 0
};

var line = new google.maps.Polyline({
  path: lineCoordinates,
  icons: [{
    icon: symbolOne,
    offset: '0%'
    },{
      icon: symbolTwo,
      offset: '50%'
    },{
      icon: symbolThree,
      offset: '100%'
    }
  ],
  map: map
});
JS演示

为符号添加动画效果

您可以使用 setTimeout() 函数按固定的间隔更改符号的偏移,从而为其添加动画效果。

var line;

function initialize() {
  var mapOptions = {
    center: new google.maps.LatLng(20.291, 153.027),
    zoom: 6,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  
  var map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);
      
  var lineCoordinates = [
    new google.maps.LatLng(22.291, 153.027),
    new google.maps.LatLng(18.291, 153.027)
  ];

  var lineSymbol = {
    path: google.maps.SymbolPath.CIRCLE,
    scale: 8,
    strokeColor: '#393'
  };

  line = new google.maps.Polyline({
    path: lineCoordinates,
    icons: [{
      icon: lineSymbol,
      offset: '100%'
    }],
    map: map
  });
}

function animateCircle() {
    var count = 0;
    offsetId = window.setInterval(function() {
      count = (count + 1) % 200;

      var icons = line.get('icons');
      icons[0].offset = (count / 2) + '%';
      line.set('icons', icons);
  }, 20);
}

多边形

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

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

多边形选项

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

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

不过,对于仅包含一条路径的简单多边形,为方便起见,您可以使用一组 LatLng 坐标来构造 Polygon。在构造完成并将此简单数组存储到 Polygon 的 paths 属性中后,Google Maps API 会将其转换为“一组数组”。此外,该 API 还提供了简单的 getPath() 方法以构造仅包含一条路径的简单多边形。

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

此外,多边形的 editable 属性用于定义此形状是否在地图上为用户可修改的。

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


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

  var bermudaTriangle;

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

  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 包含四个坐标,不过请注意,其中第一个坐标和最后一个坐标的位置相同,从而定义了一个环路。不过,实际上由于多边形定义的就是封闭区域,因此无需定义这最后一个坐标。对于任意给定路径,Maps API 将通过绘制连接最后一个坐标与第一个坐标的笔触来自动“封闭”任何多边形。

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

查看示例 (polygon-autoclose.html)

多边形数组

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

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

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

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


var map;
var infoWindow;

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

  var bermudaTriangle;

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

  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 = "Bermuda Triangle Polygon
"
;   contentString += "Clicked Location:
"
+ event.latLng.lat() + "," + event.latLng.lng() + "
"
;   // Iterate over the vertices.   for (var i =0; i < vertices.length; i++) {     var xy = vertices.getAt(i);     contentString += "
"
+ "Coordinate: " + i + "
"
+ 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,用于指定圆形的半径(以米为单位)。

此外,圆形的 editable 属性用于定义此形状是否在地图上为用户可修改的。

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


// 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 属性:

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

此外,矩形的 editable 属性用于定义此形状是否在地图上为用户可修改的。

以下示例针对任何 'zoom_changed' 事件分别根据前一个视口创建了矩形:


function initialize() {

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

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

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

  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)

用户可修改的形状

您可将任何形状的叠加层(折线、多边形、圆形和矩形)设为用户可修改,方法是在形状选项中将 editable 设为 true

要将标记设为可拖动,请在标记选项中将 draggable 设为 true

var circleOptions = {
  center: new google.maps.LatLng(-34.397, 150.644),
  radius: 25000,
  map: map,
  editable: true
};
var circle = new google.maps.Circle(circleOptions);

将某种形状的叠加层设为可修改会增加对该形状的处理,从而允许用户直接在地图上对其进行重新定位、形状调整和/或大小调整。

查看示例 (user-editable-shapes.html)

用户在某个会话中针对对象所作出的更改不会适用于其他会话。如果您想要保存针对折线所作出的修改,请务必自行捕获并存储相关信息。

修改事件

如果对形状进行了修改,那么系统会在修改完毕后触发相关事件。下面列出了这些事件。

形状 事件
圆形 radius_changed
center_changed
多边形 insert_at
remove_at
set_at

监听器必须设置在多边形的路径上。如果多边形有多条路径,那么每条路径上都应设置监听器。

折线 insert_at
remove_at
set_at

监听器必须设置在折线的路径上。

矩形 bounds_changed
google.maps.event.addListener(circle, 'radius_changed', function() {
  radius = circle.getRadius();
});

google.maps.event.addListener(outerPath, 'set_at', function() {
  print('Vertex moved on outer path.');
});

google.maps.event.addListener(innerPath, 'insert_at', function() {
  print('Vertex removed from inner path.');
});

绘图库

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

http://maps.googleapis.com/maps/api/js?sensor=false&libraries=drawing 

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

DrawingManager 类提供了一个图形界面,以供用户在地图上绘制多边形、矩形、折线、圆形和标记。DrawingManager 对象以如下方式创建:

var drawingManager = new google.maps.drawing.DrawingManager();
drawingManager.setMap(map);

DrawingManager 选项

DrawingManager 构造函数采用一组选项,以定义要显示的控件集、控件的位置以及初始绘图状态。

  • DrawingManager 的 drawingMode 属性用于定义 DrawingManager 的初始绘图状态。该属性接受 google.maps.drawing.OverlayType 常量,且默认为 null(在此情况下启动 DrawingManager 时,光标会处于非绘图模式)。
  • DrawingManager 的 drawingControl 属性用于定义地图上的绘图工具选择界面的可见性。该属性接受布尔值。
  • 您还可以使用 DrawingManager 的 drawingControlOptions 属性,定义控件的位置以及控件中应表示的叠加层的类型。
    • position 用于定义绘图控件在地图上的位置,且接受 google.maps.ControlPosition 常量。
    • drawingModes 是一组 google.maps.drawing.OverlayType 常量,且用于定义绘图控件形状选择器中包含的叠加层类型。系统将始终显示手形图标,以便用户无需绘图即可与地图进行交互。
  • 您可为每种叠加层类型都指定一组默认属性,以便定义首次创建相应叠加层时所采用的外观。这些属性可在叠加层的 {overlay}Options 属性(其中 {overlay} 表示叠加层的类型)中进行定义。例如,圆形的填充属性、笔触属性、zIndex 和可点击性可使用 circleOptions 属性进行定义。如果已传递任何大小、位置或地图值,则系统会忽略这些默认属性。有关哪些属性可设置的完整详情,请参阅 API 参考文档。

    提示:要在创建形状后将其设为用户可修改,请将其 editable 属性设为 true

var drawingManager = new google.maps.drawing.DrawingManager({
  drawingMode: google.maps.drawing.OverlayType.MARKER,
  drawingControl: true,
  drawingControlOptions: {
    position: google.maps.ControlPosition.TOP_CENTER,
    drawingModes: [google.maps.drawing.OverlayType.MARKER, google.maps.drawing.OverlayType.CIRCLE]
  },
  markerOptions: {
    icon: new google.maps.MarkerImage('http://www.example.com/icon.png')
  },
  circleOptions: {
    fillColor: '#ffff00',
    fillOpacity: 1,
    strokeWeight: 5,
    clickable: false,
    zIndex: 1,
    editable: true
  }
});
drawingManager.setMap(map);

查看示例 (drawing-tools.html)

更新绘图工具控件

创建 DrawingManager 对象后,您可调用 setOptions() 并传递新的值,以进行更新。

drawingManager.setOptions({
  drawingControlOptions: {
    position: google.maps.ControlPosition.BOTTOM_LEFT,
    drawingModes: [google.maps.drawing.OverlayType.MARKER]
  }
});

使用以下方法即可隐藏或显示绘图工具控件:

// To hide:
drawingManager.setOptions({
  drawingControl: false
});

// To show:
drawingManager.setOptions({
  drawingControl: true
});

要从 map 对象删除绘图工具控件,请使用以下方法:

drawingManager.setMap(null);

隐藏绘图控件会导致绘图工具控件无法显示,不过 DrawingManager 类的所有功能仍然可用。这样即可实现您自己的控件(如有必要)。从 map 对象删除 DrawingManager 会导致所有绘图功能停用;要恢复绘图地图项,请务必使用 drawingManager.setMap(map) 将 DrawingManager 对象重新附加到地图,或者构造新的该对象。

绘图事件

创建形状叠加层后,会触发以下两个事件:

  • {overlay}complete 事件(其中 {overlay} 代表叠加层类型,例如 circlecompletepolygoncomplete 等)。对相应叠加层的引用会作为参数进行传递。
  • overlaycomplete 事件。包含 OverlayType 和对相应叠加层的引用的对象常量会作为参数进行传递。
google.maps.event.addListener(drawingManager, 'circlecomplete', function(circle) {
  var radius = circle.getRadius();
});

google.maps.event.addListener(drawingManager, 'overlaycomplete', function(event) {
  if (event.type == google.maps.drawing.OverlayType.CIRCLE) {
    var radius = event.overlay.getRadius();
  }
});

信息窗口

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

InfoWindow 构造函数采用 InfoWindow options 对象,以指定一组关于信息窗口的显示方式的初始参数。创建完毕后,所生成的信息窗口不会添加到地图上。要显示该信息窗口,您需要对 InfoWindow 调用 open() 方法,并向其传递要在其上打开信息窗口的 Map,以及用于锚定该信息窗口的 Marker(可选)。(如果未提供任何标记,则会在该信息窗口的position 属性处将其打开。)

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

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

InfoWindow 的内容可以是文本字符串、HTML 代码段,也可以就是 DOM 元素。要设置此内容,请在 InfoWindow options 构造函数中传递该内容,或者对信息窗口显式调用setContent()。要显式调整内容的大小,您可以使用 

 进行调整,或者启用滚动功能(如果您希望的话)。请注意,如果您没有启用滚动功能,且内容的大小又超出了信息窗口的可用空间,那么内容可能会从信息窗口中“溢”出。

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

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

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

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

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

var contentString = '
'+     '
'+     '
'
+     '

Uluru

'
+     '
'+     '

Uluru, also referred to as Ayers Rock, 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.

'
+     '

Attribution: Uluru, '+     'http://en.wikipedia.org/w/index.php?title=Uluru (last visited June 22, 2009).

'
+     '
'
+     '
'
; 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)

地面叠加层

多边形在表示不规则的区域时很有用,但不能显示图片。要在地图上放置一张图片,请使用 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 mapOptions = {
  zoom: 13,
  center: newark,
  mapTypeId: google.maps.MapTypeId.ROADMAP
}

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

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

查看示例 (groundoverlay-simple.html)

自定义叠加层

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

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

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

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

叠加层的子类化

我们将会使用 OverlayView 创建简单的图片叠加层(类似于 V2 API 中的 GGroundOverlay)。我们将创建一个 USGSOverlay 对象,其中包含了相关区域的 USGS 图片以及该图片的边界。

var overlay;

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

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

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

接下来,我们将创建一个该类的构造函数,并将已传递的参数初始化为新对象的属性。此外,我们还需要显式地将 OverlayView 中的 USGSOverlay 子类化。为此,我们会将新类的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() 方法将其添加到地图。在处理此方法时,我们会创建一个用于存储图片的 

,然后添加一个  元素并将其附加到 
,最后将叠加层附加到地图的一个“窗格”(即 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,并计算对象的右上角和左下角锚定点的准确坐标,从而重新调整 

 的大小;同时,此操作还可重新调整图片的大小,以使其与我们在叠加层的构造函数中所指定的范围相匹配。

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() 方法添加到叠加层的原型,以切换容器 

 的可见性。此外,我们还添加了 toogleDOM() 方法,该方法可将叠加层附加到地图,或将两者分离开来。请注意,如果我们将可见性设为 "hidden",那么系统会通过 toggleDOM() 将地图与 DOM 分离;如果我们稍后重新附加了地图,那么叠加层会再次显示出来,这是因为我们利用叠加层的 onAdd() 方法重新创建了其中所包含的 

// Note that the visibility property must be a string enclosed in quotes
USGSOverlay.prototype.hide = function() {
  if (this.div_) {
    this.div_.style.visibility = "hidden";
  }
}

USGSOverlay.prototype.show = function() {
  if (this.div_) {
    this.div_.style.visibility = "visible";
  }
}

USGSOverlay.prototype.toggle = function() {
  if (this.div_) {
    if (this.div_.style.visibility == "hidden") {
      this.show();
    } else {
      this.hide();
    }
  }
}

USGSOverlay.prototype.toggleDOM = function() {
  if (this.getMap()) {
    this.setMap(null);
  } else {
    this.setMap(this.map_);
  }
}
// Now we add an input button to initiate the toggle method
// on the specific overlay
 id ="toolbar" width="100%; height:20px;" style="text-align:center">
   type="button" value="Toggle Visibility" onclick="overlay.toggle();">
   type="button" value="Toggle DOM Attachment" onclick="overlay.toggleDOM();">
id="map_canvas" style="width: 100%; height: 95%;">

你可能感兴趣的:(WebGIS)