Google Maps API v3:如何将缩放级别和地图中心设置为用户提交的位置?
Posted
技术标签:
【中文标题】Google Maps API v3:如何将缩放级别和地图中心设置为用户提交的位置?【英文标题】:Google Maps API v3: How to Set Zoom Level And Map Center To User Submitted Location? 【发布时间】:2012-01-25 08:43:17 【问题描述】:我已经使用 Google 的这个教程构建了一个网络应用程序,它可以从用户输入的位置找到最近的商店:
http://code.google.com/apis/maps/articles/phpsqlsearch_v3.html
我的应用程序几乎按照我想要的方式工作,在页面加载时,地图被加载、居中并设置为 6 级缩放,并且用户填写表单及其位置。
然后,该应用会从数据库中提取所有商店信息,并使用每个标记填充地图。
缩放级别似乎也降低了,但我在任何地方的代码中都找不到。
我在提交时真正想要做的是放大到缩放级别 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 标签上,但 iframe 源可以在这里找到:tiny.cc/6gto0 【参考方案1】:在文档中找到了我正在寻找的方法(惊喜,惊喜!)
只需在searchLocationsNear
函数的map.fitBounds(bounds);
下添加这两行即可:
map.setZoom(11);
map.setCenter(center);
【讨论】:
【参考方案2】:既然你说这将用作 Facebook 应用程序,我有一个友好的建议。
现在您的代码正在运行,您应该考虑将其包装在自己的命名空间中并实现module pattern。这样做将保证您的函数名称,尤其是 load(),不会发生冲突或被同一 FB 页面上的其他应用程序覆盖。
我创建了一个小的sample app here。你的可能就像这样简单:
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);
【讨论】:
以上是关于Google Maps API v3:如何将缩放级别和地图中心设置为用户提交的位置?的主要内容,如果未能解决你的问题,请参考以下文章
在 maps.google.com 上的缩放比在 Google Maps API v3 上更流畅
Google Maps API v3:我可以在 fitBounds 之后设置缩放吗?
Google Maps API v3:如何以 2 个动态地址为中心?