Example #1
0
def masker(image: Image):
    cloudShadowBitMask = 1 << 3
    cloudsBitMask = 1 << 5
    qa: Image = image.select('pixel_qa')

    mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0).And(qa.bitwiseAnd(cloudsBitMask).eq(0))
    return image.updateMask(mask)
Example #2
0
def unit(img: ee.Image, epsilon: ee.Image):
    t_max = img.reduce(ee.Reducer.max())
    t_min = img.reduce(ee.Reducer.min())

    united = img.subtract(t_min).divide((t_max.subtract(t_min)).add(epsilon))

    return united
Example #3
0
def cast_shadows(image: ee.Image, cloud: ee.Image) -> ee.Image:
    """
    Calculate potential locations of cloud shadows.

    Adapted from the 3_Sentinel2_CloudAndShadowMask notebook in:
    https://github.com/rdandrimont/AGREE/
    """
    # solar geometry (radians)
    azimuth = (ee.Number(image.get("MEAN_SOLAR_AZIMUTH_ANGLE")).multiply(
        np.pi / 180.0).add(0.5 * np.pi))
    zenith = (ee.Number(0.5 * np.pi).subtract(
        ee.Number(image.get("MEAN_SOLAR_ZENITH_ANGLE")).multiply(np.pi /
                                                                 180.0)))
    # find where cloud shadows should be based on solar geometry
    nominalScale = cloud.projection().nominalScale()

    def change_cloud_projection(cloudHeight):
        shadowVector = zenith.tan().multiply(cloudHeight)
        x = azimuth.cos().multiply(shadowVector).divide(nominalScale).round()
        y = azimuth.sin().multiply(shadowVector).divide(nominalScale).round()
        return cloud.changeProj(cloud.projection(),
                                cloud.projection().translate(x, y))

    cloudHeights = ee.List.sequence(200, 10000, 500)
    shadows = cloudHeights.map(change_cloud_projection)
    shadows = ee.ImageCollection.fromImages(shadows).max()

    # (modified by Sam Murphy) dark pixel detection
    # B3 = green
    # B12 = swir2
    dark = image.normalizedDifference(["B3", "B12"]).gt(0.25)
    shadows = shadows.And(dark)
    return shadows
def addLayer(image: ee.Image,
             visParams=None,
             name=None,
             shown=True,
             opacity=1.0):
    """
        Mimique addLayer GEE function

        https://developers.google.com/earth-engine/api_docs#map.addlayer

        Uses:
            >>> from ee_plugin import Map
            >>> Map.addLayer(.....)
    """

    if not isinstance(image, ee.Image):
        err_str = "\n\nThe image argument in 'addLayer' function must be a 'ee.Image' instance."
        raise AttributeError(err_str)

    if visParams:
        image = image.visualize(**visParams)

    if name is None:
        # extract name from id
        try:
            name = json.loads(
                image.id().serialize())["scope"][0][1]["arguments"]["id"]
        except:
            name = "untitled"

    ee_plugin.utils.add_or_update_ee_image_layer(image, name, shown, opacity)
Example #5
0
def add_map_layer(
    self: folium.Map,
    image: ee.Image,
    vis_params: dict = None,
    name: str = None,
    show: bool = True,
    opacity: float = 1,
    min_zoom: int = 0,
):
    """Add an image layer to a :class:`folium.Map`."""
    import folium
    if vis_params is None:
        vis_params = vis(image)
    if name is None:
        name = ', '.join(image.bandNames().getInfo())
    attribution = ('Map Data &copy; <a href="https://earthengine.google.com/">'
                   'Google Earth Engine</a>')
    tiles = image.getMapId(vis_params)['tile_fetcher']
    folium.raster_layers.TileLayer(
        tiles=tiles.url_format,
        attr=attribution,
        name=name,
        show=show,
        opacity=opacity,
        min_zoom=min_zoom,
        overlay=True,
        control=True,
    ).add_to(self)
