I recently shared the showcase Works with IPyLeaflet. Since then I discovered that Panel Ipywidgets does not support adding LayerGroup to Ipyleaflet map · Issue #2710.
So I figured I would test the alternative of combining Leaflet and ReactiveHTML. There is actually already a Leaflet HeatMap Example in the Gallery
The below showcases an interactive Leaflet map with one tile, 3 markers, one layer, a control and click events propagated to the python backend.
import numpy as np
import panel as pn
import holoviews as hv
import xarray as xr
import hvplot.xarray
import param
pn.extension(sizing_mode="stretch_width")
class LeafletMap(pn.reactive.ReactiveHTML):
marker1_clicks = param.Integer()
marker2_clicks = param.Integer()
marker3_clicks = param.Integer()
_template = """<div id="mapid" style="height:100%"></div>"""
__css__ = ["https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"]
__javascript__ = ["https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"]
_scripts = {
'render': """
var mymap = L.map(mapid).setView([50, 0], 6);
state.map=mymap
var tileLayer = L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
accessToken: 'YOUR_MAPBOX_TOKEN_HERE'
}).addTo(mymap)
var marker1 = L.marker([48, -2], name='marker1');
marker1.on('click', (e) => { data.marker1_clicks = data.marker1_clicks + 1 })
var marker2 = L.marker([50, 0], name='marker2');
marker2.on('click', (e) => { data.marker2_clicks = data.marker2_clicks + 1 })
var marker3 = L.marker([52, 2], name='marker3');
marker3.on('click', (e) => { data.marker3_clicks = data.marker3_clicks + 1 })
var layer1 = L.layerGroup([marker1, marker2, marker3]);
layer1.addTo(mymap)
L.control.layers({"tile1": tileLayer},{"layer1": layer1}).addTo(mymap);
""",
# Need to resize leaflet map to size of outer container
'after_layout': """
state.map.invalidateSize();console.log("invalidated");
""",
}
map = LeafletMap(height=400)
ACCENT_BASE_COLOR = "#4099da"
template = pn.template.FastListTemplate(
site="Awesome Panel",
title="Leaflet with ReactiveHTML",
logo="https://panel.holoviz.org/_static/logo_stacked.png",
header_background=ACCENT_BASE_COLOR,
accent_base_color=ACCENT_BASE_COLOR,
sidebar=[pn.Param(map, parameters=["marker1_clicks", "marker2_clicks", "marker3_clicks"])],
main=[map],
).servable()