谷歌Maps Api相当新。我有一个数据数组,我想循环遍历并在地图上绘制。看似相当简单,但我发现的所有多标记教程都相当复杂。

让我们以谷歌网站的数据数组为例:

var locations = [
  ['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]
];

我只是想绘制所有这些点,并在单击时弹出一个infoWindow来显示名称。


当前回答

下面是一个几乎完整的示例javascript函数,它允许在JSONObject中定义多个标记。

它将只显示在地图边界内的标记。

这很重要,这样你就不用做额外的工作了。

你也可以设置一个标记的限制,这样你就不会显示一个极端数量的标记(如果有可能在你的使用);

如果地图中心的变化不超过500米,就不会显示标记。 这很重要,因为如果用户单击标记并在此过程中意外地拖动了地图,您不希望地图重新加载标记。

我将这个函数附加到地图的空闲事件侦听器,因此标记只在地图空闲时显示,并在不同的事件后重新显示标记。

活动屏幕截图 在信息窗口中显示更多内容的屏幕截图有一个小变化。 粘贴自pastbin.com

<script src=“//pastebin.com/embed_js/uWAbRxfg”></script>

其他回答

当前地图标记和聚类算法修改后的最新最简单算法:

修改地址:https://developers.google.com/maps/documentation/javascript/marker-clustering

<!DOCTYPE Html>
<html>
<head>
<meta Content-Security-Policy="default-src  'self'; script-src 'self' 'unsafe-eval' https://*/;">
<link type="text/css" href="http://www.mapsmarker.com/wp-content/uploads/leaflet-maps-marker-icons/bar_coktail.png">
<link rel="icon" href="data:,">
<title>App</title>
</head>
<style type="text/css">
   #map {
    height: 500
}
</style>

<body>
<div id='map' style="width:100%; height:400px"></div>
<script type='text/javascript'>
    function initMap() {
        maps = new google.maps.Map(document.getElementById('map'), {
            center: new google.maps.LatLng(12.9824855, 77.637094),
            zoom: 5,
            disableDefaultUI: false,
            mapTypeId: google.maps.MapTypeId.HYBRID
        });
        var labels='ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        var markerImage = 'http://www.mapsmarker.com/wp-content/uploads/leaflet-maps-marker-icons/bar_coktail.png';
        marker = locations.map(function (location, i) {
            return new google.maps.Marker({
                position: new google.maps.LatLng(location.lat, location.lng),
                map: maps,
                title: "Map",
                label: labels[i % labels.length],
                icon: markerImage
            });
        });

        var markerCluster = new MarkerClusterer(maps, marker, {
            imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
        });
    }
    var locations = [
            { lat: 12.9824855, lng: 77.637094},
            { lat: 11.9824855, lng: 77.154312 },
            { lat: 12.8824855, lng: 77.637094},
            { lat: 10.8824855, lng: 77.054312 },
            { lat: 12.9824855, lng: 77.637094},
            { lat: 11.9824855, lng: 77.154312 },
            { lat: 12.8824855, lng: 77.637094},
            { lat: 13.8824855, lng: 77.054312 },
            { lat: 14.9824855, lng: 54.637094},
            { lat: 15.9824855, lng: 54.154312 },
            { lat: 16.8824855, lng: 53.637094},
            { lat: 17.8824855, lng: 52.054312 },
            { lat: 18.9824855, lng: 51.637094},
            { lat: 19.9824855, lng: 69.154312 },
            { lat: 20.8824855, lng: 68.637094},
            { lat: 21.8824855, lng: 67.054312 },
            { lat: 12.9824855, lng: 76.637094},
            { lat: 11.9824855, lng: 75.154312 },
            { lat: 12.8824855, lng: 74.637094},
            { lat: 10.8824855, lng: 74.054312 },
            { lat: 12.9824855, lng: 73.637094},
            { lat: 3.9824855, lng: 72.154312 },
            { lat: 2.8824855, lng: 71.637094},
            { lat: 1.8824855, lng: 70.054312 }
        ];

</script>
<script src="https://unpkg.com/@google/markerclustererplus@4.0.1/dist/markerclustererplus.min.js">
</script>
<script src="https:maps.googleapis.com/maps/api/js?key=AIzaSyDWu6_Io9xA1oerfOxE77YAv31etN4u3Dw&callback=initMap">
</script>
<script type='text/javascript'></script>

在程序中添加标记非常简单。你只需要添加以下代码:

var marker = new google.maps.Marker({
  position: myLatLng,
  map: map,
  title: 'Hello World!'
});

