I'm trying to add multiple markers using address, and I'm struggling for hours to fix it, my JSON have 4 address and only iterate the first one then stop, but it wont add any markers. Someone can point where I'm missing?
function successAvoid(data, textStatus) {
var geocoder;
var map;
var myOptions = {
center: new google.maps.LatLng(0, 0),
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map-page"), myOptions);
$.each(data, function (i, x) {
geocoder.geocode({ 'address': x.address}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
map: map,
position: results[i].geometry.location
});
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
});
}
Try inserting return true after the geocoder.geocode call. If it is returning false, it is probably canceling the each loop.
From jquery.com:
We can break the $.each() loop at a particular iteration by making the callback
function return false. Returning non-false is the same as a continue statement in
a for loop; it will skip immediately to the next iteration.
Related
fairly new to javascript and trying to make a simple map application. I am trying to center a new map around an address that is passed through a function. The issue I have is it is always being returned null which I do not understand, do I have to specify return types in the function format?
My code:
<script>
var geocoder;
var map;
function initialize() {
var address = document.getElementById('address').value;
var latlng = GetLatLong(address);
alert(latlng);
var mapOptions = {
zoom: 8,
center: latlng
}
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
}
function GetLatLong(address) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
alert(results[0].geometry.location)
return results[0].geometry.location;
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
I have a div for the address text and a div for the map location. To debug I put alert("") in some places to see the order in which it gets called on runtime, why would the line I put the first alert be called before the function is called?
Thanks
The Google Maps API call that you are performing is asynchronous. In layman's terms that means that as soon as you start the call, the rest of your program keeps executing independent of it. It is essentially running to the side of the rest of your program. The purpose of the function that you pass to the geocoder call is to deal with the data that the call returns asynchronously.
You would need to change your code to do something like this:
function initialize() {
var address = document.getElementById('address').value;
GetLatLong(address);
}
var map;
function GetLatLong(address) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
alert(results[0].geometry.location)
var latlng = results[0].geometry.location;
var mapOptions = {
zoom: 8,
center: latlng
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
Ive been working on a Google Maps application and have hit a hurdle due to a lack of knowledge in js me thinks?!
So... here's my JSON object
{"pickuppoint0":"LE9 8GB","pickuppoint1":"LE2 0QA","pickuppoint2":"LE3 6AF","pickuppoint3":"LE2 8GB","pickuppoint4":"LE8 8TE","pickuppoint5":"LE2 2GB","pickuppoint6":"LE1 6AF"}
And here's a loop through the JSON object...
$.each(alltravelgroups, function(k, v){
for(var i=0; i < boxes.length; i++){
var bounds = boxes[i];
if(bounds.contains(getLatLng(v))){
alert("im here");
}
}
});
And here's my getLatLng() method I've created...
function getLatLng(pickuppoint) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode( { 'address': pickuppoint}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
return results[0].geometry.location
} else {
alert('getLatLng Geocode was not successful for the following reason: ' + status);
}
});
}
Now... what I'm trying to do is simply take the value from each key/value pair and produce a LatLng object that can then be used within the "bounds.contains()" method for searching within the bounds box provided by the RouteBoxer class.
The problem I'm facing is the value returned by the getLatLng method is "undefined" when using alert(getLatLng(v)) and should just be a 'location' containing both latitude and longitde? Anyone able to point what I'm doing wrong?
Please refer the link below.
http://jsfiddle.net/y829C/13/
var mapOptions = {
center: new google.maps.LatLng(-33.8665433, 151.1956316),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
In the above code, semicolon is missing in return results[0].geometry.location.
I am having issues passing two coordinates from one function to another. I don't really know JavaScript, but it seems to be somewhat correct. Could you please let me know where is my error?
<script type="text/javascript">
function initialize() {
var address = "Chicago IL";
locs= getLatLong(address);
alert(locs.lat()); //does not work
var myOptions = {
zoom: 4,
center: new google.maps.LatLng(41, -87),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_canvas'),
myOptions);
}
function getLatLong(address){
var geo = new google.maps.Geocoder;
geo.geocode({'address':address},function(results, status){
if (status == google.maps.GeocoderStatus.OK) {
locations[0] = results[0].geometry.location.lat();
locations[1] = results[0].geometry.location.lng();
//alert(locations[0]); //test is good- works! Need to pass it back to function
//alert(locations[1]); //test is good- works! Need to pass it back to function
locs =results[0].geometry.location;
return locs;
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
</script>
It is not possible to return a value from an asynchronous function. Do not try it.
Use a callback instead.
function setLocationOnMap(locs) {
alert(locs.lat()); // works now!
var myOptions = {
zoom: 4,
center: new google.maps.LatLng(41, -87),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
}
function initialize() {
var address = "Chicago IL";
getLatLong(address, setLocationOnMap);
}
function getLatLong(address, callback){
var geo = new google.maps.Geocoder;
geo.geocode({'address':address},function(results, status){
if (status == google.maps.GeocoderStatus.OK) {
// processing...
locs = results[0].geometry.location;
callback(locs);
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
You must understand that asynchronous function calls like geo.geocode() return immediately, i.e. before any result is ready. That's why you can't use return to return a value from them - they don't have it yet.
Once the result (most often, an HTTP request) is ready, the asynchronous function relies on a callback function to handle it. You must do all your further processing in that callback function, either directly or by making another function call.
I've been cobbling together various bits of code from around the internet (including StackOverflow) and I've got a working map (almost) which geocodes postcodes from an array and creates infowindows for each one.
Two problems:
1) my info windows, which should take their text from another array, always use the last array value
2) i can't get the map to center automatically. I'm using a bit of code which has worked in other circumstances, but it doesn't in my code.
The code is fairly self-explanatory:
var geocoder = new google.maps.Geocoder();
var map = new google.maps.Map(document.getElementById('map'), {
//zoom: 10,
//center: new google.maps.LatLng(-33.92, 151.25),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var postcodes = [
"EH14 1PR",
"KY7 4TP",
"IV6 7UP"
];
var descriptions = [
"Slateford",
"Cortachy",
"Marybank"
];
var markersArray = [];
var infowindow = new google.maps.InfoWindow();
var marker, i, address, description;
for(var i = 0; i < postcodes.length; i++) {
address = postcodes[i];
description = descriptions[i];
geocoder.geocode(
{
'address': address,
'region' : 'uk'
},
function(results, status){
if (status == google.maps.GeocoderStatus.OK) {
marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map
});
markersArray[i] = marker;
console.log(markersArray[i]);
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(description);
infowindow.open(map, marker);
}
})(marker, i));
} else {
alert("Geocode was not successful for the following reason: " + status);
return false;
}
}
);
var bounds = new google.maps.LatLngBounds();
$.each(markersArray, function (index, marker) {
bounds.extend(marker.position);
});
map.fitBounds(bounds);
console.log(bounds);
}
Any thoughts? The issue seems to be with the value of the counter i inside the geocode function.
Any help much appreciated!
1) my info windows, which should take their text from another array,
always use the last array value
2) i can't get the map to center automatically. I'm using a bit of
code which has worked in other circumstances, but it doesn't in my
code.
1) Yes this is a closure issue. This is how I get around it.
I create an object to store all of the properties I will be using. In your example I am going to use the postcode and the description.
function location(postalcode, desc){
this.PostalCode = postalcode;
this.Description = desc;
}
Now do a quick loop to add all the location objects to an array.
var locations = [];
for(var i = 0; i < postcodes.length; i++) {
locations.push(new location(postcodes[i], descriptions[i]));
}
Extract the geocode functionality into its own function with a parameter to take a location object. Then you can loop through the location object array and geocode each individually. So now both the post code and description are in scope when the request is built and sent.
function GeoCode(singleLocation){
geocoder.geocode(
{
'address': singleLocation.PostalCode,
'region' : 'uk'
},
function(results, status){
if (status == google.maps.GeocoderStatus.OK) {
var marker = new google.maps.Marker({
position: results[0].geometry.location,
map: map
});
//quick and dirty way
bounds.extend(marker.position);
map.fitBounds(bounds);
markersArray[i] = marker;
console.log(markersArray[i]);
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(singleLocation.Description);
infowindow.open(map, this); //this refers to the marker
});
} else {
alert("Geocode was not successful for the following reason: "
+ status);
return false;
}
}
);
}
2) As you can see above the quick an dirty way to do this is extend and fit the bounds inside of the callback function for the geocode. This causes the fitBounds function to be called multiple times and isnt really a big deal if you only have a few markers, but will cause problems if you have hundreds or thousands of markers. In that case the right-way to do this is to create an async loop function. You can see an example of it on one of my previous answers.
Here is a functioning example of the code based on your example.
Two problems:
1) my info windows, which should take their text from another array,
always use the last array value
2) i can't get the map to center automatically. I'm using a bit of
code which has worked in other circumstances, but it doesn't in my
code.
Answers:
1) This is because most likely you have a closure issue here.
2) center will define the center point of your map, but in your code you have commented this
//center: new google.maps.LatLng(-33.92, 151.25),
removing the comment for this line will center to map to latitude of -33.92 and longitude of 151.25.
Use below:
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(-33.92, 151.25),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
First off thank you in advance for taking time to help me with this, I appreciate your efforts.
I have a problem with google maps api, JavaScript version 3.
I have written the following code
$('.adr').ready(function(){
initialize();
})
function initialize() {
var myLatlng = codeAddress();
var myOptions = {
zoom: 14,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.SATELLITE
};
var map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
}
function codeAddress()
{
var geocoder = new google.maps.Geocoder();
var address;
var street = cropAdr($(".street-address").text());
var city = cropAdr($(".locality").text());
var state = cropAdr($(".region").text());
var zip = cropAdr($(".zip").text());
address = street + ", " + city + ", " + state + ", " + zip;
geocoder.geocode( {'address': address}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
var latlng = results[0].geometry.location;
return latlng;
}
else
{
alert("Geocode was not successful for the following reason: " + status);
return null;
}
});
}
function cropAdr(args)
{
var index = args.indexOf(":");
var value = args.substr(index+1);
return value;
}
But it doesn't work.
I have checked the value of the "results[0].geometry.location" return and its perfect, so the address manipulation works. The "results[0].geometry.location" is a google.maps.Latlng object, but I have tried to strip out just the co-ords as strings, then create a new google.maps.Latlng object but no dice.
yet if I manually copy that string and paste the value into "var myLatlng = new google.maps.Latlng(Paste Copied String here!)" the whole thing works!!
I cannot see what else is wrong this script (apologies for the jumble of Jquery and Javascritpt).
The Google Maps API Geocoder accepts a function that will be run when the address has been geocoded, but that function may be called asynchronously - that is, after the rest of your code has already finished running.
In codeAddress you call the Geocoder and pass in a function with this line:
geocoder.geocode( {'address': address}, function(results, status)
You then try and return a latLng from the function passed to the geocoder, but that is not the same as returning a value from codeAddress. The value you return from inside this function will be passed to the geocoder object, which will just ignore it.
You need to have the function you pass to geocode do something with the latLng. For example, replace:
return latLng;
with:
map.setCenter(latLng);
And the map should center itself on the geocoded address once the result is available.
(To do this you will need to make the map object global or otherwise make it available to codeAddress. I suggest adding "var map;" at the top of your code, and remove "var" from in front of the use of map in initialize)