Example #6
0
 def print_projection_info(cls, image: ee.Image ):
     bandNames = image.bandNames();
     print(f'Band names: {bandNames}')
     b1proj = image.select('B1').projection()
     print(f'Band 1 projection: {b1proj}' )
     b1scale = image.select('B1').projection().nominalScale()
     print(f'Band 1 scale: {b1scale}')
Example #7
0
 def addCloudAndShadowBand(cls, image: ee.Image) -> ee.Image:
     qa = image.select('pixel_qa')
     cloudBitMask = ee.Number(2).pow(5).int()
     cloudShadowBitMask = ee.Number(2).pow(3).int()
     cloud = qa.bitwiseAnd(cloudBitMask).neq(0)
     cloudShadow = qa.bitwiseAnd(cloudShadowBitMask).neq(0)
     mask = ee.Image(0).where(cloud.eq(1), 1).where(cloudShadow.eq(1), 1).rename('cloud_mask')
     return image.addBands(mask)
def add_evi_ndvi(composite: ee.Image) -> ee.Image:
    red = composite.select("B3")
    blue = composite.select("B1")
    infrared = composite.select("B4")
    return composite.addBands(
        infrared.subtract(red).multiply(2.5).divide(
            infrared.add(red.multiply(6)).subtract(
                blue.multiply(7.5)).add(1))).addBands(
                    composite.normalizedDifference(bandNames=["B4", "B3"]))
Example #9
0
def cloud_mask(img: ee.Image) -> ee.Image:
    img = ee.Image(img)
    qa_band = img.select('QA')
    # Bits 10 and 11 are clouds and cirrus, respectively
    bit_mask_cloud = 1 << 10
    bit_mask_cirrus = 1 << 11
    no_clouds = qa_band.bitwiseAnd(bit_mask_cloud).eq(0).And(
        qa_band.bitwiseAnd(bit_mask_cirrus).eq(0))
    return img.updateMask(no_clouds)
Example #10
0
def vis(img: ee.Image, bands: list = None, region: ee.Geometry = None) -> dict:
    """Return visualization parameters for the given image."""
    region = region or img.geometry()
    bands = bands or img.bandNames().getInfo()
    reducer = ee.Reducer.percentile([1, 99], ['min', 'max'])
    quantiles = img.reduceRegion(reducer, scale=90, bestEffort=True).getInfo()
    return {
        'min': [quantiles[b + '_min'] for b in bands],
        'max': [quantiles[b + '_max'] for b in bands],
    }
Example #11
0
 def indices(cls, image: ee.Image) -> ee.Image:
     bands = ee.Image([
         cls.mndwi(image),
         cls.mbsr(image),
         cls.ndvi(image),
         cls.awesh(image),
         image.select("B"),
         image.select("NIR"),
         image.select("SWIR1"),
         image.select("SWIR2"),
         image.select("cloud_mask")
     ])
     return bands.set('system:time_start', image.get('system:time_start'))
Example #12
0
def add_latlon(img: ee.Image) -> ee.Image:
    '''Creates a new ee.Image with 2 added bands of longitude and latitude
    coordinates named 'LON' and 'LAT', respectively
    '''
    latlon = ee.Image.pixelLonLat().select(
        opt_selectors=['longitude', 'latitude'], opt_names=['LON', 'LAT'])
    return img.addBands(latlon)
