rio-tiler 7.0.1__tar.gz → 7.2.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.
Files changed (241) hide show
  1. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/PKG-INFO +2 -1
  2. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/pyproject.toml +2 -1
  3. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/__init__.py +1 -1
  4. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/io/stac.py +19 -4
  5. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/io/xarray.py +215 -53
  6. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/utils.py +19 -5
  7. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/.gitignore +0 -0
  8. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/AUTHORS.txt +0 -0
  9. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/LICENSE +0 -0
  10. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/README.md +0 -0
  11. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/__init__.py +0 -0
  12. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/accent.npy +0 -0
  13. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/accent_r.npy +0 -0
  14. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/afmhot.npy +0 -0
  15. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/afmhot_r.npy +0 -0
  16. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/algae.npy +0 -0
  17. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/algae_r.npy +0 -0
  18. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/amp.npy +0 -0
  19. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/amp_r.npy +0 -0
  20. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/autumn.npy +0 -0
  21. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/autumn_r.npy +0 -0
  22. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/balance.npy +0 -0
  23. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/balance_r.npy +0 -0
  24. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/binary.npy +0 -0
  25. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/binary_r.npy +0 -0
  26. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/blues.npy +0 -0
  27. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/blues_r.npy +0 -0
  28. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/bone.npy +0 -0
  29. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/bone_r.npy +0 -0
  30. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/brbg.npy +0 -0
  31. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/brbg_r.npy +0 -0
  32. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/brg.npy +0 -0
  33. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/brg_r.npy +0 -0
  34. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/bugn.npy +0 -0
  35. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/bugn_r.npy +0 -0
  36. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/bupu.npy +0 -0
  37. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/bupu_r.npy +0 -0
  38. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/bwr.npy +0 -0
  39. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/bwr_r.npy +0 -0
  40. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/cfastie.npy +0 -0
  41. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/cividis.npy +0 -0
  42. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/cividis_r.npy +0 -0
  43. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/cmrmap.npy +0 -0
  44. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/cmrmap_r.npy +0 -0
  45. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/cool.npy +0 -0
  46. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/cool_r.npy +0 -0
  47. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/coolwarm.npy +0 -0
  48. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/coolwarm_r.npy +0 -0
  49. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/copper.npy +0 -0
  50. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/copper_r.npy +0 -0
  51. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/cubehelix.npy +0 -0
  52. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/cubehelix_r.npy +0 -0
  53. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/curl.npy +0 -0
  54. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/curl_r.npy +0 -0
  55. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/dark2.npy +0 -0
  56. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/dark2_r.npy +0 -0
  57. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/deep.npy +0 -0
  58. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/deep_r.npy +0 -0
  59. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/delta.npy +0 -0
  60. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/delta_r.npy +0 -0
  61. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/dense.npy +0 -0
  62. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/dense_r.npy +0 -0
  63. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/diff.npy +0 -0
  64. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/diff_r.npy +0 -0
  65. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/flag.npy +0 -0
  66. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/flag_r.npy +0 -0
  67. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_earth.npy +0 -0
  68. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_earth_r.npy +0 -0
  69. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_gray.npy +0 -0
  70. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_gray_r.npy +0 -0
  71. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_heat.npy +0 -0
  72. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_heat_r.npy +0 -0
  73. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_ncar.npy +0 -0
  74. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_ncar_r.npy +0 -0
  75. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_rainbow.npy +0 -0
  76. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_rainbow_r.npy +0 -0
  77. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_stern.npy +0 -0
  78. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_stern_r.npy +0 -0
  79. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_yarg.npy +0 -0
  80. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gist_yarg_r.npy +0 -0
  81. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gnbu.npy +0 -0
  82. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gnbu_r.npy +0 -0
  83. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gnuplot.npy +0 -0
  84. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gnuplot2.npy +0 -0
  85. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gnuplot2_r.npy +0 -0
  86. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gnuplot_r.npy +0 -0
  87. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gray.npy +0 -0
  88. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/gray_r.npy +0 -0
  89. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/greens.npy +0 -0
  90. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/greens_r.npy +0 -0
  91. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/greys.npy +0 -0
  92. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/greys_r.npy +0 -0
  93. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/haline.npy +0 -0
  94. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/haline_r.npy +0 -0
  95. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/hot.npy +0 -0
  96. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/hot_r.npy +0 -0
  97. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/hsv.npy +0 -0
  98. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/hsv_r.npy +0 -0
  99. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/ice.npy +0 -0
  100. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/ice_r.npy +0 -0
  101. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/inferno.npy +0 -0
  102. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/inferno_r.npy +0 -0
  103. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/jet.npy +0 -0
  104. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/jet_r.npy +0 -0
  105. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/magma.npy +0 -0
  106. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/magma_r.npy +0 -0
  107. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/matter.npy +0 -0
  108. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/matter_r.npy +0 -0
  109. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/nipy_spectral.npy +0 -0
  110. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/nipy_spectral_r.npy +0 -0
  111. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/ocean.npy +0 -0
  112. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/ocean_r.npy +0 -0
  113. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/oranges.npy +0 -0
  114. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/oranges_r.npy +0 -0
  115. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/orrd.npy +0 -0
  116. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/orrd_r.npy +0 -0
  117. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/oxy.npy +0 -0
  118. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/oxy_r.npy +0 -0
  119. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/paired.npy +0 -0
  120. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/paired_r.npy +0 -0
  121. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/pastel1.npy +0 -0
  122. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/pastel1_r.npy +0 -0
  123. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/pastel2.npy +0 -0
  124. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/pastel2_r.npy +0 -0
  125. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/phase.npy +0 -0
  126. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/phase_r.npy +0 -0
  127. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/pink.npy +0 -0
  128. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/pink_r.npy +0 -0
  129. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/piyg.npy +0 -0
  130. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/piyg_r.npy +0 -0
  131. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/plasma.npy +0 -0
  132. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/plasma_r.npy +0 -0
  133. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/prgn.npy +0 -0
  134. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/prgn_r.npy +0 -0
  135. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/prism.npy +0 -0
  136. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/prism_r.npy +0 -0
  137. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/pubu.npy +0 -0
  138. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/pubu_r.npy +0 -0
  139. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/pubugn.npy +0 -0
  140. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/pubugn_r.npy +0 -0
  141. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/puor.npy +0 -0
  142. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/puor_r.npy +0 -0
  143. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/purd.npy +0 -0
  144. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/purd_r.npy +0 -0
  145. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/purples.npy +0 -0
  146. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/purples_r.npy +0 -0
  147. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rain.npy +0 -0
  148. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rain_r.npy +0 -0
  149. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rainbow.npy +0 -0
  150. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rainbow_r.npy +0 -0
  151. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rdbu.npy +0 -0
  152. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rdbu_r.npy +0 -0
  153. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rdgy.npy +0 -0
  154. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rdgy_r.npy +0 -0
  155. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rdpu.npy +0 -0
  156. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rdpu_r.npy +0 -0
  157. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rdylbu.npy +0 -0
  158. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rdylbu_r.npy +0 -0
  159. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rdylgn.npy +0 -0
  160. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rdylgn_r.npy +0 -0
  161. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/reds.npy +0 -0
  162. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/reds_r.npy +0 -0
  163. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/rplumbo.npy +0 -0
  164. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/schwarzwald.npy +0 -0
  165. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/seismic.npy +0 -0
  166. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/seismic_r.npy +0 -0
  167. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/set1.npy +0 -0
  168. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/set1_r.npy +0 -0
  169. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/set2.npy +0 -0
  170. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/set2_r.npy +0 -0
  171. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/set3.npy +0 -0
  172. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/set3_r.npy +0 -0
  173. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/solar.npy +0 -0
  174. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/solar_r.npy +0 -0
  175. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/spectral.npy +0 -0
  176. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/spectral_r.npy +0 -0
  177. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/speed.npy +0 -0
  178. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/speed_r.npy +0 -0
  179. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/spring.npy +0 -0
  180. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/spring_r.npy +0 -0
  181. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/summer.npy +0 -0
  182. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/summer_r.npy +0 -0
  183. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/tab10.npy +0 -0
  184. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/tab10_r.npy +0 -0
  185. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/tab20.npy +0 -0
  186. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/tab20_r.npy +0 -0
  187. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/tab20b.npy +0 -0
  188. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/tab20b_r.npy +0 -0
  189. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/tab20c.npy +0 -0
  190. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/tab20c_r.npy +0 -0
  191. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/tarn.npy +0 -0
  192. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/tarn_r.npy +0 -0
  193. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/tempo.npy +0 -0
  194. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/tempo_r.npy +0 -0
  195. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/terrain.npy +0 -0
  196. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/terrain_r.npy +0 -0
  197. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/thermal.npy +0 -0
  198. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/thermal_r.npy +0 -0
  199. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/topo.npy +0 -0
  200. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/topo_r.npy +0 -0
  201. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/turbid.npy +0 -0
  202. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/turbid_r.npy +0 -0
  203. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/turbo.npy +0 -0
  204. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/turbo_r.npy +0 -0
  205. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/twilight.npy +0 -0
  206. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/twilight_r.npy +0 -0
  207. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/twilight_shifted.npy +0 -0
  208. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/twilight_shifted_r.npy +0 -0
  209. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/viridis.npy +0 -0
  210. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/viridis_r.npy +0 -0
  211. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/winter.npy +0 -0
  212. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/winter_r.npy +0 -0
  213. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/wistia.npy +0 -0
  214. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/wistia_r.npy +0 -0
  215. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/ylgn.npy +0 -0
  216. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/ylgn_r.npy +0 -0
  217. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/ylgnbu.npy +0 -0
  218. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/ylgnbu_r.npy +0 -0
  219. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/ylorbr.npy +0 -0
  220. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/ylorbr_r.npy +0 -0
  221. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/ylorrd.npy +0 -0
  222. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/cmap_data/ylorrd_r.npy +0 -0
  223. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/colormap.py +0 -0
  224. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/constants.py +0 -0
  225. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/errors.py +0 -0
  226. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/expression.py +0 -0
  227. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/io/__init__.py +0 -0
  228. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/io/base.py +0 -0
  229. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/io/rasterio.py +0 -0
  230. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/logger.py +0 -0
  231. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/models.py +0 -0
  232. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/mosaic/__init__.py +0 -0
  233. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/mosaic/methods/__init__.py +0 -0
  234. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/mosaic/methods/base.py +0 -0
  235. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/mosaic/methods/defaults.py +0 -0
  236. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/mosaic/reader.py +0 -0
  237. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/profiles.py +0 -0
  238. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/py.typed +0 -0
  239. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/reader.py +0 -0
  240. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/tasks.py +0 -0
  241. {rio_tiler-7.0.1 → rio_tiler-7.2.0}/rio_tiler/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rio-tiler
