google-maps-api-3

on Google maps, how to have infowindow come up for different circles that are layered on top of one another but are different radii?


I have a map with a form above it. The user enters an address and the map places four circles of various radii around that address. I want the user to be able to click each of the circles and get an infowindow saying what the radius of that circle is. I can get this to work on the outermost circle (the biggest one), but for the smaller circles inside it, nothing happens. Why is this happening and what can I do please?

$( "#fAddress" ).on( "submit", function( event ) {
          event.preventDefault();
        
         geocoder = new google.maps.Geocoder();

          user_address = $("#address").val(); 
          geocoder.geocode({ address: user_address }, (results, status) => {
            if (status === "OK") {
             
              map.setCenter(results[0].geometry.location);
                
                
                const radCircle3 = new google.maps.Circle({
                  strokeColor: "#000000",
                  strokeOpacity: 0.8,
                  strokeWeight: 2,
                  fillColor: "#0000ff",
                  fillOpacity: 0.35,
                  map: map,
                  center: results[0].geometry.location,
                  content: "2,500 feet",
                  clickable: true,
                  radius: .3048 * 2500 //meters
                });
                
                const infoWindow = new google.maps.InfoWindow();
                google.maps.event.addListener(radCircle3, 'click', function(ev){ //works
                    infoWindow.setPosition(ev.latLng);
                    infoWindow.setContent("2,500 feet");
                    infoWindow.open(map);
                });
                
                const radCircle1 = new google.maps.Circle({
                  strokeColor: "#000000",
                  strokeOpacity: 0.8,
                  strokeWeight: 2,
                  fillColor: "#0000ff",
                  fillOpacity: 0.35,
                  map: map,
                  clickable: true,
                  center: results[0].geometry.location,
                  radius: .3048 * 500 //meters
                });
                
                google.maps.event.addListener(radCircle1, 'click', function(ev){
                    //infoWindow.open(map); //nothing happens
                    alert("500 feet"); //nothing happens
                });
                
                
                
                const radCircle2 = new google.maps.Circle({
                  strokeColor: "#000000",
                  strokeOpacity: 0.8,
                  strokeWeight: 2,
                  fillColor: "#0000ff",
                  fillOpacity: 0.35,
                  map,
                  center: results[0].geometry.location,
                  radius: .3048 * 1000 //meters
                });
                
                
                
                const radCircle4 = new google.maps.Circle({
                  strokeColor: "#000000",
                  strokeOpacity: 0.8,
                  strokeWeight: 2,
                  fillColor: "#0000ff",
                  fillOpacity: 0.35,
                  map,
                  center: results[0].geometry.location,
                  radius: .3048 * 750 //meters
                });

            } else {
             
              console.error("Geocode was not successful for the following reason: " + status);
            }
          });
        });
     
    