Example #13
0
def edge_effect(img: ee.Image) -> ee.Image:
    ones = ee.Image(1)
    resolutionOut = 30
    # Set some constants
    distance = min(255 * resolutionOut, 10000)
    halfLife = 500
    HMeeMax = ee.Image(0)

    seq = arange(0.1, 1.05, 0.05)
    for i in seq:
        HMt = img.gt(i)
        # dt: filter out small "salt" patches
        # JA: keeping this at 90 for now
        HMt = HMt.focal_mean(90, "circle", "meters")
        HMt = HMt.gt(0.5)

        # dt: calculate Euc distance away from 1s
        HMtdistance = HMt.distance(ee.Kernel.euclidean(distance, "meters"),
                                   False)
        HMee = (ee.Image(i).multiply(
            ee.Image(0.5).pow(HMtdistance.divide(
                ee.Image(halfLife)))).unmask(0))
        HMeeMax = HMeeMax.max(HMee)

    return ones.subtract(ones.subtract(HMeeMax).multiply(ones.subtract(img)))
Example #14
0
    def rename_l8(img: ee.Image) -> ee.Image:
        '''
        Args
        - img: ee.Image, Landsat 8 image

        Returns
        - img: ee.Image, with bands renamed

        See: https://developers.google.com/earth-engine/datasets/catalog/LANDSAT_LC08_C01_T1_SR

        Name       Scale Factor Description
        B1         0.0001       Band 1 (Ultra Blue) surface reflectance, 0.435-0.451 um
        B2         0.0001       Band 2 (Blue) surface reflectance, 0.452-0.512 um
        B3         0.0001       Band 3 (Green) surface reflectance, 0.533-0.590 um
        B4         0.0001       Band 4 (Red) surface reflectance, 0.636-0.673 um
        B5         0.0001       Band 5 (Near Infrared) surface reflectance, 0.851-0.879 um
        B6         0.0001       Band 6 (Shortwave Infrared 1) surface reflectance, 1.566-1.651 um
        B7         0.0001       Band 7 (Shortwave Infrared 2) surface reflectance, 2.107-2.294 um
        B10        0.1          Band 10 brightness temperature (Kelvin), 10.60-11.19 um
        B11        0.1          Band 11 brightness temperature (Kelvin), 11.50-12.51 um
        sr_aerosol              Aerosol attributes, see Aerosol QA table
        pixel_qa                Pixel quality attributes, see Pixel QA table
        radsat_qa               Radiometric saturation QA, see Radsat QA table
        '''
        newnames = [
            'AEROS', 'BLUE', 'GREEN', 'RED', 'NIR', 'SWIR1', 'SWIR2', 'TEMP1',
            'TEMP2', 'sr_aerosol', 'pixel_qa', 'radsat_qa'
        ]
        return img.rename(newnames)
Example #15
0
    def rename_l57(img: ee.Image) -> ee.Image:
        '''
        Args
        - img: ee.Image, Landsat 5/7 image

        Returns
        - img: ee.Image, with bands renamed

        See: https://developers.google.com/earth-engine/datasets/catalog/LANDSAT_LT05_C01_T1_SR
             https://developers.google.com/earth-engine/datasets/catalog/LANDSAT_LE07_C01_T1_SR

        Name             Scale Factor Description
        B1               0.0001       Band 1 (blue) surface reflectance, 0.45-0.52 um
        B2               0.0001       Band 2 (green) surface reflectance, 0.52-0.60 um
        B3               0.0001       Band 3 (red) surface reflectance, 0.63-0.69 um
        B4               0.0001       Band 4 (near infrared) surface reflectance, 0.77-0.90 um
        B5               0.0001       Band 5 (shortwave infrared 1) surface reflectance, 1.55-1.75 um
        B6               0.1          Band 6 brightness temperature (Kelvin), 10.40-12.50 um
        B7               0.0001       Band 7 (shortwave infrared 2) surface reflectance, 2.08-2.35 um
        sr_atmos_opacity 0.001        Atmospheric opacity; < 0.1 = clear; 0.1 - 0.3 = average; > 0.3 = hazy
        sr_cloud_qa                   Cloud quality attributes, see SR Cloud QA table. Note:
                                          pixel_qa is likely to present more accurate results
                                          than sr_cloud_qa for cloud masking. See page 14 in
                                          the LEDAPS product guide.
        pixel_qa                      Pixel quality attributes generated from the CFMASK algorithm,
                                          see Pixel QA table
        radsat_qa                     Radiometric saturation QA, see Radiometric Saturation QA table
        '''
        newnames = [
            'BLUE', 'GREEN', 'RED', 'NIR', 'SWIR1', 'TEMP1', 'SWIR2',
            'sr_atmos_opacity', 'sr_cloud_qa', 'pixel_qa', 'radsat_qa'
        ]
        return img.rename(newnames)
