Google maps API v3 cluster markers with info windows - google-maps-api-3

I've read the documentation, but my script skills aren't great, so I'm struggling to implement clustering in my Google Map.
The code I have works fine - taking an array of locations and plotting them onto a map. However, I have several hundred points on the map now, so I need to crudely cluster these just so the map is cleaner. The code I have is like this:
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="/scripts/google-maps-marker-cluster.js"></script>
<script type="text/javascript">
var infowindow = null;
$(document).ready(function () { initialize(); });
function initialize() {
var centerMap = new google.maps.LatLng(54.5753459, -3.9550781);
var myOptions = {
zoom: 6,
center: centerMap,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
setMarkers(map, sites);
infowindow = new google.maps.InfoWindow({
content: "loading..."
});
var markerCluster = new MarkerClusterer(map,sites);
}
var sites = [
['AAA', 57.340558, -2.324553, 1, '<h2>Organisation AAA</h2><address>The address</address>'],
['ZZZ', 50.827138, -0.139432, 1, '<h2>Organisation ZZZ</h2><address>The address</address>']
];
function setMarkers(map, markers) {
var image = new google.maps.MarkerImage('/css/img/icon.png',
new google.maps.Size(16, 16),
new google.maps.Point(0,0),
new google.maps.Point(0, 32)
);
var shadow = new google.maps.MarkerImage('/css/img/shadow.png',
new google.maps.Size(37, 14),
new google.maps.Point(0,0),
new google.maps.Point(0, 32)
);
var shape = {
coord: [1, 1, 1, 20, 18, 20, 18 , 1],
type: 'poly'
};
for (var i = 0; i < markers.length; i++) {
var sites = markers[i];
var siteLatLng = new google.maps.LatLng(sites[1], sites[2]);
var marker = new google.maps.Marker({
position: siteLatLng,
map: map,
shape: shape,
title: sites[0],
zIndex: sites[3],
html: sites[4]
});
var contentString = "Some content";
google.maps.event.addListener(marker, "click", function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
}
</script>
<div id="map_canvas"></div>
Can anyone tell me the simplest way to cluster these markers? I've tried moving the var markerCluster = new MarkerClusterer(map); line around in several places, but nothing works.
Thanks for any pointers...

Here's how I'm doing it in a Rails project. It's pretty similar to yours except I'm looping a Rails variable and assigning that to the javascript to build the markers array.
The biggest difference here is that my markers are being scoped inside my initialize function.
function initialize() {
var latlng = new google.maps.LatLng(0, 0);
var myOptions = {
zoom: 8,
center: latlng,
scrollwheel: false,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById("map"),
myOptions);
var latlnglist = []
var markers = []
var infowindow = new google.maps.InfoWindow({
content: "Loading..."
})
<% #map.each do |artwork| %>
<% unless artwork.location.blank? %>
latlnglist.push(artwork_lat_lng = new google.maps.LatLng (<%= artwork.lat %>, <%= artwork.lng %>))
markers.push(marker = new google.maps.Marker({
position: artwork_lat_lng,
title: "<%=raw escape_javascript(artwork.title) %>",
html: "<%=raw escape_javascript("#{link_to image_fu(artwork.image, '315x120>', :size => '315x120', :alt => artwork.title), map_url(artwork)} <h4>#{artwork.page_title}</h4>") %>"
}))
google.maps.event.addListener(marker, 'click', function() {
infowindow.close();
infowindow.setContent(this.html);
infowindow.open(map, this);
})
<% end %>
<% end %>
var mcOptions = {
gridSize: 50,
maxZoom: 15
}
var markerCluster = new MarkerClusterer(map, markers, mcOptions);
var bounds = new google.maps.LatLngBounds();
for (var i = 0, len = latlnglist.length; i < len; i++) {
bounds.extend(latlnglist[i]);
}
map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, 'load', initialize);

Related

Show data when Google Maps marker is clicked in markercluster

I am trying to work out how to show custom data when a Google Maps markerclusterer marker is clicked but can't find this documented anywhere.
My markerclusterer code looks like this but my attempt at capturing the click event on a marker is not working:
var markerClusterer = null;
var map = null;
var imageUrl = 'http://chart.apis.google.com/chart?cht=mm&chs=24x32&' +
'chco=FFFFFF,008CFF,000000&ext=.png';
google.maps.event.addDomListener(window, 'load', initialize);
function refreshMap() {
if (markerClusterer) {
markerClusterer.clearMarkers();
}
var markers = [];
var markerImage = new google.maps.MarkerImage(imageUrl,
new google.maps.Size(24, 32));
/*
for (var i = 0; i < 1000; ++i) {
var latLng = new google.maps.LatLng(data.photos[i].latitude,
data.photos[i].longitude)
var marker = new google.maps.Marker({
position: latLng,
icon: markerImage
});
markers.push(marker);
}
*/
for (var i = 0; i < numItemsToShow; ++i) {
var latLng = new google.maps.LatLng(itemsToShow[i].lat, itemsToShow[i].long);
var marker = new google.maps.Marker({
position: latLng,
icon: markerImage
});
markers.push(marker);
}
var zoom = parseInt(document.getElementById('zoom').value, 10);
var size = parseInt(document.getElementById('size').value, 10);
var style = parseInt(document.getElementById('style').value, 10);
zoom = zoom == -1 ? null : zoom;
size = size == -1 ? null : size;
style = style == -1 ? null: style;
markerClusterer = new MarkerClusterer(map, markers, {
maxZoom: zoom,
gridSize: size,
styles: styles[style]
});
}
function initialize() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: new google.maps.LatLng(39.91, 116.38),
mapTypeId: google.maps.MapTypeId.ROADMAP,
//styles: [{"featureType":"administrative","elementType":"labels.text.fill","stylers":[{"color":"#444444"}]},{"featureType":"administrative.land_parcel","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"landscape","elementType":"all","stylers":[{"color":"#f2f2f2"}]},{"featureType":"landscape.natural","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"poi","elementType":"all","stylers":[{"visibility":"on"},{"color":"#052366"},{"saturation":"-70"},{"lightness":"85"}]},{"featureType":"poi","elementType":"geometry.fill","stylers":[{"saturation":"-100"},{"lightness":"0"}]},{"featureType":"poi","elementType":"labels","stylers":[{"visibility":"simplified"},{"lightness":"-53"},{"weight":"1.00"},{"gamma":"0.98"}]},{"featureType":"poi","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"poi","elementType":"labels.icon","stylers":[{"visibility":"off"},{"lightness":"0"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"hue":"#3dff00"},{"saturation":"-100"}]},{"featureType":"road","elementType":"all","stylers":[{"saturation":-100},{"lightness":45},{"visibility":"on"}]},{"featureType":"road","elementType":"geometry","stylers":[{"saturation":"-18"}]},{"featureType":"road","elementType":"labels","stylers":[{"visibility":"off"}]},{"featureType":"road.highway","elementType":"all","stylers":[{"visibility":"on"}]},{"featureType":"road.arterial","elementType":"all","stylers":[{"visibility":"on"}]},{"featureType":"road.arterial","elementType":"labels.icon","stylers":[{"visibility":"off"}]},{"featureType":"road.local","elementType":"all","stylers":[{"visibility":"on"}]},{"featureType":"road.local","elementType":"labels.text","stylers":[{"visibility":"off"}]},{"featureType":"transit","elementType":"all","stylers":[{"visibility":"off"}]},{"featureType":"water","elementType":"all","stylers":[{"color":"#57677a"},{"visibility":"on"}]},{"featureType":"water","elementType":"geometry.fill","stylers":[{"lightness":"40"}]}]
styles: [{"featureType":"water","stylers":[{"visibility":"on"},{"color":"#b5cbe4"}]},
{"featureType":"landscape","stylers":[{"color":"#efefef"}]},
{"featureType":"road.highway","elementType":"geometry","stylers":[{"color":"#83a5b0"}]},
{"featureType":"road.arterial","elementType":"geometry","stylers":[{"color":"#bdcdd3"}]},
{"featureType":"road.local","elementType":"geometry","stylers":[{"color":"#ffffff"}]},
{"featureType":"poi.park","elementType":"geometry","stylers":[{"color":"#e3eed3"}]},
{"featureType":"administrative","stylers":[{"visibility":"on"},{"lightness":33}]},
{"featureType":"road"},
{"featureType":"poi.park","elementType":"labels","stylers":[{"visibility":"on"},{"lightness":20}]},{},
{"featureType":"road","stylers":[{"lightness":20}]}]
});
var refresh = document.getElementById('refresh');
google.maps.event.addDomListener(refresh, 'click', refreshMap);
var clear = document.getElementById('clear');
google.maps.event.addDomListener(clear, 'click', clearClusters);
google.maps.event.addListener(markerClusterer, 'click', function () {
// do something with this marker ...
this.setTitle('I am clicked');
});
refreshMap();
}
function clearClusters(e) {
e.preventDefault();
e.stopPropagation();
markerClusterer.clearMarkers();
}
This works for me (it opens an infowindow when you mouseover the cluster icon, if you click on the cluster icon, the default behavior is to zoom to the cluster bounds, which makes it hard to see the change of the tooltip/title on the cluster icon):
var infoWindow = new google.maps.InfoWindow();
google.maps.event.addListener(markerClusterer, 'mouseover', function (cluster) {
// do something with this cluster ...
infoWindow.setContent("Mouseover<br>"+cluster.getCenter().toUrlValue());
infoWindow.setPosition(cluster.getCenter());
infoWindow.open(map);
});

