Hello,
I’m want access the ID of a feature in a MVTLayer (or even better would be all of its properties) which is inside a Panel pane. Here is working example (or open it in Colab):
import panel as pn
import pydeck
from functools import partial
pn.extension("deckgl")
view_state = pydeck.ViewState(
    latitude = 33.740,
    longitude = 35.905,
    zoom = 10,
    max_zoom = 11.49,
    pitch = 45,
    bearing = 0
)
layer = pydeck.Layer(
    type = 'MVTLayer',
    data = "https://raw.githubusercontent.com/bertcoerver/MVTile_tests/main/tpc_folder/{z}/{x}/{y}.pbf",
    get_line_color = [0, 255, 0],
    get_fill_color = [155, 0, 100],
    line_width_min_pixels = 1,
    pickable = True,
)
deck = pydeck.Deck(
    layers = [layer],
    initial_view_state = view_state,
    map_style = "light",
    )
pn_deck = pn.pane.DeckGL(deck)
def on_map_click(event, deck):
    print(deck.layers[0])
    print(event.obj.click_state)
    print(event.obj.click_state["index"])
    # How to find the ID thats shown in the tooltip
pn_deck.param.watch(partial(on_map_click, deck = deck), ["click_state"])
pn.Column(pn_deck)
When I hover over the map I can see the ID in the tooltip. When I click the map, there is a callback function (called on_map_click) in which I have access to the coordinates of the click, and the Deck.
So, given the variable deck (which contains the layer) and a coordinate, can I retrieve the corresponding ID (or properties)?
Thanks for any help!
Bert
             
            
              
              
              
            
           
          
            
            
              Reviving this as I’m still interested in getting this working.
In the meantime I have found a “workaround” by using the clicked lat/lon/zoom to determine which tile (i.e. {z}/{x}/{y}.pbf) I’m clicking on, then downloading that specific tile (with a request.get), and then using the “index” (from click_state) to find the feature, then I can read the features properties. But this seems overly complicated.
In the Deck.GL docs, I can see that the MVTLayer has a method called getRenderedFeature.
Is there a way I can somehow use this method when there is a click-event and store its output into a Parameter? Any clues on how to implement this?
             
            
              
              
              
            
           
          
            
            
              Found a solution (very happy about this 
)
I’ve added a event to the pn.pane.DeckGL that takes whatever is in the tooltip and puts that into a new Parameter.
import panel as pn
import param
from panel.custom import JSComponent, Child
class SuperDeckGL(JSComponent):
    child: pn.pane.DeckGL = Child(class_=pn.pane.DeckGL)
    tooltip = param.String(default="nothing")
    _esm = """
    export function render({ model }) {
      const map_pane = document.createElement("map_pane");
      const child = model.get_child("child")
      child.addEventListener("click", (ev) => {
        var data = child.shadowRoot.querySelector(".deck-tooltip").innerHTML
        model.send_msg(data)
      });
      map_pane.append(child)
      return map_pane
    }
    """
    def _handle_msg(self, msg):
        print(msg)
        self.param.update(tooltip = str(msg))
json_spec = {
    "initialViewState": {
        "latitude": 9.05,
        "longitude": 0.6,
        "pitch": 35,
        "zoom": 4,
    },
    "layers": [
        {
            "@@type": "MVTLayer",
            "getLineColor":[255, 10, 255, 150],
            "getFillColor":[0, 255, 0, 0],
            "id": "L1",
            "data": "https://storage.googleapis.com/fao-cog-data/footprints/L1/{z}/{x}/{y}.pbf",
            "pickable": True,
        },
    ],
    "mapStyle": "https://basemaps.cartocdn.com/gl/positron-gl-style/style.json",
    "views": [{"@@type": "MapView", "controller": True}],
}
pane_ = pn.pane.DeckGL(
        json_spec, 
        height=300,
        width=600,
        tooltips={"html": "{properties.fid}"}
    )
pane = SuperDeckGL(child=pane_)
pn.serve(
    pane,
    port=8000 # otherwise this particular MVTLayer gives CORS error.
)
- This is already really convenient for my application. Even better would be if I could figure out how to get the Deck instance so that I can call functions like 
getRenderedFeature on a layer. 
- I’m not so familiar with javascript, so not sure if this is the most efficient way to write the 
_esm code (e.g. for now the event seems to trigger twice). 
             
            
              
              
              
            
           
          
            
            
              Guess I cheered too soon, would really appreciate some help…
The code above is basically working and doing what I want, but when I try to put it into my application everything seems to break. Especially when I remove the width=600 and replace it with sizing_mode="stretch_width". Its like there is some styling logic missing, but I have no clues on how to add that?
I’m seeing the following error in my console:
[Error] Error rendering Bokeh items: – TypeError: undefined is not an object (evaluating 'this.deckGL.redraw') — panel.min.js:174:5109 TypeError: undefined is not an object (evaluating 'this.deckGL.redraw') 
[Error] TypeError: undefined is not an object (evaluating 'this.deckGL.redraw') 
[Warning] [bokeh 3.7.3] – "panel.models.layout.ColumnView(p1004) wasn't built properly" (bokeh.min.js, line 594) 
             
            
              
              
              
            
           
          
            
            
              Can you submit a GitHub issue on Panel? And do you have the latest panel?
             
            
              
              
              
            
           
          
            
            
              Hi @ahuang11 yes I’m on 1.7.2.
So there is no nothing “wrong” with my code? I’m new to these JSComponents, so wasnt sure if this is a bug or if I’m making a mistake.