Example #16
0
def export(
    image: ee.Image,
    region: ee.Geometry,
    filename: str,
    drive_folder: str,
    monitor: bool = False,
) -> ee.batch.Export:

    task = ee.batch.Export.image(
        image.clip(region),
        filename,
        {
            "scale": 10,
            "region": region,
            "maxPixels": 1e13,
            "driveFolder": drive_folder
        },
    )

    try:
        task.start()
    except ee.ee_exception.EEException as e:
        print(f"Task not started! Got exception {e}")
        return task

    if monitor:
        monitor_task(task)

    return task
Example #17
0
 def _joinFilteredETI(self, et, i):
     time_filter = EEFilter.equals(leftField="system:time_start",
                                   rightField="system:time_start")
     join = ee.Join.inner()
     joinCollETI = EEImageCollection(join.apply(et, i, time_filter))
     return joinCollETI.map(lambda element: EEImage.cat(
         element.get('primary'), element.get('secondary'))).sort(
             'system:time_start')
Example #18
0
def maxvalue(x: ee.Image, scale: Optional[float] = None) -> float:
    """Get a maximum value.

    Returns the maximum value of an ee.Image. The return value
    will be an approximation if the polygon (x.geometry())
    contains too many pixels at the native scale.

    Args:
        x: An ee.Image.
        scale: A nominal scale in meters of the projection
            to work in. Defaults image x$geometry()$projection()$nominalScale().

    Returns:
        An float number describing the x (ee.Image) maximum value.

    Examples:
        >>> import ee
        >>> import ee_extra
        >>> ee.Initialize()
        >>> img = ee.Image.random()
        >>> maxvalue(img)
    """

    if scale is None:
        scale = x.geometry().projection().nominalScale()

    # Create a clean geometry i.e. geodesic = FALSE
    img_geom_local = x.geometry().getInfo()["coordinates"]
    ee_geom = ee.Geometry.Polygon(
        coords=img_geom_local,
        proj="EPSG:4326",
        evenOdd=True,
        maxError=1.0,
        geodesic=False,
    )

    # get max values
    maxval = ee.Image.reduceRegion(
        image=x,
        reducer=ee.Reducer.max(),
        scale=scale,
        geometry=ee_geom,
        bestEffort=True,
    ).getInfo()

    return maxval
Example #19
0
def extract_deforestation_events(LT_segments: ee.Image, start_year: int,
                                 end_year: int,
                                 dsnr_threshold: float) -> ee.Image:
    """
    Given an image with information about loss segments, assumed to be the
    output of get_segment_data, bounds on start and end year, and a threshold
    on the disturbance signal-to-noise ratio (DSNR), filter to only events
    within the years of interest which pass the DSNR threshold.

    Note: the decision to extract the most recent event, rather than the
    selecting the largest or using a different selection mechanism, is made
    because this was written with the goal of identifying deforestation events
    followed by a recovery period.

    Parameters
    ----------
    LT_segments: ee.Image
        Landtrendr segment data, assumed to be the output of get_segment_data
    start_year: int
        The first year to consider for deforestation events.
    end_year: int
        The last year to consider for deforestation events.
    dsnr_threshold: float
        The threshold on the disturbance signal-to-noise ratio (DSNR) for the
        deforestation segments.

    Returns
    -------
    ee.Image
        The input image filtered to the most recent event in each pixel which
        passes the given threshold.
    """
    start_years = LT_segments.arraySlice(0, 0, 1)
    end_years = LT_segments.arraySlice(0, 1, 2)
    dsnr = LT_segments.arraySlice(0, 7, 8)
    mask = (start_years.gte(ee.Image(start_year)).And(
        end_years.lte(ee.Image(end_year))).And(
            dsnr.gte(ee.Image(dsnr_threshold))))

    masked_segments = LT_segments.arrayMask(mask)

    # Extract the most recent segments for each pixel
    # factor of -1 to flip delta, since arraySort is ascending
    sort_by = masked_segments.arraySlice(0, 0, 1).toArray(0).multiply(-1)
    segments_sorted = masked_segments.arraySort(sort_by)
    return segments_sorted.arraySlice(1, 0, 1)
