Display InfoWindow for marker clusterers with the same position - google-maps-api-3

I am using MarkerClusterer script to display pins on map. When the user clicks on a pin, it displays an info window. This works fine for single pins.
There are also multiple pins with the exact same location and according to MarkerClusterer documentation it should be possible to display the info window with summarized description for all pins under this cluster. This is done using the infoOnClick: true option and infoOnClickZoom settings.
This however does not seem to work properly. It displays the info window, but always on the same location on the map. Even when I click on a different cluster, the info window is displayed on the last spot.
I think I'm missing something in my code.
I made a demo to demonstrate the issue:
https://jsfiddle.net/JospoDev/htj42kvz/
(for some reason in this JSFiddle the info window for grouped cluster is not displayed at all, but it works with live code)
Here is the code I'm using:
var map = null;
var infowindow = new google.maps.InfoWindow({
size: new google.maps.Size(150, 150)
});
// Draw map and make clusterers
function drawMap() {
var rows = [
[
"Marker 01",
"Address 01",
"Description 01",
"1.746491908970114, 16.92597806453705"
],
[
"Marker 02",
"Address 02",
"Description 02",
"1.7468350744069, 16.917788091659546"
],
[
"Marker 03",
"Address 03",
"Description 03",
"1.74514002150984, 16.935933225260244"
],
[
"Marker 04",
"Address 04",
"Description 04",
"1.74514002150984, 16.935933225260244"
],
[
"Marker 05",
"Address 05",
"Description 05",
"1.74514002150984, 16.935933225260244"
],
[
"Marker 06",
"Address 06",
"Description 06",
"1.74514002150984, 16.945933225260244"
],
[
"Marker 07",
"Address 07",
"Description 07",
"1.74514002150984, 16.945933225260244"
],
[
"Marker 08",
"Address 08",
"Description 08",
"1.74514002150984, 16.945933225260244"
]
];
map.markers = [];
for (var i in rows) {
var latlng = rows[i][3];
var htmlDescription = '';
var commaPos = latlng.indexOf(',');
var coordinatesLat = parseFloat(latlng.substring(0, commaPos));
var coordinatesLong = parseFloat(latlng.substring(commaPos + 1, latlng.length));
// Postition
var markerpos = new google.maps.LatLng(coordinatesLat, coordinatesLong);
// Description
htmlDescription = '<strong>' + rows[i][0] + '</strong> — ' + rows[i][1];
// Create marker
map.markers.push(createMarker(markerpos, rows[i][0], htmlDescription));
}
mc.addMarkers(map.markers);
}
// A function to create the marker and set up the event window function
function createMarker(latlng, name, html) {
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: name,
content: html
});
marker.info = new google.maps.InfoWindow({
content: html
});
// Event listener for click function
google.maps.event.addListener(marker, 'click', function(evt) {
infowindow.setContent(html);
infowindow.open(map, marker);
});
return marker;
}
// Initialize google map and run query
function initialize() {
map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(1.74514002150984, 16.925833225250244),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
// Cluster options
var mcOptions = {
infoOnClick: true, // Display info window on click
zoomOnClick: false, // Don't zoom on click
infoOnClickZoom: 14, // Threshold for displaying info window
imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'
};
// Mark Clusterer
mc = new MarkerClusterer(map, map.markers, mcOptions);
// Close the info window when clicking on the map
google.maps.event.addListener(map, 'click', function() {
infowindow.close();
});
// Draw map
drawMap();
}
// Callback to initialize
google.maps.event.addDomListener(window, 'load', initialize);
Thank you for your help.

I've had a similar issue to the one you're having. I was creating markers, however it would also display on the last marker I created. I found that the issue was because I was creating a new marker in the for loop. For whatever reason that kept overwriting the previous markers.
I fixed this by creating a function that creates markers, and calling that with whatever data I needed and returned the marker.

Related

Center map on window with random number

