Can anyone see any problems with my function?
I call the function like so:
var elevation = getElevation(tempWaypt);
tempWaypt is a LatLng Object Literal, and it keeps telling me that
elevation
is undefined!
function getElevation(location) {
elevator.getElevationForLocations({
'locations': [location]
}, function(results, status) {
if (status === 'OK')
{
if (results[0])
{
return results[0].elevation;
}
}
});
}
Im using the function to determine if the LatLng is on land, or in sea!
Also, when ever I set a variable in the getElevation function equal to:
results[0].elevation
It gives me the correct answer
A lot of Google Maps API services are asynchronous. Should you want to access the result, you could do but not limited to the following way, or using a Promise.
var elevation;
function getElevation(location) {
..., function(results, status) {
...
if (results[0]) {
elevation = results[0];
}
...
}
Using a Promise
getElevation.then(function(elevation){
console.log("Elevation: " + elevation);
});
function getElevation(location) {
return new Promise(function(resolve, reject) {
//...
function(results, status) {
//...
if (results[0]) {
resolve(results[0]);
} else {
reject('Your reason ...');
}
//...
}
}
Elevation can be a tricky way to figure out if a point is on water or land because many dry places on earth exist at or below sea level. You may want to get a more explicit answer using a data source that deals specifically with water.
I work for a company that offers a free web API to determine if points are on water or land. We use it internally. It is called onwater.io and it is fairly straight forward: given a latitude and longitude it will accurately return true or false via a get request.
Example on water:
https://api.onwater.io/23.92323,-66.3
{
lat: 23.92323,
lon: -66.3,
water: true
}
Example on land:
https://api.onwater.io/42.35,-71.1
{
lat: 42.35,
lon: -71.1,
water: false
}
Since you're using JavaScript, here is an example jQuery snippet you might use:
function is_water_huh(lat, lon) {
$.get( "https://api.onwater.io/api/v1/results/" + lat + "," + lon, function( data ) {
return data['water'];
});
}
alert(is_water_huh(23.92323, -66.3));
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.
I am teaching myself scripting and have learned a lot. I am, however, stuck at this one point. I am wanting to display a weather map and have it center to the users location. Here is what I have in the body of my html so far..
<div id="map-canvas"></div>
<div id="loading">Loading animation layers... <br>
<span id="progress"></span>% done.
</div>
<script type="text/javascript">
var map, radar, satellite;
var animationSync;
// GeoLocation Services
function showLocation(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
}
function errorHandler(err) {
if(err.code == 1) {
alert("Error: Access is denied!");
}
else if( err.code == 2) {
alert("Error: Position is unavailable!");
}
}
function getLocation(){
if(navigator.geolocation){
// timeout at 60000 milliseconds (60 seconds)
var options = {timeout:60000};
navigator.geolocation.getCurrentPosition(showLocation, errorHandler, options);
}
else{
alert("Sorry, browser does not support geolocation!");
}
}
// End GeoLocation Services
map = new aeris.maps.Map('map-canvas', {zoom: 9, center: [36.0462, -96.9942]});
// here is what I am wanting to do instead of the above line..
// map = new aeris.maps.Map('map-canvas', {zoom: 9, center: [latitude +',' + longitude]});
I can display the map perfectly if I hard code the LAT and LON but thats not what I need. I am confident my GeoLocation routine is working as the console in my browser does not show any errors, its only when I try to center the map using LAT and LONG as variables that I have a problem. I am hoping this is just a syntax type issue, but I just don't know enough to figure this out. I have also tried using the map.setCenter command but can't figure where to use it so it works.
Thanks in advance for any help.
Just replace the last line by
map = new aeris.maps.Map('map-canvas', {zoom: 9, center: [latitude, longitude]});
The quotes were not needed and transformed your array with 2 values in an array with a single string value
Current issue
The issue right now is you're performing string concatenation with latitude and longitude. You can just use them as normal inside the array:
map = new aeris.maps.Map('map-canvas', {zoom: 9, center: [latitude, longitude]});
More info that may be of use:
The thing to remember is that both these variables need to be in scope, which they currently aren't. latitude and longitude exist only inside showLocation(), and to further complicate things, it's a callback which means your new aeris.maps.Map() will fail because neither values are set.
If you're just trying to display a map around the position of the current user, this should do it:
var map, radar, satellite;
var animationSync;
// GeoLocation Services
function showLocation(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
map = new aeris.maps.Map("map-canvas", {
zoom: 9,
center: [latitude, longitude]
});
}
function errorHandler(err) {
if (err.code == 1) {
alert("Error: Access is denied!");
} else if (err.code == 2) {
alert("Error: Position is unavailable!");
}
}
function getLocation() {
if (navigator.geolocation) {
// timeout at 60000 milliseconds (60 seconds)
var options = {
timeout: 60000
};
navigator.geolocation.getCurrentPosition(showLocation, errorHandler, options);
} else {
alert("Sorry, browser does not support geolocation!");
}
}
getLocation();
It's a bit tricky since the action happens asynchronously, meaning anything you do with map have to happen after showLocation is called.
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.
I'm developing with Nokia Maps (a wonderful option I really love them) but I'm only able to get the location (latitude and longitude) with HTML5 but I can't the name where I am :/, maybe somebody could give an idea, how to do it, thank you very mach for your help.
Maps API for JavaScript 3.x
The current 3.x JavaScript API offers a thin wrapper around the REST Geocoder API. You need to make a ReverseGeocode search, and then extract the data from the Location object(s) found in the result.
A fully working reverse geocoding example can be found here, but the important bit (getting the address) can be see below:
function reverseGeocode(platform) {
var geocoder = platform.getGeocodingService(),
reverseGeocodingParameters = {
prox: '52.5309,13.3847,150', // Location
mode: 'retrieveAddresses',
maxresults: '1',
jsonattributes : 1
};
geocoder.reverseGeocode(
reverseGeocodingParameters,
function (result) {
var locations = result.response.view[0].result;
// ... etc.
},
function (error) {
alert('Ooops!');
}
);
}
Maps API for JavaScript 2.x (deprecated)
With the recently deprecated 2.x JavaScript API, again you need to make a ReverseGeocode search, and then extract the data from the Address object found in the result.
The code is a bit longer, but the important bit (getting the address) can be seen below:
// Function for receiving search results from places search and process them
var processResults = function (data, requestStatus, requestId) {
var i, len, locations, marker;
if (requestStatus == "OK") {
// The function findPlaces() and reverseGeoCode() of return results in slightly different formats
locations = data.results ? data.results.items : [data.location];
// We check that at least one location has been found
if (locations.length > 0) {
for (i = 0, len = locations.length; i < len; i++) {
alert(locations[i].address.street);
alert(locations[i].address.state);
}
} else {
alert("Your search produced no results!");
}
} else {
alert("The search request failed");
}
};
/* We perform a reverse geocode search request: translating a given
* latitude & longitude into an address
*/
var reverseGeoCodeTerm = new nokia.maps.geo.Coordinate(
52.53099,
13.38455
);
nokia.places.search.manager.reverseGeoCode({
latitude: reverseGeoCodeTerm.latitude,
longitude: reverseGeoCodeTerm.longitude,
onComplete: processResults
});