Clustering markers with google maps version 3

I have about 2400 markers that are being displayed on google maps version 3. The problem is that there are too many markers on the map and that is not a good visual representation. What is want to do is group that the markers (i.e. cluster them). I'm experiencing some issues regarding that. Below is my sample code.
function initialize() {
var markers = JSON.parse('<%=ConvertDataTabletoString() %>');
var mapOptions = {
center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
zoom: 2,
mapTypeId: google.maps.MapTypeId.ROADMAP
//marker:true
};
var infoWindow = new google.maps.InfoWindow();
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
//Get marker image
var redMarker = 'Images/marker2.png';
var greenMarker = 'Images/g48.png';
var currentMarker;
var gmarkers = [];
for (i = 0; i < markers.length; i++) {
var data = markers[i];
var mag = data.Magnitude;
if (mag < 5) {
currentMarker = greenMarker;
}
else if (mag >= 5) {
currentMarker = redMarker;
};
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title,
icon: currentMarker
});
(function (marker, data) {
//Attaching a click event to the current marker
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent('Magnitude: ' + data.Magnitude + '<br />'
+ 'Location: ' + data.title);
infoWindow.open(map, marker);
});
})(marker, data);
gmarkers.push(marker);
}
}
var markerCluster = new MarkerClusterer(map, gmarkers);
window.onload = function () { initialize();
}
I get a javascript error in your code as posted
Uncaught ReferenceError: map is not defined
on this line:
var markerCluster = new MarkerClusterer(map, gmarkers);
The map variable is local to the initialize function.
That line is outside of the initialize function, so the map variable isn't available to it.
Put it inside the initialize function (but after the markers have been parsed).

