How to create pop up windows on google map clusterer circles - google-maps

I am using the following google map plugin
google map clusterer
And it works perfectly(insead of random variable that you see in that link I just read locations from database.)
Now I have been asked the followoing: when a user hover on the clustered area(Not a markers) , by clustered area I mean red or yellow or blue circle , I want a pop up window appears for showing some information . I searched the web a lot but I could not find anything, Is it possible to do this?(I appreciate any help)
Update:
Here is the code that I am using :
$('#map_canvas').gmap({ 'zoom': 3, 'disableDefaultUI': true }).one('init', function (evt, map) {
var bounds = map.getBounds();
var temp = mark1;
var southWest = bounds.getSouthWest();
var northEast = bounds.getNorthEast();
var lngSpan = northEast.lng() - southWest.lng();
var latSpan = northEast.lat() - southWest.lat();
for (var i = 0; i < 300; i++) {
var contentString = 'test';
var $marker = $(this).gmap('addMarker',
{
'id': i, 'position': new google.maps.LatLng(
southWest.lat() + latSpan * Math.random(),
southWest.lng() + lngSpan * Math.random()),
'content': 'm_' + i
}).click(function (i) {
$('#map_canvas').gmap('openInfoWindow', {
content: this.content
}, this);
});
markers.push($marker); // add to the marker array
}
$(this).gmap('set', 'MarkerClusterer', new MarkerClusterer(map, $(this).gmap('get', 'markers')));
});

With the latest markerclusterer.js this should work:
google.maps.event.addDomListener(markerClusterer, 'mouseover', function() {
console.log('mouse over marker clusterer');
});

Related

Google maps Spiderfier, map unresponsive after setmap(null)

I have a function that loads my map to keep my map static.
<script>
var delArray = new Array();
var gm;
var map;
var iw;
var oms;
window.onload = function(){
gm = google.maps;
map = new gm.Map(document.getElementById('map_canvas'), {
mapTypeId: gm.MapTypeId.TERRAIN,
center: new gm.LatLng(-29.335205, 24.793563),
scrollwheel: false,
zoom: 6
});
iw = new gm.InfoWindow();
oms = new OverlappingMarkerSpiderfier(map,
{markersWontMove: true, markersWontHide: true});
}
</script>
I then use another function to construct my spiderfier data.
<script>
function spider(mapData){
var usualColor = 'eebb22';
var spiderfiedColor = 'ffee22';
var iconWithColor = function(color) {
return 'http://chart.googleapis.com/chart?chst=d_map_xpin_letter&chld=pin|+|' +
color + '|000000|ffff00';
}
var shadow = new gm.MarkerImage(
'https://www.google.com/intl/en_ALL/mapfiles/shadow50.png',
new gm.Size(37, 34), // size - for sprite clipping
new gm.Point(0, 0), // origin - ditto
new gm.Point(10, 34) // anchor - where to meet map location
);
oms.addListener('click', function(marker) {
iw.setContent(marker.desc);
iw.open(map, marker);
});
oms.addListener('spiderfy', function(markers) {
for(var i = 0; i < markers.length; i ++) {
markers[i].setIcon(iconWithColor(spiderfiedColor));
markers[i].setShadow(null);
}
iw.close();
});
oms.addListener('unspiderfy', function(markers) {
for(var i = 0; i < markers.length; i ++) {
markers[i].setIcon(iconWithColor(usualColor));
markers[i].setShadow(shadow);
}
});
var bounds = new gm.LatLngBounds();
for (var i = 0; i < mapData.length; i ++) {
var datum = mapData[i];
var loc = new gm.LatLng(datum[0], datum[1]);
bounds.extend(loc);
var marker = new gm.Marker({
position: loc,
title: datum[2],
animation: google.maps.Animation.DROP,
map: map,
icon: iconWithColor(usualColor),
shadow: shadow
});
marker.desc = datum[3];
oms.addMarker(marker);
delArray.push(marker);
}
map.fitBounds(bounds);
// for debugging/exploratory use in console
window.map = map;
window.oms = oms;
}
</script>
And Another to remove markers from the map:
<script>
function delMe(){
if(delArray){
for(i =0; i <= delArray.length; i++){
delArray[i].setMap(null);
}
this.delArray = new Array();
}
}
</script>
My map data (mapData) comes from a php script and passed on via Jason. And that's also where I call my delete function right before I call my spider (map) function. This I do to clear the map before I pass the new data.
$( document ).ready(function() {
delMe();
var pdata = $js_array;
spider(pdata);
});
Now, my problem is that all data is displaying perfectly but after calling the delMe() function it clears the markers 100% but then my map become unresponsive it's not loading new data when calling the spider() function with new data.
I can overcome this problem by reloading/creating the map again, but I want to avoid that and only use a static map. And if I don't delete markers it just fill the map with 100's of markers mixing the old and new.
I am a bit of a noob when it comes to javascript/jquery, any help will be much appreciated!.
It looks like you're missing an OMS removeMarker call in your delMe function, which should go something like this:
function delMe(){
if (delArray){
for (i =0; i <= delArray.length; i++){
oms.removeMarker(delArray[i]);
delArray[i].setMap(null);
}
this.delArray = [];
}
}
(It's possible you have other problems too, but here's a start).
It's not clear from what you write, but are you using the JS developer console? Google '[your browser] developer console' for more info — it lets you see if errors are causing your map to become unresponsive.

Google Maps Multiple markers with the exact same location Not working

I want to check to see if any of the existing markers match the latlng of the new marker and if so then merge the info window/tooltip text.
This is what I tried to do:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title></title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclustererplus/src/markerclusterer.js"></script>
<script type="text/javascript">
var map;
var mc;//marker clusterer
var mcOptions = {gridSize: 10, maxZoom: 8};
var infowindow = new google.maps.InfoWindow();//global infowindow
var geocoder = new google.maps.Geocoder(); //geocoder
var address = new Array("42.3334,-89.1572",
"39.2058,-76.7531",
"39.7751,-86.1322",
"40.4894,-78.3499",
"42.0203,-87.9059",
"36.2673,-86.2912",
"33.6115,-84.3745",
"44.9793,-93.273",
"40.1461,-76.0738",
"32.2911,-90.1927",
"32.9315,-96.6158",
"36.0553,-79.8317",
"41.8397,-88.0887",
"47.8029,-103.267",
"34.106,-83.589",
"41.5907,-87.3199",
"43.0905,-74.3554",
"40.3438,-74.4289",
"40.8651,-96.8231",
"40.8651,-96.8231",
"41.759,-88.1524",
"38.2512,-86.8675",
"41.8119,-87.6873",
"41.3651,-89.0866",
"25.7791,-80.1978",
"41.6404,-88.0696",
"41.7684,-88.1366",
"39.7299,-86.4234",
"41.5234,-81.5996",
"41.6233,-88.0225",
"41.0171,-80.8029",
"40.2899,-82.9811",
"41.8119,-87.6873",
"32.3445,-99.8021",
"41.8119,-87.6873",
"29.8131,-95.3098",
"35.1693,-89.9904",
"33.6115,-84.3745",
"47.7374,-103.298",
"46.3502,-94.1",
"41.9907,-88.4298",
"35.3716,-80.5621",
"38.189,-85.6768",
"41.8119,-87.6873",
"32.7714,-97.2915");
var content = new Array("UnitNo1",
"UnitNo2",
"UnitNo3",
"UnitNo4",
"UnitNo5",
"UnitNo6",
"UnitNo7",
"UnitNo8",
"UnitNo9",
"UnitNo10",
"UnitNo11",
"UnitNo12",
"UnitNo13",
"UnitNo14",
"UnitNo15",
"UnitNo16",
"UnitNo17",
"UnitNo18",
"UnitNo19",
"UnitNo20",
"UnitNo21",
"UnitNo22",
"UnitNo23",
"UnitNo24",
"UnitNo25",
"UnitNo26",
"UnitNo27",
"UnitNo28",
"UnitNo29",
"UnitNo30",
"UnitNo31",
"UnitNo32",
"UnitNo33",
"UnitNo34",
"UnitNo35",
"UnitNo36",
"UnitNo37",
"UnitNo38",
"UnitNo39",
"UnitNo40",
"UnitNo41",
"UnitNo42",
"UnitNo43",
"UnitNo44",
"UnitNo45");
//min and max limits for multiplier, for random numbers //keep the range pretty small, so markers are kept close by
var min = .999999;
var max = 1.000001;
function createMarker(latlng,text) {
var marker = new google.maps.Marker({
position: latlng,
map: map
});
///get array of markers currently in cluster
var allMarkers = mc.getMarkers();
//check to see if any of the existing markers match the latlng of the new marker
if (allMarkers.length != 0) {
for (i=0; i < allMarkers.length; i++) {
var existingMarker = allMarkers[i];
var pos = existingMarker.getPosition();
if (latlng.equals(pos)) {
text = text + " & " + content[i];
}
}
}
// WHERE TO ADD: mc.addMarker(marker); //??
google.maps.event.addListener(marker, 'click', function() {
infowindow.close();
infowindow.setContent(text);
infowindow.open(map,marker);
});
return marker;
}
function initialize(){
var options = {
zoom: 4,
center: new google.maps.LatLng(39.8282,-98.5795),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map'), options);
var gmarkers = [];
for (i=0; i<address.length; i++) {
var ptStr = address[i];
var coords = ptStr.split(",");
var latlng = new google.maps.LatLng(parseFloat(coords[0]),parseFloat(coords[1]))
gmarkers.push(createMarker(latlng,content[i]));
}
//marker cluster
mc = new MarkerClusterer(map, gmarkers, mcOptions);
for (i=0; i<address.length; i++) {
geocodeAddress(address[i],i);
}
}
</script>
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body onload="initialize();">
<div id="map"></div>
</body>
</html>
I tired to take this working example found here http://www.geocodezip.com/SO_OverQueryLimitB.html and add the following code into it:
///get array of markers currently in cluster
var allMarkers = mc.getMarkers();
//check to see if any of the existing markers match the latlng of the new marker
if (allMarkers.length != 0) {
for (i=0; i < allMarkers.length; i++) {
var existingMarker = allMarkers[i];
var pos = existingMarker.getPosition();
if (latlng.equals(pos)) {
text = text + " & " + content[i];
}
}
}
So that the final result when you click on a marker that has the same latlng it would display one info window with the merged text like the one found here http://maps.caseypthomas.org/ex/MarkerClustererPlus/exCoincidentMarkers_SharedInfowindow_wGeocoding.html See it shows the number 4 but displays only 3 markers that's because the one on the right side is merged with another one behind it and when you click on it it shows you the text for both. only I would like to use geocodezip's example and work on top of that since I already have the cords and don't need google to go get them for me.
Thank you for just reading this LONG Question if noting else..
and Thank you 1Mill X over if you can help me find a solution.
Thanks again!!!
You need to :
create the marker clusterer first.
add the markers to the MarkerClusterer (and format your code so it is easier to read...).
function createMarker(latlng,text) {
var marker = new google.maps.Marker({
position: latlng,
map: map
});
///get array of markers currently in cluster
var allMarkers = mc.getMarkers();
//check to see if any of the existing markers match the latlng of the new marker
if (allMarkers.length != 0) {
for (i=0; i < allMarkers.length; i++) {
var existingMarker = allMarkers[i];
var pos = existingMarker.getPosition();
if (latlng.equals(pos)) {
text = text + " & " + content[i];
}
}
}
google.maps.event.addListener(marker, 'click', function() {
infowindow.close();
infowindow.setContent(text);
infowindow.open(map,marker);
});
mc.addMarker(marker);
return marker;
}
working example

Can't prevent all marker overlays from overlapping markers google maps api v3

I have a google map using api version 3. I want to create markers with a custom icon and numbered labels. I've been trying to use what seems to be the most accepted method for this, the "labels.js" solution that I've provided below. However, no matter what I try, all the numbered overlays overlap all of the markers (despite me setting the marker and the label with the same zIndex). See the screenshot provided to see what I'm talking about. If you take a look at markers 14 and 15 in the screen, you'll see that the 15 label overlaps the 14 marker, but it shouldn't, it should be underneath the 14 marker.
http://i.imgur.com/QoYqcHJ.jpg
Many discussions about properly overlapping with custom overlays revolve around the line of code:
var pane = this.getPanes().overlayImage;
However, I have this in place. I'm setting each label overlay and marker pair to the same zIndex, and the properly overlapping markers proves that this zIndex increment is working. I've provided all of my code below, and have run into a brick wall. I've tried everything possible with no luck. Assume all variables have been properly declared.
label.js:
/* START label.js */
// Define the overlay, derived from google.maps.OverlayView
function Label(opt_options) {
// Initialization
this.setValues(opt_options);
// Here go the label styles
var span = this.span_ = document.createElement('span');
span.style.cssText = 'position: relative;' +
'white-space: nowrap;color:#666666;' +
'font-family: Arial; font-weight: bold;' +
'font-size: 11px;';
var div = this.div_ = document.createElement('div');
div.appendChild(span);
div.style.cssText = 'position: absolute; display: none;';
};
Label.prototype = new google.maps.OverlayView;
Label.prototype.onAdd = function () {
var pane = this.getPanes().overlayImage;
pane.appendChild(this.div_);
// Ensures the label is redrawn if the text or position is changed.
var me = this;
this.listeners_ = [
google.maps.event.addListener(this, 'position_changed',
function () { me.draw(); }),
google.maps.event.addListener(this, 'text_changed',
function () { me.draw(); }),
google.maps.event.addListener(this, 'zindex_changed',
function () { me.draw(); })
];
};
// Implement onRemove
Label.prototype.onRemove = function () {
this.div_.parentNode.removeChild(this.div_);
// Label is removed from the map, stop updating its position/text.
for (var i = 0, I = this.listeners_.length; i < I; ++i) {
google.maps.event.removeListener(this.listeners_[i]);
}
};
// Implement draw
Label.prototype.draw = function () {
var projection = this.getProjection();
var div = this.div_;
// Some custom code to properly get the offset for the numbered label for each marker
var labelOffset;
if (parseInt(this.get('text').toString()) < 10) labelOffset = new google.maps.Point(6, -35);
else labelOffset = new google.maps.Point(9, -35);
var point1 = this.map.getProjection().fromLatLngToPoint(
(this.get('position') instanceof google.maps.LatLng) ? this.get('position') : this.map.getCenter()
);
var point2 = new google.maps.Point(
((typeof (labelOffset.x) == 'number' ? labelOffset.x : 0) / Math.pow(2, map.getZoom())) || 0,
((typeof (labelOffset.y) == 'number' ? labelOffset.y : 0) / Math.pow(2, map.getZoom())) || 0
);
var offSetPosition = this.map.getProjection().fromPointToLatLng(new google.maps.Point(
point1.x - point2.x,
point1.y + point2.y
));
var position = projection.fromLatLngToDivPixel(offSetPosition);
// End custom code
div.style.left = position.x + 'px';
div.style.top = position.y + 'px';
div.style.display = 'block';
div.style.zIndex = this.get('zIndex'); //ALLOW LABEL TO OVERLAY MARKER
this.span_.innerHTML = this.get('text').toString();
};
/* END label.js */
Code to create map with markers:
var mapOptions = {
zoom: myZoom,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
streetViewControl: false
};
map = new google.maps.Map(document.getElementById("gmap"), mapOptions);
/* Insert logic here to iterate and add each marker */
// This function is called for every marker, i increases by 1 each call
function addMarker(latlng, mylabel, isShowroom, data, type, i) {
var markerImage;
var labelColor = '#666666';
if (isShowroom) {
markerImage = 'http://www.subzero-wolf.com/common/images/locator/pin-showroom.png';
} else {
if (type == 'service') {
markerImage = '/common/images/locator/pin-dealer.png';
} else if (type == 'parts') {
markerImage = '/common/images/locator/pin-parts.png';
} else {
markerImage = '/common/images/locator/pin-dealer.png';
}
}
var myMarker = new google.maps.Marker({
position: latlng,
draggable: false,
clickable: true,
map: map,
icon: markerImage,
zIndex: isShowroom ? 9999 : i
});
var html = "test content"
myMarker['isShowroom'] = isShowroom;
myMarker['infowindow'] = new google.maps.InfoWindow({
content: html
});
google.maps.event.addListener(myMarker, 'click', function() {
this['infowindow'].open(map, this);
});
// Dont show a label for the showroom because this is the marker with the star icon, no number needed
if (!isShowroom) {
var label = new Label({
map: map
});
label.set('zIndex', i);
label.bindTo('position', myMarker, 'position');
label.set('text', mylabel);
}
markerArray.push(myMarker);
}

How can I check if google map is already loaded

I am working in a project to provide a map to mobile phone. For now I am trying on a iPhone.
It works fine, and when I load my first page I can see a map with my position, and the market is refreshed each 10 sec and move to my next position.
Some time when I change of page and I come back to the first page, the map is not full displayed. If I move the map, it move but some image of the map is still not displayed.
Also I am working with jquery mobe.
I also noticed that each time I return to the first map, the map is reloaded.
Is there a way to load the map once?
So how can i check that my map is already loaded?
Here is my code
$('#home').live('pagebeforeshow', function(e){
// Resize #mapHome (#mapHome = Sreen hight - footer - header)
$('#mapHome').css('height', Resize.content()-2 +'px');
// extract les id des modules existants
navigator.geolocation.getCurrentPosition(function(position){
showMap('mapHome',position.coords.latitude, position.coords.longitude);
//console.log(position.coords.latitude, position.coords.longitude);
},
function(){
//error
},
{
enableHighAccuracy : true,
maximumAge : 30000
//maximumAge:Infinity
});
// Place and move the marker regarding to my position and deplacement
var track_id = "me";
Tracking.watch_id = navigator.geolocation.watchPosition(
// Success
function(position){
console.log('WatchPosition called');
var lat = position.coords.latitude;
var long = position.coords.longitude;
var latLng = new Array();
latLng[0] = lat;
latLng[1] = long;
//Tracking.myCoordinates.push(lat,long);
Tracking.myCoordinates.push(latLng);
addMarker(lat, long);
},
// Error
showError,
{
frequency: 1000
});
})
I just changed that line to
$('#home').live('pageshow', function(e){... code...}
And it semas to be better but I am not sure-
Here is the code of my function showMap()
function showMap(canvas,lat,long){
var latLng = new google.maps.LatLng(lat,long);
// Google Map options var myOptions = {
zoom: 19,
//zoomControl : 1,
center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP////ROADMAP, SATELLITE, HYBRID and TERRAIN };
// Create the Google Map, set options Tracking.mapy = new google.maps.Map(document.getElementById(canvas), myOptions);
}
And here is the code addMarker()
function addMarker(lat, long){
Tracking.mapBounds = new google.maps.LatLngBounds();
// Clean previous markers
for (var i = 0; i < Tracking.markers.length; i++ ) {
Tracking.markers[i].setMap(null);
}
// Add the owner's marker
var latitudeAndLongitude = new google.maps.LatLng(lat, long);
var image = "img/iconGoogleMap/phones.png";
marker = new google.maps.Marker({
title : 'me',
//animation: google.maps.Animation.DROP, //BOUNCE
position: latitudeAndLongitude,
map : Tracking.mapy,
icon : image
});
Tracking.markers.push(marker);
//Tracking.markers.push(marker);
//console.log(localStorage.getItem('mapToDisplay'));
/* ADDING MODULES MAKERS */
// Store the ID of available module.
modulesJSON = Modules.get('bipme');
for (var i = 0; i < modulesJSON['modules'].length; i++) {
console.log('module id = ' +modulesJSON['modules'][i].id);
console.log('Module ' + modulesJSON['modules'][i].id + ' position : ' + ModulesPos.module(modulesJSON['modules'][i].id));
nlatLong = ModulesPos.module(modulesJSON['modules'][i].id).split(",");
var LatitudeAndLongitudeModules = new google.maps.LatLng(nlatLong[0],nlatLong[1]);
var image = "img/iconGoogleMap/" + modulesJSON['modules'][i].profile + "-" + modulesJSON['modules'][i].iconColor + ".png";
marker = new google.maps.Marker({
title : modulesJSON['modules'][i].pseudo,
//animation: google.maps.Animation.DROP, //BOUNCE
position: LatitudeAndLongitudeModules,
map : Tracking.mapy,
icon : image
});
Tracking.mapBounds.extend(LatitudeAndLongitudeModules);
Tracking.markers.push(marker);
};
By the way, is there a way to create a button, from which I can manually refresh the map?

Show multiple location marker on Google map

How can we openInfoWindowHtml on google map while mouse over on PHP MySQL result as follows,
http://www.yelp.com/c/denver/health
This sites shows Information window on google map while mouse over on result title
Tried as following,
//<![CDATA[
var map;
var geocoder;
var markerArray = [];
function loadMap(params) {
if (GBrowserIsCompatible()) {
geocoder = new GClientGeocoder();
map = new GMap2(document.getElementById('map'));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(40, -100), 4);
map.setZoom(8);
searchLocationsNear(params)
}
}
function searchLocationsNear(params) {
var data = JSON.parse(params);
var lenght = data.length;
var bounds = new GLatLngBounds();
for ( var i = 0; i < lenght; i++) {
// check lat and long available with data
if (data[i].enough_for_map) {
var name = data[i].name;
var address = data[i].address;
if (data[i].description)
var description = data[i].description;
var point = new GLatLng(data[i].latitude, data[i].longitude);
var marker = createMarker(point, name, address, description);
map.addOverlay(marker);
markerArray[i + 1] = marker;
var el_index = $('service_name_' + i);
if (el_index) {
el_index.addEvent('mouseover', marker);
// GEvent.addDomListener(el_index, 'mouseover', function() {
// GEvent.trigger(markerArray[i], 'click');
// });
}
bounds.extend(point);
}
}
map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
}
function createMarker(point, name, address, description) {
var marker = new GMarker(point);
var html = '<b>' + name + '</b> <br/><p>' + description + '</p>' + address;
GEvent.addListener(marker, 'click', function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
above map locations pointed from mysql result set.
<h2>
<a id="service_name_1" href="/example/details/bookkeeper/191">Photographer</a>
</h2>
<h2>
<a id="service_name_2" href="/example/details/bookkeeper/192">Teacher</a>
</h2>
<h2>
<a id="service_name_3" href="/example/details/bookkeeper/193">Accountant</a>
</h2>
Excepted result:
While mouseover on each h2 should show corresponding location info on map.
Any suggestion will greatly appreciated
Thanks
How far have you gotten?
In principle you could,
Put a standard 'click'-event listeners on the markers you've placed on the map which displays the custom infoWindow (a few different approaches/examples here: http://code.google.com/intl/sv-SE/apis/maps/documentation/javascript/demogallery.html).
Have another listener for 'mouseover' on the li elements of the sidebar-list, which in turns triggers the click-event. (Here's how to trigger google map events: http://code.google.com/intl/sv-SE/apis/maps/documentation/javascript/reference.html#event)