Skip to content
Open
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
5 changes: 5 additions & 0 deletions folium/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,11 @@ def mercator(x):
for j in range(nblayers):
out[:, i, j] = np.interp(latslats, mercator(lats), array[:, i, j])

# Keep integer images (e.g. uint8 RGBA) in their original dtype, otherwise
# write_png treats them as float data and rescales each channel.
if np.issubdtype(array.dtype, np.integer):
out = np.round(out).astype(array.dtype)

# Eventually flip the image.
if origin == "upper":
out = out[::-1, :, :]
Expand Down
11 changes: 11 additions & 0 deletions tests/test_raster_layers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

"""

import numpy as np
import pytest
import xyzservices

Expand Down Expand Up @@ -113,6 +114,16 @@ def test_image_overlay():
assert bounds == [[0, -180], [90, 180]], bounds


def test_image_overlay_mercator_project_keeps_uint8_colors():
data = np.full((4, 3, 4), (100, 50, 200, 255), dtype="uint8")
bounds = [[40, 0], [50, 10]]

plain = folium.raster_layers.ImageOverlay(data, bounds)
projected = folium.raster_layers.ImageOverlay(data, bounds, mercator_project=True)

assert projected.url == plain.url


@pytest.mark.parametrize(
"tiles", ["CartoDB DarkMatter", xyzservices.providers.CartoDB.DarkMatter]
)
Expand Down
10 changes: 10 additions & 0 deletions tests/test_utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
get_obj_in_upper_tree,
if_pandas_df_convert_to_numpy,
javascript_identifier_path_to_array_notation,
mercator_transform,
normalize_bounds_type,
parse_font_size,
parse_options,
Expand Down Expand Up @@ -171,6 +172,15 @@ def test_normalize_bounds_type(bounds, expected):
assert normalize_bounds_type(bounds) == expected


def test_mercator_transform_keeps_integer_dtype():
# A uint8 image must stay uint8, otherwise write_png treats the result as
# float data and stretches every channel to its maximum.
data = np.full((4, 3, 4), (100, 50, 200, 255), dtype="uint8")
out = mercator_transform(data, (40, 50))
assert out.dtype == np.uint8
np.testing.assert_array_equal(out, data)


def test_camelize():
assert camelize("variable_name") == "variableName"
assert camelize("variableName") == "variableName"
Expand Down