예제 #1
0
    def test_multi_processing(self):
        task = SentinelHubInputTask(
            bands_feature=(FeatureType.DATA, 'BANDS'),
            bands=["B01", "B02", "B03"],
            additional_data=[(FeatureType.MASK, 'dataMask')],
            size=self.size,
            maxcc=self.maxcc,
            time_difference=self.time_difference,
            data_collection=DataCollection.SENTINEL2_L1C,
            max_threads=self.max_threads
        )

        time_intervals = [
            ('2017-01-01', '2017-01-30'),
            ('2017-02-01', '2017-02-28'),
            ('2017-03-01', '2017-03-30'),
            ('2017-04-01', '2017-04-30'),
            ('2017-05-01', '2017-05-30'),
            ('2017-06-01', '2017-06-30')
        ]

        with futures.ProcessPoolExecutor(max_workers=3) as executor:
            tasks = [executor.submit(task.execute, None, self.bbox, interval) for interval in time_intervals]
            eopatches = [task.result() for task in futures.as_completed(tasks)]

        array = np.concatenate([eop.data['BANDS'] for eop in eopatches], axis=0)

        width, height = self.size
        self.assertTrue(array.shape == (20, height, width, 3))
예제 #2
0
    def test_additional_data(self):
        """ Download additional data, such as viewAzimuthMean, sunAzimuthAngles...
        """
        task = SentinelHubInputTask(bands_feature=(FeatureType.DATA, 'BANDS'),
                                    bands=['B01', 'B02', 'B05'],
                                    additional_data=[
                                        (FeatureType.MASK, 'dataMask',
                                         'IS_DATA'), (FeatureType.MASK, 'CLM'),
                                        (FeatureType.MASK, 'SCL'),
                                        (FeatureType.MASK, 'SNW'),
                                        (FeatureType.MASK, 'CLD'),
                                        (FeatureType.DATA, 'CLP'),
                                        (FeatureType.DATA, 'viewAzimuthMean',
                                         'view_azimuth_mean'),
                                        (FeatureType.DATA, 'sunAzimuthAngles'),
                                        (FeatureType.DATA, 'sunZenithAngles')
                                    ],
                                    size=self.size,
                                    maxcc=self.maxcc,
                                    time_difference=self.time_difference,
                                    data_source=DataSource.SENTINEL2_L2A,
                                    max_threads=self.max_threads)

        eopatch = task.execute(bbox=self.bbox,
                               time_interval=self.time_interval)

        bands = eopatch[(FeatureType.DATA, 'BANDS')]
        is_data = eopatch[(FeatureType.MASK, 'IS_DATA')]
        clm = eopatch[(FeatureType.MASK, 'CLM')]
        scl = eopatch[(FeatureType.MASK, 'SCL')]
        snw = eopatch[(FeatureType.MASK, 'SNW')]
        cld = eopatch[(FeatureType.MASK, 'CLD')]
        clp = eopatch[(FeatureType.DATA, 'CLP')]
        view_azimuth_mean = eopatch[(FeatureType.DATA, 'view_azimuth_mean')]
        sun_azimuth_angles = eopatch[(FeatureType.DATA, 'sunAzimuthAngles')]
        sun_zenith_angles = eopatch[(FeatureType.DATA, 'sunZenithAngles')]

        self.assertTrue(
            np.allclose(array_stats(bands), [0.027, 0.0243, 0.0162]))

        width, height = self.size
        self.assertTrue(bands.shape == (4, height, width, 3))
        self.assertTrue(is_data.shape == (4, height, width, 1))
        self.assertTrue(is_data.dtype == np.bool)
        self.assertTrue(clm.shape == (4, height, width, 1))
        self.assertTrue(clm.dtype == np.uint8)
        self.assertTrue(scl.shape == (4, height, width, 1))
        self.assertTrue(snw.shape == (4, height, width, 1))
        self.assertTrue(cld.shape == (4, height, width, 1))
        self.assertTrue(clp.shape == (4, height, width, 1))
        self.assertTrue(view_azimuth_mean.shape == (4, height, width, 1))
        self.assertTrue(sun_azimuth_angles.shape == (4, height, width, 1))
        self.assertTrue(sun_zenith_angles.shape == (4, height, width, 1))
        self.assertTrue(len(eopatch.timestamp) == 4)
    def test_additional_data(self):
        task = SentinelHubInputTask(
            bands_feature=(FeatureType.DATA, "BANDS"),
            bands=["B01", "B02", "B05"],
            additional_data=[
                (FeatureType.MASK, "dataMask", "IS_DATA"),
                (FeatureType.MASK, "CLM"),
                (FeatureType.MASK, "SCL"),
                (FeatureType.MASK, "SNW"),
                (FeatureType.MASK, "CLD"),
                (FeatureType.DATA, "CLP"),
                (FeatureType.DATA, "viewAzimuthMean", "view_azimuth_mean"),
                (FeatureType.DATA, "sunAzimuthAngles"),
                (FeatureType.DATA, "sunZenithAngles"),
            ],
            size=self.size,
            maxcc=self.maxcc,
            time_difference=self.time_difference,
            data_collection=DataCollection.SENTINEL2_L2A,
            max_threads=self.max_threads,
        )

        eopatch = task.execute(bbox=self.bbox,
                               time_interval=self.time_interval)

        bands = eopatch[(FeatureType.DATA, "BANDS")]
        is_data = eopatch[(FeatureType.MASK, "IS_DATA")]
        clm = eopatch[(FeatureType.MASK, "CLM")]
        scl = eopatch[(FeatureType.MASK, "SCL")]
        snw = eopatch[(FeatureType.MASK, "SNW")]
        cld = eopatch[(FeatureType.MASK, "CLD")]
        clp = eopatch[(FeatureType.DATA, "CLP")]
        view_azimuth_mean = eopatch[(FeatureType.DATA, "view_azimuth_mean")]
        sun_azimuth_angles = eopatch[(FeatureType.DATA, "sunAzimuthAngles")]
        sun_zenith_angles = eopatch[(FeatureType.DATA, "sunZenithAngles")]

        assert calculate_stats(bands) == approx([0.027, 0.0243, 0.0162])

        width, height = self.size
        assert bands.shape == (4, height, width, 3)
        assert is_data.shape == (4, height, width, 1)
        assert is_data.dtype == bool
        assert clm.shape == (4, height, width, 1)
        assert clm.dtype == np.uint8
        assert scl.shape == (4, height, width, 1)
        assert snw.shape == (4, height, width, 1)
        assert cld.shape == (4, height, width, 1)
        assert clp.shape == (4, height, width, 1)
        assert view_azimuth_mean.shape == (4, height, width, 1)
        assert sun_azimuth_angles.shape == (4, height, width, 1)
        assert sun_zenith_angles.shape == (4, height, width, 1)
        assert len(eopatch.timestamp) == 4
    def test_no_data_input_task_request(self):
        task = SentinelHubInputTask(
            bands_feature=(FeatureType.DATA, "BANDS"),
            additional_data=[(FeatureType.MASK, "dataMask")],
            size=self.size,
            maxcc=0.0,
            data_collection=DataCollection.SENTINEL2_L1C,
        )
        eopatch = task.execute(bbox=self.bbox,
                               time_interval=("2021-01-01", "2021-01-20"))

        bands = eopatch[FeatureType.DATA, "BANDS"]
        assert bands.shape == (0, 101, 99, 13)
        masks = eopatch[FeatureType.MASK, "dataMask"]
        assert masks.shape == (0, 101, 99, 1)
