2

We have been given the following code to show a specific Google Maps API infoWindow when the map is opened:

https://jsfiddle.net/e26qyzxm/

The thing is that the zoom level was hard-coded in the code to:

map.setZoom(16);

that works fine when using the sample markers as shown.

However, we need the zoom level to be dynamically set so when real-world markers are loaded from the backend, the zoom level is set to just above the level at which the marker would be out of its cluster if any. Otherwise, that zoom level of 16 may be too low and the infoWindow may not show because the specific marker is still in a cluster.

Can anyone suggest an amendment to the code to do that?

Map

HTML:

<div id="map"></div>
 <!-- Replace the value of the key parameter with your own API key. -->
<script src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js"></script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>

CSS:

#map {
  height: 100%;
}

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}

Javascript:

var MrkId = 62440;
var markersC = [];
var markersA = [];
var infowindow;
var map;
var markerCluster;

var points = [
  ['Point 1', 'adresse 1 ', 46.613317, 2.249830, 62437],
  ['Point 2', 'adresse 2 ', 46.713317, 2.249830, 62438],
  ['Point 3', 'adresse 3 ', 46.613317, 2.349830, 62439],
  ['Point 4', 'adresse 4 ', 46.713317, 2.449830, 62440],
  ['Point 5', 'adresse 5 ', 46.613317, 2.449830, 62441],
  ['Point 1', 'adresse 1 ', 46.413317, 2.249830, 62442],
  ['Point 2', 'adresse 2 ', 46.513317, 2.249830, 62443],
  ['Point 3', 'adresse 3 ', 46.513317, 2.349830, 62444],
  ['Point 4', 'adresse 4 ', 46.413317, 2.449830, 62445],
  ['Point 5', 'adresse 5 ', 46.513317, 2.449830, 62446],
];

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {
      lat: 46.613317,
      lng: 2.349830
    },
    zoom: 9
  });

  infowindow = new google.maps.InfoWindow();
  setMarkers();
}

function MkrClick(Mrk, Cnt, point) {
  var contentString = '<div class="marker-infowindow">' + '<h2>' + point[0] + '</h1>' + '<div><a target="_blank" href="https://tutoandco.colas-delmas.fr/developpement/inserer-carte-google-maps-wordpress/?utm_source=jsfiddle&utm_medium=website">Voir le tuto complet</a></div></div>';

  Mrk.addListener('click', function() {
    infowindow.setContent(Cnt);
    infowindow.open(map, Mrk);

  });
}

function setMarkers() {
  console.log("setMarkers")
  for (var i = 0; i < points.length; i++) {
    var point = points[i];
    var contentString = '<div class="marker-infowindow">' + '<h2>' + point[0] + '</h1>' + '<div><a target="_blank" href="https://tutoandco.colas-delmas.fr/developpement/inserer-carte-google-maps-wordpress/?utm_source=jsfiddle&utm_medium=website">Voir le tuto complet</a></div></div>';

    var marker = new google.maps.Marker({
      position: {
        lat: point[2],
        lng: point[3]
      },
      map: map,
      title: point[0],
      loc_id: point[4],
      loc_txt: contentString,
    });
    markersA.push(marker);
    markersC.push(marker);
    MkrClick(marker, contentString, point);

    if (i == (points.length - 1)) {
      // Add a marker clusterer to manage the markers.
      markerCluster = new MarkerClusterer(map, markersC, {
        imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
      });
      if (MrkId != 0) {
        ShowInfo(MrkId)
        if (MrkId * 1 == point[4] * 1) {
          console.log("MrkId=" + MrkId);       
        }
      }
    }
  }
}

function ShowInfo(MrkIdSel) {

  var IdxFound = -1;
  for (var a = 0; a < markersC.length; a++) {

    var McLoc = markersC[a].loc_id;
    var McLocA = markersA[a].loc_id;

    if (McLoc == MrkIdSel) {
      IdxFound = a;

      a = (markersC.length - 1)

    }

    if (a == (markersC.length - 1)) {
      var bounds = new google.maps.LatLngBounds(markersC[IdxFound].position);
      map.fitBounds(bounds);
      setTimeout(function() {
        map.setZoom(16);
        google.maps.event.trigger(markersA[IdxFound], "click", {});
      }, 125);
    }
  }
}

