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.
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/CHANGELOG.md +6 -6
- {pygeofetch-2.2.0/pygeofetch.egg-info → pygeofetch-2.4.0}/PKG-INFO +3 -3
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/__init__.py +2 -2
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/main.py +2 -2
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/unwrap.py +97 -4
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/meta.yaml +1 -1
- {pygeofetch-2.2.0 → pygeofetch-2.4.0/pygeofetch.egg-info}/PKG-INFO +3 -3
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/requires.txt +2 -2
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pyproject.toml +3 -3
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_pgv_integration_contract.py +1 -1
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/LICENSE +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/MANIFEST.in +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/README.md +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/__init__.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/auth_commands.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/config_commands.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/download_commands.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/index_commands.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/pipeline_process_commands.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/postprocess_commands.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/preprocess_commands.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/sar_commands.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/cli/search_commands.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/config/__init__.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/config/defaults.yaml +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/config/settings.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/__init__.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/authenticator.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/cache_manager.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/downloader.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/engine.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/logging.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/orbits.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/scheduler.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/core/searcher.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/__init__.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/analysis.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/annotation.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/atmosphere.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/coregister.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/deburst.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/esd.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/extraction.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/flatearth.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/geolocation.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/gpu.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/interferogram.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/ionosphere.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/preflight.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/provenance.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/splitspectrum_diagnostic.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/stack_selection.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/synthetic.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/timeseries.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/validate.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/visualize.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/insar/workflow.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/models/__init__.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/models/download_task.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/models/satellite_data.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/models/search_query.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/models/user_auth.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/__init__.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/base.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/batch.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/indices.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/pipeline.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/postprocessor.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/preprocessor.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processing/sar.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processor/__init__.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processor/indices.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processor/landsat.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processor/loader.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processor/stacker.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/processor/timeseries.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/__init__.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/airbus_oneatlas.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/alaska_satellite_facility.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/aws_earth.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/base.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/copernicus.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/copernicus_nodes.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/digitalglobe.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/earth_explorer_additional.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/element84.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/eodag_provider.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/esa_scihub.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/geoserver_generic.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/google_earth_engine.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/inpe_cbers.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/isro_bhuvan.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/jaxa_earth.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/maxar_gbdx.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/nasa_earthdata.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/nasa_earthdata_cloud.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/noaa_big_data.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/opentopography.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/planet.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/planetary_computer.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/sentinel_hub.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/terrabotics.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/providers/usgs.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/sar/__init__.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/sar/_native.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/sar/_ost.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/sar/_sarxarray.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/sar/extraction.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/sar/processor.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/__init__.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/file_utils.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/gcp_recovery.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/geo_utils.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/logging_setup.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/retry_handler.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/utils/validators.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/viz/__init__.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/viz/map.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch/viz/plot.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/SOURCES.txt +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/dependency_links.txt +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/entry_points.txt +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/not-zip-safe +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/pygeofetch.egg-info/top_level.txt +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/setup.cfg +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_atmospheric_circular_regression (1).py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_atmospheric_circular_regression.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_build_sbas_network.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_burst_metadata.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_burst_processing_integration.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_burst_sync_large_gap.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_burst_sync_prescreening.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_burst_synchronization.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_copernicus_nodes.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_coregister_integration.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_coregister_upgrades.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_era5_atmospheric_correction.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_extraction.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_flat_earth_phase.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_gcp_reprojection.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_insar.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_ionosphere.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_map_preview_consolidation.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_models.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_preflight_gate (1).py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_preflight_gate.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_provider_geometry_audit (1).py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_provider_geometry_audit.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_provider_scene_disambiguation.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_providers.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_raster_collocation_integration.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_reference_pixel_and_despike.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_risk_mapping.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_screen_stack_orchestration.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_search_download.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_splitspectrum_diagnostic.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_stack_selection_consolidation.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_topo_r2_bug.py +0 -0
- {pygeofetch-2.2.0 → pygeofetch-2.4.0}/tests/test_utils.py +0 -0
- {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.
|
|
4
|
+
Format follows [Keep a Changelog](https://keepachangelog.com/en/2.4.0/).
|
|
5
5
|
|
|
6
|
-
## [2.
|
|
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.
|
|
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.
|
|
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.
|
|
192
|
-
| **2.
|
|
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
|
+
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.
|
|
95
|
-
Requires-Dist: whiteboxgui>=2.
|
|
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
|
+
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.
|
|
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
|
+
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.
|
|
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
|
-
|
|
405
|
-
|
|
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,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pygeofetch
|
|
3
|
-
Version: 2.
|
|
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.
|
|
95
|
-
Requires-Dist: whiteboxgui>=2.
|
|
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"
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pygeofetch"
|
|
7
|
-
version = "2.
|
|
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.
|
|
98
|
-
"whiteboxgui>=2.
|
|
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.
|
|
1156
|
+
# Contract version: PyGeoVision v2.4.0 / PyGeoFetch patch July 2026
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|