Marker clusterer - javascript

I would like to ask whether is my code's error or wrong arrangement of code.
The sidebar is shown and the infowindow also. But the marker still can't be clustered.(why?)
<!DOCTYPE html >
<html>
<head>
<title>Google Maps</title>
<script type="text/javascript" src="https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/markerclusterer.js"></script>
</head>
<body >
<table border=1>
<tr>
<td>
<div id="map" style="width: 550px; height: 450px"></div>
</td>
<td width = 150 valign="top" style="text-decoration: underline; color: #4444ff;">
<div id="side_bar"></div>
</td>
</tr>
</table>
<script type="text/javascript">
// this variable will collect the html which will eventually be placed in the side_bar
var side_bar_html = "";
// arrays to hold copies of the markers and html used by the side_bar
// because the function closure trick doesnt work there
var gmarkers = [];
// A function to create the marker and set up the event window
function createMarker(point,name,html) {
var marker = new GMarker(point);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
// save the info we need to use later for the side_bar
gmarkers.push(marker);
// add a line to the side_bar html
side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '<\/a><br>';
return marker;
}
// This function picks up the click and opens the corresponding info window
function myclick(i) {
GEvent.trigger(gmarkers[i], "click");
}
// create the map
var map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng( 43.907787,-79.359741), 8);
// add the points
var point = new GLatLng(43.65654,-79.90138);
var marker = createMarker(point,"This place","Some stuff to display in the<br>First Info Window")
map.addOverlay(marker);
var point = new GLatLng(43.91892,-78.89231);
var marker = createMarker(point,"That place","Some stuff to display in the<br>Second Info Window")
map.addOverlay(marker);
var point = new GLatLng(43.82589,-78.89231);
var marker = createMarker(point,"The other place","Some stuff to display in the<br>Third Info Window")
map.addOverlay(marker);
var markers = [];
var markerCluster = new MarkerClusterer(map, markers, {
imagePath: 'https://raw.githubusercontent.com/googlemaps/v3-utility-library/master/markerclustererplus/images/m2.png',
gridSize: 10,
minimumClusterSize: 2
});
var mc = new MarkerClusterer(map, markers);
// put the assembled side_bar_html contents into the side_bar div
document.getElementById("side_bar").innerHTML = side_bar_html;
</script>
</body>
</html>
Hope someone can take a look at this,your help will be appreciated .Thank you.

