33from typing import List , Tuple , Union
44
55# Thresholds
6- POLYGON_AREA_THRESHOLD_KM2 = 2500 # AOI > 2500 km² triggers spatial tiling
7- DATE_RANGE_THRESHOLD_DAYS = 30 # Polygons: split if range >30 days
8- POINT_DATE_THRESHOLD_DAYS = 3 * 365 # Points: split if range >3 years (~1095 days)
9- MAX_SCENES_PER_REQUEST = 500 # Max scenes per slice
6+ POLYGON_AREA_THRESHOLD_KM2 = 2500
7+ DATE_RANGE_THRESHOLD_DAYS = 30
8+ POINT_DATE_THRESHOLD_DAYS = 3 * 365
9+ MAX_SCENES_PER_REQUEST = 500
1010
1111
1212def estimate_scene_count (days : int , avg_scenes_per_day : float = 1.0 ) -> int :
@@ -17,64 +17,58 @@ def estimate_scene_count(days: int, avg_scenes_per_day: float = 1.0) -> int:
1717def tile_dates (
1818 start : datetime , end : datetime , is_point : bool = False
1919) -> List [Tuple [datetime , datetime ]]:
20- (
21- " Break a date range into smaller slices if it exceeds thresholds. Args: start:"
22- "start datetime end: end datetime is_point: True if the input is a point, False"
23- "for polygons/AOIs Returns: List of (start, end) tuples"
24- )
20+ """Break a date range into smaller slices if it exceeds thresholds.
21+
22+ Args:
23+ start: Start datetime
24+ end: End datetime
25+ is_point: True if input is a point, False for polygons/AOIs
26+
27+ Returns:
28+ List of (start, end) tuples
29+ """
2530 total_days = (end - start ).days + 1
2631 slices = []
2732
28- # Determine threshold
29- threshold_days = (
30- POINT_DATE_THRESHOLD_DAYS if is_point else DATE_RANGE_THRESHOLD_DAYS
31- )
33+ threshold_days = POINT_DATE_THRESHOLD_DAYS if is_point else DATE_RANGE_THRESHOLD_DAYS
3234 if total_days <= threshold_days :
3335 return [(start , end )]
3436
35- # Split into slices
3637 slice_length = min (threshold_days , total_days )
3738 current_start = start
3839 while current_start <= end :
3940 current_end = min (current_start + timedelta (days = slice_length - 1 ), end )
4041 slices .append ((current_start , current_end ))
4142 current_start = current_end + timedelta (days = 1 )
43+
4244 return slices
4345
4446
4547def tile_aoi (geom : Union [Polygon , Point ]) -> List [Polygon ]:
46- (
47- " Split a polygon into ~1°x1° tiles if AOI is large. Points are returned as"
48- "buffered polygons automatically. Args: geom: AOI polygon or point Returns:"
49- "List of Polygons for API requests"
50- )
48+ """Split a polygon into ~1°x1° tiles if AOI is large. Points are returned as buffered polygons."""
5149 if isinstance (geom , Point ):
52- # buffer a small area around the point (~0.01 degrees)
5350 return [geom .buffer (0.01 )]
5451
55- # Check area (approximation using degrees -> km²)
5652 lon_min , lat_min , lon_max , lat_max = geom .bounds
5753 area_km2 = (lon_max - lon_min ) * (lat_max - lat_min ) * 111 ** 2
5854 if area_km2 <= POLYGON_AREA_THRESHOLD_KM2 :
5955 return [geom ]
6056
61- # Split polygon into 1°x1° tiles
6257 tiles = []
6358 lat = lat_min
6459 while lat < lat_max :
6560 lon = lon_min
6661 while lon < lon_max :
67- tile = Polygon (
68- [
69- (lon , lat ),
70- (min (lon + 1 , lon_max ), lat ),
71- (min (lon + 1 , lon_max ), min (lat + 1 , lat_max )),
72- (lon , min (lat + 1 , lat_max )),
73- ]
74- )
62+ tile = Polygon ([
63+ (lon , lat ),
64+ (min (lon + 1 , lon_max ), lat ),
65+ (min (lon + 1 , lon_max ), min (lat + 1 , lat_max )),
66+ (lon , min (lat + 1 , lat_max )),
67+ ])
7568 tiles .append (tile .intersection (geom ))
7669 lon += 1
7770 lat += 1
71+
7872 return tiles
7973
8074
@@ -85,10 +79,7 @@ def fetch_planet_data(
8579 max_cloud : float = 0.5 ,
8680 min_sun_angle : float = 0.0 ,
8781):
88- (
89- " Main entry point to fetch Planet data, automatically tiling AOIs or temporal"
90- "ranges when thresholds are exceeded. Returns: ids, geometries, properties"
91- )
82+ """Main entry point to fetch Planet data, automatically tiling AOIs or temporal ranges."""
9283 ids , geometries , properties = [], [], []
9384
9485 for geom in aois :
@@ -100,16 +91,12 @@ def fetch_planet_data(
10091 date_slices = tile_dates (start , end , is_point = is_point )
10192
10293 for s_start , s_end in date_slices :
103- # Call the Planet API here (simplified)
104- # response = session.get(..., params=
105- # {geom: tile, dates: s_start->s_end})
106- # Extract ids, geometries, properties
107- # For demonstration, we(
108- "ll append mock data ids.append(f" scene_ {s_start .strftime ((
109- " )%Y%m%d')}("
110- )) geometries .append (tile .__geo_interface__ ) properties .append ( {(
111- " )cloud_cover"
112- ): max_cloud , "sun_angle" : min_sun_angle }
113- )
114-
115- return ids , geometries , properties
94+ # Mock data for demonstration
95+ ids .append (f"scene_{ s_start .strftime ('%Y%m%d' )} " )
96+ geometries .append (tile .__geo_interface__ )
97+ properties .append ({
98+ "cloud_cover" : max_cloud ,
99+ "sun_angle" : min_sun_angle
100+ })
101+
102+ return ids , geometries , properties
0 commit comments