Google Maps Clustering - google-maps

Hi I am making a map view for my classified ads site and I am having trouble adding a clustering function to the map. I was wondering if anybody could help me and offer some advice as to how I can edit my code to make the clustering work for all the ads on my site because as it is right now it displays all my ads accordingly but it just doesn't cluster them when I add cluster code for some reason, I'm a bit of a newb so I'm obviously inputting the code wrong. Any help would be greatly appreciated. Thanks in advance.
Here is my code:
$(document).ready(function() {
var markersInfo = $('.ia-card').map(function() {
var info = {
id: $(this).data('map-id'),
address: $(this).data('map-address'),
title: $(this).data('map-title'),
price: $(this).data('map-price'),
latitude: $(this).data('map-latitude'),
longitude: $(this).data('map-longitude'),
html: "<img src=" + $(this).data('map-image') + ">",
link: $(this).data("map-link"),
contentHtml: "<div class='image'>" + "<img src=" + $(this).data('map-image') + ">" + "</div>" + '<b>' + $(this).data('map-title') + '</b><br>' + $(this).data('map-price') + "<br><a href='" + $(this).data("map-link") + "'>More>></a>"
};
return info;
}).get();
initGoogleMap(markersInfo);
// GMAP ON SEARCH RESULTS PAGE
function initGoogleMap(markersInfo) {
var mapOptions = {
// zoom: 2,
// center: new google.maps.LatLng(53.334430, -7.736673) // center of Ireland
},
bounds = new google.maps.LatLngBounds(),
mapElement = document.getElementById('map-canvas'),
map = new google.maps.Map(mapElement, mapOptions);
var geocoder = new google.maps.Geocoder();
$.each(markersInfo, function(key, val) {
var marker = new google.maps.Marker({
map: map,
position: {lat: parseFloat(val.latitude), lng: parseFloat(val.longitude)},
title: val.title,
info: new google.maps.InfoWindow({
content: val.contentHtml
})
});
google.maps.event.addListener(marker, 'click', function() {
marker.info.open(map, marker);
});
loc = new google.maps.LatLng(val.latitude, val.longitude);
bounds.extend(loc);
});
map.fitBounds(bounds);
map.panToBounds(bounds);
var markerCluster = new MarkerClusterer(map, markersInfo, {
zoomOnClick: true,
gridSize: 40,
maxZoom: 15,
imagePath: 'images/m',
minimumClusterSize: 2
});
};
});

Well the when passing the marker list to the MarkerClusterer you need to pass it as an array of actual google markers.
So you need to store the markers (not their info, but the actual markers) in an array and pass that on.
You also should not set the map property of each marker as that adds it to the map directly, while you want the MarkerClusterer to handle that.
$(document).ready(function() {
var markersInfo = $('.ia-card').map(function() {
var info = {
id: $(this).data('map-id'),
address: $(this).data('map-address'),
title: $(this).data('map-title'),
price: $(this).data('map-price'),
latitude: $(this).data('map-latitude'),
longitude: $(this).data('map-longitude'),
html: "<img src=" + $(this).data('map-image') + ">",
link: $(this).data("map-link"),
contentHtml: "<div class='image'>" + "<img src=" + $(this).data('map-image') + ">" + "</div>" + '<b>' + $(this).data('map-title') + '</b><br>' + $(this).data('map-price') + "<br><a href='" + $(this).data("map-link") + "'>More>></a>"
};
return info;
}).get();
initGoogleMap(markersInfo);
// GMAP ON SEARCH RESULTS PAGE
function initGoogleMap(markersInfo) {
var mapOptions = {
// zoom: 2,
// center: new google.maps.LatLng(53.334430, -7.736673) // center of Ireland
},
bounds = new google.maps.LatLngBounds(),
mapElement = document.getElementById('map-canvas'),
map = new google.maps.Map(mapElement, mapOptions),
markerList = []; // create an array to hold the markers
var geocoder = new google.maps.Geocoder();
$.each(markersInfo, function(key, val) {
var marker = new google.maps.Marker({
/*map: map,*/ // do not set the map on each marker
position: {
lat: parseFloat(val.latitude),
lng: parseFloat(val.longitude)
},
title: val.title,
info: new google.maps.InfoWindow({
content: val.contentHtml
});
});
markerList.push(marker); // add the marker to the list
google.maps.event.addListener(marker, 'click', function() {
marker.info.open(map, marker);
});
loc = new google.maps.LatLng(val.latitude, val.longitude);
bounds.extend(loc);
});
map.fitBounds(bounds);
map.panToBounds(bounds);
var markerCluster = new MarkerClusterer(map, markerList, {
zoomOnClick: true,
gridSize: 40,
maxZoom: 15,
imagePath: 'images/m',
minimumClusterSize: 2
});
};
});

