python-visualization / folium

Python Data. Leaflet.js Maps.
https://python-visualization.github.io/folium/
MIT License
6.87k stars 2.22k forks source link

How to add a fixed position (in screen) static custom Text (html) like Legend #1718

Open Atreyagaurav opened 1 year ago

Atreyagaurav commented 1 year ago

Is your feature request related to a problem? Please describe. Is there a way to just insert some overlay into the map with custom html code? Like legend but with descriptions or titles and such?

Describe the solution you'd like There are clearly the elements like Layer control, Minimaps and such that are overlaid in the map, so I feel like there should be a way to put some boxes there with some custom contents. The contents can be static (generated from python string)

I'd prefer to do it with just a python string passed to some python function, without the need to write js or css ourselves if possible.

Describe alternatives you've considered

Additional context I went through some issues thinking it should be there but didn't find anywhere.

https://github.com/python-visualization/folium/issues/86 says there used to be a custom map template you could make but it's gone now. https://github.com/transport-nantes/tn_web/issues/135 https://github.com/python-visualization/folium/issues/781

Implementation I'm not good with css or js, but I can do some python dev. If there is a easy way to just copy some parts from the LayerControl or such and add it, then I can help.

Atreyagaurav commented 1 year ago

With examples from other plugins I was able to make something.

from branca.element import MacroElement
from jinja2 import Template

class FloatHTML(MacroElement):
    """Adds a floating image in HTML canvas on top of the map.
    Parameters
    ----------
    html: str
        html string.
    **kwargs
        Additional keyword arguments are applied as CSS properties.
        For example: `width='300px'`.
    """

    _template = Template(
        """
            {% macro header(this,kwargs) %}
                <style>
                    .leaflet-control-floathtml {
                        background-color: rgba(255,255,255,.7);
                        box-shadow: 0 0 5px #bbb;
                        padding: 0 5px;
                        margin: 0;
                        color: #333;
                        font: 11px/1.5 "Helvetica Neue",Arial,Helvetica,sans-serif;
                    }

                    #{{this.get_name()}} {
                        position: absolute;
                        z-index: 99999
                        {%- for property, value in this.css.items() %}
                          {{ property }}: {{ value }};
                        {%- endfor %}
                        }
                </style>
            {% endmacro %}
            {% macro html(this,kwargs) %}
            <div id="{{this.get_name()}}" class="leaflet-control leaflet-control-floathtml">
                 {{ this.html }}
            </div>
            {% endmacro %}
            """
    )

    def __init__(self, html, **kwargs):
        super().__init__()
        self._name = "FloatHTML"
        self.html = html
        self.css = kwargs

And use it like:

FloatHTML(legend_html,
          float="right",
          right="10px",
          bottom="50px",
          width="400px").add_to(map)

Which seems to work well. If there is nothing that's similar in nature then maybe we can add this, and maybe with better css or other stuff than this.

advait-zx commented 11 months ago

i will work on it

Atreyagaurav commented 11 months ago

@advait-zx I already have that working model as shown in the previous comment. I am waiting on any interest from the maintainers before I make a pull reques, so far noone seems interested.