当你构造一个标记时,下面的字段是特别重要和经常设置的:

position(必选)指定标识标记初始位置的LatLng。检索LatLng的一种方法是使用地理编码服务。 map(可选)指定放置标记的map。如果在构建标记时没有指定映射,则会创建标记,但不会附加到(或显示在)映射上。稍后可以通过调用标记的setMap()方法添加标记。

注意,在本例中,标题字段设置了将作为工具提示显示的标记标题。

您可以在这里查阅谷歌api文档。


这是在地图中设置一个标记的完整示例。注意,你必须用你的谷歌API密钥替换YOUR_API_KEY:

<!DOCTYPE html>
<html>
<head>
   <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
   <meta charset="utf-8">
   <title>Simple markers</title>
<style>
  /* Always set the map height explicitly to define the size of the div
   * element that contains the map. */
  #map {
    height: 100%;
  }
  /* Optional: Makes the sample page fill the window. */
  html, body {
    height: 100%;
    margin: 0;
    padding: 0;
  }
</style>
</head>
<body>
 <div id="map"></div>
<script>

  function initMap() {
    var myLatLng = {lat: -25.363, lng: 131.044};

    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 4,
      center: myLatLng
    });

    var marker = new google.maps.Marker({
      position: myLatLng,
      map: map,
      title: 'Hello World!'
    });
  }
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>


现在,如果你想在map中绘制数组的标记,你应该这样做:

var locations = [
  ['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 initMap() {
  var myLatLng = {lat: -33.90, lng: 151.16};

  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: myLatLng
    });

  var count;

  for (count = 0; count < locations.length; count++) {  
    new google.maps.Marker({
      position: new google.maps.LatLng(locations[count][1], locations[count][2]),
      map: map,
      title: locations[count][0]
      });
   }
}

这个例子给出了如下结果:


你也可以在你的pin中添加一个infoWindow。你只需要这段代码:

var marker = new google.maps.Marker({
    position: new google.maps.LatLng(locations[count][1], locations[count][2]),
    map: map
    });

marker.info = new google.maps.InfoWindow({
    content: 'Hello World!'
    });

你可以在这里找到谷歌关于infoWindows的文档。


现在,我们可以在标记像这样“点击”时打开infoWindow:

var marker = new google.maps.Marker({
     position: new google.maps.LatLng(locations[count][1], locations[count][2]),
     map: map
     });

marker.info = new google.maps.InfoWindow({
     content: locations [count][0]
     });


google.maps.event.addListener(marker, 'click', function() {  
    // this = marker
    var marker_map = this.getMap();
    this.info.open(marker_map, this);
    // Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
            });

注意,您可以在谷歌developer中获得一些关于Listener的文档。


最后,如果用户点击它,我们可以在标记中绘制一个infoWindow。这是我的完整代码:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Info windows</title>
    <style>
    /* Always set the map height explicitly to define the size of the div
    * element that contains the map. */
    #map {
        height: 100%;
    }
    /* Optional: Makes the sample page fill the window. */
    html, body {
        height: 100%;
        margin: 0;
        padding: 0;
    }
    </style>
