eoda-dev / py-maplibregl

Python bindings for MapLibre GL JS
https://eoda-dev.github.io/py-maplibregl/
MIT License
42 stars 5 forks source link

update raster source url? #111

Open wendellwt opened 1 day ago

wendellwt commented 1 day ago

How do I update the url in a raster source?

This works fine when the layer source is GeoJSONSource:

m.set_data(JSON_LAYER_ID, new_data) # works great, but only for GeoJSON source

is there an equivalent for raster layers? Maybe something like:

m.set_raster_url(RASTER_LAYER_ID, new_url) # no such method

I tried this, but it doesn't do anything useful:

m.set_layout_property(RASTER_LAYER_ID, 'url', new_url) # nope

Thank you.

crazycapivara commented 1 day ago

You have to remove and re-add the layer with the new url.

wendellwt commented 23 hours ago

Thank you, but how do I do that? I don't see any remove_layer() function in the api docs, and nothing in the examples removes a layer. (deckgl_layer/app_update_layer.py has a function async def update_layer(): but that doesn't seem to replace the layer)

Do I map.add_layer() with a layer with the same layer_id?

(If there is no current function for this, I would be willing to try to update the code & do a pull request, if that would help)

crazycapivara commented 21 hours ago

You are right. There are not mappings for all JavaScript Map methods but with the powerful Map.add_call method you can trigger any maplibregl.Map method. The first argument is the name of the JavaScript method followed by the arguments of the method itself.

In your case you have to take a look at Map.removeLayer. As you can see the only argument ist the layerId, so in Python it looks like this:

m = Map()
# ...
m.add_call("removeLayer", layer_id)
wendellwt commented 18 hours ago

That works great! Thank you.

BTW, I removed both the layer and the source, then added them both again. Was that necessary?

def layer_update(params):

    m.add_call("removeLayer", LAYER_ID)
    m.add_call("removeSource", SOURCE_ID)

    new_url = f"https://whatever.com/{z}/{x}/{y}?{params}.tiff"

    raster_tile_source = RasterTileSource(
        tiles=[new_url],
        ...
    )
    m.add_source(SOURCE_ID, raster_tile_source)

    wx_layer = Layer(
        type=LayerType.RASTER,
        source=SOURCE_ID,
        id=LAYER_ID,
    )
    m.add_layer(wx_layer)
crazycapivara commented 1 hour ago

Yes, that is correct because a source can be consumed by multiple layers. Therefore, it is not removed automatically if a layer is removed. And maybe you want to use the source later on. So if you really want to update it as in your case, you have to remove it. I think only data of a GeoJSON Source can be updated without removing it.