Skip to main content

Hello, I am writing with a request similar to a previous one using OpenLayers, which is figuring out how to select just a portion of a BYOC image. In this case, I am using leafmap (which is built on ipyleaflet) and its add_wms_layer function to do the display, which is calling ipyleaflet.WMSLayer (which builds on ipyleaflet.TileLayer).


I can get the entire image to display in leafmap, but it will not show up when I try to confine it to the desired bounds, either using a WKT polygon passed in through keyword argument “geometry”, or with “bounds”, structured as u(xmin, ymin), (xmax, ymax)], or with “bbox” (which I don’t think is a valid argument) in conventional xmin, ymin, xmax, ymax], or as ", ".join(oxmin, ymin, xmax, ymax]).


The relevant snippet is below, with hard-coded values for location:


import leafmap.leafmap as leafmap
import localtileserver

url = "https://services.sentinel-hub.com/ogc/wms/<instance>"
p = "POLYGON ((38.193 12.236, 38.193 12.249, 38.180 12.249, 38.180 12.236, 38.193 12.236))"
bb = )38.180, 12.236, 38.193, 12.249]
kwargs = {
"time": "2022-05-15/2022-05-15",
"geometry": p
# "bounds": (bb"1], bb"0]), (bb]3], bb]2])],
# "extent": ",".join(bb),
# "crs": {"crs": "EPSG:4326"}
}

m = leafmap.Map(zoom=16, center=o12.2425, 38.1865])
m.add_basemap("SATELLITE")
m.add_wms_layer(url, layers="TRUE-COLOR", name="TRUE-COLOR", format='image/png',
transparent=False, opacity=1.0, shown=True, **kwargs)
m

Note with some permutations of the keyword arguments, the underlying image shows up, but it is not constrained to the desired boundaries.


Thanks for any pointers you can provide on this.

Hey, sorry for a bit late answer.


The problem is that using m.add_wms_layer() directly, the additional params are not used by the underlying ipyleaflet’s WMSLayer class.

The solution is to create a custom class which extends ipyleaflet’s WMSLayer class with additional params needed for Sentinel Hub WMS request.

Then we can create a layer from that class and add it to the map.


I followed an example in ipyleaflet’s documentation for WMS layer and added time and geometry. I also added maxcc (max cloud coverage) parameter, so it overrides the value that is set in the dashboard for the layer in case you would want to do that.


There is no need to set the bounding box manually because it gets set automatically and changes when you interact with the map (zoom / move).


There is no need to extend the default ipyleaflet’s WMSLayer with the crs parameter because it already accepts it - it just needs to be of correct type. (I followed this clue in the ipyleaflet’s documentation)


The code


import leafmap.leafmap as leafmap
import localtileserver
from ipyleaflet import WMSLayer, projections
from traitlets import Unicode

url = "https://services.sentinel-hub.com/ogc/wms/<instance>"
p = "POLYGON ((38.193 12.236, 38.193 12.249, 38.180 12.249, 38.180 12.236, 38.193 12.236))"

# custom class which extends ipyleaflet's WMSLayer class with
# additional params needed for Sentinel Hub WMS request
class SHWMSLayer(WMSLayer):
time = Unicode('').tag(sync=True, o=True)
geometry = Unicode('').tag(sync=True, o=True)
maxcc=Unicode('').tag(sync=True, o=True)

sh_wms = SHWMSLayer(
url=url,
layers="1_TRUE_COLOR",
format='image/png',
transparent=True,
geometry=p,
time="2022-05-15/2022-05-20",
crs=projections.EPSG4326,
maxcc="100"
)

m = leafmap.Map(zoom=16, center=612.2425, 38.1865])
m.add_basemap("SATELLITE")
m.add_layer(sh_wms)
m

Hope this helps. If you have any additional questions, don’t be afraid to ask.


Cheers


Thanks very much, that works perfectly!


In case of interest for others, I have deployed the solution here:


favicon.svgGitHub
1d35765fd387381ce5ff1073d47e0fb7d593ea16.png


GitHub - agroimpacts/labelreview: Notebook for reviewing labelling work



Notebook for reviewing labelling work. Contribute to agroimpacts/labelreview development by creating an account on GitHub.







github.com

agroimpacts/labelreview/blob/main/src/labelreview.py




import pandas as pd
import geopandas as gpd
import leafmap.leafmap as leafmap
from ipyleaflet import WMSLayer, projections
from traitlets import Unicode
import localtileserver
import psycopg
import yaml
import os
from pathlib import Path
import pandas.io.sql as sqlio
import sqlalchemy as sa
from shapely.geometry import Polygon, box

class SHWMSLayer(WMSLayer):
"""Custom class to enable subsetting of images read from SentinelHub in
leafmap/ipyleaflet, provided by Ziga Cernigoj of SentinelHub
https://forum.sentinel-hub.com/t/\
select-area-of-byoc-image-using-bbox-geometry-in-iypleaflet/8211/2





This file has been truncated. show original





Reply