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.
Related
I'm working with leaflet js and I have an array in which i store my markers which are automatically added to the map after the location of the user has been obtained.
problem is that i want to add an onclick listener so that any marker that is clicked will run a function.
please help me out cuz i'm stuck right now.
//objects for markers
var allMarkers=[];
var AllMarkers = L.layerGroup(allMarkers);
var Allpoints=[{
"latitudes":9.4258946,"longitudes":-0.8842213, "names":"first", "eastings":556568, "northings":446445, "description": "aijaskj jnrkajra skjanjanek ", "elevations": 5668
},
{
"latitudes":9.4254946,"longitudes":-0.8812213, "names":"second"},
{
"latitudes":9.4054946,"longitudes":-0.8802213, "names":"third"},
{
"latitudes":9.4754946,"longitudes":-0.8712213, "names":"fourth"},
];
//automatically plot all previous markers
var point = L.point(9.2754946, -0.8912213);
q = 0;
while(q< Allpoints.length){
//create Marker here
_newMarker = L.marker(
[Allpoints[q].latitudes, Allpoints[q].longitudes],
{title: Allpoints[q].names,
riseOnHover: true,
} ).addTo(mymap);
allMarkers.push(_newMarker);
q++
}
//function to send back the details of the clicked marker to a paragraph in my index.htm
//PROBLEM
L.marker('click', markers, showMarkerDetails) //however the code immediately above does not work
function showMarkerDetails(){
$("#returnControlName").html(controlName);
$("#returnControlLocation").html(`${controlLat.toFixed(4)} , ${controlLong.toFixed(4)} `);
$("#returnControlEastings").html(controlEastings);
$("#returnControlName").html(controlNorthings);
$("#returnControlName").html(controlElevation);
$("#returnControlName").html(controlDescription);
}
With L.marker() you add new markers / points to the map, you can't add events like that to them. (L.marker('click', markers, showMarkerDetails) )
Change your code to:
//automatically plot all previous markers
var point = L.point(9.2754946, -0.8912213);
q = 0;
while(q< Allpoints.length){
//create Marker here
_newMarker = L.marker([Allpoints[q].latitudes, Allpoints[q].longitudes],
{title: Allpoints[q].names,
riseOnHover: true,
}).addTo(mymap);
_newMarker.informations = Allpoints[q]; // save the data to the marker to read it later out
_newMarker.on('click',showMarkerDetails); // add click event to the markers
allMarkers.push(_newMarker);
q++
}
function showMarkerDetails(e){
var layer = e.target // get the clicked marker
var infos = layer.informations;
console.log(infos.description);
$("#returnControlName").html(controlName);
$("#returnControlLocation").html(`${controlLat.toFixed(4)} , ${controlLong.toFixed(4)} `);
$("#returnControlEastings").html(controlEastings);
$("#returnControlName").html(controlNorthings);
$("#returnControlName").html(controlElevation);
$("#returnControlName").html(controlDescription);
}
After hours of searching I have finally got markers on my map from MySQL. the last part im struggling with is how to move the makers once the data is changed in MySQL.
currently I have.
function loadMarkers() {
$.get('ajax-get-markers.php', function (data, textStatus, jqXHR) {
var data = JSON.parse(data);
console.log(data)
Array.prototype.forEach.call(data, function(d){
console.log(d.lng, d.lat);
// make a marker for each feature and add to the map
var marker = new mapboxgl.Marker()
.setLngLat({lng: d.lng ,lat: d.lat})
.setPopup(new mapboxgl.Popup()
.setHTML("<h3>" + d.name+ "</h3>"))
.addTo(map);
});
console.log(currentMarkers)
})
}
setInterval(loadMarkers, 5000)
</script>
I have realized this just drops a marker on top of itself each call.
one option I have is to remove all the markers and re-add them but is there another way?
You would have to keep track of the markers that exist. For example you could create an array that holds the marker objects.
marker[i] = new mapboxgl.Marker()
.setLngLat({lng: d.lng ,lat: d.lat})
.setPopup(new mapboxgl.Popup()
.setHTML("<h3>" + d.name+ "</h3>"))
.addTo(map);
You can also change the markers location after they were added to the map by using
marker[i].setLngLat({lng: d.lng ,lat: d.lat})
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've got the following Google map on my website..
function initialize() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(53.347247,-6.259031), 13);
map.setUIToDefault();
GEvent.addListener(map, "click", function(overlay, latLng)
{
// display the lat/lng in your form's lat/lng fields
document.getElementById("lat").value = latLng.lat();
document.getElementById("lng").value = latLng.lng();
});
}
}
What would I need to add / edit so that whenever a user clicked a location on the map a pin / balloon / any kind of indicator would be dropped at the location they clicked?
Thanks.
All you have to do is add this to your existing addListener call:
if (latLng) {
marker = new GMarker(latLng, {draggable:true});
map.addOverlay(marker);
}
See this article linked by Google in their API information for an even more advanced example that lets your users edit the map data.
Update: Changed case of 'l' to 'L' in latLng.
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