pygeofetch 2.3.0__tar.gz → 2.4.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 (160) hide show
  1. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/CHANGELOG.md +6 -6
  2. {pygeofetch-2.3.0/pygeofetch.egg-info → pygeofetch-2.4.0}/PKG-INFO +3 -3
  3. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/__init__.py +2 -2
  4. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/cli/main.py +2 -2
  5. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/unwrap.py +95 -8
  6. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/meta.yaml +1 -1
  7. {pygeofetch-2.3.0 → pygeofetch-2.4.0/pygeofetch.egg-info}/PKG-INFO +3 -3
  8. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/requires.txt +2 -2
  9. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pyproject.toml +3 -3
  10. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_pgv_integration_contract.py +1 -1
  11. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/LICENSE +0 -0
  12. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/MANIFEST.in +0 -0
  13. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/README.md +0 -0
  14. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/cli/__init__.py +0 -0
  15. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/cli/auth_commands.py +0 -0
  16. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/cli/config_commands.py +0 -0
  17. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/cli/download_commands.py +0 -0
  18. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/cli/index_commands.py +0 -0
  19. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/cli/pipeline_process_commands.py +0 -0
  20. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/cli/postprocess_commands.py +0 -0
  21. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/cli/preprocess_commands.py +0 -0
  22. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/cli/sar_commands.py +0 -0
  23. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/cli/search_commands.py +0 -0
  24. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/config/__init__.py +0 -0
  25. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/config/defaults.yaml +0 -0
  26. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/config/settings.py +0 -0
  27. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/core/__init__.py +0 -0
  28. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/core/authenticator.py +0 -0
  29. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/core/cache_manager.py +0 -0
  30. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/core/downloader.py +0 -0
  31. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/core/engine.py +0 -0
  32. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/core/logging.py +0 -0
  33. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/core/orbits.py +0 -0
  34. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/core/scheduler.py +0 -0
  35. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/core/searcher.py +0 -0
  36. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/__init__.py +0 -0
  37. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/analysis.py +0 -0
  38. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/annotation.py +0 -0
  39. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/atmosphere.py +0 -0
  40. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/coregister.py +0 -0
  41. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/deburst.py +0 -0
  42. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/esd.py +0 -0
  43. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/extraction.py +0 -0
  44. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/flatearth.py +0 -0
  45. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/geolocation.py +0 -0
  46. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/gpu.py +0 -0
  47. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/interferogram.py +0 -0
  48. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/ionosphere.py +0 -0
  49. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/preflight.py +0 -0
  50. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/provenance.py +0 -0
  51. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/splitspectrum_diagnostic.py +0 -0
  52. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/stack_selection.py +0 -0
  53. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/synthetic.py +0 -0
  54. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/timeseries.py +0 -0
  55. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/validate.py +0 -0
  56. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/visualize.py +0 -0
  57. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/insar/workflow.py +0 -0
  58. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/models/__init__.py +0 -0
  59. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/models/download_task.py +0 -0
  60. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/models/satellite_data.py +0 -0
  61. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/models/search_query.py +0 -0
  62. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/models/user_auth.py +0 -0
  63. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processing/__init__.py +0 -0
  64. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processing/base.py +0 -0
  65. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processing/batch.py +0 -0
  66. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processing/indices.py +0 -0
  67. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processing/pipeline.py +0 -0
  68. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processing/postprocessor.py +0 -0
  69. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processing/preprocessor.py +0 -0
  70. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processing/sar.py +0 -0
  71. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processor/__init__.py +0 -0
  72. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processor/indices.py +0 -0
  73. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processor/landsat.py +0 -0
  74. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processor/loader.py +0 -0
  75. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processor/stacker.py +0 -0
  76. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/processor/timeseries.py +0 -0
  77. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/__init__.py +0 -0
  78. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/airbus_oneatlas.py +0 -0
  79. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/alaska_satellite_facility.py +0 -0
  80. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/aws_earth.py +0 -0
  81. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/base.py +0 -0
  82. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/copernicus.py +0 -0
  83. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/copernicus_nodes.py +0 -0
  84. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/digitalglobe.py +0 -0
  85. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/earth_explorer_additional.py +0 -0
  86. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/element84.py +0 -0
  87. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/eodag_provider.py +0 -0
  88. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/esa_scihub.py +0 -0
  89. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/geoserver_generic.py +0 -0
  90. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/google_earth_engine.py +0 -0
  91. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/inpe_cbers.py +0 -0
  92. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/isro_bhuvan.py +0 -0
  93. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/jaxa_earth.py +0 -0
  94. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/maxar_gbdx.py +0 -0
  95. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/nasa_earthdata.py +0 -0
  96. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/nasa_earthdata_cloud.py +0 -0
  97. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/noaa_big_data.py +0 -0
  98. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/opentopography.py +0 -0
  99. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/planet.py +0 -0
  100. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/planetary_computer.py +0 -0
  101. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/sentinel_hub.py +0 -0
  102. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/terrabotics.py +0 -0
  103. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/providers/usgs.py +0 -0
  104. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/sar/__init__.py +0 -0
  105. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/sar/_native.py +0 -0
  106. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/sar/_ost.py +0 -0
  107. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/sar/_sarxarray.py +0 -0
  108. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/sar/extraction.py +0 -0
  109. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/sar/processor.py +0 -0
  110. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/utils/__init__.py +0 -0
  111. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/utils/file_utils.py +0 -0
  112. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/utils/gcp_recovery.py +0 -0
  113. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/utils/geo_utils.py +0 -0
  114. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/utils/logging_setup.py +0 -0
  115. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/utils/retry_handler.py +0 -0
  116. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/utils/validators.py +0 -0
  117. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/viz/__init__.py +0 -0
  118. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/viz/map.py +0 -0
  119. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch/viz/plot.py +0 -0
  120. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/SOURCES.txt +0 -0
  121. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/dependency_links.txt +0 -0
  122. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/entry_points.txt +0 -0
  123. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/not-zip-safe +0 -0
  124. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/top_level.txt +0 -0
  125. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/setup.cfg +0 -0
  126. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_atmospheric_circular_regression (1).py +0 -0
  127. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_atmospheric_circular_regression.py +0 -0
  128. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_build_sbas_network.py +0 -0
  129. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_burst_metadata.py +0 -0
  130. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_burst_processing_integration.py +0 -0
  131. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_burst_sync_large_gap.py +0 -0
  132. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_burst_sync_prescreening.py +0 -0
  133. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_burst_synchronization.py +0 -0
  134. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_copernicus_nodes.py +0 -0
  135. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_coregister_integration.py +0 -0
  136. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_coregister_upgrades.py +0 -0
  137. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_era5_atmospheric_correction.py +0 -0
  138. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_extraction.py +0 -0
  139. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_flat_earth_phase.py +0 -0
  140. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_gcp_reprojection.py +0 -0
  141. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_insar.py +0 -0
  142. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_ionosphere.py +0 -0
  143. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_map_preview_consolidation.py +0 -0
  144. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_models.py +0 -0
  145. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_preflight_gate (1).py +0 -0
  146. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_preflight_gate.py +0 -0
  147. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_provider_geometry_audit (1).py +0 -0
  148. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_provider_geometry_audit.py +0 -0
  149. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_provider_scene_disambiguation.py +0 -0
  150. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_providers.py +0 -0
  151. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_raster_collocation_integration.py +0 -0
  152. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_reference_pixel_and_despike.py +0 -0
  153. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_risk_mapping.py +0 -0
  154. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_screen_stack_orchestration.py +0 -0
  155. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_search_download.py +0 -0
  156. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_splitspectrum_diagnostic.py +0 -0
  157. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_stack_selection_consolidation.py +0 -0
  158. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_topo_r2_bug.py +0 -0
  159. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_utils.py +0 -0
  160. {pygeofetch-2.3.0 → pygeofetch-2.4.0}/tests/test_viz_plot.py +0 -0
@@ -1,9 +1,9 @@
1
1
  # Changelog
2
2
 
3
3
  All notable changes to PyGeoFetch are documented here.
4
- Format follows [Keep a Changelog](https://keepachangelog.com/en/2.3.0/).
4
+ Format follows [Keep a Changelog](https://keepachangelog.com/en/2.4.0/).
5
5
 
6
- ## [2.3.0] — 2026-07-29
6
+ ## [2.4.0] — 2026-07-29
7
7
 
8
8
  ### Added
9
9
  - Major SNAPHU unwrapping improvements for urban InSAR applications
@@ -51,7 +51,7 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/2.3.0/).
51
51
 
52
52
  ### Migration Guide
53
53
  ```python
54
- # Before (v2.3.0)
54
+ # Before (v2.4.0)
55
55
  unwrapper = PhaseUnwrapper(cost_mode="defo", init_method="mcf")
56
56
  unwrapped = unwrapper.unwrap(phase, coherence, nlooks=2.0)
57
57
 
@@ -72,7 +72,7 @@ unwrapped = unwrapper.unwrap(
72
72
 
73
73
  ---
74
74
 
75
- ## [2.3.0] — 2026-07-12
75
+ ## [2.4.0] — 2026-07-12
76
76
 
77
77
  ### Added
78
78
  - Federated search across 22+ satellite data providers
@@ -188,8 +188,8 @@ unwrapped = unwrapper.unwrap(
188
188
 
189
189
  | Version | Date | Key Changes |
190
190
  |---------|------------|-------------|
191
- | **2.3.0** | 2026-07-29 | SNAPHU unwrapping fixes, 87.1% reliable pixels |
192
- | **2.3.0** | 2026-07-12 | 22 providers, 17 indices, Sentinel-1C/D |
191
+ | **2.4.0** | 2026-07-29 | SNAPHU unwrapping fixes, 87.1% reliable pixels |
192
+ | **2.4.0** | 2026-07-12 | 22 providers, 17 indices, Sentinel-1C/D |
193
193
  | **1.9.2** | 2026-06-15 | Batch processing, parallel downloads |
194
194
  | **1.9.1** | 2026-05-20 | 3D terrain, SNAPHU integration, time series |
195
195
  | **1.9.0** | 2026-04-25 | Initial public release |
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pygeofetch
3
- Version: 2.3.0
3
+ Version: 2.4.0
4
4
  Summary: Universal satellite data pipeline + geospatial processing platform
5
5
  Author-email: Samuel Appiah Kubi <appiahkubis14@gmail.com>
6
6
  License: MIT License
@@ -91,8 +91,8 @@ Requires-Dist: sidecar>=0.6.0; extra == "viz"
91
91
  Requires-Dist: bokeh>=3.0.0; extra == "viz"
92
92
  Requires-Dist: seaborn>=0.12.0; extra == "viz"
93
93
  Requires-Dist: plotly>=5.14.0; extra == "viz"
94
- Requires-Dist: whitebox>=2.3.0; extra == "viz"
95
- Requires-Dist: whiteboxgui>=2.3.0; extra == "viz"
94
+ Requires-Dist: whitebox>=2.4.0; extra == "viz"
95
+ Requires-Dist: whiteboxgui>=2.4.0; extra == "viz"
96
96
  Requires-Dist: geemap>=0.28.0; extra == "viz"
97
97
  Requires-Dist: osmnx>=1.9.4; extra == "viz"
98
98
  Requires-Dist: contextily>=1.9.4; extra == "viz"
@@ -1,5 +1,5 @@
1
1
  """
2
- PyGeoFetch v2.3.0 — Universal Satellite Data Pipeline.
2
+ PyGeoFetch v2.4.0 — Universal Satellite Data Pipeline.
3
3
 
4
4
  Unified access to 22+ satellite data providers with a consistent
5
5
  Python API and CLI. Supports authentication management, federated search,
@@ -30,7 +30,7 @@ CLI::
30
30
  pygeofetch doctor
31
31
  """
32
32
 
33
- __version__ = "2.3.0"
33
+ __version__ = "2.4.0"
34
34
  __author__ = "PyGeoFetch Contributors"
35
35
  __license__ = "MIT"
36
36
 
@@ -1,5 +1,5 @@
1
1
  """
2
- PyGeoFetch CLI v2.3.0 main entry point.
2
+ PyGeoFetch CLI v2.4.0 main entry point.
3
3
 
4
4
  Full command reference:
5
5
  pygeofetch auth — credential management
@@ -71,7 +71,7 @@ def cli(
71
71
  ) -> None:
72
72
  """
73
73
  \b
74
- PyGeoFetch v2.3.0 — Universal Satellite Data Pipeline
74
+ PyGeoFetch v2.4.0 — Universal Satellite Data Pipeline
75
75
  ===========================================================
76
76
  Unified access to 22+ satellite data providers.
77
77
 
@@ -356,6 +356,7 @@ class PhaseUnwrapper:
356
356
 
357
357
  def _unwrap_cli(self, igram, corr, nlooks, min_conncomp_frac, min_region_size):
358
358
  import numpy as np
359
+ import os
359
360
  cli_path = _ensure_snaphu_cli()
360
361
  height, width = igram.shape
361
362
  bin_dir = Path(cli_path).parent
@@ -371,10 +372,6 @@ class PhaseUnwrapper:
371
372
  corr.tofile(str(corr_path))
372
373
  nlooks_int = max(1, int(nlooks))
373
374
 
374
- # FIX: Removed 'CONNCOMPOUTFORMAT UINT_DATA'. It is not a valid
375
- # SNAPHU parameter. SNAPHU always writes connected components as
376
- # 32-bit unsigned integers by default. The strict Windows port
377
- # we use rejects the config file if it sees unknown keys.
378
375
  conf_text = f"""INFILE igram.cpx
379
376
  INFILEFORMAT COMPLEX_DATA
380
377
  CORRFILE corr.cor
@@ -396,7 +393,6 @@ NLOOKSAZ {nlooks_int}
396
393
  with tempfile.TemporaryDirectory() as tmp_dir:
397
394
  result, unw_path, cc_path = _run_snaphu(tmp_dir)
398
395
 
399
- # AUTO-REPAIR: Catch Windows STATUS_DLL_NOT_FOUND (0xC0000135)
400
396
  if result.returncode in (3221225781, -1073741515):
401
397
  logger.warning("SNAPHU crashed with STATUS_DLL_NOT_FOUND (0xC0000135). Auto-bundling runtime DLLs...")
402
398
  self._ensure_runtime_dlls(bin_dir)
@@ -406,8 +402,44 @@ NLOOKSAZ {nlooks_int}
406
402
  if result.returncode != 0:
407
403
  raise RuntimeError(f"SNAPHU CLI failed with code {result.returncode}: {result.stderr}")
408
404
 
409
- unw = np.fromfile(str(unw_path), dtype=np.float32).reshape((height, width))
410
- conncomp = np.fromfile(str(cc_path), dtype=np.uint32).reshape((height, width))
405
+ # ═══════════════════════════════════════════════════════════════
406
+ # SMART FILE READER (Handles Windows Port Quirks)
407
+ # ═══════════════════════════════════════════════════════════════
408
+ expected_pixels = height * width
409
+
410
+ # 1. Read Unwrapped Phase (Usually FLOAT_DATA = 4 bytes)
411
+ unw_size = os.path.getsize(str(unw_path))
412
+ unw_dtype = np.float32 if unw_size <= expected_pixels * 4 else np.float64
413
+ unw = np.fromfile(str(unw_path), dtype=unw_dtype)
414
+
415
+ # 2. Read Connected Components (Adapts to 1-byte, 2-byte, or 4-byte formats)
416
+ cc_size = os.path.getsize(str(cc_path))
417
+ if cc_size >= expected_pixels * 4:
418
+ cc_dtype = np.uint32
419
+ elif cc_size >= expected_pixels * 2:
420
+ cc_dtype = np.uint16
421
+ else:
422
+ cc_dtype = np.uint8 # The Windows port default
423
+
424
+ conncomp = np.fromfile(str(cc_path), dtype=cc_dtype)
425
+
426
+ # 3. Auto-heal the Windows "off-by-one" truncation bug
427
+ if conncomp.size < expected_pixels:
428
+ logger.warning(
429
+ "SNAPHU conncomp file is %d elements, expected %d. Padding missing bytes with 0 "
430
+ "(known Windows port truncation quirk).", conncomp.size, expected_pixels
431
+ )
432
+ conncomp = np.pad(conncomp, (0, expected_pixels - conncomp.size), mode='constant', constant_values=0)
433
+ elif conncomp.size > expected_pixels:
434
+ conncomp = conncomp[:expected_pixels]
435
+
436
+ if unw.size < expected_pixels:
437
+ unw = np.pad(unw, (0, expected_pixels - unw.size), mode='constant', constant_values=0)
438
+ elif unw.size > expected_pixels:
439
+ unw = unw[:expected_pixels]
440
+
441
+ unw = unw.reshape((height, width))
442
+ conncomp = conncomp.reshape((height, width))
411
443
 
412
444
  total_pixels = height * width
413
445
  labels, counts = np.unique(conncomp, return_counts=True)
@@ -591,4 +623,59 @@ NLOOKSAZ {nlooks_int}
591
623
 
592
624
  def _np(self):
593
625
  import numpy as np
594
- return np
626
+ return np
627
+
628
+
629
+ import shutil
630
+ import subprocess
631
+ import logging
632
+ import sys
633
+
634
+ logger = logging.getLogger(__name__)
635
+
636
+ def verify_snaphu_ready():
637
+ """
638
+ Proactively checks for snaphu availability to assure the user
639
+ that no manual installation is required.
640
+ """
641
+ # 1. Check for the standard SNAPHU binary in the system PATH
642
+ snaphu_bin = shutil.which("snaphu")
643
+ if snaphu_bin:
644
+ # Optional: Verify the binary actually executes and isn't just a broken alias
645
+ try:
646
+ subprocess.run(
647
+ ["snaphu"],
648
+ stdout=subprocess.DEVNULL,
649
+ stderr=subprocess.DEVNULL,
650
+ timeout=3
651
+ )
652
+ except Exception:
653
+ pass # Snaphu without args prints usage to stderr and exits; this is expected.
654
+
655
+ msg = f"✅ Success: snaphu binary detected at '{snaphu_bin}'. No manual installation needed."
656
+ print(msg)
657
+ logger.info(msg)
658
+ return True
659
+
660
+ # 2. Fallback: Check if it's available as a Python package/module
661
+ try:
662
+ import snaphu # or pysnaphu, depending on your wrapper
663
+ msg = "✅ Success: snaphu Python module detected. No manual installation needed."
664
+ print(msg)
665
+ logger.info(msg)
666
+ return True
667
+ except ImportError:
668
+ pass
669
+
670
+ # 3. If neither is found, handle the failure gracefully
671
+ msg = "❌ snaphu not found in PATH or Python environment. Phase unwrapping will fail."
672
+ print(msg)
673
+ logger.warning(msg)
674
+ return False
675
+
676
+ # --- Embed this early in your notebook or pipeline ---
677
+ snaphu_is_ready = verify_snaphu_ready()
678
+
679
+ if not snaphu_is_ready:
680
+ # Decide how to handle the missing dependency (see questions below)
681
+ pass
@@ -1,4 +1,4 @@
1
- {% set version = "2.3.0" %}
1
+ {% set version = "2.4.0" %}
2
2
 
3
3
  package:
4
4
  name: pygeofetch
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pygeofetch
3
- Version: 2.3.0
3
+ Version: 2.4.0
4
4
  Summary: Universal satellite data pipeline + geospatial processing platform
5
5
  Author-email: Samuel Appiah Kubi <appiahkubis14@gmail.com>
6
6
  License: MIT License
@@ -91,8 +91,8 @@ Requires-Dist: sidecar>=0.6.0; extra == "viz"
91
91
  Requires-Dist: bokeh>=3.0.0; extra == "viz"
92
92
  Requires-Dist: seaborn>=0.12.0; extra == "viz"
93
93
  Requires-Dist: plotly>=5.14.0; extra == "viz"
94
- Requires-Dist: whitebox>=2.3.0; extra == "viz"
95
- Requires-Dist: whiteboxgui>=2.3.0; extra == "viz"
94
+ Requires-Dist: whitebox>=2.4.0; extra == "viz"
95
+ Requires-Dist: whiteboxgui>=2.4.0; extra == "viz"
96
96
  Requires-Dist: geemap>=0.28.0; extra == "viz"
97
97
  Requires-Dist: osmnx>=1.9.4; extra == "viz"
98
98
  Requires-Dist: contextily>=1.9.4; extra == "viz"
@@ -85,8 +85,8 @@ sidecar>=0.6.0
85
85
  bokeh>=3.0.0
86
86
  seaborn>=0.12.0
87
87
  plotly>=5.14.0
88
- whitebox>=2.3.0
89
- whiteboxgui>=2.3.0
88
+ whitebox>=2.4.0
89
+ whiteboxgui>=2.4.0
90
90
  geemap>=0.28.0
91
91
  osmnx>=1.9.4
92
92
  contextily>=1.9.4
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pygeofetch"
7
- version = "2.3.0"
7
+ version = "2.4.0"
8
8
  description = "Universal satellite data pipeline + geospatial processing platform"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -94,8 +94,8 @@ viz = [
94
94
  "bokeh>=3.0.0",
95
95
  "seaborn>=0.12.0",
96
96
  "plotly>=5.14.0",
97
- "whitebox>=2.3.0",
98
- "whiteboxgui>=2.3.0",
97
+ "whitebox>=2.4.0",
98
+ "whiteboxgui>=2.4.0",
99
99
  "geemap>=0.28.0",
100
100
  "osmnx>=1.9.4",
101
101
  "contextily>=1.9.4",
@@ -1153,4 +1153,4 @@ class TestFinalEngineSmoke:
1153
1153
 
1154
1154
  # ── Contract footer ───────────────────────────────────────────────────────────
1155
1155
  # PyGeoVision integration contract: ALL TESTS MUST PASS
1156
- # Contract version: PyGeoVision v2.3.0 / PyGeoFetch patch July 2026
1156
+ # Contract version: PyGeoVision v2.4.0 / PyGeoFetch patch July 2026
File without changes
File without changes
File without changes
File without changes