Esempio n. 1
0
 def run(self):
     logger.info(
         'Monitoring Earth Engine export. task_id: {0}, destination: {1}'.
         format(self.task_id, self.destination))
     ee.InitializeThread(self.credentials)
     while self.running():
         time.sleep(10)
         status = Task(self.task_id).status()
         state = status['state']
         if state == Task.State.READY:
             self._update_state(State.PENDING)
         elif state == Task.State.RUNNING:
             self._update_state(State.ACTIVE)
         elif state == Task.State.COMPLETED:
             self._update_state(State.COMPLETED)
             self.resolve()
             return
         else:
             error_message = status[
                 'error_message'] if state == Task.State.FAILED else 'Earth Engine export was canceled'
             self._status = {
                 'state': State.FAILED,
                 'message': error_message
             }
             raise Exception(error_message if error_message else
                             'Earth Engine export failed')
Esempio n. 2
0
 def run(self):
     ee.InitializeThread(self.credentials)
     task_id = self._image_to_asset()
     self._monitor = MonitorEarthEngineExportTask(self.credentials, task_id, self.description)
     self.dependent(self._monitor) \
         .submit() \
         .then(self.resolve, self.reject)
Esempio n. 3
0
 def _smooth(self):
     tasks = []
     for primitive_type in self.primitive_types:
         primitive_collection = ee.ImageCollection([
             _primitive_asset_id(self.asset_path, year, primitive_type)
             for year in range(self.start_year, self.end_year + 1)
         ])
         smoothed_primitive_collection, rmse = smooth_primitive_collection(
             primitive_collection)
         for year in range(self.start_year, self.end_year + 1):
             smoothed_primitive = ee.Image(
                 smoothed_primitive_collection.filterDate(
                     ee.Date.fromYMD(year, 1, 1),
                     ee.Date.fromYMD(year + 1, 1, 1)).first())
             tasks.append(
                 self.dependent(
                     ImageToAsset(credentials=self.credentials,
                                  image=smoothed_primitive,
                                  region=self.aoi.bounds(),
                                  description=None,
                                  assetId=_smoothed_primitive_asset_id(
                                      self.asset_path, year,
                                      primitive_type),
                                  scale=self.scale,
                                  retries=5)))
     ee.InitializeThread(self.credentials)
     return Task.submit_all(tasks)
Esempio n. 4
0
    def run(self):
        ee.InitializeThread(self.spec.credentials)
        # Explicitly create folder, to prevent GEE race-condition
        self.drive_folder = drive.create_folder(self.spec.credentials,
                                                self.drive_folder_name)
        self.dependent(drive.Touch([self.drive_folder_name])).submit()
        if isinstance(self.spec.aoi, ee.FeatureCollection):
            feature_collection = self.spec.aoi
            aois = [
                ee.Feature(
                    feature_collection.filterMetadata(
                        'system:index', 'equals',
                        feature_index).first()).geometry()
                for feature_index in get_info(
                    feature_collection.aggregate_array('system:index'))
            ]
        else:
            aois = [self.spec.aoi]

        self.download_tasks = [
            DownloadFeature(drive_folder=self.drive_folder_name,
                            download_dir=self.download_dir,
                            description=self.description,
                            feature_description=str(i + 1).zfill(
                                len(str(len(aois)))),
                            spec=self.spec._replace(aoi=aoi))
            for i, aoi in enumerate(aois)
        ]
        return Task.submit_all(self.download_tasks) \
            .then(self.resolve, self.reject)
Esempio n. 5
0
 def run(self):
     logger.info('Monitoring Earth Engine export. task_id: {0}, destination: {1}'
                 .format(self.task_id, self.destination))
     ee.InitializeThread(self.credentials)
     while self.running():
         time.sleep(10)
         self.check()
Esempio n. 6
0
def before():
    credentials = AccessTokenCredentials.create()
    if not credentials:
        credentials = gee.service_account_credentials
    logger.debug('Using credentials: ' + str(credentials))
    thread_local.context = Context(credentials=credentials, download_dir=sys.argv[3])
    ee.InitializeThread(credentials)
