0

Sometimes searching for scenes over a large date range is necessary to obtain cloud-free images, but can be prohibitively slow for satellites with high revisit rates (e.g. Sentinel-2).

Is there a simple way to search for scenes with scenes.search to only return scenes within less cloudy time periods (e.g. summer) at the location?

4

There are a few ways to search or filter for cloud-free imagery over a date range. For some products (including Sentinel-2), there is a cloud_fraction property that can be used to filter out cloudy Scenes. The start_datetime and end_datetime arguments can be used to filter by the date the imagery was acquired. Using dl.scenes.search, you will want to modify the limit argument, which defaults to 100:

import descarteslabs as dl

scenes, ctx = dl.scenes.search(
    aoi.geometry,
    products='sentinel-2:L1C',
    start_datetime='2019-05-01',
    end_datetime='2019-08-01',
    cloud_fraction=0.1,
    limit=None
)

You can also search across multiple years and filter the results afterwards:

scenes, ctx = dl.scenes.search(
    aoi.geometry,
    products='sentinel-2:L1C',
    start_datetime='2015-01-01',
    cloud_fraction=0.1,
    limit=None
)

summer_scenes = scenes.filter(lambda scene: 5 <= scene.properties.date.month <= 7)

To limit the number of Scenes thrown out in the filter step, you can also consider looping over years of interest and searching over the months you need along with filtering by cloud_fraction.


To select a specific date range from each year between the start and end date, you can string a series of queries together to supply to the query argument for a single Scenes.search call:

# construct query ('2010-05-31' < date < '2010-08-31') | ('2011-05-31' < date < '2011-08-31') | ...
query = None
for year in range(2010, 2020):
    query = (query | (f'{year}-05-31' < dl.properties.acquired < f'{year}-08-31') 
            if query is not None else (f'{year}-05-31' < dl.properties.acquired < f'{year}-08-31'))

scenes, ctx = dl.scenes.search(
    aoi.geometry,
    products='sentinel-2:L1C',
    cloud_fraction=0.1,
    query=query,
    limit=None
)

If your AOI is very large, that may slow down your search. In that case, you might also consider tiling the region and searching over each tile:

tiles = dl.scenes.DLTile.from_shape(
    aoi.geometry,
    tilesize=1000,
    resolution=10.,
    pad=0
)

Disclosure: I am on the Customer Success team at Descartes Labs

4
  • Thanks for the tips. The issue with just using cloud fraction is that scenes.search is still slow even when using a small fraction. I'm wondering if it's possible to reduce the search space to make this faster. Is it possible to supply more than one contiguous time range to scenes.search? E.g. search over the same 3month period in both 2018 and 2019. Maybe this wouldn't be any faster than just filtering after? Then I could determine the ideal date ranges based on the lat/lon, and hopefully make the scenes.search call faster than searching over the full date range. – Jeremy Irvin Jul 26 '20 at 7:51
  • Understood; see edits to the answer. I added some code to search for Scenes between two dates for each year in the input list. Typically, search is quite performant, so this may be a situation where tiling the AOI will help to limit the geographic extent of each search. – Jay Carlson Jul 27 '20 at 20:45
  • Got it. Turns out that the main bottleneck was actually the mosaic, not the scenes.search. Any tips on how to speed that up would be really appreciated! Planning on trying reduce the number of scenes for now. Thanks for your help again. – Jeremy Irvin Jul 30 '20 at 4:20
  • You're correct that reducing the number of scenes to be mosaicked will speed a mosaic call up. If you have additional questions about that approach, please feel free to ask another question on that subject! – Jay Carlson Jul 31 '20 at 18:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.