Multiple markers on the exact same position on a Leaflet map - leaflet

We use leafletJS to show maps with round about 100 markers. Some of these markers are located on exact the same position. Marker2 is above Marker1 so Marker1 isn't visible. Is there a way to rotate Markers in a way that you can see there are more then one marker?

may be you should look at https://github.com/Leaflet/Leaflet.markercluster plugin
here demo - http://leaflet.github.io/Leaflet.markercluster/example/marker-clustering-realworld.388.html

The drawback with walla's answer is that Leaflet.markercluster requires clustering, which may not be an option depending on your requirements i.e. you need to always display individual markers.
OverlappingMarkerSpiderfier-Leaflet (a bit of a mouthful) works well in this case and it's fairly well documented. It displays a 'spider' of markers on click only if they overlap i.e. if the zoom level increases so markers don't overlap, then it won't 'spider' on click, which is quite nice. Demo.
It's available as a NPM package but it isn't a proper ES module, so usage is a bit trickier than usual if you're expecting an ES module:
// Need to specifically import the distributed JS file
import 'overlapping-marker-spiderfier-leaflet/dist/oms';
// Note access to constructor via window object
// map refers to your leaflet map object
const oms = new window.OverlappingMarkerSpiderfier(map);
oms.addListener('click', (marker) => {
// Your callback when marker is clicked
});
// Markers need to be added to OMS to spider overlapping markers
markers.forEach((marker) => {
oms.addMarker(marker);
});
// Conversely use oms.removeMarker(marker) if a marker is removed
Alternatively there is a forked version (confusingly) called OverlappingMarkerSpiderfier that is a proper ES module so you can do:
import OverlappingMarkerSpiderfier from 'overlapping-marker-spiderfier'
const oms = new OverlappingMarkerSpiderfier(map);
However as of 24 Jan 2020 there's a fair bit of divergence based on commits between the two so YMMV.
FWIW I'm using the original.

If anyone is looking working sample for Angular below are the steps,
Install it via npm: npm i --save overlapping-marker-spiderfier-leaflet
Then import it into the component where you need it: import 'overlapping-marker-spiderfier-leaflet/dist/oms';
Add this line on top of the file where you import it: const OverlappingMarkerSpiderfier = (<any>window).OverlappingMarkerSpiderfier;
Add the oms markup like that: this.oms = new OverlappingMarkerSpiderfier(this.map, { nearbyDistance: 20, keepSpiderfied: true });
Add the markers to oms at the same place where you add your markers to the map so oms can track them properly this.oms.addMarker(marker);
xlm is already gave a complete answer. Thanks to him for that answer. But this is a slightly changed answer that worked for me in angular.

we had the same problem, follows the jsFiddle with the solution we found http://jsfiddle.net/atma_tecnologia/mgkuq0gf/2/
var marker1 = new google.maps.Marker({
position: myLatLng,
map: map,
icon: {
url: image,
size: new google.maps.Size(134,130), //different sizes
},
zIndex: 2, //different overlays
title: '1º marker',
});

Related

Markers in the same position don't work properly with Vue3 + Leaflet Markercluster

The problem is that the leaflet map inside the vue3 App loads perfectly and looks great. Also, when you click on a location with two icons in the same position, they open perfectly, but when you click on the same place again, the icons disappear and the "spider" remains visible (see picture).
spider remains
The methods in the Vue3 App are:
methods:{
setupMarkers(){
this.markers.clearLayers();
this.cursesData.forEach(cursa =>this.ficaMarkers(cursa));
this.map.addLayer(this.markers);
},
setupLeafletMap(){
this.map=L.map("mapContainer").setView(this.center,6);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",{
attribution:'OpenStreetMap',
}).addTo(this.map);
this.markers= L.markerClusterGroup({
//spiderfyOnMaxZoom: true,
});
},
ficaMarkers(cursa){
this.markers.addLayer(L.marker([cursa.coordenades[0],cursa.coordenades[1]],{title:cursa.nom})
.bindPopup(cursa.distancies)
)
},
},
If someone could help me, I would be very grateful.
Thanks.
It is a similar issue as in Uncaught TypeError: this._map is null (Vue.js 3, Leaflet) :
What seems to be the culprit is the proxying of this.map by Vue, which seems to interfere with Leaflet events (un)binding. It looks like Vue 3 now automatically performs deep proxying, whereas Vue 2 was shallow.
In your case, the same thing happens for this.markers (which is the Leaflet MarkerClusterGroup).
A solution consists in "unwrapping" / un-proxying the map and the mcg whenever you use them, e.g. with Vue3's toRaw:
toRaw(this.map).addLayer(toRaw(this.markers));
Then we retrieve the normal MCG behaviour, i.e. if you click on the cluster while it is already spiderfied, nothing happens (whereas initially the Markers were collapsing, but the spider legs were remaining indefinitely)
Fixed CodeSandbox: https://codesandbox.io/s/markers-hide-spiders-stay-forked-l2ruqh?file=/src/App.vue

