I've problem in javascript function, there are two variables which are declared in global scope of function and set within jquery plugin. How can i get these variable value out side of jquery.
function GetDirectionFromCurrentLocation(StoreAddress) {
var positionStore = null;
var positionCurrent = null;
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': StoreAddress }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
positionStore = results[0].geometry.location;
}
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
positionCurrent = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
});
}
});
window.open("http://maps.google.com/maps?saddr=" + positionCurrent + "&daddr=" + positionStore + "&hl=en&output=html");
}
These variables are always null.
Move your window.open call inside of the anonymous function. Your variables are null because your window.open line of code is being called BEFORE the anonymous function is being called.
I would suggest you the open the new window inside the jQuery function, as it's need to be synchronous to get the proper values.
It seems that your geocode call is asynchronous and when your code reaches the window open call, the background job isn't finished.
function GetDirectionFromCurrentLocation(StoreAddress) {
var positionStore = null;
var positionCurrent = null;
var geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'address': StoreAddress }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
positionStore = results[0].geometry.location;
}
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
positionCurrent = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
});
}
if (positionCurrent && positionStore) {
window.open("http://maps.google.com/maps?saddr=" + positionCurrent + "&daddr=" + positionStore + "&hl=en&output=html");
}
});
}
Related
Using Google Maps and the Geocoder, I'm trying to loop over an object of addresses, return LatLng addresses for them, and create markers using both the original details and the latlng address in the setMarker function below.
The problem is, the response[a] is being overwritten by the last address in the object, because the for loop is running ahead of the AJAX results being returned.
How can I save the data in the current response[a] being looped over, so that when setMarker() is later called, it contains the right information?
Thanks
var limit = 0;
for (a in response){
if(limit<5){ // limit API calls
var addr = [response[a].Addr1, response[a].City, response[a].Zip];
geo = new google.maps.Geocoder();
geo.geocode({
address: addr.join(", "),
componentRestrictions: {
// country: 'UK'
}
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK && results) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
var latlng = new google.maps.LatLng(latitude, longitude);
if(latitude!="" && longitude!=""){
bounds.extend(latlng);
map.fitBounds(bounds);
_this.setMarker(map, limit, latlng, response[a]);
}
} // if geo results
});
}
limit++;
}
The problem you are facing is a classic one that can be solved using closure function.
Current code looks something like :
var a[20];
for(i=0;i<20;i++) {
some_async_method() {
//code that uses 'a[i]'
}
}
Using closure to preserve the scope of var a inside a async function :
var a[20];
for(i=0;i<20;i++) {
(function(_a){
some_async_method() {
//code that uses 'a[i]' as '_a'
}
})(a[i]);// self calling function that preserves the scope of a[i]
}
So your code will look like :
var limit = 0;
for (a in response){
if(limit<5){ // limit API calls
var addr = [response[a].Addr1, response[a].City, response[a].Zip];
geo = new google.maps.Geocoder();
(function(response_a){ // closure function to preserve scope of 'response[a]'
geo.geocode({
address: addr.join(", "),
componentRestrictions: {
// country: 'UK'
}
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK && results) {
var latitude = results[0].geometry.location.lat();
var longitude = results[0].geometry.location.lng();
var latlng = new google.maps.LatLng(latitude, longitude);
if(latitude!="" && longitude!=""){
bounds.extend(latlng);
map.fitBounds(bounds);
_this.setMarker(map, limit, latlng, response_a);
}
} // if geo results
});
})(response[a]);
}
limit++;
}
I have some latitudes and longitudes i want to find out their addresses.
function OnSuccess(response) {
showLatLng(0, JSON.parse(response.d).Table, JSON.parse(response.d).Table.length);
}
Where JSON.parse(response.d).Table contains the result set.
function showLatLng(index, resultSet, totalLen) {
var lat = resultSet[index].x;
var lng = resultSet[index].y;
var latlng = new google.maps.LatLng(lat, lng);
new google.maps.Geocoder().geocode({ 'latLng': latlng },
function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
var z = " <tr>" +
"<td>" + results[0].formatted_address + "</td>" +
"</tr>";
$("#result").append(z);
if (index < totalLen) {
showLatLng(index + 1, resultSet, totalLen);
}
}
}
});
}
This code is working only 4 to 5 times then stops and no error in firebug.
Please give me a better way to do this.
EDIT:
Lucas You are absolutely right.
Previously I have used loop with timeout as below
$.each(JSON.parse(response.d).Table, function (index, value) {
setTimeout(function () {
showLatLng(index , value.x, value.y);
}, (index + 1) * 7000);
});
But for some reason (because I think it is working on async call) it is skipping some results.
pass Latitude and Longitude value to script
function GetAddress() {
var lat = parseFloat(document.getElementById("txtLatitude").value);
var lng = parseFloat(document.getElementById("txtLongitude").value);
var latlng = new google.maps.LatLng(lat, lng);
var geocoder = geocoder = new google.maps.Geocoder();
geocoder.geocode({ 'latLng': latlng }, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
alert("Location: " + results[1].formatted_address);
}
}
});
}
I have two set of lat and lng.
I want both address and stored in some variable:
var geocoder = new google.maps.Geocoder();
for(var i=0; i<json_devices.length; i++)
{
var lat = json_devices[i].latitude;
var lng = json_devices[i].longitude;
console.log(lat);
console.log(lng);
var latlng = new google.maps.LatLng(lat,lng);
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
address=results[1].formatted_address;
} else {
alert('No results found');
}
} else {
alert('Geocoder failed due to: ' + status);
}
});
console.log(address);
}
In this, lat & lan get correctly. But address are not stored in variable. What is the mistake?
I am using this method and it is working perfect for me.
Please have a look on it.
public String getAddressFromLatLong(GeoPoint point) {
String address = "Address Not Found";
Geocoder geoCoder = new Geocoder(
getBaseContext(), Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocation(
point.getLatitudeE6() / 1E6,
point.getLongitudeE6() / 1E6, 1);
if (addresses.size() > 0) {
address =addresses.get(0).getAddressLine(0);
if(address.length()<=0)
address =addresses.get(0).getSubLocality();
}
}
catch (Exception e) {
e.printStackTrace();
}
return address;
}
Here the Google geocode is asynchonous type of function call.
From DOCS:
Accessing the Geocoding service is asynchronous, since the Google Maps
API needs to make a call to an external server. For that reason, you
need to pass a callback method to execute upon completion of the
request. This callback method processes the result(s). Note that the
geocoder may return more than one result.
So you can't get the address like that, instead use the common approach called callback.
Here I have created a sample code to explain the process, which can be altered by yourself.
var geocoder;
function codeLatLng(callback) {
geocoder = new google.maps.Geocoder();
var input = document.getElementById("latlng").value;
var latlngStr = input.split(",", 2);
var lat = parseFloat(latlngStr[0]);
var lng = parseFloat(latlngStr[1]);
var latlng = new google.maps.LatLng(lat, lng);
geocoder.geocode({
'latLng': latlng
}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
address = results[1].formatted_address;
callback(address);
} else {
alert("No results found");
}
} else {
alert("Geocoder failed due to: " + status);
}
});
}
$('input[type="button"]').on('click', function () {
codeLatLng(function (address) { //function call with a callback
console.log(address); // THE ADDRESS WILL BE OBTAINED
})
});
JSFIDDLE
This is the code I'm working from: http://jsfiddle.net/9B84H/26/
function autosuggest() {
var input = document.getElementById('location');
var options = {types: [],};
var autocomplete = new google.maps.places.Autocomplete(input, options);
}
function getLatLng() {
var geocoder = new google.maps.Geocoder();
var address = document.getElementById('location').value;
geocoder.geocode({
'address': address
}, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
$('#lat').val(results[0].geometry.location.lat());
$('#lng').val(results[0].geometry.location.lng());
} else {
alert("Geocode failed: " + status);
}
});
}
There are two variables which are pretty much the same:
var address = document.getElementById('location').value;
var input = document.getElementById('location');
Is there any opportunity to combine this into one line as a global variable?
You could use your anonymous self invoking function or just use the dom-ready method in jQuery to wrap your code (dom-ready seems like a better idea if you don´t put your JS code at the bottom of the page).
I did an example removing the onclick, onfocus attribute on your input and put them in the javascript section: http://jsfiddle.net/9B84H/27/
$(function() {
var location = document.getElementById('location');
var getLatLng = function() {
var geocoder = new google.maps.Geocoder();
var address = location.value;
geocoder.geocode({
'address': address
}, function (results, status) {
if (status === google.maps.GeocoderStatus.OK) {
$('#lat').val(results[0].geometry.location.lat());
$('#lng').val(results[0].geometry.location.lng());
alert("Geocode success");
} else {
alert("Geocode failed: " + status);
}
});
};
var autosuggest = function() {
var options = {types: []};
var autocomplete = new google.maps.places.Autocomplete(location, options);
};
$("#location").on("focus", autosuggest);
$(":button[name='Geocode']").on("click", getLatLng);
});
you now have a local variable named location that reference the #location element in your document.
I am trying ReverseGeCoding its working but i cant get return value
function reverseGeoCode(lat,lng) {
var reverseGeoAddress = '';
var geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(lat, lng);
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
if(results[1].formatted_address.length){
reverseGeoAddress = results[1].formatted_address;
//NOTE: when i console.log(reverseGeoAddress );
//its working fine i am getting the address
return reverseGeoAddress;
//but return not working.
}
}
}
});
}
when i call my function like
var address = reverseGeoCode(31.518945,74.349316);
now every time my address variable is "undefined";
why is this doing so??
Any hint ?
Function reverseGeoCode is not having any return value
return reverseGeoAddress; is inside anonymous function.
Simple fix would be - you can possibly use callback since it is asynchronous function. "callback" can be a handler from the place you invoke.
// Invoking reverseGeoCode....
reverseGeoCode(lat,lng, function(myAddress){
// Your custom code goes here...
});
function reverseGeoCode(lat,lng, callback) {
var reverseGeoAddress = '';
var geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(lat, lng);
geocoder.geocode({'latLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
if(results[1].formatted_address.length){
reverseGeoAddress = results[1].formatted_address;
// Callback the handler if it exists here
// No return value
callback(reverseGeoAddress);
}
}
}
});
}