예제 #5
0
    def test_S2L1C_float32_uint16(self):
        """ Download S2L1C bands and dataMask
        """
        test_dir = os.path.dirname(os.path.realpath(__file__))
        cache_folder = os.path.join(test_dir, 'cache_test')

        if os.path.exists(cache_folder):
            shutil.rmtree(cache_folder)

        task = SentinelHubInputTask(
            bands_feature=(FeatureType.DATA, 'BANDS'),
            additional_data=[(FeatureType.MASK, 'dataMask')],
            size=self.size,
            maxcc=self.maxcc,
            time_difference=self.time_difference,
            data_collection=DataCollection.SENTINEL2_L1C,
            max_threads=self.max_threads,
            cache_folder=cache_folder)

        eopatch = task.execute(bbox=self.bbox,
                               time_interval=self.time_interval)
        bands = eopatch[(FeatureType.DATA, 'BANDS')]
        is_data = eopatch[(FeatureType.MASK, 'dataMask')]

        self.assertTrue(
            np.allclose(array_stats(bands), [0.0233, 0.0468, 0.0252]))

        width, height = self.size
        self.assertTrue(bands.shape == (4, height, width, 13))
        self.assertTrue(is_data.shape == (4, height, width, 1))
        self.assertTrue(len(eopatch.timestamp) == 4)
        self.assertTrue(bands.dtype == np.float32)

        self.assertTrue(os.path.exists(cache_folder))

        # change task's bans_dtype and run it again
        task.bands_dtype = np.uint16

        eopatch = task.execute(bbox=self.bbox,
                               time_interval=self.time_interval)
        bands = eopatch[(FeatureType.DATA, 'BANDS')]

        self.assertTrue(
            np.allclose(array_stats(bands), [232.5769, 467.5385, 251.8654]))

        self.assertTrue(bands.dtype == np.uint16)

        shutil.rmtree(cache_folder)