Related

Comparing lat/long values in Google Maps V3

I have a map with a number of markers on it. Because of the way it is set up, one marker will always coincide with the centre of the map. I want to show a different icon on that marker to all the others.
The markers and their corresponding info box are defined with this function:
function createMarker(latlng, html, summary, photo1, photo2, thisLatlng) {
var contentString = "<div style='min-height:150px'>" + photo1 + "<img src='/images/" + photo2 + "' width='225' height='150' align='left' style='margin-right:8px;border:none'></a><span class='title'>" + html +"</span><br>" + summary + "</div>";
var marker = new google.maps.Marker({
map: map,
position: latlng,
icon: thisicon,
zIndex: Math.round(latlng.lat()*-100000)<<5
});
google.maps.event.addListener(marker, 'mouseover', function() {
ib.close(map, marker);
boxText.innerHTML = contentString;
ib.open(map, marker);
});
google.maps.event.addListener(map, 'click', function() {
ib.close(map, marker);
});
gmarkers.push(marker);
}
"latlng" is the a lat/long that is different for each marker. "thisLatlng" is the centre of the map and the lat/long of one specific marker.
My intention was to use something like this to determine the correct icon to use:
if(latlng===thisLatlng){
var thisicon = icon1;
}else{
var thisicon = icon2;
}
However it's not working as the "if" always returns false. I've tried
if(latlng===thisLatlng){
and
if(latlng==thisLatlng){
and I've also tried turning it the other way around with != and !== but they always return false.
I've checked that the two values are equal by printing them one above the other and they look exactly the same (as they should be).
I must be doing something wrong, but what?
The LatLng class has an equals method.
equals
equals(other)
Parameters:
other: LatLng
Return Value: boolean
Comparison function.
The other option is to compute the difference between the two points and set a threshold (say 1 meter) for "equals"
That said, your existing code (with === works for me): fiddle as does .equals (fiddle)
code snippet:
var map;
var gmarkers = [];
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {
lat: 19.12170,
lng: 72.85083
},
zoom: 13.5,
mapTypeId: 'terrain'
});
createMarker(map.getCenter(), "center", "summary", "", "", map.getCenter());
var otherPt = new google.maps.LatLng(19.12, 72.851);
createMarker(otherPt, "not center", "summary2", "", "", map.getCenter());
}
function createMarker(latlng, html, summary, photo1, photo2, thisLatlng) {
var contentString = "<div style='min-height:150px'>" + photo1 + "<img src='/images/" + photo2 + "' width='225' height='150' align='left' style='margin-right:8px;border:none'></a><span class='title'>" + html + "</span><br>" + summary + "</div>";
if (latlng.equals(thisLatlng)) {
var thisicon = "http://maps.google.com/mapfiles/ms/micons/blue.png";
} else {
var thisicon = "http://maps.google.com/mapfiles/ms/micons/green.png";
}
var marker = new google.maps.Marker({
map: map,
position: latlng,
icon: thisicon,
});
}
#map {
height: 100%;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>

