pygeofetch 2.2.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.2.0 → pygeofetch-2.4.0}/CHANGELOG.md +6 -6
  2. {pygeofetch-2.2.0/pygeofetch.egg-info → pygeofetch-2.4.0}/PKG-INFO +3 -3
  3. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/__init__.py +2 -2
  4. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/main.py +2 -2
  5. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/unwrap.py +97 -4
  6. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/meta.yaml +1 -1
  7. {pygeofetch-2.2.0 → pygeofetch-2.4.0/pygeofetch.egg-info}/PKG-INFO +3 -3
  8. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/requires.txt +2 -2
  9. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pyproject.toml +3 -3
  10. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_pgv_integration_contract.py +1 -1
  11. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/LICENSE +0 -0
  12. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/MANIFEST.in +0 -0
  13. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/README.md +0 -0
  14. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/__init__.py +0 -0
  15. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/auth_commands.py +0 -0
  16. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/config_commands.py +0 -0
  17. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/download_commands.py +0 -0
  18. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/index_commands.py +0 -0
  19. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/pipeline_process_commands.py +0 -0
  20. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/postprocess_commands.py +0 -0
  21. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/preprocess_commands.py +0 -0
  22. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/sar_commands.py +0 -0
  23. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/search_commands.py +0 -0
  24. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/config/__init__.py +0 -0
  25. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/config/defaults.yaml +0 -0
  26. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/config/settings.py +0 -0
  27. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/__init__.py +0 -0
  28. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/authenticator.py +0 -0
  29. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/cache_manager.py +0 -0
  30. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/downloader.py +0 -0
  31. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/engine.py +0 -0
  32. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/logging.py +0 -0
  33. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/orbits.py +0 -0
  34. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/scheduler.py +0 -0
  35. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/searcher.py +0 -0
  36. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/__init__.py +0 -0
  37. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/analysis.py +0 -0
  38. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/annotation.py +0 -0
  39. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/atmosphere.py +0 -0
  40. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/coregister.py +0 -0
  41. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/deburst.py +0 -0
  42. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/esd.py +0 -0
  43. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/extraction.py +0 -0
  44. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/flatearth.py +0 -0
  45. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/geolocation.py +0 -0
  46. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/gpu.py +0 -0
  47. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/interferogram.py +0 -0
  48. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/ionosphere.py +0 -0
  49. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/preflight.py +0 -0
  50. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/provenance.py +0 -0
  51. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/splitspectrum_diagnostic.py +0 -0
  52. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/stack_selection.py +0 -0
  53. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/synthetic.py +0 -0
  54. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/timeseries.py +0 -0
  55. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/validate.py +0 -0
  56. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/visualize.py +0 -0
  57. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/workflow.py +0 -0
  58. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/models/__init__.py +0 -0
  59. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/models/download_task.py +0 -0
  60. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/models/satellite_data.py +0 -0
  61. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/models/search_query.py +0 -0
  62. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/models/user_auth.py +0 -0
  63. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/__init__.py +0 -0
  64. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/base.py +0 -0
  65. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/batch.py +0 -0
  66. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/indices.py +0 -0
  67. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/pipeline.py +0 -0
  68. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/postprocessor.py +0 -0
  69. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/preprocessor.py +0 -0
  70. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/sar.py +0 -0
  71. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processor/__init__.py +0 -0
  72. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processor/indices.py +0 -0
  73. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processor/landsat.py +0 -0
  74. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processor/loader.py +0 -0
  75. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processor/stacker.py +0 -0
  76. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processor/timeseries.py +0 -0
  77. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/__init__.py +0 -0
  78. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/airbus_oneatlas.py +0 -0
  79. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/alaska_satellite_facility.py +0 -0
  80. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/aws_earth.py +0 -0
  81. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/base.py +0 -0
  82. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/copernicus.py +0 -0
  83. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/copernicus_nodes.py +0 -0
  84. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/digitalglobe.py +0 -0
  85. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/earth_explorer_additional.py +0 -0
  86. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/element84.py +0 -0
  87. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/eodag_provider.py +0 -0
  88. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/esa_scihub.py +0 -0
  89. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/geoserver_generic.py +0 -0
  90. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/google_earth_engine.py +0 -0
  91. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/inpe_cbers.py +0 -0
  92. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/isro_bhuvan.py +0 -0
  93. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/jaxa_earth.py +0 -0
  94. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/maxar_gbdx.py +0 -0
  95. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/nasa_earthdata.py +0 -0
  96. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/nasa_earthdata_cloud.py +0 -0
  97. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/noaa_big_data.py +0 -0
  98. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/opentopography.py +0 -0
  99. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/planet.py +0 -0
  100. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/planetary_computer.py +0 -0
  101. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/sentinel_hub.py +0 -0
  102. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/terrabotics.py +0 -0
  103. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/usgs.py +0 -0
  104. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/sar/__init__.py +0 -0
  105. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/sar/_native.py +0 -0
  106. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/sar/_ost.py +0 -0
  107. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/sar/_sarxarray.py +0 -0
  108. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/sar/extraction.py +0 -0
  109. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/sar/processor.py +0 -0
  110. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/__init__.py +0 -0
  111. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/file_utils.py +0 -0
  112. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/gcp_recovery.py +0 -0
  113. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/geo_utils.py +0 -0
  114. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/logging_setup.py +0 -0
  115. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/retry_handler.py +0 -0
  116. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/validators.py +0 -0
  117. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/viz/__init__.py +0 -0
  118. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/viz/map.py +0 -0
  119. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/viz/plot.py +0 -0
  120. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/SOURCES.txt +0 -0
  121. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/dependency_links.txt +0 -0
  122. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/entry_points.txt +0 -0
  123. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/not-zip-safe +0 -0
  124. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/top_level.txt +0 -0
  125. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/setup.cfg +0 -0
  126. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_atmospheric_circular_regression (1).py +0 -0
  127. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_atmospheric_circular_regression.py +0 -0
  128. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_build_sbas_network.py +0 -0
  129. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_burst_metadata.py +0 -0
  130. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_burst_processing_integration.py +0 -0
  131. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_burst_sync_large_gap.py +0 -0
  132. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_burst_sync_prescreening.py +0 -0
  133. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_burst_synchronization.py +0 -0
  134. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_copernicus_nodes.py +0 -0
  135. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_coregister_integration.py +0 -0
  136. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_coregister_upgrades.py +0 -0
  137. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_era5_atmospheric_correction.py +0 -0
  138. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_extraction.py +0 -0
  139. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_flat_earth_phase.py +0 -0
  140. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_gcp_reprojection.py +0 -0
  141. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_insar.py +0 -0
  142. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_ionosphere.py +0 -0
  143. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_map_preview_consolidation.py +0 -0
  144. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_models.py +0 -0
  145. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_preflight_gate (1).py +0 -0
  146. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_preflight_gate.py +0 -0
  147. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_provider_geometry_audit (1).py +0 -0
  148. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_provider_geometry_audit.py +0 -0
  149. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_provider_scene_disambiguation.py +0 -0
  150. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_providers.py +0 -0
  151. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_raster_collocation_integration.py +0 -0
  152. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_reference_pixel_and_despike.py +0 -0
  153. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_risk_mapping.py +0 -0
  154. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_screen_stack_orchestration.py +0 -0
  155. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_search_download.py +0 -0
  156. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_splitspectrum_diagnostic.py +0 -0
  157. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_stack_selection_consolidation.py +0 -0
  158. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_topo_r2_bug.py +0 -0
  159. {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_utils.py +0 -0
  160. {pygeofetch-2.2.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.2.0/).
4
+ Format follows [Keep a Changelog](https://keepachangelog.com/en/2.4.0/).
5
5
 
6
- ## [2.2.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.2.0/).
51
51
 
52
52
  ### Migration Guide
53
53
  ```python
54
- # Before (v2.2.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.2.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.2.0** | 2026-07-29 | SNAPHU unwrapping fixes, 87.1% reliable pixels |
192
- | **2.2.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.2.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.2.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.2.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.2.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.2.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
@@ -370,6 +371,7 @@ class PhaseUnwrapper:
370
371
  igram.tofile(str(igram_path))
371
372
  corr.tofile(str(corr_path))
372
373
  nlooks_int = max(1, int(nlooks))
374
+
373
375
  conf_text = f"""INFILE igram.cpx
374
376
  INFILEFORMAT COMPLEX_DATA
375
377
  CORRFILE corr.cor
@@ -377,7 +379,6 @@ CORRFILEFORMAT FLOAT_DATA
377
379
  OUTFILE unw.unw
378
380
  OUTFILEFORMAT FLOAT_DATA
379
381
  CONNCOMPFILE conncomp.cc
380
- CONNCOMPOUTFORMAT UINT_DATA
381
382
  LINELENGTH {width}
382
383
  STATCOSTMODE {self._cost_mode.upper()}
383
384
  INITMETHOD {self._init_method.upper()}
@@ -401,8 +402,44 @@ NLOOKSAZ {nlooks_int}
401
402
  if result.returncode != 0:
402
403
  raise RuntimeError(f"SNAPHU CLI failed with code {result.returncode}: {result.stderr}")
403
404
 
404
- unw = np.fromfile(str(unw_path), dtype=np.float32).reshape((height, width))
405
- 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))
406
443
 
407
444
  total_pixels = height * width
408
445
  labels, counts = np.unique(conncomp, return_counts=True)
@@ -411,6 +448,7 @@ NLOOKSAZ {nlooks_int}
411
448
  if count < min_region_size or (count / total_pixels) < min_conncomp_frac:
412
449
  conncomp[conncomp == lbl] = 0
413
450
  return unw, conncomp.astype(np.int32)
451
+
414
452
 
415
453
  def _ensure_runtime_dlls(self, bin_dir: Path):
416
454
  import shutil, zipfile, io, urllib.request
@@ -585,4 +623,59 @@ NLOOKSAZ {nlooks_int}
585
623
 
586
624
  def _np(self):
587
625
  import numpy as np
588
- 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.2.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.2.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.2.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.2.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