예제 #6
0
    def test_scl_only(self):
        """ Download just SCL, without any other bands
        """
        task = SentinelHubInputTask(
            bands_feature=None,
            additional_data=[(FeatureType.DATA, 'SCL')],
            size=self.size,
            maxcc=self.maxcc,
            time_difference=self.time_difference,
            data_collection=DataCollection.SENTINEL2_L2A,
            max_threads=self.max_threads
        )

        eopatch = task.execute(bbox=self.bbox, time_interval=self.time_interval)
        scl = eopatch[(FeatureType.DATA, 'SCL')]

        width, height = self.size
        self.assertTrue(scl.shape == (4, height, width, 1))
예제 #7
0
    def test_aux_request_args(self):
        """ Download low resolution data with `PREVIEW` mode
        """
        task = SentinelHubInputTask(
            bands_feature=(FeatureType.DATA, 'BANDS'),
            resolution=260,
            maxcc=self.maxcc,
            time_difference=self.time_difference,
            data_collection=DataCollection.SENTINEL2_L1C,
            max_threads=self.max_threads,
            aux_request_args={'dataFilter': {'previewMode': 'PREVIEW'}}
        )

        eopatch = task.execute(bbox=self.bbox, time_interval=self.time_interval)
        bands = eopatch[(FeatureType.DATA, 'BANDS')]

        self.assertTrue(bands.shape == (4, 4, 4, 13))
        self.assertTrue(np.allclose(array_stats(bands), [0.0, 0.0493, 0.0277]))
    def test_aux_request_args(self):
        """Download low resolution data with `PREVIEW` mode"""
        task = SentinelHubInputTask(
            bands_feature=(FeatureType.DATA, "BANDS"),
            resolution=260,
            maxcc=self.maxcc,
            time_difference=self.time_difference,
            data_collection=DataCollection.SENTINEL2_L1C,
            max_threads=self.max_threads,
            aux_request_args={"dataFilter": {
                "previewMode": "PREVIEW"
            }},
        )

        eopatch = task.execute(bbox=self.bbox,
                               time_interval=self.time_interval)
        bands = eopatch[(FeatureType.DATA, "BANDS")]

        assert bands.shape == (4, 4, 4, 13)
        assert calculate_stats(bands) == approx([0.0, 0.0493, 0.0277])
    def test_specific_bands(self):
        task = SentinelHubInputTask(
            bands_feature=(FeatureType.DATA, "BANDS"),
            bands=["B01", "B02", "B03"],
            additional_data=[(FeatureType.MASK, "dataMask")],
            size=self.size,
            maxcc=self.maxcc,
            time_difference=self.time_difference,
            data_collection=DataCollection.SENTINEL2_L1C,
            max_threads=self.max_threads,
        )

        eopatch = task.execute(bbox=self.bbox,
                               time_interval=self.time_interval)
        bands = eopatch[(FeatureType.DATA, "BANDS")]

        assert calculate_stats(bands) == approx([0.0648, 0.1193, 0.063])

        width, height = self.size
        assert bands.shape == (4, height, width, 3)
예제 #10
0
    def test_specific_bands(self):
        """ Download S2L1C bands and dataMask
        """
        task = SentinelHubInputTask(
            bands_feature=(FeatureType.DATA, 'BANDS'),
            bands=["B01", "B02", "B03"],
            additional_data=[(FeatureType.MASK, 'dataMask')],
            size=self.size,
            maxcc=self.maxcc,
            time_difference=self.time_difference,
            data_collection=DataCollection.SENTINEL2_L1C,
            max_threads=self.max_threads
        )

        eopatch = task.execute(bbox=self.bbox, time_interval=self.time_interval)
        bands = eopatch[(FeatureType.DATA, 'BANDS')]

        self.assertTrue(np.allclose(array_stats(bands), [0.0648, 0.1193, 0.063]))

        width, height = self.size
        self.assertTrue(bands.shape == (4, height, width, 3))
