I am trying to produce a folium map, using the folium.raster_layers.WmsTileLayer class to stream images from a geoserver. The imagecoming from a collection of tiles depending on time and space, I need to pass on bbox and cql_filter options. I've read the discussions on cql_filter from several years ago which seems to be a solved problem now (https://github.com/python-visualization/folium/issues/1248)
However, I cant seem to make my image appear on the map. This request provides a perfectly good image:
https://hydroweb.next.theia-land.fr/geoserver/SWOT_HR/ows?cql_filter=(start_time%3C2024-01-03T23:00:00.000Z%20and%20end_time%3E=2024-01-02T23:00:00.000Z)&service=WMS&request=GetMap&layers=swot_l2_hr_raster_100m_water_area&styles=&format=image%2Fpng&transparent=true&version=1.1.1&width=512&height=512&crs=EPSG:4326&bbox=1.1,49,4,51
Trying to reproduce this with folium:
import folium
m = folium.Map(width='100%', height='100%', location=[50.715, 2.450], control_scale=True, zoom_start=9, tiles="cartodb positron")
name="swot_l2_hr_raster_100m_water_area"
flood_layer= folium.raster_layers.WmsTileLayer(
url="https://hydroweb.next.theia-land.fr/geoserver/SWOT_HR/ows?",
layers=name,
fmt="image/png",
crs="EPSG:4326",
transparent=False,
version='1.1.1',
size=(512, 512),
bbox='1.1,49,4,51',
cql_filter="(start_time<2024-01-03T23:00:00.000Z and end_time>=2024-01-02T23:00:00.000Z)",
)
flood_layer.add_to(m)
folium.LayerControl().add_to(m)
m.save('test.html')
m
The image does not appear. If we take a look at the html that has been generated in test.html, things do look consistent:
var macro_element_c276b3534addda38765f0ec0c10cd373 = L.tileLayer.wms( "https://hydroweb.next.theia-land.fr/geoserver/SWOT_HR/ows?", {"attribution": "", "bbox": "1.1,49,4,51", "cql_filter": "(start_time\u003c2024-01-03T23:00:00.000Z and end_time\u003e=2024-01-02T23:00:00.000Z)", "crs": "EPSG:4326", "format": "image/png", "layers": "swot_l2_hr_raster_100m_water_area", "size": [512, 512], "styles": "", "transparent": false, "version": "1.1.1"} );
However, trying with owslib works:
from owslib.wms import WebMapService
from IPython.display import Image
name="swot_l2_hr_raster_100m_water_area"
left, bottom, right, top = (1.1, 49, 4, 51)
end_time = ''
start_time = ''
wms = WebMapService(f"https://hydroweb.next.theia-land.fr/geoserver/SWOT_HR/ows?",)
layer = wms.contents[name]
response = wms.getmap(
layers=[
name,
],
bbox=(left, bottom, right, top), # Left, bottom, right, top
format="image/png",
size=(512, 512),
crs="EPSG:4326",
cql_filter=f"(start_time<2024-01-03T23:00:00.000Z and end_time>=2024-01-02T23:00:00.000Z)",
transparent=True,
)
It is possible to provide the corresponding image to folium:
def saveLayerAsImage(layer, inname):
out = open(inname, 'wb')
out.write(layer.read())
out.close()
saveLayerAsImage(response, 'test.png')
import folium
m = folium.Map(width='100%', height='100%', location=[50.715, 2.450], control_scale=True, zoom_start=9, tiles="cartodb positron")
flood_layer= folium.raster_layers.ImageOverlay(
image='test.png',
bounds=[[bottom, left], [top, right]],
transparent=True,
interactive=True,
cross_origin=False,
format="image/png",
zindex=1,
).add_to(m)
folium.LayerControl().add_to(m)
m
This works, this is exactly the output I wanted but I do not like this solution and do not understand what is different.
Can you see something that I am missing? I am using python3.10 with folium 0.15.1, owslib 0.25.0
I also tried to trick folium.raster_layers.WmsTileLayer by providing response.geturl() as the url, which did not work (it was worth a try)!
thanks a lot for any idea!