function isMarkerClustered(Marker) {
  var clusters = markerCluster.clusters_;
  var Pos = 0;
  console.log("isMarkerClustered clusters.length=" + clusters.length)
  for (var i = 0; i < clusters.length; i++) {
    var Cmarkers = clusters[i].getMarkers();
    for (var m = 0; m < Cmarkers.length; m++) {
      if (Cmarkers[m] === Marker) {
        Pos = clusters[i].getCenter()
      }

      if (i == (clusters.length - 1)) {
        if (m == (Cmarkers.length - 1)) {

          if (Pos != 0) {
            Pos = Marker.position
          }

          var Info2 = new google.maps.InfoWindow({
            //position: markersC[a].position,
            position: Pos,
            content: Marker.loc_txt,
          }).open(map);
        }
      }
    }
  }
}

UPDATE 1:

I guess an alternative would be to turn off clustering and hard code the zoom to say 16. Then if the user zooms out, hide the infoWindow and re-enable the clustering. If anyone can suggest an amendment to the code to do that I'd be appreciative.

Yrll
  • 1,619
  • 2
  • 5
  • 19
user1946932
  • 474
  • 1
  • 16
  • 41
  • 2
    Please provide a [mcve] that exhibits the issue you are trying to fix (provide sample data that exhibits the issue). – geocodezip Nov 17 '21 at 02:33
  • @geocodezip Simply changing the zoom level to 9 or less on line 98 of the JavaScript in https://jsfiddle.net/e26qyzxm/ illustrates that behaviour—namely the marker in question is hidden inside a cluster. Change it to a number above that, and it is not hidden. – user1946932 Nov 17 '21 at 07:41

2 Answers2

2

After you perform the load, having the locations for the markers, you can use bounds.extend and map.fitBounds so the map automatically zooms to show all the pins returned by your backend, like this:

//markers is an array that contains the loaded result
var bounds = new google.maps.LatLngBounds();
for (var i = 0, marker; marker = markers[i]; i++) {
  //pass the location of each marker to bounds.extend
  bounds.extend(marker.geometry.location);
}
//tell your map to sets the viewport to contain all the markers.
map.fitBounds(bounds);

If you just want to load a zone by zip code, for example, using the geocoder, you can also use map.fitBounds to set the viewport to show the entire specific zone that was returned by the geocoder, like this:

//response is the geocoder's response
map.fitBounds(response[0].geometry.viewport);

Another solution could be:

    var geoCoder = new GClientGeocoder();
    geoCoder.setViewport(map.getBounds());
    geoCoder.getLocations('searchquery', function(latlng) {
      if( latlng.Placemark.length > 0 ) {
        var box = latlng.Placemark[0].ExtendedData.LatLonBox;
        var bounds = new GLatLngBounds(new GLatLng(box.south, box.west), new GLatLng(box.north, box.east));
        var center = new GLatLng(box.Placemark[0].Point.coordinates[1], latlng.Placemark[0].Point.coordinates[0]);
        var zoom = oMap.getBoundsZoomLevel(bounds);
        map.setCenter(center, zoom);
      }
    })
Raymond
  • 550
  • 1
  • 5
  • 14
  • Your second example is Google Maps Javascript API v2 code, that API was deprecated on May 19, 2010 and shut down on May 26, 2021. – geocodezip Nov 18 '21 at 17:03
  • @Raymond Thanks but does that address the clustering as mentioned? – user1946932 Nov 18 '21 at 19:44
  • @Raymond I think basically we just want to determine (get) the lowest zoom level (1-20) at which the specific given marker is not clustered. – user1946932 Nov 18 '21 at 20:52
  • 1
    @user1946932 is almost the same working principle. You can also look at this question and perhaps combining this knowledge you can develop the specific solution for your problem. https://stackoverflow.com/questions/21487686/how-to-know-zoom-level-to-display-a-marker-inside-google-marker-cluster – Raymond Nov 19 '21 at 07:48
0

I would use the following js code https://jsfiddle.net/r15h2jy7/1/

var MrkId = 62440;
var markersC = [];
var markersA = [];
var infowindow;
var map;
var markerCluster;