예제 #11
0
    def test_single_scene(self):
        """ Download S2L1C bands and dataMask
        """
        task = SentinelHubInputTask(
            bands_feature=(FeatureType.DATA, 'BANDS'),
            additional_data=[(FeatureType.MASK, 'dataMask')],
            size=self.size,
            maxcc=self.maxcc,
            time_difference=self.time_difference,
            data_collection=DataCollection.SENTINEL2_L1C,
            max_threads=self.max_threads,
            single_scene=True,
            mosaicking_order="leastCC"
        )

        eopatch = task.execute(bbox=self.bbox, time_interval=self.time_interval)
        bands = eopatch[(FeatureType.DATA, 'BANDS')]
        is_data = eopatch[(FeatureType.MASK, 'dataMask')]

        width, height = self.size
        self.assertTrue(bands.shape == (1, height, width, 13))
        self.assertTrue(is_data.shape == (1, height, width, 1))
        self.assertTrue(len(eopatch.timestamp) == 1)
    def test_s2l1c_float32_uint16(self, cache_folder):
        task = SentinelHubInputTask(
            bands_feature=(FeatureType.DATA, "BANDS"),
            additional_data=[(FeatureType.MASK, "dataMask")],
            size=self.size,
            maxcc=self.maxcc,
            time_difference=self.time_difference,
            data_collection=DataCollection.SENTINEL2_L1C,
            max_threads=self.max_threads,
            cache_folder=cache_folder,
        )

        eopatch = task.execute(bbox=self.bbox,
                               time_interval=self.time_interval)
        bands = eopatch[(FeatureType.DATA, "BANDS")]
        is_data = eopatch[(FeatureType.MASK, "dataMask")]

        assert calculate_stats(bands) == approx([0.0233, 0.0468, 0.0252])

        width, height = self.size
        assert bands.shape == (4, height, width, 13)
        assert is_data.shape == (4, height, width, 1)
        assert len(eopatch.timestamp) == 4
        assert bands.dtype == np.float32

        assert os.path.exists(cache_folder)

        # change task's bans_dtype and run it again
        task.bands_dtype = np.uint16

        eopatch = task.execute(bbox=self.bbox,
                               time_interval=self.time_interval)
        bands = eopatch[(FeatureType.DATA, "BANDS")]

        assert calculate_stats(bands) == approx([232.5769, 467.5385, 251.8654])

        assert bands.dtype == np.uint16
