I have the following code:
function codeAddress(){
geocoder = new google.maps.Geocoder();
for (var i=1; i < 4; i++){
var sAddress =document.getElementById("search_postcode" + i).value ;
var loc=[];
geocoder.geocode({ 'address': sAddress}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK)
{
loc[0] = results[0].geometry.location.lat();
loc[1]=results[0].geometry.location.lng();
document.getElementById("geo_lat" + i).value = loc[0];
document.getElementById("geo_lon" + i).value = loc[1];
}
else
{
alert(status);
}
}); //end geocode function
} //end for
} //end codeAddress function
Can anybody see why the variable i isnt getting set? The code works fine if I replace the i's with a number, but in the javascript error console, i isnt being defined so var sAddress is NULL.
EDIT
The following code gives the correct answer when typed into the console when I put a breakpoint immediately after the defining of the 'for' loop:
Why would it not work in code but will work when manually typed into the console?
If the exact code works with i replaced with numbers as you say then it looks like the problem is that by the time your callback is called the captured i will be 4 (which if it doesn't cause your current issue will cause future issues)
Try this (copies i into a new scope):
function codeAddress(){
geocoder = new google.maps.Geocoder();
for (var i=1; i < 4; i++){
var sAddress =document.getElementById("search_postcode" + i).value ;
var loc=[];
geocoder.geocode({ 'address': sAddress}, (function(i){
return function(results, status) {
if (status == google.maps.GeocoderStatus.OK)
{
loc[0] = results[0].geometry.location.lat();
loc[1]=results[0].geometry.location.lng();
document.getElementById("geo_lat" + i).value = loc[0];
document.getElementById("geo_lon" + i).value = loc[1];
}
else
{
alert(status);
}
};
})(i)); //end geocode function
} //end for
} //end codeAddress function
Otherwise if document.getElementById("search_postcode" + i) is returning null in your function and not in the console then it probably means your code is running before the document has loaded
check whether perticular Id exists or not before invoking the getElementById method,
Related
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
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");
}
});
}
I'm new to jquery but I am having a bit of a hard time at the moment. This is as far as I can get, the eventual idea is to do the following:
User types in an address and clicks search
Google Geocoder runs
Either error if not result, or grab co-ordinates, state, zip, country, city and print in a message box
The code I have at the moment is not even able to complete the process of grabbing the coordinates from the input box. It keeps telling me it is expecting a bracket but no matter where I put the bracket I cannot get it to run.
This is my trying to run:
http://jsfiddle.net/QA7Xr/16/
Here is the complete code:
var myLatlng = new google.maps.LatLng(31.272410, 0.190898);
// INITALIZATION
function initialize() {
var mapOptions = {
zoom: 4,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
}
// GEOCODE
function codeAddress() {
var address = document.getElementById("address").value;
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
alert("Geocode was successful");
};
} else {
alert("Geocode was not successful for the following reason: " + status);
};
};
}
// GET ADDRESS DETAILS
function getLatLongDetail() {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
'latLng': myLatlng
},
function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[0]) {
var address = "",
city = "",
state = "",
zip = "",
country = "";
for (var i = 0; i < results[0].address_components.length; i++) {
var addr = results[0].address_components[i];
// check if this entry in address_components has a type of country
if (addr.types[0] == 'country') country = addr.long_name;
else if (addr.types[0] == 'street_address') // address 1
address = address + addr.long_name;
else if (addr.types[0] == 'establishment') address = address + addr.long_name;
else if (addr.types[0] == 'route') // address 2
address = address + addr.long_name;
else if (addr.types[0] == 'postal_code') // Zip
zip = addr.short_name;
else if (addr.types[0] == ['administrative_area_level_1']) // State
state = addr.long_name;
else if (addr.types[0] == ['locality']) // City
city = addr.long_name;
}
alert('City: ' + city + '\n' + 'State: ' + state + '\n' + 'Zip: ' + zip + '\n' + 'Country: ' + country);
}
}
});
}
initialize();
getLatLongDetail();
Can anyone tell me where I am going wrong please? I've hit a dead end with this.
Your JS was a mess, I've tidied it up: http://jsfiddle.net/QA7Xr/19/
In order:
Two extra close brackets in a function
You used getElementById() using an ID that did not exist
You bound an onClick when a JS assignment is easier
Your geocoder var was local within getLatLongDetail. You needed it in codeAddress, so I've made it global.
Points to improve:
Wrap your code in a closure to avoid namespace pollution
Use the Google events to control your code assignments. Right now, if a user clicks too quickly, your code will throw up
Simplify the logic
Here is the updated link,
http://jsfiddle.net/QA7Xr/24/
geocoder.geocode({}, function(){....}); /*not closed properly*/
and there are improper usage of semicolon.
Hi I have some trouble with an array with a for in JavaScript. Let's have a look:
var Villes = [
['Versailles+France', 'upr2.png'],
['Paris+France', 'upr5.png'],
['Bruxelle+Belgique', 'upr4.png'],
['Manchester+Angleterre', 'upr1.png'],
['Monaco+Monaco', 'upr3.png']
];
function initialize() {
var mapOptions = {
zoom: 5,
center: new google.maps.LatLng(46.225453,2.219238),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
var geocoder = new google.maps.Geocoder();
for (var i = 0; i < Villes.length; i++) {
var ville = Villes[i];
geocoder.geocode( { 'address': ville[0]}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({position: results[0].geometry.location,map: map,icon: ville[1]});
alert(ville[1] + status);
} else {
alert("Geocode n'a pas fonctionner. Erreur: " + status);
}
});
}
}
My Map comes with all my marker but the icon never change like ville[1] is a static call to upr3.png I'm not used to JS and it's the first time I see that.
By the time the callback you give to geocode is called, i has the value of end of loop.
The usual generic solution is to protect it by an immediately called function expression :
for (var i = 0; i < Villes.length; i++) {
(function(ville){
geocoder.geocode( { 'address': ville[0]}, function(results, status)
...
});
})(Villes[i]);
}
As the scope of a variable is the function in which it is declared, this makes the new variable ville immune to the variation of the loop.
The geocode call is asynchronous, which means that you will loop through all the places and send requests, then the responses will arrive. At that time you have already run through the loop, and the ville variable has the value of the last place.
Put a function expression around the code in the loop, so that each iteration has its own copy of the variable:
for (var i = 0; i < Villes.length; i++) {
(function(ville){
geocoder.geocode( { 'address': ville[0]}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({position: results[0].geometry.location,map: map,icon: ville[1]});
alert(ville[1] + status);
} else {
alert("Geocode n'a pas fonctionner. Erreur: " + status);
}
});
})(Villes[i]);
}
The problem is that ville is not an array, so by the time the for loop finishes, ville only has the value of the last item in your initial array (png3). You need call the function right after setting the value to ville
I don't know how to search for this in SO, so I'm asking a new question. What could cause or what is the concrete problem of my code: HTML generated by Javascript (createElement() and appendChild) is not being shown in Opera and Firefox, but it works in Chromium.
The HTML generating code:
function typesOfPlaces(map, bounds) {
var allowedTypes = [
"amusement_park",
"aquarium",
"art_gallery",
"cemetery",
"church",
"city_hall",
"hindu_temple",
"mosque",
"museum",
"night_club",
"park",
"place_of_worship",
"rv_park",
"spa",
"synagogue",
"travel_agency",
"zoo"
];
var typesToDisplay = new Array();
var request = {
bounds: bounds,
types: allowedTypes
};
var service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, function(results, status) {
if(status == google.maps.places.PlacesServiceStatus.OK) {
for(var i = 0; i < results.length; i++) {
for(var j = 0; j < results[i].types.length; j++) {
for(var k = 0; k < allowedTypes.length; k++) {
if(results[i].types[j] == allowedTypes[k]) {
var allowed = true;
for(var x = 0; x < typesToDisplay.length; x++) {
if(allowedTypes[k]==typesToDisplay[x]) {
allowed = false;
}
}
if(allowed) {
typesToDisplay.push(allowedTypes[k]);
}
}
}
}
}
var parent = document.getElementById("types");
for(var i = 0; i < typesToDisplay.length; i++) {
var typeBox = document.createElement("div");
var checkBox = document.createElement("input");
var checkID = randomString(10);
var label = document.createElement("label");
checkBox.setAttribute("type", "checkbox");
checkBox.setAttribute("id", checkID);
label.setAttribute("for", checkID);
label.innerHTML = typesToDisplay[i];
typeBox.appendChild(checkBox);
typeBox.appendChild(label);
parent.appendChild(typeBox);
}
}
});
}//END OF Function
UPDATE TO COMMENTS
The randomString is just SO'ed code for generating random string:
function randomString(L) {
var s= '';
var randomchar=function() {
var n= Math.floor(Math.random()*62);
if(n<10) return n; //1-10
if(n<36) return String.fromCharCode(n+55); //A-Z
return String.fromCharCode(n+61); //a-z
}
while(s.length< L) s+= randomchar();
return s;
}
div #types really exists, it look like this:
<html>
<head>
...
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=MyKey&sensor=false&libraries=places&language=lt"></script>
</head>
<body>
<div>
<div>
<div id="types"></div>
</div>
</div>
</body>
</html>
You can see the import of google.maps.places.PlacesService by looking at the <head> section of the <script> tag, where you can see "&libraries=places".
SECOND UPDATE AFTER SOME TESTING
ok. I've figured out that if I deny location sharing in opera it works (it works in chromium because by default it does not even ask user if he is kind to share his geolocation with website)
The code for geolocation:
function initGeo()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(successFunction, errorFunction);
}
else
{
errorFunction();
}
}
so, the function that does not work is successFunction (which is being launched if user kindly shares his geolocation)
function successFunction(position)
{
var geocoder = new google.maps.Geocoder();
var abstract_location;
var latlng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
geocoder.geocode({'latLng': latlng}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
abstract_location = new google.maps.LatLngBounds(
results[0].geometry.viewport.getSouthWest(),
results[0].geometry.viewport.getNorthEast());
}
else
{
alert("NOT SUCCESS 1");
}
showGMap(latlng, abstract_location);
});
}
And the errorFunction, which successfully works on chromium by default and on Opera if you deny access to your geolocation:
function errorFunction(error)
{
var geocoder = new google.maps.Geocoder();
if(google.loader.ClientLocation)
{
var latlng = new google.maps.LatLng(google.loader.ClientLocation.latitude, google.loader.ClientLocation.longitude);
geocoder.geocode({'latLng': latlng}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
var abstract_location = new google.maps.LatLngBounds(
results[0].geometry.viewport.getSouthWest(),
results[0].geometry.viewport.getNorthEast());
}
else
{
alert("NOT SUCCESS 2");
}
showGMap(latlng, abstract_location);
});
}
else
{
geocoder.geocode( {'address': 'Vilnius Region, Lithuania'}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
var latlng = results[0].geometry.location;
var abstract_location = new google.maps.LatLngBounds(
results[0].geometry.viewport.getSouthWest(),
results[0].geometry.viewport.getNorthEast());
showGMap(latlng, abstract_location);
}
else
{
alert("NOT SUCCESS 3");
}
});
}
}
Nor Chromium nor Opera does not give me ANY errors, nor javascript exceptionaly, nor in general.
So the problem is in success function. Because it even does not give me alert(typesToDisplay.length) [as suggested by Stuart in the comments] - it means that there is no alert at all - in case of error function I get the aswer 4 and thus i can see my generated HTML.
In case of success function there is just empty (without any appended childs) #types .
I do not see what could be causing success function to be NOTSUCCESS (:))
Ok, so i have figured it out - it was pretty simple though...
The Geolocation data which you get is an address, so bounds are very small, you have to extract city with reverse geocoding (results[6].formatted_address) and then you geocode that reverse geocode (so confused though Geocoding -> reverse -> again geocode) and then it works!
So the problem was at geocoding (haven't thought that bounds of address is not the whole city (that should have been obvious in the first place, but was not).
HTML5 geocoding could have the info about the city (not only lan and lng, firefox has something, but that's only firefox, not the whole HTML5), but i do not know if it would be good or not (lack of my personal knowlede at the moment in this specific field)
So if anyone does get to something similar -> check the bounds ;)
Thank you for your comments and for your view's.