Skip to content

Commit

Permalink
improved resampling and renamed function for clarity
Browse files Browse the repository at this point in the history
  • Loading branch information
kcartier-wri committed Dec 20, 2024
1 parent 66baa49 commit b8965b9
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 51 deletions.
28 changes: 15 additions & 13 deletions city_metrix/layers/albedo.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import xarray
from dask.diagnostics import ProgressBar

from .layer import Layer, get_utm_zone_epsg, get_image_collection, set_resampling_method
from .layer import Layer, get_utm_zone_epsg, get_image_collection, set_resampling_for_continuous_raster


class Albedo(Layer):
Expand All @@ -15,16 +15,16 @@ class Albedo(Layer):
threshold: threshold value for filtering the retrieval
"""

def __init__(self, start_date="2021-01-01", end_date="2022-01-01", spatial_resolution=10,
resampling_method='bilinear', threshold=None, **kwargs):
def __init__(self, start_date="2021-01-01", end_date="2022-01-01", spatial_resolution:int=10,
resampling_method:str='bilinear', threshold=None, **kwargs):
super().__init__(**kwargs)
self.start_date = start_date
self.end_date = end_date
self.spatial_resolution = spatial_resolution
self.resampling_method = resampling_method
self.threshold = threshold

def get_data(self, bbox):
def get_data(self, bbox: tuple[float, float, float, float]):
S2 = ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
S2C = ee.ImageCollection("COPERNICUS/S2_CLOUD_PROBABILITY")

Expand Down Expand Up @@ -121,15 +121,17 @@ def calc_s2_albedo(image):
## S2 MOSAIC AND ALBEDO
dataset = get_masked_s2_collection(ee.Geometry.BBox(*bbox), self.start_date, self.end_date)
s2_albedo = dataset.map(calc_s2_albedo)
if self.resampling_method is not None:
albedo_mean = (s2_albedo
.map(lambda x: set_resampling_method(x, self.resampling_method))
.reduce(ee.Reducer.mean())
)
else:
albedo_mean = (s2_albedo
.reduce(ee.Reducer.mean())
)

albedo_mean = (s2_albedo
.map(lambda x:
set_resampling_for_continuous_raster(x,
self.resampling_method,
self.spatial_resolution,
bbox
)
)
.reduce(ee.Reducer.mean())
)

albedo_mean_ic = ee.ImageCollection(albedo_mean)
data = get_image_collection(
Expand Down
35 changes: 17 additions & 18 deletions city_metrix/layers/alos_dsm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import xarray as xr


from .layer import Layer, get_image_collection, set_resampling_method
from .layer import Layer, get_image_collection, set_resampling_for_continuous_raster


class AlosDSM(Layer):
Expand All @@ -13,29 +13,28 @@ class AlosDSM(Layer):
resampling_method: interpolation method used by Google Earth Engine. Default is 'bilinear'. All options are: ('bilinear', 'bicubic', None).
"""

def __init__(self, spatial_resolution=30, resampling_method='bilinear', **kwargs):
def __init__(self, spatial_resolution:int=30, resampling_method:str='bilinear', **kwargs):
super().__init__(**kwargs)
self.spatial_resolution = spatial_resolution
self.resampling_method = resampling_method

def get_data(self, bbox):
def get_data(self, bbox: tuple[float, float, float, float]):
alos_dsm = ee.ImageCollection("JAXA/ALOS/AW3D30/V3_2")

if self.resampling_method is not None:
alos_dsm_ic = ee.ImageCollection(
alos_dsm
.filterBounds(ee.Geometry.BBox(*bbox))
.map(lambda x: set_resampling_method(x, self.resampling_method), )
.select('DSM')
.mean()
)
else:
alos_dsm_ic = ee.ImageCollection(
alos_dsm
.filterBounds(ee.Geometry.BBox(*bbox))
.select('DSM')
.mean()
)
alos_dsm_ic = ee.ImageCollection(
alos_dsm
.filterBounds(ee.Geometry.BBox(*bbox))
.select('DSM')
.map(lambda x:
set_resampling_for_continuous_raster(x,
self.resampling_method,
self.spatial_resolution,
bbox
)
)
.mean()
)


