Я использовал этот учебник Google для создания веб-приложения, которое находит ближайший магазин от введенного пользователем пользователя:
http://code.google.com/apis/maps/articles/phpsqlsearch_v3.html
У меня есть приложение, почти работающее так, как я этого хочу, при загрузке страницы, карта загружается, центрируется и устанавливается на уровень масштабирования 6, и пользователь заполняет форму своим местоположением.
Затем приложение извлекает всю информацию о магазине из db и заполняет карту маркером для каждого.
Уровень масштабирования также уменьшается, но я не могу найти его в коде где угодно.
То, что я на самом деле хочу сделать, – это увеличить масштаб до уровня 6 и центрировать карту на широту и долготу введенного пользователем местоположения и выводить информацию о ближайших магазинах, например ближайший 5. Мне было интересно, знает ли кто-нибудь здесь, как для реализации этой функции?
index.php
<div> <input type="text" id="addressInput" size="50"/> <input type="hidden" id="radiusSelect" value="5"/> <input type="button" onclick="searchLocations()" value="Search"/> </div> <div><select id="locationSelect" style="width:100%;visibility:hidden"></select></div> <div id="map" style="width:100%; height:50%"></div> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script> <script type="text/javascript"> //<![CDATA[ var map; var markers = []; var infoWindow; var locationSelect; function load() { map = new google.maps.Map(document.getElementById("map"), { center: new google.maps.LatLng(54.600939134593, -2.399894114594), zoom: 6, mapTypeId: 'roadmap', mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU} }); infoWindow = new google.maps.InfoWindow(); locationSelect = document.getElementById("locationSelect"); locationSelect.onchange = function() { var markerNum = locationSelect.options[locationSelect.selectedIndex].value; if (markerNum != "none"){ google.maps.event.trigger(markers[markerNum], 'click'); } }; } function searchLocations() { var address = document.getElementById("addressInput").value; var geocoder = new google.maps.Geocoder(); geocoder.geocode({address: address}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { searchLocationsNear(results[0].geometry.location); } else { alert(address + ' not found'); } }); } function clearLocations() { infoWindow.close(); for (var i = 0; i < markers.length; i++) { markers[i].setMap(null); } markers.length = 0; locationSelect.innerHTML = ""; var option = document.createElement("option"); option.value = "none"; option.innerHTML = "See all results:"; locationSelect.appendChild(option); } function searchLocationsNear(center) { clearLocations(); var radius = document.getElementById('radiusSelect').value; var searchUrl = 'phpsqlsearch_genxml.php?lat=' + center.lat() + '&lng=' + center.lng() + '&radius=' + radius; downloadUrl(searchUrl, function(data) { var xml = parseXml(data); var markerNodes = xml.documentElement.getElementsByTagName("marker"); var bounds = new google.maps.LatLngBounds(); for (var i = 0; i < markerNodes.length; i++) { var town = markerNodes[i].getAttribute("town"); var postcode = markerNodes[i].getAttribute("postcode"); var name = markerNodes[i].getAttribute("name"); var address = markerNodes[i].getAttribute("address"); var distance = parseFloat(markerNodes[i].getAttribute("distance")); var latlng = new google.maps.LatLng( parseFloat(markerNodes[i].getAttribute("lat")), parseFloat(markerNodes[i].getAttribute("lng"))); var id = markerNodes[i].getAttribute("id"); var fname = markerNodes[i].getAttribute("fname"); var link = '<a href="http://www.domain.co.uk/stores/' + fname + '-' + id + '.html" target="_blank" title="Store: ' + town + '">More info</a>'; createOption(name, distance, i); createMarker(latlng, name, address, town, postcode, link); bounds.extend(latlng); } map.fitBounds(bounds); locationSelect.style.visibility = "visible"; locationSelect.onchange = function() { var markerNum = locationSelect.options[locationSelect.selectedIndex].value; google.maps.event.trigger(markers[markerNum], 'click'); }; }); } function createMarker(latlng, name, address, town, postcode, link) { var html = "<b>" + town + "</b> <br/>" + address + "<br/>" + postcode + "<br/>" + link; var marker = new google.maps.Marker({ map: map, position: latlng }); google.maps.event.addListener(marker, 'click', function() { infoWindow.setContent(html); infoWindow.open(map, marker); }); markers.push(marker); } function createOption(name, distance, num) { var option = document.createElement("option"); option.value = num; option.innerHTML = name + "(" + distance.toFixed(1) + ")"; locationSelect.appendChild(option); } function downloadUrl(url, callback) { var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest; request.onreadystatechange = function() { if (request.readyState == 4) { request.onreadystatechange = doNothing; callback(request.responseText, request.status); } }; request.open('GET', url, true); request.send(null); } function parseXml(str) { if (window.ActiveXObject) { var doc = new ActiveXObject('Microsoft.XMLDOM'); doc.loadXML(str); return doc; } else if (window.DOMParser) { return (new DOMParser).parseFromString(str, 'text/xml'); } } function doNothing() {} //]]> </script> <script type="text/javascript"> $(document).ready(function() { load(); }); </script>
phpsqlsearch_genxml.php
<?php $db_conn = mysql_connect('xxx.xxx.xx.xx', 'xxxxxxxx', 'xxxxxx') or die('error'); mysql_select_db('uk_db', $db_conn) or die(mysql_error()); // Get parameters from URL $center_lat = $_GET["lat"]; $center_lng = $_GET["lng"]; $radius = $_GET["radius"]; if(!$_GET['zoom']) { $_GET['zoom'] = 11; } // Start XML file, create parent node $dom = new DOMDocument("1.0"); $node = $dom->createElement("markers"); $parnode = $dom->appendChild($node); // Select all the rows in the markers table $query = 'SELECT address1, address2, address3, longitude, latitude, name, town, store_id, postcode, storenumber FROM uk_store WHERE isActive=1 '; if($_GET["region"] != '') { $query .= ' AND region = "' . $_GET["region"] . '"'; } else { $query .= ' AND region in("Scotland", "England", "Wales", "Northern Ireland") '; } // lets start to check what has been search on if($_GET['postcode'] != '') { //lets make sure postcode only has numbers letter and spaces $searchparams .= 'postcode=' . $_GET['postcode'] . '&'; $postcode = $_GET['postcode']; $postcode = verifyInput($postcode); $query .= " AND postcode = '" . $postcode . "'"; } if($_GET['town'] != '') { // make sure town only has letters or spaces. $searchparams .= 'town=' . $_GET['town'] . '&'; $town = $_GET['town']; $town = verifyInput($town); $query .= " AND town = '" . $town . "'"; } if($_GET['min_lat'] && $_GET['min_long'] && $_GET['max_lat'] && $_GET['max_long'] ) { $query .= " AND latitude BETWEEN " . $_GET['min_lat'] . " AND " . $_GET['max_lat'] . " AND longitude BETWEEN " . $_GET['min_long'] . " AND " . $_GET['max_long'] ; $mapsearch = 1; } if(!($_GET['postcodeLat'] && $_GET['postcodeLong'])) { $query .= " ORDER BY Region, Town , Name "; } $result = mysql_query($query); if (!$result) { die("Invalid query: " . mysql_error()); } header("Content-type: text/xml"); echo '<markers>'; if($_GET['postcodeLat'] && $_GET['postcodeLong']) { $count = 0; // we need to sort the results by distance while ($row = @mysql_fetch_array($result, MYSQL_ASSOC)) { $address = $row['address1'] . ' ' . $row['address2'] . ' ' . $row['address3']; $distance = distance($_GET['postcodeLat'], $_GET['postcodeLong'], $row['latitude'], $row['longitude']); $row['distance'] = number_format($distance, 2); $row['fname'] = $row['town'] . '-' . $row['name']; $row['fname'] = str_replace("'",'', $row['fname']); $row['fname'] = ereg_replace(' ','-', $row['fname']); $row['fname'] = ereg_replace('\/','-', $row['fname']); $row['fname'] = ereg_replace('\(','', $row['fname']); $row['fname'] = ereg_replace('\)','', $row['fname']); $row['fname'] = strtolower($row['fname']); //get distance and add to $row array $results[$distance.$row['id']] = $row; } ksort($results); foreach ($results as $key => $row) { // ADD TO XML DOCUMENT NODE $address = $row['address1'] . ' ' . $row['address2'] . ' ' . $row['address3']; echo '<marker '; echo 'name="' . parseToXML($row['name']) . '" '; echo 'fname="' . parseToXML($row['fname']) . '" '; echo 'town="' . parseToXML($row['town']) . '" '; echo 'lat="' . $row['latitude'] . '" '; echo 'lng="' . $row['longitude'] . '" '; echo 'id="' . $row['store_id'] . '" '; echo 'address="' . $address . '" '; echo 'distance="' . $row['distance'] . '" '; echo 'postcode="' . $row['postcode'] . '" '; echo 'storenumber="' . $row['storenumber'] . '" '; echo 'address1="' . parsetoXml($row['address1']). '" '; echo 'address2="' . parsetoXml($row['address2']). '" '; echo 'address3="' . parsetoXml($row['address3']). '" '; echo '/>'; } } else { // Iterate through the rows, printing XML nodes for each while ($row = @mysql_fetch_assoc($result)) { $address = $row['address1'] . ' ' . $row['address2'] . ' ' . $row['address3']; $row['fname'] = $row['town'] . '-' . $row['name']; $row['fname'] = ereg_replace(' ','-', $row['fname']); $row['fname'] = ereg_replace('\/','-', $row['fname']); $row['fname'] = ereg_replace('\(','', $row['fname']); $row['fname'] = ereg_replace('\)','', $row['fname']); // ADD TO XML DOCUMENT NODE echo '<marker '; echo 'name="' . parseToXML($row['name']) . '" '; echo 'fname="' . strtolower(parseToXML($row['fname'])) . '" '; echo 'town="' . parseToXML($row['town']) . '" '; echo 'lat="' . $row['latitude'] . '" '; echo 'lng="' . $row['longitude'] . '" '; echo 'id="' . $row['store_id'] . '" '; echo 'isSurg="' . $row['isLaserSurgery'] . '" '; echo 'isCons="' . $row['isLaserConsult'] . '" '; echo 'address="' . parsetoXml($address). '" '; echo 'address1="' . parsetoXml($row['address1']). '" '; echo 'address2="' . parsetoXml($row['address2']). '" '; echo 'address3="' . parsetoXml($row['address3']). '" '; echo 'postcode="' . $row['postcode'] . '" '; echo 'storenumber="' . $row['storenumber'] . '" '; echo '/>'; } } // End XML file echo '</markers>'; // make sure the data is xml friendly function parseToXML($htmlStr) { $xmlStr=str_replace('<','<',$htmlStr); $xmlStr=str_replace('>','>',$xmlStr); $xmlStr=str_replace('"','"',$xmlStr); //$xmlStr=str_replace("'",''',$xmlStr); $xmlStr=str_replace("&",'&',$xmlStr); return $xmlStr; } // calculate the distance in miles or kms between any two points function distance($lat1, $lon1, $lat2, $lon2, $unit = '') { $theta = $lon1 - $lon2; $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); $dist = acos($dist); $dist = rad2deg($dist); $miles = $dist * 60 * 1.1515; if($unit != '') { $unit = strtoupper($unit); } if ($unit == "K") { return ($miles * 1.609344); } else if ($unit == "N") { return ($miles * 0.8684); } else { return $miles; } } function VerifyInput ($input, $forceInt = false) { if (is_numeric($input)) { return $input; } elseif (!$forceInt) { if (get_magic_quotes_gpc() && trim(ini_get("magic_quotes_sybase")) == "") { $input = stripslashes($input); $input = str_replace("'", "", $input); $input = str_replace("`", "", $input); } elseif (!get_magic_quotes_gpc()) { $input = str_replace("'", "", $input); $input = str_replace("`", "", $input); } return $input; } elseif ($forceInt) { return 0; } } ?>
Извинения, это много вставки там, но я думал, что лучше включать все, а не рисковать тем, кто не может ответить, потому что не было достаточно деталей.
ОБНОВИТЬ
Я попытался вставить этот фрагмент кода в функцию searchLocations
но, похоже, это не изменило поведение:
function searchLocations() { var address = document.getElementById("addressInput").value; var geocoder = new google.maps.Geocoder(); geocoder.geocode({address: address}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { searchLocationsNear(results[0].geometry.location); /////////////// new code var myOptions = { zoom: 11, center: address.geometry.location, mapTypeId: google.maps.MapTypeId.TERRAIN } map = new google.maps.Map(document.getElementById("map"), myOptions); //////////////// } else { alert(address + ' not found'); } }); }
Поскольку вы сказали, что это будет использоваться в качестве приложения Facebook, у меня есть дружеское предложение.
Теперь, когда ваш код работает, вы должны изучить его в своем собственном пространстве имен и реализовать шаблон модуля . Это гарантирует, что имена ваших функций, особенно load (), не будут конфликтовать или перезаписываться другими приложениями на той же странице FB.
Здесь я создал небольшое примерное приложение . Ваш может быть таким простым, как что-то вроде:
if (!window.Carlin) { window.Carling = {}; } Carlin.Locator = function() { var map,markers,infoWindow,locationSelect; markers = []; function load() { } function searchLocations() { } function clearLocations() { } //...etc return { init: load } }(); $(document).ready(Carlin.Locator.init);
Нашли методы, которые я искал в документации (удивление, удивление!)
Просто добавьте эти две строки в map.fitBounds(bounds);
в функции searchLocationsNear
:
map.setZoom(11); map.setCenter(center);