Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating an SVG divicon variable and using it in a marker works. Adding a second, marker that uses that variable causes neither to appear as expected #1885

Open
rl-utility-man opened this issue Feb 24, 2024 · 3 comments
Labels
bug An issue describing unexpected or malicious behaviour

Comments

@rl-utility-man
Copy link

rl-utility-man commented Feb 24, 2024

Describe the bug

If I pass the same object reference to Marker twice, it fails cryptically, but if I pass two distinct but identical objects to Marker, it succeeds

If I create one marker containing a variable that contains a DivIcon with an svg image tag, it works. If I add a second marker containing a different svg image tag -- even if the code underlying the divicon is identical, it will also work (see the left panel). But if I create a second marker containing the same svg icon variable, both of the icons fail (see the right panel).

folium

For now, a viable workaround seems to be to avoid creating an icon variable and instead to just use:

folium.Marker(
...    icon=folium.DivIcon(
    icon_anchor=(15, 15),
    html=f"""<div><img src="book-open-variant-outline.svg" height="35" width="35"/></div>""")
).add_to(map_lc)

I suspect based on some struggles I've had in the last few days, but have not confirmed, that this affects font-awesome DivIcons as well.

To Reproduce

import folium
import copy
# Library of Congress coordinates (latitude, longitude)
loc_coordinates = (38.8886, -77.0047)

# Create a Folium map centered around the Library of Congress
map_lc = folium.Map(location=loc_coordinates, zoom_start=15)

# Define the DivIcon with the custom icon.  This variable can be used in one marker successfully, but will fail if we use it in two markers.


icon=folium.DivIcon(
    icon_anchor=(15, 15),
    html=f"""<div><img src="book-open-variant-outline.svg" height="35" width="35"/></div>""")


folium.Marker(
    location=(38.886970844230866, -77.00471380332),
    popup='Library of Congress:  James Madison Building',
    icon=icon
).add_to(map_lc)
#if we save here, everything will be fine.


map_lc_this_will_fail = copy.deepcopy(map_lc)

#creating a second divicon variable which we will use successfully just once.
icon2=folium.DivIcon(
    icon_anchor=(15, 15),
    html=f"""<div><img src="book-open-variant-outline.svg" height="35" width="35"/></div>""")


# Place the DivIcon on the map at a second Library of Congress building
folium.Marker(
    location=loc_coordinates,
    popup='Library of Congress',
    icon=icon2

).add_to(map_lc)

map_lc.save("map_lc_two_markers_working.html")

# Now we go back to the original map with one marker and one icon variable, and add a second marker reusing the icon variable.  this will fail.

folium.Marker(
    location=loc_coordinates,
    popup='Library of Congress',
    icon=icon
).add_to(map_lc_this_will_fail)

map_lc_this_will_fail.save("map_lc_two_markers_failing.html")

I think the problem is in the following section of output:
Here is the last section of output for the working version:

      
    
            var div_icon_4498347d8908f5fb01eb5edf2d8f8686 = L.divIcon({"className": "empty", "html": "\u003cdiv\u003e\u003cimg src=\"book-open-variant-outline.svg\" height=\"35\" width=\"35\"/\u003e\u003c/div\u003e", "iconAnchor": [15, 15]});
            marker_d22f07e6b7d4128cdb776c42c0bf7338.setIcon(div_icon_4498347d8908f5fb01eb5edf2d8f8686);
        
    
        var popup_4da04ad31f973bf8571e17602171f9e2 = L.popup({"maxWidth": "100%"});

        
            
                var html_109688bee6a903cb0c7b60eab2c8df3b = $(`<div id="html_109688bee6a903cb0c7b60eab2c8df3b" style="width: 100.0%; height: 100.0%;">Library of Congress</div>`)[0];
                popup_4da04ad31f973bf8571e17602171f9e2.setContent(html_109688bee6a903cb0c7b60eab2c8df3b);
            
        

        marker_d22f07e6b7d4128cdb776c42c0bf7338.bindPopup(popup_4da04ad31f973bf8571e17602171f9e2)
        ;

        
    
</script>
</html>

Here is the last section of output for the failing version:

   
            var marker_d68a61b4cefaeb27aa01a913ae70110f = L.marker(
                [38.8886, -77.0047],
                {}
            ).addTo(map_1fa405e7ecfa1525f7efcde55531458f);
        
    
        var popup_6e53ecd0bf0bfcc83ca8d766f47677ac = L.popup({"maxWidth": "100%"});

        
            
                var html_daad95df46a6fd6a8e27a761c60854c9 = $(`<div id="html_daad95df46a6fd6a8e27a761c60854c9" style="width: 100.0%; height: 100.0%;">Library of Congress</div>`)[0];
                popup_6e53ecd0bf0bfcc83ca8d766f47677ac.setContent(html_daad95df46a6fd6a8e27a761c60854c9);
            
        

        marker_d68a61b4cefaeb27aa01a913ae70110f.bindPopup(popup_6e53ecd0bf0bfcc83ca8d766f47677ac)
        ;

        
    
</script>
</html>

Expected behavior

Using one variable pointing at an svg icon variable in multiple maps should work. In other words, both maps should work.

The behavior should be the same and correct regardless of whether you specify

folium.Marker(
...    icon=folium.DivIcon(
    icon_anchor=(15, 15),
    html=f"""<div><img src="book-open-variant-outline.svg" height="35" width="35"/></div>""")
).add_to(map_lc)

or

icon=folium.DivIcon(
    icon_anchor=(15, 15),
    html=f"""<div><img src="book-open-variant-outline.svg" height="35" width="35"/></div>""")

folium.Marker(
...    icon=icon
).add_to(map_lc)

Right now, specifying folium.Marker(...icon=icon...) repeatedly will fail, but repeating folium.Marker(...icon=folium.DivIcon(... works.

Environment (please complete the following information):

  • Browser: Edge
  • Jupyter Notebook or html files? I built it in Jupyter.
  • Python version: 3.12.1
  • folium version: 0.15.1
  • branca version: 0.7.1

Additional context
Add any other context about the problem here.

Possible solutions
List any solutions you may have come up with.

folium is maintained by volunteers. Can you help making a fix for this issue?

Yes, I can try to help. Are these the relevant sections of code?

if icon is not None:

https://github.com/python-visualization/branca/blob/f3d866f598a194f9acd30e24e1affe52a32a9f05/branca/element.py#L129

The SVG icon I saved locally and used is: book-open-variant-outline

@rl-utility-man rl-utility-man changed the title One SVG icon in a divicon marker works. Adding a second, identical marker causes neither to appear as expected Creating an SVG divicon variable and using it in a marker works. Adding a second, marker that uses that variable causes neither to appear as expected Feb 25, 2024
@hansthen
Copy link
Collaborator

hansthen commented Apr 7, 2024

@rl-utility-man I managed to reproduce the error. The issue seems to be that there is a parent-child relationship between the Marker and the Icon. Since each child can have only one parent (in this context at least) the code breaks. Are you still willing to help fix this?

A possible solution would be to add a clone() method to Icon and make a clone inside Marker. __init__.

@hansthen hansthen added the bug An issue describing unexpected or malicious behaviour label Apr 7, 2024
@rl-utility-man
Copy link
Author

rl-utility-man commented Apr 8, 2024

Thanks @hansthen! Yes, I can take a look at a fix along the lines you recommend and either issue a pull request or circle back with questions. Give me a week or two.

@Conengmo
Copy link
Member

Conengmo commented May 6, 2024

Duplicate of #744 it seems. I'll leave this one open since we have more recent discussion here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An issue describing unexpected or malicious behaviour
Projects
None yet
Development

No branches or pull requests

3 participants