Esempio n. 7
0
def before():
    credentials = gee.service_account_credentials
    if path.exists(access_token_file):
        credentials = FileCredentials(access_token_file)
    logger.debug('Using credentials: ' + str(credentials))
    thread_local.context = Context(credentials=credentials,
                                   download_dir=sys.argv[3])
    ee.InitializeThread(credentials)
Esempio n. 8
0
def init_ee():
    credentials = service_account_credentials
    if 'sepal-user' in request.headers:
        user = json.loads(request.headers['sepal-user'])
        googleTokens = user.get('googleTokens', None)
        if googleTokens:
            credentials = Credentials(googleTokens['accessToken'])
    ee.InitializeThread(credentials)
Esempio n. 9
0
def test_timeseries():
    ee.InitializeThread(credentials)

    #
    # class CancelingTask(ThreadTask):
    #     def __init__(self, to_stop):
    #         super(CancelingTask, self).__init__()
    #         self.to_stop = to_stop
    #
    #     def run(self):
    #         print('Running stopping task')
    #         time.sleep(2)
    #         self.to_stop.cancel()
    #
    #         print('Stopping task')
    #         self.resolve()
    #
    #
    # class StatusMonitor(ThreadTask):
    #     def __init__(self, to_monitor):
    #         super(StatusMonitor, self).__init__()
    #         self.to_monitor = to_monitor
    #
    #     def run(self):
    #         previous_status = None
    #         i = 0
    #         while self.to_monitor.running() and self.running():
    #             i += 1
    #             # if i > 60:
    #             #     raise Exception('Test with a failure')
    #             status = self.to_monitor.status_message()
    #             if previous_status != status:
    #                 previous_status = status
    #                 print(status)
    #             time.sleep(0.1)
    #         self.resolve()
    #
    #     def close(self):
    #         self.to_monitor.cancel()

    class PrintingTask(ProcessTask):
        def __init__(self):
            super(PrintingTask, self).__init__()

        def run(self):
            raise AttributeError('A raised error')
            # for i in range(0, 5):
            #     print('Running')
            #     time.sleep(1)
            # self.cancel()
            # self.resolve()

        def close(self):
            print('closing printing task')

    printing_task = PrintingTask()

    Task.submit_all([printing_task]).catch(re_raise).get()
Esempio n. 10
0
 def run(self):
     logger.info('Exporting Earth Engine table to asset. asset_id: {0}'
                 .format(self.asset_id))
     ee.InitializeThread(self.credentials)
     task_id = self._table_to_asset()
     self.dependent(
         MonitorEarthEngineExportTask(self.credentials, task_id, self.asset_id)) \
         .submit() \
         .then(self.resolve, self.reject)
Esempio n. 11
0
def before():
    credentials = sepal.service_account_credentials
    if path.exists(access_token_file):
        credentials = FileCredentials(access_token_file)
    else:
        logging.info('Access token file not found: ' + access_token_file)
    logging.info('Using credentials: ' + str(credentials))
    thread_local.credentials = credentials
    ee.InitializeThread(credentials)
Esempio n. 12
0
 def run(self):
     logger.info(
         'Exporting Earth Engine table to cloud storage. description: {0}, folder: {1}'
         .format(self.description, self.folder))
     ee.InitializeThread(self.credentials)
     task_id = self._table_to_cloud_storage()
     self.dependent(
         MonitorEarthEngineExportTask(self.credentials, task_id, self.description)) \
         .submit() \
         .then(self.resolve, self.reject)
Esempio n. 13
0
    def run(self):
        ee.InitializeThread(self._spec.credentials)
        time_series = TimeSeries(self._spec)
        stack = time_series.stack
        dates = time_series.dates
        if not get_info(dates.size()):
            return self.resolve()

        self._table_export = self.dependent(
            TableToDrive(
                credentials=self._spec.credentials,
                table=dates,
                description='_'.join([self._description, self._feature_description, str(self._year), 'dates']),
                folder=self._drive_folder
            ))
        self._table_download = self.dependent(
            Download(
                credentials=self._spec.credentials,
                drive_path=self._drive_folder,
                destination_path=self._year_dir,
                matching='{0}/{1}*.csv'.format(self._drive_folder, self._table_export.description),
                move=True
            ))
        self._image_export = self.dependent(
            ImageToDrive(
                credentials=self._spec.credentials,
                image=stack,
                region=self._spec.aoi,
                description='_'.join([self._description, self._feature_description, str(self._year), 'stack']),
                folder=self._drive_folder,
                scale=30,
                maxPixels=1e12,
                shardSize=64,
                fileDimensions=512
            ))
        self._image_download = self.dependent(
            Download(
                credentials=self._spec.credentials,
                drive_path=self._drive_folder,
                destination_path=self._year_dir,
                matching='{0}/{1}*.tif'.format(self._drive_folder, self._image_export.description),
                move=True
            ))

        self._process_year = self.dependent(
            ProcessYear(self._year_dir))

        Task.submit_all([
            self._table_export.submit()
                .then(self._table_download.submit, self.reject).catch(self.reject),
            self._image_export.submit()
                .then(self._image_download.submit, self.reject).catch(self.reject)
        ]) \
            .then(self._process_year.submit, self.reject) \
            .then(self.resolve, self.reject)