Example #20
0
def addLayer(image: ee.Image,
             visParams=None,
             name=None,
             shown=True,
             opacity=1.0):
    """
        Adds a given EE object to the map as a layer.

        https://developers.google.com/earth-engine/api_docs#map.addlayer

        Uses:
            >>> from ee_plugin import Map
            >>> Map.addLayer(.....)
    """

    if not isinstance(image, ee.Image) and not isinstance(
            image, ee.FeatureCollection) and not isinstance(
                image, ee.Feature) and not isinstance(image, ee.Geometry):
        err_str = "\n\nThe image argument in 'addLayer' function must be an instace of one of ee.Image, ee.Geometry, ee.Feature or ee.FeatureCollection."
        raise AttributeError(err_str)

    if isinstance(image, ee.Geometry) or isinstance(
            image, ee.Feature) or isinstance(image, ee.FeatureCollection):
        features = ee.FeatureCollection(image)

        color = '000000'

        if visParams and 'color' in visParams:
            color = visParams['color']

        image = features.style(**{'color': color})

    else:
        if isinstance(image, ee.Image) and visParams:
            image = image.visualize(**visParams)

    if name is None:
        # extract name from id
        try:
            name = json.loads(
                image.id().serialize())["scope"][0][1]["arguments"]["id"]
        except:
            name = "untitled"

    ee_plugin.utils.add_or_update_ee_image_layer(image, name, shown, opacity)
Example #21
0
def extract_latitude_longitude_pixel(image: ee.Image, geometry: ee.Geometry, bands: list, scale: int = 30, tile_scale: int = 16):

  # extract pixels lat and lons
  coordinates   = image.addBands(image.pixelLonLat()).select(['longitude', 'latitude']+bands)
  coordinates   = coordinates.reduceRegion(reducer=ee.Reducer.toList(), geometry=geometry, scale=scale, bestEffort=False, tileScale=tile_scale)

  # add bands
  band_values = []
  for band in bands:
    band_values.append(np.array(ee.List(coordinates.get(band)).getInfo(), dtype=np.float64))

  # build results
  band_values = np.array(band_values)
  result      = np.zeros(shape=(2+band_values.shape[0], band_values.shape[1]))
  result[0]   = np.array(ee.List(coordinates.get('longitude')).getInfo(), dtype=np.float64)
  result[1]   = np.array(ee.List(coordinates.get('latitude')).getInfo(), dtype=np.float64)
  for i, band_value in enumerate(band_values):
    result[i+2] = band_value

  # result
  return np.stack(result, axis=1)
Example #22
0
    def rescale_l8(img: ee.Image) -> ee.Image:
        '''
        Args
        - img: ee.Image, Landsat 8 image, with bands already renamed
            by rename_l8()

        Returns
        - img: ee.Image, with bands rescaled
        '''
        opt = img.select(
            ['AEROS', 'BLUE', 'GREEN', 'RED', 'NIR', 'SWIR1', 'SWIR2'])
        therm = img.select(['TEMP1', 'TEMP2'])
        masks = img.select(['sr_aerosol', 'pixel_qa', 'radsat_qa'])

        opt = opt.multiply(0.0001)
        therm = therm.multiply(0.1)

        scaled = ee.Image.cat([opt, therm, masks]).copyProperties(img)
        # system properties are not copied
        scaled = scaled.set('system:time_start', img.get('system:time_start'))
        return scaled
