Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
fixed conflicts updating to 0.14.0
  • Loading branch information
benjaminleighton committed Aug 31, 2023
2 parents a1c2c8d + e9ded40 commit 073a0e5
Show file tree
Hide file tree
Showing 20 changed files with 327 additions and 121 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.13.3
current_version = 0.14.0
commit = True
tag = True
tag_name = {new_version}
Expand Down
32 changes: 30 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Release Notes

## 0.14.0 (unreleased)
## 0.14.0 (2023-08-30)

### titiler.core

Expand All @@ -10,12 +10,40 @@

* replace `buffer` and `color_formula` endpoint parameters by external dependencies (`BufferParams` and `ColorFormulaParams`)

* add `titiler.core.utils.render_image` which allow non-binary alpha band created with custom colormap. `render_image` replace `ImageData.render` method.

```python
# before
if cmap := colormap or dst_colormap:
image = image.apply_colormap(cmap)

if not format:
format = ImageType.jpeg if image.mask.all() else ImageType.png

content = image.render(
img_format=format.driver,
**format.profile,
**render_params,
)

# now
# render_image will:
# - apply the colormap
# - choose the right output format if `None`
# - create the binary data
content, media_type = render_image(
image,
output_format=format,
colormap=colormap or dst_colormap,
**render_params,
)
```

### titiler.extension

* rename `geom-densify-pts` to `geometry_densify` **breaking change**
* rename `geom-precision` to `geometry_precision` **breaking change**


## 0.13.3 (2023-08-27)

* fix Factories `url_for` method and avoid changing `Request.path_params` object
Expand Down
1 change: 1 addition & 0 deletions deployment/aws/lambda/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ RUN if [ "$INSTALL_TYPE" = "dev" ]; then \
pip install /tmp/titiler/extensions['wms, cogeo, stac'] /tmp/titiler/application /tmp/titiler/core /tmp/titiler/mosaic "mangum>=0.10.0" -t /asset --no-binary pydantic ; \
else \
pip install "titiler.application==0.13.3" "mangum>=0.10.0" -t /asset --no-binary pydantic ; \
pip install "titiler.application==0.14.0" "mangum>=0.10.0" -t /asset --no-binary pydantic
fi

# Reduce package size and remove useless files
Expand Down
2 changes: 1 addition & 1 deletion deployment/k8s/charts/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
apiVersion: v1
appVersion: 0.13.3
appVersion: 0.14.0
description: A dynamic Web Map tile server
name: titiler
version: 1.1.2
Expand Down
15 changes: 10 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Topic :: Scientific/Engineering :: GIS",
]
version="0.13.3"
version="0.14.0"
dependencies = [
"titiler.core==0.13.3",
"titiler.extensions==0.13.3",
"titiler.mosaic==0.13.3",
"titiler.application==0.13.3",
"titiler.core==0.14.0",
"titiler.extensions==0.14.0",
"titiler.mosaic==0.14.0",
"titiler.application==0.14.0",
]

[project.optional-dependencies]
Expand Down Expand Up @@ -127,3 +127,8 @@ no_implicit_optional = true
strict_optional = true
namespace_packages = true
explicit_package_bases = true

