rio-tiler 7.8.1__tar.gz → 7.9.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 (243) hide show
  1. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/PKG-INFO +1 -1
  2. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/pyproject.toml +1 -1
  3. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/__init__.py +1 -1
  4. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/io/xarray.py +121 -76
  5. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/reader.py +1 -22
  6. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/utils.py +22 -0
  7. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/.gitignore +0 -0
  8. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/AUTHORS.txt +0 -0
  9. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/LICENSE +0 -0
  10. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/README.md +0 -0
  11. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/__init__.py +0 -0
  12. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/accent.npy +0 -0
  13. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/accent_r.npy +0 -0
  14. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/afmhot.npy +0 -0
  15. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/afmhot_r.npy +0 -0
  16. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/algae.npy +0 -0
  17. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/algae_r.npy +0 -0
  18. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/amp.npy +0 -0
  19. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/amp_r.npy +0 -0
  20. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/autumn.npy +0 -0
  21. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/autumn_r.npy +0 -0
  22. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/balance.npy +0 -0
  23. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/balance_r.npy +0 -0
  24. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/binary.npy +0 -0
  25. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/binary_r.npy +0 -0
  26. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/blues.npy +0 -0
  27. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/blues_r.npy +0 -0
  28. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/bone.npy +0 -0
  29. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/bone_r.npy +0 -0
  30. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/brbg.npy +0 -0
  31. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/brbg_r.npy +0 -0
  32. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/brg.npy +0 -0
  33. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/brg_r.npy +0 -0
  34. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/bugn.npy +0 -0
  35. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/bugn_r.npy +0 -0
  36. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/bupu.npy +0 -0
  37. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/bupu_r.npy +0 -0
  38. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/bwr.npy +0 -0
  39. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/bwr_r.npy +0 -0
  40. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/cfastie.npy +0 -0
  41. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/cividis.npy +0 -0
  42. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/cividis_r.npy +0 -0
  43. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/cmrmap.npy +0 -0
  44. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/cmrmap_r.npy +0 -0
  45. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/cool.npy +0 -0
  46. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/cool_r.npy +0 -0
  47. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/coolwarm.npy +0 -0
  48. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/coolwarm_r.npy +0 -0
  49. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/copper.npy +0 -0
  50. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/copper_r.npy +0 -0
  51. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/cubehelix.npy +0 -0
  52. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/cubehelix_r.npy +0 -0
  53. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/curl.npy +0 -0
  54. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/curl_r.npy +0 -0
  55. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/dark2.npy +0 -0
  56. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/dark2_r.npy +0 -0
  57. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/deep.npy +0 -0
  58. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/deep_r.npy +0 -0
  59. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/delta.npy +0 -0
  60. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/delta_r.npy +0 -0
  61. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/dense.npy +0 -0
  62. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/dense_r.npy +0 -0
  63. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/diff.npy +0 -0
  64. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/diff_r.npy +0 -0
  65. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/flag.npy +0 -0
  66. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/flag_r.npy +0 -0
  67. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_earth.npy +0 -0
  68. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_earth_r.npy +0 -0
  69. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_gray.npy +0 -0
  70. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_gray_r.npy +0 -0
  71. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_heat.npy +0 -0
  72. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_heat_r.npy +0 -0
  73. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_ncar.npy +0 -0
  74. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_ncar_r.npy +0 -0
  75. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_rainbow.npy +0 -0
  76. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_rainbow_r.npy +0 -0
  77. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_stern.npy +0 -0
  78. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_stern_r.npy +0 -0
  79. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_yarg.npy +0 -0
  80. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gist_yarg_r.npy +0 -0
  81. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gnbu.npy +0 -0
  82. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gnbu_r.npy +0 -0
  83. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gnuplot.npy +0 -0
  84. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gnuplot2.npy +0 -0
  85. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gnuplot2_r.npy +0 -0
  86. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gnuplot_r.npy +0 -0
  87. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gray.npy +0 -0
  88. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/gray_r.npy +0 -0
  89. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/greens.npy +0 -0
  90. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/greens_r.npy +0 -0
  91. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/greys.npy +0 -0
  92. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/greys_r.npy +0 -0
  93. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/haline.npy +0 -0
  94. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/haline_r.npy +0 -0
  95. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/hot.npy +0 -0
  96. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/hot_r.npy +0 -0
  97. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/hsv.npy +0 -0
  98. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/hsv_r.npy +0 -0
  99. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/ice.npy +0 -0
  100. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/ice_r.npy +0 -0
  101. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/inferno.npy +0 -0
  102. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/inferno_r.npy +0 -0
  103. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/jet.npy +0 -0
  104. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/jet_r.npy +0 -0
  105. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/magma.npy +0 -0
  106. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/magma_r.npy +0 -0
  107. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/matter.npy +0 -0
  108. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/matter_r.npy +0 -0
  109. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/nipy_spectral.npy +0 -0
  110. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/nipy_spectral_r.npy +0 -0
  111. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/ocean.npy +0 -0
  112. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/ocean_r.npy +0 -0
  113. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/oranges.npy +0 -0
  114. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/oranges_r.npy +0 -0
  115. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/orrd.npy +0 -0
  116. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/orrd_r.npy +0 -0
  117. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/oxy.npy +0 -0
  118. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/oxy_r.npy +0 -0
  119. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/paired.npy +0 -0
  120. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/paired_r.npy +0 -0
  121. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/pastel1.npy +0 -0
  122. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/pastel1_r.npy +0 -0
  123. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/pastel2.npy +0 -0
  124. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/pastel2_r.npy +0 -0
  125. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/phase.npy +0 -0
  126. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/phase_r.npy +0 -0
  127. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/pink.npy +0 -0
  128. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/pink_r.npy +0 -0
  129. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/piyg.npy +0 -0
  130. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/piyg_r.npy +0 -0
  131. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/plasma.npy +0 -0
  132. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/plasma_r.npy +0 -0
  133. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/prgn.npy +0 -0
  134. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/prgn_r.npy +0 -0
  135. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/prism.npy +0 -0
  136. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/prism_r.npy +0 -0
  137. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/pubu.npy +0 -0
  138. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/pubu_r.npy +0 -0
  139. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/pubugn.npy +0 -0
  140. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/pubugn_r.npy +0 -0
  141. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/puor.npy +0 -0
  142. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/puor_r.npy +0 -0
  143. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/purd.npy +0 -0
  144. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/purd_r.npy +0 -0
  145. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/purples.npy +0 -0
  146. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/purples_r.npy +0 -0
  147. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rain.npy +0 -0
  148. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rain_r.npy +0 -0
  149. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rainbow.npy +0 -0
  150. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rainbow_r.npy +0 -0
  151. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rdbu.npy +0 -0
  152. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rdbu_r.npy +0 -0
  153. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rdgy.npy +0 -0
  154. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rdgy_r.npy +0 -0
  155. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rdpu.npy +0 -0
  156. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rdpu_r.npy +0 -0
  157. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rdylbu.npy +0 -0
  158. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rdylbu_r.npy +0 -0
  159. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rdylgn.npy +0 -0
  160. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rdylgn_r.npy +0 -0
  161. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/reds.npy +0 -0
  162. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/reds_r.npy +0 -0
  163. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/rplumbo.npy +0 -0
  164. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/schwarzwald.npy +0 -0
  165. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/seismic.npy +0 -0
  166. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/seismic_r.npy +0 -0
  167. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/set1.npy +0 -0
  168. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/set1_r.npy +0 -0
  169. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/set2.npy +0 -0
  170. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/set2_r.npy +0 -0
  171. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/set3.npy +0 -0
  172. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/set3_r.npy +0 -0
  173. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/solar.npy +0 -0
  174. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/solar_r.npy +0 -0
  175. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/spectral.npy +0 -0
  176. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/spectral_r.npy +0 -0
  177. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/speed.npy +0 -0
  178. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/speed_r.npy +0 -0
  179. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/spring.npy +0 -0
  180. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/spring_r.npy +0 -0
  181. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/summer.npy +0 -0
  182. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/summer_r.npy +0 -0
  183. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/tab10.npy +0 -0
  184. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/tab10_r.npy +0 -0
  185. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/tab20.npy +0 -0
  186. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/tab20_r.npy +0 -0
  187. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/tab20b.npy +0 -0
  188. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/tab20b_r.npy +0 -0
  189. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/tab20c.npy +0 -0
  190. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/tab20c_r.npy +0 -0
  191. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/tarn.npy +0 -0
  192. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/tarn_r.npy +0 -0
  193. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/tempo.npy +0 -0
  194. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/tempo_r.npy +0 -0
  195. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/terrain.npy +0 -0
  196. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/terrain_r.npy +0 -0
  197. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/thermal.npy +0 -0
  198. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/thermal_r.npy +0 -0
  199. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/topo.npy +0 -0
  200. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/topo_r.npy +0 -0
  201. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/turbid.npy +0 -0
  202. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/turbid_r.npy +0 -0
  203. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/turbo.npy +0 -0
  204. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/turbo_r.npy +0 -0
  205. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/twilight.npy +0 -0
  206. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/twilight_r.npy +0 -0
  207. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/twilight_shifted.npy +0 -0
  208. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/twilight_shifted_r.npy +0 -0
  209. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/viridis.npy +0 -0
  210. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/viridis_r.npy +0 -0
  211. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/winter.npy +0 -0
  212. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/winter_r.npy +0 -0
  213. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/wistia.npy +0 -0
  214. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/wistia_r.npy +0 -0
  215. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/ylgn.npy +0 -0
  216. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/ylgn_r.npy +0 -0
  217. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/ylgnbu.npy +0 -0
  218. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/ylgnbu_r.npy +0 -0
  219. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/ylorbr.npy +0 -0
  220. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/ylorbr_r.npy +0 -0
  221. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/ylorrd.npy +0 -0
  222. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/cmap_data/ylorrd_r.npy +0 -0
  223. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/colormap.py +0 -0
  224. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/constants.py +0 -0
  225. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/errors.py +0 -0
  226. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/experimental/__init__.py +0 -0
  227. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/experimental/vsifile.py +0 -0
  228. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/expression.py +0 -0
  229. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/io/__init__.py +0 -0
  230. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/io/base.py +0 -0
  231. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/io/rasterio.py +0 -0
  232. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/io/stac.py +0 -0
  233. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/logger.py +0 -0
  234. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/models.py +0 -0
  235. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/mosaic/__init__.py +0 -0
  236. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/mosaic/methods/__init__.py +0 -0
  237. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/mosaic/methods/base.py +0 -0
  238. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/mosaic/methods/defaults.py +0 -0
  239. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/mosaic/reader.py +0 -0
  240. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/profiles.py +0 -0
  241. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/py.typed +0 -0
  242. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/tasks.py +0 -0
  243. {rio_tiler-7.8.1 → rio_tiler-7.9.0}/rio_tiler/types.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rio-tiler
