Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions folium/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ class Icon(MacroElement):
var {{ this.get_name() }} = L.AwesomeMarkers.icon(
{{ this.options|tojavascript }}
);
{{ this._parent.get_name() }}.setIcon({{ this.get_name() }});
{% endmacro %}
"""
)
Expand Down Expand Up @@ -372,6 +371,20 @@ class Marker(MacroElement):
"""
)

class SetIcon(MacroElement):
"""Set the icon of a marker after both are created."""
_template = Template("""
{% macro script(this, kwargs) %}
{{ this.marker.get_name() }}.setIcon({{ this.icon.get_name() }});
{% endmacro %}
""")

def __init__(self, marker: 'Marker', icon: 'Icon'):
super().__init__()
self._name = "SetIcon"
self.marker = marker
self.icon = icon

def __init__(
self,
location: Optional[Sequence[float]] = None,
Expand All @@ -389,7 +402,6 @@ def __init__(
)
if icon is not None:
self.add_child(icon)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did the above code not work?

Copy link
Member Author

@Conengmo Conengmo Jan 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It worked I think, but it's not necessary. Figure.script is an OrderedDict, so we are already guaranteed that multiple renders of the same Icon object will result in only one entry in Figure.script.

  • Multiple markers may now have the same Icon object as child.
  • In the first rendering pass, of MacroElement.render, that one Icon object is rendered multiple times
  • Those multiple renders are added to Figure.script with the Icon object name as key. So each render overwrites the previous one, and the result is the Icon object appears in the final output only once.

self.icon = icon
if popup is not None:
self.add_child(popup if isinstance(popup, Popup) else Popup(str(popup)))
if tooltip is not None:
Expand All @@ -410,6 +422,9 @@ def render(self):
raise ValueError(
f"{self._name} location must be assigned when added directly to map."
)
for child in list(self._children.values()):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks strange to me. A marker can have only one Icon, correct? Why do we need to look through all the children? Would it not be easier to use self.icon?

Copy link
Member Author

@Conengmo Conengmo Jan 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it not be easier to use self.icon?

That would not work for the case where the icon is added using marker.add_child(icon) or icon.add_to(marker).

By looking through the children, we catch the icon whichever way it was added.

if isinstance(child, Icon):
self.add_child(self.SetIcon(marker=self, icon=child))
super().render()


Expand Down