I have a Google map that is showing a number of markers. When the user moves the map, the markers are redrawn for the new boundaries, using the code below:
GEvent.addListener(map, "moveend", function() {
var newBounds = map.getBounds();
for(var i = 0; i < places_json.places.length ; i++) {
// if marker is within the new bounds then do...
var latlng = new GLatLng(places_json.places[i].lat, places_json.places[i].lon);
var html = "blah";
var marker = createMarker(latlng, html);
map.addOverlay(marker);
}
});
My question is simple. If the user has clicked on a marker so that it is showing an open info window, currently when the boundaries are redrawn the info window is closed, because the marker is added again from scratch. How can I prevent this?
It is not ideal, because often the boundaries are redrawn when the user clicks on a marker and the map moves to display the info window - so the info window appears and then disappears again :)
I guess there are a couple of possible ways:
remember which marker has an open info window, and open it again when the markers are redrawn
don't actually re-add the marker with an open info window, just leave it there
However, both require the marker with an open window to have some kind of ID number, and I don't know that this is actually the case in the Google Maps API. Anyone?
----------UPDATE------------------
I've tried doing it by loading the markers into an initial array, as suggested. This loads OK, but the page crashes after the map is dragged.
<script type="text/javascript" src="{{ MEDIA_URL }}js/markerclusterer.js"></script>
<script type='text/javascript'>
function createMarker(point,html, hideMarker) {
//alert('createMarker');
var icon = new GIcon(G_DEFAULT_ICON);
icon.image = "http://chart.apis.google.com/chart?cht=mm&chs=24x32&chco=FFFFFF,008CFF,000000&ext=.png";
var tmpMarker = new GMarker(point, {icon: icon, hide: hideMarker});
GEvent.addListener(tmpMarker, "click", function() {
tmpMarker.openInfoWindowHtml(html);
});
return tmpMarker;
}
var map = new GMap2(document.getElementById("map_canvas"));
map.addControl(new GSmallMapControl());
var mapLatLng = new GLatLng({{ place.lat }}, {{ place.lon }});
map.setCenter(mapLatLng, 12);
map.addOverlay(new GMarker(mapLatLng));
// load initial markers from json array
var markers = [];
var initialBounds = map.getBounds();
for(var i = 0; i < places_json.places.length ; i++) {
var latlng = new GLatLng(places_json.places[i].lat, places_json.places[i].lon);
var html = "<strong><a href='/place/" + places_json.places[i].placesidx + "/" + places_json.places[i].area + "'>" + places_json.places[i].area + "</a></strong><br/>" + places_json.places[i].county;
var hideMarker = true;
if((initialBounds.getSouthWest().lat() < places_json.places[i].lat) && (places_json.places[i].lat < initialBounds.getNorthEast().lat()) && (initialBounds.getSouthWest().lng() < places_json.places[i].lon) && (places_json.places[i].lon < initialBounds.getNorthEast().lng()) && (places_json.places[i].placesidx != {{ place.placesidx }})) {
hideMarker = false;
}
var marker = createMarker(latlng, html, hideMarker);
markers.push(marker);
}
var markerCluster = new MarkerClusterer(map, markers, {maxZoom: 11});
</script>
You should probably create all your markers at an initial stage with your createMarker() method, and store the returned GMarker objects inside an array. Make sure to set the hide: true property in GMarkerOptions when you create your markers, so that they would be created as hidden by default.
Then instead of iterating through places_json.places, you could iterate through your new GMarker array. You would be able to get the coordinates of each marker with the GMarker.getLatLng() method, with which to check if each marker lies within the bounds.
Finally simply call GMarker.show() for markers that lie within the bounds, or GMarker.hide() to hide them.
You would eliminate the expensive destruction/creation of markers on each map movement. As a positive-side effect, this will also solve your GInfoWindow problem.
If you're using that many markers, make sure you use GMarkerManager. It's designed for many markers, with only a few visible at once.
http://mapki.com/wiki/Marker_Optimization_Tips
Related
I have a Leaflet OpenStreetMap map where I set a new marker. I want the marker to move, which would mean clearing all previous markers, and adding a new one. Currently new clicks just result in new markers, with more than one staying on the map.
How can I clear all markers upon clicking again?
initmap();
var home = new L.LayerGroup();
map.on('click', function(e) {
// clear all markers here somehow
document.getElementById("latFld").value = e.latlng.lat;
document.getElementById("lngFld").value = e.latlng.lng;
L.marker([e.latlng.lat,e.latlng.lng]).addTo(map);
});
Edit:
My original markers did not belong to a group.
L.marker([43.653409, -79.384112]).bindPopup('Original Home').addTo(map);
Regardless of the LayerGroup into a variable, I was asking if there was a way to clear all markers regardless. It is not a duplicate.
Shoved my markers into a layerGroup so I can use that for clearing:
var mymarkers = L.layerGroup([
L.marker([43.677681,-79.389943]).bindPopup('Some place'),
L.marker([<%= #mylat %>,<%= #mylon %>]).bindPopup('Original Home')
]);
L.control.layers(mymarkers).addTo(mymap);
mymap.on('click', function(e) {
mymarkers.clearLayers();
document.getElementById("latFld").value = e.latlng.lat;
document.getElementById("lngFld").value = e.latlng.lng;
L.marker([e.latlng.lat,e.latlng.lng]).bindPopup('New ome').addTo(mymarkers);
$('#update').html("Values updated");
});
I was expecting an object that automatically held all markers, but it wasn't there. So I had to assign then to one.
I'm new to this google-maps and javascript, I have go through these examples.But I still no idea how to apply it into my codes, It doesn't works.Hope someone can help me.Thank you.
// 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);
// put the assembled side_bar_html contents into the side_bar div
document.getElementById("side_bar").innerHTML = side_bar_html;
}
The sidebar is made next to the google-maps.Hope someone can take a look on my code.
The documentation you got there is pretty good actually.
Let me know to simplify it a bit more.
So to get clusterer going you'll need the following bits and pieces.
Your project will have to import the markerclusterer.js file.
You need an array of markers.
You need to instantiate the MarkerClusterer object.
That is all, straight forward.
1: Instantiation of markers
I can see from the code you have already done it.
var marker = new google.maps.Marker(
{
position: myLatLng,
map: map,
title: '1111'
});
2: Building an array of markers
Nothing much here. Basically you declare an [] object and push the markers into it.
var markers = [ marker, marker2, marker3 ];
3: Instantiate the MarkerClusterer object
I guess the only challenging part is this one. As mentioned before, you'll new to import the markerclusterer.js file.
Build an object to hold whatever configuration that is needed for the MarkerClusterer object and instantiate it.
markerCluster = new MarkerClusterer(map, markers, {
imagePath: 'https://googlemaps.github.io/js-marker-clusterer/images/m',
gridSize: 10,
minimumClusterSize: 2
});
Here is an example;
Clusterer
I have a cluster of Google map marker’s. I am showing Google maps in a ModalPopupExtender on a button click. After map is loaded with marker’s I want to pop up info window on mouse over of marker’s. how can I keep the details of info window of each marker when map is loading with marker’s?.
$('#map-canvas').fadeIn('slow', function() {
google.maps.event.trigger(map, 'resize');
for (var i = 0; i < asGridselectedRows.length; i++) {
var row = asGridselectedRows[i];
var Latitude = asGridMasterTable.getCellByColumnUniqueName(row, "Latitude");
var Longitude = asGridMasterTable.getCellByColumnUniqueName(row, "Longitude");
var messno = asGridMasterTable.getCellByColumnUniqueName(row, "MessNo");
var messnumber = messno.innerHTML.substring(6, messno.innerHTML.length - 7);
var Lat = Latitude.innerHTML.substring(6, Latitude.innerHTML.length - 7);
var Long = Longitude.innerHTML.substring(6, Longitude.innerHTML.length - 7);
var myLatLng = new google.maps.LatLng(Lat, Long);
map.setCenter(myLatLng);
map.setZoom(13);
marker = new google.maps.Marker({
map: map
});
if (messnumber == '00')
{
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/blue-dot.png');
}
else
{
marker.setIcon('http://maps.google.com/mapfiles/ms/icons/green-dot.png');
}
marker.setPosition(myLatLng);
marker.setVisible(true);
}
});
You need to build the info window as part of the event listener. See the example given in the answer here: Changing data in the info window with Google Map markers
You can add attributes to each marker so that these can be referenced in the hover event. In your case it looks like you could simply use the messno as an attribute and then reference your data table with the marker info in
LoadPin is a function to add a marker to a map. It initializes the layer on the first call. map is an openlayers map object.
But using map.removeLayer("markers") or "Markers", does not remove the markers from the map. I saw a mention of a destroy operation to do this but cant find that.
AND, how do I remove the popups?
var markers = null
function LoadPin(LL, name, description) {
var size = new OpenLayers.Size(36, 47);
var offset = new OpenLayers.Pixel(-(size.w / 2), -size.h);
var icon = new OpenLayers.Icon('http://www.waze.co.il/images/home.png', size, offset);
if (markers == null) {
markers = new OpenLayers.Layer.Markers("Markers");
map.addLayer(markers);
}
var marker = new OpenLayers.Marker(LL, icon)
markers.addMarker(marker);
var bounds = markers.getDataExtent();
map.zoomToExtent(bounds);
map.addPopup(new OpenLayers.Popup.FramedCloud("test", LL, null,
"<div style='font-family:Arial,sans-serif;font-size:0.8em;'>" + name + "<br>" + description + "</div>",
anchor = null, true, null));
}
You can remove individual markers from a marker layer with:
markers.removeMarker(marker);
Removing the entire layer, with markers should be achieved with:
markers.destroy();
You should be able to remove a popup with:
map.removePopup(popup);
where popup is the Popup object created earlier.
I know this post is old but to remove all markers from the marker layer list use:
markerLayer.clearMarkers();
Try the any of below code i hope it will help you.
this.markerSource.removeFeature(this.iconFeature);
or
this.markerSource.removeFeature(iconFeature);
I'm adding markers and sidebar this way:
<script type="text/javascript">
//<![CDATA[
if (GBrowserIsCompatible()) {
// 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 += '<li><a href="javascript:myclick(' + (gmarkers.length-1) + ')">' + name + '<\/a><\/li>';
return marker;
}
// This function picks up the click and opens the corresponding info window
function myclick(i) {
GEvent.trigger(gmarkers[i], "click");
GEvent.trigger(gmarkers2[i], "click");
}
// create the map
var map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng( 52.898962,-8.21228), 7);
// add the points
var point = new GLatLng( 53.357826,-6.28418 );
var marker = createMarker(point,"Ashgrove Interparts Ltd.","<strong>Ashgrove Interparts Ltd.</strong><br>Kill Avenue.<br>Dunlaoire.<br>Co Dublin.<br>Tel; 01-2805063.<br>Contact; Mr Dermot Kelly.<br>Dublin Area")
map.addOverlay(marker);
var point = new GLatLng( 53.285845,-6.158266 );
var marker = createMarker(point,"Abbey Service Station.","<strong>Abbey Service Station.</strong><br>Abbey Road.<br>Monkstown.<br>Co. Dublin.<br>Tel; 01-2809626.<br>Contact; George/Kay.")
map.addOverlay(marker);
var point = new GLatLng( 53.340508,-6.228905 );
var marker = createMarker(point,"A & D Motorfactors.","<strong>A & D Motorfactors.</strong><br>Cromwellsfort Rd,<br>Dublin 12.<br>Tel; 01-460-1808.<br>Contact; Aiden/Ed.")
map.addOverlay(marker);
var point2 = new GLatLng( 53.440508,-6.238905 );
var marker2 = createMarker(point2,"test","<strong>A & D Motorfactors.</strong><br>Cromwellsfort Rd,<br>Dublin 12.<br>Tel; 01-460-1808.<br>Contact; Aiden/Ed.")
map.addOverlay(marker);
// put the assembled side_bar_html contents into the side_bar div
document.getElementById("side_bar").innerHTML = side_bar_html;
}
else {
alert("Sorry, the Google Maps API is not compatible with this browser");
}
//]]>
</script>
Now got question. How to extend it and make possible to add different markers to differend elements?
I am assuming that what you are trying to do is to differentiate your sets of markers, but use your common myclick handler code to show the appropriate info window for the marker.
There are a few ways you could do this. It looks like you were wanting to have a separate arrays of markers for each city because you have referenced a gmarkers2 array in your myclick handler. This is not going to work because you are creating the markers using the same handler function and the index wont work for both arrays.
So you either need a createMarker function that adds the new marker to the appropriate marker array and specifies a click handler that uses that array or you can use the same marker array and just change createMarker to update separate side_bar_html variables to store the reference url.
I have hacked together an example (based on your source) that uses the second approach. Please let me know if this isn't what you are trying to do.
N.B. In my sample, I stuck the "side bar" below the map.