예제 #13
0
    def test_S2L2A(self):
        """ Download just SCL, without other bands
        """
        task = SentinelHubInputTask(bands_feature=(FeatureType.DATA, 'BANDS'),
                                    additional_data=[(FeatureType.MASK,
                                                      'dataMask')],
                                    size=self.size,
                                    maxcc=self.maxcc,
                                    time_difference=self.time_difference,
                                    data_source=DataSource.SENTINEL2_L2A,
                                    max_threads=self.max_threads)

        eopatch = task.execute(bbox=self.bbox,
                               time_interval=self.time_interval)
        bands = eopatch[(FeatureType.DATA, 'BANDS')]
        is_data = eopatch[(FeatureType.MASK, 'dataMask')]

        self.assertTrue(
            np.allclose(array_stats(bands), [0.0107, 0.0123, 0.0087]))

        width, height = self.size
        self.assertTrue(bands.shape == (4, height, width, 12))
        self.assertTrue(is_data.shape == (4, height, width, 1))
        self.assertTrue(len(eopatch.timestamp) == 4)
        input_json = json.loads(line)
        features = input_json["geometry"]
        dam_nominal = shape(features)
        dam_bbox = get_bbox(dam_nominal)

        # Use login credentials from Sentinel Hub
        config = login_config(input_json["access_settings"]["CLIENT_ID"],
                              input_json["access_settings"]["CLIENT_SECRET"],
                              input_json["access_settings"]["instance_id"])

        # Create an EOPatch and add all EO features (satellite imagery data)
        download_task = SentinelHubInputTask(
            data_collection=DataCollection.SENTINEL2_L1C,
            bands_feature=(FeatureType.DATA, 'BANDS'),
            resolution=20,
            maxcc=0.5,
            bands=['B02', 'B03', 'B04', 'B08'],
            additional_data=[(FeatureType.MASK, 'dataMask', 'IS_DATA'),
                             (FeatureType.MASK, 'CLM')],
            config=config)

        calculate_ndwi = NormalizedDifferenceIndexTask(
            (FeatureType.DATA, 'BANDS'), (FeatureType.DATA, 'NDWI'), (1, 3))

        dam_gdf = gpd.GeoDataFrame(crs=CRS.WGS84.pyproj_crs(),
                                   geometry=[dam_nominal])
        add_nominal_water = VectorToRaster(
            dam_gdf, (FeatureType.MASK_TIMELESS, 'NOMINAL_WATER'),
            values=1,
            raster_shape=(FeatureType.MASK, 'IS_DATA'),
            raster_dtype=np.uint8)
    # AOI bounding box
    full_bbox = BBox(bbox=[
        lon, lat, lon + grid_size * block_width, lat + grid_size * block_height
    ],
                     crs=CRS.WGS84)

    # ---------------------------------------------------------------------------------------------------------- #
    # Cloud-based image filtering to find viable blocks                                                          #
    # ---------------------------------------------------------------------------------------------------------- #

    # eo-learn request
    input_task = SentinelHubInputTask(
        data_collection=DataCollection.SENTINEL2_L1C,
        additional_data=[(FeatureType.DATA, 'CLP'),
                         (FeatureType.MASK, 'dataMask')],
        time_difference=datetime.timedelta(seconds=1),
        resolution=60,
        config=config)
    timelapse = LinearWorkflow(input_task)

    try:
        result = timelapse.execute(
            {input_task: {
                'bbox': full_bbox,
                'time_interval': time_interval
            }})
    except:
        continue

    # parse cloud images and register useful blocks
