Пример #1
0
logging.basicConfig(filename='warnings.log',level=logging.DEBUG)

download_dest = "/home/leo/landsat8_1x1_grid/"
check_dest = "/home/leo/landsat_1x1_new/"

ee.Initialize()

# Select 1x1 degree tiles on North America
northamerica = ee.FeatureCollection('ft:1Ep6prwb941jMjmMxqD_BsISZj6JCiAE76mFcAiYl') \
	.filterMetadata('CONTINENT', 'equals', 'North America')
tiles = ee.FeatureCollection('ft:15P7IFF53wKVGefe_c6Cb2RBnsUql-wgMAX5OBcmq')
spatialFilter = ee.Filter.intersects('.geo', None, '.geo', None, 10)
saveAllJoin = ee.Join.saveAll('scenes')
intersectJoined = saveAllJoin.apply(northamerica, tiles, spatialFilter)
northamerica_tiles = ee.List(intersectJoined.first().get('scenes'))

time.sleep(15)

numTiles = 4366
for i in range(35, numTiles - 1):

	checkpath = os.path.join(check_dest, 'tile' + str(i) + '.zip')
	savepath = os.path.join(download_dest, 'tile' + str(i) + '.zip')

	#check if file exists
	if(os.path.isfile(checkpath)):
		logging.warning('tile:' + str(i) + ' exists, skipping...')
		continue

	if(os.path.isfile(savepath)):
Пример #2
0
 def test_Container_Length(self):
     """Test the Container Emulation Methods"""
     test = len(ee.List([1, 2, 3]))
     self.assertIsInstance(test, int)
Пример #3
0
 def test_binary1(self):
     """Test the eeList module for binary operators 1"""
     binary1_tested = ee.List([1, 2, 3]) + ee.List([4, 5, 6]) * 5
     self.assertIsInstance(binary1_tested, ee.ee_list.List)
Пример #4
0
def bootstrapOtsu(collection,target_date, reductionPolygons,
                  neg_buffer=-1500,     # negative buffer for masking potential bad data
                  upper_threshold=-14,  # upper limit for water threshold
                  canny_threshold=7,    # threshold for canny edge detection
                  canny_sigma=1,        # sigma value for gaussian filter
                  canny_lt=7,           # lower threshold for canny detection
                  smoothing=100,        # amount of smoothing in meters
                  connected_pixels=200, # maximum size of the neighborhood in pixels
                  edge_length=50,       # minimum length of edges from canny detection
                  smooth_edges=100,
                  qualityBand=None,
                  reverse=False,
                  reductionScale=90):

    tDate = ee.Date(target_date)
    targetColl = collection.filterDate(tDate,tDate.advance(1,'day'))

    nImgs = targetColl.size().getInfo()
    if nImgs <= 0:
        raise EEException('Selected date has no imagery, please try processing another date')

    collGeom = targetColl.geometry()
    polygons = reductionPolygons.filterBounds(collGeom)

    nPolys = polygons.size().getInfo()
    if nPolys > 0:
        ids = ee.List(polygons.aggregate_array('id'))
        random_ids = []
        for i in range(3):
            random_ids.append(random.randint(0, ids.size().subtract(1).getInfo()))
        random_ids = ee.List(random_ids)

        def getRandomIds(i):
            return ids.get(i)

        ids = random_ids.map(getRandomIds)
        polygons = polygons.filter(ee.Filter.inList('id', ids))

        if qualityBand == None:
            target   = targetColl.mosaic().set('system:footprint', collGeom.dissolve())
            target   = target.clip(target.geometry().buffer(neg_buffer))
            smoothed = target.focal_median(smoothing, 'circle', 'meters')
            histBand = ee.String(target.bandNames().get(0))
        else:
            target   = targetColl.qualityMosaic(qualityBand).set('system:footprint', collGeom.dissolve())
            target   = target.clip(target.geometry().buffer(neg_buffer))
            smoothed = target.focal_median(smoothing, 'circle', 'meters')
            histBand = ee.String(qualityBand)

        canny = ee.Algorithms.CannyEdgeDetector(smoothed,canny_threshold,canny_sigma)

        connected = canny.mask(canny).lt(canny_lt).connectedPixelCount(connected_pixels, True)
        edges = connected.gte(edge_length)

        edgeBuffer = edges.focal_max(smooth_edges, 'square', 'meters')

        histogram_image = smoothed.mask(edgeBuffer)
        histogram = histogram_image.reduceRegion(ee.Reducer.histogram(255, 2),polygons.geometry(),reductionScale,bestEffort=True)

        threshold = ee.Number(otsu_function(histogram.get(histBand))).min(upper_threshold)
    else:
        threshold = upper_threshold

    water = smoothed.lt(threshold).clip(geeutils.LAND.geometry())

    return water
Пример #5
0
 def test_Container_Get_Item_By_Index(self):
     """Test the Container Emulation Methods"""
     test = ee.List([1, 2, 3])[0]
     self.assertIsInstance(test, ee.computedobject.ComputedObject)
Пример #6
0
def line(start, end):
    return ee.Geometry.LineString(ee.List([start, end]))
Пример #7
0
def y(point):
    return ee.Number(ee.List(point).get(1))
Пример #8
0
def used_ids_sample(image, aoi, ids):
    samples = image.select('index').uint16().sample(region=aoi.geometry(),
                                                    scale=300,
                                                    factor=0.01)
    usedIndexes = ee.List(samples.distinct('index').aggregate_array('index'))
    return usedIndexes.map(lambda index: ids.get(index))
