谷歌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来显示名称。


当前回答

我知道这个答案太迟了。但我希望这也能帮助到其他开发者。: -) 下面的代码将使用信息窗口在谷歌地图上添加多个标记。 这段代码可以用来在地图上绘制任意数量的标记。 请将您的谷歌映射API键放在此代码的正确位置。(我已将其标记为“您的API密钥”)


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Google Map</title>
    <style>
        #map{
            height: 600px;
            width: 100%;
        }
    </style>
</head>
<body>

<h1>My Google Map`</h1>
<div id="map"></div>


    <script>
        function initMap(){
          //Map options
            var options = {
                zoom:9,
                center:{lat:42.3601, lng:-71.0589}
            }
            // new map
            var map = new google.maps.Map(document.getElementById('map'), options);
            // customer marker
            var iconBase = 'https://maps.google.com/mapfiles/kml/shapes/parking_lot_maps.png';
            //array of Marrkeers
            var markers = [
              {
                coords:{lat: 42.4668, lng: -70.9495},img:iconBase,con:'<h3> This Is your Content <h3>'
              },
              {
                coords:{lat: 42.8584, lng: -70.9300},img:iconBase,con:'<h3> This Is your Content <h3>'
              },
              {
                coords:{lat: 42.7762, lng: -71.0773},img:iconBase,con:'<h3> This Is your Content <h3>'
              }
            ];

            //loopthrough markers
            for(var i = 0; i <markers.length; i++){
              //add markeers
              addMarker(markers[i]);
            }

            //function for the plotting markers on the map
            function addMarker (props){
              var marker = new google.maps.Marker({
                position: props.coords,
                map:map,
                icon:props.img
              });
              var infoWindow = new google.maps.InfoWindow({
                content:props.con,
              });
              marker.addListener("click", () => {
                infoWindow.open(map, marker);
              });
            }
        }
    </script>

    <script
      src="https://maps.googleapis.com/maps/api/js?key=**YourAPIKey**&callback=initMap"
      defer
    ></script>

</body>
</html>

其他回答

来自谷歌Map API示例:

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 &lt;area&gt; 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]
    });
  }
}

var arr = new Array();
    function initialize() { 
        var i;  
        var Locations = [
                {
                  lat:48.856614, 
                  lon:2.3522219000000177, 
                  address:'Paris',
                  gval:'25.5',
                  aType:'Non-Commodity',
                  title:'Paris',
                  descr:'Paris'           
                },        
                    {
                  lat: 55.7512419, 
                  lon: 37.6184217,
                  address:'Moscow',
                  gval:'11.5',
                  aType:'Non-Commodity',
                  title:'Moscow',
                  descr:'Moscow Airport'              
                },     

                {
              lat:-9.481553000000002, 
              lon:147.190242, 
              address:'Port Moresby',
              gval:'1',
              aType:'Oil',
              title:'Papua New Guinea',
              descr:'Papua New Guinea 123123123'              
            },
            {
           lat:20.5200,
           lon:77.7500,
           address:'Indore',
            gval:'1',
            aType:'Oil',
            title:'Indore, India',
            descr:'Airport India'
        }
    ];

    var myOptions = {
        zoom: 2,
        center: new google.maps.LatLng(51.9000,8.4731),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

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

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

    for (i = 0; i < Locations.length; i++) {
            size=15;        
            var img=new google.maps.MarkerImage('marker.png',           
                new google.maps.Size(size, size),
                new google.maps.Point(0,0),
                new google.maps.Point(size/2, size/2)
           );

        var marker = new google.maps.Marker({
            map: map,
            title: Locations[i].title,
            position: new google.maps.LatLng(Locations[i].lat, Locations[i].lon),           
                icon: img
        });

        bindInfoWindow(marker, map, infowindow, "<p>" + Locations[i].descr + "</p>",Locations[i].title);  

    }

}

function bindInfoWindow(marker, map, infowindow, html, Ltitle) { 
    google.maps.event.addListener(marker, 'mouseover', function() {
            infowindow.setContent(html); 
            infowindow.open(map, marker); 

    });
    google.maps.event.addListener(marker, 'mouseout', function() {
        infowindow.close();

    }); 
} 

完整的工作示例。你可以复制,粘贴和使用。

下面是另一个使用唯一标题和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标记和性能,这个例子将非常有用。

这是我写的另一个版本来节省地图的空间,它将infowindow指针放在标记的实际纬度和长度上,而在显示infowindow时暂时隐藏标记。

它还取消了标准的“标记”分配,并加快了速度 通过直接将新标记分配给标记创建中的标记数组进行处理。但是请注意,标记和信息窗口都添加了额外的属性,所以这种方法有点不合常规……但那是我!

在这些信息窗口问题中从未提到,标准的信息窗口不是放在标记点的lat和lng上,而是放在标记图像的顶部。标记可见性必须隐藏,否则Maps API将再次将信息窗口锚推回标记图像的顶部。

对“标记”数组中的标记的引用在标记声明后立即创建,用于以后可能需要的任何额外处理任务(隐藏/显示,抓取坐标等)。这样就省去了将标记对象赋值给'marker'的额外步骤,然后将'marker'推到标记数组中…在我的书里有很多不必要的处理。

不管怎样,对信息窗口有不同的看法,希望它能帮助你了解和激励你。

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

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

      var num_markers = locations.length;
      for (var i = 0; i < num_markers; i++) {  
        markers[i] = new google.maps.Marker({
          position: {lat:locations[i][1], lng:locations[i][2]},
          map: map,
          html: locations[i][0],
          id: i,
        });

        google.maps.event.addListener(markers[i], 'click', function(){
          var infowindow = new google.maps.InfoWindow({
            id: this.id,
            content:this.html,
            position:this.getPosition()
          });
          google.maps.event.addListenerOnce(infowindow, 'closeclick', function(){
            markers[this.id].setVisible(true);
          });
          this.setVisible(false);
          infowindow.open(map);
        });
      }
    }

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

这是一个工作的JSFiddle

额外的注意 您将注意到在给定的谷歌示例数据中,'locations'数组中的第四个位置是一个数字。在这个例子中,你也可以使用这个值作为标记id来代替当前循环的值,这样…

var num_markers = locations.length;
for (var i = 0; i < num_markers; i++) {  
  markers[i] = new google.maps.Marker({
    position: {lat:locations[i][1], lng:locations[i][2]},
    map: map,
    html: locations[i][0],
    id: locations[i][3],
  });
};

下面是一个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,
};