Solution

  • One option is to stack the circles in size order with the biggest on the bottom (added to the map first).

    const radCircle3 = new google.maps.Circle({
       ...
       radius: 0.3048 * 2500, //meters
    })
    
    const radCircle2 = new google.maps.Circle({
       ...
       radius: 0.3048 * 1000, //meters
    })
    
    const radCircle4 = new google.maps.Circle({
       ...
       radius: 0.3048 * 750, //meters
    })
    
    const radCircle1 = new google.maps.Circle({
       ...
       radius: 0.3048 * 500, //meters
    })
    

    proof of concept fiddle

    image of working map image of working map

    code snippet:

    let map
    let marker
    let geocoder
    let responseDiv
    let response
    
    function initMap() {
      map = new google.maps.Map(document.getElementById("map"), {
        zoom: 15,
        center: { lat: -34.397, lng: 150.644 },
        mapTypeControl: false,
      })
      geocoder = new google.maps.Geocoder()
    
      geocoder.geocode({ address: "New York, New York" }, (results, status) => {
        if (status === "OK") {
          map.setCenter(results[0].geometry.location)
    
          const radCircle3 = new google.maps.Circle({
            strokeColor: "#000000",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: "#0000ff",
            fillOpacity: 0.35,
            map: map,
            center: results[0].geometry.location,
            content: "2,500 feet",
            radius: 0.3048 * 2500, //meters
          })
    
          const infoWindow = new google.maps.InfoWindow();
          function addInfoWindow(circle) {
             google.maps.event.addListener(circle, "click", function (ev) {
               infoWindow.setPosition(ev.latLng)
               infoWindow.setContent(circle.content)
               infoWindow.open(map)
             })
          }
          addInfoWindow(radCircle3);
          const radCircle2 = new google.maps.Circle({
            strokeColor: "#000000",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: "#0000ff",
            fillOpacity: 0.35,
            map,
            center: results[0].geometry.location,
            content: "1,000 feet",
            radius: 0.3048 * 1000, //meters
          })
          addInfoWindow(radCircle2);
          const radCircle4 = new google.maps.Circle({
            strokeColor: "#000000",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: "#0000ff",
            fillOpacity: 0.35,
            map,
            center: results[0].geometry.location,
            content: "750 feet",
            radius: 0.3048 * 750, //meters
          })
          addInfoWindow(radCircle4);
          const radCircle1 = new google.maps.Circle({
            strokeColor: "#000000",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: "#0000ff",
            fillOpacity: 0.35,
            map: map,
            center: results[0].geometry.location,
            content: "500 feet",
            radius: 0.3048 * 500, //meters
          })
          addInfoWindow(radCircle1);
    
    } else {
          console.error(
            "Geocode was not successful for the following reason: " + status,
          )
        }
      })
    }
    
    window.initMap = initMap
    #map {
      height: 100%;
    }
    
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    <!doctype html>
    <html>
    
    <head>
      <title>Geocoding Service</title>
    
    </head>
    
    <body>
      <div id="map"></div>
    
      <!-- 
          The `defer` attribute causes the script to execute after the full HTML
          document has been parsed. For non-blocking uses, avoiding race conditions,
          and consistent behavior across browsers, consider loading using Promises. See
          https://developers.google.com/maps/documentation/javascript/load-maps-js-api
          for more information.
          -->
      <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&v=weekly" defer></script>
    </body>
    
    </html>

    Another option would be to add a "zIndex" property to each circle in the order you want them stacked (lowest zIndex on the bottom/biggest circle, highest zIndex on the top/smallest circle):

    const radCircle3 = new google.maps.Circle({
       ...
       zIndex: 0,
       radius: .3048 * 2500 //meters
    });
    
    const radCircle1 = new google.maps.Circle({
       ...
       zIndex: 3,
       radius: .3048 * 500 //meters
    });
    
    const radCircle2 = new google.maps.Circle({
       zIndex: 1,
       radius: .3048 * 1000 //meters
    });
    
    const radCircle4 = new google.maps.Circle({
       ... 
       zIndex: 2,
       radius: .3048 * 750 //meters
    });
    
    

    zIndex code snippet:

    let map
    let marker
    let geocoder
    let responseDiv
    let response
    
    function initMap() {
      map = new google.maps.Map(document.getElementById("map"), {
        zoom: 15,
        center: {
          lat: -34.397,
          lng: 150.644
        },
        mapTypeControl: false,
      })
      geocoder = new google.maps.Geocoder()
    
      geocoder.geocode({
        address: "New York, New York"
      }, (results, status) => {
        if (status === "OK") {
          map.setCenter(results[0].geometry.location)
    
          const radCircle3 = new google.maps.Circle({
            strokeColor: "#000000",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: "#0000ff",
            fillOpacity: 0.35,
            map: map,
            zIndex: 0,
            center: results[0].geometry.location,
            content: "2,500 feet",
            radius: .3048 * 2500 //meters
          });
    
          const radCircle1 = new google.maps.Circle({
            strokeColor: "#000000",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: "#0000ff",
            fillOpacity: 0.35,
            map: map,
            zIndex: 3,
            center: results[0].geometry.location,
            radius: .3048 * 500 //meters
          });
    
          const radCircle2 = new google.maps.Circle({
            strokeColor: "#000000",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: "#0000ff",
            fillOpacity: 0.35,
            map,
            zIndex: 1,
            center: results[0].geometry.location,
            radius: .3048 * 1000 //meters
          });
    
          const radCircle4 = new google.maps.Circle({
            strokeColor: "#000000",
            strokeOpacity: 0.8,
            strokeWeight: 2,
            fillColor: "#0000ff",
            fillOpacity: 0.35,
            map,
            zIndex: 2,
            center: results[0].geometry.location,
            radius: .3048 * 750 //meters
          });
    
    
          const infoWindow = new google.maps.InfoWindow()
          google.maps.event.addListener(radCircle3, "click", function(ev) {
            //works
            infoWindow.setPosition(ev.latLng)
            infoWindow.setContent("radCircle3 2,500 feet")
            infoWindow.open(map)
          })
          google.maps.event.addListener(radCircle2, "click", function(ev) {
            //works
            infoWindow.setPosition(ev.latLng)
            infoWindow.setContent("radCircle3 1000 feet")
            infoWindow.open(map)
          })
          google.maps.event.addListener(radCircle4, "click", function(ev) {
            //works
            infoWindow.setPosition(ev.latLng)
            infoWindow.setContent("radCircle4 750 feet")
            infoWindow.open(map)
          })
          google.maps.event.addListener(radCircle1, "click", function(ev) {
            //works
            infoWindow.setPosition(ev.latLng)
            infoWindow.setContent("radCircle1 500 feet")
            infoWindow.open(map)
          })
    
    
        } else {
          console.error(
            "Geocode was not successful for the following reason: " + status,
          )
        }
      })
    }
    
    window.initMap = initMap
    #map {
      height: 100%;
    }
    
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    <!doctype html>
    <html>
    
    <head>
      <title>Geocoding Service</title>
    
    </head>
    
    <body>
      <div id="map"></div>
    
      <!-- 
          The `defer` attribute causes the script to execute after the full HTML
          document has been parsed. For non-blocking uses, avoiding race conditions,
          and consistent behavior across browsers, consider loading using Promises. See
          https://developers.google.com/maps/documentation/javascript/load-maps-js-api
          for more information.
          -->
      <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&v=weekly" defer></script>
    </body>
    
    </html>