var points = [
  ['Point 1', 'adresse 1 ', 46.613317, 2.249830, 62437],
  ['Point 2', 'adresse 2 ', 46.713317, 2.249830, 62438],
  ['Point 3', 'adresse 3 ', 46.613317, 2.349830, 62439],
  ['Point 4', 'adresse 4 ', 46.713317, 2.449830, 62440],
  ['Point 5', 'adresse 5 ', 46.613317, 2.449830, 62441],
  ['Point 1', 'adresse 1 ', 46.413317, 2.249830, 62442],
  ['Point 2', 'adresse 2 ', 46.513317, 2.249830, 62443],
  ['Point 3', 'adresse 3 ', 46.513317, 2.349830, 62444],
  ['Point 4', 'adresse 4 ', 46.413317, 2.449830, 62445],
  ['Point 5', 'adresse 5 ', 46.513317, 2.449830, 62446],
];

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {

//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  minZoom: 0,
  maxZoom: 1,
      restriction: {
    latLngBounds: {
      north: 46.713317,
      south: 46.413317,
      east: 2.449830,
      west: 2.249830,
    },
  },
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
  });

  infowindow = new google.maps.InfoWindow();
  setMarkers();
}

function MkrClick(Mrk, Cnt, point) {
  var contentString = '<div class="marker-infowindow">' + '<h2>' + point[0] + '</h1>' + '<div><a target="_blank" href="https://tutoandco.colas-delmas.fr/developpement/inserer-carte-google-maps-wordpress/?utm_source=jsfiddle&utm_medium=website">Voir le tuto complet</a></div></div>';

  Mrk.addListener('click', function() {
    infowindow.setContent(Cnt);
    infowindow.open(map, Mrk);

  });
}

function setMarkers() {
  console.log("setMarkers")
  for (var i = 0; i < points.length; i++) {
    var point = points[i];
    var contentString = '<div class="marker-infowindow">' + '<h2>' + point[0] + '</h1>' + '<div><a target="_blank" href="https://tutoandco.colas-delmas.fr/developpement/inserer-carte-google-maps-wordpress/?utm_source=jsfiddle&utm_medium=website">Voir le tuto complet</a></div></div>';

    var marker = new google.maps.Marker({
      position: {
        lat: point[2],
        lng: point[3]
      },
      map: map,
      title: point[0],
      loc_id: point[4],
      loc_txt: contentString,
    });
    markersA.push(marker);
    markersC.push(marker);
    MkrClick(marker, contentString, point);

    if (i == (points.length - 1)) {
      // Add a marker clusterer to manage the markers.
      markerCluster = new MarkerClusterer(map, markersC, {
        imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
      });
      if (MrkId != 0) {
        ShowInfo(MrkId)
        if (MrkId * 1 == point[4] * 1) {
          console.log("MrkId=" + MrkId);       
        }
      }
    }
  }
}

function ShowInfo(MrkIdSel) {

  var IdxFound = -1;
  for (var a = 0; a < markersC.length; a++) {

    var McLoc = markersC[a].loc_id;
    var McLocA = markersA[a].loc_id;

    if (McLoc == MrkIdSel) {
      IdxFound = a;

      a = (markersC.length - 1)

    }

    if (a == (markersC.length - 1)) {
      var bounds = new google.maps.LatLngBounds(markersC[IdxFound].position);
      map.fitBounds(bounds);
      setTimeout(function() {
        map.setZoom(16);
        google.maps.event.trigger(markersA[IdxFound], "click", {});
      }, 125);
    }
  }
}

function isMarkerClustered(Marker) {
  var clusters = markerCluster.clusters_;
  var Pos = 0;
  console.log("isMarkerClustered clusters.length=" + clusters.length)
  for (var i = 0; i < clusters.length; i++) {
    var Cmarkers = clusters[i].getMarkers();
    for (var m = 0; m < Cmarkers.length; m++) {
      if (Cmarkers[m] === Marker) {
        Pos = clusters[i].getCenter()
      }

      if (i == (clusters.length - 1)) {
        if (m == (Cmarkers.length - 1)) {

          if (Pos != 0) {
            Pos = Marker.position
          }

          var Info2 = new google.maps.InfoWindow({
            //position: markersC[a].position,
            position: Pos,
            content: Marker.loc_txt,
          }).open(map);
        }
      }
    }
  }
}
user16930239
  • 6,319
  • 2
  • 9
  • 33