I have a script which I can't get working. I keep getting the error 'Geocoder failed' but I am not sure why. It is supposed to get the long/lat and then reverse geocode it to show the street address in an alert box. I have tried ensuring that the browser is letting it share the location. I have also tried accessing via HTTPS as I read that this was needed now but it still doesn't work.
If anyone can help me to get this working I would be most grateful!
Thanks in advance.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Current Location Address</title>
<style>
</style>
</head>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var geocoder;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
}
//Get the latitude and the longitude;
function successFunction(position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
codeLatLng(lat, lng)
}
function errorFunction(){
alert("Geocoder failed");
}
function initialize() {
geocoder = new google.maps.Geocoder();
}
function codeLatLng(lat, lng) {
var latlng = new google.maps.LatLng(lat, lng);
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.log(results)
if (results[1]) {
//formatted address
alert(results[0].formatted_address)
//find country name
for (var i=0; i<results[0].address_components.length; i++) {
for (var b=0;b<results[0].address_components[i].types.length;b++) {
//there are different types that might hold a city admin_area_lvl_1 usually does in come cases looking for sublocality type will be more appropriate
if (results[0].address_components[i].types[b] == "administrative_area_level_1") {
//this is the object you are looking for
city= results[0].address_components[i];
break;
}
}
}
//city data
alert(city.short_name + " " + city.long_name)
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
</script>
</head>
<body onload="initialize()"> <font face="verdana">
<!DOCTYPE html>
If available, your current address will have been displayed in a message window. Please press 'Back' when finished.
</body>
</html>
Your errorFunction is automatically passed an error parameter that you can take a look at:
function errorFunction(error){
alert("Geocoder failed: "+error.message);
}
See the MDN docs for more background and examples.
Related
First of all, please apologize my English.
Hi! I need to print with PHP the current user´s address, i have this small script:
<?
function getaddress($lat,$lng)
{
$url = 'http://maps.googleapis.com/maps/api/geocode/json?latlng='.trim($lat).','.trim($lng).'&sensor=false';
$json = #file_get_contents($url);
$data=json_decode($json);
$status = $data->status;
if($status=="OK")
{
return $data->results[0]->formatted_address;
}
else
{
return false;
}
}
?>
<?php
$lat= 21.884766199999998; //latitude
$lng= -102.2996459; //longitude
$address= getaddress($lat,$lng);
if($address)
{
echo $address;
}
else
{
echo "Not found";
}
?>
of course it works, but I don't know how to change the $lat and $long variables to the current users location.
In few words; how I can pass the current user lat and long location to the PHP variables to let this script works?
<html>
<body>
<p id="demo">Click the button to get your coordinates:</p>
<button onclick="getLocation()">Try It</button>
<script>
var x=document.getElementById("demo");
function getLocation()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(showPosition);
}
else{x.innerHTML="Geolocation is not supported by this browser.";}
}
function showPosition(position)
{
x.innerHTML="Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
}
</script>
</body>
</html>
this is an javascript based search. you can try it in html browser and pass the lat long to the php scripts.
if it helps you its ok or you can tell , i have other ways too.
You need to get this using JavaScript or other google api. Which you can place lat & lang in an separate hidden field and then assign to your php variables from that hidden fields.
Here is an example script to get this using html 5 and java-script
<script>
var x = document.getElementById("demo");
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
}
</script>
This is another script using google Geo-location API
<!DOCTYPE html>
<html>
<head>
<title>Geolocation</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
// Note: This example requires that you consent to location sharing when
// prompted by your browser. If you see the error "The Geolocation service
// failed.", it means you probably did not give permission for the browser to
// locate you.
var map, infoWindow;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 6
});
infoWindow = new google.maps.InfoWindow;
// Try HTML5 geolocation.
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
infoWindow.open(map);
map.setCenter(pos);
}, function() {
handleLocationError(true, infoWindow, map.getCenter());
});
} else {
// Browser doesn't support Geolocation
handleLocationError(false, infoWindow, map.getCenter());
}
}
function handleLocationError(browserHasGeolocation, infoWindow, pos) {
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Error: The Geolocation service failed.' :
'Error: Your browser doesn\'t support geolocation.');
infoWindow.open(map);
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
</body>
</html>
I dont understand, how could this happen? I only got 1 variable but it seems like it has 2 different values. Please see the output below. Here's the code of the webpage:
<!DOCTYPE html>
<html>
<head>
<script src="http://maps.googleapis.com/maps/api/js"></script>
<script>
var map;
var geocoder;
var center = new google.maps.LatLng(11.17840187,122.59643555);
var marker = new google.maps.Marker();
var info = new google.maps.InfoWindow();
var latitude = 0.00;
var longitude = 0.00;
var address = "NO ADDRESS";
var loaded = false;
function initialize() {
var mapProp = {
center : center,
zoom : 5,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("googleMap"),mapProp);
geocoder = new google.maps.Geocoder();
google.maps.event.addListener(map, "click", function (event) {
latitude = event.latLng.lat();
longitude = event.latLng.lng();
center = new google.maps.LatLng(latitude,longitude);
displayAddress();
moveToCenter();
console.log("Address : " + address)
});
}
google.maps.event.addDomListener(window, 'load', initialize);
function moveToCenter(){
map.panTo(center);
marker.setPosition(center);
marker.setMap(map);
}
function displayAddress(){
geocoder.geocode( {'latLng': center},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK) {
if(results[0]) {
address = results[0].formatted_address;
}
else {
address = "";
}
info.setContent("<b>" + address + "</b>");
info.open(map,marker);
}
});
}
function setWidth(width){
document.getElementById('googleMap').style.width = width + "px";
google.maps.event.trigger(map, 'resize');
}
function setHeight(height){
document.getElementById('googleMap').style.height = height + "px";
google.maps.event.trigger(map, 'resize');
}
</script>
<style>
body
{
padding : 0;
margin : 0;
overlow : hidden;
}
#googleMap
{
width : 600px;
height : 600px;
overlow : hidden;
}
</style>
</head>
<body>
<div id="googleMap"></div>
</body>
</html>
I have a variable address in my code, but I dont understand why it has two different values. How does this happen? Is it a Javascript Bug?
Here's the output:
I see what you're asking now. Perhaps we can we rephrase the question.
Q: Why when I set address in displayAddress() does it display the address correctly in the map but still log "No address" in the console?
A: It's because you've introduced an asynchronous process into your code.
You think that the following should happen:
Set address to "No address"
Call displayAddress() which changes the value of address and
also displays it on the map
Log the changed address
What's actually happening is this:
Set address to "No address"
Call displayAddress() - the async process geocode starts
Log the address (this hasn't changed)
The async operation completes and the address is displayed on the map.
If you want to know more about async processes and how to return values from them this SO question has lots of relevant information.
I think the problem comes from the fact that the code which modifies your address variable is called after the console.log instruction.
As a matter of fact, all of the following code:
if(status == google.maps.GeocoderStatus.OK) {
if(results[0]) {
address = results[0].formatted_address;
}
else {
address = "";
}
info.setContent("<b>" + address + "</b>");
info.open(map,marker);
}
is contained in the callback function which is passed to the geocoder.geocode method, and which will then be executed once the remote request has been completed. Which, given the reponse time of the remote request (a few tens or hundreds of miiliseconds), occurs after the execution of the console.log statement.
Take a closer look at your code.
function displayAddress(){
geocoder.geocode( {'latLng': center},
function(results, status) {
if(status == google.maps.GeocoderStatus.OK) {
if(results[0]) {
address = results[0].formatted_address; <------ Take a look at this
}
else {
address = "";
}
info.setContent("<b>" + address + "</b>");
info.open(map,marker);
}
});
}
When i am running the following code, which i have taken from this answer, i am getting Uncaught TypeError: Cannot read property 'geocode' of undefined error in browser's console, why its happening because on the body load here initialize function has to be called, and instead of calling initialize function here codeLatLng(lat, lng) is calling first.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Reverse Geocoding</title>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var geocoder;
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
}
//Get the latitude and the longitude;
function successFunction(position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
codeLatLng(lat, lng)
}
function errorFunction(){
alert("Geocoder failed");
}
function initialize() {
geocoder = new google.maps.Geocoder();
}
function codeLatLng(lat, lng) {
var latlng = new google.maps.LatLng(lat, lng);
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
console.log(results)
if (results[1]) {
//formatted address
alert(results[0].formatted_address)
//find country name
for (var i=0; i<results[0].address_components.length; i++) {
for (var b=0;b<results[0].address_components[i].types.length;b++) {
//there are different types that might hold a city admin_area_lvl_1 usually does in come cases looking for sublocality type will be more appropriate
if (results[0].address_components[i].types[b] == "administrative_area_level_1") {
//this is the object you are looking for
city= results[0].address_components[i];
break;
}
}
}
//city data
alert(city.short_name + " " + city.long_name)
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
</script>
</head>
<body onload="initialize()">
</body>
</html>
There is no need to wait for the onload-event until you initialize the Geocoder-instance. You load the maps-API synchronously, so the API(including google.maps.Geocoder) is available immediately after loading the API.
The issue: when geolocation runs too fast, and the callback of navigator.geolocation.getCurrentPosition will be executed before the onload-event, geocoder is undefined.
Replace this line:
var geocoder;
with this line:
var geocoder = new google.maps.Geocoder();
So; I am developing this web application that works based on the location of the user.
The part that finds the coordinates and the part that converts those coordinates into an address both work individually. However the variable from the first function doesn't seem to transfer over to do the second function and I can't figure out why.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script type="text/javascript">
var coordinates;
function getCoordinates(){
var options = {
enableHighAccuracy: true,
timeout: 4500,
maximumAge: 0
};
function success(pos) {
var crd = pos.coords;
console.log('Enlem : ' + crd.latitude);
console.log('Boylam: ' + crd.longitude);
console.log('Hata Payı ' + crd.accuracy + ' metre.');
coordinates = new google.maps.LatLng(crd.latitude, crd.longitude);
alert(coordinates);
return coordinates;
};
function error(err) {
console.warn('HATA(' + err.code + '): ' + err.message);
};
navigator.geolocation.getCurrentPosition(success, error, options);
}
var ReverseGeocode = function () {
//This is declaring the Global variables
var geocoder, map, marker;
//This is declaring the 'Geocoder' variable
geocoder = new google.maps.Geocoder();
function GeoCode(latlng) {
// This is making the Geocode request
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if(status !== google.maps.GeocoderStatus.OK)
{
alert(status);
}
// This is checking to see if the Geoeode Status is OK before proceeding
if (status == google.maps.GeocoderStatus.OK) {
var address = (results[0].formatted_address);
//This is placing the returned address in the 'Address' field on the HTML form
document.getElementById('Address').value = results[0].formatted_address;
}
});
}
return {
Init: function () {
var latlng = getCoordinates();
alert(latlng);
GeoCode(latlng);
},
};
} ();
</script>
</head>
<body>
<div>
<input name="Address" type="text" id="Address" size="55" />
</div>
<div>
<input type="button" value="Adres Bul" onclick="ReverseGeocode.Init()">
</div>
<div id="map_canvas" style="height: 90%; top: 60px; border: 1px solid black;">
</div>
</body>
</html>
Your main problem: getCoordinates() does not return coordinates. So you cannot use it like this:
var latlng = getCoordinates();
Javascript has asyncronous stuff. That means it takes javascript some time to do it.
The way javascript handles this: You send a request, and you provide a callback (a function). Whenever javascript is ready, your callback will be executed. Positioning is one of those asynchronic things.
Here is a short example:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script type="text/javascript">
// this function is triggered when geolocation has found coordinates
function geolocationReturnedCoordinates(coordinates) {
document.getElementById('log').innerHTML =
'lat: ' + coordinates.coords.latitude +
'<br>lng: ' + coordinates.coords.longitude +
'<br>accuracy: ' + coordinates.coords.accuracy;
// Here would be a good place to call Reverse geocoding, since you have the coordinates here.
GeoCode(new google.maps.LatLng(coordinates.coords.latitude, coordinates.coords.longitude));
}
// geocoder
geocoder = new google.maps.Geocoder();
function GeoCode(latlng) {
// This is making the Geocode request
geocoder.geocode({'location': latlng }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var address = (results[0].formatted_address);
//This is placing the returned address in the 'Address' field on the HTML form
document.getElementById('Address').value = results[0].formatted_address;
}
});
}
function search_position_and_address() {
// we start the request, to ask the position of the client
// we will pass geolocationReturnedCoordinates as the success callback
navigator.geolocation.getCurrentPosition(geolocationReturnedCoordinates, null, null);
}
</script>
</head>
<body>
<input type="button" value="GO" onclick="search_position_and_address()"> Get position (coordinates) of the client. -- Then look for the address
<div id="log"></div>
<input id="Address" placeholder="Address">
</body>
</html>
It's up to you to put it back in your structure.
I just compiled the shortest code that permitted me to make my point.
Also the names of the functions ... I'm trying to make a point. In real life you would pick a shorter name.
A form in an html file passes an input called "address" to a php file "registerEvent.php" where it is to be geocoded. No matter what address is inputted, the function still outputs ZERO_RESULTS status in an alert which can happen if the inputted address is invalid(i.e. NULL or an impossible address). I have tested, that recieving the address value from the html form works correctly both in php and at the start of the codeAddress() function.
<?php
$geoadrese = $_POST['address'];
?>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js"></script>
<script type="text/javascript">
geocoder = new google.maps.Geocoder();
var inputLat;
var inputLng;
function codeAddress() {
var address = '<?php echo $geoadrese; ?>';
// everything works fine up until this point
geocoder.geocode( { 'address': address }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
inputLat = results[0].geometry.location.lat();
inputLng = results[0].geometry.location.lng();
window.location.href = "registerEvent.php?inputLat=" + inputLat + "&inputLng=" + inputLng;
} else {
alert('Geocode was not successful for the following reason: ' + status);
};
});
}
codeAddress();
</script>