3

I am using Leaflet. I need to make custom, draggable, resizable icons for the map, using custom images that are set inside a sidebar as such:

<div id="mySidebar" class="sidebar">
        <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
        <div class="dropdown">Actions
            <div class="dropdown-content">
                <img src="Symboles\Actions\Actions Défensives\def_lig.png" alt="def lig" title="def lig" class="dragger"><p>Défense en ligne</p></img>
                <img src="Symboles\Actions\Actions Défensives\def_lig_pre.png" alt="def lig pre" title="def lig pre" class="dragger"><p>Défense en ligne prévue</p></img>
                <img src="Symboles\Actions\Actions Défensives\def_prm.png" alt="def prm" title="def prm" class="dragger"><p>Défense périmétrique</p></img>
                <img src="Symboles\Actions\Actions Défensives\def_prm_pre.png" alt="def prm pre" title="def prm pre" class="dragger"><p>Défense périmétrique prévue</p></img>
                <img src="Symboles\Actions\Actions offensives\act_loc_inde.png" alt="act loc inde" title="act loc inde" class="dragger"><p>Action localisée indépendante</p></img>
                <img src="Symboles\Actions\Actions offensives\act_noria.png" alt="act noria" title="act noria" class="dragger"><p>Action en Noria</p></img>
                <img src="Symboles\Actions\Actions offensives\act_smlt_cct.png" alt="act smlt cct" title="act smlt cct" class="dragger"><p>Action simultanée et concertée</p></img>
            </div>
        </div>
</div>

I know I have to use L.icons But I have no idea on how to do it with my sidebar, since it'll have about 100 images.

5
  • Are you sure you want L.Icon? I'm testing around a bit here and L.Icon doesn't change its size when you change the zoom level. From the given image descriptions it rather looks as if you were looking for ImageOverlay. Can you confirm? Sep 17, 2018 at 10:51
  • ImageOverlay ? never heard/seen that one before
    – Nylak
    Sep 17, 2018 at 10:55
  • That's not the question. ;-) What do you want to achieve? A marker that stays the same size no matter the underlying map and its zoom level? Or an image that fits some geographic bounds? :) PS.: Haven't used ImageOverlay either, but it looks promising. Sep 17, 2018 at 10:58
  • I want my image to be integrated to the map, and can be dragged around and resizable (I can already drag and rezise them, but they're not in the map) PS : and yes, ImageOverlay looks promising :)
    – Nylak
    Sep 17, 2018 at 10:59
  • @Stefan_Fairphone you cans use iconSize to change the size of the icon ;)
    – Nylak
    Sep 17, 2018 at 12:09

2 Answers 2

7

Using the HTML Drag and Drop API you can drag an image from the sidebar and drop it onto the map. For this you will have to bind two listener functions to the map container:

mapdiv = document.getElementById("map")

mapdiv.ondragover = function (e) {
  e.preventDefault()
  e.dataTransfer.dropEffect = "move"
}

mapdiv.ondrop = function (e) {
  e.preventDefault()
  imagePath = e.dataTransfer.getData("text/plain")
  coordinates = map.containerPointToLatLng(L.point([e.clientX,e.clientY]))
  L.marker(coordinates,{icon: L.icon({iconUrl: imagePath}),
                        draggable: true})
    .addTo(map)
}

https://jsfiddle.net/430oz1pj/197/

ondragover has to exist, but we just define the default behaviour. ondrop is the important part for your question. Luckily the drop event comes with some coordinates (clientX,clientY) that we can pass on to the Leaflet map to create a marker.

Note that this only works correctly if the whole map is visible in the viewport (browser window).

PS.: Markers don't change their size when you zoom the map. That's why I suggested an imageOverlay in the comments. Unfortunately these aren't draggable by default, but you can workaround it by binding them to draggable polygons as described in this gis.se answer.

6
  • If you like, besides marking it as a solution you can upvote it. This is better than posting thanks as a comment. :) Sep 17, 2018 at 13:34
  • I don't have enough rep to upvote :(
    – Nylak
    Sep 17, 2018 at 13:40
  • Oh, I forgot about this limitation. Then it's fine. Glad I could help. :) Sep 17, 2018 at 13:57
  • That's totally fine :) Now, time to make these icons resizable and spinnable, since the script I had don't work for them...
    – Nylak
    Sep 17, 2018 at 13:58
  • @Stefan I know this is an old question but I notice the first time I drop the image it shifts (down and left). Can that be avoided? Thanks, Mike Oct 7, 2020 at 11:51
1

For those who're straggling with the incorrect location of the marker after drag and drop an img on the map(addition to the previous comment):

const val = target.getBoundingClientRect(); 

const { x, y } = val;

[e.clientX-x, e.clientY-y]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.