I am trying to write a method which will take in some data and try to find the coordinates using the .geocode method from the google maps API. Due to the data not being completely correct some of the data will not be found and therefore will not have a coord assigned to it. So i need a function to either store the coordinates for correct data or store "fail" for erroneous data. This is what i have:
function codeAdd(callback) {
geocoder.geocode( { 'address': geoName}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var arr = [results[0].geometry.location.lat(),results[0].geometry.location.lng()];
callback('ok',arr);
} else {
callback('fail',null);
}
});
}
function codeAddCall(){;
codeAdd(function(status,callback) {
if(status == 'ok'){
latArray.push(callback[0]);
lngArray.push(callback[1]);
console.log("add success");
}
if(status == 'fail'){
latArray.push("fail");
lngArray.push("fail");
}
if((latArray.length==lngArray.length)&&(latArray.length==infArray.length)){
convertToAssoc(infArray,latArray,lngArray);
}
});
}
However with the "status" condition it completes the data set correctly, i.e putting the results in the right places and any erroneous data is stored with "fail" in the lat and lng array. However it causes browsers to crash(latest versions of chrome and firefox).
I really dont undertstand why this is breaking ?
Still can't get anything working can anyone help ?
You made a typo:
function codeAddCall(){);
^
Maybe this is why your code fails.
Related
This question already has an answer here:
Reverse Geocoder Returning undefined
(1 answer)
Closed 1 year ago.
I am a newbie in web development. Today, I am trying to use Google Map API to get the country name and the state name from longitude and latitude using JavaScript. I read the documentation from the Google Map API and did some research but I was kinda confused about this. I gave it a go and this is what I did:
function getCountryName(latitude, longitude){
var country;
const geocoder = new google.maps.Geocoder();
geocoder.geocode({location: {lat: latitude, lng: longitude}}, (results, status) => {
if(status === "OK"){
if(results[0]){
country = results[0].address_components[0].types[0].country;
}
else{
country = "N/A";
}
}
});
return country;
}
However, I keep getting the "undefine" result. Is there anything wrong with my approach?
Thanks you all in advance!
You seem to be confused about the asynchronous programming happening here.
Basically you have return country; statement at the end of function execution which will always be undefined since the results haven't been fetched by that time.
The 2nd parameter that you are sending to the geocoder.geocode is a callback function that will be called once google has fetched the results which obviously takes a little bit of time.
So your function should be something like this
function getCountryName(latitude, longitude, onSucess){
const geocoder = new google.maps.Geocoder();
geocoder.geocode({location: {lat: latitude, lng: longitude}}, (results, status) => {
if(status === "OK"){
if(results[0]){
onSucess(results[0].address_components[0].types[0].country);
}
else{
onSucess("N/A");
}
}
});
return country;
}
And when you are about to use this function elsewhere, you have to use it like this
getCountryName(1.1111, 2.2222, (country) => {
alert(country);
console.log(country);
// You can do anything here like showing it to ui or using it elsewhere
}
If you want to learn more about callbacks in JS, go through this Article.
I created a function making use of Googles Geocoder API to perform a reverse geolocation. It pulls lat/lon from the browser's native functions and sends them through to Google. The intent of the function is to get the approximate street address of the user (ie. 123 Fake Street). The City/Municipality, Province/State, Country and Post code are not wanted, just the street address.
function geoSuccess(pos) {
Geocoder = new google.maps.Geocoder;
Geocoder.geocode({location: {lat:pos.coords.latitude,lng:pos.coords.longitude}}, function(r, s) {
if (s === 'OK') {
var found = false,
x = 0;
do {
if (r[x].address_components[0].types.indexOf('route') !== -1) {
found = true;
}
x++;
} while(!found && x < r.length);
alert(r[x-1].address_components[0].long_name);
}
});
}
Based on how the function works, it scans through the resulting JSON to find the route. However, there is a discrepancy for mobile devices where the accuracy is different than desktops. Despite searching for route, frequently mobile devices will return either the wrong data (closest highway).
After looking at the comments made (and revising the question), the function was rewritten. Nested loops through the JSON were made to tally up all of the unique data from the query. From their, street address was manually recreated instead of relying on Google to provide the desired result.
function geoSuccess(pos) {
var Geocoder = new google.maps.Geocoder;
Geocoder.geocode({location: {lat:pos.coords.latitude,lng:pos.coords.longitude}}, function(r, s) {
if (s === 'OK') {
var addr = [];
r.each(function(o) {
o.address_components.each(function(a) {
addr[a.types.join('.')] = a.long_name
});
});
alert(addr['street_number']+' '+addr['route']);
}
});
}
So far this stands as the best way I found to get the data I wanted.
Hello smarter than me people. ;)
I really cannot figure this weird behaviour of my code out.
What it is supposed to do is to execute the function fixedlocation() when a button is pressed in order to check if a valid address can be found and then execute some code.
In order to check if it works properly I have an alert in the code which gives me the state of the Boolean that should be changed. Now I really dont get why, but it only works from the second time the button is pressed onwards. Meaning that even if a valid address can be found, the first time the alert will pop up with a false...
At first I thought it must have something to do with where I defined the variable but then it couldnt work the second time could it?
Any help or pointing in the right direction would be much appreciated.
var geoinfobool=new Boolean();
function fixedlocation()
{
var addresscoordinates = new google.maps.LatLng(document.getElementById('addresslat').value,document.getElementById('addresslng').value)
geocoder.geocode({'latLng': addresscoordinates}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
geoinfoavailable(true);
//do other stuff in here//
}
else
{
geoinfoavailable(false);
//do other stuff in here//
}
});
alert(geoinfobool);
}
function geoinfoavailable(state)
{
geoinfobool = state;
}
In your code geocoder is not defined .
Try
var addresscoordinates = new google.maps.LatLng(document.getElementById('addresslat').value,document.getElementById('addresslng').value);
var geocoder = new google.maps.Geocoder();
geocoder.geocode({'latLng': addresscoordinates}, function(results, status)
{
I wonder whether someone may be able to help me please.
This page allows users to filter (via checkboxes), markers which are placed on the map. Clicking on any marker performs a 'reverse geocode' action and in conjunction with selecting the 'Search Locations' button, the user can then see POI's within a given radius of the clicked marker.
For demo purposes, if you select the 'Coin' checkbox, click the green marker, then select the 'Search Locations' button, the marker will bounce and the right hand sidebar will be populated with POI's.
The problem I'm having is that in Internet Explorer everything works fine, but when I try to run this in Chrome, the marker looses the 'bounce' functionality, the 'reverse geocode' doesn't run and in the error console I receive the following error:
Uncaught ReferenceError: reversegeocode is not defined at line 55 of my code which is:
reversegeocode(); I've done some reading on this and other sites and from reading the guidance I've tried changing this part of my code to this:
function geocodePosition(pos) {
var clickListener =
document.getElementById('findosgb36lat').value = this.mylat;
document.getElementById('findosgb36lon').value = this.mylon;
document.getElementById('address').value = this.myaddress;
if(bouncingMarker)
bouncingMarker.setAnimation(null);
if(bouncingMarker != this) {
this.setAnimation(google.maps.Animation.BOUNCE);
bouncingMarker = this;
}
else bouncingMarker = null;
}
geocoder.geocode({latLng: pos }, function(responses) {
if (responses && responses.length > 0) {
updateMarkerAddress(responses[0].formatted_address);
} else {
updateMarkerAddress('Cannot determine address at this location.');
}
});
}
function updateMarkerAddress(str) {
document.getElementById('address').value = str;
}
function getAddress(latlng) {
if (!geocoder) {
geocoder = new google.maps.Geocoder();
}
geocoder.geocode({ 'latLng': latlng }, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
// Looping through the result
for (var i = 0; i < results.length; i++) {
if (results[0].formatted_address) {
document.getElementById('address').value =
results[0].formatted_address;
}
}
}
}
)
}
But unfortunately, this doesn't work and actually creates more problems with syntax errors.
I'm relatively new to Javascript, so perhaps I've totally misunderstood,. But I just wondered whether someone could possibly take a look at this please and let me know where I'm going wrong?
Many thanks and kind regards
Code feedback:
What is the second line in your code: var clickListener = meant to do (something is missing)?
Both of your calls to geocoder.geocode pass an object with a property named: latLng; the object passed should match the structure of google.maps.GeocoderRequestapi-doc, which has properties named: address, bounds, location, and region. I suggest you change the name of these properties from: latLng to location.
I'm not sure of the context of the code shown, but the usage of this in this code section looks suspicious:
if(bouncingMarker != this) {
this.setAnimation(google.maps.Animation.BOUNCE);
bouncingMarker = this;
}
It looks like you are within a global function, so it looks like the use of this may not make sense here?
That's all I see after a first pass; hope this helps you -
i still have some problems with javascript closures, and input/output variables.
Im playing with google maps api for a no profit project: users will place the marker into a gmap, and I have to save the locality (with coordinates) in my db.
The problem comes when i need to do a second geocode in order to get a unique pairs of lat and lng for a location: lets say two users place the marker in the same town but in different places, I dont want to have the same locality twice in the database with differents coords.
I know i can do the second geocode after the user select the locality, but i want to understand what am i mistaking here:
// First geocoding, take the marker coords to get locality.
geocoder.geocode(
{
'latLng': new google.maps.LatLng($("#lat").val(), $("#lng").val()),
'language': 'it'
},
function(results_1, status_1){
// initialize the html var inside this closure
var html = '';
if(status_1 == google.maps.GeocoderStatus.OK)
{
// do stuff here
for(i = 0, geolen = results_1[0].address_components.length; i != geolen)
{
// Second type of geocoding: for each location from the first geocoding,
// i want to have a unique [lat,lan]
geocoder.geocode(
{
'address': results_1[0].address_components[i].long_name
},
function(results_2, status_2){
// Here come the problem. I need to have the long_name here, and
// 'html' var should increment.
coords = results_2[0].geometry.location.toUrlValue();
html += 'some html to let the user choose the locality';
}
);
}
// Finally, insert the 'html' variable value into my dom...
//but it never gets updated!
}
else
{
alert("Error from google geocoder:" + status_1)
}
}
);
I tryed with:
// Second type of geocoding: for each location from the first geocoding, i want
// to have a unique [lat,lan]
geocoder.geocode(
{
'address': results_1[0].address_components[i].long_name
},
(function(results_2, status_2, long_name){
// But in this way i'll never get results_2 or status_2, well, results_2
// get long_name value, status_2 and long_name is undefined.
// However, html var is correctly updated.
coords = results_2[0].geometry.location.toUrlValue();
html += 'some html to let the user choose the locality';
})(results_1[0].address_components[i].long_name)
);
And with:
// Second type of geocoding: for each location from the first geocoding, i want to have
// a unique [lat,lan]
geocoder.geocode(
{
'address': results_1[0].address_components[i].long_name
},
(function(results_2, status_2, long_name){
// But i get an obvious "results_2 is not defined" error (same for status_2).
coords = results_2[0].geometry.location.toUrlValue();
html += 'some html to let the user choose the locality, that can be more than one';
})(results_2, status_2, results_1[0].address_components[i].long_name)
);
Any suggestion?
EDIT:
My problem is how to pass an additional arguments to the geocoder inner function:
function(results_2, status_2, long_name){
//[...]
}
becose if i do that with a clousure, I mess with the original parameters (results_2 and status_2)
If I'm understanding you correctly:
Your problem in the first example is that the second (innermost) geocode's callback function (which appends the string to html) will not have executed by the time you reach the line with the comment Finally, insert the 'html' variable value into my dom....
You are effectively launching the second geocode request, and then inserting html before the operation has completed.
Regarding passing an extra argument to the callback, you could always make a function that creates and returns a function:
eg.
function(my_argument)
{
return(function(cb1,cb2) { ... });
}(my_argument_value);
Then you can pass in whatever you want for my_argument_value, and the innermost code (...) will see it as well as the two callback args.
The return value of this function is what you pass as the callback to the geocode call.