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
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.
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?
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;
}
}
?>
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 searchLocations
function but it doesn't seem tochange the behaviour in anyway:
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');
}
});
}