rio-tiler 7.9.2__tar.gz → 8.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/PKG-INFO +12 -36
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/README.md +6 -6
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/pyproject.toml +39 -40
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/__init__.py +1 -1
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/colormap.py +7 -4
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/errors.py +8 -0
- rio_tiler-8.0.0/rio_tiler/experimental/zarr.py +366 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/expression.py +6 -6
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/io/base.py +20 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/io/rasterio.py +1 -8
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/io/xarray.py +70 -58
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/models.py +223 -66
- rio_tiler-8.0.0/rio_tiler/mosaic/backend.py +242 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/mosaic/reader.py +6 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/reader.py +31 -32
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/tasks.py +16 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/utils.py +29 -1
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/.gitignore +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/AUTHORS.txt +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/LICENSE +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/__init__.py +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/accent.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/accent_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/afmhot.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/afmhot_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/algae.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/algae_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/amp.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/amp_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/autumn.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/autumn_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/balance.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/balance_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/binary.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/binary_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/blues.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/blues_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/bone.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/bone_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/brbg.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/brbg_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/brg.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/brg_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/bugn.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/bugn_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/bupu.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/bupu_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/bwr.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/bwr_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/cfastie.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/cividis.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/cividis_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/cmrmap.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/cmrmap_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/cool.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/cool_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/coolwarm.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/coolwarm_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/copper.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/copper_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/cubehelix.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/cubehelix_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/curl.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/curl_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/dark2.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/dark2_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/deep.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/deep_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/delta.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/delta_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/dense.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/dense_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/diff.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/diff_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/flag.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/flag_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_earth.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_earth_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_gray.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_gray_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_heat.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_heat_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_ncar.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_ncar_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_rainbow.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_rainbow_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_stern.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_stern_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_yarg.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gist_yarg_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gnbu.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gnbu_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gnuplot.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gnuplot2.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gnuplot2_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gnuplot_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gray.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/gray_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/greens.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/greens_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/greys.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/greys_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/haline.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/haline_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/hot.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/hot_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/hsv.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/hsv_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/ice.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/ice_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/inferno.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/inferno_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/jet.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/jet_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/magma.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/magma_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/matter.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/matter_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/nipy_spectral.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/nipy_spectral_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/ocean.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/ocean_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/oranges.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/oranges_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/orrd.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/orrd_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/oxy.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/oxy_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/paired.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/paired_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/pastel1.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/pastel1_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/pastel2.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/pastel2_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/phase.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/phase_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/pink.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/pink_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/piyg.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/piyg_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/plasma.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/plasma_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/prgn.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/prgn_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/prism.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/prism_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/pubu.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/pubu_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/pubugn.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/pubugn_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/puor.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/puor_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/purd.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/purd_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/purples.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/purples_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rain.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rain_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rainbow.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rainbow_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rdbu.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rdbu_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rdgy.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rdgy_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rdpu.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rdpu_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rdylbu.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rdylbu_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rdylgn.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rdylgn_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/reds.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/reds_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/rplumbo.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/schwarzwald.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/seismic.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/seismic_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/set1.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/set1_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/set2.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/set2_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/set3.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/set3_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/solar.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/solar_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/spectral.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/spectral_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/speed.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/speed_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/spring.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/spring_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/summer.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/summer_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/tab10.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/tab10_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/tab20.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/tab20_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/tab20b.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/tab20b_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/tab20c.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/tab20c_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/tarn.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/tarn_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/tempo.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/tempo_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/terrain.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/terrain_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/thermal.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/thermal_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/topo.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/topo_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/turbid.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/turbid_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/turbo.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/turbo_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/twilight.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/twilight_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/twilight_shifted.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/twilight_shifted_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/viridis.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/viridis_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/winter.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/winter_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/wistia.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/wistia_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/ylgn.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/ylgn_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/ylgnbu.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/ylgnbu_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/ylorbr.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/ylorbr_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/ylorrd.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/cmap_data/ylorrd_r.npy +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/constants.py +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/experimental/__init__.py +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/experimental/vsifile.py +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/io/__init__.py +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/io/stac.py +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/logger.py +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/mosaic/__init__.py +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/mosaic/methods/__init__.py +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/mosaic/methods/base.py +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/mosaic/methods/defaults.py +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/profiles.py +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/py.typed +0 -0
- {rio_tiler-7.9.2 → rio_tiler-8.0.0}/rio_tiler/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rio-tiler
|
|
3
|
-
Version:
|
|
3
|
+
Version: 8.0.0
|
|
4
4
|
Summary: User friendly Rasterio plugin to read raster datasets.
|
|
5
5
|
Project-URL: Homepage, https://cogeotiff.github.io/rio-tiler/
|
|
6
6
|
Project-URL: Documentation, https://cogeotiff.github.io/rio-tiler/
|
|
@@ -43,54 +43,30 @@ Keywords: COGEO,Cloud Optimized Geotiff,STAC,rasterio,slippy-map
|
|
|
43
43
|
Classifier: Intended Audience :: Information Technology
|
|
44
44
|
Classifier: Intended Audience :: Science/Research
|
|
45
45
|
Classifier: License :: OSI Approved :: BSD License
|
|
46
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
47
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
48
46
|
Classifier: Programming Language :: Python :: 3.11
|
|
49
47
|
Classifier: Programming Language :: Python :: 3.12
|
|
50
48
|
Classifier: Programming Language :: Python :: 3.13
|
|
51
49
|
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
52
|
-
Requires-Python: >=3.
|
|
50
|
+
Requires-Python: >=3.11
|
|
53
51
|
Requires-Dist: attrs
|
|
54
52
|
Requires-Dist: cachetools
|
|
55
53
|
Requires-Dist: color-operations
|
|
56
54
|
Requires-Dist: httpx
|
|
57
|
-
Requires-Dist: morecantile<
|
|
55
|
+
Requires-Dist: morecantile<8.0,>=5.0
|
|
58
56
|
Requires-Dist: numexpr
|
|
59
57
|
Requires-Dist: numpy
|
|
60
58
|
Requires-Dist: pydantic~=2.0
|
|
61
59
|
Requires-Dist: pystac<2.0,>=1.9
|
|
62
60
|
Requires-Dist: rasterio>=1.4.0
|
|
63
61
|
Requires-Dist: typing-extensions
|
|
64
|
-
Provides-Extra: benchmark
|
|
65
|
-
Requires-Dist: pytest; extra == 'benchmark'
|
|
66
|
-
Requires-Dist: pytest-benchmark; extra == 'benchmark'
|
|
67
|
-
Provides-Extra: dev
|
|
68
|
-
Requires-Dist: bump-my-version; extra == 'dev'
|
|
69
|
-
Requires-Dist: pre-commit; extra == 'dev'
|
|
70
|
-
Provides-Extra: docs
|
|
71
|
-
Requires-Dist: griffe-inherited-docstrings>=1.0.0; extra == 'docs'
|
|
72
|
-
Requires-Dist: mkdocs-jupyter>=0.24.5; extra == 'docs'
|
|
73
|
-
Requires-Dist: mkdocs-material[imaging]>=9.5; extra == 'docs'
|
|
74
|
-
Requires-Dist: mkdocs>=1.4.3; extra == 'docs'
|
|
75
|
-
Requires-Dist: mkdocstrings[python]>=0.25.1; extra == 'docs'
|
|
76
|
-
Requires-Dist: pygments; extra == 'docs'
|
|
77
62
|
Provides-Extra: s3
|
|
78
63
|
Requires-Dist: boto3; extra == 's3'
|
|
79
|
-
Provides-Extra: test
|
|
80
|
-
Requires-Dist: boto3; extra == 'test'
|
|
81
|
-
Requires-Dist: h5netcdf; extra == 'test'
|
|
82
|
-
Requires-Dist: morecantile<7.0,>=6.0; extra == 'test'
|
|
83
|
-
Requires-Dist: pytest; extra == 'test'
|
|
84
|
-
Requires-Dist: pytest-cov; extra == 'test'
|
|
85
|
-
Requires-Dist: rioxarray; extra == 'test'
|
|
86
|
-
Requires-Dist: vsifile>=0.2; extra == 'test'
|
|
87
|
-
Requires-Dist: xarray; extra == 'test'
|
|
88
|
-
Provides-Extra: tilebench
|
|
89
|
-
Requires-Dist: pytest; extra == 'tilebench'
|
|
90
|
-
Requires-Dist: tilebench; extra == 'tilebench'
|
|
91
64
|
Provides-Extra: xarray
|
|
92
65
|
Requires-Dist: rioxarray; extra == 'xarray'
|
|
93
66
|
Requires-Dist: xarray; extra == 'xarray'
|
|
67
|
+
Provides-Extra: zarr
|
|
68
|
+
Requires-Dist: obstore; extra == 'zarr'
|
|
69
|
+
Requires-Dist: zarr~=3.0; extra == 'zarr'
|
|
94
70
|
Description-Content-Type: text/markdown
|
|
95
71
|
|
|
96
72
|
# rio-tiler
|
|
@@ -264,17 +240,17 @@ At the low level, `rio-tiler` is *just* a wrapper around the [rasterio](https://
|
|
|
264
240
|
You can install `rio-tiler` using pip
|
|
265
241
|
|
|
266
242
|
```bash
|
|
267
|
-
|
|
268
|
-
|
|
243
|
+
python -m pip install -U pip
|
|
244
|
+
python -m pip install -U rio-tiler
|
|
269
245
|
```
|
|
270
246
|
|
|
271
247
|
or install from source:
|
|
272
248
|
|
|
273
249
|
```bash
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
250
|
+
git clone https://github.com/cogeotiff/rio-tiler.git
|
|
251
|
+
cd rio-tiler
|
|
252
|
+
python -m pip install -U pip
|
|
253
|
+
python -m pip install -e .
|
|
278
254
|
```
|
|
279
255
|
|
|
280
256
|
## Plugins
|
|
@@ -169,17 +169,17 @@ At the low level, `rio-tiler` is *just* a wrapper around the [rasterio](https://
|
|
|
169
169
|
You can install `rio-tiler` using pip
|
|
170
170
|
|
|
171
171
|
```bash
|
|
172
|
-
|
|
173
|
-
|
|
172
|
+
python -m pip install -U pip
|
|
173
|
+
python -m pip install -U rio-tiler
|
|
174
174
|
```
|
|
175
175
|
|
|
176
176
|
or install from source:
|
|
177
177
|
|
|
178
178
|
```bash
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
179
|
+
git clone https://github.com/cogeotiff/rio-tiler.git
|
|
180
|
+
cd rio-tiler
|
|
181
|
+
python -m pip install -U pip
|
|
182
|
+
python -m pip install -e .
|
|
183
183
|
```
|
|
184
184
|
|
|
185
185
|
## Plugins
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name = "rio-tiler"
|
|
3
3
|
description = "User friendly Rasterio plugin to read raster datasets."
|
|
4
4
|
readme = "README.md"
|
|
5
|
-
requires-python = ">=3.
|
|
5
|
+
requires-python = ">=3.11"
|
|
6
6
|
license = {file = "LICENSE"}
|
|
7
7
|
authors = [
|
|
8
8
|
{name = "Vincent Sarago", email = "vincent@developmentseed.com"},
|
|
@@ -12,8 +12,6 @@ classifiers = [
|
|
|
12
12
|
"Intended Audience :: Information Technology",
|
|
13
13
|
"Intended Audience :: Science/Research",
|
|
14
14
|
"License :: OSI Approved :: BSD License",
|
|
15
|
-
"Programming Language :: Python :: 3.9",
|
|
16
|
-
"Programming Language :: Python :: 3.10",
|
|
17
15
|
"Programming Language :: Python :: 3.11",
|
|
18
16
|
"Programming Language :: Python :: 3.12",
|
|
19
17
|
"Programming Language :: Python :: 3.13",
|
|
@@ -26,7 +24,7 @@ dependencies = [
|
|
|
26
24
|
"httpx",
|
|
27
25
|
"numexpr",
|
|
28
26
|
"numpy",
|
|
29
|
-
"morecantile>=5.0,<
|
|
27
|
+
"morecantile>=5.0,<8.0",
|
|
30
28
|
"pydantic~=2.0",
|
|
31
29
|
"pystac>=1.9,<2.0",
|
|
32
30
|
"rasterio>=1.4.0",
|
|
@@ -34,10 +32,11 @@ dependencies = [
|
|
|
34
32
|
"typing-extensions",
|
|
35
33
|
]
|
|
36
34
|
|
|
37
|
-
[
|
|
38
|
-
|
|
35
|
+
[dependency-groups]
|
|
36
|
+
dev = [
|
|
39
37
|
"pytest",
|
|
40
38
|
"pytest-cov",
|
|
39
|
+
"pytest-benchmark",
|
|
41
40
|
# XarrayReader
|
|
42
41
|
"xarray",
|
|
43
42
|
"rioxarray",
|
|
@@ -45,25 +44,34 @@ test = [
|
|
|
45
44
|
# S3
|
|
46
45
|
"boto3",
|
|
47
46
|
# Some tests will fail with 5.0
|
|
48
|
-
"morecantile>=6.0,<
|
|
47
|
+
"morecantile>=6.0,<8.0",
|
|
49
48
|
# Experimental
|
|
50
49
|
"vsifile>=0.2",
|
|
50
|
+
"zarr~=3.0",
|
|
51
|
+
"obstore",
|
|
52
|
+
"tilebench",
|
|
53
|
+
"pre-commit",
|
|
54
|
+
"bump-my-version",
|
|
51
55
|
]
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
"pytest",
|
|
57
|
+
performance = [
|
|
55
58
|
"pytest-benchmark",
|
|
56
|
-
]
|
|
57
|
-
|
|
58
|
-
tilebench = [
|
|
59
|
-
"pytest",
|
|
60
59
|
"tilebench",
|
|
61
60
|
]
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
"
|
|
65
|
-
"
|
|
62
|
+
docs = [
|
|
63
|
+
"mkdocs>=1.4.3",
|
|
64
|
+
"mkdocs-jupyter>=0.24.5",
|
|
65
|
+
"mkdocs-material[imaging]>=9.5",
|
|
66
|
+
"griffe-inherited-docstrings>=1.0.0",
|
|
67
|
+
"mkdocstrings[python]>=0.25.1",
|
|
68
|
+
"pygments",
|
|
66
69
|
]
|
|
70
|
+
deploy = [
|
|
71
|
+
"hatch",
|
|
72
|
+
]
|
|
73
|
+
|
|
74
|
+
[project.optional-dependencies]
|
|
67
75
|
s3 = [
|
|
68
76
|
"boto3",
|
|
69
77
|
]
|
|
@@ -71,13 +79,9 @@ xarray = [
|
|
|
71
79
|
"xarray",
|
|
72
80
|
"rioxarray",
|
|
73
81
|
]
|
|
74
|
-
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
"mkdocs-material[imaging]>=9.5",
|
|
78
|
-
"griffe-inherited-docstrings>=1.0.0",
|
|
79
|
-
"mkdocstrings[python]>=0.25.1",
|
|
80
|
-
"pygments",
|
|
82
|
+
zarr = [
|
|
83
|
+
"zarr~=3.0",
|
|
84
|
+
"obstore",
|
|
81
85
|
]
|
|
82
86
|
|
|
83
87
|
[project.urls]
|
|
@@ -87,28 +91,18 @@ Issues = "https://github.com/cogeotiff/rio-tiler/issues"
|
|
|
87
91
|
Source = "https://github.com/cogeotiff/rio-tiler"
|
|
88
92
|
Changelog = "https://cogeotiff.github.io/rio-tiler/release-notes/"
|
|
89
93
|
|
|
94
|
+
[build-system]
|
|
95
|
+
requires = ["hatchling"]
|
|
96
|
+
build-backend = "hatchling.build"
|
|
90
97
|
|
|
91
98
|
[tool.hatch.version]
|
|
92
99
|
path = "rio_tiler/__init__.py"
|
|
93
100
|
|
|
94
101
|
[tool.hatch.build.targets.sdist]
|
|
95
|
-
|
|
96
|
-
"/tests",
|
|
97
|
-
"/docs",
|
|
98
|
-
".github",
|
|
99
|
-
".history",
|
|
100
|
-
".bumpversion.cfg",
|
|
101
|
-
".flake8",
|
|
102
|
-
".gitignore",
|
|
103
|
-
".pre-commit-config.yaml",
|
|
104
|
-
"AUTHORS.txt",
|
|
105
|
-
"CHANGES.md",
|
|
106
|
-
"CONTRIBUTING.md",
|
|
107
|
-
]
|
|
102
|
+
only-include = ["rio_tiler/"]
|
|
108
103
|
|
|
109
|
-
[build
|
|
110
|
-
|
|
111
|
-
build-backend = "hatchling.build"
|
|
104
|
+
[tool.hatch.build.targets.wheel]
|
|
105
|
+
only-include = ["rio_tiler/"]
|
|
112
106
|
|
|
113
107
|
[tool.coverage.run]
|
|
114
108
|
branch = true
|
|
@@ -161,7 +155,7 @@ exclude = [
|
|
|
161
155
|
max-complexity = 14
|
|
162
156
|
|
|
163
157
|
[tool.bumpversion]
|
|
164
|
-
current_version = "
|
|
158
|
+
current_version = "8.0.0"
|
|
165
159
|
parse = """(?x)
|
|
166
160
|
(?P<major>\\d+)\\.
|
|
167
161
|
(?P<minor>\\d+)\\.
|
|
@@ -191,3 +185,8 @@ tag_name = "{new_version}"
|
|
|
191
185
|
filename = "rio_tiler/__init__.py"
|
|
192
186
|
search = '__version__ = "{current_version}"'
|
|
193
187
|
replace = '__version__ = "{new_version}"'
|
|
188
|
+
|
|
189
|
+
[tool.pytest.ini_options]
|
|
190
|
+
filterwarnings = [
|
|
191
|
+
"ignore::rio_tiler.errors.RioTilerExperimentalWarning",
|
|
192
|
+
]
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""rio-tiler colormap functions and classes."""
|
|
2
2
|
|
|
3
|
+
import itertools
|
|
3
4
|
import json
|
|
4
5
|
import os
|
|
5
6
|
import pathlib
|
|
@@ -166,9 +167,10 @@ def apply_discrete_cmap(
|
|
|
166
167
|
|
|
167
168
|
data = numpy.transpose(res, [2, 0, 1])
|
|
168
169
|
|
|
169
|
-
# If
|
|
170
|
+
# If colormap values are between 0-255
|
|
170
171
|
# we cast the output array to Uint8
|
|
171
|
-
|
|
172
|
+
cmap_v = list(itertools.chain(*colormap.values()))
|
|
173
|
+
if min(cmap_v) >= 0 and max(cmap_v) <= 255:
|
|
172
174
|
data = data.astype("uint8")
|
|
173
175
|
|
|
174
176
|
return data[:-1], data[-1]
|
|
@@ -206,9 +208,10 @@ def apply_intervals_cmap(
|
|
|
206
208
|
|
|
207
209
|
data = numpy.transpose(res, [2, 0, 1])
|
|
208
210
|
|
|
209
|
-
# If
|
|
211
|
+
# If colormap values are between 0-255
|
|
210
212
|
# we cast the output array to Uint8
|
|
211
|
-
|
|
213
|
+
cmap_v = list(itertools.chain(*[v for k, v in colormap]))
|
|
214
|
+
if min(cmap_v) >= 0 and max(cmap_v) <= 255:
|
|
212
215
|
data = data.astype("uint8")
|
|
213
216
|
|
|
214
217
|
return data[:-1], data[-1]
|
|
@@ -95,3 +95,11 @@ class InvalidGeographicBounds(RioTilerError):
|
|
|
95
95
|
|
|
96
96
|
class RioTilerExperimentalWarning(UserWarning):
|
|
97
97
|
"""A rio-tiler specific experimental functionality warning."""
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class MaxArraySizeError(RioTilerError):
|
|
101
|
+
"""Trying to load to many pixels in memory."""
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class NoAssetFoundError(RioTilerError):
|
|
105
|
+
"""No Asset found"""
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
"""rio_tiler experimental ZarrReaders."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import contextlib
|
|
6
|
+
from functools import cache
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Any, Callable, Dict, List, Literal, Optional, Union
|
|
9
|
+
from urllib.parse import urlparse
|
|
10
|
+
|
|
11
|
+
import attr
|
|
12
|
+
from morecantile import TileMatrixSet
|
|
13
|
+
from rasterio.crs import CRS
|
|
14
|
+
|
|
15
|
+
from rio_tiler.constants import WEB_MERCATOR_TMS, WGS84_CRS
|
|
16
|
+
from rio_tiler.errors import InvalidGeographicBounds
|
|
17
|
+
from rio_tiler.io.base import BaseReader
|
|
18
|
+
from rio_tiler.io.xarray import XarrayReader
|
|
19
|
+
from rio_tiler.models import BandStatistics, ImageData, Info, PointData
|
|
20
|
+
from rio_tiler.types import BBox
|
|
21
|
+
|
|
22
|
+
try:
|
|
23
|
+
import obstore
|
|
24
|
+
from zarr.storage import ObjectStore
|
|
25
|
+
except ImportError: # pragma: nocover
|
|
26
|
+
ObjectStore = None # type: ignore
|
|
27
|
+
obstore = None # type: ignore
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
import rioxarray
|
|
31
|
+
import xarray
|
|
32
|
+
except ImportError: # pragma: nocover
|
|
33
|
+
xarray = None # type: ignore
|
|
34
|
+
rioxarray = None # type: ignore
|
|
35
|
+
|
|
36
|
+
sel_methods = Literal["nearest", "pad", "ffill", "backfill", "bfill"]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@cache
|
|
40
|
+
def open_dataset(src_path: str, **kwargs: Any) -> xarray.Dataset:
|
|
41
|
+
"""Open Xarray dataset
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
src_path (str): dataset path.
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
xarray.DataTree
|
|
48
|
+
|
|
49
|
+
"""
|
|
50
|
+
parsed = urlparse(src_path)
|
|
51
|
+
if not parsed.scheme:
|
|
52
|
+
src_path = str(Path(src_path).resolve())
|
|
53
|
+
src_path = "file://" + src_path
|
|
54
|
+
store = obstore.store.from_url(src_path, **kwargs)
|
|
55
|
+
zarr_store = ObjectStore(store=store, read_only=True)
|
|
56
|
+
ds = xarray.open_dataset(
|
|
57
|
+
zarr_store,
|
|
58
|
+
decode_times=True,
|
|
59
|
+
decode_coords="all",
|
|
60
|
+
consolidated=True,
|
|
61
|
+
engine="zarr",
|
|
62
|
+
)
|
|
63
|
+
return ds
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@attr.s
|
|
67
|
+
class ZarrReader(BaseReader):
|
|
68
|
+
"""Zarr dataset Reader.
|
|
69
|
+
|
|
70
|
+
Attributes:
|
|
71
|
+
input (str): dataset path.
|
|
72
|
+
dataset (xarray.Dataset): Xarray dataset.
|
|
73
|
+
tms (morecantile.TileMatrixSet, optional): TileMatrixSet grid definition. Defaults to `WebMercatorQuad`.
|
|
74
|
+
opener (Callable): Xarray dataset opener. Defaults to `open_dataset`.
|
|
75
|
+
opener_options (dict): Options to forward to the opener callable.
|
|
76
|
+
|
|
77
|
+
Examples:
|
|
78
|
+
>>> with ZarrReader(
|
|
79
|
+
"s3://mur-sst/zarr-v1",
|
|
80
|
+
opener_options={
|
|
81
|
+
"skip_signature": True,
|
|
82
|
+
"region": "us-west-2",
|
|
83
|
+
}
|
|
84
|
+
) as src:
|
|
85
|
+
print(src)
|
|
86
|
+
print(src.variables)
|
|
87
|
+
img = src.tile(x, y, z, tmax)
|
|
88
|
+
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
input: str = attr.ib()
|
|
92
|
+
dataset: xarray.Dataset = attr.ib(default=None)
|
|
93
|
+
|
|
94
|
+
tms: TileMatrixSet = attr.ib(default=WEB_MERCATOR_TMS)
|
|
95
|
+
|
|
96
|
+
opener: Callable[..., xarray.Dataset] = attr.ib(default=open_dataset)
|
|
97
|
+
opener_options: Dict = attr.ib(factory=dict)
|
|
98
|
+
_ctx_stack: contextlib.ExitStack = attr.ib(init=False, factory=contextlib.ExitStack)
|
|
99
|
+
|
|
100
|
+
def __attrs_post_init__(self):
|
|
101
|
+
"""Set bounds and CRS."""
|
|
102
|
+
assert xarray is not None, "xarray must be installed to use XarrayReader"
|
|
103
|
+
assert rioxarray is not None, "rioxarray must be installed to use XarrayReader"
|
|
104
|
+
|
|
105
|
+
if not self.dataset:
|
|
106
|
+
self.dataset = self._ctx_stack.enter_context(
|
|
107
|
+
self.opener(self.input, **self.opener_options)
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# NOTE: rioxarray returns **ordered** bounds in form of (minx, miny, maxx, maxx)
|
|
111
|
+
self.bounds = tuple(self.dataset.rio.bounds())
|
|
112
|
+
# Make sure we have a valid CRS
|
|
113
|
+
self.dataset = self.dataset.rio.write_crs(
|
|
114
|
+
self.dataset.rio.crs or "epsg:4326",
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
self.crs = self.dataset.rio.crs
|
|
118
|
+
|
|
119
|
+
# adds half x/y resolution on each values
|
|
120
|
+
# https://github.com/corteva/rioxarray/issues/645#issuecomment-1461070634
|
|
121
|
+
xres, yres = map(abs, self.dataset.rio.resolution())
|
|
122
|
+
if self.crs == WGS84_CRS and (
|
|
123
|
+
self.bounds[0] + xres / 2 < -180
|
|
124
|
+
or self.bounds[1] + yres / 2 < -90
|
|
125
|
+
or self.bounds[2] - xres / 2 > 180
|
|
126
|
+
or self.bounds[3] - yres / 2 > 90
|
|
127
|
+
):
|
|
128
|
+
raise InvalidGeographicBounds(
|
|
129
|
+
f"Invalid geographic bounds: {self.bounds}. Must be within (-180, -90, 180, 90)."
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
self.transform = self.dataset.rio.transform()
|
|
133
|
+
self.height = self.dataset.rio.height
|
|
134
|
+
self.width = self.dataset.rio.width
|
|
135
|
+
|
|
136
|
+
def close(self):
|
|
137
|
+
"""Close xarray dataset."""
|
|
138
|
+
self._ctx_stack.close()
|
|
139
|
+
|
|
140
|
+
def __exit__(self, exc_type, exc_value, traceback):
|
|
141
|
+
"""Support using with Context Managers."""
|
|
142
|
+
self.close()
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def variables(self) -> List[str]:
|
|
146
|
+
"""Return dataset variable names"""
|
|
147
|
+
return list(self.dataset.data_vars)
|
|
148
|
+
|
|
149
|
+
def _arrange_dims(self, da: xarray.DataArray) -> xarray.DataArray:
|
|
150
|
+
"""Arrange coordinates and time dimensions.
|
|
151
|
+
|
|
152
|
+
An rioxarray.exceptions.InvalidDimensionOrder error is raised if the coordinates are not in the correct order time, y, and x.
|
|
153
|
+
See: https://github.com/corteva/rioxarray/discussions/674
|
|
154
|
+
|
|
155
|
+
We conform to using x and y as the spatial dimension names..
|
|
156
|
+
|
|
157
|
+
"""
|
|
158
|
+
if "x" not in da.dims and "y" not in da.dims:
|
|
159
|
+
try:
|
|
160
|
+
latitude_var_name = next(
|
|
161
|
+
name
|
|
162
|
+
for name in ["lat", "latitude", "LAT", "LATITUDE", "Lat"]
|
|
163
|
+
if name in da.dims
|
|
164
|
+
)
|
|
165
|
+
longitude_var_name = next(
|
|
166
|
+
name
|
|
167
|
+
for name in ["lon", "longitude", "LON", "LONGITUDE", "Lon"]
|
|
168
|
+
if name in da.dims
|
|
169
|
+
)
|
|
170
|
+
except StopIteration as e:
|
|
171
|
+
raise ValueError(f"Couldn't find X/Y dimensions in {da.dims}") from e
|
|
172
|
+
|
|
173
|
+
da = da.rename({latitude_var_name: "y", longitude_var_name: "x"})
|
|
174
|
+
|
|
175
|
+
if "TIME" in da.dims:
|
|
176
|
+
da = da.rename({"TIME": "time"})
|
|
177
|
+
|
|
178
|
+
if extra_dims := [d for d in da.dims if d not in ["x", "y"]]:
|
|
179
|
+
da = da.transpose(*extra_dims, "y", "x")
|
|
180
|
+
else:
|
|
181
|
+
da = da.transpose("y", "x")
|
|
182
|
+
|
|
183
|
+
# If min/max values are stored in `valid_range` we add them in `valid_min/valid_max`
|
|
184
|
+
vmin, vmax = da.attrs.get("valid_min"), da.attrs.get("valid_max")
|
|
185
|
+
if "valid_range" in da.attrs and not (vmin is not None and vmax is not None):
|
|
186
|
+
valid_range = da.attrs.get("valid_range")
|
|
187
|
+
da.attrs.update({"valid_min": valid_range[0], "valid_max": valid_range[1]})
|
|
188
|
+
|
|
189
|
+
return da
|
|
190
|
+
|
|
191
|
+
def _get_variable(
|
|
192
|
+
self,
|
|
193
|
+
variable: str,
|
|
194
|
+
sel: Optional[List[str]] = None,
|
|
195
|
+
method: Optional[sel_methods] = None,
|
|
196
|
+
) -> xarray.DataArray:
|
|
197
|
+
"""Get DataArray from xarray Dataset."""
|
|
198
|
+
da = self.dataset[variable]
|
|
199
|
+
|
|
200
|
+
if sel:
|
|
201
|
+
_idx: Dict[str, List] = {}
|
|
202
|
+
for s in sel:
|
|
203
|
+
val: Union[str, slice]
|
|
204
|
+
dim, val = s.split("=")
|
|
205
|
+
|
|
206
|
+
# cast string to dtype of the dimension
|
|
207
|
+
if da[dim].dtype != "O":
|
|
208
|
+
val = da[dim].dtype.type(val)
|
|
209
|
+
|
|
210
|
+
if dim in _idx:
|
|
211
|
+
_idx[dim].append(val)
|
|
212
|
+
else:
|
|
213
|
+
_idx[dim] = [val]
|
|
214
|
+
|
|
215
|
+
sel_idx = {k: v[0] if len(v) < 2 else v for k, v in _idx.items()}
|
|
216
|
+
da = da.sel(sel_idx, method=method)
|
|
217
|
+
|
|
218
|
+
da = self._arrange_dims(da)
|
|
219
|
+
|
|
220
|
+
# Make sure we have a valid CRS
|
|
221
|
+
crs = da.rio.crs or "epsg:4326"
|
|
222
|
+
da = da.rio.write_crs(crs)
|
|
223
|
+
|
|
224
|
+
if crs == "epsg:4326" and (da.x > 180).any():
|
|
225
|
+
# Adjust the longitude coordinates to the -180 to 180 range
|
|
226
|
+
da = da.assign_coords(x=(da.x + 180) % 360 - 180)
|
|
227
|
+
|
|
228
|
+
# Sort the dataset by the updated longitude coordinates
|
|
229
|
+
da = da.sortby(da.x)
|
|
230
|
+
|
|
231
|
+
assert len(da.dims) in [
|
|
232
|
+
2,
|
|
233
|
+
3,
|
|
234
|
+
], "rio_tiler.io.xarray.DatasetReader can only work with 2D or 3D DataArray"
|
|
235
|
+
|
|
236
|
+
return da
|
|
237
|
+
|
|
238
|
+
def spatial_info( # type: ignore
|
|
239
|
+
self,
|
|
240
|
+
*,
|
|
241
|
+
variable: str,
|
|
242
|
+
sel: Optional[List[str]] = None,
|
|
243
|
+
method: Optional[sel_methods] = None,
|
|
244
|
+
):
|
|
245
|
+
"""Return xarray.DataArray info."""
|
|
246
|
+
with XarrayReader(
|
|
247
|
+
self._get_variable(variable, sel=sel, method=method),
|
|
248
|
+
) as da:
|
|
249
|
+
return {
|
|
250
|
+
"crs": da.crs,
|
|
251
|
+
"bounds": da.bounds,
|
|
252
|
+
"minzoom": da.minzoom,
|
|
253
|
+
"maxzoom": da.maxzoom,
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
def get_geographic_bounds( # type: ignore
|
|
257
|
+
self,
|
|
258
|
+
crs: CRS,
|
|
259
|
+
*,
|
|
260
|
+
variable: str,
|
|
261
|
+
sel: Optional[List[str]] = None,
|
|
262
|
+
method: Optional[sel_methods] = None,
|
|
263
|
+
) -> BBox:
|
|
264
|
+
"""Return Geographic Bounds for a Geographic CRS."""
|
|
265
|
+
with XarrayReader(
|
|
266
|
+
self._get_variable(variable, sel=sel, method=method),
|
|
267
|
+
) as da:
|
|
268
|
+
return da.get_geographic_bounds(crs)
|
|
269
|
+
|
|
270
|
+
def info( # type: ignore
|
|
271
|
+
self,
|
|
272
|
+
*,
|
|
273
|
+
variable: str,
|
|
274
|
+
sel: Optional[List[str]] = None,
|
|
275
|
+
method: Optional[sel_methods] = None,
|
|
276
|
+
) -> Info:
|
|
277
|
+
"""Return xarray.DataArray info."""
|
|
278
|
+
with XarrayReader(
|
|
279
|
+
self._get_variable(variable, sel=sel, method=method),
|
|
280
|
+
) as da:
|
|
281
|
+
return da.info()
|
|
282
|
+
|
|
283
|
+
def statistics( # type: ignore
|
|
284
|
+
self,
|
|
285
|
+
*args: Any,
|
|
286
|
+
variable: str,
|
|
287
|
+
sel: Optional[List[str]] = None,
|
|
288
|
+
method: Optional[sel_methods] = None,
|
|
289
|
+
**kwargs: Any,
|
|
290
|
+
) -> Dict[str, BandStatistics]:
|
|
291
|
+
"""Return statistics from a dataset."""
|
|
292
|
+
with XarrayReader(
|
|
293
|
+
self._get_variable(variable, sel=sel, method=method),
|
|
294
|
+
) as da:
|
|
295
|
+
return da.statistics(*args, **kwargs)
|
|
296
|
+
|
|
297
|
+
def tile( # type: ignore
|
|
298
|
+
self,
|
|
299
|
+
*args: Any,
|
|
300
|
+
variable: str,
|
|
301
|
+
sel: Optional[List[str]] = None,
|
|
302
|
+
method: Optional[sel_methods] = None,
|
|
303
|
+
**kwargs: Any,
|
|
304
|
+
) -> ImageData:
|
|
305
|
+
"""Read a Web Map tile from a dataset."""
|
|
306
|
+
with XarrayReader(
|
|
307
|
+
self._get_variable(variable, sel=sel, method=method),
|
|
308
|
+
tms=self.tms,
|
|
309
|
+
) as da:
|
|
310
|
+
return da.tile(*args, **kwargs)
|
|
311
|
+
|
|
312
|
+
def part( # type: ignore
|
|
313
|
+
self,
|
|
314
|
+
*args: Any,
|
|
315
|
+
variable: str,
|
|
316
|
+
sel: Optional[List[str]] = None,
|
|
317
|
+
method: Optional[sel_methods] = None,
|
|
318
|
+
**kwargs: Any,
|
|
319
|
+
) -> ImageData:
|
|
320
|
+
"""Read part of a dataset."""
|
|
321
|
+
with XarrayReader(
|
|
322
|
+
self._get_variable(variable, sel=sel, method=method),
|
|
323
|
+
) as da:
|
|
324
|
+
return da.part(*args, **kwargs)
|
|
325
|
+
|
|
326
|
+
def preview( # type: ignore
|
|
327
|
+
self,
|
|
328
|
+
*args: Any,
|
|
329
|
+
variable: str,
|
|
330
|
+
sel: Optional[List[str]] = None,
|
|
331
|
+
method: Optional[sel_methods] = None,
|
|
332
|
+
**kwargs: Any,
|
|
333
|
+
) -> ImageData:
|
|
334
|
+
"""Return a preview of a dataset."""
|
|
335
|
+
with XarrayReader(
|
|
336
|
+
self._get_variable(variable, sel=sel, method=method),
|
|
337
|
+
) as da:
|
|
338
|
+
return da.preview(*args, **kwargs)
|
|
339
|
+
|
|
340
|
+
def point( # type: ignore
|
|
341
|
+
self,
|
|
342
|
+
*args: Any,
|
|
343
|
+
variable: str,
|
|
344
|
+
sel: Optional[List[str]] = None,
|
|
345
|
+
method: Optional[sel_methods] = None,
|
|
346
|
+
**kwargs: Any,
|
|
347
|
+
) -> PointData:
|
|
348
|
+
"""Read a pixel value from a dataset."""
|
|
349
|
+
with XarrayReader(
|
|
350
|
+
self._get_variable(variable, sel=sel, method=method),
|
|
351
|
+
) as da:
|
|
352
|
+
return da.point(*args, **kwargs)
|
|
353
|
+
|
|
354
|
+
def feature( # type: ignore
|
|
355
|
+
self,
|
|
356
|
+
*args: Any,
|
|
357
|
+
variable: str,
|
|
358
|
+
sel: Optional[List[str]] = None,
|
|
359
|
+
method: Optional[sel_methods] = None,
|
|
360
|
+
**kwargs: Any,
|
|
361
|
+
) -> ImageData:
|
|
362
|
+
"""Read part of a dataset defined by a geojson feature."""
|
|
363
|
+
with XarrayReader(
|
|
364
|
+
self._get_variable(variable, sel=sel, method=method),
|
|
365
|
+
) as da:
|
|
366
|
+
return da.feature(*args, **kwargs)
|