Example #23
0
    def rescale_l57(img: ee.Image) -> ee.Image:
        '''
        Args
        - img: ee.Image, Landsat 5/7 image, with bands already renamed
            by rename_157()

        Returns
        - img: ee.Image, with bands rescaled
        '''
        opt = img.select(['BLUE', 'GREEN', 'RED', 'NIR', 'SWIR1', 'SWIR2'])
        atmos = img.select(['sr_atmos_opacity'])
        therm = img.select(['TEMP1'])
        masks = img.select(['sr_cloud_qa', 'pixel_qa', 'radsat_qa'])

        opt = opt.multiply(0.0001)
        atmos = atmos.multiply(0.001)
        therm = therm.multiply(0.1)

        scaled = ee.Image.cat([opt, therm, masks, atmos]).copyProperties(img)
        # system properties are not copied
        scaled = scaled.set('system:time_start', img.get('system:time_start'))
        return scaled
Example #24
0
def mask_qaclear(img: ee.Image) -> ee.Image:
    '''
    Args
    - img: ee.Image

    Returns
    - img: ee.Image, input image with cloud-shadow, snow, cloud, and unclear
        pixels masked out
    '''
    qam = decode_qamask(img)
    cloudshadow_mask = qam.select('pxqa_cloudshadow')
    snow_mask = qam.select('pxqa_snow')
    cloud_mask = qam.select('pxqa_cloud')
    return img.updateMask(cloudshadow_mask).updateMask(snow_mask).updateMask(
        cloud_mask)
Example #25
0
def addLayer(image: ee.Image, visParams=None, name='untitled', shown=True, opacity=1.0):
    """
        Mimique addLayer GEE function

        Uses:
            >>> from ee_plugin import Map
            >>> Map.addLayer(.....)
    """
    if not isinstance(image, ee.Image):
        err_str = "\n\nThe image argument in 'addLayer' function must be a 'ee.Image' instance."
        raise AttributeError(err_str)

    if visParams:
        image = image.visualize(**visParams)

    ee_plugin.utils.add_or_update_ee_image_layer(image, name, shown, opacity)
Example #26
0
def get_array_patches(img: ee.Image,
                      scale: Numeric,
                      ksize: Numeric,
                      points: ee.FeatureCollection,
                      export: str,
                      prefix: str,
                      fname: str,
                      selectors: Optional[ee.List] = None,
                      dropselectors: Optional[ee.List] = None,
                      bucket: Optional[str] = None) -> ee.batch.Task:
    '''Creates and starts a task to export square image patches in TFRecord
    format to Google Drive or Google Cloud Storage (GCS). The image patches are
    sampled from the given ee.Image at specific coordinates.

    Args
    - img: ee.Image, image covering the entire region of interest
    - scale: int or float, scale in meters of the projection to sample in
    - ksize: int or float, radius of square image patch
    - points: ee.FeatureCollection, coordinates from which to sample patches
    - export: str, 'drive' for Google Drive, 'gcs' for GCS
    - prefix: str, folder name in Drive or GCS to export to, no trailing '/'
    - fname: str, filename for export
    - selectors: None or ee.List, names of properties to include in output,
        set to None to include all properties
    - dropselectors: None or ee.List, names of properties to exclude
    - bucket: None or str, name of GCS bucket, only used if export=='gcs'

    Returns: ee.batch.Task
    '''
    kern = ee.Kernel.square(radius=ksize, units='pixels')
    patches_array = img.neighborhoodToArray(kern)

    # ee.Image.sampleRegions() does not cut it for larger collections,
    # using mapped sample instead
    samples = points.map(lambda pt: sample_patch(pt, patches_array, scale))

    # export to a TFRecord file which can be loaded directly in TensorFlow
    return tfexporter(collection=samples,
                      export=export,
                      prefix=prefix,
                      fname=fname,
                      selectors=selectors,
                      dropselectors=dropselectors,
                      bucket=bucket)