def arrayToPairs(array, startDate, EndDate, delta=1, CLOUDY_PIXEL_PERCENTAGE=10):
    ee.Initialize()
    area = ee.Geometry.Polygon(array)

    # query
    collection_NDVI = ee.ImageCollection("COPERNICUS/S2").filterBounds(area) \
        .filterDate(startDate, EndDate) \
        .filterMetadata("CLOUDY_PIXEL_PERCENTAGE", "less_than", CLOUDY_PIXEL_PERCENTAGE) \
        .select(['B8', 'B4', 'QA60']) \
        .sort('date')

    NDVI_size = collection_NDVI.size().getInfo()
    l_NDVI = collection_NDVI.toList(NDVI_size)
    l_NDVI_dates = getDates(l_NDVI, NDVI_size, process=False)

    # use NDVI dates to make date-filter for SAR data, taking into account
    valid_dates = None
    for i_NDVI in range(NDVI_size):
        NDVI_date = l_NDVI_dates[i_NDVI]
        if not valid_dates:
            valid_dates = ee.Filter.date(NDVI_date.advance(-delta, 'day'), NDVI_date.advance(delta, 'day'))
        else:
            valid_dates = ee.Filter.Or(valid_dates, ee.Filter.date(NDVI_date.advance(-delta, 'day'),
                                                                   NDVI_date.advance(delta, 'day')))

    if (not valid_dates):
        raise ValueError("no valid dates for the image")

    collection_SAR = ee.ImageCollection('COPERNICUS/S1_GRD').filterBounds(area) \
        .filter(valid_dates) \
        .select(['VH', 'VV'])

    SAR_size = collection_SAR.size().getInfo()
    l_SAR = collection_SAR.toList(SAR_size)
    l_SAR_dates = getDates(l_SAR, SAR_size)
    l_NDVI_dates = getDates(l_NDVI, NDVI_size)

    # map collections to their respective special data formats
    collection_NDVI = collection_NDVI.map(getNDVI.getNDVI)
    l_NDVI = collection_NDVI.toList(NDVI_size)
    # NDVI-[SAR] list
    pairs_i = {}
    for i_SAR in range(SAR_size):
        SAR_date = l_SAR_dates[i_SAR]
        for i_NDVI in range(NDVI_size):
            NDVI_date = l_NDVI_dates[i_NDVI]
            if abs(SAR_date - NDVI_date) <= timedelta(days=delta):
                if i_NDVI not in pairs_i:
                    pairs_i[i_NDVI] = [i_SAR]
                else:
                    pairs_i[i_NDVI].append(i_SAR)

    sorted_pairs = sorted(pairs_i)
    print(pairs_i)
    arr = []
    precomputed_SAR = dict()
    LatLonImgsNDVI = ee.List(
        [common.fastLatLonImg(ee.Image(l_NDVI.get(NDVI)), area) for NDVI in sorted_pairs])
    LatLonImgsSAR = ee.List([LatLonImgVHVV(ee.Image(l_SAR.get(SAR)), area) for SAR in range(SAR_size)])
    both_lists = ee.List([LatLonImgsNDVI, LatLonImgsSAR]).getInfo()
    LatLonImgsNDVI = both_lists[0]
    LatLonImgsSAR = both_lists[1]

    for NDVI in range(len(LatLonImgsNDVI)):
        i = sorted_pairs[NDVI]
        for SAR in pairs_i[i]:
            ndvi_temp = (LatLonImgsNDVI[NDVI][0], LatLonImgsNDVI[NDVI][1], LatLonImgsNDVI[NDVI][2])
            if SAR not in precomputed_SAR:
                lats = LatLonImgsSAR[SAR][0]
                lons = LatLonImgsSAR[SAR][1]
                vh = LatLonImgsSAR[SAR][2]
                vv = LatLonImgsSAR[SAR][3]
                precomputed_SAR[SAR] = []
                precomputed_SAR[SAR].append((lats, lons, vh) + (f'SAR (VH) {l_SAR_dates[SAR]:%B %d, %Y}',))
                precomputed_SAR[SAR].append((lats, lons, vv) + (f'SAR (VV) {l_SAR_dates[SAR]:%B %d, %Y}',))
            arr.append(ndvi_temp + (f'NDVI {l_NDVI_dates[NDVI]:%B %d, %Y}',))
            arr.extend(precomputed_SAR[SAR])

    return rasteriser.rasteriseImages(arr)
CRS = 'EPSG:4326'
SCALE = 30
NULL_VALUE = 0
MASK_VALUE = 0  # used for ADDON image
startJulian = 152  # start april
endJulian = 243  # early oct

# parts to divide into if 'too many values' error
n = 10

# wait time
wait = 10  # seconds

# values to copy from fusion table/feature collection
feat_properties = ['site']
KEYS = ee.List(feat_properties)

# properties to retrieve from scene
scene_properties = [
    'CLOUD_COVER', 'GEOMETRIC_RMSE_MODEL', 'LANDSAT_ID', 'SOLAR_ZENITH_ANGLE'
]
PROPERTY_LIST = ee.List(scene_properties)

# Bands to retrieve
bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'pixel_qa', 'radsat_qa']
BAND_LIST = ee.List(bands)

# addon asset and bands
ADDON = ee.Image('JRC/GSW1_0/GlobalSurfaceWater').float().unmask(MASK_VALUE)
ADDON_BANDLIST = ee.List(['max_extent'])
 def _combine(this, prev):
     return ee.List(prev).add(this)
Пример #12
0

# end and start date of period of interest
start_date = ee.Date.fromYMD(2001, 1, 1)
end_date  = ee.Date.fromYMD(2019, 12, 31)
# add dn
collection = collection.map(add_dn_date_all(Year = False, days = 8))

# mask out crap pixels
MOD09masked = collection.filterDate(start_date, end_date).map(maskPixels)

# add NDVI as a new band
MOD09ndvi = MOD09masked.map(addNDVI).select('NDVI')

tmpseas = ["%02d" % x for x in list(range(1, 46+1))]
tmpseas1 = ee.List(tmpseas)

# get year from bash environment
year = int(os.environ["year"])

# climatology
yearp5 = ee.Number(year).add(5)
start_date = ee.Date.fromYMD(year,1,1)
end_date = ee.Date.fromYMD(yearp5,12,31)
MOD09ndviY = MOD09ndvi.filterDate(start_date, end_date)
MinNDVI = MOD09ndviY.min()
meanNDVI = MOD09ndviY.mean()

# climatology 5 years (monthly composites)
seasons = ee.ImageCollection.fromImages(tmpseas1.map(clim5y)) # problems start here!!!
def main(ini_path=None, overwrite_flag=False, delay_time=0, gee_key_file=None,
         max_ready=-1, reverse_flag=False):
    """Compute annual Tcorr images from scene images

    Parameters
    ----------
    ini_path : str
        Input file path.
    overwrite_flag : bool, optional
        If True, overwrite existing files (the default is False).
    delay_time : float, optional
        Delay time in seconds between starting export tasks (or checking the
        number of queued tasks, see "max_ready" parameter).  The default is 0.
    gee_key_file : str, None, optional
        Earth Engine service account JSON key file (the default is None).
    max_ready: int, optional
        Maximum number of queued "READY" tasks.  The default is -1 which is
        implies no limit to the number of tasks that will be submitted.
    reverse_flag : bool, optional
        If True, process WRS2 tiles in reverse order.

    """
    logging.info('\nCompute annual Tcorr images from scene images')

    ini = utils.read_ini(ini_path)

    model_name = 'SSEBOP'
    # model_name = ini['INPUTS']['et_model'].upper()

    tmax_name = ini[model_name]['tmax_source']

    export_id_fmt = 'tcorr_scene_{product}_{wrs2}_annual_from_scene'
    asset_id_fmt = '{coll_id}/{wrs2}'

    tcorr_annual_coll_id = '{}/{}_annual_from_scene'.format(
        ini['EXPORT']['export_coll'], tmax_name.lower())

    wrs2_coll_id = 'projects/earthengine-legacy/assets/' \
                   'projects/usgs-ssebop/wrs2_descending_custom'
    wrs2_tile_field = 'WRS2_TILE'
    # wrs2_path_field = 'ROW'
    # wrs2_row_field = 'PATH'

    try:
        wrs2_tiles = str(ini['INPUTS']['wrs2_tiles'])
        wrs2_tiles = [x.strip() for x in wrs2_tiles.split(',')]
        wrs2_tiles = sorted([x.lower() for x in wrs2_tiles if x])
    except KeyError:
        wrs2_tiles = []
        logging.debug('  wrs2_tiles: not set in INI, defaulting to []')
    except Exception as e:
        raise e

    try:
        study_area_extent = str(ini['INPUTS']['study_area_extent']) \
            .replace('[', '').replace(']', '').split(',')
        study_area_extent = [float(x.strip()) for x in study_area_extent]
    except KeyError:
        study_area_extent = None
        logging.debug('  study_area_extent: not set in INI, defaulting to None')
    except Exception as e:
        raise e

    # TODO: Add try/except blocks and default values?
    # TODO: Filter Tcorr scene collection based on collections parameter
    # collections = [x.strip() for x in ini['INPUTS']['collections'].split(',')]
    cloud_cover = float(ini['INPUTS']['cloud_cover'])
    min_pixel_count = float(ini['TCORR']['min_pixel_count'])
    min_scene_count = float(ini['TCORR']['min_scene_count'])

    if (tmax_name.upper() == 'CIMIS' and
            ini['INPUTS']['end_date'] < '2003-10-01'):
        logging.error(
            '\nCIMIS is not currently available before 2003-10-01, exiting\n')
        sys.exit()
    elif (tmax_name.upper() == 'DAYMET' and
            ini['INPUTS']['end_date'] > '2018-12-31'):
        logging.warning(
            '\nDAYMET is not currently available past 2018-12-31, '
            'using median Tmax values\n')
        # sys.exit()
    # elif (tmax_name.upper() == 'TOPOWX' and
    #         ini['INPUTS']['end_date'] > '2017-12-31'):
    #     logging.warning(
    #         '\nDAYMET is not currently available past 2017-12-31, '
    #         'using median Tmax values\n')
    #     # sys.exit()


    logging.info('\nInitializing Earth Engine')
    if gee_key_file:
        logging.info('  Using service account key file: {}'.format(gee_key_file))
        # The "EE_ACCOUNT" parameter is not used if the key file is valid
        ee.Initialize(ee.ServiceAccountCredentials('x', key_file=gee_key_file),
                      use_cloud_api=True)
    else:
        ee.Initialize(use_cloud_api=True)


    logging.debug('\nTmax properties')
    tmax_source = tmax_name.split('_', 1)[0]
    tmax_version = tmax_name.split('_', 1)[1]
    tmax_coll_id = 'projects/earthengine-legacy/assets/' \
                   'projects/usgs-ssebop/tmax/{}'.format(tmax_name.lower())
    tmax_coll = ee.ImageCollection(tmax_coll_id)
    tmax_mask = ee.Image(tmax_coll.first()).select([0]).multiply(0)
    logging.debug('  Collection: {}'.format(tmax_coll_id))
    logging.debug('  Source: {}'.format(tmax_source))
    logging.debug('  Version: {}'.format(tmax_version))


    # Get the Tcorr scene image collection properties
    logging.debug('\nTcorr scene collection')
    tcorr_scene_coll_id = '{}/{}_scene'.format(
        ini['EXPORT']['export_coll'], tmax_name.lower())


    logging.debug('\nExport properties')
    export_info = utils.get_info(ee.Image(tmax_mask))
    if 'daymet' in tmax_name.lower():
        # Custom smaller extent for DAYMET focused on CONUS
        export_extent = [-1999750, -1890500, 2500250, 1109500]
        export_shape = [4500, 3000]
        export_geo = [1000, 0, -1999750, 0, -1000, 1109500]
        # Custom medium extent for DAYMET of CONUS, Mexico, and southern Canada
        # export_extent = [-2099750, -3090500, 2900250, 1909500]
        # export_shape = [5000, 5000]
        # export_geo = [1000, 0, -2099750, 0, -1000, 1909500]
        export_crs = export_info['bands'][0]['crs']
    else:
        export_crs = export_info['bands'][0]['crs']
        export_geo = export_info['bands'][0]['crs_transform']
        export_shape = export_info['bands'][0]['dimensions']
        # export_geo = ee.Image(tmax_mask).projection().getInfo()['transform']
        # export_crs = ee.Image(tmax_mask).projection().getInfo()['crs']
        # export_shape = ee.Image(tmax_mask).getInfo()['bands'][0]['dimensions']
        export_extent = [
            export_geo[2], export_geo[5] + export_shape[1] * export_geo[4],
            export_geo[2] + export_shape[0] * export_geo[0], export_geo[5]]
    export_geom = ee.Geometry.Rectangle(
        export_extent, proj=export_crs, geodesic=False)
    logging.debug('  CRS: {}'.format(export_crs))
    logging.debug('  Extent: {}'.format(export_extent))
    logging.debug('  Geo: {}'.format(export_geo))
    logging.debug('  Shape: {}'.format(export_shape))


    if study_area_extent is None:
        if 'daymet' in tmax_name.lower():
            # CGM - For now force DAYMET to a slightly smaller "CONUS" extent
            study_area_extent = [-125, 25, -65, 49]
            # study_area_extent =  [-125, 25, -65, 52]
        elif 'cimis' in tmax_name.lower():
            study_area_extent = [-124, 35, -119, 42]
        else:
            # TODO: Make sure output from bounds is in WGS84
            study_area_extent = tmax_mask.geometry().bounds().getInfo()
        logging.debug(f'\nStudy area extent not set in INI, '
                      f'default to {study_area_extent}')
    study_area_geom = ee.Geometry.Rectangle(
        study_area_extent, proj='EPSG:4326', geodesic=False)


    if not ee.data.getInfo(tcorr_annual_coll_id):
        logging.info('\nExport collection does not exist and will be built'
                     '\n  {}'.format(tcorr_annual_coll_id))
        input('Press ENTER to continue')
        ee.data.createAsset({'type': 'IMAGE_COLLECTION'}, tcorr_annual_coll_id)

    # Get current asset list
    logging.debug('\nGetting GEE asset list')
    asset_list = utils.get_ee_assets(tcorr_annual_coll_id)
    # if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
    #     pprint.pprint(asset_list[:10])

    # Get current running tasks
    tasks = utils.get_ee_tasks()
    if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
        logging.debug('  Tasks: {}\n'.format(len(tasks)))
        input('ENTER')

    # Limit by year
    month_list = list(range(1, 13))
    # try:
    #     month_list = sorted(list(utils.parse_int_set(ini['TCORR']['months'])))
    # except:
    #     logging.info('\nTCORR "months" parameter not set in the INI,'
    #                  '\n  Defaulting to all months (1-12)\n')
    #     month_list = list(range(1, 13))
    try:
        year_list = sorted(list(utils.parse_int_set(ini['TCORR']['years'])))
    except:
        logging.info('\nTCORR "years" parameter not set in the INI,'
                     '\n  Defaulting to all available years\n')
        year_list = []


    # Get the list of WRS2 tiles that intersect the data area and study area
    wrs2_coll = ee.FeatureCollection(wrs2_coll_id) \
        .filterBounds(export_geom) \
        .filterBounds(study_area_geom)
    if wrs2_tiles:
        wrs2_coll = wrs2_coll.filter(ee.Filter.inList(wrs2_tile_field, wrs2_tiles))
    wrs2_info = wrs2_coll.getInfo()['features']


    # Iterate over date ranges
    for wrs2_ftr in sorted(wrs2_info,
                           key=lambda k: k['properties']['WRS2_TILE'],
                           reverse=reverse_flag):
        wrs2_tile = wrs2_ftr['properties'][wrs2_tile_field]
        logging.info('{}'.format(wrs2_tile))

        wrs2_path = int(wrs2_tile[1:4])
        wrs2_row = int(wrs2_tile[5:8])
        # wrs2_path = wrs2_ftr['properties'][wrs2_path_field]
        # wrs2_row = wrs2_ftr['properties'][wrs2_row_field]

        export_id = export_id_fmt.format(
            product=tmax_name.lower(), wrs2=wrs2_tile)
        logging.debug('  Export ID: {}'.format(export_id))

        asset_id = asset_id_fmt.format(
            coll_id=tcorr_annual_coll_id, wrs2=wrs2_tile)
        logging.debug('  Asset ID: {}'.format(asset_id))

        if overwrite_flag:
            if export_id in tasks.keys():
                logging.debug('  Task already submitted, cancelling')
                ee.data.cancelTask(tasks[export_id]['id'])
            # This is intentionally not an "elif" so that a task can be
            # cancelled and an existing image/file/asset can be removed
            if asset_id in asset_list:
                logging.debug('  Asset already exists, removing')
                ee.data.deleteAsset(asset_id)
        else:
            if export_id in tasks.keys():
                logging.debug('  Task already submitted, exiting')
                continue
            elif asset_id in asset_list:
                logging.debug('  Asset already exists, skipping')
                continue

        tcorr_coll = ee.ImageCollection(tcorr_scene_coll_id) \
            .filterMetadata('wrs2_tile', 'equals', wrs2_tile) \
            .filterMetadata('tcorr_pixel_count', 'not_less_than', min_pixel_count) \
            .filter(ee.Filter.inList('year', year_list))
        # TODO: Should CLOUD_COVER_LAND filter should be re-applied here?
        #     .filterMetadata('CLOUD_COVER_LAND', 'less_than', cloud_cover)
        #     .filterDate(start_date, end_date)
        #     .filterBounds(ee.Geometry(wrs2_ftr['geometry']))

        # Use a common reducer for the images and property stats
        reducer = ee.Reducer.median() \
            .combine(ee.Reducer.count(), sharedInputs=True)

        # Compute stats from the collection images
        # This might be used when Tcorr is spatial
        # tcorr_img = tcorr_coll.reduce(reducer).rename(['tcorr', 'count'])

        # Compute stats from the image properties
        tcorr_stats = ee.List(tcorr_coll.aggregate_array('tcorr_value')) \
            .reduce(reducer)
        tcorr_stats = ee.Dictionary(tcorr_stats) \
            .combine({'median': 0, 'count': 0}, overwrite=False)
        tcorr = ee.Number(tcorr_stats.get('median'))
        count = ee.Number(tcorr_stats.get('count'))
        index = count.lt(min_scene_count).multiply(7).add(2)
        # index = ee.Algorithms.If(count.gte(min_scene_count), 2, 9)

        # Clip the mask image to the Landsat footprint
        # Change mask values to 1 if count >= threshold
        # Mask values of 0 will be set to nodata
        mask_img = tmax_mask.add(count.gte(min_scene_count)) \
            .clip(ee.Geometry(wrs2_ftr['geometry']))
        output_img = ee.Image(
                [mask_img.multiply(tcorr), mask_img.multiply(count)]) \
            .rename(['tcorr', 'count']) \
            .updateMask(mask_img.unmask(0))

        # # Write an empty image if the pixel count is too low
        # # CGM: Check/test if this can be combined into a single If()
        # tcorr_img = ee.Algorithms.If(
        #     count.gte(min_scene_count),
        #     tmax_mask.add(tcorr), tmax_mask.updateMask(0))
        # count_img = ee.Algorithms.If(
        #     count.gte(min_scene_count),
        #     tmax_mask.add(count), tmax_mask.updateMask(0))
        #
        # # Clip to the Landsat image footprint
        # output_img = ee.Image([tcorr_img, count_img]) \
        #     .rename(['tcorr', 'count']) \
        #     .clip(ee.Geometry(wrs2_ftr['geometry']))
        # # Clear the transparency mask
        # output_img = output_img.updateMask(output_img.unmask(0))

        output_img = output_img.set({
            'date_ingested': datetime.datetime.today().strftime('%Y-%m-%d'),
            'model_name': model_name,
            'model_version': ssebop.__version__,
            # 'system:time_start': utils.millis(start_dt),
            'tcorr_value': tcorr,
            'tcorr_index': index,
            'tcorr_scene_count': count,
            'tmax_source': tmax_source.upper(),
            'tmax_version': tmax_version.upper(),
            'wrs2_path': wrs2_path,
            'wrs2_row': wrs2_row,
            'wrs2_tile': wrs2_tile,
            'years': ','.join(map(str, year_list)),
            # 'year_start': year_list[0],
            # 'year_end': year_list[-1],
        })
        # pprint.pprint(output_img.getInfo())
        # input('ENTER')

        logging.debug('  Building export task')
        task = ee.batch.Export.image.toAsset(
            image=output_img,
            description=export_id,
            assetId=asset_id,
            crs=export_crs,
            crsTransform='[' + ','.join(list(map(str, export_geo))) + ']',
            dimensions='{0}x{1}'.format(*export_shape),
        )

        logging.info('  Starting export task')
        utils.ee_task_start(task)

        # Pause before starting the next export task
        utils.delay_task(delay_time, max_ready)
        logging.debug('')
