I have a forloop that has a call to a function inside of it. Within that function, I'm pushing values to an array called markers.
Is there a way to access the values of the markers array outside of the forloop?
Here's the code:
<script type="text/javascript">
// arrays to hold copies of the markers and html used by the side_bar
// because the function closure trick doesnt work there
var map = null;
geocoder = new google.maps.Geocoder();
var side_bar_html = "";
var icon = '';
var markers = [];
function codeAddress(this_address,index,callback) {
geocoder.geocode( { 'address': this_address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
callback.call(window,index,results[0].geometry.location)
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
function initialize() {
// create the map
var myOptions = {
zoom: 3,
center: new google.maps.LatLng(46.90, -121.00),
mapTypeControl: true,
mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
navigationControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
for (var i = 0; i < businesses.length; i++) {
codeAddress(businesses[i].address,i,function(i,point){
var description = businesses[i].description;
if(businesses[i].business_type == "Wine"){
//http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld=A|00CC99|000000
icon = 'http://google-maps-icons.googlecode.com/files/wineyard.png';
}else if(businesses[i].business_type == "Golf"){
icon = 'http://google-maps-icons.googlecode.com/files/golf.png';
}else{
icon = 'http://google-maps-icons.googlecode.com/files/festival.png';
}
var marker = createMarker(point,businesses[i].name,description,icon);
// put the assembled side_bar_html contents into the side_bar div
document.getElementById("side_bar").innerHTML = side_bar_html;
});//End codeAddress-function
}//End for-loop
console.log(markers);
var markerCluster = new MarkerClusterer(map, markers);
}
// A function to create the marker and set up the event window function
function createMarker(latlng, name, html,icon) {
var contentString = html;
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: icon,
zIndex: Math.round(latlng.lat()*-100000)<<5
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(contentString);
infowindow.open(map,marker);
});
// save the info we need to use later for the side_bar
markers.push(marker);
// add a line to the side_bar html
side_bar_html += '<a href="javascript:myclick(' + (markers.length-1) + ')">' + name + '<\/a><br />'+html+'<br />';
}
var infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(150,50)
});
// This function picks up the click and opens the corresponding info window
function myclick(i) {
google.maps.event.trigger(markers[i], "click");
}
</script>
As you can see, the last line says "var markerCluster = new MarkerClusterer(map, markers);" This is where I want to be able to access the information from.
Thanks!
The problem is you're not accounting for the asynchronous nature of the call to codeAddress. You're calling that function in a loop, which is triggering a series of calls to the Google Maps API.
You are running this line:
var markerCluster = new MarkerClusterer(map, markers);
...even before the callbacks have been triggered.
To fix, maintain a counter. Each time the callback is triggered increase that counter by 1. Once it is equal to businesses.length you know all the addresses have been geo-coded, and all markers have been added to the array. Now you can create the MarkerCluster.
Yes, Declare it before the for loop.
var markers
for(....
Bring the definition of the marker outside of the for loop ...
var markers = new Array ();
for (var i = 0; i < businesses.length; i++) {
markers[i] = ...
Related
I have a map-making tool that is built with the Google Maps API V3. It allows users to enter two or more locations and produce a map and route. I also have a checkbox that, when clicked, shows markers indicating nearby points of interest.
When I first built the tool, I think it worked well every time. Recently, though, I've noticed that the markers do not always appear when the checkbox is clicked. The map and routing work fine, but the markers only work occasionally. This error seems to occur when they don't work:
Uncaught ReferenceError: map is not defined
It references a section of the "cmarkers" section of javascript (see below).
Background detail: This is part of a Rails web app and a webpage / layout called "Itineraries". When you land on the itineraries webpage and click on the "Map Maker" icon, the map-making tool appears. It's loaded in an i-frame, it's called "map.html.erb", and the map view lives in /views/itineraries. All of the javascript for the map maker lives in the Itineraries layout file, however.
Based on reviewing these posts, I think it might be something in the way that I've ordered or initialized the code, and I think the main culprit is likely in that "cmarkers" section of the code.
Google Maps API Sometimes Not Showing Markers
Google maps api(v3) doesn't show markers
Google Maps API v3 javascript Markers don't always load
I've tried several different changes, but each has either not worked or stopped the map from initializing. Here is the javascript; please note that the API key and other small sections are redacted. Below it is the code for the markers.
<script src="https://maps.googleapis.com/maps/api/js?key=MYAPIKEY&sensor=false"></script>
<script type='text/javascript'>
$(function(){
var directionsDisplay;
var map;
function overlaysClear() {
if (markersArray) {
for( var i = 0, n = markersArray.length; i < n; ++i ) {
markersArray[i].setVisible(false);
}
}
}
function overlaysShow() {
if (markersArray) {
for( var i = 0, n = markersArray.length; i < n; ++i ) {
markersArray[i].setVisible(true);
}
}
}
$("#showmapview").click(function() {
overlaysClear();
$('#mapeach').attr('checked', false);
});
$('#mapeach').change(function() {
if( $('#mapeach').attr("checked")) {
overlaysShow();
}
else {
overlaysClear();
}
});
cmarkers();
google.maps.event.addDomListener(window, 'load', initialize);
});
var directionsService = new google.maps.DirectionsService();
var markersArray = [];
var arrInfoWindows = null;
function initialize() {
var rendererOptions = {
draggable: true,
panel:document.getElementById('directions_panel')
};
directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
var chicago = new google.maps.LatLng(41.850033, -87.6500523);
var mapOptions = {
zoom: 6,
center: chicago,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
directionsDisplay.setMap(map);
}
function calcRoute() {
var start = document.getElementById("start").value;
var end = document.getElementById("end").value;
var waypts = [];
var checkboxArray = document.getElementById("waypoints");
for (var i = 0; i < checkboxArray.length; i++) {
waypts.push({
location:checkboxArray[i].value,
stopover:true
});
}
var request = {
origin: start,
destination: end,
waypoints: waypts,
optimizeWaypoints: optimize,
travelMode: google.maps.TravelMode.DRIVING
};
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
var route = response.routes[0];
}
});
};
function cmarkers() {
$.getJSON( "/mapeach.js", {}, function( data ) {
$.each( data, function( i, item ) {
var loc = item.mainlocation;
$("#markers").append('<li>' + loc.nickname + '</li>');
var marker = new google.maps.Marker({
position: new google.maps.LatLng(+loc.latitude, +loc.longitude),
map: map,
title: loc.nickname,
});
markersArray.push(marker);
var infowindow = new google.maps.InfoWindow({
content: '<a class="clink" href="/spots/'+ loc.id +'/'+ loc.nickname +'" target="_blank">'+ loc.nickname +'</a>'
});
google.maps.event.addListener(marker, 'click', function() {
if (arrInfoWindows != null) {
arrInfoWindows.close();
}
infowindow.open(map,marker);
arrInfoWindows = infowindow;
});
});
});
};
</script>
The mapeach.js file is formatted as below:
[{"mainlocation":{"latitude":"40.706352","nickname":"First Location","id":100000,"longitude":"-73.987650"}},{"mainlocation":{"latitude":"34.061148","nickname":"Second Location","id":100001,"longitude":"-118.273067"}}]
I was able to solve this problem by moving the cmarkers code inside the initialize. I think that the javascript wasn't making clear that the map variable in the initialize was also the map variable in the cmarkers function (sorry if the language isn't precise; I'm not great in js). See below:
function initialize() {
var rendererOptions = {
draggable: true,
panel:document.getElementById('directions_panel')
};
directionsDisplay = new google.maps.DirectionsRenderer(rendererOptions);
var chicago = new google.maps.LatLng(41.850033, -87.6500523);
var mapOptions = {
zoom: 6,
center: chicago,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
directionsDisplay.setMap(map);
cmarkers();
function cmarkers() {
$.getJSON( "/mapeach.js", {}, function( data ) {
$.each( data, function( i, item ) {
var loc = item.mainlocation;
$("#markers").append('<li>' + loc.nickname + '</li>');
var marker = new google.maps.Marker({
position: new google.maps.LatLng(+loc.latitude, +loc.longitude),
map: map,
title: loc.nickname,
});
markersArray.push(marker);
var infowindow = new google.maps.InfoWindow({
content: '<a class="clink" href="/spots/'+ loc.id +'/'+ loc.nickname +'" target="_blank">'+ loc.nickname +'</a>'
});
google.maps.event.addListener(marker, 'click', function() {
if (arrInfoWindows != null) {
arrInfoWindows.close();
}
infowindow.open(map,marker);
arrInfoWindows = infowindow;
});
});
});
};
Special credit to this post for giving me the idea: can't see google marker
All of my markers are coming from an AJAX call and are accurately placed on the map. However, the initial view is fully zoomed out, along the equator, in North America.
I know the solution lays somewhere with bounds.extend and map.fitBounds but apparently I'm doing it wrong.
I've always had an issue with this, so hopefully someone can help elevate this thorn in my side:
var map;
var markers = [];
var home_marker;
function initialize() {
// Display a map on the page
if ( document.contains(document.getElementById("map_canvas")) ) {
bounds = new google.maps.LatLngBounds();
map = new google.maps.Map(document.getElementById("map_canvas"), {
zoom: 12,
center: new google.maps.LatLng(48.4222, -123.3657)
});
// a new Info Window is created
infoWindow = new google.maps.InfoWindow();
// Event that closes the InfoWindow with a click on the map
google.maps.event.addListener(map, 'click', function() {
infoWindow.close();
});
// Add Home Marker
home_marker = new google.maps.Marker({
position: new google.maps.LatLng(user_address_lat, user_address_lng),
map: map,
icon: '/images/map-icon-your-home.png'
});
}
}
function displayMarkers( properties ) {
// this variable sets the map bounds and zoom level according to markers position
var bounds = new google.maps.LatLngBounds();
// For loop that runs through the info on markersData making it possible to createMarker function to create the markers
for (var i = 0; i < properties.length; i++){
var latlng = new google.maps.LatLng(properties[i]['latitude'], properties[i]['longitude']);
var price_current = properties[i]['price_current'];
var bedrooms = properties[i]['bedrooms'];
var total_baths = properties[i]['total_baths'];
var listing_id = properties[i]['listing_id'];
createMarker( latlng, price_current, bedrooms, total_baths, matrix_unique_ID );
// Marker’s Lat. and Lng. values are added to bounds variable
bounds.extend(latlng);
}
// Finally the bounds variable is used to set the map bounds
// with API’s fitBounds() function
map.fitBounds(bounds);
}
function createMarker( latlng, price, bedrooms, bathrooms, matrix_id ) {
var formatted_price = accounting.formatMoney(price, '$', 0);
var marker = new google.maps.Marker({
map: map,
position: latlng,
icon: '/images/map-icon.png'
});
google.maps.event.addListener(marker, 'click', function() {
// Variable to define the HTML content to be inserted in the infowindow
var iwContent = '<div class="row"><div class="small-12 columns"><img src="http://www.mywebsite.com/properties/'+listing_id+'/image-'+matrix_id+'-1.jpg"></div></div>' +
'<div class="row"><div class="small-12 columns"><p class="price-current text-center">'+formatted_price+'</p></div></div><hr>' +
'<div class="row"><div class="small-6 columns"><p class="bedrooms"><span class="fw-semi-bold">Beds:</span> '+bedrooms+'</p></div>' +
'<div class="small-6 columns"><p class="total-baths"><span class="fw-semi-bold">Baths:</span> '+bathrooms+'</p></div></div>';
// including content to the infowindow
infoWindow.setContent(iwContent);
// opening the infowindow in the current map and at the current marker location
infoWindow.open(map, marker);
});
}
// Sets the map on all markers in the array.
function setMapOnAll(map) {
for (var i = 0; i < markers.length; i++) {
markers[i].setMap(map);
}
}
// Removes the markers from the map, but keeps them in the array.
function clearMarkers() {
setMapOnAll(null);
}
// Deletes all markers in the array by removing references to them.
function deleteMarkers() {
clearMarkers();
markers = [];
}
Make a new Part to your script or make a new one, and code it specificly to change zoom in camera ammount and, add ui button for it.
I have an array like this deviceId = [005305230001JIZZZZ, 085835360001NBGJZZ, 085835360002NBGJZZ].
The info window should show the deviceId and be displayed based on which marker is clicked. I started looking at JavaScript only a few days back and can't understand how the functions work and dont have the time right now to learn becauseI have to get this done. I saw a few implementations on this, but I think they have done the adding multiple markers differently using functions, I think. I couldn't understand it so I used for loop.
The latArray and lngArray have something like this [12.1456,12.5256,11.566] and [72.145,72.4557,75.23535]
I cant figure out how to add info windows for corresponding markers.
This is the code for map:
function initMap() {
var bounds = new google.maps.LatLngBounds();
var mapDiv = document.getElementById('map');
var map = new google.maps.Map(mapDiv);
map.setCenter(new google.maps.LatLng(latArray[0],lngArray[0]));
map.setZoom(18);
for(i=0;i<latArray.length;i++)
{
marker = new google.maps.Marker({
position: new google.maps.LatLng(latArray[i],lngArray[i]),
map: map,
title:"This is the place.",
// icon:"phone4.png"
});
//bounds.extend(marker.getPosition());
console.log(latArray);
console.log(lngArray);
}
//map.fitBounds(bounds);
var infoWindow = new google.maps.InfoWindow({
content: contentString
});
marker.addListener('click', function() {
infoWindow.open(map, marker);
});
}
How to show info window of corresponding markers.
This is content for marker:
contentString = '<div id = "content>'
+'<p style = "color:#000000">DeviceID<p>' +
'<p>'+ deviceId[i] + '<br></p>' //deviceId is the array with content
+ '</div>'
I read something about closures but didn't understand. Please help
Edit: I just tried this. I'm getting js?callback=initMap:34 InvalidValueError: setPosition: not a LatLng or LatLngLiteral: not an Object
What i tried:
var markerArray=[];
for(i=0;i<latArray.length;i++)
{
markerArray.push("new google.maps.LatLng("+ latArray[i]+","+lngArray[i]+")");
console.log(markerArray[i]);
}
console.log(markerArray[0]);
for(i=0;i<latArray.length;i++)
{
marker = new google.maps.Marker({
position: markerArray[i],
map: map,
title:"This is the place.",
// icon:"phone4.png"
});
var infoWindow = new google.maps.InfoWindow({
content: contentString[i]
});
marker.addListener('click', function(marker,contentString) {
infoWindow.open(map, marker);
});
}
So I will not bother you with the explanation how closures work (as you are saying your not interested in it now), I just supply you the solution:
// Your arrays with geo informations
var latArray = [-25.363, -26.263, -25.163];
var lngArray = [131.044, 131.144, 132.044];
// Your array with device information
var deviceIdArray = ["AAA", "BBB", "CCC"];
// Just create map according to the first geo info
var map = new google.maps.Map(document.getElementById("map"), {
center: {lat: latArray[0], lng: lngArray[0]},
zoom: 6
});
// Loop throuhg all geo info
latArray.forEach(function(lat, i) {
// For each one create info window
var infoWindow = new google.maps.InfoWindow({
content: '<div id="content>'
+ '<p style="color:#000000">DeviceID<p>'
+ '<p>'+ deviceIdArray[i] + '</p>'
+'</div>'
});
// For each one create marker
var marker = new google.maps.Marker({
map: map,
position: {lat: latArray[i], lng: lngArray[i]}
});
// Click on the currently created marker will show the right info window
marker.addListener("click", function() {
infoWindow.open(map, marker);
});
});
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3"></script>
<div id="map"></div>
Take a look at my function with map. It takes json object with some data from PHP and 'translate' it into array and then adds content to multiple markers (it is not dynamic in real time - you have to reload page). In addition it has a search box (which opens certain info window). If you don't understand do not hestitate to ask :).
//check if document is fully loaded, seetting a container for ajax call results
$(document).ready(function() {
var tablica = [];
// ajax call for action preparing set of names, descriptions, coords and slugs needed to render deatiled markers on map
$.ajax({
url: 'map/json_prepare',
dataType: 'json',
success: function(response) {
var obj = JSON && JSON.parse(response) || $.parseJSON(response);
obj.forEach(function(item, index, array)
{
tablica.push(item);
});
//call a function rendering a map itself
var map;
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 50.06561980, lng: 19.946850},
zoom: 12
});
////////////////////////////////////////////////////////////////////////////////////////////////////
// LOOP ADDING MARKERS FROM DB WITH PROPER INFO WINDOWS (DESCRIPTION AND LINKS)
// Add a markers reference
var markers = [];
$.each(tablica, function( key, value ) {
//markers
var myLatLng = {lat: value[1], lng: value[2]};
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: value[0],
clickable: true,
animation: google.maps.Animation.DROP,
adress: value[5]
});
//infowindows
marker.info = new google.maps.InfoWindow ({
content: '<h1>'+ value[0] + '</h1>' + '<br>' + '<br>' + value[3] + '<br>' + value[5] +'<br>' + '<br>' + '' + 'Details' + '<br/>' +
'' + 'Take part in' + '<br>'
});
//eventlistener - after click infowindow opens
google.maps.event.addListener(marker, 'click', function() {
marker.info.open(map, marker);
});
//event listener - after dblclick zoom on certain event is set
google.maps.event.addListener(marker, 'dblclick', function() {
map.setZoom(18);
map.setCenter(marker.getPosition());
});
markers.push(marker);
});
// End of loop adding markers from db.
///////////////////////////////////////////////////////////////////////////////////////////////////////////
///additional event listener - rightclick to get back default zoom
google.maps.event.addListener(map, 'rightclick', function() {
map.setZoom(12);
map.setCenter(map.getPosition());
});
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//CENTRING MAP AS ALL OF MARKERS IS VISIBLE//
//create empty LatLngBounds object
var bounds = new google.maps.LatLngBounds();
var infowindow = new google.maps.InfoWindow();
for (i = 0; i < tablica.length; i++) {
var marker = new google.maps.Marker({
position: new google.maps.LatLng(tablica[i][1], tablica[i][2]),
map: map
});
//extend the bounds to include each marker's position
bounds.extend(marker.position);
}
//now fit the map to the newly inclusive bounds
map.fitBounds(bounds);
/////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
///SEARCH_BOX////////
///Here comes part of script adding search box
// Create the search box and link it to the UI element.
// Anchor search box and search button to the map.
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
var button = document.getElementById('submitSearch');
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(button);
//replacing polish characters on order to search without necessity typing them
function cleanUpSpecialChars(str)
{
str = str.replace(/[Ą]/g,"A");
str = str.replace(/[ą]/g,"a");
str = str.replace(/[Ę]/g,"E");
str = str.replace(/[ę]/g,"e");
str = str.replace(/[Ć]/g,"C");
str = str.replace(/[ć]/g,"c");
str = str.replace(/[Ł]/g,"L");
str = str.replace(/[ł]/g,"l");
str = str.replace(/[Ń]/g,"N");
str = str.replace(/[ń]/g,"n");
str = str.replace(/[Ó]/g,"O");
str = str.replace(/[ó]/g,"o");
str = str.replace(/[Ś]/g,"S");
str = str.replace(/[ś]/g,"s");
str = str.replace(/[Ź]/g,"Z");
str = str.replace(/[ź]/g,"z");
str = str.replace(/[Ż]/g,"Z");
str = str.replace(/[ż]/g,"z");
return str;
}
//Function, that search in array of markers, one which fits the key word written in searchbox.
$('#submitSearch').click(function() {
//Catching searched word and preparing its value for search process
var toSearch = $(input).val().trim();
toSearch = cleanUpSpecialChars(toSearch);
toSearch = toSearch.toLowerCase();
console.log('Szukana fraza -> ' + toSearch);
var results = [];
if (toSearch.length >=3) {
// Iterate through the array
$.each(markers, function (i, marker) {
//preparing certain elemnts of marker objects for search process
markers[i].title = cleanUpSpecialChars(markers[i].title);
markers[i].adress = cleanUpSpecialChars(markers[i].adress);
markers[i].title = markers[i].title.toLowerCase();
markers[i].adress = markers[i].adress.toLowerCase();
if (markers[i].title.indexOf(toSearch) > -1 || markers[i].adress.indexOf(toSearch) > -1) {
results.push(markers[i]);
}
});
if (results.length < 1) {
console.log ('nic');
$('#message2').slideDown(500, function () {
setTimeout(function () {
$('#message2').slideUp(500);
}, 5000);
});
}
// Close all the infoWindows, before rendering Search results.
markers.forEach(function (marker) {
marker.info.close(map, marker);
});
//Opens infWindows for multiple markers found and set bounds so that all markers found are visible
results.forEach(function (result) {
result.info.open(map, result);
bounds.extend(result.position);
});
map.fitBounds(bounds);
}
else{
//what if user has typed less than three characters in searchbox -> render flash mess.
$("#message").slideDown(500, function(){
setTimeout(function(){
$("#message").slideUp(500);
},5000);
});
}
});
//Enabling key Enter for triggering a search action.
$(input).keypress(function(e){
if(e.which == 13){//Enter key pressed
$('#submitSearch').click();//Trigger search button click event
}
});
},
//////////////////////////////////////////////////////////////////////////////////////////
//obsługa błędu, jeśli nie zostanie wyświetlona mapa
error: function (xhr, ajaxOptions, thrownError) {
console.log(xhr.status);
console.log(thrownError);
console.log(ajaxOptions);
alert('Map is broken. Please try again later.')
}
});
});
It will not qork here because it doesn't contain data from php.
I have created a nice Google map form that gets clients data from the database ( with a jQuery post call to php) and loads it into the clients_details. if clients_details[]['location'] which is Latlng is provided in the database all works well and marker gets displayed as expected. Problem is that when clients_details[]['location'] is not provided then I use the address from clients_details[]['address'] and try to get position of the marker by using geocoder.geocode. However surprisingly every time the code gets to the geocoder it jumps from it and comes back to it after it initialized the map ! so markers wont get added to the map !
I am assuming it has something to do with JavaScript function priorities but not sure how
<script>
var clients_details // getting this from database;
var infowindow =[];
var geocoder;
var map;
function showMarkers(clients_details)
{
var marker = [];
for (var i = 0; i < clients_details.length; i++)
{
content = 'Test Content' ;
infowindow[i] = new google.maps.InfoWindow({
content: content,
maxWidth: 350
});
var client_location;
if (clients_details[i]['location'] !== null)
{
// Geting Lat and Lng from the database string
LatLng = clients_details[i]['location'];
client_location = new google.maps.LatLng (LatLng);
}
else
{
client_address = clients_details[i]['address'];
geocoder.geocode(
{ 'address': client_address},
function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
client_location = results[0].geometry.location;
}
else
alert('Geocode was not successful for the following\n\
reason: ' + clients_details[i]['name']+'\n' + status);
});
}
marker[i] = new google.maps.Marker({
position: client_location,
map: map,
title: clients_details[i]['name']
});
// Add 'click' event listener to the marker
addListenerMarkerList(infowindow[i], map, marker[i]);
}// for
}// function
The
marker[i] = new google.maps.Marker({
position: client_location,
map: map,
title: clients_details[i]['name']
});
Code should be inside the callback in the geocoder.geocode call.
Because in your code the client_location is computed after the marker[i].
What you could do is:
compute the client_location and when the client_locolation is computed
then compute the marker[i]
So your code could be like this:
// ... your code as is
geocoder.geocode(
{ 'address': client_address},
function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
client_location = results[0].geometry.location;
// closure needed, for the marker[i] to work correctly,
// because we are in a loop on i
(function (i) {
marker[i] = new google.maps.Marker({
position: client_location,
map: map,
title: clients_details[i]['name']
});
})(i);
}
else
{
alert('Geocode was not successful for the following\n\
reason: ' + clients_details[i]['name']+'\n' + status);
}
}
);
// .... your code as is
You need to bind your call back function to the right event. Bind the initialize of the map to window load. Inside that function then call the rest of the marker/geocoder logic. As extracted from their documentation:
function initialize() {
var mapOptions = {
zoom: 4,
center: new google.maps.LatLng(-25.363882, 131.044922)
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var marker = new google.maps.Marker({
position: map.getCenter(),
map: map,
title: 'Click to zoom'
});
google.maps.event.addListener(map, 'center_changed', function() {
// 3 seconds after the center of the map has changed, pan back to the
// marker.
window.setTimeout(function() {
map.panTo(marker.getPosition());
}, 3000);
});
google.maps.event.addListener(marker, 'click', function() {
map.setZoom(8);
map.setCenter(marker.getPosition());
});
}
google.maps.event.addDomListener(window, 'load', initialize);
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I have trouble with my google map script where the markers on a same location overlapped and not visible to user.
I tried to edit my script using OverlappingMarkerSpiderfier available in this link https://github.com/jawj/OverlappingMarkerSpiderfier. But overlapping issue exist.No improvement occured.
<script type="text/javascript">
var geocoder;
var map;
// initializing the map
function initialize()
{
// define map center
var latlng = new google.maps.LatLng(40.44694705960048,-101.953125);
// define map options
var myOptions =
{
zoom: 3,
center: latlng,
mapTypeId: google.maps.MapTypeId.MAP,
scaleControl: true,
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.SMALL
},
mapTypeControl: false,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
}
};
// initialize map
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// add event listener for when a user clicks on the map
google.maps.event.addListener(map, 'click', function(event) {
findAddress(event.latLng);
});
}
// finds the address for the given location
function findAddress(loc)
{
geocoder = new google.maps.Geocoder();
if (geocoder)
{
geocoder.geocode({'latLng': loc}, function(results, status)
{
if (status == google.maps.GeocoderStatus.OK)
{
if (results[0])
{
address = results[0].formatted_address;
// fill in the results in the form
document.getElementById('lat').value = loc.lat();
document.getElementById('long').value = loc.lng();
document.getElementById('address').value = address;
}
}
else
{
alert("Geocoder failed due to: " + status);
}
});
}
}
// initialize the array of markers
var markers = new Array();
// the function that adds the markers to the map
function addMarkers()
{
// get the values for the markers from the hidden elements in the form
var lats = document.getElementById('lats').value;
var lngs = document.getElementById('lngs').value;
var addresses = document.getElementById('addresses').value;
var names = document.getElementById('names').value;
var descrs = document.getElementById('descrs').value;
var photos = document.getElementById('photos').value;
var user_names = document.getElementById('user_names').value;
var user_locs = document.getElementById('user_locs').value;
var las = lats.split(";;")
var lgs = lngs.split(";;")
var ads = addresses.split(";;")
var nms = names.split(";;")
var dss = descrs.split(";;")
var phs = photos.split(";;")
var usrn = user_names.split(";;")
var usrl = user_locs.split(";;")
// for every location, create a new marker and infowindow for it
for (i=0; i<las.length; i++)
{
if (las[i] != "")
{
// add marker
var loc = new google.maps.LatLng(las[i],lgs[i]);
var marker = new google.maps.Marker({
position: loc,
map: window.map,
title: nms[i]
});
markers[i] = marker;
var contentString = [
'<div id="tabs">',
'<div id="tab-1">',
'<p><span>'+nms[i]+'</span></p>',
'<p><img src="./photos/'+phs[i]+'"/></p>'+
'</div>',
'<div id="tab-3">',
'<p><img src="images/b-line.jpg"/></p>',
'</div>',
'</div>'
].join('');
var infowindow = new google.maps.InfoWindow;
bindInfoWindow(marker, window.map, infowindow, contentString);
}
}
}
// make conection between infowindow and marker (the infowindw shows up when the user goes with the mouse over the marker)
function bindInfoWindow(marker, map, infoWindow, contentString)
{
google.maps.event.addListener(marker, 'mouseover', function() {
map.setCenter(marker.getPosition());
infoWindow.setContent(contentString);
infoWindow.open(map, marker);
$("#tabs").tabs();
});
}
// highlighting a marker
// make the marker show on top of the others
// change the selected markers icon
function highlightMarker(index)
{
// change zindex and icon
for (i=0; i<markers.length; i++)
{
if (i == index)
{
markers[i].setZIndex(10);
markers[i].setIcon('http://www.google.com/mapfiles/arrow.png');
}
else
{
markers[i].setZIndex(2);
markers[i].setIcon('http://www.google.com/mapfiles/marker.png');
}
}
}
</script>
Thanks in advance.
Refer OverlappingMarkerSpiderfier and this