Show One WindowInfo Per Marker(Google Map)

I try this but I can only last windowInfo.
Help me please
function initialize() {
var mapOptions = {
zoom: 5,
center: new google.maps.LatLng(33.414837,54.68141),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map'),mapOptions);
/*var weatherLayer = new google.maps.weather.WeatherLayer({
temperatureUnits: google.maps.weather.TemperatureUnit.Degree
});
weatherLayer.setMap(map);*/
/*var cloudLayer = new google.maps.weather.CloudLayer();
cloudLayer.setMap(map)*/
for (i = 0; i < StationListArray.length; i++) {
var image = StationListArray[i].split("|")[4];
var StationLocation = new google.maps.LatLng(StationListArray[i].split("|")[2], StationListArray[i].split("|")[1]);
var marker = new google.maps.Marker({
position: StationLocation,
map: map,
title: StationListArray[i].split("|")[0],
icon: image
});
google.maps.event.addListener(marker,'click',function() {
var infowindow = new google.maps.InfoWindow({
content:"Hello World!"});
infowindow.open(map,marker);
});
}
}
google.maps.event.addDomListener(window, 'load', initialize);
Change the 2nd argument of open() to this
infowindow.open(map,this);
marker refers to the variable marker, which will be overwritten on each iteration. When the loop has been finished, it points to the last marker that has been created. this inside the click-callback refers to the marker that has been clicked.

More Efficient Way to Add Markers to Google Maps v3

I am building this JS programmatically. Each marker is being represented by separate variables like marker_0,marker_1, etc... This works but is there a way to generate the markers & info windows in a more efficient/elegant way?
<script type="text/javascript">
var map;
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(41.056466,-85.3312009),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions);
//**************************************************************
//Add 1st marker
//**************************************************************
var contentString_0 ='<strong>Club name: Fort Wayne Time Corners</strong>';
var infowindow_0 = new google.maps.InfoWindow({
content: contentString_0
});
var image_0 = '/js/markers/marker1.png';
var Latlng_0 = new google.maps.LatLng(41.057814980291,-85.329851919709);
var marker_0 = new google.maps.Marker({
position: Latlng_0,
title:"0",
icon: image_0});
marker_0.setMap(map);
google.maps.event.addListener(marker_0, 'click', function() {
infowindow_0.open(map,marker_0);
});
//**************************************************************
//Add 2nd marker
//**************************************************************
var contentString_1='<strong>Club name: Roanoke</strong>';
var infowindow_1 = new google.maps.InfoWindow({
content: contentString_1
});
var image_1 = '/js/markers/marker2.png';
var Latlng_1 = new google.maps.LatLng(41.17805990,-85.4436640);
var marker_1 = new google.maps.Marker({
position: Latlng_1,
title:"1",
icon: image_1});
marker_1.setMap(map);
google.maps.event.addListener(marker_1, 'click', function() {
infowindow_1.open(map,marker_1);
});
}
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js&sensor=false&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript;
</script>
Yes, you can do this easily:
Create an array of data that describes each marker.
Write a function that adds a single marker based on the description in one entry of that array.
Call that function for each entry in that array.
So the only part you have to generate dynamically is that array of data; all of the actual marker code is shared for all markers.
Like this:
var map;
var places = [
{
lat: 41.057814980291,
lng: -85.329851919709,
image: 'marker1',
title: '0',
club: 'Fort Wayne Time Corners'
},
{
lat: 41.17805990,
lng: -85.4436640,
image: 'marker2',
title: '1',
club: 'Roanoke'
}
];
function initialize() {
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(41.056466,-85.3312009),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(
document.getElementById("map-canvas"),
mapOptions
);
for( var i = 0; i < places.length; i++ ) {
addPlace( places[i] );
}
function addPlace( place ) {
var content = '<strong>Club name: ' + place.club + '</strong>';
var infowindow = new google.maps.InfoWindow({
content: content
});
var image = '/js/markers/' + place.image + '.png';
var latlng = new google.maps.LatLng( place.lat, place.lng );
var marker = new google.maps.Marker({
position: latlng,
title: place.title,
icon: image
});
marker.setMap( map );
google.maps.event.addListener( marker, 'click', function() {
infowindow.open( map, marker );
});
}
}
function loadScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "http://maps.googleapis.com/maps/api/js&sensor=false&callback=initialize";
document.body.appendChild(script);
}
window.onload = loadScript;

