简体   繁体   中英

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> 

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM