首页 文章

谷歌 Map - 查找给定半径内的所有标记Javascript / Php

提问于
浏览
7

我有这个脚本,将在谷歌 Map 上显示自定义标记,但我想包括一个输入文本框,并能够输入一个城市/州和一个邮政编码,看看是否有任何标记,让我们说400距离该城市/州或邮政编码的里程数 . 我希望如果 Map 可以是动态的,那么当你输入城市/州或邮政编码时,它会通过删除所有其他标记并仅留下该半径范围内的标记来显示 Map 上的结果,如果那太难了,那么一个简单的改变框说单位是最接近的也将是OK :)我搜索并发现有人说我应该加载几何库并使用 computeDistanceBetween() 找到每个标记距离你的中心点的距离但是我不知道如何编写邮政编码部分或如何将所有这些放在一起工作 .

这是我的代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title></title>
<script type="text/javascript"  src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclustererplus/src/markerclusterer.js"></script>

<script type="text/javascript"> 
   var image = new google.maps.MarkerImage("marker-images/image.png",new google.maps.Size(40,35),new google.maps.Point(0,0),new google.maps.Point(20,35));

   var shadow = new google.maps.MarkerImage(
                            'marker-images/shadow.png',
                            new google.maps.Size(62,35),
                            new google.maps.Point(0,0),
                            new google.maps.Point(20,35)
                          );

   var shape = {
                coord: [27,0,30,1,32,2,34,3,35,4,36,5,38,6,39,7,39,8,39,9,39,10,38,11,37,12,33,13,34,14,34,15,33,16,32,17,31,18,27,19,28,20,28,21,27,22,26,23,22,25,23,26,24,27,24,28,24,29,24,30,24,31,24,32,23,33,22,34,17,34,16,33,15,32,15,31,14,30,14,29,15,28,15,27,16,26,17,25,13,23,12,22,11,21,11,20,12,19,8,18,7,17,6,16,5,15,5,14,6,13,2,12,1,11,0,10,0,9,0,8,0,7,1,6,3,5,4,4,5,3,7,2,9,1,12,0,27,0],
                type: 'poly'
          };

     // 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;

     //marker clusterer
     var mc;
     var mcOptions = {gridSize: 10, maxZoom: 8};

     //global infowindow
     var infowindow = new google.maps.InfoWindow();

     //geocoder
     var geocoder = new google.maps.Geocoder(); 
     var address = new Array("41.8119,-87.6873",
                        "40.7888,-74.056",
                        "41.8119,-87.6873",
                        "48.6681,-97.3627",
                        "44.9793,-93.273",
                        "39.4857,-75.6775",
                        "41.8119,-87.6873",
                        "42.0203,-87.9059",
                        "32.7812,-96.7903",
                        "27.5159,-99.4941",
                        "32.7812,-96.7903",
                        "37.5608,-95.6684",
                        "41.8119,-87.6873",
                        "38.3763,-97.6702",
                        "42.2458,-83.2491",
                        "41.8122,-91.9139",
                        "41.8397,-88.0887",
                        "41.8397,-88.0887",
                        "38.5128,-122.787",
                        "41.8397,-88.0887",
                        "42.8863,-87.892",
                        "42.8863,-87.892",
                        "30.7539,-83.3321",
                        "39.889,-84.2422",
                        "34.106,-83.589");
     var content = new Array("Unit No# 0206",
                        "Unit No# #2003",
                        "Unit No# 0176",
                        "Unit No# #2001",
                        "Unit No# 0124",
                        "Unit No# 0157",
                        "Unit No# #0162",
                        "Unit No# 0104",
                        "Unit No# 0118",
                        "Unit No# #2007",
                        "Unit No# 0112",
                        "Unit No# 0139",
                        "Unit No# 0205",
                        "Unit No# 0127",
                        "Unit No# 0187",
                        "Unit No# 0105",
                        "Unit No# 0214",
                        "Unit No# 0186",
                        "Unit No# 0173",
                        "Unit No# 0134",
                        "Unit No# 0128",
                        "Unit No# 0125",
                        "Unit No# 0158",
                        "Unit No# 0193",
                        "Unit No# 0201");

     //min and max limits for multiplier, for random numbers
     //keep the range pretty small, so markers are kept close by
     var min = .999999;
            var max = 1.000001;

    function createMarker(latlng,text) {
      var marker = new google.maps.Marker({
         draggable: false,
         raiseOnDrag: false,
         icon: image,
         shadow: shadow,
         shape: shape,
         position: latlng,
         map: map
       });

     ///get array of markers currently in cluster
     var allMarkers = mc.getMarkers();

     //check to see if any of the existing markers match the latlng of the new marker
      if (allMarkers.length != 0) {
        for (i=0; i < allMarkers.length; i++) {
          var existingMarker = allMarkers[i];
          var pos = existingMarker.getPosition();

          if (latlng.equals(pos)) {
            text = text + " & " + content[i];
          }                   
        }
      }

      google.maps.event.addListener(marker, 'click', function() {
        infowindow.close();
        infowindow.setContent(text);
        infowindow.open(map,marker);
      });
      mc.addMarker(marker);
      return marker;
    }
    function initialize(){
        var options = { 
            zoom: 4, 
            center: new google.maps.LatLng(39.8282,-98.5795), 
            mapTypeId: google.maps.MapTypeId.ROADMAP 
        };
        map = new google.maps.Map(document.getElementById('map'), options); 

    //marker cluster
        var gmarkers = [];
        mc = new MarkerClusterer(map, [], mcOptions);
        for (i=0; i<address.length; i++) {
           var ptStr = address[i];
           var coords = ptStr.split(",");
           var latlng = new google.maps.LatLng(parseFloat(coords[0]),parseFloat(coords[1]));
           gmarkers.push(createMarker(latlng,content[i]));
        }
    }

          function codeAddress() {
            var address = document.getElementById('address').value;
            var radius = parseInt(document.getElementById('radius').value, 10) * 1609.34;
            geocoder.geocode( { 'address': address}, function(results, status) {
              if (status == google.maps.GeocoderStatus.OK) {
                map.setCenter(results[0].geometry.location);
                var marker = new google.maps.Marker({
            //        map: map,  <-- uncomment to show red marker
                    position: results[0].geometry.location
                });
                if (circle) circle.setMap(null);
                circle = new google.maps.Circle({center:marker.getPosition(),
                                                 radius: radius,
                                                 fillOpacity: 0.35,
                                                 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(),marker.getPosition()) < radius) {
                    bounds.extend(gmarkers[i].getPosition())
                    gmarkers[i].setMap(map);
            foundMarkers++;
                  } else {
                    gmarkers[i].setMap(null);
                  }
                }
                if (foundMarkers > 0) {
                  map.fitBounds(bounds);
            } else {
                  map.fitBounds(circle.getBounds());
                }
              } else {
                alert(status);
              }
            });
          }

    var infowindow = new google.maps.InfoWindow(
      { 
        size: new google.maps.Size(150,50)
      });


    function handleKeyPress(e){
     var key=e.keyCode || e.which;
      if (key==13){
         codeAddress();
      }
    }

    function handleResetKeyPress(e){
        if (map.getZoom() != 4) map.setZoom(4);
          map.setCenter(new google.maps.LatLng(39.8282, -98.5795));
        document.getElementById("address").value = 'Enter City,State or Zipcode';
        document.getElementById("radius").value = '200';
    }
    </script> 

    <style>
    html, body, #map {
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
    }
    .auto-style1 {
        text-align: center;
    }
      #footer {
        position : absolute;
        bottom : 0;
        height : 40px;
        margin-top : 40px;
     /* border: 1px solid blue; */
      }
    </style>
    </head>
    <body onload='initialize()'>
    <div id="map"></div>
    <div id="footer" class="auto-style1" style="left: 0px; bottom: 0; width: 100%">
          <input type="text" id="address" value="Enter City,State or Zipcode" onclick="if(this.value=='Enter City,State or Zipcode'){this.value=''}" onblur="if(this.value==''){this.value='Enter City,State or Zipcode'}" onkeypress="handleKeyPress(event);" style="width: 183px">
          <input type="button" value="Search" onclick="codeAddress();">
          <input type="button" value="Reset" onclick="handleResetKeyPress();">
          <input type="text" id="radius" value="200" style="width: 42px" onclick="if(this.value=='200'){this.value=''}" onblur="if(this.value==''){this.value='200'}" onkeypress="handleKeyPress(event);"> miles
    </div>
    </body>