3
- Version: 7.0.1
3
+ Version: 7.2.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/
@@ -79,6 +79,7 @@ Provides-Extra: s3
79
79
  Requires-Dist: boto3; extra == 's3'
80
80
  Provides-Extra: test
81
81
  Requires-Dist: boto3; extra == 'test'
82
+ Requires-Dist: h5netcdf; extra == 'test'
82
83
  Requires-Dist: morecantile<7.0,>=6.0; extra == 'test'
83
84
  Requires-Dist: pytest; extra == 'test'
84
85
  Requires-Dist: pytest-cov; extra == 'test'
@@ -43,6 +43,7 @@ test = [
43
43
  # XarrayReader
44
44
  "xarray",
45
45
  "rioxarray",
46
+ "h5netcdf",
46
47
  # S3
47
48
  "boto3",
48
49
  # Some tests will fail with 5.0
@@ -157,7 +158,7 @@ ignore = [
157
158
  max-complexity = 14
158
159
 
159
160
  [tool.bumpversion]
160
- current_version = "7.0.1"
161
+ current_version = "7.2.0"
161
162
  search = "{current_version}"
162
163
  replace = "{new_version}"
163
164
  regex = false
@@ -1,6 +1,6 @@
1
1
  """rio-tiler."""
2
2
 
3
- __version__ = "7.0.1"
3
+ __version__ = "7.2.0"
4
4
 
5
5
  from . import ( # noqa
6
6
  colormap,
@@ -3,7 +3,18 @@
3
3
  import json
4
4
  import os
5
5
  import warnings
6
- from typing import Any, Dict, Iterator, Optional, Sequence, Set, Tuple, Type, Union
6
+ from typing import (
7
+ Any,
8
+ Dict,
9
+ Iterator,
10
+ List,
11
+ Optional,
12
+ Sequence,
13
+ Set,
14
+ Tuple,
15
+ Type,
16
+ Union,
17
+ )
7
18
  from urllib.parse import urlparse
8
19
 
9
20
  import attr
@@ -273,7 +284,13 @@ class STACReader(MultiBaseReader):
273
284
  self.minzoom = self.minzoom if self.minzoom is not None else self._minzoom
274
285
  self.maxzoom = self.maxzoom if self.maxzoom is not None else self._maxzoom
275
286
 
276
- self.assets = list(
287
+ self.assets = self.get_asset_list()
288
+ if not self.assets:
289
+ raise MissingAssets("No valid asset found. Asset's media types not supported")
290
+
291
+ def get_asset_list(self) -> List[str]:
292
+ """Get valid asset list"""
293
+ return list(
277
294
  _get_assets(
278
295
  self.item,
279
296
  include=self.include_assets,
@@ -282,8 +299,6 @@ class STACReader(MultiBaseReader):
282
299
  exclude_asset_types=self.exclude_asset_types,
283
300
  )
284
301
  )
285
- if not self.assets:
286
- raise MissingAssets("No valid asset found. Asset's media types not supported")
287
302
 
288
303
  def _get_reader(self, asset_info: AssetInfo) -> Tuple[Type[BaseReader], Dict]:
289
304
  """Get Asset Reader."""
@@ -2,15 +2,21 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import warnings
5
6
  from typing import Any, Dict, List, Optional
6
7
 
7
8
  import attr
9
+ import numpy
8
10
  from morecantile import Tile, TileMatrixSet
9
11
  from rasterio.crs import CRS
10
12
  from rasterio.enums import Resampling
13
+ from rasterio.errors import NotGeoreferencedWarning
14
+ from rasterio.features import bounds as featureBounds
15
+ from rasterio.features import rasterize
11
16
  from rasterio.transform import from_bounds, rowcol
12
17
  from rasterio.warp import calculate_default_transform
13
18
  from rasterio.warp import transform as transform_coords
19
+ from rasterio.warp import transform_geom
14
20
 
15
21
  from rio_tiler.constants import WEB_MERCATOR_TMS, WGS84_CRS
16
22
  from rio_tiler.errors import (
@@ -21,8 +27,9 @@ from rio_tiler.errors import (
21
27
  )
22
28
  from rio_tiler.io.base import BaseReader
23
29
  from rio_tiler.models import BandStatistics, ImageData, Info, PointData
24
- from rio_tiler.types import BBox, NoData, WarpResampling
25
- from rio_tiler.utils import CRS_to_uri, _validate_shape_input
30
+ from rio_tiler.reader import _get_width_height
31
+ from rio_tiler.types import BBox, NoData, RIOResampling, WarpResampling
32
+ from rio_tiler.utils import CRS_to_uri, _validate_shape_input, get_array_statistics
26
33
 
27
34
  try:
28
35
  import xarray
@@ -76,11 +83,14 @@ class XarrayReader(BaseReader):
76
83
  "Dataset doesn't have CRS information, please add it before using rio-tiler (e.g. `ds.rio.write_crs('epsg:4326', inplace=True)`)"
77
84
  )
78
85
 
86
+ # adds half x/y resolution on each values
87
+ # https://github.com/corteva/rioxarray/issues/645#issuecomment-1461070634
88
+ xres, yres = map(abs, self.input.rio.resolution())
79
89
  if self.crs == WGS84_CRS and (
80
- round(self.bounds[0]) < -180
81
- or round(self.bounds[1]) < -90
82
- or round(self.bounds[2]) > 180
83
- or round(self.bounds[3]) > 90
90
+ self.bounds[0] + xres / 2 < -180
91
+ or self.bounds[1] + yres / 2 < -90
92
+ or self.bounds[2] - xres / 2 > 180
93
+ or self.bounds[3] - yres / 2 > 90
84
94
  ):
85
95
  raise InvalidGeographicBounds(
86
96
  f"Invalid geographic bounds: {self.bounds}. Must be within (-180, -90, 180, 90)."
@@ -109,16 +119,20 @@ class XarrayReader(BaseReader):
109
119
  @property
110
120
  def band_names(self) -> List[str]:
111
121
  """Return list of `band names` in DataArray."""
112
- return [str(band) for d in self._dims for band in self.input[d].values]
122
+ return [str(band) for d in self._dims for band in self.input[d].values] or [
123
+ "value"
124
+ ]
113
125
 
114
126
  def info(self) -> Info:
115
127
  """Return xarray.DataArray info."""
116
- bands = [str(band) for d in self._dims for band in self.input[d].values]
117
- metadata = [band.attrs for d in self._dims for band in self.input[d]]
128
+ bands = [str(band) for d in self._dims for band in self.input[d].values] or [
129
+ "value"
130
+ ]
131
+ metadata = [band.attrs for d in self._dims for band in self.input[d]] or [{}]
118
132
 
119
133
  meta = {
120
134
  "bounds": self.bounds,
121
- "crs": CRS_to_uri(self.crs),
135
+ "crs": CRS_to_uri(self.crs) or self.crs.to_wkt(),
122
136
  "band_metadata": [(f"b{ix}", v) for ix, v in enumerate(metadata, 1)],
123
137
  "band_descriptions": [(f"b{ix}", v) for ix, v in enumerate(bands, 1)],
124
138
  "dtype": str(self.input.dtype),
@@ -127,8 +141,12 @@ class XarrayReader(BaseReader):
127
141
  "count": self.input.rio.count,
128
142
  "width": self.input.rio.width,
129
143
  "height": self.input.rio.height,
130
- "attrs": self.input.attrs,
144
+ "attrs": {
145
+ k: (v.tolist() if isinstance(v, (numpy.ndarray, numpy.generic)) else v)
146
+ for k, v in self.input.attrs.items()
147
+ },
131
148
  }
149
+
132
150
  return Info(**meta)
133
151
 
134
152
  def statistics(
@@ -137,11 +155,30 @@ class XarrayReader(BaseReader):
137
155
  categories: Optional[List[float]] = None,
138
156
  percentiles: Optional[List[int]] = None,
139
157
  hist_options: Optional[Dict] = None,
140
- max_size: int = 1024,
158
+ nodata: Optional[NoData] = None,
141
159
  **kwargs: Any,
142
160
  ) -> Dict[str, BandStatistics]:
143
- """Return bands statistics from a dataset."""
144
- raise NotImplementedError
161
+ """Return statistics from a dataset."""
162
+ hist_options = hist_options or {}
163
+
164
+ ds = self.input
165
+ if nodata is not None:
166
+ ds = ds.rio.write_nodata(nodata)
167
+
168
+ data = ds.to_masked_array()
169
+ data.mask |= data.data == ds.rio.nodata
170
+
171
+ stats = get_array_statistics(
172
+ data,
173
+ categorical=categorical,
174
+ categories=categories,
175
+ percentiles=percentiles,
176
+ **hist_options,
177
+ )
178
+
179
+ return {
180
+ self.band_names[ix]: BandStatistics(**val) for ix, val in enumerate(stats)
181
+ }
145
182
 
146
183
  def tile(
147
184
  self,
@@ -152,6 +189,7 @@ class XarrayReader(BaseReader):
152
189
  reproject_method: WarpResampling = "nearest",
153
190
  auto_expand: bool = True,
154
191
  nodata: Optional[NoData] = None,
192
+ **kwargs: Any,
155
193
  ) -> ImageData:
156
194
  """Read a Web Map tile from a dataset.
157
195
 
@@ -203,6 +241,11 @@ class XarrayReader(BaseReader):
203
241
  arr = ds.to_masked_array()
204
242
  arr.mask |= arr.data == ds.rio.nodata
205
243
 
244
+ output_bounds = ds.rio._unordered_bounds()
245
+ if output_bounds[1] > output_bounds[3] and ds.rio.transform().e > 0:
246
+ yaxis = self.input.dims.index(self.input.rio.y_dim)
247
+ arr = numpy.flip(arr, axis=yaxis)
248
+
206
249
  return ImageData(
207
250
  arr,
208
251
  bounds=tile_bounds,
@@ -219,6 +262,11 @@ class XarrayReader(BaseReader):
219
262
  reproject_method: WarpResampling = "nearest",
220
263
  auto_expand: bool = True,
221
264
  nodata: Optional[NoData] = None,
265
+ max_size: Optional[int] = None,
266
+ height: Optional[int] = None,
267
+ width: Optional[int] = None,
268
+ resampling_method: RIOResampling = "nearest",
269
+ **kwargs: Any,
222
270
  ) -> ImageData:
223
271
  """Read part of a dataset.
224
272
 
@@ -229,11 +277,21 @@ class XarrayReader(BaseReader):
229
277
  reproject_method (WarpResampling, optional): WarpKernel resampling algorithm. Defaults to `nearest`.
230
278
  auto_expand (boolean, optional): When True, rioxarray's clip_box will expand clip search if only 1D raster found with clip. When False, will throw `OneDimensionalRaster` error if only 1 x or y data point is found. Defaults to True.
231
279
  nodata (int or float, optional): Overwrite dataset internal nodata value.
280
+ max_size (int, optional): Limit the size of the longest dimension of the dataset read, respecting bounds X/Y aspect ratio.
281
+ height (int, optional): Output height of the array.
282
+ width (int, optional): Output width of the array.
283
+ resampling_method (RIOResampling, optional): RasterIO resampling algorithm. Defaults to `nearest`.
232
284
 
233
285
  Returns:
234
286
  rio_tiler.models.ImageData: ImageData instance with data, mask and input spatial info.
235
287
 
236
288
  """
289
+ if max_size and width and height:
290
+ warnings.warn(
291
+ "'max_size' will be ignored with with 'height' and 'width' set.",
292
+ UserWarning,
293
+ )
294
+
237
295
  dst_crs = dst_crs or bounds_crs
238
296
 
239
297
  ds = self.input
@@ -271,7 +329,12 @@ class XarrayReader(BaseReader):
271
329
  arr = ds.to_masked_array()
272
330
  arr.mask |= arr.data == ds.rio.nodata
273
331
 
274
- return ImageData(
332
+ output_bounds = ds.rio._unordered_bounds()
333
+ if output_bounds[1] > output_bounds[3] and ds.rio.transform().e > 0:
334
+ yaxis = self.input.dims.index(self.input.rio.y_dim)
335
+ arr = numpy.flip(arr, axis=yaxis)
336
+
337
+ img = ImageData(
275
338
  arr,
276
339
  bounds=ds.rio.bounds(),
277
340
  crs=ds.rio.crs,
@@ -279,11 +342,30 @@ class XarrayReader(BaseReader):
279
342
  band_names=self.band_names,
280
343
  )
281
344
 
345
+ output_height = height or img.height
346
+ output_width = width or img.width
347
+ if max_size and not (width and height):
348
+ output_height, output_width = _get_width_height(
349
+ max_size, img.height, img.width
350
+ )
351
+
352
+ if output_height != img.height or output_width != img.width:
353
+ img = img.resize(
354
+ output_height, output_width, resampling_method=resampling_method
355
+ )
356
+
357
+ return img
358
+
282
359
  def preview(
283
360
  self,
284
361
  max_size: int = 1024,
285
362
  height: Optional[int] = None,
286
363
  width: Optional[int] = None,
364
+ nodata: Optional[NoData] = None,
365
+ dst_crs: Optional[CRS] = None,
366
+ reproject_method: WarpResampling = "nearest",
367
+ resampling_method: RIOResampling = "nearest",
368
+ **kwargs: Any,
287
369
  ) -> ImageData:
288
370
  """Return a preview of a dataset.
289
371
 
@@ -291,12 +373,76 @@ class XarrayReader(BaseReader):
291
373
  max_size (int, optional): Limit the size of the longest dimension of the dataset read, respecting bounds X/Y aspect ratio. Defaults to 1024.
292
374
  height (int, optional): Output height of the array.
293
375
  width (int, optional): Output width of the array.
376
+ nodata (int or float, optional): Overwrite dataset internal nodata value.
377
+ dst_crs (rasterio.crs.CRS, optional): target coordinate reference system.
378
+ reproject_method (WarpResampling, optional): WarpKernel resampling algorithm. Defaults to `nearest`.
379
+ resampling_method (RIOResampling, optional): RasterIO resampling algorithm. Defaults to `nearest`.
294
380
 
295
381
  Returns:
296
382
  rio_tiler.models.ImageData: ImageData instance with data, mask and input spatial info.
297
383
 
298
384
  """
299
- raise NotImplementedError
385
+ if max_size and width and height:
386
+ warnings.warn(
387
+ "'max_size' will be ignored with with 'height' and 'width' set.",
388
+ UserWarning,
389
+ )
390
+
391
+ ds = self.input
392
+ if nodata is not None:
393
+ ds = ds.rio.write_nodata(nodata)
394
+
395
+ if dst_crs and dst_crs != self.crs:
396
+ dst_transform, w, h = calculate_default_transform(
397
+ self.crs,
398
+ dst_crs,
399
+ ds.rio.width,
400
+ ds.rio.height,
401
+ *ds.rio.bounds(),
402
+ )
403
+ ds = ds.rio.reproject(
404
+ dst_crs,
405
+ shape=(h, w),
406
+ transform=dst_transform,
407
+ resampling=Resampling[reproject_method],
408
+ nodata=nodata,
409
+ )
410
+
411
+ # Forward valid_min/valid_max to the ImageData object
412
+ minv, maxv = ds.attrs.get("valid_min"), ds.attrs.get("valid_max")
413
+ stats = None
414
+ if minv is not None and maxv is not None:
415
+ stats = ((minv, maxv),) * ds.rio.count
416
+
417
+ arr = ds.to_masked_array()
418
+ arr.mask |= arr.data == ds.rio.nodata
419
+
420
+ output_bounds = ds.rio._unordered_bounds()
421
+ if output_bounds[1] > output_bounds[3] and ds.rio.transform().e > 0:
422
+ yaxis = self.input.dims.index(self.input.rio.y_dim)
423
+ arr = numpy.flip(arr, axis=yaxis)
424
+
425
+ img = ImageData(
426
+ arr,
427
+ bounds=ds.rio.bounds(),
428
+ crs=ds.rio.crs,
429
+ dataset_statistics=stats,
430
+ band_names=self.band_names,
431
+ )
432
+
433
+ output_height = height or img.height
434
+ output_width = width or img.width
435
+ if max_size and not (width and height):
436
+ output_height, output_width = _get_width_height(
437
+ max_size, img.height, img.width
438
+ )
439
+
440
+ if output_height != img.height or output_width != img.width:
441
+ img = img.resize(
442
+ output_height, output_width, resampling_method=resampling_method
443
+ )
444
+
445
+ return img
300
446
 
301
447
  def point(
302
448
  self,
@@ -304,6 +450,7 @@ class XarrayReader(BaseReader):
304
450
  lat: float,
305
451
  coord_crs: CRS = WGS84_CRS,
306
452
  nodata: Optional[NoData] = None,
453
+ **kwargs: Any,
307
454
  ) -> PointData:
308
455
  """Read a pixel value from a dataset.
309
456
 
@@ -331,7 +478,11 @@ class XarrayReader(BaseReader):
331
478
 
332
479
  y, x = rowcol(ds.rio.transform(), ds_lon, ds_lat)
333
480
 
334
- arr = ds[:, int(y[0]), int(x[0])].to_masked_array()
481
+ if ds.ndim == 2:
482
+ arr = numpy.expand_dims(ds[int(y[0]), int(x[0])].to_masked_array(), axis=0)
483
+ else:
484
+ arr = ds[:, int(y[0]), int(x[0])].to_masked_array()
485
+
335
486
  arr.mask |= arr.data == ds.rio.nodata
336
487
 
337
488
  return PointData(
@@ -347,7 +498,13 @@ class XarrayReader(BaseReader):
347
498
  dst_crs: Optional[CRS] = None,
348
499
  shape_crs: CRS = WGS84_CRS,
349
500
  reproject_method: WarpResampling = "nearest",
501
+ auto_expand: bool = True,
350
502
  nodata: Optional[NoData] = None,
503
+ max_size: Optional[int] = None,
504
+ height: Optional[int] = None,
505
+ width: Optional[int] = None,
506
+ resampling_method: RIOResampling = "nearest",
507
+ **kwargs: Any,
351
508
  ) -> ImageData:
352
509
  """Read part of a dataset defined by a geojson feature.
353
510
 
@@ -356,52 +513,57 @@ class XarrayReader(BaseReader):
356
513
  dst_crs (rasterio.crs.CRS, optional): Overwrite target coordinate reference system.
357
514
  shape_crs (rasterio.crs.CRS, optional): Input geojson coordinate reference system. Defaults to `epsg:4326`.
358
515
  reproject_method (WarpResampling, optional): WarpKernel resampling algorithm. Defaults to `nearest`.
516
+ auto_expand (boolean, optional): When True, rioxarray's clip_box will expand clip search if only 1D raster found with clip. When False, will throw `OneDimensionalRaster` error if only 1 x or y data point is found. Defaults to True.
359
517
  nodata (int or float, optional): Overwrite dataset internal nodata value.
518
+ max_size (int, optional): Limit the size of the longest dimension of the dataset read, respecting bounds X/Y aspect ratio.
519
+ height (int, optional): Output height of the array.
520
+ width (int, optional): Output width of the array.
521
+ resampling_method (RIOResampling, optional): RasterIO resampling algorithm. Defaults to `nearest`.
360
522
 
361
523
  Returns:
362
524
  rio_tiler.models.ImageData: ImageData instance with data, mask and input spatial info.
363
525
 
364
526
  """
527
+ shape = _validate_shape_input(shape)
528
+
365
529
  if not dst_crs:
366
530
  dst_crs = shape_crs
367
531
 
368
- shape = _validate_shape_input(shape)
532
+ # Get BBOX of the polygon
533
+ bbox = featureBounds(shape)
369
534
 
370
- ds = self.input
371
- if nodata is not None:
372
- ds = ds.rio.write_nodata(nodata)
535
+ img = self.part(
536
+ bbox,
537
+ dst_crs=dst_crs,
538
+ bounds_crs=shape_crs,
539
+ nodata=nodata,
540
+ max_size=max_size,
541
+ width=width,
542
+ height=height,
543
+ reproject_method=reproject_method,
544
+ resampling_method=resampling_method,
545
+ )
373
546
 
374
- ds = ds.rio.clip([shape], crs=shape_crs)
547
+ if dst_crs != shape_crs:
548
+ shape = transform_geom(shape_crs, dst_crs, shape)
375
549
 
376
- if dst_crs != self.crs:
377
- dst_transform, w, h = calculate_default_transform(
378
- self.crs,
379
- dst_crs,
380
- ds.rio.width,
381
- ds.rio.height,
382
- *ds.rio.bounds(),
383
- )
384
- ds = ds.rio.reproject(
385
- dst_crs,
386
- shape=(h, w),
387
- transform=dst_transform,
388
- resampling=Resampling[reproject_method],
389
- nodata=nodata,
550
+ with warnings.catch_warnings():
551
+ warnings.filterwarnings(
552
+ "ignore",
553
+ category=NotGeoreferencedWarning,
554
+ module="rasterio",
390
555
  )
391
-
392
- # Forward valid_min/valid_max to the ImageData object
393
- minv, maxv = ds.attrs.get("valid_min"), ds.attrs.get("valid_max")
394
- stats = None
395
- if minv is not None and maxv is not None:
396
- stats = ((minv, maxv),) * ds.rio.count
397
-
398
- arr = ds.to_masked_array()
399
- arr.mask |= arr.data == ds.rio.nodata
400
-
401
- return ImageData(
402
- arr,
403
- bounds=ds.rio.bounds(),
404
- crs=ds.rio.crs,
405
- dataset_statistics=stats,
406
- band_names=self.band_names,
407
- )
556
+ cutline_mask = rasterize(
557
+ [shape],
558
+ out_shape=(img.height, img.width),
559
+ transform=img.transform,
560
+ all_touched=True, # Mandatory for matching masks at different resolutions
561
+ default_value=0,
562
+ fill=1,
563
+ dtype="uint8",
564
+ ).astype("bool")
565
+
566
+ img.cutline_mask = cutline_mask
567
+ img.array.mask = numpy.where(~cutline_mask, img.array.mask, True)
568
+
569
+ return img
@@ -3,7 +3,17 @@
3
3
  import math
4
4
  import warnings
5
5
  from io import BytesIO
6
- from typing import Any, Dict, Generator, List, Optional, Sequence, Tuple, Union
6
+ from typing import (
7
+ Any,
8
+ Callable,
9
+ Dict,
10
+ Generator,
11
+ List,
12
+ Optional,
13
+ Sequence,
14
+ Tuple,
15
+ Union,
16
+ )
7
17
 
8
18
  import numpy
9
19
  import rasterio
@@ -642,12 +652,15 @@ def pansharpening_brovey(
642
652
  def _convert_to_raster_space(
643
653
  src_dst: Union[DatasetReader, DatasetWriter, WarpedVRT],
644
654
  poly_coordinates: List,
655
+ op: Optional[Callable[[float], Any]] = None,
645
656
  ) -> List[str]:
657
+ # NOTE: we could remove this once we have rasterio >= 1.4.2
658
+ op = op or numpy.floor
646
659
  polygons = []
647
660
  for point in poly_coordinates:
648
661
  xs, ys = zip(*coords(point))
649
- src_y, src_x = rowcol(src_dst.transform, xs, ys)
650
- polygon = ", ".join([f"{x} {y}" for x, y in list(zip(src_x, src_y))])
662
+ src_y, src_x = rowcol(src_dst.transform, xs, ys, op=op)
663
+ polygon = ", ".join([f"{int(x)} {int(y)}" for x, y in list(zip(src_x, src_y))])
651
664
  polygons.append(f"({polygon})")
652
665
 
653
666
  return polygons
@@ -657,6 +670,7 @@ def create_cutline(
657
670
  src_dst: Union[DatasetReader, DatasetWriter, WarpedVRT],
658
671
  geometry: Dict,
659
672
  geometry_crs: CRS = None,
673
+ op: Optional[Callable[[float], Any]] = None,
660
674
  ) -> str:
661
675
  """
662
676
  Create WKT Polygon Cutline for GDALWarpOptions.
@@ -678,13 +692,13 @@ def create_cutline(
678
692
  geometry = transform_geom(geometry_crs, src_dst.crs, geometry)
679
693
 
680
694
  if geom_type == "Polygon":
681
- polys = ",".join(_convert_to_raster_space(src_dst, geometry["coordinates"]))
695
+ polys = ",".join(_convert_to_raster_space(src_dst, geometry["coordinates"], op))
682
696
  wkt = f"POLYGON ({polys})"
683
697
 
684
698
  elif geom_type == "MultiPolygon":
685
699
  multi_polys = []
686
700
  for poly in geometry["coordinates"]:
687
- polys = ",".join(_convert_to_raster_space(src_dst, poly))
701
+ polys = ",".join(_convert_to_raster_space(src_dst, poly, op))
688
702
  multi_polys.append(f"({polys})")
689
703
  str_multipoly = ",".join(multi_polys)
690
704
  wkt = f"MULTIPOLYGON ({str_multipoly})"
File without changes
File without changes
File without changes
File without changes