I am new to this forum (this is my first post) and a beginner in using google map with javascript. I hope I apologize if the question is silly.
I have an arrangement with several cities and want to focus the map according to the result of a random number. I'm using the attached code, but does not work me. Can anyone see what I am doing wrong? Thank you.
<script>
var myrand=0
function initialize() {
var i;
var Locations = [
{
lat: 40.7127837,
lon: -74.00594130000002,
title: "New york",
description: "I'm number 1"
},
{
lat: 23.634501,
lon: -102.55278399999997,
title: "Mexico",
description: "I'm number 2"
},
{
lat: 36.778261,
lon: -119.41793239999998,
title: "California",
description: "I'm number 3"
}
];
var myOptions = {
zoom: 4,
center: new google.maps.LatLng(30.011902,-98.48424649999998),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
//var map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
map = new google.maps.Map(document.getElementById('map-canvas'), myOptions);
var infowindow = new google.maps.InfoWindow({
content: ''
});
// loop over our array
for (i = 0; i < Locations.length; i++) {
// create a marker
var marker = new google.maps.Marker({
title: Locations[i].title,
position: new google.maps.LatLng(Locations[i].lat, Locations[i].lon),
map: map
});
// add an event listener for this marker
bindInfoWindow(marker, map, infowindow, "<p>" + Locations[i].description + "</p>");
//bindInfoWindow(marker, map, infowindow, Locations[i].description);
}
}
function bindInfoWindow(marker, map, infowindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(html);
infowindow.open(map, marker);
//alert("seleccionado el "+html);
});
}
function aleatorio(min,max)
{
myrand = Math.floor(Math.random()*(max-min+1)+min);
alert('salió '+ myrand);
map.setCenter({lat: Locations[myrand].lat, lng: Locations[myrand].lon});
return Math.floor(Math.random()*(max-min+1)+min);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
You have typos in your code:
the random number function in javascript is Math.random, not Math.myrandom.
the function aleatorio depends on the array Locations being in scope. Currently that array is local to the initialize function. You either need to move aleatorio inside the initialize function or move the Locations array into the global namespace.
proof of concept fiddle
code snippet:
var myrand = 0
function initialize() {
var i;
var Locations = [{
lat: 40.7127837,
lon: -74.00594130000002,
title: "New york",
description: "I'm number 1"
}, {
lat: 23.634501,
lon: -102.55278399999997,
title: "Mexico",
description: "I'm number 2"
}, {
lat: 36.778261,
lon: -119.41793239999998,
title: "California",
description: "I'm number 3"
}];
var myOptions = {
zoom: 4,
center: new google.maps.LatLng(30.011902, -98.48424649999998),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map-canvas'), myOptions);
var infowindow = new google.maps.InfoWindow({
content: ''
});
// loop over our array
for (i = 0; i < Locations.length; i++) {
// create a marker
var marker = new google.maps.Marker({
title: Locations[i].title,
position: new google.maps.LatLng(Locations[i].lat, Locations[i].lon),
map: map
});
// add an event listener for this marker
bindInfoWindow(marker, map, infowindow, "<p>" + Locations[i].description + "</p>");
}
aleatorio(0, 2);
function aleatorio(min, max) {
myrand = Math.floor(Math.random() * (max - min + 1) + min);
map.setCenter({
lat: Locations[myrand].lat,
lng: Locations[myrand].lon
});
return Math.floor(Math.random() * (max - min + 1) + min);
}
}
function bindInfoWindow(marker, map, infowindow, html) {
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(html);
infowindow.open(map, marker);
//alert("seleccionado el "+html);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
html,
body,
#map-canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map-canvas"></div>

Google maps code going hay-wire when more than one route added?

I have the following markers:
var markers = [
{
"title": '1. Welgemeend',
"lat": '-33.805556',
"stopover": true,
"lng": '18.869722',
"description": '1. Welgemeend'
},
{
"title": '2. Ruitersvlei',
"lat": '-33.783294',
"lng": '18.935900',
"stopover": true,
"description": '2. Ruitersvlei'
}
];
However, when I add a third marker:
var markers = [
{
"title": '1. Welgemeend',
"lat": '-33.805556',
"stopover": true,
"lng": '18.869722',
"description": '1. Welgemeend'
},
{
"title": '2. Ruitersvlei',
"lat": '-33.783294',
"lng": '18.935900',
"stopover": true,
"description": '2. Ruitersvlei'
}
,
{
"title": '3. Spice Route',
"lat": '-33.760815',
"lng": '18.916757',
"stopover": true,
"description": '3. Spice Route'
},
];
The drawing of the lines go crazy. Here is my gmaps code:
<div id="property-map"></div>
<script type="text/javascript">
jQuery(function($) {
var mapOptions = {
center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("property-map"), mapOptions);
var infoWindow = new google.maps.InfoWindow();
var lat_lng = new Array();
var latlngbounds = new google.maps.LatLngBounds();
for (i = 0; i < markers.length; i++) {
var data = markers[i]
var myLatlng = new google.maps.LatLng(data.lat, data.lng);
lat_lng.push(myLatlng);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: data.title
});
latlngbounds.extend(marker.position);
(function (marker, data) {
google.maps.event.addListener(marker, "click", function (e) {
infoWindow.setContent(data.description);
infoWindow.open(map, marker);
});
})(marker, data);
}
map.setCenter(latlngbounds.getCenter());
map.fitBounds(latlngbounds);
//***********ROUTING****************//
//Intialize the Path Array
var path = new google.maps.MVCArray();
//Intialize the Direction Service
var service = new google.maps.DirectionsService();
//Set the Path Stroke Color
var poly = new google.maps.Polyline({ map: map, strokeColor: '#4986E7' });
//Loop and Draw Path Route between the Points on MAP
for (var i = 0; i < lat_lng.length - 1; i++) {
var src = lat_lng[i];
var des = lat_lng[i + 1];
path.push(src);
poly.setPath(path);
service.route({
origin: src,
destination: des,
travelMode: google.maps.DirectionsTravelMode.DRIVING
}, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
for (var i = 0, len = result.routes[0].overview_path.length; i < len; i++) {
path.push(result.routes[0].overview_path[i]);
}
}
});
}
});
</script>
What could be causing this?
Line 51: remove the line
path.push(src);
The first time you push polylines to this array; a few lines further you push route segments.
This gives you two different sets of lines superimposed.
You are using confusing variable names; this causes problems. "path" is probably not a good name to store an array of data (well, not for what you are doing).
A few other details: for(var i ...) -> You should put the var on the first for(), not on the second for().
poly.setPath(path); should not be inside a loop.
Here is how I would have done this.
(I added a 4th random point. Remove it if you want)
<head>
<style>
html, body, #property-map {
height: 400px;
margin: 0px;
padding: 0px
}
#content {
width: 200px;
overflow: hidden;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?"></script>
<script>
var markers = [{
"title": '1. Welgemeend',
"lat": '-33.805556',
"lng": '18.869722',
"stopover": true,
"description": '1. Welgemeend'
},
{
"title": '2. Ruitersvlei',
"lat": '-33.783294',
"lng": '18.935900',
"stopover": true,
"description": '2. Ruitersvlei'
}
,
{
"title": '3. Spice Route',
"lat": '-33.760815',
"lng": '18.916757',
"stopover": true,
"description": '3. Spice Route'
},
{
"title": '4. Some random point',
"lat": '-33.75',
"lng": '18.90',
"stopover": true,
"description": '4. Some random point'
}];
jQuery(function($) {
var mapOptions = {
center: new google.maps.LatLng(markers[0].lat, markers[0].lng),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("property-map"), mapOptions);
var infoWindow = new google.maps.InfoWindow();
var routeObjects = [];
var markerObjects = [];
var directionService = new google.maps.DirectionsService();
var latlngbounds = new google.maps.LatLngBounds();
// loop through the markers.
// Create the marker, then send a request for a route between this marker and the next (except for the last iteration).
for (var i=0; i<markers.length; i++) {
// create the marker
var marker = new google.maps.Marker({
position: new google.maps.LatLng(markers[i].lat, markers[i].lng),
title: markers[i].title,
map: map
});
markerObjects.push(marker);
latlngbounds.extend(marker.position);
// click event: show an infowindow with the description
google.maps.event.addListener(marker, "click", function (e) {
var i = markerObjects.indexOf(this);
infoWindow.setContent('<div id="content">' + markers[i].description + '</div>');
infoWindow.setPosition(this.getPosition());
infoWindow.open(map, this);
});
// send a route request, except on the last iteration
if (i < markers.length - 1) {
directionService.route({
origin: new google.maps.LatLng(markers[i].lat, markers[i].lng),
destination: new google.maps.LatLng(markers[i + 1].lat, markers[i + 1].lng),
travelMode: google.maps.DirectionsTravelMode.DRIVING
}, function (result, status) {
if (status == google.maps.DirectionsStatus.OK) {
// We will draw this part of the route on the map; not worry about the other requests
var path = new google.maps.MVCArray();
for (var j = 0; j < result.routes[0].overview_path.length; j++) {
path.push(result.routes[0].overview_path[j]);
}
var poly = new google.maps.Polyline({
path: path,
map: map,
strokeColor: '#4986E7'
});
routeObjects.push(path); // I don't really us this in this script, but it might be useful
}
});
}
else { // last iteration. This might be a good place to do the last-minute things
map.fitBounds(latlngbounds);
}
}
});
</script>
</head>
<body>
<div id="property-map"></div>
</body>

