javascript Google Maps API v3:如何为用户提交的位置设置缩放级别和地图中心?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8591488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 03:54:59  来源:igfitidea点击:

Google Maps API v3: How to Set Zoom Level And Map Center To User Submitted Location?

phpjavascriptmysqlgoogle-mapsgoogle-maps-api-3

提问by martincarlin87

I have used this tutorial from Google to build a web app that finds the closest store from the user entered location:

我已经使用谷歌的这个教程来构建一个网络应用程序,从用户输入的位置找到最近的商店:

http://code.google.com/apis/maps/articles/phpsqlsearch_v3.html

http://code.google.com/apis/maps/articles/phpsqlsearch_v3.html

I have my app almost working the way I want it, upon page load, the map is loaded, centered and set to zoom level 6 and the user fills out the form with their location.

我的应用程序几乎按照我想要的方式工作,在页面加载时,地图被加载、居中并设置为缩放级别 6,并且用户用他们的位置填写表单。

The app then pulls all the store info from the db and populates the map with a marker for each.

然后,该应用程序从数据库中提取所有商店信息,并为每个信息填充地图。

The zoom level seems to decrease aswell but I can't find this in the code anywhere.

缩放级别似乎也降低了,但我在代码中的任何地方都找不到。

What I actually want to do on submit is zoom in to zoom level 6 and center the map to the latitude and longitude of the user entered location and output info on the nearest stores, e.g the nearest 5. I was wondering if anyone here knew how to implement this feature?

我在提交时真正想做的是放大到缩放级别 6 并将地图居中到用户输入位置的纬度和经度并输出最近商店的信息,例如最近的 5。我想知道这里是否有人知道如何实现这个功能?

index.php

索引.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

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

?>

Apologies, that's a lot of pasting there but I thought it better to include everything rather than risk someone not being able to answer because there wasn't enough detail.

抱歉,这里有很多粘贴,但我认为最好包括所有内容,而不是冒着有人无法回答的风险,因为没有足够的细节。

UPDATE

更新

I have tried inserting this piece of code into the searchLocationsfunction but it doesn't seem tochange the behaviour in anyway:

我试过将这段代码插入到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');
   }
 });
}

采纳答案by Butifarra

Since you said this would be used as a Facebook app, I have a friendly suggestion.

既然你说这将用作 Facebook 应用程序,我有一个友好的建议。

Now that your code is working, you should look into wrapping it in its own namespace and implement the module pattern. Doing so will guarantee that your function names, especially load(), do not clash or get overwritten by other apps on the same FB page.

现在您的代码正在运行,您应该考虑将其包装在自己的命名空间中并实现模块模式。这样做将保证您的函数名称,尤其是 load(),不会与同一 FB 页面上的其他应用程序发生冲突或覆盖。

I have created a small sample app here. Yours could be as simple as something like:

我在这里创建了一个小示例应用程序。您的可能很简单,例如:

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

回答by martincarlin87

Found the methods I was looking for in the documentation (surprise, surprise!)

在文档中找到了我正在寻找的方法(惊喜,惊喜!)

Simply add these two lines under map.fitBounds(bounds);in the searchLocationsNearfunction:

只需map.fitBounds(bounds);searchLocationsNear函数下添加这两行:

   map.setZoom(11);
   map.setCenter(center);