""" Python wrapper for downloading Planet satellite data. Can be imported and called from other Python scripts. Usage: from download_planet_missing_dates import download_missing_dates result = download_missing_dates( start_date='2023-01-01', end_date='2025-12-15', project='angata', resolution=3, dry_run=False ) if result == 0: print("Download successful!") """ import sys from pathlib import Path # Add parent directory to path so we can import the main script sys.path.insert(0, str(Path(__file__).parent)) from download_planet_missing_dates import main, get_config, setup_paths, get_existing_dates from download_planet_missing_dates import get_missing_dates, setup_bbox_list, is_image_available from download_planet_missing_dates import download_function, merge_files import datetime def download_missing_dates(start_date, end_date, project='angata', resolution=3, dry_run=False): """ Download missing Planet satellite dates. Args: start_date (str): Start date in YYYY-MM-DD format end_date (str): End date in YYYY-MM-DD format project (str): Project name (default: angata) resolution (int): Resolution in meters (default: 3) dry_run (bool): If True, show what would be downloaded without downloading Returns: int: 0 on success, 1 on error """ print("="*80) print("PLANET SATELLITE DATA DOWNLOADER - MISSING DATES ONLY") print("="*80) # Parse dates try: start = datetime.datetime.strptime(start_date, "%Y-%m-%d").date() end = datetime.datetime.strptime(end_date, "%Y-%m-%d").date() except ValueError as e: print(f"ERROR: Invalid date format: {e}") return 1 print(f"\nConfiguration:") print(f" Start date: {start}") print(f" End date: {end}") print(f" Project: {project}") print(f" Resolution: {resolution}m") if dry_run: print(f" Mode: DRY-RUN") # Setup paths paths = setup_paths(project) print(f"\nPaths:") print(f" Merged TIFs: {paths['merged_tifs']}") # Check GeoJSON exists if not paths['geojson'].exists(): print(f"\nERROR: GeoJSON not found at {paths['geojson']}") return 1 # Get existing and missing dates print(f"\nScanning existing dates...") existing_dates = get_existing_dates(paths['merged_tifs']) print(f" Found {len(existing_dates)} existing dates") missing_dates = get_missing_dates(start, end, existing_dates) print(f" {len(missing_dates)} dates to download") if not missing_dates: print("\n✓ All dates already downloaded!") return 0 print(f"\n Date range: {missing_dates[0]} to {missing_dates[-1]}") if dry_run: print("\n[DRY-RUN] Would download the above dates") return 0 # Setup BBox list print(f"\nLoading field geometries...") bbox_list = setup_bbox_list(paths['geojson'], resolution=resolution) if bbox_list is None: return 1 print(f" Created {len(bbox_list)} BBox tiles") # Download and merge print(f"\nDownloading {len(missing_dates)} missing dates...") print(f"{'='*80}") from download_planet_missing_dates import byoc, config, catalog, collection_id, bbox_to_dimensions success_count = 0 for i, slot in enumerate(missing_dates, 1): print(f"\n[{i}/{len(missing_dates)}] Processing {slot}...") if not is_image_available(slot, bbox_list, collection_id): print(f" Skipping {slot}") continue print(f" Downloading {len(bbox_list)} tiles...") for bbox in bbox_list: size = bbox_to_dimensions(bbox, resolution=resolution) download_function(slot, bbox, size, paths['single_images']) print(f" Merging tiles...") if merge_files(slot, paths['single_images'], paths['merged_tifs'], paths['virtual_raster']): success_count += 1 print(f"\n{'='*80}") print(f"Successfully processed: {success_count}/{len(missing_dates)} dates") return 0 if __name__ == "__main__": # Example usage result = download_missing_dates( start_date='2023-01-01', end_date='2025-12-15', project='angata', dry_run=False ) sys.exit(result)