How to fetch Data on click of a Marker on google Map

I am dynamically adding Markers to a Google Map on click of a button
The following is the JSON I am sending it from backend .
[
{
"longititude": "78.486671",
"latitude": "17.385044",
"address": "xxxx",
"dealerId": "1"
},
{
"longititude": "78.43471",
"latitude": "17.367044",
"address": "xxxxSS",
"dealerId": "2"
}
]
On click of a button i am calling the following code
My question is on click of a button how can i fetch the dealerId ??
I have got a listener below , how can i fetch the dealer ID ??
google.maps.event.addListener(global_markers[i], 'click', function() {
infowindow.setContent(this['infowindow']);
infowindow.open(map, this);
});
function initializeCalllater(lator,lonor,response) {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(lator, lonor);
var myOptions = {
zoom: 10,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
addMarker(response);
}
function addMarker(markers) {
if(markers.length>0)
{
var infowindow = new google.maps.InfoWindow({});
var global_markers = [];
for (var i = 0; i < markers.length; i++) {
// obtain the attribues of each marker
var lat = parseFloat(markers[i].latitude);
var lng = parseFloat(markers[i].longititude);
var trailhead_name = markers[i].address;
var dealerId = markers[i].dealerID;
var myLatlng = new google.maps.LatLng(lat, lng);
var contentString = "<html><body><div><p><h2>" + trailhead_name + "</h2></p></div></body></html>";
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: "Coordinates: " + lat + " , " + lng + " | Trailhead name: " + trailhead_name
});
marker['infowindow'] = contentString;
global_markers[i] = marker;
$(".howmanyfound").text(markers.length + ' Found');
google.maps.event.addListener(global_markers[i], 'click', function() {
infowindow.setContent(this['infowindow']);
infowindow.open(map, this);
});
}
}
}
Could you please let me know how to fetch dealerId on click of a Marker ??
You can add dealerId as a property of the google.maps.Marker object (like you did with the InfoWindow contents):
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: "Coordinates: " + lat + " , " + lng + " | Trailhead name: " + trailhead_name,
dealerId: dealerId
});
Then in the click function, this.dealerId will give you the value for that marker.

Infobubble only displaying content from last marker added via PHP/Mysql with tabs

