Google Maps v3: Markerclusterer not being fired? - javascript

I have a bit of a puzzle on my hands. I'm Using Google Maps v3 and MarkerClusterer v3. When I load my page, the map appears, the points are all there, but nothing is clustered.
If I go to the firebug console and do:
markerCluster = new MarkerClusterer(map, markers);
Suddenly clustering works.
Weirdly, If I put an alert between the map instantiation and the markerclusterer instantiation, again clustering suddenly works.
Here is the end of my $(document).ready function:
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
markerCluster = new MarkerClusterer(map, markers);
and all it takes to make the clustering work is:
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
alert("test");
markerCluster = new MarkerClusterer(map, markers);
What am I missing here? Do I need to refresh the map somehow? Is that what is happening with the alert box?
If you need more code drop me a comment.

Your problem comes from the fact that $.ajax(), $.getJSON() are asynchronous methods. Once executed, your code is not blocked (otherwise the browser would be blocked as well). Therefore, var markerCluster = new MarkerClusterer(map, markers); is called before the end of the AJAX response processing.
To solve this issue, you have to use a callback, such as complete(), which is fired once the processing is done.
For example:
$.getJSON('/your_data.json', function(data) {
for (var i=0;i<data.length;i++){
// code to display markers
}
}).complete(function() {
var marker_cluster = new MarkerClusterer(map, gmarkers);
});
Hope this helps.

Here is a lightly edited version of what I ended up using. I'm giving most of script here so people can get an idea of the context each function is happening in as well as the scope of everything. Hopefully this will save someone some head scratching.
var initialize = function(){
var markers = [];
var infowindow = new google.maps.InfoWindow();
function load_content(marker, id){
$.ajax({
url: 'eventos/' + id,
success: function(data){
infowindow.setContent(data);
infowindow.open(map, marker);
}
});
}
var opt = { ...options...}
var map = new google.maps.Map(document.getElementById('map_canvas'), opt);
map.setCenter(new google.maps.LatLng(-44.4419, 170.1419));
map.setZoom(9);
$.ajax({
url: 'eventos/',
method: 'GET',
dataType: 'json',
success: function(data){
$.each(data, function(i, a){
var latlng = new google.maps.LatLng(a.evento.lat, a.evento.lng);
var marker = new google.maps.Marker({
position : latlng,
title: a.evento.title
});
google.maps.event.addListener(marker, 'closeclick', function() {
infowindow.setContent("");
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.close();
infowindow.setContent("<img src='loading.gif'>");
load_content(marker, a.evento.id);
});
markers.push(marker);
});
var markerCluster = new MarkerClusterer(map, markers);
}
});
};

I had the exact same issue and symptoms. My solution in the end was to load the map with google loader instead, which for some reason worked fine.
This does not work with mapclusterer:
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
...
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
While this works:
<script src="http://www.google.com/jsapi"></script>
...
google.load('maps', '3', { other_params: 'sensor=false' });
google.setOnLoadCallback(initialize);
function initalize() {
var map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
}
This workaround might not be possible for everyone, but hopefully someone can benefit from it.

Have you checked out this thread on MarkerClusterer v3? It's got a few links to some handy resources, namely code examples and reference docs.
Check the examples and make sure they're working OK in your testing browser (you never know, could be an issue with MC).

Related

How to use Pagination in Google Maps and Ajax