Esempio n. 14
0
 def cancel():
     if task.state in [
             Task.State.COMPLETED, Task.State.CANCEL_REQUESTED,
             Task.State.CANCELLED, Task.State.FAILED
     ]:
         return
     ee.InitializeThread(credentials)
     try:
         task.cancel()
     except Exception:
         logging.exception('{}: cancelling failed'.format(task))
     return empty()
Esempio n. 15
0
    def run(self):
        ee.InitializeThread(self.credentials)
        image_spec = image_spec_factory.create(self.image_spec)
        self._export = self.dependent(
            ImageToAsset(credentials=self.credentials,
                         image=image_spec._ee_image(),
                         region=image_spec.aoi.geometry(),
                         description=self.description,
                         scale=image_spec.scale))

        return self._export.submit() \
            .then(self.resolve, self.reject)
Esempio n. 16
0
 def run(self):
     ee.InitializeThread(self.credentials)
     create_asset_image_collection(
         to_asset_id(self.asset_path + '/primitives'))
     create_asset_image_collection(
         to_asset_id(self.asset_path + '/smoothed-primitives'))
     create_asset_image_collection(
         to_asset_id(self.asset_path + '/assembly'))
     self.drive_folder = drive.create_folder(self.credentials,
                                             self.drive_folder_name)
     return self.pipe(self._sample, self._create_primitives, self._smooth,
                      self._assemble, self.resolve)
Esempio n. 17
0
 def close(self, retry=0):
     try:
         ee.InitializeThread(self.credentials)
         task = find_task(self.task_id)
         if task and task.state in (Task.State.READY, Task.State.RUNNING):
             logger.debug('Canceling Earth Engine Task {0}: {1}'.format(self, task.status()))
             task.cancel()
     except ee.EEException as e:
         logger.warn('Failed to cancel task {0}: {1}'.format(self, e))
         if retry < 3:
             throttle_seconds = max(2 ^ retry * random.uniform(0.1, 0.2), 30)
             time.sleep(throttle_seconds)
             self.close(retry + 1)
Esempio n. 18
0
def create(spec, context):
    credentials = context.credentials
    ee.InitializeThread(credentials)
    image_spec = image_spec_factory.create(context.sepal_api, spec['image'])
    return export_image_to_asset(
        credentials=credentials,
        description=spec['description'],
        image=image_spec._ee_image(),
        pyramiding_policy=image_spec.pyramiding_policy,
        dimensions=None,
        scale=image_spec.scale,
        crs='EPSG:4326',
        max_pixels=1e12
    )
Esempio n. 19
0
def index():
    if not accessToken:
        return redirect(
            'https://accounts.google.com/o/oauth2/v2/auth?'
            'scope=' + ee.oauth.SCOPE +
            ' https://www.googleapis.com/auth/drive&'
            'redirect_uri=http%3A%2F%2F127.0.0.1:5001%2Foauth%2Fcallback&'
            'response_type=code&'
            'client_id=' + oauth['web']['client_id'])

    credentials = OAuth2Credentials(accessToken, None, None, None, None, None,
                                    None)
    ee.InitializeThread(credentials)
    return 'Hello, GEE!'
Esempio n. 20
0
def before():
    credentials = AccessTokenCredentials.create(earthengine_credentials_file)
    if not credentials:
        credentials = gee.service_account_credentials
    logger.info('Using credentials: ' + str(credentials))
    thread_local.context = Context(
        credentials=credentials,
        download_dir=download_dir,
        username=username,
        sepal_api=SepalApi(host=sepal_host,
                           username=sepal_username,
                           password=sepal_password),
    )
    ee.InitializeThread(credentials)
Esempio n. 21
0
 def close(self):
     try:
         ee.InitializeThread(self.credentials)
         status = Task(self.task_id).status()
         if status['state'] in (Task.State.READY, Task.State.RUNNING):
             logger.debug('Canceling Earth Engine Task {0}: {1}'.format(
                 self, status))
             Task(
                 status['id'], {
                     'type': status['task_type'],
                     'description': status['description'],
                     'state': status['state'],
                 }).cancel()
     except ee.EEException as e:
         logger.warn('Failed to cancel task {0}: {1}'.format(self, e))
Esempio n. 22
0
def create(spec, context):
    credentials = context.credentials
    ee.InitializeThread(credentials)
    image_spec = image_spec_factory.create(context.sepal_api, spec['image'])
    return image_to_sepal(
        credentials,
        description=spec['description'],
        download_dir=context.download_dir,
        image=image_spec._ee_image(),
        dimensions=None,
        scale=image_spec.scale,
        crs='EPSG:4326',
        max_pixels=1e12,
        shard_size=256,
        file_dimensions=4096
    )
Esempio n. 23
0
 def _poll_status(self):
     ee.InitializeThread(self.credentials)
     logging.debug('Starting polling status of Google Earth Engine export task: ' + self.task_id)
     try:
         while self.running:
             status = self._task_status()
             self.listener.update_status(status)
             if status['state'] != 'ACTIVE':
                 self.stop()
                 return
             time.sleep(10)
     except Exception:
         logger.exception('Export to Google Drive failed. Task id: ' + self.task_id)
         self.listener.update_status({
             'state': 'FAILED',
             'description': 'Export to Google Drive failed'})
         self.stop()
Esempio n. 24
0
def initialize(ee_account='', ee_key_path='', ee_user_token=''):
    try:
        if ee_user_token:
            credentials = OAuth2Credentials(ee_user_token, None, None, None,
                                            None, None, None)
            ee.InitializeThread(credentials)
        elif ee_account and ee_key_path:
            credentials = ServiceAccountCredentials.from_p12_keyfile(
                service_account_email=ee_account,
                filename=ee_key_path,
                private_key_password='******',
                scopes=ee.oauth.SCOPE +
                ' https://www.googleapis.com/auth/drive')
            ee.Initialize(credentials)
        else:
            ee.Initialize()
    except (EEException, TypeError):
        pass
Esempio n. 25
0
    def _export_year(geometry, year_start, year_end, export_description,
                     year_dir):
        stack = _create_stack(geometry, year_start, year_end)
        ee.InitializeThread(credentials)
        if not stack.bandNames().size().getInfo():
            logging.info('No data between {} and {}'.format(
                year_start, year_end))
            return of({
                'exported': 1,
                'downloaded': 1,
                'downloaded_bytes': 0,
                'processed': 1
            })
        initial_progress = of({
            'exported': 0,
            'stack_bytes': 0,
            'dates_bytes': 0,
            'downloaded': 0,
            'processed': 0
        })

        def aggregate_downloaded_bytes(p):
            return {
                'exported': p['exported'],
                'downloaded': p['downloaded'],
                'downloaded_bytes': p['stack_bytes'] + p['dates_bytes'],
                'processed': p['processed']
            }

        return concat(
            initial_progress,
            merge(
                _export_and_download_stack(stack, export_description,
                                           year_dir),
                _export_and_download_dates(stack, export_description,
                                           year_dir)), _process_year(year_dir),
            of({'processed': 1})).pipe(scan(lambda acc, p: {
                **acc,
                **p
            }, {}), map(aggregate_downloaded_bytes))