[tool.pytest.ini_options]
filterwarnings = [
"ignore::rasterio.errors.NotGeoreferencedWarning",
]
6 changes: 3 additions & 3 deletions src/titiler/application/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ classifiers = [
]
dynamic = ["version"]
dependencies = [
"titiler.core==0.13.3",
#"titiler.extensions[cogeo,stac]==0.13.3",
"titiler.mosaic==0.13.3",
"titiler.core==0.14.0",
"titiler.extensions[cogeo,stac]==0.14.0",
"titiler.mosaic==0.14.0",
"starlette-cramjam>=0.3,<0.4",
"pydantic-settings~=2.0",
]
Expand Down
2 changes: 1 addition & 1 deletion src/titiler/application/titiler/application/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""titiler.application"""

__version__ = "0.13.3"
__version__ = "0.14.0"
14 changes: 3 additions & 11 deletions src/titiler/core/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
"""``pytest`` configuration."""

import os
import warnings
from typing import Any, Dict

import pytest
import rasterio
from rasterio.errors import NotGeoreferencedWarning
from rasterio.io import MemoryFile

DATA_DIR = os.path.join(os.path.dirname(__file__), "fixtures")
Expand All @@ -25,15 +23,9 @@ def set_env(monkeypatch):

def parse_img(content: bytes) -> Dict[Any, Any]:
"""Read tile image and return metadata."""
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore",
category=NotGeoreferencedWarning,
module="rasterio",
)
with MemoryFile(content) as mem:
with mem.open() as dst:
return dst.profile
with MemoryFile(content) as mem:
with mem.open() as dst:
return dst.profile


def mock_rasterio_open(asset):
Expand Down
28 changes: 6 additions & 22 deletions src/titiler/core/tests/test_algorithms.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
"""Test the Algorithms class."""

import json
import warnings

import numpy
from fastapi import Depends, FastAPI
from rasterio.errors import NotGeoreferencedWarning
from rasterio.io import MemoryFile
from rio_tiler.models import ImageData
from starlette.responses import Response
Expand Down Expand Up @@ -89,16 +87,9 @@ def main(algorithm=Depends(default_algorithms.dependency)):
# MAPBOX Terrain RGB
response = client.get("/", params={"algorithm": "terrainrgb"})
assert response.status_code == 200

with warnings.catch_warnings():
warnings.filterwarnings(
"ignore",
category=NotGeoreferencedWarning,
module="rasterio",
)
with MemoryFile(response.content) as mem:
with mem.open() as dst:
data = dst.read().astype(numpy.float64)
with MemoryFile(response.content) as mem:
with mem.open() as dst:
data = dst.read().astype(numpy.float64)

# https://docs.mapbox.com/data/tilesets/guides/access-elevation-data/
elevation = -10000 + (((data[0] * 256 * 256) + (data[1] * 256) + data[2]) * 0.1)
Expand All @@ -107,16 +98,9 @@ def main(algorithm=Depends(default_algorithms.dependency)):
# TILEZEN Terrarium
response = client.get("/", params={"algorithm": "terrarium"})
assert response.status_code == 200

with warnings.catch_warnings():
warnings.filterwarnings(
"ignore",
category=NotGeoreferencedWarning,
module="rasterio",
)
with MemoryFile(response.content) as mem:
with mem.open() as dst:
data = dst.read().astype(numpy.float64)
with MemoryFile(response.content) as mem:
with mem.open() as dst:
data = dst.read().astype(numpy.float64)

# https://github.com/tilezen/joerd/blob/master/docs/formats.md#terrarium
elevation = (data[0] * 256 + data[1] + data[2] / 256) - 32768
Expand Down
28 changes: 10 additions & 18 deletions src/titiler/core/tests/test_factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
from fastapi import Depends, FastAPI, HTTPException, Path, Query, security, status
from morecantile.defaults import TileMatrixSets
from rasterio.crs import CRS
from rasterio.errors import NotGeoreferencedWarning
from rasterio.io import MemoryFile
from rio_tiler.errors import NoOverviewWarning
from rio_tiler.io import BaseReader, MultiBandReader, Reader, STACReader
Expand Down Expand Up @@ -1540,23 +1539,16 @@ def test_AutoFormat_Colormap():
response = client.get(f"/preview?url={DATA_DIR}/cog.tif&bidx=1&{cmap}")
assert response.status_code == 200
assert response.headers["content-type"] == "image/png"

with warnings.catch_warnings():
warnings.filterwarnings(
"ignore",
category=NotGeoreferencedWarning,
module="rasterio",
)
with MemoryFile(response.content) as mem:
with mem.open() as dst:
img = dst.read()
assert img[:, 0, 0].tolist() == [
0,
0,
0,
0,
] # when creating a PNG, GDAL will set masked value to 0
assert img[:, 500, 500].tolist() == [255, 0, 0, 255]
with MemoryFile(response.content) as mem:
with mem.open() as dst:
img = dst.read()
assert img[:, 0, 0].tolist() == [
0,
0,
0,
0,
] # when creating a PNG, GDAL will set masked value to 0
assert img[:, 500, 500].tolist() == [255, 0, 0, 255]


def test_rescale_dependency():
Expand Down
105 changes: 105 additions & 0 deletions src/titiler/core/tests/test_rendering.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
"""test titiler rendering function."""

import warnings

import numpy
import pytest
from rasterio.io import MemoryFile
from rio_tiler.errors import InvalidDatatypeWarning
from rio_tiler.models import ImageData

from titiler.core.resources.enums import ImageType
from titiler.core.utils import render_image


def test_rendering():
"""test rendering."""
im = ImageData(numpy.zeros((1, 256, 256), dtype="uint8"))

# Should render as JPEG
content, media = render_image(im)
assert media == "image/jpeg"
with MemoryFile(content) as mem:
with mem.open() as dst:
assert dst.profile["driver"] == "JPEG"
assert dst.count == 1
assert dst.width == 256
assert dst.height == 256
arr = dst.read()
assert numpy.unique(arr).tolist() == [0]

# Should render as PNG
content, media = render_image(im, output_format=ImageType.png)
assert media == "image/png"
with MemoryFile(content) as mem:
with mem.open() as dst:
assert dst.profile["driver"] == "PNG"
assert dst.count == 2
arr = dst.read()
assert numpy.unique(arr[0]).tolist() == [0]

with pytest.warns(InvalidDatatypeWarning):
_, media = render_image(
ImageData(numpy.zeros((1, 256, 256), dtype="uint16")),
output_format=ImageType.jpeg,
)
assert media == "image/jpeg"

with pytest.warns(InvalidDatatypeWarning):
_, media = render_image(
ImageData(numpy.zeros((1, 256, 256), dtype="float32")),
output_format=ImageType.png,
)
assert media == "image/png"

with pytest.warns(InvalidDatatypeWarning):
_, media = render_image(
ImageData(numpy.zeros((1, 256, 256), dtype="float32")),
output_format=ImageType.jp2,
)
assert media == "image/jp2"

# Make sure that we do not rescale uint16 data when there is a colormap
# Because the colormap will result in data between 0 and 255 it should be of type uint8
with warnings.catch_warnings():
warnings.simplefilter("error")
cm = {1: (0, 0, 0, 255), 1000: (255, 255, 255, 255)}
d = numpy.zeros((1, 256, 256), dtype="float32") + 1
d[0, 0:10, 0:10] = 1000
content, media = render_image(
ImageData(d),
output_format=ImageType.jpeg,
colormap=cm,
)
assert media == "image/jpeg"

with MemoryFile(content) as mem:
with mem.open() as dst:
assert dst.count == 3
assert dst.dtypes == ("uint8", "uint8", "uint8")
assert dst.read()[:, 0, 0].tolist() == [255, 255, 255]
assert dst.read()[:, 11, 11].tolist() == [0, 0, 0]

# Partial alpha values
cm = {
1: (0, 0, 0, 0),
500: (100, 100, 100, 50),
1000: (255, 255, 255, 255),
}
d = numpy.ma.zeros((1, 256, 256), dtype="float32") + 1
d[0, 0:10, 0:10] = 500
d[0, 10:20, 10:20] = 1000
content, media = render_image(
ImageData(d),
output_format=ImageType.png,
colormap=cm,
)
assert media == "image/png"

with MemoryFile(content) as mem:
with mem.open() as dst:
assert dst.count == 4
assert dst.dtypes == ("uint8", "uint8", "uint8", "uint8")
assert dst.read()[:, 0, 0].tolist() == [100, 100, 100, 50]
assert dst.read()[:, 11, 11].tolist() == [255, 255, 255, 255]
assert dst.read()[:, 30, 30].tolist() == [0, 0, 0, 0]
2 changes: 1 addition & 1 deletion src/titiler/core/titiler/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""titiler.core"""

__version__ = "0.13.3"
__version__ = "0.14.0"

from . import dependencies, errors, factory, routing # noqa
from .factory import ( # noqa
Expand Down
Loading

0 comments on commit 073a0e5

Please sign in to comment.