I have an api where is pagination because of a lot of data. Now I am trying to do Google Maps where I use API to get lat and lng from database. I still get just first page of API Data. What's wrong with my code ? What should I change. Please help. I will be glad to you.
Hi. I have an api where is pagination because of a lot of data. Now I am trying to do Google Maps where I use API to get lat and lng from database. I still get just first page of API Data. What's wrong with my code ? What should I change. Please help. I will be glad to you.
<script>
function initMap(map) {
var start_point = new google.maps.LatLng(27.772321, 1.803125);
// Creating a new map
var map = new google.maps.Map(document.getElementById("companies-map"), {
center: start_point,
zoom: 2,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
function setMarkerPoints(map) {
var bounds = new google.maps.LatLngBounds();
var mc = [];
var infoWindow = new google.maps.InfoWindow();
url = '/api/companies/map/',
$.ajax({
type: "GET",
url: url,
dataType: "json",
success: function(data, pagination) {
$.each(data.results, function(marker, data) {
var latLng = new google.maps.LatLng(data.point.latitude, data.point.longitude);
bounds.extend(latLng);
// Creating a marker and putting it on the map
var marker = new google.maps.Marker({
position: latLng,
animation: google.maps.Animation.DROP,
map: map,
});
google.maps.event.addListener(marker, 'click', function() {
infoWindow.setContent('' + data.name + '<br>' + data.name);
infoWindow.open(map, marker);
});
mc.push(marker);
});
if (pagination.hasNextPage) {
pagination.nextPage();
};
new MarkerClusterer(map, mc, {
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
});
},
error: function(data) {
console.log('Please refresh the page and try again');
}
});
//END MARKER DATA
// end loop through json
}
setMarkerPoints(map);
}
google.maps.event.addDomListener(window, 'load', renderGoogleMap);
renderGoogleMap();
</script>
THANK YOU SO MUCH
You need to create a PlaceSearchPagination object in order to access additional pages. The object is created via a callback function.
https://developers.google.com/maps/documentation/javascript/places#place_search_responses
Take a look at the Accessing Additional Results section, specifically under the comments "// Create the places service" and "// Perform a nearby search.".

javascript google maps api - dynamic search place

i've done like this video has shown but something just not working. mine not showing the place i seaching for and the marker also didnt move to that place. Youtube tutorial
and this is my code
var map = new google.maps.Map(document.getElementById('map-canvas'),{
center:{
lat:-7.9666,
lng:112.6326
},
zoom:15
} );
var marler = new google.maps.Marker({
position:{
lat:-7.9666,
lng:112.6326
},
map:map,
draggable:true
});
var searchBox = new google.maps.places.SearchBox(document.getElementById('mapsearch'));
google.maps.event.addListener (searchBox, 'places_changed', function(){
var places = searchBox.getPlaces();
var bounds = new google.maps.LatLngBounds();
var i, place;
for (i=0; place=places[i];i++){
//console.log(place.geometry.location);
bounds.extend(place.geometry.location);
marker.setPosition(place.geometry.location);
}
map.fitBounds(bounds);
map.setZoom(15);
});
problem starts from var searchBox line down below
im using libraries=places at the end of google api script.
thanks for your help :beer
viola, i actually have a typo for the marker that written as marler.
case close everyone,
you should go to that youtube tutorial, that works!

Google Maps info windows only displays info from the first click

I have a script that:
pulls results from a database in the form of an XML file
parses those results
creates a marker for each result and places it on a map (a single map for all markers)
at the same times, builds a clickable HTML list (sidebar) containing all those results.
When the user clicks on a place name in the sidebar, the info window from the corresponding marker on the map is automatically displayed. Of course the user can also click directly on a marker on the map, and the same info window is also displayed.
This code has been working fine for several years, but last week I noticed that its behavior was now bugged. When viewing some given results, the first click (either on the map or in the sidebar) works fine (the info window opens and displays the correct information), but the following clicks all show the same information from the first click, all in their respective info window. (To be clear: the information shown is the one from the very first click, not from the previous click.)
I've been trying to debug that for hours but I don't understand why it doesn't work anymore. As you can see in my code below, I tried adding a console.log in the google.maps.event.addListener function, to see what data is being worked with when the marker is clicked, but even there, I don't see anything wrong.
Here is my code (simplified to be more readable):
var side_bar_html = '\n';
var gmarkers = []; // array for created markers
var infoWindow;
var center_lat = <?php echo $position_lat; ?>;
var center_lng = <?php echo $position_lng; ?>;
function createMarker(point, name, html, place_id, map) {
var marker, markerOptions;
markerOptions = {
map: map,
position: point,
dataId: place_id,
icon : 'theme/marker.png',
shadow: 'theme/marker_shadow.png'
};
marker = new google.maps.Marker(markerOptions);
infoWindow = new google.maps.InfoWindow({content: html});
google.maps.event.addListener(marker, 'click', function() {
console.log(this, marker, html);
infoWindow.content = html;
infoWindow.open(map, this);
});
gmarkers.push(marker);
side_bar_html += '\n<li>' + name + '</li>';
return marker;
}
function showPlace(i) {
google.maps.event.trigger(gmarkers[i], 'click');
}
function loadEarth(opt, zoom) {
var map, point, mapCenter, mapOptions;
if (zoom === null) {zoom = 7;}
mapCenter = new google.maps.LatLng(center_lat, center_lng);
mapOptions = {
zoom: zoom,
center: mapCenter,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
point = new google.maps.LatLng(parseFloat(center_lat), parseFloat(center_lng));
if (opt != 0) {
map.setMap(new google.maps.Marker(point));
}
}
// receiving results via XML
function go() {
var map, bounds;
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
bounds = new google.maps.LatLngBounds();
$.ajax({
url : 'url/to/data.xml',
type : 'GET',
dataType : 'xml',
success : function(xml) {
var markers, lat, lng, place_id, point, label, html, marker;
markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
// extract data for each marker
lat = parseFloat(markers[i].getAttribute("lat"));
lng = parseFloat(markers[i].getAttribute("lng"));
place_id = parseFloat(markers[i].getAttribute("place_id"));
point = new google.maps.LatLng(lat,lng);
label = $(markers[i]).find('label').eq(0).text();
html = $(markers[i]).find('infowindow').eq(0).text();
// marker creation
marker = createMarker(point, label, html, place_id, map);
// extend visible zone to newly added marker
bounds.extend(point);
}
map.setCenter(new google.maps.LatLng(center_lat, center_lng), 7);
bounds.extend(point);
if (markers.length>0) {
document.getElementById("side_results").innerHTML = side_bar_html;
map.fitBounds(bounds);
map.setCenter(bounds.getCenter());
} else {
loadEarth();
}
} // end AJAX success
}); // end AJAX
} // end go()
if ($('#places_page').is('.empty')) {
loadEarth(0,8);
} else go();
Any help would be greatly appreciated.
Edit:
As requested, here's a sample of the XML received. In this case, the PHP variables at the start of the script would receive the following values:
$position_lat: 46.9479222
$position_lng: 7.4446085
<?xml version="1.0" encoding="UTF-8"?><markers>
<marker place_id="955" lat="46.950218" lng="7.442429">
<label><![CDATA[<em>Place 955</em><strong>3011 Bern</strong>]]></label>
<infowindow>
<![CDATA[<p><em>Place 955</em><br />Speichergasse 35<br />3011 <ins>Bern</ins></p>]]>
</infowindow>
</marker>
<marker place_id="985" lat="46.942032" lng="7.389993">
<label><![CDATA[<em>Place 985</em><strong>3018 Bern</strong>]]></label>
<infowindow>
<![CDATA[<p><em>Place 985</em><br />BrĂ¼nnenstrasse 106A<br />3018 <ins>Bern</ins></p>]]>
</infowindow>
</marker>
</markers>
The Google Maps API is included via this line:
<script src="http://maps.google.com/maps/api/js?v=3&sensor=true&language=fr&key=..."></script>
Edit 2:
Changing the API call to force it to use version 3.18 does fix the problem:
<script src="http://maps.google.com/maps/api/js?v=3.18&sensor=true&language=fr&key=..."></script>
Obviously this is a temporary fix, since v. 3.18 won't always be available. Now I need to understand what change in the 3.19 version made this bug appear. Any suggestion is still appreciated. :)
This undocumented usage:
infoWindow.content = html;
May be the issue. Should be:
infoWindow.setContent(html);
The .content property went away or is no longer supported issue

Getting data stored in additional field of googlemap's marker

I'm working with google maps api and javascript which I am not much familiar with. Here's the code I use to draw markers on my map. I get Latitudes and Longitudes from my database:
var geocoder;
var map;
var jsonStr = '<?php echo json_encode($arajka) ?>';
var LatLong = JSON.parse(jsonStr);
function initialize() {
geocoder = new google.maps.Geocoder();
var mapOptions = {
center: new google.maps.LatLng(50.000001, 20.000001),
zoom: 12
};
map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
var marker = [];
for(var i=0;i<LatLong.length;i++){
var LatLong1 = new google.maps.LatLng(LatLong[i].lat, LatLong[i].lon);
marker.ajdi=LatLong[i].id; // storing additional data (I need to get it when user clicks on certain marker)
marker.push(new google.maps.Marker({position: LatLong1, map: map, title: LatLong[i].login}));
}
// trying to set some listener but it fails.
google.maps.event.addListener(marker, 'click', function() {
map.setZoom(8);
map.setCenter(marker.getPosition());
alert("ASDASDASD" + marker.ajdi);
});
}
So, this listener doesn't work, I don't know why. Well, I expect that it doesn't exactly know what marker is it about. When I tried to do it with a single one, like in tutorial, it worked properly. I don't know what to do when I have this array. Any suggestions please?
You have several mistakes in your code:
As #Hollister mentions, marker is an array, so you need to put the addListener call inside the loop;
You have to store the additional marker data into the marker, not into the marker array;
you have to use this in the listener, not marker.
for(var i=0;i<LatLong.length;i++){
var LatLong1 = new google.maps.LatLng(LatLong[i].lat, LatLong[i].lon);
var this_marker = new google.maps.Marker({position: LatLong1, map: map, title: LatLong[i].login});
this_marker.ajdi=LatLong[i].id; // storing additional data (I need to get it when user clicks on certain marker)
marker.push(this_marker);
// trying to set some listener but it fails.
google.maps.event.addListener(this_marker, 'click', function() {
map.setZoom(8);
map.setCenter(this.getPosition());
alert("ASDASDASD" + this.ajdi);
});
}

Google Maps V3 - json marker loading issue (using Rails 3.1 for data)

We're building a google map app in rails that initially loads some makers using a javascript json marker generating function (using the rails .to_json method on the data object).
Then we have a listener on the zoom action that hoovers the new json file directly and feeds it into the same marker function above.
On initial load the markers turn up fine, but on zoom no new ones seem to be showing up. Checking in the rails logs, the json file is being called, so the problem is either to do with how that json data is processed, or how the markers are delivered.
Can any of you see what the problem is?
var map;
function initialize() {
var myOptions = {
zoom: <%= #zoom %>,
center: new google.maps.LatLng(<%= #centre %>),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map_canvas'),
myOptions);
stream_json = (<%= raw(#stream.to_json) %>);
parse_json(stream_json);
google.maps.event.addListener(map, 'zoom_changed', function() {
json_url = "/test?bounds="+map.getBounds()+"&zoom="+map.getZoom();
stream_json = $.getJSON(json_url);
parse_json(stream_json);
});
function parse_json(json) {
if (json.length > 0) {
var markers = [];
for (i=0; i<json.length; i++) {
var place = json[i];
alert(place.longitude +','+place.latitude);
// addLocation(place);
markers[i] = new google.maps.Marker({
map: map,
position: new google.maps.LatLng(place.latitude, place.longitude)
});
}
}
};
}
google.maps.event.addDomListener(window, 'load', initialize);
Many thanks in advance for any pointers you can send our way!
You're not using getJSON correctly. It's an asynchronous call, so you need to supply a callback:
google.maps.event.addListener(map, 'zoom_changed', function() {
json_url = "/test?bounds="+map.getBounds()+"&zoom="+map.getZoom();
$.getJSON(json_url, function(data) {
parse_json(data);
});
});

Categories