Esempio n. 26
0
    def run(self):
        ee.InitializeThread(self.credentials)
        self._drive_folder = drive.create_folder(self.credentials, self.drive_path)
        self.dependent(drive.Touch([self.drive_path], self.credentials)).submit()
        image_spec = image_spec_factory.create(self.sepal_api, self.image_spec)
        self._export = self.dependent(
            ImageToDrive(
                credentials=self.credentials,
                image=image_spec._ee_image(),
                region=image_spec.aoi.geometry(),
                description=self.description,
                folder=self.drive_path,
                scale=image_spec.scale,
                maxPixels=1e12,
                shardSize=256,
                fileDimensions=4096
            ))
        destination_path = self.download_dir + '/' + self.description
        self._download = self.dependent(
            Download(
                credentials=self.credentials,
                drive_path=self.drive_path,
                destination_path=destination_path,
                move=True
            ))
        tifs = destination_path + '/*.tif'
        self._build_vrt = self.dependent(
            BuildVrt(destination_path + '/' + self.description + '.vrt', tifs))
        self._set_band_names = self.dependent(
            SetBandNames(image_spec.bands, [tifs, destination_path + '/*.vrt']))
        self._build_overviews = self.dependent(
            BuildOverviews(destination_path + '/*.vrt'))

        return self._export.submit() \
            .then(self._download.submit, self.reject) \
            .then(self._build_vrt.submit, self.reject) \
            .then(self._set_band_names.submit, self.reject) \
            .then(self._build_overviews.submit, self.reject) \
            .then(self.resolve, self.reject)
Esempio n. 27
0
 def schedule():
     credentials = get_credentials()
     return rx.interval(period, TimeoutScheduler()).pipe(
         do_action(lambda _: ee.InitializeThread(credentials)),
     )
Esempio n. 28
0
def create(spec, context):
    def get_region():
        aoi_spec = spec['aoi']
        if aoi_spec['type'] == 'FUSION_TABLE':
            if aoi_spec.get('keyColumn'):
                return Aoi.create(aoi_spec).feature_collection
            else:
                return ee.FeatureCollection('ft:' + aoi_spec['id'])
        else:
            return Aoi.create(aoi_spec).geometry()

    def image_collection_factory(geometry, start_date, end_date):
        if 'SENTINEL_1' in spec['dataSets']:
            return create_radar_collection(geometry, start_date, end_date)
        else:
            return create_optical_collection(geometry, start_date, end_date)

    def create_radar_collection(geometry, start_date, end_date):
        collection = radar_collection.create(
            region=geometry,
            orbits=spec.get('orbits', ('ASCENDING', )),
            start_date=start_date,
            end_date=end_date,
            geometric_correction=spec.get('geometricCorrection', 'ELLIPSOID'),
            speckle_filter=spec.get('speckleFilter', 'NONE'),
            outlier_removal=spec.get('outlierRemoval', 'NONE'),
            harmonics_dependents=())
        if spec['indicator'] in ['VV', 'VH']:
            return collection.select(spec['indicator'])
        else:
            return collection.map(lambda image: replace(
                image,
                image.select('VV').divide(image.select('VH'))))

    def create_optical_collection(geometry, start_date, end_date):
        OpticalSpec = namedtuple(
            'OpticalSpec',
            'credentials, surface_reflectance, shadow_tolerance, '
            'mask_clouds, mask_snow, brdf_correct, target_day, masked_on_analysis, bands, calibrate, cloud_buffer'
        )

        def _process_collection(collection, optical_spec):
            collection = mask_clouds(optical_spec, collection)
            collection = mask_shadows(optical_spec, collection)
            return collection

        optical_spec = OpticalSpec(
            credentials=credentials,
            surface_reflectance=spec['surfaceReflectance'],
            shadow_tolerance=1,
            mask_clouds=True,
            mask_snow=spec['maskSnow'],
            brdf_correct=spec['brdfCorrect'],
            target_day=0,
            masked_on_analysis=False,
            bands=[],
            calibrate='SENTINEL_2' in spec['dataSets'],
            cloud_buffer=0)

        def calculate_indicator(image):
            return replace(
                image,
                optical_indexes.to_index(
                    image, spec['indicator']).multiply(10000).int16())

        def get_data_sets():
            date_filter = ee.Filter.date(to_ee_date(start_date),
                                         to_ee_date(end_date))
            landsat_data_set_names = [
                name for name in spec['dataSets'] if name.startswith('LANDSAT')
            ]
            data_sets = landsat_data_sets(landsat_data_set_names, geometry,
                                          optical_spec, date_filter)
            if 'SENTINEL_2' in spec['dataSets']:
                data_sets.append(
                    sentinel_2_data_set(geometry, optical_spec, date_filter))
            return data_sets

        data_sets = get_data_sets()
        collection = ee.ImageCollection([])
        for data_set in data_sets:
            data_set_collection = analyze(optical_spec, data_set,
                                          data_set.to_collection())
            collection = ee.ImageCollection(
                collection.merge(data_set_collection))

        return _process_collection(collection, optical_spec) \
            .map(calculate_indicator)

    credentials = context.credentials
    ee.InitializeThread(credentials)
    return time_series_to_sepal(
        credentials,
        description=spec['description'],
        download_dir=context.download_dir,
        image_collection_factory=image_collection_factory,
        start_date=spec['fromDate'],
        end_date=spec['toDate'],
        region=get_region(),
        scale=spec.get('scale', 30),
        crs='EPSG:4326',
        max_pixels=1e12,
        file_dimensions=512,
        nodata_value=0,
        retries=2)