Пример #14
0
 def unique_properties(coll, property):
     return ee.String(ee.List(ee.Dictionary(
         coll.aggregate_histogram(property)).keys()).join(','))
Пример #15
0
def get_data_from_image():

    # static values
    scale_value = 1000
    nameOfArea = "polygon"

    # Extract image or image collection name from request
    image_name = request.json.get('imageName')


    # Load the SRTM image. Handling error for image vs image collection
    try:
        image_data = ee.ImageCollection(image_name).filterBounds(polygon)
        # load image
        srtm = ee.Image(image_data.first()).clip(polygon)
    except:
        image_data = ee.Image(image_name).filterBounds(polygon)
        # load first image from collection
        srtm = ee.Image(image_data).clip(polygon)


    # Polygon region
    region = ee.Geometry.Rectangle(-122.2806, 37.1209, -122.0554, 37.2413)


    # meanDict = srtm.reduceRegion(reducer=ee.Reducer.toList(), geometry=region, scale=30)


    # Compute the mean elevation in the polygon.
    meanDict = srtm.reduceRegion( reducer= ee.Reducer.toList(), geometry= polygon, scale= scale_value)

    # print('meanDict:', meanDict)


    # Get the mean from the dictionary and print it.
    mean = meanDict.get('elevation');
    # print('Mean elevation', mean);


    # # TEST IMAGE
    first = srtm.clip(polygon);

    # get image projection
    proj = first.select([0]).projection();

    # get coordinates image
    latlon = ee.Image.pixelLonLat().reproject(proj)
    # Map.addLayer(first, {bands:[bands], min:0, max:500}, 'Image')


    coords = latlon.select(['longitude', 'latitude']).reduceRegion(reducer=ee.Reducer.toList(),
    geometry=region,
    scale=30)


    # get lat & lon
    lat = ee.List(coords.get('latitude'))
    lon = ee.List(coords.get('longitude'))

    # zip them. Example: zip([1, 3],[2, 4]) --> [[1, 2], [3,4]]
    point_list = lon.zip(lat)
    print('point list', point_list)
    csv_data = []


    # TODO: format data to return JSON
    return str(point_list)
Пример #16
0
def regionCover(image,
                region,
                bands=None,
                scale=None,
                operator='OR',
                property_name='REGION_COVER',
                crs=None,
                crsTransform=None,
                bestEffort=False,
                maxPixels=1e13,
                tileScale=1):
    """ Compute the percentage of values greater than 1 in a region. If more
     than one band is specified, it applies the specified operator """
    operators = ['OR', 'AND']
    if operator not in operators:
        raise ValueError('operator must be one of {}'.format(operators))

    if not bands:
        bands = ee.List([image.bandNames().get(0)])

    if operator == 'AND':
        reducer = ee.Reducer.bitwiseAnd()
    else:
        reducer = ee.Reducer.bitwiseOr()

    bandname = 'regionCover'
    mask = image.select(bands).reduce(reducer).rename(bandname)

    # get projection
    projection = mask.projection()

    if not scale:
        scale = projection.nominalScale()

    # Make an image with all ones
    ones_i = ee.Image.constant(1).reproject(projection).rename(bandname)

    # manage geometry types
    if isinstance(region, (ee.Feature, ee.FeatureCollection)):
        region = region.geometry()

    unbounded = region.isUnbounded()

    # Get total number of pixels
    ones = ones_i.reduceRegion(
        reducer=ee.Reducer.count(),
        geometry=region,
        scale=scale,
        maxPixels=maxPixels,
        crs=crs,
        crsTransform=crsTransform,
        bestEffort=bestEffort,
        tileScale=tileScale,
    ).get(bandname)
    ones = ee.Number(ones)

    # select first band, unmask and get the inverse
    image_to_compute = mask.selfMask()

    # Get number of zeros in the given image
    zeros_in_mask = image_to_compute.reduceRegion(
        reducer=ee.Reducer.count(),
        geometry=region,
        scale=scale,
        maxPixels=maxPixels,
        crs=crs,
        crsTransform=crsTransform,
        bestEffort=bestEffort,
        tileScale=tileScale).get(bandname)
    zeros_in_mask = ee.Number(zeros_in_mask)

    percentage = zeros_in_mask.divide(ones)

    # Multiply by 100
    cover = percentage.multiply(100)

    # Return None if geometry is unbounded
    final = ee.Number(ee.Algorithms.If(unbounded, 0, cover))
    return image.set(property_name, final)