I can't add multiple markers in Google Map API v3

Hi,
that's normal code at Google
var map;
function initialize()
{
var latLng = new google.maps.LatLng(41.079120183660486, 28.994637246032653);
var mapOptions = {
center: latLng,
zoom: 8,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var marker = new google.maps.Marker({
position: map.getCenter(),
map: map,
});
google.maps.event.addListener(map, 'click', function (event) {
//map.setZoom(9);
//map.setCenter(marker.getPosition());
});
}google.maps.event.addDomListener(window, 'load', initialize);
and I want to multiply marker from my DB and I can't do it. I searched in site but always result is gray map.
And my code is:
<script type="text/javascript">
var map;
var latLng;
function initialize() {
var mapOptions = {
//center: latLng,
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
var markers = [];
#foreach (var item in Model)
{
#:markers.push("#item.map")
// item.map content coming like this : 41.079120183660486,28.994637246032653
}
for (var i = 0; i < markers.length; i++) {
var marker = new google.maps.Marker({
position: latLng,
map: map,
});
}
//google.maps.event.addListener(map, 'click', function (event) {
// //map.setZoom(9);
// map.setCenter(marker.getPosition());
// //placeMarker(event.latLng);
//});
}
google.maps.event.addDomListener(window, 'load', initialize);
I can't add markers. I think missing a lot of things? I really need your opinion. Thanks
Based on your code, it looks like you're adding markers to the same lat/lng. The code below adds a few markers in a loop.
<script>
var map;
var center = new google.maps.LatLng(39.715, -84.103);
$(document).ready(initialize);
function initialize() {
// Create map
var mapOptions = {
zoom: 10,
center: center,
panControl: false,
zoomControl: true,
mapTypeControl: true,
scaleControl: true,
streetViewControl: true,
overviewMapControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map($('#map_canvas')[0], mapOptions);
for (var ii = 0; ii < 5; ii++) {
var lat = center.lat() + (0.1 * ii);
var lng = center.lng() + (0.1 * ii);
var loc = new google.maps.LatLng(lat, lng);
var marker = new google.maps.Marker({
position: loc,
map: map
});
}
}
</script>

Resources