I have a folium.Map
, and I'd like to add buttons in the exported HTML file, so that when I click on them, it would change the view to the locations selected.
Here is the Python code to generate the HTML map, with two buttons:
import folium
m = folium.Map(location=[48.8566, 2.3522], zoom_start=10)
# Add buttons to jump to Paris and London
buttons_html = """
<div style="position: fixed; top: 10px; left: 50px; z-index: 1000;">
<button onclick="jumpToCity(48.8566, 2.3522, 12)">Paris</button>
<button onclick="jumpToCity(51.5074, -0.1278, 12)">London</button>
</div>
<script>
function jumpToCity(lat, lng, zoom) {
var map = document.querySelector('.leaflet-container')._leaflet_map;
map.setView([lat, lng], zoom);
}
</script>
"""
m.get_root().html.add_child(folium.Element(buttons_html))
m.save('output.html')
After some digging, in the generated HTML file, I found that the object of the map is generated with a name composed of a hash that changes every time I run the code:
var map_931983127ff2ad4bbeb40856ea0710c9 = L.map(
"map_931983127ff2ad4bbeb40856ea0710c9",
{
center: [48.8566, 2.3522],
crs: L.CRS.EPSG3857,
zoom: 10,
zoomControl: true,
preferCanvas: false,
}
);
If I manually change the command map.setView(...)
to map_931983127ff2ad4bbeb40856ea0710c9.setView(...)
in the HTML, the buttons work well.
Is there a way to set this automatically? A solution (but an ugly one) would be to include in the Python a small script after the export that would update the HTML file (using regexp or something like that).
the issue arises because folium generates a random ID for the map variable every time. Instead of manually updating the html, you can dynamically obtain the map object in js instead of hardcoding map_931983127ff2ad4bbeb40856ea0710c9, you can retrieve the map instance dynamically using folium’s _leaflet_map property.
import folium
m = folium.Map(location=[48.8566, 2.3522], zoom_start=10)
# JavaScript code to dynamically get the map object
buttons_html = """
<div style="position: fixed; top: 10px; left: 50px; z-index: 1000;">
<button onclick="jumpToCity(48.8566, 2.3522, 12)">Paris</button>
<button onclick="jumpToCity(51.5074, -0.1278, 12)">London</button>
</div>
<script>
function jumpToCity(lat, lng, zoom) {
var map = Object.values(window).find(obj => obj instanceof L.Map);
if (map) {
map.setView([lat, lng], zoom);
}
}
</script>
"""
m.get_root().html.add_child(folium.Element(buttons_html))
m.save("output.html")