Пример #17
0
def line_from_coords(coordinates, fromIndex, toIndex):
    return ee.Geometry.LineString(
        ee.List([coordinates.get(fromIndex),
                 coordinates.get(toIndex)]))
Пример #18
0
 def interpolation(band):
     look = _lookup(source.getArray(band), target.getArray(band))
     x = ee.List(look.get('x'))
     y = ee.List(look.get('y'))
     return sourceImg.select([band]).interpolate(x, y)
Пример #19
0
def x(point):
    return ee.Number(ee.List(point).get(0))
Пример #20
0
def parametrize(image, range_from, range_to, bands=None, drop=False):
    """ Parametrize from a original **known** range to a fixed new range

    :param range_from: Original range. example: (0, 5000)
    :type range_from: tuple
    :param range_to: Fixed new range. example: (500, 1000)
    :type range_to: tuple
    :param bands: bands to parametrize. If *None* all bands will be
        parametrized.
    :type bands: list
    :param drop: drop the bands that will not be parametrized
    :type drop: bool

    :return: the parsed image with the parsed bands parametrized
    :rtype: ee.Image
    """
    original_range = range_from if isinstance(range_from, ee.List) \
        else ee.List(range_from)

    final_range = range_to if isinstance(range_to, ee.List) \
        else ee.List(range_to)

    # original min and max
    min0 = ee.Image.constant(original_range.get(0))
    max0 = ee.Image.constant(original_range.get(1))

    # range from min to max
    rango0 = max0.subtract(min0)

    # final min max images
    min1 = ee.Image.constant(final_range.get(0))
    max1 = ee.Image.constant(final_range.get(1))

    # final range
    rango1 = max1.subtract(min1)

    # all bands
    all = image.bandNames()

    # bands to parametrize
    if bands:
        bands_ee = ee.List(bands)
    else:
        bands_ee = image.bandNames()

    inter = ee_list.intersection(bands_ee, all)
    diff = ee_list.difference(all, inter)
    image_ = image.select(inter)

    # Percentage corresponding to the actual value
    percent = image_.subtract(min0).divide(rango0)

    # Taking count of the percentage of the original value in the original
    # range compute the final value corresponding to the final range.
    # Percentage * final_range + final_min

    final = percent.multiply(rango1).add(min1)

    if not drop:
        # Add the rest of the bands (no parametrized)
        final = image.select(diff).addBands(final)

    # return passProperty(image, final, 'system:time_start')
    return ee.Image(final.copyProperties(source=image))
Пример #21
0
    def testDynamicConstructor(self):
        # Test the behavior of the dynamic class constructor.

        # Use a custom set of known functions for classes Foo and Bar.
        # Foo Foo(arg1, [arg2])
        # Bar Foo.makeBar()
        # Bar Foo.takeBar(Bar bar)
        # Baz Foo.baz()
        def MockSend(path, unused_params, unused_method=None, unused_raw=None):
            if path == '/algorithms':
                return {
                    'Foo': {
                        'returns':
                        'Foo',
                        'args': [{
                            'name': 'arg1',
                            'type': 'Object'
                        }, {
                            'name': 'arg2',
                            'type': 'Object',
                            'optional': True
                        }]
                    },
                    'Foo.makeBar': {
                        'returns': 'Bar',
                        'args': [{
                            'name': 'foo',
                            'type': 'Foo'
                        }]
                    },
                    'Foo.takeBar': {
                        'returns':
                        'Bar',
                        'args': [{
                            'name': 'foo',
                            'type': 'Foo'
                        }, {
                            'name': 'bar',
                            'type': 'Bar'
                        }]
                    },
                    'Bar.baz': {
                        'returns': 'Baz',
                        'args': [{
                            'name': 'bar',
                            'type': 'Bar'
                        }]
                    }
                }

        ee.data.send_ = MockSend
        ee.Initialize(None)

        # Try to cast something that's already of the right class.
        x = ee.Foo('argument')
        self.assertEquals(ee.Foo(x), x)

        # Tests for dynamic classes, where there is a constructor.
        #
        # If there's more than 1 arg, call the constructor.
        x = ee.Foo('a')
        y = ee.Foo(x, 'b')
        ctor = ee.ApiFunction.lookup('Foo')
        self.assertEquals(y.func, ctor)
        self.assertEquals(y.args, {'arg1': x, 'arg2': 'b'})

        # Can't cast a primitive; call the constructor.
        self.assertEquals(ctor, ee.Foo(1).func)

        # A computed object, but not this class; call the constructor.
        self.assertEquals(ctor, ee.Foo(ee.List([1, 2, 3])).func)

        # Tests for dynamic classes, where there isn't a constructor.
        #
        # Foo.makeBar and Foo.takeBar should have caused Bar to be generated.
        self.assertTrue(hasattr(ee, 'Bar'))

        # Make sure we can create a Bar.
        bar = ee.Foo(1).makeBar()
        self.assertTrue(isinstance(bar, ee.Bar))

        # Now cast something else to a Bar and verify it was just a cast.
        cast = ee.Bar(ee.Foo(1))
        self.assertTrue(isinstance(cast, ee.Bar))
        self.assertEquals(ctor, cast.func)

        # We shouldn't be able to cast with more than 1 arg.
        try:
            ee.Bar(x, 'foo')
            self.fail('Expected an exception.')
        except ee.EEException as e:
            self.assertTrue('Too many arguments for ee.Bar' in str(e))

        # We shouldn't be able to cast a primitive.
        try:
            ee.Bar(1)
            self.fail('Expected an exception.')
        except ee.EEException as e:
            self.assertTrue('Must be a ComputedObject' in str(e))
Пример #22
0
 def sum_bands(n, ini):
     condition = ee.List(band_names).contains(n)
     return ee.Algorithms.If(condition,
                             ee.Image(ini).add(image.select([n])),
                             ee.Image(ini))
Пример #23
0
def bmaxOtsu(collection,target_data,region,
             smoothing=100,
             qualityBand=None,
             reductionScale=90,
             initThresh=0,
             reverse=False,
             gridSize=0.1,
             bmaxThresh=0.75,
             maxBoxes=100,
             seed=7):

    def constuctGrid(i):
        def contructXGrid(j):
            j = ee.Number(j)
            box = ee.Feature(ee.Geometry.Rectangle(j,i,j.add(gridSize),i.add(gridSize)))
            out = ee.Algorithms.If(geom.contains(box.geometry()),box,null)
            return ee.Feature(out)
        i = ee.Number(i)
        out = ee.List.sequence(west,east.subtract(gridSize),gridSize).map(constuctXGrid)
      return out


    def calcBmax(feature):
        segment = target.clip(feature)
        initial = segment.lt(initThresh)
        p1 = ee.Number(initial.reduceRegion(
            reducer= ee.Reducer.mean(),
            geometry= feature.geometry(),
            bestEffort= True,
            scale= reductionScale,
        ).get(histBand))
        p2 = ee.Number(1).subtract(p1)

        m = segment.updateMask(initial).rename('m1').addBands(
            segment.updateMask(initial.not()).rename('m2')
        )

        mReduced = m.reduceRegion(
            reducer= ee.Reducer.mean(),
            geometry= feature.geometry(),
            bestEffort= True,
            scale= reductionScale,
        )

        m1 = ee.Number(mReduced.get('m1'))
        m2 = ee.Number(mReduced.get('m2'))

        m1 = ee.Number(ee.Algorithms.If(m1,m1,globalLow))
        m2 = ee.Number(ee.Algorithms.If(m2,m2,globalHigh))

        sigmab = p1.multiply(p2.multiply(m1.subtract(m2).pow(2)))
        sigmat = ee.Number(segment.reduceRegion(
            reducer= ee.Reducer.variance(),
            geometry= feature.geometry(),
            bestEffort= True,
            scale= reductionScale,
        ).get(histBand))
        bmax = sigmab.divide(sigmat)
        return feature.set({'bmax':bmax})


    tDate = ee.Date(target_date)
    targetColl = collection.filterDate(tDate,tDate.advance(1,'day'))

    if qualityBand == None:
        histBand = ee.String(target.bandNames().get(0))
        target = targetColl.mosaic()\
            .select(histBand)
    else:
        histBand = ee.String(qualityBand)
        target = targetColl.qualityMosaic(qualityBand)\
            .select(histBand)

    searchRegion = ee.Feature(ee.List(targeColl.map(geeutilsgetGeom).toList(1)).get(0))

    theoretical = target.reduceRegion(
        reducer= ee.Reducer.percentile([10,90]),
        geometry= searchRegion.geometry(),
        bestEffort= True,
        scale: 5000
    )
    globalLow = theoretical.get(histBand.cat('_p10'))
    globalHigh = theoretical.get(histBand.cat('_p90'))

    geom = searchRegion.geometry()
    bounds = geom.bounds()
    coords = ee.List(bounds.coordinates().get(0))
    gridSize = ee.Number(gridSize)

    west = ee.Number(ee.List(coords.get(0)).get(0))
    south = ee.Number(ee.List(coords.get(0)).get(1))
    east = ee.Number(ee.List(coords.get(2)).get(0))
    north = ee.Number(ee.List(coords.get(2)).get(1))

    west = west.subtract(west.mod(gridSize))
    south = south.subtract(south.mod(gridSize))
    east = east.add(gridSize.subtract(east.mod(gridSize)))
    north = north.add(gridSize.subtract(north.mod(gridSize)))

    grid = ee.FeatureCollection(
      ee.List.sequence(south,north.subtract(gridSize),gridSize).map(constuctGrid).flatten()
    )

    bmaxes = grid.map(calcBmax).filter(ee.Filter.gt('bmax',bmaxThresh)).randomColumn('random',seed)

    nBoxes = ee.Number(bmax.size())
    randomThresh = maxBoxes.divide(nBoxes)
    selection = bmaxes.filter(ee.Filter.lt('random',randomThresh))

    histogram =  histogram_image.reduceRegion(ee.Reducer.histogram(255, 2)\
                                .combine('mean', None, True)\
                                .combine('variance', None,True),selection,reductionScale,bestEffort=True,
                                tileScale=16)

    threshold = geeutils.otsu_function(histogram.get(histBand.cat('_histogram')))

    water = target.gt(threshold).clip(geeutils.LAND.geometry())

    return water.rename('water')
