Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Leaflet geosearch - binding results marker to an existing one

I have a Leaflet map with a marker and a form with text fields showing its coordinates. The marker can be moved or dragged updating the corresponding form fields.

With Leaflet.GeoSearch, when a search is made (clicking an auto complete option), a new instance of a marker is created, what i want to do is to update the existing marker's location and the corresponding lat/long fields (instead of creating a new marker). According to this post a custom marker can be specified via marker: myCustomMarker option, however it doesn't appear to work in my code.

Thanks in advance

Here is the code:

var tileLayer = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> Contributors'
});
var latlng = L.latLng(50.5, 30.5);

var map = new L.Map('map', {
'center': latlng,
'zoom': 12,
'layers': [tileLayer]
});

var marker = L.marker(latlng,{
    draggable: true,
    autoPan: true
}).addTo(map);

marker.on('dragend', function (e) {
updateLatLng(marker.getLatLng().lat, marker.getLatLng().lng);
});

map.on('click', function (e) {
marker.setLatLng(e.latlng);
updateLatLng(marker.getLatLng().lat, marker.getLatLng().lng);
});

function updateLatLng(lat,lng) {
document.getElementById('latitude').value = marker.getLatLng().lat;
document.getElementById('longitude').value = marker.getLatLng().lng;
}
const searchControl  = new GeoSearch.GeoSearchControl({
  style: 'bar',
  provider: new GeoSearch.OpenStreetMapProvider ({
  showMarker: true,
  marker: marker, // use custom marker, not working?
}),

});
map.addControl(searchControl);

JSFiddle:

https://jsfiddle.net/rtjLm6uq/

like image 823
Esquirish Avatar asked Jan 25 '26 07:01

Esquirish


1 Answers

I took a quick peek into their source code and that property is only used to extract its values, it won't actually use the instance passed in, so that will never be used as you expect.

You have another problem with your code. It is:

const searchControl  = new GeoSearch.GeoSearchControl ({
  style: 'bar',
  provider: new GeoSearch.OpenStreetMapProvider({
  showMarker: true,
  marker: marker, // use custom marker, not working?
}),
});

But it should be:

const searchControl  = new GeoSearch.GeoSearchControl({
  style: 'bar',
  provider: new GeoSearch.OpenStreetMapProvider(),
  showMarker: true,
  marker: marker, // use custom marker, not working?
});

Lastly, in order to fix your problem, what you could instead is listen for the GeoSearch events, more precisely, the showlocation event which is fired when location is chosen from the result list, to clean the previous marker, since that package will always add their own marker (if enabled).

This being said, adding the following code to your file, should fix the issue.

map.on('geosearch/showlocation', () => {
  if (marker) {
    map.removeControl(marker);
  }
});

Update acording to your comment

If you want to preserve the initial marker properties when using the GeoSearch lib, you will have to apply it yourself. Here is an example:

map.on('geosearch/showlocation', () => {
  if (marker) {
    map.removeControl(marker);
  }
  // The marker class extends the layer class,
  // so you can search for it among the layers
  map.eachLayer(item => {
    if (item instanceof L.Marker) {
      // Once you found it, set the properties
      item.options.draggable = true;
      item.options.autoPan = true;
      // Then enable the dragging. Without this, it wont work
      item.dragging.enable();
    }
  });
});

Demo

like image 171
David Fontes Avatar answered Jan 27 '26 22:01

David Fontes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!