Google Fusion Styles api, last style applied to all

So I'm trying to apply styles according to contents of a string in a certain column, at the moment I'm just testing for one particular string.
function makeMap(lat, lng, zoom) {
myLatLng = new google.maps.LatLng(lat, lng)
map = new google.maps.Map(document.getElementById('googft-mapCanvas'), {
center: myLatLng,
zoom: zoom,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: { enabled: false },
query: {
select: "col5",
from: "1Qrjmw1bt5n__AQhdCbiShbMCVS8FqySXx8Jie4A",
where: "month = 2013-05 || month = 2013-06"
},
styles: [
{ markerOptions: { iconName: 'small_yellow' }},
{
where: "'Last outcome category' = 'No further action at this time'",
markerOptions: { iconName: 'small_red' }
}
],
options: {
templateId: 2
}
});
marker = new google.maps.Marker({
position: myLatLng,
map: map,
title:"You are here!"
});
}
What this seems to be doing at the moment is applying the last style to everything, so in this case everything is the red marker but if I switch it around everything will be the yellow marker.
The where clause in the FusionTableLayer query is invalid
where: "month = 2013-05 || month = 2013-06"
(There is no 'or' (||) operator in FusionTables) It seems to be causing the styles not to be processed correctly.
working example

google maps async

I have a google maps script that I'm using that works fine declaring google maps with a script tag, but I'd like to load it asynchronously and am having trouble making the changes. This is what I currently have:
//<![CDATA[
$(window).load(function(){
var locations = [
[
"850 Boylston Street",
"Chestnut Hill, MA 02467",
"42.326435",
"-71.149499"
],
[
"Subway Brookline Village",
"Green Line, D",
"42.33279",
"-71.11630"
],
[
"Shuttle Brookline Village",
"10 Brookline Place",
"42.33262",
"-71.116439"
],
[
"Subway Chestnut Hill",
"Green Line, B",
"42.338164",
"-71.153164"
],
[
"Subway Cleveland Circle",
"Green Line, C",
"42.336145",
"-71.149323"
],
[
"Subway Reservoir",
"Green Line, D",
"42.335132",
"-71.148762"
],
[
"Bus 51 Reservoir",
"Pick up from Subway",
"42.335021",
"-71.148988"
],
[
"Bus 51 Route 9",
"Drop off Route 9",
"42.326499",
"-71.142588"
],
[
"75 Francis Street",
"Boston, MA 02115",
"42.33619",
"-71.10705"
],
[
"Shuttle Longwood",
"Shapiro Building",
"42.33603",
"-71.10779"
],
[
"Subway Longwood",
"Green Line, D",
"42.34113",
"-71.11044"
],
[
"Subway Brigham Circle",
"Green Line, E",
"42.33422",
"-71.10455"
],
[
"Parking Garage",
"70 Francis Street",
"42.33422",
"-71.10455"
],
[
"20 Patriots Place",
"Foxboro, MA 02035",
"42.09254",
"-71.26629"
]
];
gmarkers = [];
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: new google.maps.LatLng(42.326435, -71.149499),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl:false
});
var infowindow = new google.maps.InfoWindow();
function createMarker(latlng, html) {
var marker = new google.maps.Marker({
position: latlng,
map: map
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(html);
infowindow.open(map, marker);
});
return marker;
}
for (var i = 0; i < locations.length; i++) {
/* alert("location:"+
locations[i][0]+":"+locations[i][2]+","+locations[i][3]);
*/
gmarkers[locations[i][0]]=
createMarker(new google.maps.LatLng(locations[i][2], locations[i][3]), locations[i][0]
+ "<br>" + locations[i][1]);
}
/*
$(function() {
$('#locations h3 a').each(function() {
$(this).on('click', function() {
google.maps.event.trigger(marker, 'click');
})
});
});
*/
});//]]>
You have two options
inject the script tag as described here:
https://developers.google.com/maps/documentation/javascript/tutorial#Loading_the_Maps_API
use the AjaxLoader:
https://google-developers.appspot.com/loader/
You would add:
<script type="text/javascript" src="http://www.google.com/jsapi"> </script>
at the top of the page and then load the map using:
google.load("maps","3.9", {"other_params":"sensor=false"});
HTH
<script type="text/javascript">
var map;
function initialize() {
var mapOpt = {
/* le coordinate di partenza si possono impostare dal db */
center: new google.maps.LatLng(42, 12),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("googleMap"), mapOpt);
}
...in your html refer in a element "< div id="googleMap">"

google maps, adding more markers to array and body

how would I go about adding additional markers to this set up? There are currently three and I've been messing around with it, but I'm not sure how to continue adding markers to it
I've been trying things on this JS Bin as well http://jsbin.com/agemuw/2/edit but haven't got it working
JS:
<script type='text/javascript'>//<![CDATA[
$(window).load(function(){
var locations = [
[
"850 Boylston Street",
"Chestnut Hill, MA 02467",
"42.326435",
"-71.149499"
],
[
"Subway Brookline Village",
"Green Line, D",
"42.33279",
"-71.11630"
],
[
"Shuttle Brookline Village",
"10 Brookline Place",
"42.33262",
"-71.116439"
]
];
gmarkers = [];
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 16,
center: new google.maps.LatLng(42.326435, -71.149499),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var infowindow = new google.maps.InfoWindow();
function createMarker(latlng, html) {
var marker = new google.maps.Marker({
position: latlng,
map: map
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(html);
infowindow.open(map, marker);
});
return marker;
}
for (var i = 0; i < locations.length; i++) {
/* alert("location:"+
locations[i][0]+":"+locations[i][2]+","+locations[i][3]);
*/
gmarkers[locations[i][0]]=
createMarker(new google.maps.LatLng(locations[i][2], locations[i][3]), locations[i][0]
+ "<br>" + locations[i][1]);
}
/*
$(function() {
$('#locations h3 a').each(function() {
$(this).on('click', function() {
google.maps.event.trigger(marker, 'click');
})
});
});
*/
});//]]>
html:
<body>
<div id="map" style="width: 500px; height: 400px;"></div>
<div id="locations">
<h3><a href="javascript:google.maps.event.trigger(gmarkers['850 Boylston
Street'],'click');">850 Boylston Street</a></h3>
<p>Arbitrary content about 1</p>
<h3><a href="javascript:google.maps.event.trigger(gmarkers['Subway Brookline
Village'],'click');">Brookline Village T Stop</a></h3>
<p>Arbitrary content about 2</p>
<h3><a href="javascript:google.maps.event.trigger(gmarkers['Shuttle Brookline
Village'],'click');">Shuttle - 10 Brookline Place</a></h3>
<p>Arbitrary content about 3</p>
</div>
</body>
you have a Javascript error
after the 3rd location you are missing a comma , after the square bracket ]
///....snip
"10 Brookline Place",
"42.33262",
"-71.116439"
], //right here
[
"Subway Chestnut Hill",
"Green Line, D",
///...snip
EDIT
adding custom markers to the map
Add the icon property like below - easy way is to just put a url in - hard way if you want to define shadows and anchor points is to build one - see the Google Maps API for the in depth stuff
var marker = new google.maps.Marker({
icon : "http://urlofmymarker.png", //comma is important
position: latlng,
map: map
});

Resources