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

add_layer doesn't work with GeoTIFF file converted from xarray Dataset #159

Closed
zxdawn opened this issue Jun 15, 2023 · 11 comments
Closed

add_layer doesn't work with GeoTIFF file converted from xarray Dataset #159

zxdawn opened this issue Jun 15, 2023 · 11 comments
Labels
bug Something isn't working

Comments

@zxdawn
Copy link

zxdawn commented Jun 15, 2023

I'm trying to add the layer using GeoTIFF file converted from xarray Dataset. However, it isn't shown in the map.

import numpy as np
import xarray as xr
import rioxarray
from localtileserver import TileClient, get_leaflet_tile_layer, examples
from ipyleaflet import Map

data = np.random.randint(100, size = (50, 50))
grid_coords = {'lat': np.arange(0, 50, 1), 'lon': np.arange(0, 50, 1)}

da_1 = xr.DataArray(data, dims=['lat', 'lon'], coords=grid_coords).rename('1')
da_2 = xr.DataArray(data*2, dims=['lat', 'lon'], coords=grid_coords).rename('2')

output = xr.merge([da_1, da_2])
output.rio.set_spatial_dims(x_dim='lon', y_dim='lat').rio.to_raster('test.tif')

client = TileClient('test.tif')

# Create ipyleaflet TileLayer from that server
t = get_leaflet_tile_layer(client, band=1)

# Create ipyleaflet map, add tile layer, and display
m = Map(center=client.center(), zoom=client.default_zoom)
m.add_layer(t)
m

image

@banesullivan
Copy link
Owner

I'm able to reproduce this... Something weird is happening here indeed. I will get to the bottom of this.

@banesullivan banesullivan added the bug Something isn't working label Jun 15, 2023
@zxdawn
Copy link
Author

zxdawn commented Jun 15, 2023

Thanks! BTW, how did you usually create GeoTIFF files for localtileserver? Maybe conversion leads to something wrong.

@giswqs
Copy link
Contributor

giswqs commented Jun 15, 2023

Try leafmap numpy_to_cog. https://leafmap.org/notebooks/47_numpy_to_cog/

@banesullivan
Copy link
Owner

There's definitely a bug specifically in localtileservers' handling of this data type that needs to be addressed, but maybe using numpy_to_cog or using rio-cogeo to convert the saved TIF to a cog could mitigate this in the meantime

how did you usually create GeoTIFF files for localtileserver?

I usually use rasterio directly

@giswqs
Copy link
Contributor

giswqs commented Jun 15, 2023

You can also use leafmap.image_to_cog() to convert an image to COG.
https://leafmap.org/common/#leafmap.common.image_to_cog

@zxdawn
Copy link
Author

zxdawn commented Jun 15, 2023

Thank you, guys. I tested numpy_to_cog but it still failed.

import numpy as np
import xarray as xr
from localtileserver import TileClient, get_leaflet_tile_layer
from ipyleaflet import Map
import leafmap


data = np.random.randint(100, size = (50, 50))
grid_coords = {'lat': np.arange(0, 50, 1), 'lon': np.arange(0, 50, 1)}

da_1 = xr.DataArray(data, dims=['lat', 'lon'], coords=grid_coords).rename('1')
da_2 = xr.DataArray(data*2, dims=['lat', 'lon'], coords=grid_coords).rename('2')

output = xr.merge([da_1, da_2])
leafmap.numpy_to_cog(output.to_array().values, 'test.tif')

client = TileClient('test.tif')

# Create ipyleaflet TileLayer from that server
t = get_leaflet_tile_layer(client, band=1)

# Create ipyleaflet map, add tile layer, and display
# m = Map(center=client.center(), zoom=client.default_zoom)
m = Map(center=client.center(), zoom=client.default_zoom)
m.add_layer(t)
m

@banesullivan
Copy link
Owner

I should have some free time soon to dive into this and resolve it. I have some suspicions of what's happening... stay tuned.

@zxdawn
Copy link
Author

zxdawn commented Jun 16, 2023

I realize I didn't pass the bound to numpy_to_cog . Here's the update code:

import numpy as np
import xarray as xr
from localtileserver import TileClient, get_leaflet_tile_layer
from ipyleaflet import Map
import leafmap

data = np.random.randint(100, size = (50, 50))
lat = np.arange(0, 50, 1)
lon = np.arange(0, 50, 1)
grid_coords = {'lat': lat, 'lon': lon}

da_1 = xr.DataArray(data, dims=['lat', 'lon'], coords=grid_coords).rename('1')
da_2 = xr.DataArray(data*2, dims=['lat', 'lon'], coords=grid_coords).rename('2')

output = xr.merge([da_1, da_2])

leafmap.numpy_to_cog(output.to_array().values, 'test.tif', bounds=(lon.min(), lat.min(), lon.max(),lat.max()), dtype='float32')

client = TileClient('test.tif')

# Create ipyleaflet TileLayer from that server
t = get_leaflet_tile_layer(client, band=1)

# Create ipyleaflet map, add tile layer, and display
m = Map(center=client.center(), zoom=2)#client.default_zoom)
m.add_layer(t)
m

I can see the data shown now. However, it only works with zoom=2. If I zoom in or out, the tile will disappear.
test

@banesullivan
Copy link
Owner

The issue with it only appearing at certain zoom levels is separate from the original issue. To fix this, you need to increase both max_native_zoom and max_zoom when using get_leaflet_tile_layer(). I actually had this same issue the other day and pushed a fix that isn't release in ff70753

As a quick fix, use max_zoom=30 and max_native_zoom=30

@giswqs
Copy link
Contributor

giswqs commented Jun 16, 2023

In leafmap, I already fixed this. You should be able to use it directly without setting these two parameters.
https://github.com/opengeos/leafmap/blob/master/leafmap/common.py#L2813

@banesullivan
Copy link
Owner

This will be fixed in the next release (0.10.0) given the switch to the more robust rio-tiler backend

(verified example in #159 (comment))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants