Born2Discover
Born2Discover

Reputation: 143

How to restrict a Google Maps API V3 radius search only to the markers within the circle?

I found this demo which I am working with from geocodezip. When a user inputs a city or zip, etc., it populates a sidebar with the results in that specified radius. However, there are items being populated in the sidebar which are outside of the indicated radius. More interesting enough, the markers that are actually in the radius show up just fine in the shaded circle. The extra markers that show up in the sidebar are not marked on the map itself.

I am really confused on how to remove these outside markers from the sidebar without impacting the current functionality.

Thank you for any and all help.

<script type="text/javascript"> 
//<![CDATA[
      // this variable will collect the html which will eventually be placed in the side_bar 
      var side_bar_html = ""; 
    
      // arrays to hold copies of the markers and html used by the side_bar 
      // because the function closure trick doesnt work there 
      var gmarkers = []; 

     // global "map" variable
      var map = null;
      var circle = null;
      var geocoder = new google.maps.Geocoder();

// A function to create the marker and set up the event window function 
function createMarker(latlng, name, html) {
    var contentString = html;
    var marker = new google.maps.Marker({
        position: latlng,
        // map: map,
        title: name,
        //name: name,
        zIndex: Math.round(latlng.lat()*-100000)<<5
        });

    google.maps.event.addListener(marker, 'click', function() {
        infowindow.setContent(contentString); 
        infowindow.open(map,marker);
        });
    // save the info we need to use later for the side_bar
    gmarkers.push(marker);
    // add a line to the side_bar html
    side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '<\/a><br>';
}
 
// This function picks up the click and opens the corresponding info window
function myclick(i) {
  google.maps.event.trigger(gmarkers[i], "click");
}

function initialize() {
  // create the map
  var myOptions = {
    zoom: 8,
    center: new google.maps.LatLng(43.907787,-79.359741),
    mapTypeControl: true,
        scale: true,
        scaleControl: true,
    mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
    navigationControl: true,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }

  map = new google.maps.Map(document.getElementById("map_canvas"),
                                myOptions);
//  google.maps.event.addListener(map, 'bounds_changed', makeSidebar);
//  google.maps.event.addListener(map, 'center_changed', makeSidebar);

  google.maps.event.addListener(map, 'click', function() {
    infowindow.close();
  });

  // Read the data from example.xml
  downloadUrl("testxml.php", function(doc) {
    var xmlDoc = xmlParse(doc);
    var markers = xmlDoc.documentElement.getElementsByTagName("marker");
    for (var i = 0; i < markers.length; i++) {
      // obtain the attribues of each marker
      var lat = parseFloat(markers[i].getAttribute("lat"));
      var lng = parseFloat(markers[i].getAttribute("lng"));
      var point = new google.maps.LatLng(lat,lng);
      var st = markers[i].getAttribute("state");
      var loc = markers[i].getAttribute("name");      var html="<b>"+name+"</b><br>";
      // create the marker
      var marker = createMarker(point,loc+" "+st,html);
    }
    // put the assembled side_bar_html contents into the side_bar div
    document.getElementById("side_bar").innerHTML = side_bar_html;
  });
}