data = get_image_collection(
alos_dsm_ic,
Expand Down
17 changes: 14 additions & 3 deletions city_metrix/layers/layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,14 +325,25 @@ def get_stats_funcs(stats_func):
return [stats_func]


def set_resampling_method(image: ee.Image, resampling_method: str):
valid_raster_resampling_methods = ['bilinear', 'bicubic']
def set_resampling_for_continuous_raster(image: ee.Image, resampling_method: str, resolution: int,
bbox: tuple[float, float, float, float]):
"""
Function sets the resampling method on the GEE query dictionary for use on continuous raster layers.
GEE only supports bilinear and bicubic interpolation methods.
"""
valid_raster_resampling_methods = ['bilinear', 'bicubic', None]

if resampling_method not in valid_raster_resampling_methods:
raise ValueError(f"Invalid resampling method ('{resampling_method}'). "
f"Valid methods: {valid_raster_resampling_methods}")

data = image.resample(resampling_method)
if resampling_method is None:
data = image
else:
crs = get_utm_zone_epsg(bbox)
data = (image
.resample(resampling_method)
.reproject(crs=crs, scale=resolution))

return data

Expand Down
31 changes: 15 additions & 16 deletions city_metrix/layers/nasa_dem.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import xee
import xarray as xr

from .layer import Layer, get_image_collection, set_resampling_method
from .layer import Layer, get_image_collection, set_resampling_for_continuous_raster


class NasaDEM(Layer):
Expand All @@ -12,27 +12,26 @@ class NasaDEM(Layer):
resampling_method: interpolation method used by Google Earth Engine. Default is 'bilinear'. All options are: ('bilinear', 'bicubic', None).
"""

def __init__(self, spatial_resolution=30, resampling_method='bilinear', **kwargs):
def __init__(self, spatial_resolution:int=30, resampling_method:str='bilinear', **kwargs):
super().__init__(**kwargs)
self.spatial_resolution = spatial_resolution
self.resampling_method = resampling_method

def get_data(self, bbox):
def get_data(self, bbox: tuple[float, float, float, float]):
nasa_dem = ee.Image("NASA/NASADEM_HGT/001")

if self.resampling_method is not None:
nasa_dem_elev = (ee.ImageCollection(nasa_dem)
.filterBounds(ee.Geometry.BBox(*bbox))
.map(lambda x: set_resampling_method(x, self.resampling_method), )
.select('elevation')
.mean()
)
else:
nasa_dem_elev = (ee.ImageCollection(nasa_dem)
.filterBounds(ee.Geometry.BBox(*bbox))
.select('elevation')
.mean()
)
nasa_dem_elev = (ee.ImageCollection(nasa_dem)
.filterBounds(ee.Geometry.BBox(*bbox))
.select('elevation')
.map(lambda x:
set_resampling_for_continuous_raster(x,
self.resampling_method,
self.spatial_resolution,
bbox
)
)
.mean()
)

nasa_dem_elev_ic = ee.ImageCollection(nasa_dem_elev)
data = get_image_collection(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

TARGET_RESOLUTION = 5
TARGET_RESAMPLING_METHOD = 'bilinear'
# TARGET_RESAMPLING_METHOD = None

@pytest.mark.skipif(RUN_DUMPS == False, reason='Skipping since RUN_DUMPS set to False')
def test_write_albedo_fixed_res(target_folder, bbox_info, target_spatial_resolution_multiplier):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_layer_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def test_albedo_metrics_default_resampling():

# Bounding values
expected_min_value = _convert_fraction_to_rounded_percent(0.03)
expected_max_value = _convert_fraction_to_rounded_percent(0.32)
expected_max_value = _convert_fraction_to_rounded_percent(0.34)
actual_min_value = _convert_fraction_to_rounded_percent(data.values.min())
actual_max_value = _convert_fraction_to_rounded_percent(data.values.max())

Expand Down

0 comments on commit b8965b9

Please sign in to comment.