</html>

2 回答

  • 9

    以下是使用地理编码API和一些简单几何体来解决此问题的示例 .

    (请注意,为简洁起见,我已对地址和半径进行了硬编码 . )

    // we assume that you have an array of markers
    var markers = [];
    
    //In order to lookup the the position of a zip-code you can use the geocoding API:
    // https://developers.google.com/maps/documentation/geocoding/
    var geocode_api_base_url = "http://maps.googleapis.com/maps/api/geocode/json?";
    var params = {
        adress : 05673,
        components : "country:us",
        sensor : false
    }
    // This is the result set of markers in area
    var in_area = [];
    
    //  http://maps.googleapis.com/maps/api/geocode/json?address=05673&components=country:US&sensor=false
    $.getJSON( geocode_api_base_url + $.param(params), function(data) {
    
        var location, search_area, in_area = [];
    
        location = data['results'][0]['address_components']['geometry']['location'];
    
        // We create a circle to look within:
        search_area = {
            strokeColor: '#FF0000',
            strokeOpacity: 0.8,
            strokeWeight: 2,
            center : new google.maps.LatLng(location.lat, location.lon),
            radius : 500
        }
    
        search_area = new google.maps.Circle(search_area);
    
        $.each(markers, function(i,marker) {
           if (google.maps.geometry.poly.containsLocation(marker.getPosition(), search_area)) {
             in_area.push(marker);
           }
        });
    
        console.info(in_area);
    
    });
    
  • 4

    这是一个有效的例子 .

    该示例使用 all_locations - 示例位置数组 .

    您可以将其替换为您的位置(例如,您从数据库中提取的位置) . 您可以将任何地址插入输入栏,例如'123 New Street, New York, 56789, NY'并使用 google.maps.Geocoder 代码将该 Map 地理编码为LatLng位置,围绕该位置绘制半径 . 只有位于地址半径范围内的位置才会显示在 Map 上 . 要查看示例位置,请输入"Second Steet, New York"作为地址 .

    var map = null;
      var radius_circle;
      var markers_on_map = [];
      var geocoder;
      var infowindow;
      
      //all_locations is just a sample, you will probably load those from database
      var all_locations = [
    	  {type: "Restaurant", name: "Restaurant 1", lat: 40.723080, lng: -73.984340},
    	  {type: "School", name: "School 1", lat: 40.724705, lng: -73.986611},
    	  {type: "School", name: "School 2", lat: 40.724165, lng: -73.983883},
    	  {type: "Restaurant", name: "Restaurant 2", lat: 40.721819, lng: -73.991358},
    	  {type: "School", name: "School 3", lat: 40.732056, lng: -73.998683}
      ];
    
      //initialize map on document ready
      $(document).ready(function(){
          var latlng = new google.maps.LatLng(40.723080, -73.984340); //you can use any location as center on map startup
          var myOptions = {
            zoom: 1,
            center: latlng,
            mapTypeControl: 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);
    	  geocoder = new google.maps.Geocoder();
          google.maps.event.addListener(map, 'click', function(){
               if(infowindow){
                 infowindow.setMap(null);
                 infowindow = null;
               }
          });
      });
      
      function showCloseLocations() {
      	var i;
      	var radius_km = $('#radius_km').val();
      	var address = $('#address').val();
    
      	//remove all radii and markers from map before displaying new ones
      	if (radius_circle) {
      		radius_circle.setMap(null);
      		radius_circle = null;
      	}
      	for (i = 0; i < markers_on_map.length; i++) {
      		if (markers_on_map[i]) {
      			markers_on_map[i].setMap(null);
      			markers_on_map[i] = null;
      		}
      	}
    
      	if (geocoder) {
      		geocoder.geocode({'address': address}, function (results, status) {
      			if (status == google.maps.GeocoderStatus.OK) {
      				if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
      					var address_lat_lng = results[0].geometry.location;
      					radius_circle = new google.maps.Circle({
      						center: address_lat_lng,
      						radius: radius_km * 1000,
      						clickable: false,
    						map: map
      					});
                        if (radius_circle) map.fitBounds(radius_circle.getBounds());
      					for (var j = 0; j < all_locations.length; j++) {
      						(function (location) {
      							var marker_lat_lng = new google.maps.LatLng(location.lat, location.lng);
      							var distance_from_location = google.maps.geometry.spherical.computeDistanceBetween(address_lat_lng, marker_lat_lng); //distance in meters between your location and the marker
      							if (distance_from_location <= radius_km * 1000) {
      								var new_marker = new google.maps.Marker({
      									position: marker_lat_lng,
      									map: map,
      									title: location.name
      								});      								google.maps.event.addListener(new_marker, 'click', function () {
                                        if(infowindow){
                 infowindow.setMap(null);
                 infowindow = null;
               }
      									infowindow = new google.maps.InfoWindow(
                { content: '<div style="color:red">'+location.name +'</div>' + " is " + distance_from_location + " meters from my location",
                  size: new google.maps.Size(150,50),
                  pixelOffset: new google.maps.Size(0, -30)
                , position: marker_lat_lng, map: map});
      								});
      								markers_on_map.push(new_marker);
      							}
      						})(all_locations[j]);
      					}
      				} else {
      					alert("No results found while geocoding!");
      				}
      			} else {
      				alert("Geocode was not successful: " + status);
      			}
      		});
      	}
      }
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <script type="text/javascript">
            google.load("maps", "3",{other_params:"sensor=false&libraries=geometry"});
          </script>
    
    <body style="margin:0px; padding:0px;" >
     <input id="address" value="Second Steet, New York" placeholder="Input Address"/>
     <select id="radius_km">
    	 <option value=1>1km</option>
    	 <option value=2>2km</option>
    	 <option value=5>5km</option>
    	 <option value=30>30km</option>
     </select>
     <button onClick="showCloseLocations()">Show Locations In Radius</button>
     <div id="map_canvas"  style="width:500px; height:300px;">
    </body>
    </html>
    

相关问题