You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, the integration of remote sensing data in aeolis-python requires preprocessing where the geospatial metadata and preprocessing steps (e.g. rotation) are not stored in the output netCDF file. This limits both the implementation potential for digital twins and the compatibility of the resulting NetCDF with existing geospatial packages. I propose to make it possible to read geotiff files, extract geospatial metadata, and initialize the model state variables using the geotiff data.
Solution Overview
To improve the integration of remote sensing data, I propose the following enhancements:
Integrate functions to read geotiff files and extract geospatial metadata. This will allow reading the arrays of geotiff-based digital elevation models (DEMs) and other remote sensing data. I would propose to integrate functionality to correct for precision errors in the resolution for robustness.
Integrate a function to calculate the x and y grid coordinates based on the geotiff metadata. This will ensure accurate spatial representation of the input data.
Add a configuration file parameter for specifying the path to the DEM geotiff file.
Pass the three grids (x, y, zb) to the constants (initial state) if the DEM path is present in the configuration. This will initialize the model state with the actual spatial coordinates and elevation data from the geotiff.
Add the true x and y grid coordinates to the output netCDF file. Add the geospatial metadata to the output netCDF file.
Ensure that the output netCDF file is compatible with the xarray transform function xds["zb"].rio.to_raster('DEM_prediction.tif'). This will enable posthoc conversion for backwards compatibility.
Required Functions
The following functions would be needed to implement the proposed solution:
defread_geotiff_as_array(geotiff_path):
""" Reads a single-band geotiff file into a NumPy array. Parameters: - geotiff_path: String. Path to the geotiff file. Returns: - NumPy array containing the raster data from the first band. """withrasterio.open(geotiff_path) asdataset:
# Read the raster data as a NumPy arrayraster_data=dataset.read(1) # Reads the first bandreturnraster_datadefextract_geotiff_metadata(geotiff_path):
""" Extracts spatial metadata from a geotiff file, dynamically addressing floating-point precision errors. Parameters: - geotiff_path: Path to the geotiff file. Returns: - A dictionary containing the CRS, transform, dynamically adjusted cell resolution for precision, and geotiff dimensions. """withrasterio.open(geotiff_path) asgeotiff:
# Dynamically determine the number of decimal places based on the resolution# This finds the first significant decimal place in the resolutionsignificant_figures=-int(math.floor(math.log10(abs(geotiff.res[0]))))
# Add additional precision to accommodate floating-point representationprecision=significant_figures+2# Address precision issue by rounding the resolutionds=round(geotiff.res[0], precision)
dn=round(geotiff.res[1], precision)
# Round the resolution components of the transforma=round(geotiff.transform.a, precision) # Resolution in X directione=round(geotiff.transform.e, precision) # Resolution in Y direction (typically negative)# Create a new transform with the adjusted resolution# Note: This assumes no rotation; adjust accordingly if your geotiffs may have rotationadjusted_transform=Affine(a, geotiff.transform.b, geotiff.transform.c,
geotiff.transform.d, e, geotiff.transform.f)
crs=geotiff.crsgeotiff_data=geotiff.read(1)
ny, nx=geotiff_data.shape# Calculate grid cell surface area and its inversedsdn=ds*abs(dn)
dsdni=1/dsdn# Return the adjusted metadatareturn {
'crs': crs,
'transform': adjusted_transform,
'ds': ds, # Adjusted for flexible precision'dn': dn, # Adjusted for flexible precision'dsdn': dsdn, # Real-world grid cell surface area'dsdni': dsdni, # Inverse of real-world grid cell surface area'nx': nx,
'ny': ny,
'zb': geotiff_data# Include the geotiff data in the metadata for further processing
}
defcalculate_grid_coordinates(transform, nx, ny):
# Calculate the center coordinates for each pixelx=np.arange(nx) *transform.a+transform.c+ (transform.a/2) # center of pixely=np.arange(ny) *transform.e+transform.f+ (transform.e/2) # center of pixelreturnx, y
These above functions can be integrated into utils.py to enable reading geotiffs, extracting metadata, and initializing the model state with the spatial information.
The following variables in MODEL_STATE constants.py would be derived from the DEM geotiff:
('ny', 'nx') : (
'x', # [m] Real-world x-coordinate of grid cell center'y', # [m] Real-world y-coordinate of grid cell center'ds', # [m] Real-world grid cell size in x-direction'dn', # [m] Real-world grid cell size in y-direction'dsdn', # [m^2] Real-world grid cell surface area'dsdni', # [m^-2] Inverse of real-world grid cell surface area'zb', # [m] Bed level above reference
)
Finally, the following variables should be passed to the netCDF file in netcdf.py when the simulation data is written to make it compatible to geospatial packages:
# store spatial metadatanc.variables['x'][:,:] =s['x']
nc.variables['y'][:,:] =s['y']
nc.variables['lat'][:,:] =s['lat'] # Add latitude valuesnc.variables['lon'][:,:] =s['lon'] # Add longitude valuesnc.variables['x_bounds'][:,:,:] =s['x_bounds'] # Add x-coordinate boundsnc.variables['y_bounds'][:,:,:] =s['y_bounds'] # Add y-coordinate boundsnc.variables['lat_bounds'][:,:,:] =s['lat_bounds'] # Add latitude boundsnc.variables['lon_bounds'][:,:,:] =s['lon_bounds'] # Add longitude bounds# store geotiff metadatanc.variables['crs'].spatial_ref=s['crs'].to_string() # Add CRS as spatial reference stringnc.variables['crs'].GeoTransform=' '.join(map(str, s['transform'])) # Add GeoTransform attribute# store model state variables derived from geotiffnc.variables['zb'][:,:] =s['zb'] # Bed levelnc.variables['ds'][:] =s['ds'] # Grid cell size in x-directionnc.variables['dn'][:] =s['dn'] # Grid cell size in y-directionnc.variables['dsdn'][:] =s['dsdn'] # Grid cell surface areanc.variables['dsdni'][:] =s['dsdni'] # Inverse of grid cell surface area
The text was updated successfully, but these errors were encountered:
Description
Currently, the integration of remote sensing data in aeolis-python requires preprocessing where the geospatial metadata and preprocessing steps (e.g. rotation) are not stored in the output netCDF file. This limits both the implementation potential for digital twins and the compatibility of the resulting NetCDF with existing geospatial packages. I propose to make it possible to read geotiff files, extract geospatial metadata, and initialize the model state variables using the geotiff data.
Solution Overview
To improve the integration of remote sensing data, I propose the following enhancements:
xds["zb"].rio.to_raster('DEM_prediction.tif')
. This will enable posthoc conversion for backwards compatibility.Required Functions
The following functions would be needed to implement the proposed solution:
These above functions can be integrated into
utils.py
to enable reading geotiffs, extracting metadata, and initializing the model state with the spatial information.The following variables in MODEL_STATE
constants.py
would be derived from the DEM geotiff:Finally, the following variables should be passed to the netCDF file in
netcdf.py
when the simulation data is written to make it compatible to geospatial packages:The text was updated successfully, but these errors were encountered: