-1

What I am trying to achieve is have a circle marker where the size changes when you zoom in or out, but I want to set a maximum size they can get (instead of just continuing to get bigger). Is there a way to do this using dash-leaflet? From what I have found on the internet, your two options are to either have the circle marker size be constant or always dynamic. The problem with setting the size as a constant is that once you have zoomed in far enough, the marker blocks other things on the map. But at the same time when I zoom way out I don't want the marker covering everything either. I know there are layers where you can use z-indices, but that is not what I am after. In the case of what I am doing, I would like the marker to get smaller as I zoom in, but only get bigger to a certain size (say 20 miles) zooming out. If anyone knows how to do this, it would be greatly appreciate to show a simple example of a circle marker doing this.

Thanks

Update

For reference, here is a simple example of what I am talking about

import dash_leaflet as dl
from dash import Dash, html

app = Dash()
app.layout = html.Div(
                    children=[
                        dl.Map(center=[39, -98], zoom=4, children=[
                            dl.TileLayer(),
                            dl.Circle(
                                center=[40.7128, -74.0060],
                                radius=9000, color='black', 
                                opacity=1, 
                                fillOpacity=1),
                            dl.CircleMarker(
                                center=[39.9526, -75.1652],
                                color='white', 
                                opacity=1, 
                                fillOpacity=1)],
                            style={'width': '100%', 'height': '100vh'})])
if __name__ == "__main__":
    app.run_server(debug=False)

When you first open the application, you can see this

enter image description here

The circle marker is bigger than the circle, and I want the circle marker to be the size of the circle at its maximum.

When you zoom in, then you see this enter image description here

Now you have the issue where the circle is too big and it should get smaller to be what the circle marker shows. So ideally I want the combination of the two where once you have zoomed far enough out that the circle marker doesn't get any bigger, but when I zoom in it should adjust in size accordingly like the circle marker.

1 Answers1

0

By injecting javascript you can have a function that sets marker size based on zoom. Have used a simple ternary operator. This could be far more sophisticated to calculate radius in pixels based on distance.

import geopandas as gpd
import folium
import numpy as np

geo_df = gpd.read_file(gpd.datasets.get_path("naturalearth_cities"))
geo_df["pop"] = np.random.randint(1, 5, len(geo_df))

m = geo_df.explore(
    column="pop",
    cmap="summer",
    height=300,
    width=500,
)

# inject html into the map html to make circle markers responsive
m.get_root().html.add_child(
    folium.Element(
        """
<script type="text/javascript">
window.onload = function(){
    var updateIconSizes = function(){
        var z = {mapObj}.getZoom();
        {mapObj}.eachLayer(function (layer) {
            if ("setRadius" in layer) {
                layer.setRadius(z<3 ? 2*z : 2+z**2);
            }; 
        });
    }
    updateIconSizes();
    {mapObj}.on("zoomend", updateIconSizes);
}
</script>
""".replace(
            "{mapObj}", m.get_name()
        )
    )
)

m
Rob Raymond
  • 29,118
  • 3
  • 14
  • 30
  • This is the general idea that I am looking for, but do you know how to achieve this in dash-leaflet? One of the things that drives me a little crazy is that even though dash-leaflet and folium both use leaflet, the approach to achieving things can be different enough that I would not even have realized how to do it [https://stackoverflow.com/questions/72998226/floatimage-in-dash-leaflet](example). Would it be that you would have that javascript in the options of the dash-leaflet Circle as an assign? What would that javascript be? – Robert Allan Aug 22 '22 at 14:56
  • the javascript is for leaflet, so as long as you inject it appropriately I would expect it works with dash-leaflet as well. you've not provided a MWE so it's not possible to know what you are trying to achieve – Rob Raymond Aug 22 '22 at 18:10
  • I have gone ahead and added an example to illustrate what I am meaning. I am sorry that I have been nebulous with things. – Robert Allan Aug 22 '22 at 19:21