</head>
<body>
    <div id="map"></div>
    <script>

    var locations = [
        ['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]
    ];


    // When the user clicks the marker, an info window opens.

    function initMap() {
        var myLatLng = {lat: -33.90, lng: 151.16};

        var map = new google.maps.Map(document.getElementById('map'), {
            zoom: 10,
            center: myLatLng
            });

        var count=0;


        for (count = 0; count < locations.length; count++) {  

            var marker = new google.maps.Marker({
                position: new google.maps.LatLng(locations[count][1], locations[count][2]),
                map: map
                });

            marker.info = new google.maps.InfoWindow({
                content: locations [count][0]
                });


            google.maps.event.addListener(marker, 'click', function() {  
                // this = marker
                var marker_map = this.getMap();
                this.info.open(marker_map, this);
                // Note: If you call open() without passing a marker, the InfoWindow will use the position specified upon construction through the InfoWindowOptions object literal.
                });
        }
    }
    </script>
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
    </script>
</body>
</html>

通常,你会得到这样的结果:

下面是另一个使用唯一标题和infoWindow文本加载多个标记的示例。使用最新的谷歌映射API V3.11进行测试。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <title>Multiple Markers Google Maps</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <script
      src="https://maps.googleapis.com/maps/api/js?v=3.11&sensor=false"
      type="text/javascript"
    ></script>
    <script type="text/javascript">
      // check DOM Ready
      $(document).ready(function () {
        // execute
        (function () {
          // map options
          var options = {
            zoom: 5,
            center: new google.maps.LatLng(39.909736, -98.522109), // centered US
            mapTypeId: google.maps.MapTypeId.TERRAIN,
            mapTypeControl: false,
          };

          // init map
          var map = new google.maps.Map(
            document.getElementById('map_canvas'),
            options
          );

          // NY and CA sample Lat / Lng
          var southWest = new google.maps.LatLng(40.744656, -74.005966);
          var northEast = new google.maps.LatLng(34.052234, -118.243685);
          var lngSpan = northEast.lng() - southWest.lng();
          var latSpan = northEast.lat() - southWest.lat();

          // set multiple marker
          for (var i = 0; i < 250; i++) {
            // init markers
            var marker = new google.maps.Marker({
              position: new google.maps.LatLng(
                southWest.lat() + latSpan * Math.random(),
                southWest.lng() + lngSpan * Math.random()
              ),
              map: map,
              title: 'Click Me ' + i,
            });

            // process multiple info windows
            (function (marker, i) {
              // add click event
              google.maps.event.addListener(marker, 'click', function () {
                infowindow = new google.maps.InfoWindow({
                  content: 'Hello, World!!',
                });
                infowindow.open(map, marker);
              });
            })(marker, i);
          }
        })();
      });
    </script>
  </head>
  <body>
    <div id="map_canvas" style="width: 800px; height: 500px"></div>
  </body>
</html>

250个标记的截图:

它将自动随机化Lat/Lng,使其独一无二。如果你想测试500、1000、xxx标记和性能,这个例子将非常有用。

下面是一个Reactjs中多个标记的例子。

下面是映射组件

import React from 'react';
import PropTypes from 'prop-types';
import { Map, InfoWindow, Marker, GoogleApiWrapper } from 'google-maps-react';

const MapContainer = (props) => {
  const [mapConfigurations, setMapConfigurations] = useState({
    showingInfoWindow: false,
    activeMarker: {},
    selectedPlace: {}
  });

  var points = [
    { lat: 42.02, lng: -77.01 },
    { lat: 42.03, lng: -77.02 },
    { lat: 41.03, lng: -77.04 },
    { lat: 42.05, lng: -77.02 }
  ]
  const onMarkerClick = (newProps, marker) => {};

  if (!props.google) {
    return <div>Loading...</div>;
  }

  return (
    <div className="custom-map-container">
      <Map
        style={{
          minWidth: '200px',
          minHeight: '140px',
          width: '100%',
          height: '100%',
          position: 'relative'
        }}
        initialCenter={{
          lat: 42.39,
          lng: -72.52
        }}
        google={props.google}
        zoom={16}
      >
        {points.map(coordinates => (
          <Marker
            position={{ lat: coordinates.lat, lng: coordinates.lng }}
            onClick={onMarkerClick}
            icon={{
              url: 'https://res.cloudinary.com/mybukka/image/upload/c_scale,r_50,w_30,h_30/v1580550858/yaiwq492u1lwuy2lb9ua.png',
            anchor: new google.maps.Point(32, 32), // eslint-disable-line
            scaledSize: new google.maps.Size(30, 30)  // eslint-disable-line
            }}
            name={name}
          />))}
        <InfoWindow
          marker={mapConfigurations.activeMarker}
          visible={mapConfigurations.showingInfoWindow}
        >
          <div>
            <h1>{mapConfigurations.selectedPlace.name}</h1>
          </div>
        </InfoWindow>
      </Map>
    </div>
  );
};

export default GoogleApiWrapper({
  apiKey: process.env.GOOGLE_API_KEY,
  v: '3'
})(MapContainer);

MapContainer.propTypes = {
  google: PropTypes.shape({}).isRequired,
};

异步版本:

<script type="text/javascript">
  function initialize() {
    var locations = [
      ['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]
    ];

    var map = new google.maps.Map(document.getElementById('map'), {
      zoom: 10,
      center: new google.maps.LatLng(-33.92, 151.25),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

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

    var marker, i;

    for (i = 0; i < locations.length; i++) {  
      marker = new google.maps.Marker({
        position: new google.maps.LatLng(locations[i][1], locations[i][2]),
        map: map
      });

      google.maps.event.addListener(marker, 'click', (function(marker, i) {
        return function() {
          infowindow.setContent(locations[i][0]);
          infowindow.open(map, marker);
        }
      })(marker, i));
    }
}

function loadScript() {
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&' +
      'callback=initialize';
  document.body.appendChild(script);
}

window.onload = loadScript;
  </script>