Google 地图 API 的多个多边形数组

Multiple polygon arrays with the Google Maps API

我正在按照 example 使用 Google 地图 API 创建多边形阵列。我想创建多个多边形,当您单击它们时,每个多边形都有不同的名称。在下面的代码中,我希望在您单击第一个三角形时将其命名为 "name 1",在单击它时将第二个三角形命名为 "name 2"。我试图这样做,但当您单击它们时,它们都被称为 "name 2"。我究竟做错了什么?谢谢!

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Polygon Arrays</title>
    <style>
      html, body, #map-canvas {
        height: 100%;
        margin: 0px;
        padding: 0px
      }
    </style>
    <script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
    <script>
// This example creates a simple polygon representing the Bermuda Triangle.
// When the user clicks on the polygon an info window opens, showing
// information about the polygon's coordinates.

var map;
var infoWindow;
var name;

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

  var bermudaTriangle;

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

  // Define the LatLng coordinates for the polygon.
  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)
  ];

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

  name = 'name 1';

  bermudaTriangle.setMap(map);

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

  infoWindow = new google.maps.InfoWindow();

  var triangleCoords = [
      new google.maps.LatLng(40.774252, -95.190262),
      new google.maps.LatLng(33.466465, -81.118292),
      new google.maps.LatLng(47.321384, -79.75737)
  ];

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

  name = 'name 2';

  bermudaTriangle.setMap(map);

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

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

/** @this {google.maps.Polygon} */
function showArrays(event) {

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

  var contentString = '<b>' + name + '</b><br>' +
      'Clicked location: <br>' + event.latLng.lat() + ',' + event.latLng.lng() +
      '<br>';

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

  // Replace the info window's content and position.
  infoWindow.setContent(contentString);
  infoWindow.setPosition(event.latLng);

  infoWindow.open(map);
}

google.maps.event.addDomListener(window, 'load', initialize);

    </script>
  </head>
  <body>
    <div id="map-canvas"></div>
  </body>
</html>

问题

您基本上遇到了 variable scope 的问题,我将强调我遇到的两个问题。

首先,您要在应用程序的顶部声明 name 变量,并设置它的值两次。第二次,当它设置为 "name 2" 时,它覆盖了 "name 1" 的初始值。这正是您正在做的..

var name;
name = "name 1";
name = "name 2"; // this second assignment overwrote the assignment above it

我希望这样看是有意义的。

其次,您还以完全相同的方式覆盖了 bermudaTriangle 变量,只是您的应用程序的性质不会导致您看到任何错误。

一个解决方案

如果我修复了您的代码的 Javascript 部分并进行了一些额外的改进,它看起来像下面的内容(here's a jsfiddle 以查看它的实际效果)。一些注意事项:

1) 因为我认为它更简洁,所以我将 pathsmap 属性移到 JS 语句中以初始化您的两个多边形。

2) 我将 name 从您正在实例化然后覆盖的应用程序级变量更改为直接属于多边形对象本身的可选 属性,然后我设置了该值在多边形声明中。

For clarity I wanted to keep the same property name you originally used. Although, to avoid unintended collisions with undocumented properties, it's better practice to give any dynamic/custom properties you create a unique prefix and use that same prefix across your application. With that in mind, name should probably be something more like x_name, etc.

3) 我给你的第二个多边形指定了唯一的变量名称,otherTriangle

var map;
var infoWindow;

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

    // These are declared outside of the init function, so I
    // initialized them together at the top of the function..
    map = new google.maps.Map(document.getElementById('map-canvas'),
    mapOptions);

    infoWindow = new google.maps.InfoWindow();


    // Here's where your data begines. I moved the 1) API-supported paths object, 
    // 2) the API-supported map object, *AND* 3) the dynamic name value inside 
    // the Polygon object declarations.. this makes "name" a property of the object.
    var bermudaTriangle = new google.maps.Polygon({
        paths: [
        new google.maps.LatLng(25.774252, -80.190262),
        new google.maps.LatLng(18.466465, -66.118292),
        new google.maps.LatLng(32.321384, -64.75737)],
        strokeColor: '#FF0000',
        strokeOpacity: 0.8,
        strokeWeight: 1,
        fillColor: '#FF0000',
        fillOpacity: 0.35,
        name: 'name 1', // dynamic, not an official API property..
        map: map
    });

    // Here's the behavior handler..
    google.maps.event.addListener(bermudaTriangle, 'click', showArrays);


    // This is a new, different object therefore we should instantiate it relative
    // to a new variable (i.e. a unique pointer). Once again I moved the paths, map,
    // and name properties inside the object declaration.
    var otherTriangle = new google.maps.Polygon({
        paths: [
        new google.maps.LatLng(40.774252, -95.190262),
        new google.maps.LatLng(33.466465, -81.118292),
        new google.maps.LatLng(47.321384, -79.75737)],
        strokeColor: '#008700',
        strokeOpacity: 0.8,
        strokeWeight: 1,
        fillColor: '#008700',
        fillOpacity: 0.35,
        name: 'name 2', // dynamic, not an official API property..
        map: map
    });

    // Aaaaand, the behavior..
    google.maps.event.addListener(otherTriangle, 'click', showArrays);

}

// The only differnece here is that I changed "name" to this.name,
// becuase "this" (the object that fired the event), now carries around 
// that "name" property we gave it..
function showArrays(event) {
    var vertices = this.getPath();

    var contentString = '<b>' + this.name + '</b><br>' +
        'Clicked location: <br>' + event.latLng.lat() + ',' + event.latLng.lng() +
        '<br>';

    for (var i = 0; i < vertices.getLength(); i++) {
        var xy = vertices.getAt(i);
        contentString += '<br>' + 'Coordinate ' + i + ':<br>' + xy.lat() + ',' + xy.lng();
    }

    infoWindow.setContent(contentString);
    infoWindow.setPosition(event.latLng);

    infoWindow.open(map);
}

google.maps.event.addDomListener(window, 'load', initialize);