Skip to content

Conversation

@emilhe
Copy link
Owner

@emilhe emilhe commented Oct 7, 2024

The PR introduces a VectorTileLayer component, based on this library, which enables rendering of (protobuf) vector tiles.

import dash_leaflet as dl
from dash import Dash
from dash_extensions.javascript import assign

eventHandlers = dict(click=assign("function(e, ctx){console.log(e); console.log(ctx);}"))

app = Dash()
app.layout = dl.Map(
    [
        dl.TileLayer(),
        dl.VectorTileLayer(url="https://openinframap.org/tiles/{z}/{x}/{y}.pbf", maxDetailZoom=6, style={}, eventHandlers=eventHandlers),
    ],
    center=[56, 10],
    zoom=8,
    style={"height": "50vh"},
)

if __name__ == "__main__":
    app.run_server(debug=True)

@emilhe emilhe mentioned this pull request Oct 7, 2024
Copy link

@Eric-UW-CRL Eric-UW-CRL left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to get an example of this working on a branch for my project. This includes a simple test of a localhost Tegola server connected to a PostGIS database. I was able to write custom queries in the Tegola config and display the layers in a layer group, which is my desired functionality.

One thing that I had a bit of trouble with was the event handlers. I am trying to access the feature on click (e.g, click on a power line and get back the details of that feature). Not sure if I am doing this right, you will see my eventHandlers dict in the code.

https://github.com/UW-Climate-Risk-Lab/climate-risk-map/tree/experimentation-dash-leaflet-vectorgrid-support/experimentation/frontend/dash_leaflet/vectorgrid

Screenshot 2024-10-11 at 12 06 31 PM

@emilhe
Copy link
Owner Author

emilhe commented Oct 14, 2024

@Eric-UW-CRL thanks for the feedback! There is nothing wrong with your code - i just didn't get to event handlers in the first take. If you bump to the next rc version,

pip install dash-leaflet==1.0.17rc2

your code should work. For reference, I have updated the example in the PR post to use event handlers. Note, I have not added any default event handlers yet (i.e. you don't have e.g. an n_clicks proper like many other components).

@emacollins
Copy link

@emilhe I see! I gave the update a try, and my event handler now works on clicks.

I was looking at the default event handlers for the GeoJSON components, and maybe it makes sense to add the same defaults for this? I imagine users would primarily want to click on the features or mouse over them to get the properties. My simple attempt using a custom event handler was as follows. This gives me enough control however to get the data from the features that I need.

eventHandlers = dict(
    click=assign(
        "function(e, ctx){ctx.setProps({clickData: e.layer.feature.properties})}"
    )
)

@kepiej
Copy link

kepiej commented Nov 7, 2024

This would be a super welcome addition to this awesome package! :)

I have a use case where the tile layer also accepts query parameters (i.e., passed in the url in the form "?param1=value1"). Is there any way that we can pass the values of these query parameters dynamically via a dash callback (e.g., depending on selected user input)?
Is this what fetchOptions is meant for? (I don't seem to get it to work ... 😢 )

@emilhe
Copy link
Owner Author

emilhe commented Nov 7, 2024

This would be a super welcome addition to this awesome package! :)

I have a use case where the tile layer also accepts query parameters (i.e., passed in the url in the form "?param1=value1"). Is there any way that we can pass the values of these query parameters dynamically via a dash callback (e.g., depending on selected user input)?

Is this what fetchOptions is meant for? (I don't seem to get it to work ... 😢 )

Did you try just passing the URL with parameters included?

FetchOptions are options passed to the request itself (method, headers, etc.)

@kepiej
Copy link

kepiej commented Nov 7, 2024

This would be a super welcome addition to this awesome package! :)
I have a use case where the tile layer also accepts query parameters (i.e., passed in the url in the form "?param1=value1"). Is there any way that we can pass the values of these query parameters dynamically via a dash callback (e.g., depending on selected user input)?
Is this what fetchOptions is meant for? (I don't seem to get it to work ... 😢 )

Did you try just passing the URL with parameters included?

Yes, that works but is not exactly what I'm looking for: I would like to be able to change the value of the query parameter dynamically (e.g., through a dash callback) when a user makes a different selection in a dropdown box. So the value in "?param1=value" would be modified by user interaction.

@emilhe
Copy link
Owner Author

emilhe commented Nov 7, 2024

In that case, I guess if the URL was made dynamic (i.e that it can be changed by a callback), that would support your use case also?

@kepiej
Copy link

kepiej commented Nov 7, 2024

In that case, I guess if the URL was made dynamic (i.e that it can be changed by a callback), that would support your use case also?

Yes, absolutely! 👍 I tried modifying it with a callback but that doesn't work currently. Hence my question here. :)

@MonSeco
Copy link

MonSeco commented Dec 3, 2024

This feature would also be super helpful for me! 😸

@kepiej
Copy link

kepiej commented Jan 31, 2025

In that case, I guess if the URL was made dynamic (i.e that it can be changed by a callback), that would support your use case also?

@emilhe Do you have any idea when this could be included? This functionality would be really convenient for my own project instead of other workarounds. :)

@frederikbylvito
Copy link

This feature would also be super helpful for me!

@kepiej
Copy link

kepiej commented May 12, 2025

In that case, I guess if the URL was made dynamic (i.e that it can be changed by a callback), that would support your use case also?

@emilhe : I was able to find a workaround that doesn't need a dynamic URL so the current Vector tile layer functionality is sufficient for my use case. :)

@akit-jwits
Copy link

@emilhe
Hi emilhe,

Thank you for your hard work on this VectorTileLayer component! It's a feature I've been really looking forward to.

I've noticed that this PR seems to be blocked by a failed test in the GitHub Actions.
I ran the tests on my local environment. It seems that if the assertion assert dash_duo.find_element("#log").text == "null" is changed to assert dash_duo.find_element("#log").text == "" in test_components.py, the test passes.

I also did some digging and it looks like the output of json.dumps(e) in stubs.py is returning an empty string "" instead of "null". I wasn't able to fully pinpoint the root cause, but it feels like some dependency update or a change in the JSONEncoder's behavior might be the reason.

I hope this information is helpful in getting this PR merged. Thanks again for all your efforts!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants