Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: use localtileserver as native deps #835

Merged
merged 6 commits into from
Jun 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions .github/workflows/unit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down
Binary file added rgb1.tif
Binary file not shown.
4 changes: 4 additions & 0 deletions rgb1.tif:Zone.Identifier
Original file line number Diff line number Diff line change
@@ -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
38 changes: 10 additions & 28 deletions sepal_ui/mapping/sepal_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -50,7 +51,6 @@


class SepalMap(ipl.Map):

# ##########################################################################
# ### Map parameters ###
# ##########################################################################
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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]

Expand All @@ -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)

Expand Down Expand Up @@ -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)
Expand All @@ -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]

Expand All @@ -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)
Expand All @@ -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)'
Expand All @@ -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
Expand Down Expand Up @@ -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, {})
Expand Down Expand Up @@ -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"
Expand Down
12 changes: 0 additions & 12 deletions tests/test_mapping/test_SepalMap.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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.

Expand Down