Skip to content

Commit 081d308

Browse files
authored
Update filters.py
designed to integrate with the new CLI and handle multiple AOIs, multiple date ranges, cloud cover, and sun angle thresholds. It’s fully modular, type hinted, and ready for tiling/pagination.
1 parent b963e7b commit 081d308

File tree

1 file changed

+124
-22
lines changed

1 file changed

+124
-22
lines changed

filters.py

Lines changed: 124 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,132 @@
1-
from typing import Dict
1+
"""
2+
filters.py
3+
Builds Planet API search filters dynamically for multiple AOIs, multiple date ranges,
4+
cloud cover, and sun angle thresholds.
5+
"""
26

3-
def build_filters(start_date: str,
4-
end_date: str,
5-
max_cloud: float) -> Dict:
7+
from datetime import datetime
8+
from typing import List, Tuple, Dict, Any
9+
from shapely.geometry import Polygon, mapping
10+
11+
def geometry_filter(aoi: Polygon) -> Dict[str, Any]:
12+
"""
13+
Convert a shapely Polygon into a Planet GeometryFilter.
14+
15+
Args:
16+
aoi (Polygon): The area of interest.
17+
18+
Returns:
19+
dict: GeometryFilter for Planet API.
20+
"""
21+
return {
22+
"type": "GeometryFilter",
23+
"field_name": "geometry",
24+
"config": mapping(aoi)
25+
}
26+
27+
28+
def date_range_filter(start: datetime, end: datetime) -> Dict[str, Any]:
29+
"""
30+
Convert a start/end datetime into a Planet DateRangeFilter.
31+
32+
Args:
33+
start (datetime): Start date.
34+
end (datetime): End date.
35+
36+
Returns:
37+
dict: DateRangeFilter for Planet API.
38+
"""
39+
return {
40+
"type": "DateRangeFilter",
41+
"field_name": "acquired",
42+
"config": {
43+
"gte": start.strftime("%Y-%m-%dT00:00:00.000Z"),
44+
"lte": end.strftime("%Y-%m-%dT23:59:59.999Z")
45+
}
46+
}
47+
48+
49+
def cloud_cover_filter(max_cloud: float) -> Dict[str, Any]:
50+
"""
51+
Filter scenes by maximum cloud cover fraction.
52+
53+
Args:
54+
max_cloud (float): Max cloud fraction (0.0-1.0).
55+
56+
Returns:
57+
dict: RangeFilter for cloud_cover.
658
"""
7-
Build Planet API search filter.
59+
return {
60+
"type": "RangeFilter",
61+
"field_name": "cloud_cover",
62+
"config": {"lte": max_cloud}
63+
}
64+
65+
66+
def sun_angle_filter(min_sun_angle: float) -> Dict[str, Any]:
867
"""
68+
Filter scenes by minimum sun angle.
969
10-
if not 0 <= max_cloud <= 1:
11-
raise ValueError("max_cloud must be between 0 and 1.")
70+
Args:
71+
min_sun_angle (float): Minimum sun angle in degrees.
1272
73+
Returns:
74+
dict: RangeFilter for sun elevation.
75+
"""
1376
return {
77+
"type": "RangeFilter",
78+
"field_name": "sun_elevation",
79+
"config": {"gte": min_sun_angle}
80+
}
81+
82+
83+
def build_filters(
84+
aois: List[Polygon],
85+
date_ranges: List[Tuple[datetime, datetime]],
86+
max_cloud: float = 0.5,
87+
min_sun_angle: float = 0.0
88+
) -> Dict[str, Any]:
89+
"""
90+
Build a Planet API search filter combining multiple AOIs, date ranges,
91+
cloud cover, and sun angle constraints.
92+
93+
Args:
94+
aois (List[Polygon]): List of AOI polygons.
95+
date_ranges (List[Tuple[datetime, datetime]]): List of start/end date tuples.
96+
max_cloud (float): Maximum cloud fraction.
97+
min_sun_angle (float): Minimum sun elevation in degrees.
98+
99+
Returns:
100+
dict: Combined Planet API filter ready for pagination.
101+
"""
102+
# Combine multiple AOIs with OrFilter
103+
if len(aois) == 1:
104+
geom_filter = geometry_filter(aois[0])
105+
else:
106+
geom_filter = {
107+
"type": "OrFilter",
108+
"config": [geometry_filter(a) for a in aois]
109+
}
110+
111+
# Combine multiple date ranges with OrFilter
112+
if len(date_ranges) == 1:
113+
date_filter = date_range_filter(date_ranges[0][0], date_ranges[0][1])
114+
else:
115+
date_filter = {
116+
"type": "OrFilter",
117+
"config": [date_range_filter(start, end) for start, end in date_ranges]
118+
}
119+
120+
# Combine quality filters
121+
quality_filters = [
122+
cloud_cover_filter(max_cloud),
123+
sun_angle_filter(min_sun_angle)
124+
]
125+
126+
# Combine everything with AndFilter
127+
combined_filter = {
14128
"type": "AndFilter",
15-
"config": [
16-
{
17-
"type": "DateRangeFilter",
18-
"field_name": "acquired",
19-
"config": {
20-
"gte": f"{start_date}T00:00:00.000Z",
21-
"lte": f"{end_date}T23:59:59.999Z"
22-
}
23-
},
24-
{
25-
"type": "RangeFilter",
26-
"field_name": "cloud_cover",
27-
"config": {"lte": max_cloud}
28-
}
29-
]
129+
"config": [geom_filter, date_filter] + quality_filters
30130
}
131+
132+
return combined_filter

0 commit comments

Comments
 (0)