예제 #16
0
    def setUpClass(cls):
        bbox = BBox(bbox=(-5.05, 48.0, -5.00, 48.05), crs=CRS.WGS84)
        bbox2 = BBox(bbox=(-72.2, -70.4, -71.6, -70.2), crs=CRS.WGS84)
        slo_bbox = BBox([14.5, 45.9, 14.7, 46.1], crs=CRS.WGS84)
        cls.size = (50, 40)
        time_interval = ('2020-06-1', '2020-06-10')
        time_difference = dt.timedelta(minutes=60)
        cls.data_feature = FeatureType.DATA, 'BANDS'
        cls.mask_feature = FeatureType.MASK, 'dataMask'

        s3slstr_500m = DataCollection.SENTINEL3_SLSTR.define_from(
            'SENTINEL3_SLSTR_500m',
            bands=('S2', 'S3', 'S6')
        )
        s5p_co = DataCollection.SENTINEL5P.define_from(
            'SENTINEL5P_CO',
            bands=('CO',)
        )

        ndvi_evalscript = """
            //VERSION=3
            function setup() {
              return {
                input: [{
                 bands: ["B04", "B08", "dataMask"]
                }],
                output: [
                  { id:"custom", bands:2, sampleType: SampleType.FLOAT32 },
                  { id:"bool_mask", bands:1, sampleType: SampleType.UINT8 }
                ]
              }
            }
            function evaluatePixel(sample) {
            return {custom: [index(sample.B08, sample.B04)], bool_mask: [sample.dataMask]};
            }
        """

        cls.test_cases = [
            IoTestCase(
                name='Sentinel-2 L2A',
                request=SentinelHubInputTask(
                    bands_feature=cls.data_feature,
                    additional_data=[cls.mask_feature],
                    size=cls.size,
                    time_difference=time_difference,
                    data_collection=DataCollection.SENTINEL2_L2A
                ),
                bbox=bbox,
                time_interval=time_interval,
                data_size=12,
                timestamp_length=2,
                stats=[0.4681, 0.6334, 0.7608]
            ),
            IoTestCase(
                name='Sentinel-2 L2A - NDVI evalscript',
                request=SentinelHubInputTask(
                    bands_feature=cls.data_feature,
                    additional_data=[cls.mask_feature],
                    size=cls.size,
                    time_difference=time_difference,
                    data_collection=DataCollection.SENTINEL2_L2A,
                    evalscript=ndvi_evalscript,
                    bands=['NDVI']
                ),
                bbox=bbox,
                time_interval=time_interval,
                data_size=1,
                timestamp_length=2,
                stats=[0.0036, 0.0158, 0.0088]
            ),
            IoTestCase(
                name='Landsat8',
                request=SentinelHubInputTask(
                    bands_feature=cls.data_feature,
                    additional_data=[cls.mask_feature],
                    size=cls.size,
                    time_difference=time_difference,
                    data_collection=DataCollection.LANDSAT8
                ),
                bbox=bbox,
                time_interval=time_interval,
                data_size=11,
                timestamp_length=1,
                stats=[0.2206, 0.2654, 0.198]
            ),
            IoTestCase(
                name='MODIS',
                request=SentinelHubInputTask(
                    bands_feature=cls.data_feature,
                    additional_data=[cls.mask_feature],
                    size=cls.size,
                    time_difference=time_difference,
                    data_collection=DataCollection.MODIS
                ),
                bbox=bbox,
                time_interval=time_interval,
                data_size=7,
                timestamp_length=10,
                stats=[0.0073, 0.0101, 0.1448]
            ),
            IoTestCase(
                name='Sentinel-1 IW',
                request=SentinelHubInputTask(
                    bands_feature=cls.data_feature,
                    additional_data=[cls.mask_feature],
                    size=cls.size,
                    time_difference=time_difference,
                    data_collection=DataCollection.SENTINEL1_IW
                ),
                bbox=bbox,
                time_interval=time_interval,
                data_size=2,
                timestamp_length=5,
                stats=[0.0165, 0.0024, 0.0087]
            ),
            IoTestCase(
                name='Sentinel-1 IW ASCENDING',
                request=SentinelHubInputTask(
                    bands_feature=cls.data_feature,
                    additional_data=[cls.mask_feature],
                    size=cls.size,
                    time_difference=time_difference,
                    data_collection=DataCollection.SENTINEL1_IW_ASC
                ),
                bbox=bbox,
                time_interval=time_interval,
                data_size=2,
                timestamp_length=1,
                stats=[0.0428, 0.0199, 0.022]
            ),
            IoTestCase(
                name='Sentinel-1 EW DESCENDING',
                request=SentinelHubInputTask(
                    bands_feature=cls.data_feature,
                    additional_data=[cls.mask_feature],
                    size=cls.size,
                    time_difference=time_difference,
                    data_collection=DataCollection.SENTINEL1_EW_DES
                ),
                bbox=bbox2,
                time_interval=time_interval,
                data_size=2,
                timestamp_length=1,
                stats=[np.nan, 0.1919, 0.4114]
            ),
            IoTestCase(
                name='Sentinel-3 OLCI',
                request=SentinelHubInputTask(
                    bands_feature=cls.data_feature,
                    additional_data=[cls.mask_feature],
                    size=cls.size,
                    time_difference=time_difference,
                    data_collection=DataCollection.SENTINEL3_OLCI
                ),
                bbox=bbox,
                time_interval=time_interval,
                data_size=21,
                timestamp_length=11,
                stats=[0.2064, 0.1354, 0.1905]
            ),
            IoTestCase(
                name='Sentinel-3 SLSTR 500m resolution',
                request=SentinelHubInputTask(
                    bands_feature=cls.data_feature,
                    additional_data=[cls.mask_feature],
                    size=cls.size,
                    time_difference=time_difference,
                    data_collection=s3slstr_500m
                ),
                bbox=bbox,
                time_interval=('2021-02-10', '2021-02-15'),
                data_size=3,
                timestamp_length=14,
                stats=[0.4236, 0.6353, 0.5117]
            ),
            IoTestCase(
                name='Sentinel-5P',
                request=SentinelHubInputTask(
                    bands_feature=cls.data_feature,
                    additional_data=[cls.mask_feature],
                    size=cls.size,
                    time_difference=time_difference,
                    data_collection=s5p_co
                ),
                bbox=bbox,
                time_interval=('2020-06-1', '2020-06-1'),
                data_size=1,
                timestamp_length=1,
                stats=[0.0351, 0.034,  0.0351]
            )
        ]