You have got a few problems there.
1st problem:
You should not be using gMap2 because it has been deprecated since 2013. Google have since rewritten its maps javascript library, making it more lightweight and compatible for mobile devices and it is version 3.
V3 example:
var map = new google.maps.Map(document.getElementById("map"),
{
zoom: 6,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
2nd problem:
Array markers is empty. You are creating the MarkerClusterer object correctly but it has been fed with an empty array. It should be an array of markers that you want the clusterer object to consider for clustering.
var markers = [];
...
var mc = new MarkerClusterer(map, markers);
3rd problem:
You are re-instantiating the variable marker over and over again. Try to give them distinct names like marker1, marker2... This is so that you can reference back the markers later in code.
var marker = createMarker(point,"This place","Some stuff to display in the<br>First Info Window")
var marker = createMarker(point,"That place","Some stuff to display in the<br>Second Info Window")
...
4th problem
This is the MOST important one. You should not EXPOSE your Google map API keys to the public!!! This gives me an opportunity to do malicious things to it and I believe you may have breach the license agreement. Please don't do it again. I'll modify your post to censor that part off.
Here is a clusterer example that I have made in JSFiddle previously.
JSFiddle

Related

Google Maps markerClusterer.MarkerClusterer not working with geoJSON

Any ideas why my markers aren't clustering? I've tried many different ways and nothing will make them cluster. I realize there might be something wrong with the arguments I'm passing the markerClusterer but I can't find a way to make it work with anything. There's also little to no documentation on markerClusterer.MarkerClusterer (which is required when using unpkg).
function initMap() {
//set map options
var myMapOptions = {
center: {lat: 40.7498024, lng: -73.9774375},
zoom: 12,
}
//fill the html div with a map and pass in map options
var myNewMap = new google.maps.Map(document.getElementById('mymap'), myMapOptions);
//pass in data
myNewMap.data.loadGeoJson('missedConnections.geojson');
//define popup windows
var infowindow = new google.maps.InfoWindow({maxWidth: 750, autopanMargin: 10,});
//create new popup windows on marker click
myNewMap.data.addListener('click', function(event) {
console.log(event);
// set variables
let videourl = event.feature.getProperty('videoURL');
//padding/margin is wonky on mobile vs desktop
let html = '<video style="padding-bottom: 5px; padding-right: 3px;" preload="none" autoplay width=" 90%"><source src="' + videourl + '"></video>';
// show the html variable in the infowindow
infowindow.setContent(html);
infowindow.setPosition(event.latLng);
infowindow.setOptions({pixelOffset: new google.maps.Size(0, -30)});
// move the infowindow up 42 pixels to the top of the default marker icon
infowindow.open(myNewMap);
});
new markerClusterer.MarkerClusterer({myNewMap.data, myNewMap});
}
First, you are using object shorthand incorrectly.
Second, that isn't the interface for the library.
const markerCluster = new MarkerClusterer({ map, markers });
where markers is an array of google.maps.Markers. See MarkerClustererOptions.
Into your html:
<script src="https://unpkg.com/#googlemaps/markerclusterer/dist/index.min.js"></script>
Into your js, code both of these works
var mc = new markerClusterer.MarkerClusterer({ markers, map });
or
new markerClusterer.MarkerClusterer({ markers, map });

Google Maps info windows only displays info from the first click

I have a script that:
pulls results from a database in the form of an XML file
parses those results
creates a marker for each result and places it on a map (a single map for all markers)
at the same times, builds a clickable HTML list (sidebar) containing all those results.
When the user clicks on a place name in the sidebar, the info window from the corresponding marker on the map is automatically displayed. Of course the user can also click directly on a marker on the map, and the same info window is also displayed.
This code has been working fine for several years, but last week I noticed that its behavior was now bugged. When viewing some given results, the first click (either on the map or in the sidebar) works fine (the info window opens and displays the correct information), but the following clicks all show the same information from the first click, all in their respective info window. (To be clear: the information shown is the one from the very first click, not from the previous click.)
I've been trying to debug that for hours but I don't understand why it doesn't work anymore. As you can see in my code below, I tried adding a console.log in the google.maps.event.addListener function, to see what data is being worked with when the marker is clicked, but even there, I don't see anything wrong.
Here is my code (simplified to be more readable):
var side_bar_html = '\n';
var gmarkers = []; // array for created markers
var infoWindow;
var center_lat = <?php echo $position_lat; ?>;
var center_lng = <?php echo $position_lng; ?>;
function createMarker(point, name, html, place_id, map) {
var marker, markerOptions;
markerOptions = {
map: map,
position: point,
dataId: place_id,
icon : 'theme/marker.png',
shadow: 'theme/marker_shadow.png'
};
marker = new google.maps.Marker(markerOptions);
infoWindow = new google.maps.InfoWindow({content: html});
google.maps.event.addListener(marker, 'click', function() {
console.log(this, marker, html);
infoWindow.content = html;
infoWindow.open(map, this);
});
gmarkers.push(marker);
side_bar_html += '\n<li>' + name + '</li>';
return marker;
}
function showPlace(i) {
google.maps.event.trigger(gmarkers[i], 'click');
}
function loadEarth(opt, zoom) {
var map, point, mapCenter, mapOptions;
if (zoom === null) {zoom = 7;}
mapCenter = new google.maps.LatLng(center_lat, center_lng);
mapOptions = {
zoom: zoom,
center: mapCenter,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
point = new google.maps.LatLng(parseFloat(center_lat), parseFloat(center_lng));
if (opt != 0) {
map.setMap(new google.maps.Marker(point));
}
}
// receiving results via XML
function go() {
var map, bounds;
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
bounds = new google.maps.LatLngBounds();
$.ajax({
url : 'url/to/data.xml',
type : 'GET',
dataType : 'xml',
success : function(xml) {
var markers, lat, lng, place_id, point, label, html, marker;
markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
// extract data for each marker
lat = parseFloat(markers[i].getAttribute("lat"));
lng = parseFloat(markers[i].getAttribute("lng"));
place_id = parseFloat(markers[i].getAttribute("place_id"));
point = new google.maps.LatLng(lat,lng);
label = $(markers[i]).find('label').eq(0).text();
html = $(markers[i]).find('infowindow').eq(0).text();
// marker creation
marker = createMarker(point, label, html, place_id, map);
// extend visible zone to newly added marker
bounds.extend(point);
}
map.setCenter(new google.maps.LatLng(center_lat, center_lng), 7);
bounds.extend(point);
if (markers.length>0) {
document.getElementById("side_results").innerHTML = side_bar_html;
map.fitBounds(bounds);
map.setCenter(bounds.getCenter());
} else {
loadEarth();
}
} // end AJAX success
}); // end AJAX
} // end go()
if ($('#places_page').is('.empty')) {
loadEarth(0,8);
} else go();
Any help would be greatly appreciated.
Edit:
As requested, here's a sample of the XML received. In this case, the PHP variables at the start of the script would receive the following values:
$position_lat: 46.9479222
$position_lng: 7.4446085
<?xml version="1.0" encoding="UTF-8"?><markers>
<marker place_id="955" lat="46.950218" lng="7.442429">
<label><![CDATA[<em>Place 955</em><strong>3011 Bern</strong>]]></label>
<infowindow>
<![CDATA[<p><em>Place 955</em><br />Speichergasse 35<br />3011 <ins>Bern</ins></p>]]>
</infowindow>
</marker>
<marker place_id="985" lat="46.942032" lng="7.389993">
<label><![CDATA[<em>Place 985</em><strong>3018 Bern</strong>]]></label>
<infowindow>
<![CDATA[<p><em>Place 985</em><br />BrĂ¼nnenstrasse 106A<br />3018 <ins>Bern</ins></p>]]>
</infowindow>
</marker>
</markers>
The Google Maps API is included via this line:
<script src="http://maps.google.com/maps/api/js?v=3&sensor=true&language=fr&key=..."></script>
Edit 2:
Changing the API call to force it to use version 3.18 does fix the problem:
<script src="http://maps.google.com/maps/api/js?v=3.18&sensor=true&language=fr&key=..."></script>
Obviously this is a temporary fix, since v. 3.18 won't always be available. Now I need to understand what change in the 3.19 version made this bug appear. Any suggestion is still appreciated. :)
This undocumented usage:
infoWindow.content = html;
May be the issue. Should be:
infoWindow.setContent(html);
The .content property went away or is no longer supported issue

Getting data stored in additional field of googlemap's marker

I'm working with google maps api and javascript which I am not much familiar with. Here's the code I use to draw markers on my map. I get Latitudes and Longitudes from my database:
var geocoder;
var map;
var jsonStr = '<?php echo json_encode($arajka) ?>';
var LatLong = JSON.parse(jsonStr);
function initialize() {
geocoder = new google.maps.Geocoder();
var mapOptions = {
center: new google.maps.LatLng(50.000001, 20.000001),
zoom: 12
};
map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
var marker = [];
for(var i=0;i<LatLong.length;i++){
var LatLong1 = new google.maps.LatLng(LatLong[i].lat, LatLong[i].lon);
marker.ajdi=LatLong[i].id; // storing additional data (I need to get it when user clicks on certain marker)
marker.push(new google.maps.Marker({position: LatLong1, map: map, title: LatLong[i].login}));
}
// trying to set some listener but it fails.
google.maps.event.addListener(marker, 'click', function() {
map.setZoom(8);
map.setCenter(marker.getPosition());
alert("ASDASDASD" + marker.ajdi);
});
}
So, this listener doesn't work, I don't know why. Well, I expect that it doesn't exactly know what marker is it about. When I tried to do it with a single one, like in tutorial, it worked properly. I don't know what to do when I have this array. Any suggestions please?
You have several mistakes in your code:
As #Hollister mentions, marker is an array, so you need to put the addListener call inside the loop;
You have to store the additional marker data into the marker, not into the marker array;
you have to use this in the listener, not marker.
for(var i=0;i<LatLong.length;i++){
var LatLong1 = new google.maps.LatLng(LatLong[i].lat, LatLong[i].lon);
var this_marker = new google.maps.Marker({position: LatLong1, map: map, title: LatLong[i].login});
this_marker.ajdi=LatLong[i].id; // storing additional data (I need to get it when user clicks on certain marker)
marker.push(this_marker);
// trying to set some listener but it fails.
google.maps.event.addListener(this_marker, 'click', function() {
map.setZoom(8);
map.setCenter(this.getPosition());
alert("ASDASDASD" + this.ajdi);
});
}

Google Maps API V3 requires page reload to show marker icons

I am reading points from a DB as JSON to create map markers and an unstructured list on a page. After adding some code to customize the list elements the map stopped showing the marker icons on first request - until a page reload is issued. Is this due to timing out from the API? Could the list object be built from the array after the map is loaded or is there some other way to speed up the code that might eliminate the problem? The map loaded markers fine with double this number of markers (300+) so I know problem is as a result of adding the formatting to the list object. No clustering required. A demo version of the page is available here
Signed a JS n00b. Thanks.
......
JSON POWERED GOOGLEMAP
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8">
var map;
var infoWindow = new google.maps.InfoWindow();
function initialize() {
var myLatlng = new google.maps.LatLng(49.57154029531499,-125.74951171875);
var myOptions = {
zoom: 8,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.TERRAIN,
streetViewControl: false
}
this.map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
} /* end initialize function */
<!-- load points from database into Locations JSON -->
$(document).ready(function () {
initialize();
$.getJSON("map-service.php?action=listpoints", function(json) {
if (json.Locations.length > 0) {
for (i=0; i<json.Locations.length; i++) {
var location = json.Locations[i];
addMarker(location);
}
}
});
//define grn icon as closed
var greenicon = 'http://maps.google.com/mapfiles/ms/icons/green-dot.png';
function addMarker(location) {
if(location.datesummit == "0000-00-00") {
var markerOptions = {map: map, title: location.name, position: new google.maps.LatLng(location.lat, location.lng),icon: greenicon};
//create marker info window content
var html='<B>'+location.name+'</B><BR> Register a summit here ';
//create list element text and onclick
$("<li class=\"notclimbed\">")
.html(location.name+"</li>")
.click(function(){
infoWindow.close();
infoWindow.setContent(html);
infoWindow.open(map, marker)
})
.appendTo("#list");
}
else{
var markerOptions = {map: map, title: location.name, position: new google.maps.LatLng(location.lat, location.lng)};
//create marker info window content
var html='<B>'+location.name+'</B><BR> Summitted: '+location.datesummit+'<BR> By:'+location.summitlog;
//create list element text and onclick
$("<li class=\"climbed\">")
.html(location.name+"</li>")
.click(function(){
infoWindow.close();
infoWindow.setContent(html);
infoWindow.open(map, marker)
})
.appendTo("#list");
}
var marker = new google.maps.Marker(markerOptions);
// add a listener to open an info window when a user clicks on one of the markers
google.maps.event.addListener(marker, 'click', function() {
infoWindow.close();
infoWindow.setContent(html);
infoWindow.open(map, marker);
});
}; // end of addmarker function
});
</script>
</head>
<body>
<div id="banner" {vertical-align:text-top;} >
<img src="test.jpg" alt="Logo" style="width:150px;height:150px;vertical-align:middle">
<img src="test.png" alt="Logo" style="vertical-align:middle">
</div>
<div id="map_canvas" >
Map Here!
</div>
<div id="mindthegap"></div>
<div id="list" > </div>
</body>
You need to make sure the map variable is initialized before you pass it to markerOptions.
A bit of overzealous debugging showed me that on the times that the page fails, the map is still undefined.
The $(document).ready() will usually occur before body.onload, so either put a call to initialize() at the very top of your $(document).ready(function() { ... }); or put the code for initialize in there.
Also, though not strictly necessary, you should consider encapsulating your map variable instead of using a global. What if you ever want to have 2 maps on one page?

Google Maps Api: How to add a marker and speech bubble?

I have managed to get a google map on my site using Javascript api of google maps.. and it works great...
Can anyone tell me how i can add the Speech bubble and marker ... Pictured here... http://code.google.com/apis/maps/
Basically my site displays a simple map but its missing the marker for where office is and a speech bubble where i want to place the office address
Any help would be really appreciated.
Here is the code i have so far
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(40.466997, -3.705482), 13);
}
A marker can be added using the GMarker class ; for instance, to add a point to a map, I would use something like this :
var point = new GPoint(45.779915302498935, 4.803814888000488);
var marker = new GMarker(point);
map.addOverlay(marker);
(Of course, you'll have to adapt the coordinates to the ones of your office, so it doesn't point to some point in France ^^ ; I suppose the ones you posted should do the trick ;-) )
And for an Information window, you can use the GMarker.openInfoWindowHhtml method, on your marker.
I guess something like this should do the trick :
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(40.466997, -3.705482), 13);
var point = new GPoint(-3.705482, 40.466997);
var marker = new GMarker(point); // Create the marker
map.addOverlay(marker); // And add it to the map
// And open some infowindow, with some HTML text in it
marker.openInfoWindowHtml(
'Hello, <strong>World!</strong>'
);
}
And the result looks like this :
(source: pascal-martin.fr)
Now, up to you to build from here ;-)
Here is some code that shows how to use an XML file to load multiple markers. Also this site is the best there is for Google Maps examples and tutorials
// A function to create the marker and set up the event window
function createMarker(point,name,html) {
var marker = new GMarker(point);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
// save the info we need to use later for the side_bar
//gmarkers.push(marker);
// add a line to the side_bar html
//side_bar_html += '<a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '<\/a><br>';
return marker;
}
// This function picks up the click and opens the corresponding info window
function myclick(i) {
GEvent.trigger(gmarkers[i], "click");
}
$(document).ready(function(){
// When class .map-overlay-right is clicked map is loaded
$(".map-overlay-right").click(function () {
var map = new GMap2(document.getElementById('map-holder'));
$("#map-holder").fadeOut('slow', function(){
var gmarkers = [];
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
// Get XML file that contains multiple markers
$.get("http://www.foo.com/xml-feed-google-maps",{},function(xml) {
$('marker',xml).each(function(i) {
// Parse the XML Markers
html = $(this).text();
lat = $(this).attr("lat");
lng = $(this).attr("lng");
label = $(this).attr("label");
var point = new GLatLng(lat,lng);
var marker = createMarker(point,label,html);
map.addOverlay(marker);
});
});
});
$("#map-holder").fadeIn('slow');
var Asia = new GLatLng(19.394068, 90.000000);
map.setCenter(Asia, 4);
});
});

Categories