Reputation: 179
I have been using dash-leaflet for 1 month and it is a good library for showing interactive map with filter widget in dash. But I have question, how do I add popup in polygon? especially in dl.GeoJSON one?
Here is my code
import dash
from dash import Dash, html, dcc
from dash.dependencies import Input, Output
import dash_mantine_components as dmc
import dash_leaflet as dl
from dash_extensions.javascript import arrow_function
import geopandas as gpd
import json
from statistics import mean
all_blocks = gpd.read_file('GeoJSON Files/blocks.geojson')
# -------------------------------------Dash Apps----------------------------------------
app = Dash(__name__, meta_tags=[
{"name": "viewport", "content": "width=device-width, initial-scale=1"}
])
app.layout = html.Section([
html.Div(children=[
html.H5('Block Name'),
dmc.MultiSelect(
placeholder="Select Block Name",
id="multiselect-block",
value=all_blocks['Block_Name'].unique().tolist(),
data=all_blocks['Block_Name'].unique().tolist(),
style={'marginTop':10},
clearable=True,
searchable=True,
nothingFound= 'No Options Found'
)
]),
html.Div(id='output-map')
])
@app.callback(
Output('output-map','children'),
Input('multiselect-block','value'),
Input('multiselect-block','data')
)
def plot_map(block_submitted_value, block_submitted_data):
edited_layer= all_blocks[(all_blocks['Block_Name'].isin(block_submitted_value)) & (all_blocks['Block_Name'].isin(block_submitted_data))]
#defining dl.GeoJSON for filtered edited_layer
layer_blocks = dl.GeoJSON(id='block_load',
data=json.loads(edited_layer.to_json()),
hoverStyle=arrow_function(dict(weight=6, fillColor='#45b6fe', fillOpacity=0.5)),
options=dict(style={'color':'#3a9bdc',
'weight':2,
'dashArray':'30, 10',
'dashOffset':'1',
'opacity':1,
}))
bounds = edited_layer.total_bounds
x = mean([bounds[0], bounds[2]])
y = mean([bounds[1], bounds[3]])
location = (y, x)
if edited_layer.empty:
return dl.Map(children=[dl.TileLayer(url='https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'),
dl.GestureHandling(),
dl.MeasureControl(position="topleft", primaryLengthUnit="kilometers", primaryAreaUnit="hectares",
activeColor="#C29200", completedColor="#972158")],
center=[5.3, 96.3],
zoom=11,
style={
'z-index':'0',
'width': '1750px',
'height': '965px',
'marginLeft':'20px',
})
return dl.Map(children=[dl.GeoJSON(layer_blocks),
dl.TileLayer('url=https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'),
dl.GestureHandling(),
dl.MeasureControl(position="topleft", primaryLengthUnit="kilometers", primaryAreaUnit="hectares",
activeColor="#C29200", completedColor="#972158")],
center=[y, x],
zoom=11,
style={
'z-index':'0',
'width': '99%',
'height': '965px',
'marginLeft':'20px',
'float':'right'
})
if __name__ == '__main__':
app.run_server(debug=True, port = 8400)
Here is my dummy data, it is in GeoJSON format
{"type":"FeatureCollection","features":[{"type":"Feature","properties":{"Block_Name":"East-Block","Status":"Production","Operator":"A","num_wells":20,"sq_km":145.97,"est_reserve":100},"geometry":{"coordinates":[[[96.4001057373053,5.208656351062942],[96.43375136718726,5.221648609300516],[96.46259047851515,5.23737571951817],[96.46121718750072,5.279084831409563],[96.35684707031174,5.279768564031215],[96.35753371582075,5.340617736210092],[96.26140334472717,5.341985064196123],[96.26140334472717,5.261307518914151],[96.32663466796942,5.23053789406255],[96.4001057373053,5.208656351062942]]],"type":"Polygon"}},{"type":"Feature","properties":{"Block_Name":"West-Block","Status":"Production","Operator":"B","num_wells":50,"sq_km":171.38,"est_reserve":420},"geometry":{"coordinates":[[[96.1500638674625,5.274467547614364],[96.14897384519247,5.419171436272961],[96.01490110586337,5.42134172287426],[96.01526444661994,5.383360416138984],[96.07521567152321,5.3826369393847955],[96.07557901227983,5.355867695999478],[96.03488484749829,5.355867696870973],[96.03452150673985,5.334162042989206],[96.0501451592911,5.327288425995064],[96.06431544881394,5.305219978512483],[96.07812239757834,5.292557397961701],[96.10500961359554,5.285683317057433],[96.13117014809939,5.279894558164472],[96.14025366702509,5.278809159853225],[96.1500638674625,5.274467547614364]]],"type":"Polygon"}},{"type":"Feature","properties":{"Block_Name":"South-Block","Status":"Exploration","Operator":"A","num_wells":0,"sq_km":48.74,"est_reserve":150},"geometry":{"coordinates":[[[96.15020619743746,5.321413143458614],[96.15075239154925,5.274369183512903],[96.15921840028875,5.269746173698309],[96.19062456174476,5.259684209917438],[96.21137993801023,5.259140315346897],[96.23814344951205,5.262403675642247],[96.26108360222605,5.263763404046799],[96.26108360222605,5.320325462349771],[96.15020619743746,5.321413143458614]]],"type":"Polygon"}},{"type":"Feature","properties":{"Block_Name":"Center-Block","Status":"Exploration","Operator":"C","num_wells":0,"sq_km":48.98,"est_reserve":120},"geometry":{"coordinates":[[[96.14996393515247,5.321933704052],[96.26084133994107,5.320846023863609],[96.26138753405411,5.3417835292513445],[96.35451363019473,5.340967795663914],[96.35451363019473,5.36924592531598],[96.29224750139701,5.369789722668301],[96.29197440434115,5.401329137491388],[96.33922019505121,5.401057252985197],[96.33922019505121,5.419001368471612],[96.14887154692752,5.419545121233369],[96.14996393515247,5.321933704052]]],"type":"Polygon"}},{"type":"Feature","properties":{"Block_Name":"North-Block","Status":"Production","Operator":"A","num_wells":30,"sq_km":64.55,"est_reserve":220},"geometry":{"coordinates":[[[96.08469351270912,5.419774728990944],[96.21141054675434,5.419774728990944],[96.33102705734086,5.41868722339008],[96.33048086322776,5.43826202425123],[96.24745935816333,5.438805759641596],[96.24745935816333,5.451311537935112],[96.30644832228882,5.451855261522326],[96.30590212817572,5.467079321826603],[96.15952210608873,5.466535612046528],[96.16006830020183,5.439893228949643],[96.08523970682091,5.440980696292215],[96.08469351270912,5.419774728990944]]],"type":"Polygon"}}]}
I want to show the pop up whenever I click the polygon, just like in Folium, and in the form of HTML like this
How do I do that in Dash-Leaflet? Any help would appreciate, thanks!
Upvotes: 1
Views: 489
Reputation: 6024
If you just need to display a simple popup, you can add a feature property named popup
, and it will be rendered as a popup automatically,
from dash import Dash
import dash_leaflet as dl
import dash_leaflet.express as dlx
app = Dash()
app.layout = dl.Map([
dl.TileLayer(),
dl.GeoJSON(data=dlx.dicts_to_geojson([dict(lat=56, lon=10, tooltip="Hello world!")])),
], center=[56,10], zoom=6, style={'height': '50vh'})
if __name__ == '__main__':
app.run_server()
If you need further customization, you can pass a custom JavaScript function via the onEachFeature
property of the GeoJSON
component function, which binds the custom popup,
from dash import Dash
from dash_extensions.javascript import assign
import dash_leaflet as dl
import dash_leaflet.express as dlx
on_each_feature = assign("""function(feature, layer, context){
layer.bindTooltip(`This is <b> html </b>. Foo is [${feature.properties.foo}])`)
}""") # add custom tooltip. Must be done in JavaScript
app = Dash()
app.layout = dl.Map([
dl.TileLayer(),
dl.GeoJSON(data=dlx.dicts_to_geojson([dict(lat=56, lon=10, foo="Hello world!")]),
onEachFeature=on_each_feature),
], center=[56, 10], zoom=6, style={'height': '50vh'})
if __name__ == '__main__':
app.run_server()
Upvotes: 0