Updating a PyDeck map after a click event

Up to this point in my Panel journey, I’ve only instantiated callbacks connecting a state change in one component to the state of another. Now I have the need to update a PyDeck map based on the click state. I’m looking to write a function that changes the DeckGL pane based on computed results that are dependent on the (latitude, longitude) for the click location. After perusing the documentation for a bit, I’m not clear on how to go about this. Could someone point me in the right direction? As always, any suggestions are greatly appreciated!

Chris

@Marc I’m wondering if you could orient me here. Is there a way to detect a click on a DeckGL map, even if the click state does not change, so that an update can be made to the map based on the location of the click?

Please provide a minimum, reproducible starting point. Just a simple script that can run in a post below :+1:

1 Like

Hi @Marc, let me share again here the best example I can offer - which is an example that updates the map based on a change in click state. I could not figure out from the documentation how to detect clicks, even when the click state is unchanged. Based on our previous exchange, it sounds like there might not be a workaround. I’m looking to confirm if that is true. Or if not, how I can solve this problem.

Original GitHub issue is here.

I’ve highlighted the line that needs an alternative in the example code below.

import json
import panel as pn
import pydeck as pdk
import geopandas as gpd

pn.extension()

gdf = gpd.read_file('https://gist.githubusercontent.com/diehl/af891ddfa2ee965a5278cec436a946ca/raw/837b8e1e128e64e5f3bc7afa1b1148eb5a421e3d/allot_union.geojson')
allot_geo_union = gdf.iloc[0]['geometry']

INIT_LAT  = 40.758701
INIT_LONG = -111.876183

INIT_ZOOM = 4
MAX_ZOOM  = 14

INITIAL_VIEW_STATE = pdk.ViewState(
  latitude=INIT_LAT, 
  longitude=INIT_LONG,    
  zoom=INIT_ZOOM,
  min_zoom=3,
  max_zoom=MAX_ZOOM,
  pitch=0,
  bearing=0
)

mp_df = gpd.GeoDataFrame(geometry=list(allot_geo_union.geoms))
mp_geojson = json.loads(mp_df.to_json(drop_id=True))

geojson_layer = pdk.Layer(
    "GeoJsonLayer",
    mp_geojson,
    filled=True,
    get_fill_color=[251, 128, 114],
    get_line_color=[251, 128, 114],
)

view = pdk.View(type="MapView", controller={"doubleClickZoom": False})

vtiles = pdk.Deck(
    initial_view_state=INITIAL_VIEW_STATE,
    views=[view],
    layers=[geojson_layer],
    map_provider='mapbox',
    map_style='mapbox://styles/diehl/cliwf0hy500m401pw9qxbeac3',
)

map = pn.pane.DeckGL(vtiles, sizing_mode='stretch_both')

def callback(event):
    if len(vtiles.layers) == 0:
        vtiles.layers = [geojson_layer]
    else:
        vtiles.layers = []
    map.object = vtiles

# ******
# The core of my question is focused here. What do I replace this line with to trigger 
# the callback when a click occurs, regardless of whether the click state changes or not?
# ******
map.param.watch(callback,['click_state'],onlychanged=False)

pn.Row(map.controls(),map).show()

Hi @Marc, Can you confirm if I’m interpreting the documentation correctly in this regard? It appears to me that at present, it is not possible to trigger a callback with a map click; instead, one can only monitor changes in click state and trigger on that. Is that correct?