3
- Version: 7.8.1
3
+ Version: 7.9.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/
@@ -161,7 +161,7 @@ exclude = [
161
161
  max-complexity = 14
162
162
 
163
163
  [tool.bumpversion]
164
- current_version = "7.8.1"
164
+ current_version = "7.9.0"
165
165
  parse = """(?x)
166
166
  (?P<major>\\d+)\\.
167
167
  (?P<minor>\\d+)\\.
@@ -1,6 +1,6 @@
1
1
  """rio-tiler."""
2
2
 
3
- __version__ = "7.8.1"
3
+ __version__ = "7.9.0"
4
4
 
5
5
  from . import ( # noqa
6
6
  colormap,
@@ -2,12 +2,14 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import math
5
6
  import warnings
6
7
  from typing import Any, Dict, List, Optional, Tuple
7
8
 
8
9
  import attr
9
10
  import numpy
10
11
  from morecantile import Tile, TileMatrixSet
12
+ from rasterio import windows
11
13
  from rasterio.crs import CRS
12
14
  from rasterio.enums import Resampling
13
15
  from rasterio.errors import NotGeoreferencedWarning
@@ -16,9 +18,9 @@ from rasterio.features import rasterize
16
18
  from rasterio.transform import from_bounds, rowcol
17
19
  from rasterio.warp import calculate_default_transform
18
20
  from rasterio.warp import transform as transform_coords
19
- from rasterio.warp import transform_geom
21
+ from rasterio.warp import transform_bounds, transform_geom
20
22
 
21
- from rio_tiler.constants import WEB_MERCATOR_TMS, WGS84_CRS
23
+ from rio_tiler.constants import WEB_MERCATOR_CRS, WEB_MERCATOR_TMS, WGS84_CRS
22
24
  from rio_tiler.errors import (
23
25
  InvalidGeographicBounds,
24
26
  MissingCRS,
@@ -27,10 +29,11 @@ from rio_tiler.errors import (
27
29
  )
28
30
  from rio_tiler.io.base import BaseReader
29
31
  from rio_tiler.models import BandStatistics, ImageData, Info, PointData
30
- from rio_tiler.reader import _get_width_height
31
32
  from rio_tiler.types import BBox, Indexes, NoData, RIOResampling, WarpResampling
32
33
  from rio_tiler.utils import (
33
34
  CRS_to_uri,
35
+ _get_width_height,
36
+ _missing_size,
34
37
  _validate_shape_input,
35
38
  cast_to_sequence,
36
39
  get_array_statistics,
@@ -268,53 +271,24 @@ class XarrayReader(BaseReader):
268
271
  f"Tile(x={tile_x}, y={tile_y}, z={tile_z}) is outside bounds"
269
272
  )
270
273
 
271
- da, band_names = self._sel_indexes(indexes)
272
-
273
- if nodata is not None:
274
- da = da.rio.write_nodata(nodata)
275
-
276
274
  tile_bounds = tuple(self.tms.xy_bounds(Tile(x=tile_x, y=tile_y, z=tile_z)))
277
275
  dst_crs = self.tms.rasterio_crs
278
276
 
279
- # Create source array by clipping the xarray dataset to extent of the tile.
280
- da = da.rio.clip_box(
281
- *tile_bounds,
282
- crs=dst_crs,
277
+ return self.part(
278
+ tile_bounds,
279
+ dst_crs=dst_crs,
280
+ bounds_crs=dst_crs,
281
+ reproject_method=reproject_method,
283
282
  auto_expand=auto_expand,
284
- )
285
- da = da.rio.reproject(
286
- dst_crs,
287
- shape=(tilesize, tilesize),
288
- transform=from_bounds(*tile_bounds, height=tilesize, width=tilesize),
289
- resampling=Resampling[reproject_method],
290
283
  nodata=nodata,
284
+ indexes=indexes,
285
+ height=tilesize,
286
+ width=tilesize,
287
+ out_dtype=out_dtype,
288
+ **kwargs,
291
289
  )
292
290
 
293
- # Forward valid_min/valid_max to the ImageData object
294
- minv, maxv = da.attrs.get("valid_min"), da.attrs.get("valid_max")
295
- stats = None
296
- if minv is not None and maxv is not None and nodata not in [minv, maxv]:
297
- stats = ((minv, maxv),) * da.rio.count
298
-
299
- arr = da.to_masked_array()
300
- if out_dtype:
301
- arr = arr.astype(out_dtype)
302
- arr.mask |= arr.data == da.rio.nodata
303
-
304
- output_bounds = da.rio._unordered_bounds()
305
- if output_bounds[1] > output_bounds[3] and da.rio.transform().e > 0:
306
- yaxis = self.input.dims.index(self.input.rio.y_dim)
307
- arr = numpy.flip(arr, axis=yaxis)
308
-
309
- return ImageData(
310
- arr,
311
- bounds=tile_bounds,
312
- crs=dst_crs,
313
- dataset_statistics=stats,
314
- band_names=band_names,
315
- )
316
-
317
- def part(
291
+ def part( # noqa: C901
318
292
  self,
319
293
  bbox: BBox,
320
294
  dst_crs: Optional[CRS] = None,
@@ -348,11 +322,12 @@ class XarrayReader(BaseReader):
348
322
  rio_tiler.models.ImageData: ImageData instance with data, mask and input spatial info.
349
323
 
350
324
  """
351
- if max_size and width and height:
325
+ if max_size and (width or height):
352
326
  warnings.warn(
353
- "'max_size' will be ignored with with 'height' and 'width' set.",
327
+ "'max_size' will be ignored with with 'height' or 'width' set.",
354
328
  UserWarning,
355
329
  )
330
+ max_size = None
356
331
 
357
332
  dst_crs = dst_crs or bounds_crs
358
333
 
@@ -361,33 +336,99 @@ class XarrayReader(BaseReader):
361
336
  if nodata is not None:
362
337
  da = da.rio.write_nodata(nodata)
363
338
 
339
+ # Forward valid_min/valid_max to the ImageData object
340
+ minv, maxv = da.attrs.get("valid_min"), da.attrs.get("valid_max")
341
+ stats = None
342
+ if minv is not None and maxv is not None:
343
+ stats = ((minv, maxv),) * da.rio.count
344
+
364
345
  da = da.rio.clip_box(
365
346
  *bbox,
366
347
  crs=bounds_crs,
367
348
  auto_expand=auto_expand,
368
349
  )
369
350
 
370
- if dst_crs != self.crs:
371
- dst_transform, w, h = calculate_default_transform(
372
- self.crs,
373
- dst_crs,
374
- da.rio.width,
375
- da.rio.height,
376
- *da.rio.bounds(),
351
+ src_width = da.rio.width
352
+ src_height = da.rio.height
353
+ src_bounds = list(da.rio.bounds())
354
+ src_transform = da.rio.transform()
355
+
356
+ # Fix for https://github.com/cogeotiff/rio-tiler/issues/654
357
+ #
358
+ # When using `calculate_default_transform` with dataset
359
+ # which span at high/low latitude outside the area_of_use
360
+ # of the WebMercator projection, we `crop` the dataset
361
+ # to get the transform (resolution).
362
+ #
363
+ # Note: Should be handled in gdal 3.8 directly
364
+ # https://github.com/OSGeo/gdal/pull/8775
365
+ if (
366
+ self.crs == WGS84_CRS
367
+ and dst_crs == WEB_MERCATOR_CRS
368
+ and (src_bounds[1] < -85.06 or src_bounds[3] > 85.06)
369
+ ):
370
+ warnings.warn(
371
+ "Adjusting dataset latitudes to avoid re-projection overflow",
372
+ UserWarning,
377
373
  )
378
- da = da.rio.reproject(
379
- dst_crs,
380
- shape=(h, w),
381
- transform=dst_transform,
382
- resampling=Resampling[reproject_method],
383
- nodata=nodata,
374
+ src_bounds[1] = max(src_bounds[1], -85.06)
375
+ src_bounds[3] = min(src_bounds[3], 85.06)
376
+ w = windows.from_bounds(*src_bounds, transform=src_transform)
377
+ src_height = round(w.height)
378
+ src_width = round(w.width)
379
+
380
+ # Specific FIX when bounds and transform are inverted
381
+ # See: https://github.com/US-GHG-Center/veda-config-ghg/pull/333
382
+ elif (
383
+ self.crs == WGS84_CRS
384
+ and dst_crs == WEB_MERCATOR_CRS
385
+ and (src_bounds[1] > 85.06 or src_bounds[3] < -85.06)
386
+ ):
387
+ warnings.warn(
388
+ "Adjusting dataset latitudes to avoid re-projection overflow",
389
+ UserWarning,
384
390
  )
391
+ src_bounds[1] = min(src_bounds[1], 85.06)
392
+ src_bounds[3] = max(src_bounds[3], -85.06)
393
+ w = windows.from_bounds(*src_bounds, transform=src_transform)
394
+ src_height = round(w.height)
395
+ src_width = round(w.width)
385
396
 
386
- # Forward valid_min/valid_max to the ImageData object
387
- minv, maxv = da.attrs.get("valid_min"), da.attrs.get("valid_max")
388
- stats = None
389
- if minv is not None and maxv is not None:
390
- stats = ((minv, maxv),) * da.rio.count
397
+ if dst_crs != self.crs:
398
+ # transform of the reprojected dataset
399
+ dst_transform, _, _ = calculate_default_transform(
400
+ self.crs, dst_crs, src_width, src_height, *src_bounds
401
+ )
402
+ else:
403
+ dst_transform = from_bounds(*src_bounds, src_width, src_height)
404
+
405
+ if bounds_crs and bounds_crs != dst_crs:
406
+ bbox = transform_bounds(bounds_crs, dst_crs, *bbox, densify_pts=21)
407
+
408
+ w, s, e, n = bbox
409
+ # max size of the output dataset for the bbox
410
+ dst_width = max(1, round((e - w) / dst_transform.a))
411
+ dst_height = max(1, round((s - n) / dst_transform.e))
412
+
413
+ if max_size:
414
+ height, width = _get_width_height(max_size, dst_height, dst_width)
415
+
416
+ elif _missing_size(height, width):
417
+ ratio = dst_height / dst_width
418
+ if width:
419
+ height = math.ceil(width * ratio)
420
+ else:
421
+ width = math.ceil(height / ratio)
422
+
423
+ height = height or dst_height
424
+ width = width or dst_width
425
+ da = da.rio.reproject(
426
+ dst_crs,
427
+ shape=(height, width),
428
+ transform=from_bounds(w, s, e, n, width, height),
429
+ resampling=Resampling[reproject_method],
430
+ nodata=nodata,
431
+ )
391
432
 
392
433
  arr = da.to_masked_array()
393
434
  if out_dtype:
@@ -401,7 +442,7 @@ class XarrayReader(BaseReader):
401
442
 
402
443
  img = ImageData(
403
444
  arr,
404
- bounds=da.rio.bounds(),
445
+ bounds=bbox,
405
446
  crs=da.rio.crs,
406
447
  dataset_statistics=stats,
407
448
  band_names=band_names,
@@ -449,11 +490,12 @@ class XarrayReader(BaseReader):
449
490
  rio_tiler.models.ImageData: ImageData instance with data, mask and input spatial info.
450
491
 
451
492
  """
452
- if max_size and width and height:
493
+ if max_size and (width or height):
453
494
  warnings.warn(
454
- "'max_size' will be ignored with with 'height' and 'width' set.",
495
+ "'max_size' will be ignored with with 'height' or 'width' set.",
455
496
  UserWarning,
456
497
  )
498
+ max_size = None
457
499
 
458
500
  da, band_names = self._sel_indexes(indexes)
459
501
 
@@ -500,17 +542,18 @@ class XarrayReader(BaseReader):
500
542
  band_names=band_names,
501
543
  )
502
544
 
503
- output_height = height or img.height
504
- output_width = width or img.width
505
- if max_size and not (width and height):
506
- output_height, output_width = _get_width_height(
507
- max_size, img.height, img.width
508
- )
545
+ if max_size:
546
+ height, width = _get_width_height(max_size, img.height, img.width)
509
547
 
510
- if output_height != img.height or output_width != img.width:
511
- img = img.resize(
512
- output_height, output_width, resampling_method=resampling_method
513
- )
548
+ elif _missing_size(height, width):
549
+ ratio = img.height / img.width
550
+ if width:
551
+ height = math.ceil(width * ratio)
552
+ else:
553
+ width = math.ceil(height / ratio)
554
+
555
+ if (height and width) and (height != da.rio.height or width != da.rio.width):
556
+ img = img.resize(height, width, resampling_method=resampling_method)
514
557
 
515
558
  return img
516
559
 
@@ -622,6 +665,8 @@ class XarrayReader(BaseReader):
622
665
  reproject_method=reproject_method,
623
666
  resampling_method=resampling_method,
624
667
  out_dtype=out_dtype,
668
+ auto_expand=auto_expand,
669
+ **kwargs,
625
670
  )
626
671
 
627
672
  if dst_crs != shape_crs:
@@ -20,6 +20,7 @@ from rio_tiler.constants import WGS84_CRS
20
20
  from rio_tiler.errors import InvalidBufferSize, PointOutsideBounds, TileOutsideBounds
21
21
  from rio_tiler.models import ImageData, PointData
22
22
  from rio_tiler.types import BBox, Indexes, NoData, RIOResampling, WarpResampling
23
+ from rio_tiler.utils import _get_width_height, _missing_size
23
24
  from rio_tiler.utils import _requested_tile_aligned_with_internal_tile as is_aligned
24
25
  from rio_tiler.utils import (
25
26
  _round_window,
@@ -42,28 +43,6 @@ class Options(TypedDict, total=False):
42
43
  post_process: Optional[Callable[[numpy.ma.MaskedArray], numpy.ma.MaskedArray]]
43
44
 
44
45
 
45
- def _get_width_height(max_size, dataset_height, dataset_width) -> Tuple[int, int]:
46
- """Get Output Width/Height based on a max_size and dataset shape."""
47
- if max(dataset_height, dataset_width) < max_size:
48
- return dataset_height, dataset_width
49
-
50
- ratio = dataset_height / dataset_width
51
- if ratio > 1:
52
- height = max_size
53
- width = math.ceil(height / ratio)
54
- else:
55
- width = max_size
56
- height = math.ceil(width * ratio)
57
-
58
- return height, width
59
-
60
-
61
- def _missing_size(w: Optional[int] = None, h: Optional[int] = None):
62
- """Check if one and only one size (width, height) is valid."""
63
- iterator = iter([w, h])
64
- return any(iterator) and not any(iterator)
65
-
66
-
67
46
  def _apply_buffer(
68
47
  buffer: float,
69
48
  bounds: BBox,
@@ -43,6 +43,28 @@ def _chunks(my_list: Sequence, chuck_size: int) -> Generator[Sequence, None, Non
43
43
  yield my_list[i : i + chuck_size]
44
44
 
45
45
 
46
+ def _get_width_height(max_size, dataset_height, dataset_width) -> Tuple[int, int]:
47
+ """Get Output Width/Height based on a max_size and dataset shape."""
48
+ if max(dataset_height, dataset_width) < max_size:
49
+ return dataset_height, dataset_width
50
+
51
+ ratio = dataset_height / dataset_width
52
+ if ratio > 1:
53
+ height = max_size
54
+ width = math.ceil(height / ratio)
55
+ else:
56
+ width = max_size
57
+ height = math.ceil(width * ratio)
58
+
59
+ return height, width
60
+
61
+
62
+ def _missing_size(w: Optional[int] = None, h: Optional[int] = None):
63
+ """Check if one and only one size (width, height) is valid."""
64
+ iterator = iter([w, h])
65
+ return any(iterator) and not any(iterator)
66
+
67
+
46
68
  # Ref: https://stackoverflow.com/posts/73905572
47
69
  def _weighted_quantiles(
48
70
  values: NDArray[numpy.floating],
File without changes
File without changes
File without changes
File without changes