diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml index 8f4827fd..67c89c17 100644 --- a/.github/workflows/unit.yml +++ b/.github/workflows/unit.yml @@ -39,7 +39,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.8", "3.9", "3.10"] include: - os: macos-latest # macos test python-version: "3.10" @@ -51,10 +51,6 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: Install GDAL - run: python -m pip install --find-links=https://girder.github.io/large_image_wheels GDAL - - name: Install localetileserver - run: python -m pip install localtileserver - name: Install dependencies run: python -m pip install .[test] - name: test with pytest @@ -78,10 +74,6 @@ jobs: - uses: actions/setup-python@v4 with: python-version: "3.10" - - name: Install GDAL - run: python -m pip install --find-links=https://girder.github.io/large_image_wheels GDAL - - name: Install localetileserver - run: python -m pip install localtileserver - name: Install dependencies run: python -m pip install . - name: test the entrypoints diff --git a/pyproject.toml b/pyproject.toml index 6a6c7a0a..e9d7c44e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,12 +12,11 @@ classifiers = [ "Intended Audience :: Developers", "Topic :: Software Development :: Build Tools", "License :: OSI Approved :: MIT License", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", ] -requires-python = ">=3.6.9" +requires-python = ">=3.8" dependencies = [ # building widgets "ipykernel", @@ -37,6 +36,7 @@ dependencies = [ "jupyter-server-proxy", # required for localtileserver "planet>=2", "pyarrow", + "localtileserver>=0.7.0", # first pure rio version # miscellaneous "python-box", "tqdm", diff --git a/rgb1.tif b/rgb1.tif new file mode 100644 index 00000000..148b6815 Binary files /dev/null and b/rgb1.tif differ diff --git a/rgb1.tif:Zone.Identifier b/rgb1.tif:Zone.Identifier new file mode 100644 index 00000000..76d746f6 --- /dev/null +++ b/rgb1.tif:Zone.Identifier @@ -0,0 +1,4 @@ +[ZoneTransfer] +ZoneId=3 +ReferrerUrl=https://github.com/rasterio/rasterio/blob/main/tests/data/rgb1.tif +HostUrl=https://raw.githubusercontent.com/rasterio/rasterio/main/tests/data/rgb1.tif diff --git a/sepal_ui/mapping/sepal_map.py b/sepal_ui/mapping/sepal_map.py index b1e85119..3526fb75 100644 --- a/sepal_ui/mapping/sepal_map.py +++ b/sepal_ui/mapping/sepal_map.py @@ -25,6 +25,7 @@ import numpy as np import rioxarray from deprecated.sphinx import deprecated +from localtileserver import TileClient, get_leaflet_tile_layer from matplotlib import colorbar from matplotlib import colors as mpc from rasterio.crs import CRS @@ -50,7 +51,6 @@ class SepalMap(ipl.Map): - # ########################################################################## # ### Map parameters ### # ########################################################################## @@ -98,6 +98,7 @@ def __init__( # set the default parameters kwargs.setdefault("center", [0, 0]) kwargs.setdefault("zoom", 2) + kwargs.setdefault("max_zoom", 24) kwargs["basemap"] = {} kwargs["zoom_control"] = False kwargs["attribution_control"] = False @@ -242,38 +243,23 @@ def add_raster( layer_name: str = "Layer_" + su.random_string(), colormap: Union[str, mpc.Colormap] = "inferno", opacity: float = 1.0, - client_host: str = "/api/sandbox/jupyter/proxy/{port}", fit_bounds: bool = True, ) -> ipl.TileLayer: """Adds a local raster dataset to the map. + If used on a cloud platform (or distant jupyter), this method won't know where the entry point of the client is set and will thus fail to display the image. Please follow instructions from https://localtileserver.banesullivan.com/installation/remote-jupyter.html and set up the ``LOCALTILESERVER_CLIENT_PREFIX`` environment variable. + Args: image: The image file path. bands: The image bands to use. It can be either a number (e.g., 1) or a list (e.g., [3, 2, 1]). Defaults to None. layer_name: The layer name to use for the raster. Defaults to None. If a layer is already using this name 3 random letter will be added colormap: The name of the colormap to use for the raster, such as 'gray' and 'terrain'. More can be found at https://matplotlib.org/3.1.0/tutorials/colors/colormaps.html. Defaults to inferno. opacity: the opacity of the layer, default 1.0. - client_host: the base url of the server. It's design to work in the SEPAL environment, you only need to change it if you want to work outside of our platform. See localtielayer lib for more details. fit_bounds: Whether or not we should fit the map to the image bounds. Default to True. Returns: the local tile layer embedding the raster member (to be used with other tools of sepal-ui) """ - # lazy import of localtileserver to avoid conflicts with GDAL - # environments - try: - from localtileserver import TileClient, get_leaflet_tile_layer - except ModuleNotFoundError: - raise ModuleNotFoundError( - "Your environment is not compatible with localtileserver, please check https://localtileserver.banesullivan.com/installation/index.html for more information" - ) - - # add the localtilelayer path to the environment - # if the value is already set we don't change anything - os.environ["LOCALTILESERVER_CLIENT_PREFIX"] = os.environ.pop( - "LOCALTILESERVER_CLIENT_PREFIX", client_host - ) - # force cast to Path and then start the client image = Path(image) @@ -319,7 +305,12 @@ def add_raster( # create the layer layer = get_leaflet_tile_layer( - client, style=style, name=layer_name, opacity=opacity + client, + style=style, + name=layer_name, + opacity=opacity, + max_zoom=20, + max_native_zoom=20, ) self.add_layer(layer) @@ -379,7 +370,6 @@ def add_colorbar( alpha = 1 if colors is not None: - # transform colors in hex colors hexcodes = [su.to_colors(c) for c in colors] @@ -395,7 +385,6 @@ def add_colorbar( norm = mpc.Normalize(vmin=vmin, vmax=vmax) elif cmap is not None: - plot_color = plt.get_cmap(cmap) norm = mpc.Normalize(vmin=vmin, vmax=vmax) @@ -488,7 +477,6 @@ def add_ee_layer( # apply it to vis_params if not vis_params and viz: - # find the viz params in the list try: vis_params = next(i for p, i in viz.items() if i["name"] == viz_name) @@ -500,7 +488,6 @@ def add_ee_layer( # invert the bands if needed inverted = vis_params.pop("inverted", None) if inverted is not None: - # get the index of the bands that need to be inverted index_list = [i for i, v in enumerate(inverted) if v is True] @@ -516,7 +503,6 @@ def add_ee_layer( # instead of remapping or using sldStyle # to preserve the class values in the image, for inspection if vis_params["type"] == "categorical": - colors = vis_params["palette"] values = vis_params["values"] min_ = min(values) @@ -536,7 +522,6 @@ def add_ee_layer( # specific case of hsv elif vis_params["type"] == "hsv": - # set to_min to 0 and to_max to 1 # in the original expression: # 'to_min + (v - from_min) * (to_max - to_min) / (from_max - from_min)' @@ -552,7 +537,6 @@ def add_ee_layer( # create the rgb bands asset = ee_object for i, band in enumerate(vis_params["bands"]): - # adapt the expression exp = expression.format( from_min=mins[i], from_max=maxs[i], band=band @@ -676,7 +660,6 @@ def get_viz_params(image: ee.Image) -> dict: # decompose each property by its number # and gather the properties in a sub dictionary for p, val in raw_prop_list.items(): - # extract the number and create the sub-dict _, number, name = p.split("_") props.setdefault(number, {}) @@ -765,7 +748,6 @@ def add_layer(self, layer: ipl.Layer, hover: bool = False) -> None: # apply default coloring for geoJson if isinstance(layer, ipl.GeoJSON): - # define the default values default_style = json.loads((ss.JSON_DIR / "layer.json").read_text())[ "layer" diff --git a/tests/test_mapping/test_SepalMap.py b/tests/test_mapping/test_SepalMap.py index 3b47dfa5..d28c2433 100644 --- a/tests/test_mapping/test_SepalMap.py +++ b/tests/test_mapping/test_SepalMap.py @@ -17,16 +17,6 @@ # create a seed so that we can check values random.seed(42) -# as using localtileserver is still in beta version it is not yet installed by -# default. Using this lazy import we can skip some tests when in github CD/CI -# will be removed when https://github.com/girder/large_image/pull/927 is ready -try: - from localtileserver import TileClient # noqa: F401 - - is_set_localtileserver = True -except ModuleNotFoundError: - is_set_localtileserver = False - def test_init() -> None: """Init a Sepal Map.""" @@ -141,7 +131,6 @@ def test_zoom_bounds() -> None: return -@pytest.mark.skipif(is_set_localtileserver is False, reason="localtileserver in beta") def test_add_raster(rgb: Path, byte: Path) -> None: """Add raster files to the map. @@ -500,7 +489,6 @@ def test_find_layer(ee_map_with_layers: sm.SepalMap) -> None: return -@pytest.mark.skipif(is_set_localtileserver is False, reason="localtileserver in beta") def test_zoom_raster(byte: Path) -> None: """Check that we can zoom on a raster.