Пример #24
0
def toGrid(image, size=1, band=None, geometry=None):
    """ Create a grid from pixels in an image. Results may depend on the image
    projection. Work fine in Landsat imagery.

    IMPORTANT: This grid is not perfect, it can be misplaced and have some
    holes due to projection.

    :param image: the image
    :type image: ee.Image
    :param size: the size of each cell, according to:
        - 1: 1 pixel
        - 2: 9 pixels (3x3)
        - 3: 25 pixels (5x5)
        - and so on..
    :type size: int
    :param band: the band to get the projection (and so, the scale) from. If
        None, the first one will be used
    :type band: str
    :param geometry: the geometry where the grid will be computed. If the image
        is unbounded this parameter must be set in order to work. If None,
        the image geometry will be used if not unbounded.
    :type geometry: ee.Geometry or ee.Feature
    """
    band = band if band else 0
    iband = image.select(band)

    if geometry:
        if isinstance(geometry, ee.Feature):
            geometry = geometry.geometry()
    else:
        geometry = image.geometry()

    projection = iband.projection()
    scale = projection.nominalScale()
    scale = scale.multiply((int(size) * 2) - 1)
    buffer = scale.divide(2)

    # get coordinates image
    latlon = ee.Image.pixelLonLat().reproject(projection)

    # put each lon lat in a list
    coords = latlon.select(['longitude', 'latitude'])

    coords = coords.reduceRegion(reducer=ee.Reducer.toList(),
                                 geometry=geometry.buffer(scale),
                                 scale=scale)

    # get lat & lon
    lat = ee.List(coords.get('latitude'))
    lon = ee.List(coords.get('longitude'))

    # zip them. Example: zip([1, 3],[2, 4]) --> [[1, 2], [3,4]]
    point_list = lon.zip(lat)

    def over_list(p):
        p = ee.List(p)
        point = ee.Geometry.Point(p).buffer(buffer).bounds()
        return ee.Feature(point)

    # make grid
    fc = ee.FeatureCollection(point_list.map(over_list))

    return fc
Пример #25
0
 def test_Container_Get_Item_By_Slice(self):
     """Test the Container Emulation Methods"""
     test = ee.List([1, 2, 3])[0:2]
     self.assertIsInstance(test, ee.ee_list.List)
Пример #26
0
 def over_list(p):
     p = ee.List(p)
     point = ee.Geometry.Point(p).buffer(buffer).bounds()
     return ee.Feature(point)
Пример #27
0
 def test_Container_Contains(self):
     """Test the Container Emulation Methods"""
     test = 2 in ee.List([1, 2, 3])
     self.assertIsInstance(test, bool)
Пример #28
0
def raster_zonal_stats(i_zones,
                       i_values,
                       statistic_type,
                       geometry,
                       crs_transform,
                       crs="EPSG:4326"):
    """ Zonal Statistics using raster zones and values.
    -------------------------------------------------------------------------------
    Output options include a ee.FeatureCollection, pd.DataFrame or ee.Image.
    The count is always included in the output results. 
    
    crs transform can be obtained by the get_crs_transform function.
    
    Note that if a zone does not contain data, the value is missing from the
    dictionary in the list.
    
    Args:
        i_zones (ee.Image) : Integer image with zones.
        i_values (ee.Image) : Image with values.
        statistic_type (string) : Statistics type like 'mean', 'sum'.
        geometry (ee.Geometry) : Geometry defining extent of calculation.
            geometry can be server side.
        nodata_value (integer) : nodata value. Defaults to -9999.
        crs_transform (list) : crs transform. 
        crs (string) : crs, deafults to 'EPSG:4326'.
        
    Returns:
        result_list (ee.List) : list of dictionaries with keys 'zones','count'
            and 'mean/max/sum etc.'. 
            
    """

    if statistic_type == "mean":
        reducer = ee.Reducer.mean().combine(reducer2=ee.Reducer.count(),
                                            sharedInputs=True).group(
                                                groupField=1,
                                                groupName="zones")
    elif statistic_type == "max":
        reducer = ee.Reducer.max().combine(reducer2=ee.Reducer.count(),
                                           sharedInputs=True).group(
                                               groupField=1, groupName="zones")
    elif statistic_type == "sum":
        reducer = ee.Reducer.sum().combine(reducer2=ee.Reducer.count(),
                                           sharedInputs=True).group(
                                               groupField=1, groupName="zones")
    elif statistic_type == "count":
        reducer = ee.Reducer.count().combine(reducer2=ee.Reducer.count(),
                                             sharedInputs=True).group(
                                                 groupField=1,
                                                 groupName="zones")
    elif statistic_type == "first":
        reducer = ee.Reducer.first().combine(reducer2=ee.Reducer.count(),
                                             sharedInputs=True).group(
                                                 groupField=1,
                                                 groupName="zones")
    else:
        raise UserWarning(
            "Statistic_type not yet supported, please modify function")

    total_image = ee.Image(i_values).addBands(ee.Image(i_zones))

    result_list = total_image.reduceRegion(geometry=geometry,
                                           reducer=reducer,
                                           crsTransform=crs_transform,
                                           crs=crs,
                                           maxPixels=1e10).get("groups")

    result_list = ee.List(result_list)
    return result_list
Пример #29
0
            def wrap(img):
                escalables = functions.list_intersection(
                    img.bandNames(), ee.List(self.to_scale))

                return tools.parametrize(rango_orig, final_range,
                                         escalables)(img)
Пример #30
0
 def f_ndvi_clim_p(image, list):
     ndvi = lf_clim_ndvi.select('offset').add(
         (lf_clim_ndvi.select('scale').multiply(image))).set(
             {'year': image.get('year')})
     return ee.List(list).add(ndvi)