class TestSentinelHubInputTaskDataCollections:
    """Integration tests for all supported data collections"""

    bbox = BBox(bbox=(-5.05, 48.0, -5.00, 48.05), crs=CRS.WGS84)
    bbox2 = BBox(bbox=(-72.2, -70.4, -71.6, -70.2), crs=CRS.WGS84)
    size = (50, 40)
    time_interval = ("2020-06-1", "2020-06-10")
    time_difference = dt.timedelta(minutes=60)
    data_feature = FeatureType.DATA, "BANDS"
    mask_feature = FeatureType.MASK, "dataMask"

    s3slstr_500m = DataCollection.SENTINEL3_SLSTR.define_from(
        "SENTINEL3_SLSTR_500m",
        bands=(
            Band("S2", (Unit.REFLECTANCE, ), (np.float32, )),
            Band("S3", (Unit.REFLECTANCE, ), (np.float32, )),
            Band("S6", (Unit.REFLECTANCE, ), (np.float32, )),
        ),
    )
    s5p_co = DataCollection.SENTINEL5P.define_from("SENTINEL5P_CO",
                                                   bands=(Band(
                                                       "CO", (Unit.DN, ),
                                                       (np.float32, )), ))

    ndvi_evalscript = """
        //VERSION=3
        function setup() {
            return {
            input: [{
                bands: ["B04", "B08", "dataMask"],
                units: ["REFLECTANCE", "REFLECTANCE", "DN"]
            }],
            output: [
                { id:"ndvi", bands:1, sampleType: SampleType.FLOAT32 },
                { id:"dataMask", bands:1, sampleType: SampleType.UINT8 }
            ]
            }
        }
        function evaluatePixel(sample) {
        return {
            ndvi: [index(sample.B08, sample.B04)],
            dataMask: [sample.dataMask]};
        }
    """

    test_cases = [
        IoTestCase(
            name="Sentinel-2 L2A",
            task=SentinelHubInputTask(
                bands_feature=data_feature,
                additional_data=[mask_feature],
                size=size,
                time_difference=time_difference,
                data_collection=DataCollection.SENTINEL2_L2A,
            ),
            bbox=bbox,
            time_interval=time_interval,
            data_size=12,
            timestamp_length=2,
            stats=[0.4676, 0.6313, 0.7688],
        ),
        IoTestCase(
            name="Sentinel-2 L2A - NDVI evalscript",
            task=SentinelHubEvalscriptTask(
                features={
                    FeatureType.DATA: [("ndvi", "NDVI-FEATURE")],
                    FeatureType.MASK: ["dataMask"],
                },
                evalscript=ndvi_evalscript,
                size=size,
                time_difference=time_difference,
                data_collection=DataCollection.SENTINEL2_L2A,
            ),
            feature="NDVI-FEATURE",
            bbox=bbox,
            time_interval=time_interval,
            data_size=1,
            timestamp_length=2,
            stats=[0.0088, 0.0083, 0.0008],
        ),
        IoTestCase(
            name="Landsat8",
            task=SentinelHubInputTask(
                bands_feature=data_feature,
                additional_data=[mask_feature],
                size=size,
                time_difference=time_difference,
                data_collection=DataCollection.LANDSAT_OT_L1,
            ),
            bbox=bbox,
            time_interval=time_interval,
            data_size=11,
            timestamp_length=1,
            stats=[48.7592, 48.726, 48.9168],
        ),
        IoTestCase(
            name="MODIS",
            task=SentinelHubInputTask(
                bands_feature=data_feature,
                additional_data=[mask_feature],
                size=size,
                time_difference=time_difference,
                data_collection=DataCollection.MODIS,
            ),
            bbox=bbox,
            time_interval=time_interval,
            data_size=7,
            timestamp_length=10,
            stats=[0.0073, 0.0101, 0.1448],
        ),
        IoTestCase(
            name="Sentinel-1 IW",
            task=SentinelHubInputTask(
                bands_feature=data_feature,
                additional_data=[mask_feature],
                size=size,
                time_difference=time_difference,
                data_collection=DataCollection.SENTINEL1_IW,
            ),
            bbox=bbox,
            time_interval=time_interval,
            data_size=2,
            timestamp_length=5,
            stats=[0.016, 0.0022, 0.0087],
        ),
        IoTestCase(
            name="Sentinel-1 IW ASCENDING",
            task=SentinelHubInputTask(
                bands_feature=data_feature,
                additional_data=[mask_feature],
                size=size,
                time_difference=time_difference,
                data_collection=DataCollection.SENTINEL1_IW_ASC,
            ),
            bbox=bbox,
            time_interval=time_interval,
            data_size=2,
            timestamp_length=1,
            stats=[0.0407, 0.0206, 0.0216],
        ),
        IoTestCase(
            name="Sentinel-1 EW DESCENDING",
            task=SentinelHubInputTask(
                bands_feature=data_feature,
                additional_data=[mask_feature],
                size=size,
                time_difference=time_difference,
                data_collection=DataCollection.SENTINEL1_EW_DES,
            ),
            bbox=bbox2,
            time_interval=time_interval,
            data_size=2,
            timestamp_length=1,
            stats=[np.nan, 0.1944, 0.3800],
        ),
        IoTestCase(
            name="Sentinel-3 OLCI",
            task=SentinelHubInputTask(
                bands_feature=data_feature,
                additional_data=[mask_feature],
                size=size,
                time_difference=time_difference,
                data_collection=DataCollection.SENTINEL3_OLCI,
            ),
            bbox=bbox,
            time_interval=time_interval,
            data_size=21,
            timestamp_length=11,
            stats=[0.317, 0.1946, 0.2884],
        ),
        IoTestCase(
            name="Sentinel-3 SLSTR 500m resolution",
            task=SentinelHubInputTask(
                bands_feature=data_feature,
                additional_data=[mask_feature],
                size=size,
                time_difference=time_difference,
                data_collection=s3slstr_500m,
            ),
            bbox=bbox,
            time_interval=("2021-02-10", "2021-02-15"),
            data_size=3,
            timestamp_length=13,
            stats=[0.3173, 0.4804, 0.4041],
        ),
        IoTestCase(
            name="Sentinel-5P",
            task=SentinelHubInputTask(
                bands_feature=data_feature,
                additional_data=[mask_feature],
                size=size,
                time_difference=time_difference,
                data_collection=s5p_co,
            ),
            bbox=bbox,
            time_interval=("2020-06-1", "2020-06-1"),
            data_size=1,
            timestamp_length=1,
            stats=[0.0351, 0.034, 0.0351],
        ),
    ]

    @pytest.mark.parametrize("test_case", test_cases)
    def test_data_collections(self, test_case):
        eopatch = test_case.task.execute(bbox=test_case.bbox,
                                         time_interval=test_case.time_interval)

        assert isinstance(eopatch, EOPatch), "Expected return type is EOPatch"

        width, height = self.size
        data = eopatch[(test_case.feature_type, test_case.feature)]
        assert data.shape == (test_case.timestamp_length, height, width,
                              test_case.data_size)

        timestamps = eopatch.timestamp
        assert all(timestamp.tzinfo is None for timestamp in
                   timestamps), f"`tzinfo` present in timestamps {timestamps}"
        assert len(timestamps) == test_case.timestamp_length

        stats = calculate_stats(data)
        assert stats == approx(
            test_case.stats,
            nan_ok=True), f"Expected stats {test_case.stats}, got {stats}"
예제 #18
0
            axis=1,
            inplace=True)

    #SentinelHubInputTask
    band_names = []
    for band in list(map(int, BANDS.strip('[]').split(','))):
        if int(band) < 10:
            band_names.append(f'B0{band}')
        else:
            band_names.append(f'B{band}')

    add_data = SentinelHubInputTask(
        bands_feature=(FeatureType.DATA, 'BANDS'),
        bands=band_names,
        resolution=10,
        maxcc=MAXCC,
        data_collection=DataCollection.SENTINEL2_L1C,
        additional_data=[(FeatureType.MASK, 'dataMask'),
                         (FeatureType.MASK, 'CLM'), (FeatureType.DATA, 'CLP')],
        max_threads=5)

    #IndexTasks
    ndvi = NormalizedDifferenceIndexTask(
        (FeatureType.DATA, 'BANDS'), (FeatureType.DATA, 'NDVI'),
        [band_names.index('B08'),
         band_names.index('B04')])

    ndwi = NormalizedDifferenceIndexTask(
        (FeatureType.DATA, 'BANDS'), (FeatureType.DATA, 'NDWI'),
        [band_names.index('B03'),
         band_names.index('B08')])