Google将API放置在地图上放置多个标记,并缩放到大多数标记所在的位置

时间:2017-05-02 14:01:08

标签: javascript arrays google-maps-api-3 google-places-api

首先,我想向您展示我已经尝试过的解决方案,所以你们不要使用它们:

  1. placing multiple markers on google map from array
  2. placing multiple markers on a google map
  3. 因为我在这些地方有以下循环:

    service.textSearch({query:query}, function(results, status) {
        if (status == google.maps.places.PlacesServiceStatus.OK) {
            //for each result in results.length ++
            for (var i = 0; i < results.length; i++) {
                //here I'm just setting the names from the variables into a list, to display the names as I show in (Figure 1).
                var item = document.createElement('li');
                item.appendChild(document.createTextNode(results[i].name));
                document.getElementById('results').appendChild(item);
    
                //here I set my variables that are necessary for the markers to work
                p_id[i] = results[i].place_id;
    
                lat[i] = results[i].geometry.location.lat();
                lng[i] = results[i].geometry.location.lng();
    
                //here I initialize the map with the given values.
                initMap(p_id, lat, lng, i);
            }
        }
    });
    

    图1: Figure 1

    当这个循环完成时,它会转到将标记放在地图上的位置。

    注意:我不想再次摆脱它所创造的places,因为它对我来说非常有用,而且它没有&似乎阻碍了我的努力。

    关于地图上的标记放置器:

    function initMap(p_id, lat, lng, i) {
        //this creates the position of the map
        var map = new google.maps.Map(document.getElementById('map'), {
            center: {lat: lat[i], lng: lng[i]},
            zoom: 13
        });
    
        var infowindow = new google.maps.InfoWindow(), marker, i;
        var service = new google.maps.places.PlacesService(map);
    
        var marker;
    
        //gets the details of the placeid over again
        service.getDetails({
            placeId: p_id[i]
        }, function(place, status) {
            if (status === google.maps.places.PlacesServiceStatus.OK) {
    
                //this is where the marker is created with position and animation
                marker = new google.maps.Marker({
                    animation: google.maps.Animation.DROP,
                    position: new google.maps.LatLng(lat[i], lng[i]),
                    map: map
                });
    
                //this is the info if you click the marker
                google.maps.event.addListener(marker, 'click', (function(marker, i) {
                    return function() {
                        infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + 'Place ID: ' + place.place_id + '<br>' + place.formatted_address + '</div>');
                        infowindow.open(map, marker);
                    }
                })(marker, i));
            }
        });
    }
    

    奇怪的是,如果只有1个地方,则显示1个标记,但是当它们有更多的地方时,则根本没有标记......正如我在图2中所示

    图2: Figure 2

    如果有人有任何解决方法的线索,请告诉他们。我似乎无法想象自己,尽管我已经寻找了一段时间。我试图制作一个Jsfiddle,但遗憾的是API无法在jsfddle上运行......

    编辑:

    SeanKendle解决了多标记问题。问题就像我已经怀疑我一直在创建多个地图......

    我只是将maps移出我的mapinit函数,并将其放在service函数的getPlaces上方,如下所示:

    var map = new google.maps.Map(document.getElementById('map'), {
        center: latlng,
        zoom: 5
    });
    
    service = new google.maps.places.PlacesService(
      document.getElementById('attributions') //attributions-container
    );
    
    //send a query
    service.textSearch({query:query}, function(results, status) {
        if (status == google.maps.places.PlacesServiceStatus.OK) {
            for (var i = 0; i < results.length; i++) {
                var item = document.createElement('li');
                item.appendChild(document.createTextNode(results[i].name));
                document.getElementById('results').appendChild(item);
    
                p_id[i] = results[i].place_id;
    
                lat[i] = results[i].geometry.location.lat();
                lng[i] = results[i].geometry.location.lng();
    
                initMap(p_id, lat, lng, i, map);
            }
        }
    });
    

    现在我面临的最后一个问题是我需要放大标记最多的地方。现在我只需设置lat和long它应该从哪里开始:

    var latlng = new google.maps.LatLng(20.540221, -4.042969);
    

    已提前感谢!

1 个答案:

答案 0 :(得分:2)

请仔细阅读我的评论。我可能错过了一些事情,我在工作中急于这样做。我已经简化了很多代码并删除了一些额外的服务调用等。

编辑:我添加了地图边界变量,以便在放置标记后设置地图缩放和中心

编辑2:我添加了一个Google地图回调函数,以消除让您无法访问google命名空间的竞争条件。请务必替换YOUR_API_KEY

首先,将实际的地图初始化移出循环:

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

<script>
    var startLatLng, //change this to some value near to where the map will end up
        allMarkers = [], //keep a global copy of your markers
        mapPointsBounds = [], //map bounds of all markers
        map; //copy of the map

    //Google will call this when it's ready, it's a query string in the script tag above `&callback=initMap`:
    function initMap() {
        startLatLng = new google.maps.LatLng([0, 0]);
        mapPointsBounds = new google.maps.LatLngBounds();

        map = new google.maps.Map(document.getElementById('map'), {
            center: startLatLng,
            zoom: 13
        });

        service.textSearch({query:query}, function(results, status) {
            if (status == google.maps.places.PlacesServiceStatus.OK) {
                //for each result in results.length ++
                for (var i = 0; i < results.length; i++) {
                    //here I'm just setting the names from the variables into a list, to display the names as I show in (Figure 1).
                    var item = document.createElement('li');
                    item.appendChild(document.createTextNode(results[i].name));
                    document.getElementById('results').appendChild(item);

                    //let's just send the object, this is unnecessary:
                    //here I set my variables that are necessary for the markers to work
                    //p_id[i] = results[i].place_id;
                    //lat[i] = results[i].geometry.location.lat();
                    //lng[i] = results[i].geometry.location.lng();

                    //Change this function name to "addMapMarker", send in the results object
                    addMapMarker(results[i], i);
                }

                //finally, fitBounds on map to set zoom and center:
                map.fitBounds(mapPointsBounds);
            }
        });
    }

    //I would change the name of this function to "addMapMarker" or something similar
    function addMapMarker(markerInfo, i) {
        //why are you initializing "i" again if you're passing it in?
        var infowindow = new google.maps.InfoWindow(), marker; //, i;
        var service = new google.maps.places.PlacesService(map);

        var marker;

        //gets the details of the placeid over again - why?  Why not send the info into the function?
        /* Is this really necessary again?
        service.getDetails({
            placeId: markerInfo.place_id
        }, function(place, status) {
            if (status === google.maps.places.PlacesServiceStatus.OK) {
        */
        //this is where the marker is created with position and animation
        marker = new google.maps.Marker({
            animation: google.maps.Animation.DROP,
            position: markerInfo.geometry.location,
            map: map,
            markerInfo: markerInfo //you can store anything in the map point
        });

        allMarkers.push(marker); //keeping all markers in an array
        mapPointsBounds.extend(markerInfo.geometry.location); //extend bounds to contain this marker


        //this is the info if you click the marker
        //you're running a function, then returning a function... just put a simple function here:
        google.maps.event.addListener(marker, 'click', function (marker, i) {
            //return function() {
            infowindow.setContent('<div><strong>' + marker.markerInfo.name + '</strong><br>' + 'Place ID: ' + marker.markerInfo.place_id + '<br>' + marker.markerInfo.formatted_address + '</div>');
            infowindow.open(map, marker);
            //}
        });
    }
</script>