I've been trying to get Infobubbles to work with 2 tabs on a map populated with markers from a Mysql database with an ajax call.
The problem is that every infobubble is displaying the same content in the tabs, from the last marker added. Here is the entire js script, any help is greatly appreciated.
var script = '<script type="text/javascript" src="http://google-maps-' +
'utility-library-v3.googlecode.com/svn/trunk/infobubble/src/infobubble';
script += '.js"><' + '/script>';
document.write(script);
var customIcons = {
free: {
icon: 'http://labs.google.com/ridefinder/images/mm_20_blue.png',
animation: google.maps.Animation.DROP,
shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
},
paid: {
icon: 'http://labs.google.com/ridefinder/images/mm_20_red.png',
animation: google.maps.Animation.DROP,
shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
}
};
// End Custom Icons
var map, infoBubble;
function initialize() {
var myOptions = {
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById('map'),
myOptions);
// Try HTML5 geolocation
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position)
{
var pos = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
var marker = new google.maps.Marker({
map: map,
position: pos,
icon:'images/markers/you.png',
animation: google.maps.Animation.DROP,
title: 'Your Location.'
});
infoBubble = new InfoBubble({
maxWidth: 300,
borderRadius: 10,
borderWidth: 1,
borderColor: '#2c2c2c',
shadowStyle: 1
});
var infoWindow = new google.maps.InfoWindow;
// Change this depending on the name of your PHP file
downloadUrl("phpsqlajax_genxml.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++)
{
var name = markers[i].getAttribute("name");
var address = markers[i].getAttribute("address");
var citystate = markers[i].getAttribute("citystate");
var phone = markers[i].getAttribute("phone");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("lng")));
var html = "<b>" + name + "</b> <br/>" + address + "<br/>" + citystate + "<br/>" + phone; //html inside InfoWindow
var description = "<b>" + name + "</b> <br/>" + address + "<br/>" + citystate + "<br/>" + phone; //html inside InfoWindow
var icon = customIcons[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
shadow: icon.shadow,
animation: google.maps.Animation.DROP
});
bindInfoWindow(marker, map, infoBubble, html, description);
}
infoBubble.addTab('Tab 1', html);
infoBubble.addTab('Tab 2', description);
});
map.setCenter(pos);
}, function() {
handleNoGeolocation(true);
});
} else {
// Browser doesn't support Geolocation
handleNoGeolocation(false);
}
}
function handleNoGeolocation(errorFlag) {
if (errorFlag) {
var content = 'Error: The Geolocation service failed.';
} else {
var content = 'Error: Your browser doesn\'t support geolocation.';
}
var options = {
map: map,
position: new google.maps.LatLng(60, 105),
content: content
};
var infoBubble = new google.maps.infoBubble(options);
map.setCenter(options.position);
}
// Additional functions related to the DB Listing function
function bindInfoWindow(marker, map, infoBubble, html) {
google.maps.event.addListener(marker, 'click', function() {
//infoBubble.setContent(html);
infoBubble.open(map, marker);
});
}
function downloadUrl(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;
request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}
function doNothing() {}
function addTab() {
var title = document.getElementById('tab-title').value;
var content = document.getElementById('tab-content').value;
if (title != '' && content != '') {
infoBubble.addTab(title, content);
}
}
google.maps.event.addDomListener(window, 'load', initialize);
The code that sets the content depending on the marker is commented out:
//infoBubble.setContent(html);
Therefor the content of the last infowindow created is always displayed.
working example, including the tab content
Q problem in google map information window on marker click when click on next marker it opens the info window with tabs but when again click on next marker then it oepns the info window with tabs but the prevoius tabs did not closed herte is the code
google.maps.event.addListener(marker, 'click', (function(marker, contentString) {
return function() {
infoBubble.addTab('Tab 1', contentString);
infoBubble.addTab('Tab 2', contentString12);
infoBubble.setContent(contentString);
infoBubble.close('Tab 1', contentString);
infoBubble.open(map,marker);

Google Maps API - 2 maps on page - marker click event on both

I have 2 maps on one page. The maps load fine but both the markers on the maps trigger only the last info window to appear. I am continuing to write bla bla because I can't submit the question if I don't :-)
here's the code:
var places = {
place1 : {
long : 0.0,
lat : 0.0,
address : 'Address...'
},
place2 : {
long : 0.0,
lat : 0.0,
address : 'Address...'
}
};
for( var i in places ) {
mapPositions[i] = new google.maps.LatLng( places[i].long, places[i].lat ),
myOptions[i] = {
zoom: 15,
center: mapPositions[i],
disableDefaultUI: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
$maps[i] = new google.maps.Map( document.getElementById( i + "_map_canvas" ), myOptions[i] );
var title = 'Company ' + i;
LatLngs[i] = new google.maps.LatLng( places[i].long, places[i].lat );
markers[i] = new google.maps.Marker({
position: $maps[i].getCenter(),
map: $maps[i],
title: title,
location: places[i]
});
infowindows[i] = new google.maps.InfoWindow({
content: '<div class="infoWindow">' +
markers[i].title + ' - ' + markers[i].location.address + '<br/>' +
'</div>'
});
google.maps.event.addListener( markers[i], 'click', function() {
infowindows[i].open( $maps[i], markers[i] );
});
}
Can anyone see whats going wrong?
Pretty much a closure issue it seems.
How do JavaScript closures work?
In this part:
google.maps.event.addListener( markers[i], 'click', function() {
infowindows[i].open( $maps[i], markers[i] );
});
It will remember the last value of i. Just change it to
var iLocal = i;
google.maps.event.addListener( markers[i], 'click', function() {
infowindows[iLocal].open( $maps[iLocal], markers[iLocal] );
});
This should help solve your closure problem.

Google Maps API v3 Point of Interest with Custom Icons

I have a page pulling in the schools, churches, and parks of my given area but I want to style the 3 POIs with 3 different icons. I searched Google and even all the docs but couldn't find the answer.
var map;
var infowindow;
function initialize() {
// Center of Map
var centerLatlng = new google.maps.LatLng(29.745376, -95.380125);
// Marker Icons Declaration
var icon = new google.maps.MarkerImage("smLinks-twitter.png", null, null, new google.maps.Point(41,47));
// Map Options
var myOptions = {
zoom: 16,
center: centerLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
icons: icon
};
// Draw the map
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// Marker Icons Implementation
markers = new google.maps.Marker({
position: centerLatlng,
map: map,
title: 'Center of Map',
icon: icon
});
// Services: Places
var request = {
location: centerLatlng,
radius: 800,
types: ["school", "church", "park"]
};
infowindow = new google.maps.InfoWindow();
var service = new google.maps.places.PlacesService(map);
service.search(request, callback);
} // function initialize()
function callback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
}
function createMarker(place) {
var placeLoc = place.geometry.location;
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location,
icon: icon
});
google.maps.event.addListener(marker, 'mouseover', function() {
infowindow.setContent(place.name + '<br/>' + place.vicinity + '<br/><img src="' + place.icon + '">');
infowindow.open(map, this);
});
}
Please see my quick and dirty Demo. The idea is to use the place.types array to determine what kind of place you are trying to add to the map. I simplistically assigned a marker to the first item of this array (usually 2 or 3 items long), which may be something like:
["school", "establishment"]
In some cases, "university" comes before "school" so a "university" icon is used. You will want to refine the way you match types to icons, that is, give a priority for school or university? Perhaps iterate through the array looking for the right types. One place (general_contractor) is not in my list of icons, so the default pin marker is placed there. A "default" icon could be used if you checked if iconType in fact has or not the desired type. I'll leave these details to you =)
Here's the source I used for icons: https://sites.google.com/site/gmapsdevelopment/
function createMarker(place) {
var placeLoc = place.geometry.location;
var iconType = {};
iconType['school'] = "http://maps.google.com/mapfiles/kml/pal2/icon2.png";
iconType['church'] = "http://maps.google.com/mapfiles/kml/pal2/icon11.png";
iconType['park'] = "http://maps.google.com/mapfiles/kml/pal2/icon12.png";
iconType['university'] = "http://maps.google.com/mapfiles/kml/pal2/icon14.png";
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location,
icon: iconType[place.types[0]]
});
google.maps.event.addListener(marker, 'mouseover', function() {
infowindow.setContent(place.name + '<br/>' + place.vicinity + '<br/><img src="' + place.icon + '">');
infowindow.open(map, this);
});
}
Alternatively, use a switch statement:
function createMarker(place) {
var placeLoc = place.geometry.location;
var iconUrl;
switch (place.types[0]) {
case 'school':
iconUrl = "http://maps.google.com/mapfiles/kml/pal2/icon2.png";
break;
case 'church':
iconUrl = "http://maps.google.com/mapfiles/kml/pal2/icon11.png";
break;
case 'park':
iconUrl = "http://maps.google.com/mapfiles/kml/pal2/icon12.png";
break;
case 'university':
iconUrl = "http://maps.google.com/mapfiles/kml/pal2/icon14.png";
break;
default:
iconUrl = "http://maps.google.com/mapfiles/kml/pal4/icon39.png";
}
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location,
icon: iconUrl
});
google.maps.event.addListener(marker, 'mouseover', function() {
infowindow.setContent(place.name + '<br/>' + place.vicinity + '<br/><img src="' + place.icon + '">');
infowindow.open(map, this);
});
}