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'] . '&amp;';
  $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'] . '&amp;';
    $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('<','&lt;',$htmlStr); 
    $xmlStr=str_replace('>','&gt;',$xmlStr); 
    $xmlStr=str_replace('"','&quot;',$xmlStr); 
    //$xmlStr=str_replace("'",'&#39;',$xmlStr); 
    $xmlStr=str_replace("&",'&amp;',$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:如何将缩放级别和地图中心设置为用户提交的位置?的主要内容,如果未能解决你的问题,请参考以下文章

Google Maps v3 - 限制可视区域和缩放级别

在 maps.google.com 上的缩放比在 Google Maps API v3 上更流畅

Google Maps API v3:我可以在 fitBounds 之后设置缩放吗?

Google Maps API v3:如何以 2 个动态地址为中心?

Google Maps API v3 在没有 fitbounds 的情况下无法加载,缩放导致无限循环/***

如何知道用户是不是更改缩放(Google Maps V3)