Leaflet - Folium : Creating a fantasy map, removing the world map

I'm trying to create an interactive map out of an image using Folium as part of a Django project in which I want to display the generated HTML on a website.
I want to be able to see only the image upon which I place markers etc., not the actual world map that is by default created.
The image is a map of a fantasy world.
I found this tutorial and tried to apply it to Folium and that generally worked. I'm essentially adding an Image Overlay with "my" map to a map-object. However, that does not remove the original real-world map, meaning when I then save this map, it still also displays a world map that I do not care about in the lower left corner attached to my image overlay.
import folium
def create_aldrune_map():
base_map = folium.Map(crs='Simple', zoom_start=4)
aldrune_overlay = folium.raster_layers.ImageOverlay(
image='Path/To/Image',
bounds=[[0, 0], [1000, 1300]],
zindex=1)
aldrune_overlay.add_to(base_map)
base_map.fit_bounds(bounds=[[0, 0], [1000, 1300]])
base_map.save('Path/To/Output')
How do I get rid of the real-world map?
Let me quote from the Folium documentation, emphasis mine:
class folium.folium.Map(location=None, width='100%', height='100%', left='0%', top='0%', position='relative', tiles='OpenStreetMap',
(snip)
, **kwargs)
Parameters
tiles (str, default 'OpenStreetMap') – Map tileset to use. Can choose from a list of built-in tiles, pass a custom URL or pass None to create a map without tiles. For more advanced tile layer options, use the TileLayer class.
Therefore you probably want something like:
base_map = folium.Map(crs='Simple', zoom_start=4, tiles=None)

Markercluster in Mapbox

I am following markercluster examples from Mapbox library, but can't solve my problem. If you guys take a look at my working example here, you will notice this line of code:
L.mapbox.featureLayer(markerLayer).on('ready', function(e) {
What I initally thought was I could put markers inside of markercluster featureLayer, but I guess it was a wrong approach. Any solutions? Thanks.
Example following here
The mapbox example you refer to makes an AJAX call to retrieve the GeoJSON data, hence it needs to attach an on "ready" listener.
In your case your GeoJSON data is defined in your scripts, so the "ready" event will not be triggered (besides, you should use L.mapbox.featureLayer with your GeoJSON object directly, not a Feature Layer).
You can simply use the eachLayer method to iterate through all created markers within the Feature Layer, and add them into your Marker Cluster Group.
var clusterGroup = new L.MarkerClusterGroup();
var markerLayer = L.mapbox.featureLayer(markers).eachLayer(function(layer) {
clusterGroup.addLayer(layer);
});
map.addLayer(clusterGroup);
Updated Plunker: http://plnkr.co/edit/fN6xYcn1Lg532eLe39IS?p=preview

Adding several geoJSON layers in Mapbox

I have two geoJSON files, one is for drawing the lines(states.js), and another one is for adding markers on the map (marker.js).
However, when I add a line of code that is supposed to be adding the marker layer, nothing works.
var markerLayer = L.mapbox.featureLayer(markers).addTo(map);
How should I approach this? I thought featureLayer would work to add multiple layers, but it doesn't seem to be working well. Help is much appreciated.
Working example so far: Plunker
Example I'm following is here.
Couple of things wrong here. You forgot to declare your global L.mapbox.accessToken:
L.mapbox.accessToken = 'pk.eyJ1Ijoia2thZ2lsbCIsImEiOiJjaWdsdmJjeWkwMjMwdWFrcjI4eGZ3MGd2In0.WslWCpxaXxUOgUZP_VT1cg';
You're adding the statesData twice, once in a L.mapbox.featureLayer and once in a L.GeoJSON:
var statesLayer = L.mapbox.featureLayer(statesData).addTo(map);
statesLayer = L.geoJson(statesData, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
Once is more than enough: here's a example on Plunker: http://plnkr.co/edit/kV8h69VJt2jtpqwdCpJo?p=preview

How to avoid overlap of markers

I've a lot markers inside of a cloudemade map. Sometimes there is a number ob markers at the same location. I use the cluster functionallity but how can I avoid that there are more then one marker on the same coordinats? In such a case, I simply want to have the marker beside each other.
var myMarkerLatLng = new CM.LatLng(<?php echo($rowg['lat'].','.$rowg['lon']); ?>);
var myMarker = new CM.Marker(myMarkerLatLng, {
title: "<?php echo($row['name']); ?>",
icon: icon
});
Our old Web Maps API is deprecated. Please use Leaflet instead of it. You can find good code examples here http://leafletjs.com/examples/quick-start.html. Is is free and easy customisable.