function makeSidebar() {
   side_bar_html = "";
   for (var i=0; i < gmarkers.length; i++){
     if (map.getBounds().contains(gmarkers[i].getPosition())) {
       // add a line to the side_bar html
       side_bar_html += '<a href="javascript:myclick(' + i + ')">' + gmarkers[i].title + '<\/a><br>';
     }
   }
   // put the assembled side_bar_html contents into the side_bar div
   document.getElementById("side_bar").innerHTML = side_bar_html;
}
        

      function codeAddress() {
        var address = document.getElementById('address').value;
        var radius = parseInt(document.getElementById('radius').value, 10)*1000;
        geocoder.geocode( { 'address': address}, function(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
            side_bar_html = "";
            map.setCenter(results[0].geometry.location);
            var searchCenter = results[0].geometry.location;
            /*
            var marker = new google.maps.Marker({
                map: map,
                position: results[0].geometry.location
            });
            */
            if (circle) circle.setMap(null);
            circle = new google.maps.Circle({center:searchCenter,
                                             radius: radius,
                                             fillOpacity: 0.15,
                                             fillColor: "#FF0000",
                                             map: map});
            var bounds = new google.maps.LatLngBounds();
	    var foundMarkers = 0;
            for (var i=0; i<gmarkers.length;i++) {
              if (google.maps.geometry.spherical.computeDistanceBetween(gmarkers[i].getPosition(),searchCenter) < radius) {
                bounds.extend(gmarkers[i].getPosition())
                gmarkers[i].setMap(map);
                // add a line to the side_bar html
                side_bar_html += '<a href="javascript:myclick(' + i + ')">' + gmarkers[i].title + '<\/a><br>';
		foundMarkers++;
              } else {
                gmarkers[i].setMap(null);
              }
            }
            // put the assembled side_bar_html contents into the side_bar div
            document.getElementById("side_bar").innerHTML = side_bar_html;
            if (foundMarkers > 0) {
              map.fitBounds(bounds);
	    } else {
              map.fitBounds(circle.getBounds());
            }
            // makeSidebar();
            google.maps.event.addListenerOnce(map, 'bounds_changed', makeSidebar);

          } else {
            alert('Geocode was not successful for the following reason: ' + status);
          }
        });
      }
 
var infowindow = new google.maps.InfoWindow(
  { 
    size: new google.maps.Size(150,50)
  });
    

    // This Javascript is based on code provided by the
    // Community Church Javascript Team
    // http://www.bisphamchurch.org.uk/   
    // http://econym.org.uk/gmap/
    // from the v2 tutorial page at:
    // http://econym.org.uk/gmap/basic3.htm 
//]]>
</script> 

Upvotes: 1

Views: 2243

Answers (1)

geocodezip
geocodezip

Reputation: 161324

The sidebar is displaying the markers on the map bounds, rather than those in the circle:

Existing "makeSidebar":

function makeSidebar() {
   side_bar_html = "";
   for (var i=0; i < gmarkers.length; i++){
     if (map.getBounds().contains(gmarkers[i].getPosition())) {
       // add a line to the side_bar html
       side_bar_html += '<a href="javascript:myclick(' + i + ')">' + gmarkers[i].title + '<\/a><br>';
     }
   }
   // put the assembled side_bar_html contents into the side_bar div
   document.getElementById("side_bar").innerHTML = side_bar_html;
}

The code creates the correct sidebar in the codeAddress function then calls makeSidebar, which overwrites it. That code is:

// circle for display
circle = new google.maps.Circle({center:searchCenter,
                                 radius: radius,
                                 fillOpacity: 0.15,
                                 fillColor: "#FF0000",
                                 map: map});
var bounds = new google.maps.LatLngBounds();
var foundMarkers = 0;
for (var i=0; i<gmarkers.length;i++) {
  // if marker is in the circle, display it and add it to the sidebar
  if (google.maps.geometry.spherical.computeDistanceBetween(gmarkers[i].getPosition(),searchCenter) < radius) {
    bounds.extend(gmarkers[i].getPosition())
    // display it
    gmarkers[i].setMap(map);
    // add a line to the side_bar html
    side_bar_html += '<a href="javascript:myclick(' + i + ')">' + gmarkers[i].title + '<\/a><br>';
    foundMarkers++;
  } else {
    // hide the marker, it is outside the circle
    gmarkers[i].setMap(null);
  }
}
// put the assembled side_bar_html contents into the side_bar div
document.getElementById("side_bar").innerHTML = side_bar_html;

The sidebar is overwritten with the markers in bounds here:

google.maps.event.addListenerOnce(map, 'bounds_changed', makeSidebar);

Comment out that line. I did in the original example, which now works as you expect.

Upvotes: 1

Related Questions