First time trying to hack together some Javascript here so any resources that will help me understand my problem case is appreciated.
I'm trying to extract the lat and long from the following request to use in another request:
var placeSearch, autocomplete;
var x = document.getElementById("location");
function initAutocomplete() {
// Create the autocomplete object, restricting the search predictions to
// geographical location types.
autocomplete = new google.maps.places.Autocomplete(
document.getElementById('autocomplete'), { types: ['geocode'] });
// Avoid paying for data that you don't need by restricting the set of
// place fields that are returned to just the address components.
autocomplete.setFields(['geometry']);
}
function showPosition() {
x.innerHTML = "Latitude: " + autocomplete.result.geometry.lat +
"<br>Longitude: " + autocomplete.result.geometry.lng;
}
/*
"result" : {
"geometry" : {
"location" : {
"lat" : 51.46588129999999,
"lng" : -0.1413263
}
}
*/
// Bias the autocomplete object to the user's geographical location,
// as supplied by the browser's 'navigator.geolocation' object.
function geolocate() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
var geolocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
var circle = new google.maps.Circle(
{ center: geolocation, radius: position.coords.accuracy });
autocomplete.setBounds(circle.getBounds());
});
}
}
When a user selects the autocompleted location the google api makes a request to:
https://maps.googleapis.com/maps/api/place/js/PlaceService.GetPlaceDetails on the selected location. I can see this returns my desired data here:
Obviously autocomplete.result.geometry.lat returns a location_search.js:18 Uncaught TypeError: Cannot read property 'geometry' of undefined error so I'm missing some knowledge here.
Thank you for your help.
I've implemented something very similar to your needs in my project recently. It's quite easy but it took me a while to realise how to do it.
Basically, you can simply use the .getPlace() method on the Autocomplete object and go from there. Here's how I got the latitude and longitude:
let locationInfo = autocomplete.getPlace().geometry.location;
let latitude = locationInfo.lat();
let longitude = locationInfo.lng();
In your specific case you should change your showPositions function to
function showPosition() {
x.innerHTML = "Latitude: " + autocomplete.getPlace().geometry.location.lat +
"<br>Longitude: " + autocomplete.getPlace().geometry.location.lng;
}
Does this do the trick?
Related
I am using the Google API (Javascript v3) and need to be able to convert latitude and longitude to a place name (not an address), and visa versa. I have read a lot of articles saying to use the Reverse Geocoding to get this but so far I have only been able to get the formatted_address and not the actual place name.
The code I was using for this is:
function showLocationAddress(e) {
var latlng = { lat: e.latLng.lat(), lng: e.latLng.lng() };
var geocoder = new google.maps.Geocoder;
geocoder.geocode({'location': latlng}, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
$('#location').empty();
$('#location').val(results[0].formatted_address);
} else {
window.alert('Geocoder failed due to: ' + status);
}
});
}
Currently the user can use the autosearch function which within a text field on the map and I can get the place_id, address, and lat and long (as discribed in this link). This is instantiated by calling var autocomplete = new google.maps.places.Autocomplete(input); and the place details are then retrieved using place = autocomplete.getPlace();.
The difficulty I am having is that I also need the same information (place_id, address, and lat and long) to be available when the user clicks on the map, but as I am not using the Autocomplete text field I don't know how to do this.
I thought it would have been something like var place = new google.maps.places.Place(latLng);.
This might be a lame question, but for me as a javascript newbie it's really a mystery.
Here is a short sample of my code that handles geolocation:
if (navigator.geolocation)
{
var latitude, longitude;
navigator.geolocation.getCurrentPosition(
function(position) {
latitude = position.coords.latitude;
longitude = position.coords.longitude;
// Here I get user's coordinates
alert("Latitude : " + latitude + " Longitude : " + longitude);
},
function() {
alert("Geo Location not supported");
}
);
// Here I don't get anything
alert("Latitude : " + latitude + " Longitude : " + longitude);
new google.maps.Geocoder().geocode({
location: new google.maps.LatLng(latitude ,longitude)
}, this.getCallback());
}
else {
error("Geolocation is not supported by this browser.");
}
As I've already mentioned in the comments - I the first case, I get coordinates, but in the second one, the values of those vars are undefined and thus I can't get the location on the map... What may cause this and how to pass those values to the Geocoder ?
That is how asynchronous requests work. You have to wait till the request completes and then execute the next block of code as callback to the success function. Executing it all in line will cause problems as you are experiencing.
function(position) {
latitude = position.coords.latitude;
longitude = position.coords.longitude;
// Here I get user's coordinates
alert("Latitude : " + latitude + " Longitude : " + longitude);
new google.maps.Geocoder().geocode({
location: new google.maps.LatLng(latitude ,longitude)
}, this.getCallback());
}
note: you'll probably need to change the context of this, for this.callback
I'm very new to Javascript and ran into a problem I can't resolve/understand myself.
Let's say that I made "UserMap" class with a "userPosition" property and want to get coordinates using Geolocation API.
navigator.geolocation.getCurrentPosition(this.getCoordinates);
Then in the callback function I get latitude and longitude:
var coords = { "lat" : position.coords.latitude, "lng" : position.coords.longitude };
My question is: how can I make this callback function report back to the UserMap instance, so the userPosition property can be updated? Obviously this.userPosition = coords; won't work here. Now I feel pretty much helpless dealing with callbacks. I hope I don't have to make a new object every time I get the updated coords from a user.
Here is the wrong code:
function UserMap() {
this.map = L.map('map', {"zoomControl" : false});
this.userPosition = {};
this.boundary = {};
if (navigator.geolocation){
navigator.geolocation.getCurrentPosition(this.getCoordinates);
}
else{ alert("Geolocation is not supported by your browser.");
return false;
}
this.map.on("click", function(e) {
alert("Lat: " + e.latlng.lat + " Lng: " + e.latlng.lng);
});
this.display();
}
UserMap.prototype.getCoordinates = function(position) {
var coords = { "lat" : position.coords.latitude, "lng" : position.coords.longitude};
this.userPosition = coords; // I understand why this line won't work, but can't find a workaround solution
}
UserMap.prototype.display = function() {
var lat = this.userPosition.lat;
var lng = this.userPosition.lng;
this.map.setView([lat, lng], 18);
var tile = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors',
minZoom: '16',
}).addTo(this.map);
L.marker([lat, lng]).addTo(this.map)
.bindPopup('You are here!')
.openPopup();
}
In the callback you can use an ajax call, wich will interact with the server in a nonblocking manner.
If you use jquery you can do something like this:
$.ajax({
url: "test.html",
data: coords
})
.done(function() {
alert("done")
});
You could use the map.locate function and the locationfound event to accomplish this:
Check this fiddle: http://jsfiddle.net/tuchi35/3fTL7/1/ and also check the locate doc: http://leafletjs.com/reference.html#map-locate
Basically, I removed your getCoordinates function and replace it with a call to the locate function and a event handler for the "locationfound" event:
map.locate({setView:true});
map.on('locationfound', function (data){
L.marker(map.getCenter).addTo(map)
.bindPopup('You are here!')
.openPopup();
});
Hope it helps
I'm looking to geoencode an address and convert it to GPS Coordinates. Basically,
var address;
// Google/Yahoo/whatever program to convert address to GPS coordinates
var output=xx.xxxxxxx,xx.xxxxxxx
I've researched Google and Yahoo APIs, but can't seem to get their codes to work in my Google Gadget. Any suggestions?
Thanks in advance!
Here's what I did for my address-to-gps-coords needs:
function get_coords(address)
{
var gc = new google.maps.Geocoder(),
opts = { 'address' : address };
gc.geocode(opts, function (results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
var loc = results[0].geometry.location,
lat = loc.$a,
long = loc.ab;
// Success. Do stuff here.
}
else
{
// Ruh roh. Output error stuff here
}
});
}
Then you call it like get_coords('1600 Pennsylvania Avenue NW Washington, DC 20500') and it'll return the latitude and longitude.
You'll need to supply your own Google Maps API key to make it work, of course.
Hope this helps!
I did this and worked perfect:
<script type="text/javascript">
var dir1 = "5th ave, new york";
var google_url = "http://maps.googleapis.com/maps/api/geocode/json?address=";
var sensor = "&sensor=false";
var resultado;
function myFunction(){
$.getJSON(
google_url+dir1+sensor,
function(result){
$( "body" ).append( "Latitude: " + JSON.stringify(result.results[0].geometry.bounds.northeast.lat) )
$( "body" ).append( "Longitude: " + JSON.stringify(result.results[0].geometry.bounds.northeast.lng) )
});
}
I help to maintain one API called LiveAddress which does this. Much easier to use than Google/Yahoo's APIs, and without the restrictive Terms of Service which prohibit requests en masse, storing the results, or using the data without showing a map or by automation.
Here's a complete example, using this sample wrapper function:
LiveAddress.init(123456789); // your API key here
LiveAddress.geocode("address goes here", function(geo) {
// You can also pass in an array of addresses,
// the ID of a DOM element containing the address,
// or an array of IDs
console.log(geo);
});
Individual coordinates are found in geo.lat and geo.lon, with the combined string "lat, lon" format in geo.coords. You can also obtain the precision of the data with geo.precision.
I have a serious problem that i have been trying to debug for a few days already.
I have a script that gets users current latitude and longitude, and then stores them in variables. however, when i try to use these variables outside this function and in the //init map zone, the map is just not showing up. by alerting out the variables i can see that outside the position function variables are set to "Undefined". here is my code:
//main function here
function initialize() {
var lat;
var lon;
//check if user has geo feature
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(
//get position
function(position){
lat = position.coords.latitude;
lon = position.coords.longitude;
},
// if there was an error
function(error){
alert('ouch');
});
}
//case the users browser doesn't support geolocations
else {
alert("Your browser doesn't support geolocations, please consider downloading Google Chrome");
}
//init map
var myOptions = {
center: new google.maps.LatLng(lat, lon),
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
}
Thanks for any help, Ariel
That is because you declare your variables within the function. The variables gets private to the initialize function and can only be accessed from within it. If you need to be able to access your variables outside of the initialize function, then move the variable declaration out of the function.
var lat;
var lon;
function initialize() {
...
Have a look at this MDN article about variable scope in JavaScript.
UPDATE
Looking through the code again I realize that the problem isn't variable scope, got confused by the indentation. I'm not familiar with the Geolocation API but I believe that the problem might be that the navigator.geolocation.getCurrentPosition() is asynchronous, as it will have to wait for the user to allow the website to get the position of the device. Therefor myOptions will have been assigned before the actual position have been retrieved - thus lat & lng are still undefined when myOptions is assigned.
Try this instead:
//main function here
function initialize() {
var lat, lon, map, myOptions;
//check if user has geo feature
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(
//get position
function(position){
lat = position.coords.latitude;
lon = position.coords.longitude;
//init map
myOptions = {
center: new google.maps.LatLng(lat, lon),
zoom: 16,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
},
// if there was an error
function(error){
alert('ouch');
});
}
//case the users browser doesn't support geolocations
else {
alert("Your browser doesn't support geolocations, please consider downloading Google Chrome");
}
}
More of a correction on the other answer. The issue of scope is not relevant. As defined in the original code lat and lon are in scope in the context to which the question author is using alert.
Here's a runnable example that proves it.
function getPos( f ) {
var position = new Object();
position.coords = new Object();
position.coords.latitude = 5;
position.coords.longitude = 10;
f( position );
}
function initialize() {
var lat;
var lon;
getPos(
function(position){
lat = position.coords.latitude;
lon = position.coords.longitude;
}
);
alert( lat + " " + lon );
}
initialize(); //expected 5 & 10
Anyways, this doesn't seem to be a pure JS issue. This seems to be an issue with whatever google api you are using. This question should have been tagged with such, as I have no knowledge of this API or whether you're calling it wrong or not.