Examples on how to use python libraries to access and use COGs. Demonstrating one of the cloud
optimized advantages, being able to access a portion of the data without having to download the entire file.
importpystac_clientimportrasterio# Define a bounding box for an AOI (Ottawa) in EPSG:4326bbox=[-75.8860,45.3157,-75.5261,45.5142]bbox_crs="EPSG:4326"# Link to ccmeo datacube stac-apistac_root="https://datacube.services.geo.ca/stac/api"catalog=pystac_client.Client.open(stac_root)search=catalog.search(collections=['mrdem-30'],bbox=bbox,)# Get the link to the data asset for mrdem-30 dtmlinks=[]forpageinsearch.pages():foriteminpage:links.append(item.assets['dtm'].href)# Read the header of a remote COG withrasterio.open(links[0])assrc:# Read the header of a COGprint(src.tags())# >> {'AREA_OR_POINT': 'Area', # 'TIFFTAG_DATETIME': '2024:06:13 12:00:00'}print(src.profile)# >> {'driver': 'GTiff', 'dtype': 'float32', 'nodata': -32767.0, # 'width': 183687, 'height': 159655, 'count': 1, # 'crs': CRS.from_epsg(3979), 'transform': Affine(30.0, 0.0, # -2454000.0, 0.0, -30.0, 3887400.0), 'blockxsize': 512, # 'blockysize': 512, 'tiled': True, 'compress': 'lzw', # 'interleave': 'band'}
Query a STAC API with pystac-client to get link to a COG;
Read a portion of a remote COG based on an AOI with the window functionality;
Optionally write the portion locally inside a .tif file
Info
This specific example uses the collection mrdem-30 from CCMEO's datacube
Tip
COG'S file contains internal tiling that can be leverage by iterating on
the src.block_windows() while reading. If the reading window does not align with
the internal tiling of the file, the data will be resampled.
importpystac_clientimportrasteriofromrasterio.windowsimportfrom_boundsfromrasterio.warpimporttransform_geomfromshapely.geometryimportbox,shape# Define a bounding box for an AOI (Ottawa) in EPSG:4326bbox=[-75.8860,45.3157,-75.5261,45.5142]bbox_crs="EPSG:4326"# Link to ccmeo datacube stac-apistac_root="https://datacube.services.geo.ca/stac/api"catalog=pystac_client.Client.open(stac_root)search=catalog.search(collections=['mrdem-30'],bbox=bbox,)# Get the link to the data asset for mrdem-30 dtmlinks=[]forpageinsearch.pages():foriteminpage:links.append(item.assets['dtm'].href)# Read AOI from the first COGwithrasterio.open(links[0])assrc:# Transform bbox to src EPSGtransformed_bbox=shape(transform_geom(src.crs,bbox_crs,box(*bbox))).bounds# Define the window to read the valueswindow=from_bounds(transformed_bbox[0],transformed_bbox[1],transformed_bbox[2],transformed_bbox[3],src.transform)# Read value from filerst=src.read(1,window=window)# Copy and update the source metadata to write the output tiffmetadata=src.meta.copy()metadata.update({'height':window.height,'width':window.width,'transform':rasterio.windows.transform(window,src.transform)})# Perform analysis ...# Write the output array to a tiff fileoutput_tiff=r"path/to/output.tif"withrasterio.open(output_tiff,'w',**metadata)asdst:dst.write(rst)