Esempio n. 29
0
def image_to_sepal(
        credentials,
        description: str,
        download_dir: str,
        image: ee.Image,
        band_names: list = None,
        dimensions=None,
        region: ee.Geometry = None,
        scale: int = None,
        crs: str = None,
        crs_transform: str = None,
        max_pixels: Union[int, float] = None,
        shard_size: int = None,
        file_dimensions=None,
        skip_empty_tiles=None,
        file_format: str = None,
        format_options: str = None,
        retries: int = 0
):
    drive_folder_path = '_'.join(['Sepal', description, str(uuid.uuid4())])
    destination_path = download_dir + '/' + description

    def _create_drive_folder():
        return concat(
            progress(
                default_message='Creating Google Drive download folder...',
                message_key='tasks.retrieve.image_to_sepal.creating_drive_folder'
            ),
            create_folder_with_path(credentials, drive_folder_path).pipe(
                flat_map(lambda _: empty())
            )
        )

    def _export_to_drive():
        return export_image_to_drive(
            credentials,
            image,
            description=description,
            folder=drive_folder_path,
            dimensions=dimensions,
            region=region,
            scale=scale,
            crs=crs,
            crs_transform=crs_transform,
            max_pixels=max_pixels,
            shard_size=shard_size,
            file_dimensions=file_dimensions,
            skip_empty_tiles=skip_empty_tiles,
            file_format=file_format,
            format_options=format_options,
            retries=retries,
        )

    def _download_from_drive():
        return download_path(
            credentials,
            path=drive_folder_path,
            destination=destination_path,
            delete_after_download=True
        )

    def _delete_drive_folder():
        return concat(
            progress(
                default_message='Deleting Google Drive download folder...',
                message_key='tasks.retrieve.image_to_sepal.deleting_drive_folder'
            ),
            delete_file_with_path(
                credentials,
                path=drive_folder_path
            ).pipe(
                flat_map(lambda _: empty())
            )
        )

    def _build_vrt():
        return concat(
            progress(
                default_message='Building VRT...',
                message_key='tasks.retrieve.image_to_sepal.building_vrt'
            ),
            build_vrt(
                destination=destination_path + '/' + description + '.vrt',
                files=destination_path + '/*.tif'
            ).pipe(
                flat_map(lambda _: empty())
            )
        )

    def _set_band_names():
        band_names_stream = of(band_names) if band_names else get_band_names(credentials, image)
        return concat(
            progress(
                default_message='Setting band names...',
                message_key='tasks.retrieve.image_to_sepal.setting_band_names'
            ),
            band_names_stream.pipe(
                flat_map(
                    lambda names: set_band_names(
                        band_names=names,
                        files=[destination_path + '/*.tif', destination_path + '/*.vrt']
                    )
                ),
                flat_map(lambda _: empty())
            )
        )

    ee.InitializeThread(credentials)
    return concat(
        _create_drive_folder(),
        _export_to_drive(),
        _download_from_drive(),
        _delete_drive_folder(),
        _build_vrt(),
        _set_band_names()
    ).pipe(
        merge_finalize(_delete_drive_folder)
    )
Esempio n. 30
0
 def run(self):
     ee.InitializeThread(self.credentials)
     return self._create_primitive(self.samples).pipe(self.resolve)