Example #27
0
def sample_patch(point: ee.Feature, patches_array: ee.Image,
                 scale: Numeric) -> ee.Feature:
    '''Extracts an image patch at a specific point.

    Args
    - point: ee.Feature
    - patches_array: ee.Image, Array Image
    - scale: int or float, scale in meters of the projection to sample in

    Returns: ee.Feature, 1 property per band from the input image
    '''
    arrays_samples = patches_array.sample(region=point.geometry(),
                                          scale=scale,
                                          projection='EPSG:3857',
                                          factor=None,
                                          numPixels=None,
                                          dropNulls=False,
                                          tileScale=12)
    return arrays_samples.first().copyProperties(point)
Example #28
0
def decode_qamask(img: ee.Image) -> ee.Image:
    '''
    Args
    - img: ee.Image, Landsat 5/7/8 image containing 'pixel_qa' band

    Returns
    - masks: ee.Image, contains 5 bands of masks

    Pixel QA Bit Flags (universal across Landsat 5/7/8)
    Bit  Attribute
    0    Fill
    1    Clear
    2    Water
    3    Cloud Shadow
    4    Snow
    5    Cloud
    '''
    qa = img.select('pixel_qa')
    clear = qa.bitwiseAnd(2).neq(0)  # 0 = not clear, 1 = clear
    clear = clear.updateMask(clear).rename(['pxqa_clear'])

    water = qa.bitwiseAnd(4).neq(0)  # 0 = not water, 1 = water
    water = water.updateMask(water).rename(['pxqa_water'])

    cloud_shadow = qa.bitwiseAnd(8).eq(0)  # 0 = shadow, 1 = not shadow
    cloud_shadow = cloud_shadow.updateMask(cloud_shadow).rename(
        ['pxqa_cloudshadow'])

    snow = qa.bitwiseAnd(16).eq(0)  # 0 = snow, 1 = not snow
    snow = snow.updateMask(snow).rename(['pxqa_snow'])

    cloud = qa.bitwiseAnd(32).eq(0)  # 0 = cloud, 1 = not cloud
    cloud = cloud.updateMask(cloud).rename(['pxqa_cloud'])

    masks = ee.Image.cat([clear, water, cloud_shadow, snow, cloud])
    return masks
Example #29
0
    def addStats(img: ee.Image) -> ee.Image:
        patch = ee.Geometry(img.get('patch'))
        patch_area = patch.area(0.001)

        img_footprint = ee.Algorithms.GeometryConstructors.Polygon(
            ee.Geometry(img.get('system:footprint')).coordinates())
        intersection = patch.intersection(img_footprint, ee.ErrorMargin(0.001))
        intersection_area = intersection.area(0.001)
        coverage = ee.Number(intersection_area).divide(patch_area)

        cloud_area_img = img.select('clouds').multiply(ee.Image.pixelArea())
        stats = cloud_area_img.reduceRegion(reducer=ee.Reducer.sum(),
                                            geometry=patch,
                                            scale=10,
                                            maxPixels=1e12)
        cloud_area = stats.get('clouds')
        cloud_coverage = ee.Number(cloud_area).divide(patch_area)
        img = img.set('patchCoverage', coverage)
        img = img.set('patchCloudCoverage', cloud_coverage)

        score = coverage.multiply(cloud_coverage)
        img = img.set('patchScore', score)
        return img
Example #30
0
 def normalize_mapper(img: ee.Image):
     return img.subtract(min_value).divide(max_value - min_value).clamp(
         0, 1).copyProperties(img)