У меня есть этот скрипт, который покажет пользовательские маркеры на карте google, но я бы хотел включить текстовое поле ввода и иметь возможность ввести город / штат и почтовый индекс и посмотреть, есть ли какие-либо маркеры внутри, скажем, 400 миль от этого города / штата или почтового индекса. Мне бы очень понравилось, если карта может быть динамичной, так как вы печатаете город / штат или почтовый индекс, он покажет результаты на карте, избавившись от всех других маркеров и оставив только тот, который находится в пределах этого радиуса, если это слишком сложно, просто ящик с computeDistanceBetween()
какая единица является ближайшей, тоже будет ОК ðŸ™‚ Я искал и обнаружил, что некоторые говорят, что я должен загрузить библиотеку геометрии и использовать computeDistanceBetween()
чтобы найти расстояние от каждого маркера от вашего центра но я понятия не имею, как сделать часть zip-кода или как собрать все это вместе для работы.
Вот мой код:
<!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>
Вот пример того, как вы могли бы решить это с помощью 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); });
Вот рабочий пример.
В примере используется all_locations
– массив примерных местоположений.
Вы можете заменить это на свои местоположения (например, места, которые вы извлекаете из своей базы данных). Вы можете вставить любой адрес в панель ввода, например «123 New Street, New York, 56789, NY» и с помощью google.maps.Geocoder
код будет привязан к географической карте в место LatLng, вокруг которого будет нарисован радиус. На карте будут отображаться только местоположения, которые попадают в радиус вокруг адреса. Чтобы увидеть пример местоположения, введите «Второй 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>