Pete171 Pete171 - 3 months ago 59
Javascript Question

Google Maps Unoptimized Marker / fitBounds

I'm writing acceptance tests using Selenium to test an application that uses the Google Maps API. In order to test the map marker placement I'm using un-optimized markers and unique title attributes to allow me to target the marker elements (from Selenium with XPath queries).

I have come across an issue wherein calling google.maps.Map.fitBounds() causes markers to be removed from the DOM when un-optimized markers are used. You have to repeatedly call fitBounds() for this to happen. This only happens with un-optimized markers and the application itself works as expected.

I've written a short test script to replicate in the browser: please run the below.

I did also create a fiddle.

I've seen nothing pertinent in the API docs.

Any help would be great.

<html>
<head>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js"></script>
<style type="text/css">
#container {
width: 800px;
height:500px;
}
</style>
</head>
<body>
<button id="show">Show</button>
<button id="hide">Hide</button>
<div id="container"></div>
<script type="text/javascript">

// Repeatedly click on 'Hide' then 'Show' (8+ times sometimes). At some point the markers disappear and not come back - even if the code for showing/hiding markers is entirely commented out.
// The issue seems to be with the map.fitBounds() call when un-optimized markers are being used.
// Note - un-optimized markers are needed for targeting marker HTML elements as part of an acceptance test.
// Replicated on: 45.0.2 Firefox; 49.0.2623.112 m Chrome.

function changeBounds(boolToggle) {
//return; // TODO - if you add this line in the problem is fixed.
var bounds = new google.maps.LatLngBounds();
var latLng = boolToggle ? new google.maps.LatLng(70, 70) : new google.maps.LatLng(30, 30);
bounds.extend(marker1.getPosition());
bounds.extend(marker2.getPosition());
bounds.extend(latLng);
map.fitBounds(bounds);
}

var mapOptions = {
center : { lat : 50, lng : 50 },
zoom: 5,
};

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

var marker1 = new google.maps.Marker({
position : {
lat : 51,
lng : 51,
},
title : "MARK1",
optimized : false
});

var marker2 = new google.maps.Marker({
position : {
lat : 52,
lng : 52,
},
title : "MARK2",
optimized : false
});

marker1.setMap(map);
marker2.setMap(map);

document.getElementById('show').onclick = function() {
//marker1.setVisible(true); // TODO - The original code was showing/hiding the markers but the issue is replicated without even doing this.
//marker2.setVisible(true);

changeBounds(true);
}

document.getElementById('hide').onclick = function() {
//marker1.setVisible(false); // TODO - The original code was showing/hiding the markers but the issue is replicated without even doing this.
//marker2.setVisible(false);

changeBounds(false);
}
</script>
</body>
</html>


Edit: I've reported this as a bug with Google. See https://code.google.com/p/gmaps-api-issues/issues/detail?id=9912

Answer

I don't know what the problem is, it must be some issue in the Google Maps API, but I have found a solution: use the pan* methods. The best one, for me, was using panBy, which says to the map to pan by x and y pixels. Moving 0 pixels worked fine, so just adding map.panBy(0,0) after fitBounds fixed the vanishing markers.

However, that means losing the nice gradual moving of the map, so instead I used panBy on the idle event. The final solution was to add the following after the creation of the map:

google.maps.event.addListener(map, 'idle', function() {
    map.panBy(0,0);
});

I am sorry, but I don't have enough time to sift through the Google APIs to actually see what the problem is.

What didn't work:

  • marker.setMap (or any other property)
  • making marker draggable or not
  • google.maps.event.trigger(map, 'some_event');

Related: