Multiple Marker InfoWindow in Google Maps v3 - google-maps-api-3

I've testing this for about 1 hour now. But for some reason I can't make it work, to display another infowindow text for each marker.
Clicking each of them, will open a new infowindow (the old one will be closed which is good), but the text inside the window is always the text I set in the last marker:
function initialize() {
var center = new google.maps.LatLng(51.133333,10.416667);
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var markers = [];
for (var i = 0, dataPhoto; dataPhoto = data.photos[i]; i++) {
var latLng = new google.maps.LatLng(dataPhoto.latitude,
dataPhoto.longitude);
var marker = new google.maps.Marker({
position: latLng,
title: dataPhoto.infotitle,
map: map,
});
/* Create Info Windows */
var infowindow = new google.maps.InfoWindow({
content: " "
});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent('<h3>'+marker.title+'</h3>'+' Infotext');
infowindow.open(map, this);
});
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers);
}
I've been seeing some solutions around here, but none of them seemed to work properly for me.
I'd really appreciate your help!
See online demo.

You simply have to set the Content to this.title, instead of marker.title
infowindow.setContent('<h3>'+this.title+'</h3>'+' Infotext');
Thanks
dz46

you dont have any way to store the infoWindow.. Look at my code, i use infoBubble library but it should be very similar. This is probably more code than you need, but more the merrier..
/**
* infoBubble Variable
* This variable is globally defined for defaults that are loaded.
*/
var infoBubbles = [];
/**
* array of all of the markers that are on the map
*
* #type {Array}
* #author Mike DeVita
* #copyright 2011 MapIT USA
* #category map_Js
*/
var markersArray = [];
/**
* array of all of the sidebar items for all of the markers on the map
*
* #type {Array}
* #author Mike DeVita
* #copyright 2011 MapIT USA
* #category map_Js
*/
var sidebarHtmlArray = [];
/**
* setPoints(locations)
*
* sets the marker, infoBubble and sidebarItem based on the locations
* that were returned from the JSON query.
*
* #param {array} locations array of all of the points, and their settings/html
*
* #author Mike DeVita
* #author Google Maps API
* #copyright 2011 MapIT USA
* #category map_js
*/
function setPoints(locations){
for (var i = 0; i < locations.length; i++) {
/** #type {array} reassigns locations array to be point, isolates it to the setPoints() function */
var point = locations;
/** #type {google} generates Googles API form of the lat lng passed from var point */
var myLatLng = new google.maps.LatLng(point[i].lat, point[i].lng);
/**
* marker variable, stores all of the information pertaining to a specific marker
* this variable creates the marker, places it on the map and then also sets some
* custom options for the infoBubbles.
*
* #type {google}
*/
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
animation: google.maps.Animation.DROP,
icon: point[i].marker_icon
});
/** push the marker to the markersArray to delete or show the overlays */
markersArray.push(marker);
var sidebarItem = point[i].sidebarHtmlView;
sidebarHtmlArray.push(sidebarItem);
infoBubbles[i] = new InfoBubble({
map: map,
minHeight: point[i].min_height,
maxHeight: point[i].max_height,
minWidth: point[i].min_width,
maxWidth: point[i].max_width,
disableAutoPan: false,
hideCloseButton: false,
arrowPosition: 30,
padding:12
});
var tabs = point[i].tabs;
infoBubbles[i].addTab('Company', point[i].html);
for (var ii = 0; ii < tabs.length; ii++) {
infoBubbles[i].addTab(tabs[ii].tabTitle, tabs[ii].tabContent);
}
/**
* add the listeners for the markerClicks and the sideBarClicks
*
* #type {google}
* #todo eventDomListener does not work yet, this is the click listener of the sidebar item's
*/
google.maps.event.addListener(marker, 'click', handleMarkerClick(marker, i));
}
}
function handleMarkerClick(marker,index) {
return function() {
if (!infoBubbles[index].isOpen()) {
infoBubbles[index].open(map, marker);
}else{
infoBubbles[index].close(map, marker);
}
}
}
/**
* addmarker(location)
*
* adds the marker to the map and pushes the marker
* to the end of the markersArray
*
* #param {google} location LatLng of where the marker should be put
*
* #author Mike DeVita
* #author Google API
* #copyright 2011 MapIT USA
* #category map_js
*/
function addMarker(location, marker_icon){
marker = new google.maps.Marker({
position: location,
map: map,
animation: google.maps.Animation.DROP,
icon: marker_icon
});
markersArray.push(marker);
}

Change your code to
var markers = new Array();
var infowindow = new Array();
var map;
function initialize() {
var center = new google.maps.LatLng(51.133333,10.416667);
map = new google.maps.Map(document.getElementById('map'), {
zoom: 6,
center: center,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
for (var i = 0, dataPhoto; dataPhoto = data.photos[i]; i++) {
var latLng = new google.maps.LatLng(dataPhoto.latitude,
dataPhoto.longitude);
markers[i] = new google.maps.Marker({
position: latLng,
title: dataPhoto.infotitle,
map: map,
});
/* Create Info Windows */
infowindow[i] = new google.maps.InfoWindow({
content: " "
});
google.maps.event.addListener(markers[i], 'click', function() {
infowindow[i].setContent('<h3>'+this.title+'</h3>'+' Infotext');
infowindow[i].open(map, this);
});
}
var markerCluster = new MarkerClusterer(map, markers);
}

Related

How to customize Google Maps AdvancedMarkerView in a dynamic map?

I'm using ACF to create maps from custom product fields in WordPress/Woocommerce.
/**
* initMarker
*
* Creates a marker for the given jQuery element and map.
*
* #date 22/10/19
* #since 5.8.6
*
* #param jQuery $el The jQuery element.
* #param object The map instance.
* #return object The marker instance.
*/
function initMarker( $marker, map ) {
// Get position from marker.
var lat = $marker.data('lat');
var lng = $marker.data('lng');
var latLng = {
lat: parseFloat( lat ),
lng: parseFloat( lng )
};
// Create marker instance.
var marker = new google.maps.Marker({
position: latLng,
map: map
});
// Append to reference for later use.
map.markers.push( marker );
// If marker contains HTML, add it to an infoWindow.
if( $marker.html() ){
// Create info window.
var infowindow = new google.maps.InfoWindow({
content: $marker.html()
});
// Show info window when marker is clicked.
google.maps.event.addListener(marker, 'click', function() {
infowindow.open( map, marker );
});
}
}
I'd like to style my initial marker with custom colors.
Google Maps documentation instructs how to work with a defined position, as follows, but if I delete the position line, my map just disappears.
// [START maps_advanced_markers_basic_style_background]
// Change the background color.
const pinViewBackground = new google.maps.marker.PinView({
background: "#FBBC04",
});
const markerViewBackground = new google.maps.marker.AdvancedMarkerView({
map,
position: { lat: 37.419, lng: -122.01 },
content: pinViewBackground.element,
});
// [END maps_advanced_markers_basic_style_background]
// [START maps_advanced_markers_basic_style_border]
// Change the border color.
const pinViewBorder = new google.maps.marker.PinView({
borderColor: "#137333",
});
const markerViewBorder = new google.maps.marker.AdvancedMarkerView({
map,
position: { lat: 37.415, lng: -122.03 },
content: pinViewBorder.element,
});
// [END maps_advanced_markers_basic_style_border]
Is there a way I can apply the above mentioned styles in a dynamic map?
Yes, you can style your markers dynamically using the icon property of the google.maps.Marker object.
You can specify a URL to a custom icon, or you can create a custom icon programmatically using a google.maps.Symbol object, which allows you to set various properties such as the fill color, stroke color, and path.
Here's an example that sets the marker's fill color to blue:
var marker = new google.maps.Marker({
position: latLng,
map: map,
icon: {
path: 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z',
fillColor: '#0000FF',
fillOpacity: 1,
strokeColor: '#000000',
strokeWeight: 2,
scale: 1
}
});
You can adjust the path and other properties to get the desired appearance for your markers.

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);
});

How come the mouseover and mouseout events for MarkerClustererPlus.js are not firing for my cluster?

The mouseover and mouseout events are not firing for the MarkerCluster class as per the MarkerClustererPlus documentation. I even tried stuffing it in the clusteringend event as I noticed you need to wait for this before doing anything else with the clusters, but no luck.
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 10,
center: new google.maps.LatLng(arrLocLatLng[0], arrLocLatLng[1]),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var arrMarkers = [
new google.maps.Marker({
position: new google.maps.LatLng(myLat1, myLng1)
}),
new google.maps.Marker({
position: new google.maps.LatLng(myLat2, myLng2)
})
];
var mcOptions = {gridSize: 50, maxZoom: 15};
var mc = new MarkerClusterer(map, arrMarkers, mcOptions);
// need to wait for clusteringend, otherwise clusters may not be in DOM
google.maps.event.addListener(mc, 'clusteringend', function () {
var arrClusters = mc.getClusters(); // will just be one
// THIS IS NOT FIRING
// Event name: mouseout
// Event args: c:Cluster
// Event Desc: This event is fired when the mouse moves out of a cluster marker.
google.maps.event.addListener(arrClusters[0], 'mouseover', function ()
{
alert('mouseover event triggered on this particular cluster);
});
// ALSO NOT FIRING
// Event name: mouseover
// Event args: c:Cluster
// Event Desc: This event is fired when the mouse moves over a cluster marker.
google.maps.event.addListener(arrClusters[0], 'mouseout', function ()
{
alert('mouseout event triggered on this particular cluster);
});
});
Found it. There's a bug in the markerclusterer.js file version 2.0.15 as of 1/29/13.
In the MarkerClusterer.js file (non-packed version), change this:
google.maps.event.addDomListener(this.div_, "mouseover", function () {
var mc = cClusterIcon.cluster_.getMarkerClusterer();
/**
* This event is fired when the mouse moves over a cluster marker.
* #name MarkerClusterer#mouseover
* #param {Cluster} c The cluster that the mouse moved over.
* #event
*/
google.maps.event.trigger(mc, "mouseover", cClusterIcon.cluster_);
});
google.maps.event.addDomListener(this.div_, "mouseout", function () {
var mc = cClusterIcon.cluster_.getMarkerClusterer();
/**
* This event is fired when the mouse moves out of a cluster marker.
* #name MarkerClusterer#mouseout
* #param {Cluster} c The cluster that the mouse moved out of.
* #event
*/
google.maps.event.trigger(mc, "mouseout", cClusterIcon.cluster_);
});
};
to this:
google.maps.event.addDomListener(this.div_, "mouseover", function () {
var c = cClusterIcon.cluster_;
/**
* This event is fired when the mouse moves over a cluster marker.
* #name MarkerClusterer#mouseover
* #param {Cluster} c The cluster that the mouse moved over.
* #event
*/
google.maps.event.trigger(c, "mouseover", cClusterIcon.cluster_);
});
google.maps.event.addDomListener(this.div_, "mouseout", function () {
var c = cClusterIcon.cluster_;
/**
* This event is fired when the mouse moves out of a cluster marker.
* #name MarkerClusterer#mouseout
* #param {Cluster} c The cluster that the mouse moved out of.
* #event
*/
google.maps.event.trigger(c, "mouseout", cClusterIcon.cluster_);
});
... and it will work.

Google Maps API v3 port

I am trying to port my google api v2 to v3 but it does not work....i get an "Polyline is not defined" error... :/ the old Polyline is GPolyline and the new is new google.maps.Polyline
https://developers.google.com/maps/documentation/javascript/overlays?hl=de-DE#Polylines
var map = "";
var mapConfig = "";
var mapElements = "";
var curActiveMenuButton = "";
var clickHandlerElementCount = "";
//window.onload = function() {
//window.addEvent('domready', function() {
//document.addEvent('domready', function() {
//alert("The DOM is ready.");
//initializeMap();
//});
/*
* function initializeMap()
*
* Initalisierung der Google-Map.
*/
function initializeMap(){
// Karte ins DOM einhängen
map = new google.maps.Map($('map_canvas'), myOptions);
//place the map on the canvas
//map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
var latlng = new google.maps.LatLng(51.05758110879136, 10.451431274414062);
// default zoomlevel and center point
var myOptions = {
zoom: 12,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
navigationControl: true,
mapTypeControl: true,
scaleControl: true,
};
// default zoomlevel and center point
var encodedPolyline = new google.maps.Polyline();
// find bounding polyline and recalculate map center
for (var i = 0; i < mapElements.length; i++) {
if (mapElements[i]['titel'] == "nationalparkhainich") {
encodedPolyline = Polyline.fromEncoded({
points: mapElements[i]['pol'],
levels: mapElements[i]['lev']
});
mapCenter = encodedPolyline.getBounds().getCenter();
i = mapElements.length;
}
}
// Kartenmenue initialisieren
//initializeMapMenue();
}
Polyline is indeed not defined. You use it here:
encodedPolyline = Polyline.fromEncoded({
Version 3 doesn't include fromEncoded() — it appears that you need to use the geometry library (which needs to be explicitly loaded separately) and
encodedPolyline.setPath(
google.maps.geometry.encoding.decodePath(mapElements[i]['pol'])
);
[split on to separate lines here for clarity]

Javascript Google map api V3 fitbounds with center location

I want to fitbound pushpins to visible all around user's location pushpin. i wrote the following code it center the user location but few pushpin goes out of map ??
FYI: userPinLoc is pushpin object which is already populated
function setInitialZoom() {
mapZoom = googleMap.getZoom();
var bounds = new google.maps.LatLngBounds();
bounds.extend(userPinLoc);
for (i in nearestEntitiesToZoom) {
entity = nearestEntitiesToZoom[i];
var googleLatLng = new google.maps.LatLng(entity.latitude,entity.longitude);
bounds.extend(googleLatLng);
}
google.maps.event.addDomListener(googleMap, 'bounds_changed', function() {
googleMap.setCenter(userPinLoc);
});
googleMap.fitBounds(bounds);
}
I'm not sure where you're getting userPinLoc from. Give this a go:
...
var bounds = new google.maps.LatLngBounds();
// Go through each...
for (i in nearestEntitiesToZoom) {
entity = nearestEntitiesToZoom[i];
var googleLatLng = new google.maps.LatLng(entity.latitude, entity.longitude);
bounds.extend(googleLatLng);
};
// Fit these bounds to the map
googleMap.fitBounds(bounds);
...
Remember, fitCenter or fitBounds needs a LatLng object as a parameter.
This code is adapted from: http://you.arenot.me/2010/06/29/google-maps-api-v3-0-multiple-markers-multiple-infowindows/
I did it using java and javascript
public static void calculateMapFitBounds(GeoLocation userLocation, List<GeoLocation> contents, Map<String, GeoLocation> latlngBounds){
if (Util.isEmtpyGeoLocation(userLocation) || contents == null || contents.isEmpty()) {
return;
}
//SW
double minLat = userLocation.getLatitude();
double minLng = userLocation.getLongitude();
//NE
double maxLat = userLocation.getLatitude();
double maxLng = userLocation.getLongitude();
for(GeoLocation content: contents){
/*
* Populating Top left cordinate (SW)
*/
minLat = Math.min(minLat, content.getLatitude());
minLng = Math.min(minLng, content.getLongitude());
/*
* Populating Bottom right cordinate (NE)
*/
maxLng = Math.max(maxLng, content.getLongitude()) ;
maxLat = Math.max(maxLat, content.getLatitude());
}
/*
* Calculating Delta fit bounds
*/
double latDelta = Math.max(Math.abs(userLocation.getLatitude() - minLat), Math.abs(maxLat-userLocation.getLatitude()));
double lngDelta = Math.max(Math.abs(userLocation.getLongitude() - maxLng), Math.abs(minLng - userLocation.getLongitude()));
//Calculating SW
minLat = userLocation.getLatitude() - latDelta;
minLng = userLocation.getLongitude()- lngDelta;
latlngBounds.put("swLatLng", new GeoLocation(minLat, minLng));
//Calculating NE
maxLat = userLocation.getLatitude() + latDelta;
maxLng = userLocation.getLongitude()+ lngDelta;
latlngBounds.put("neLatLng", new GeoLocation(maxLat, maxLng));
}
I am using velocity views so here is velocity and js code
#if($swLatLng && $neLatLng)
var swLatLn = new google.maps.LatLng($!swLatLng.latitude, $!swLatLng.longitude, false);
var neLatLn = new google.maps.LatLng($neLatLng.latitude, $neLatLng.longitude, false);
var bounds = new google.maps.LatLngBounds(swLatLn, neLatLn);
googleMap.fitBounds(bounds);
#end
When I've done this before, I've done the bounds.extend() for the map center as the very last one, not the first one. Which seemed to work better for some reason.
function initialize() {
var points = [
{
lat: 51.498725,
lng: -0.17312
},
{
lat: 51.4754091676,
lng: -0.186810493469
},
{
lat: 51.4996066187,
lng: -0.113682746887
},
{
lat: 51.51531272,
lng: -0.176296234131
}
];
var centerLatLng = {lat: 51.532315, lng: -0.1544};
var map = new google.maps.Map(document.getElementById("map"), {
zoom: 15,
center: centerLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var bounds = new google.maps.LatLngBounds();
var homeMarker = new google.maps.Marker({
position: centerLatLng,
map: map,
icon: "http://maps.google.com/mapfiles/ms/micons/green-dot.png"
});
for (var i = 0; i < points.length; i++) {
var marker = new google.maps.Marker({
position: points[i],
map: map
});
bounds.extend(points[i]);
}
bounds.extend(centerLatLng);
map.fitBounds(bounds);
}

Resources