Module geodata_harvester.getdata_radiometric
Script to download Radiometric data from NCI’s GSKY Data Server (using WCS) for a given resolution, and bounding box. Final data is saved as geotiff or NetCDF.
A full ist of datasets can be retrieved with get_radiometricdict() or get_capabilities() for a given url An overview of all datasets can be also found here: https://opus.nci.org.au/display/Help/Datasets
For more details of the NCI GSKY WCS, please see here: https://opus.nci.org.au/pages/viewpage.action?pageId=137199852
LIMITATIONS: for some layers the server readout time can occasionally exceed 30s (longer readout time in request seems to be ignored) In case this happens please try later again when the NCI server is less loaded.
This package is part of the Data Harvester project developed for the Agricultural Research Federation (AgReFed).
Copyright 2022 Sydney Informatics Hub (SIH), The University of Sydney
This open-source software is released under the LGPL-3.0 License.
Author: Sebastian Haan
Expand source code
"""
Script to download Radiometric data from NCI’s GSKY Data Server (using WCS) for a given
resolution, and bounding box. Final data is saved as geotiff or NetCDF.
A full ist of datasets can be retrieved with get_radiometricdict() or get_capabilities() for a given url
An overview of all datasets can be also found here:
https://opus.nci.org.au/display/Help/Datasets
For more details of the NCI GSKY WCS, please see here:
https://opus.nci.org.au/pages/viewpage.action?pageId=137199852
LIMITATIONS: for some layers the server readout time can occasionally exceed 30s (longer readout time in request seems to be ignored)
In case this happens please try later again when the NCI server is less loaded.
This package is part of the Data Harvester project developed for the Agricultural Research Federation (AgReFed).
Copyright 2022 Sydney Informatics Hub (SIH), The University of Sydney
This open-source software is released under the LGPL-3.0 License.
Author: Sebastian Haan
"""
import os
from owslib.wcs import WebCoverageService
import rasterio
from rasterio.plot import show
from datetime import datetime, timezone
from termcolor import cprint, colored
from alive_progress import alive_bar, config_handler
from geodata_harvester import utils
from geodata_harvester.utils import spin
def get_radiometricdict():
    """
    Returns dictionary of keys and layer titles
    To update manually please run get_capabilities() to retrieve all current layer details
    """
    rmdict = {
        "resolution_arcsec": 3.6,
        "layernames": {
            "radmap2019_grid_dose_terr_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 unfiltered terrestrial dose rate",
            "radmap2019_grid_dose_terr_filtered_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 filtered terrestrial xf",
            "radmap2019_grid_k_conc_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 unfiltered pct potassium",
            "radmap2019_grid_k_conc_filtered_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 filtered pct potassium grid",
            "radmap2019_grid_th_conc_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 unfiltered ppm thorium",
            "radmap2019_grid_th_conc_filtered_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 filtered ppm thorium",
            "radmap2019_grid_thk_ratio_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 ratio thorium over potassium",
            "radmap2019_grid_u2th_ratio_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 ratio uranium squared over thorium",
            "radmap2019_grid_u_conc_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 unfiltered ppm uranium",
            "radmap2019_grid_u_conc_filtered_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 filtered ppm uranium",
            "radmap2019_grid_uk_ratio_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 ratio uranium over potassium",
            "radmap2019_grid_uth_ratio_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 ratio uranium over thorium",
        },
    }
    return rmdict
def getdict_license():
    """
    Retrieves the Geoscience Australia data license and NCI attribution information as dict
    """
    dict = {
        "name": "Geoscience Australia National Geophysical Compilation Sub-collection Radiometrics",
        "source_url": "https://opus.nci.org.au/display/Help/Datasets",
        "license": "CC BY 4.0",
        "license_title": "Creative Commons Attribution 4.0 International (CC BY 4.0)",
        "license_url": "https://creativecommons.org/licenses/by/4.0/",
        "copyright": "© Copyright 2017-2022, Geoscience Australia",
        "attribution": "Geoscience Australia. The WCS service relies on GSKY - A Scalable, Distributed Geospatial Data Service \
from the National Centre for Environmental Information (NCI).",
    }
    return dict
def plot_raster(infname):
    """
    Read in raster tif with rasterio and visualise as map.
    Parameters
    ----------
    infname : str
    """
    data = rasterio.open(infname)
    # show image
    show(data)
def get_capabilities():
    """
    Get capabilities from WCS layer.
    Parameters
    ----------
    url : str
        layer url
    Returns
    -------
    keys    : list
        layer identifiers
    titles  : list  of str
        layer titles
    descriptions : list of str
        layer descriptions
    bboxs   : list of floats
        layer bounding boxes
    """
    # URL
    url = "https://gsky.nci.org.au/ows/national_geophysical_compilations?service=WCS&version=1.0.0&request=GetCapabilities"
    # Create WCS object
    wcs = WebCoverageService(url, version="1.0.0", timeout=300)
    # Get coverages and content dict keys
    content = wcs.contents
    keys = content.keys()
    print("Following data layers are available:")
    title_list = []
    description_list = []
    bbox_list = []
    for key in keys:
        print(f"key: {key}")
        print(f"title: {wcs[key].title}")
        title_list.append(wcs[key].title)
        print(f"{wcs[key].abstract}")
        description_list.append(wcs[key].abstract)
        print(f"bounding box: {wcs[key].boundingBoxWGS84}")
        bbox_list.append(wcs[key].boundingBoxWGS84)
        print("")
    return keys, title_list, description_list, bbox_list
def get_radiometric_layers(
    outpath, layernames, bbox, resolution=1, crs="EPSG:4326", format_out="GeoTIFF"
):
    """
    Wrapper function for downloading radiometric data layers and save geotiffs from WCS layer.
    Parameters
    ----------
    outpath: str
        output path
    layername : list of strings
        layer identifiers
    bbox : list
        layer bounding box
    resolution : int
        layer resolution in arcsec
    url : str
        url of wcs server
    crs: str
        crsm default 'EPSG:4326'
    format_out: str
        output format, either "GeoTIFF" or "NetCDF"
    Return
    ------
    list of output filenames
    """
    url = "https://gsky.nci.org.au/ows/national_geophysical_compilations?service=WCS"
    if type(layernames) != list:
        layernames = [layernames]
    if format_out == "GeoTIFF":
        fname_end = ".tif"
    elif format_out == "NetCDF":
        fname_end = ".nc"
    else:
        print(
            f"\u2716 {format_out} not supported. Choose either GeoTIFF or NetCDF.")
        return outfnames
    # Loop over all layers
    fnames_out = []
    for layername in layernames:
        outfname = os.path.join(
            outpath, "radiometric_" + layername + fname_end)
        ok = get_radiometric_image(
            outfname, layername, bbox, url, resolution=1, crs=crs, format_out=format_out
        )
        if ok:
            fnames_out.append(outfname)
    return fnames_out
def get_radiometric_image(
    outfname, layername, bbox, url, resolution=1, crs="EPSG:4326", format_out="GeoTIFF"
):
    """
    Download radiometric data layer and save geotiff from WCS layer.
    Parameters
    ----------
    outfname : str
        output file name
    layername : str
        layer identifier
    bbox : list
        layer bounding box
    resolution : int
        layer resolution in arcsec
    url : str
        url of wcs server
    crs: str
        crsm default 'EPSG:4326'
    format: str
        output format, either "GeoTIFF" or "NetCDF"
    Return
    ------
    Exited ok: boolean
    """
    # If the resolution passed is None, set to native resolution of datasource
    if resolution is None:
        resolution = get_radiometricdict()["resolution_arcsec"]
    # Convert resolution into width and height pixel number
    width = abs(bbox[2] - bbox[0])
    height = abs(bbox[3] - bbox[1])
    nwidth = int(width / resolution * 3600)
    nheight = int(height / resolution * 3600)
    # Get date
    times = get_times(url, layername)
    # There is only one time available per layer
    date = times[0]
    # Get data
    if os.path.exists(outfname):
        utils.msg_warn(f"{layername}.tif already exists, skipping download")
    else:
        try:
            with spin(f"Downloading {layername}") as s:
                wcs = WebCoverageService(url, version="1.0.0", timeout=300)
                data = wcs.getCoverage(
                    identifier=layername,
                    time=[date],
                    bbox=bbox,
                    format=format_out,
                    crs=crs,
                    width=nwidth,
                    height=nheight,
                )
                s(1)
        except:
            utils.msg_err("Download failed")
            return False
        # Save data
        with open(outfname, "wb") as f:
            f.write(data.read())
        # print(f"Layer {layername} saved in {outfname}")
    return True
def get_times(url, layername, year=None):
    """
    Return available dates for layer.
    Parameters
    ----------
    url: str, layer url
    layername: str, name of layer id
    year: int or str, year of interest (if None, times for all available years are returned)
    Return
    ------
    list of dates
    """
    wcs = WebCoverageService(url, version="1.0.0", timeout=300)
    times = wcs[layername].timepositions
    if year is None:
        return times
    else:
        year = int(year)
        dates = []
        for time in times:
            if datetime.fromisoformat(time[:-1]).astimezone(timezone.utc).year == year:
                dates.append(time)
        return dates
Functions
def get_capabilities()- 
Get capabilities from WCS layer.
Parameters
url:str- layer url
 
Returns
keys : list- layer identifiers
 titles : listofstr- layer titles
 descriptions:listofstr- layer descriptions
 bboxs : listoffloats- layer bounding boxes
 
Expand source code
def get_capabilities(): """ Get capabilities from WCS layer. Parameters ---------- url : str layer url Returns ------- keys : list layer identifiers titles : list of str layer titles descriptions : list of str layer descriptions bboxs : list of floats layer bounding boxes """ # URL url = "https://gsky.nci.org.au/ows/national_geophysical_compilations?service=WCS&version=1.0.0&request=GetCapabilities" # Create WCS object wcs = WebCoverageService(url, version="1.0.0", timeout=300) # Get coverages and content dict keys content = wcs.contents keys = content.keys() print("Following data layers are available:") title_list = [] description_list = [] bbox_list = [] for key in keys: print(f"key: {key}") print(f"title: {wcs[key].title}") title_list.append(wcs[key].title) print(f"{wcs[key].abstract}") description_list.append(wcs[key].abstract) print(f"bounding box: {wcs[key].boundingBoxWGS84}") bbox_list.append(wcs[key].boundingBoxWGS84) print("") return keys, title_list, description_list, bbox_list def get_radiometric_image(outfname, layername, bbox, url, resolution=1, crs='EPSG:4326', format_out='GeoTIFF')- 
Download radiometric data layer and save geotiff from WCS layer.
Parameters
outfname:str- output file name
 layername:str- layer identifier
 bbox:list- layer bounding box
 resolution:int- layer resolution in arcsec
 url:str- url of wcs server
 crs:str- crsm default 'EPSG:4326'
 format:str- output format, either "GeoTIFF" or "NetCDF"
 
Return
Exited ok: boolean
Expand source code
def get_radiometric_image( outfname, layername, bbox, url, resolution=1, crs="EPSG:4326", format_out="GeoTIFF" ): """ Download radiometric data layer and save geotiff from WCS layer. Parameters ---------- outfname : str output file name layername : str layer identifier bbox : list layer bounding box resolution : int layer resolution in arcsec url : str url of wcs server crs: str crsm default 'EPSG:4326' format: str output format, either "GeoTIFF" or "NetCDF" Return ------ Exited ok: boolean """ # If the resolution passed is None, set to native resolution of datasource if resolution is None: resolution = get_radiometricdict()["resolution_arcsec"] # Convert resolution into width and height pixel number width = abs(bbox[2] - bbox[0]) height = abs(bbox[3] - bbox[1]) nwidth = int(width / resolution * 3600) nheight = int(height / resolution * 3600) # Get date times = get_times(url, layername) # There is only one time available per layer date = times[0] # Get data if os.path.exists(outfname): utils.msg_warn(f"{layername}.tif already exists, skipping download") else: try: with spin(f"Downloading {layername}") as s: wcs = WebCoverageService(url, version="1.0.0", timeout=300) data = wcs.getCoverage( identifier=layername, time=[date], bbox=bbox, format=format_out, crs=crs, width=nwidth, height=nheight, ) s(1) except: utils.msg_err("Download failed") return False # Save data with open(outfname, "wb") as f: f.write(data.read()) # print(f"Layer {layername} saved in {outfname}") return True def get_radiometric_layers(outpath, layernames, bbox, resolution=1, crs='EPSG:4326', format_out='GeoTIFF')- 
Wrapper function for downloading radiometric data layers and save geotiffs from WCS layer.
Parameters
outpath:str- output path
 layername:listofstrings- layer identifiers
 bbox:list- layer bounding box
 resolution:int- layer resolution in arcsec
 url:str- url of wcs server
 crs:str- crsm default 'EPSG:4326'
 format_out:str- output format, either "GeoTIFF" or "NetCDF"
 
Return
list of output filenames
Expand source code
def get_radiometric_layers( outpath, layernames, bbox, resolution=1, crs="EPSG:4326", format_out="GeoTIFF" ): """ Wrapper function for downloading radiometric data layers and save geotiffs from WCS layer. Parameters ---------- outpath: str output path layername : list of strings layer identifiers bbox : list layer bounding box resolution : int layer resolution in arcsec url : str url of wcs server crs: str crsm default 'EPSG:4326' format_out: str output format, either "GeoTIFF" or "NetCDF" Return ------ list of output filenames """ url = "https://gsky.nci.org.au/ows/national_geophysical_compilations?service=WCS" if type(layernames) != list: layernames = [layernames] if format_out == "GeoTIFF": fname_end = ".tif" elif format_out == "NetCDF": fname_end = ".nc" else: print( f"\u2716 {format_out} not supported. Choose either GeoTIFF or NetCDF.") return outfnames # Loop over all layers fnames_out = [] for layername in layernames: outfname = os.path.join( outpath, "radiometric_" + layername + fname_end) ok = get_radiometric_image( outfname, layername, bbox, url, resolution=1, crs=crs, format_out=format_out ) if ok: fnames_out.append(outfname) return fnames_out def get_radiometricdict()- 
Returns dictionary of keys and layer titles
To update manually please run get_capabilities() to retrieve all current layer details
Expand source code
def get_radiometricdict(): """ Returns dictionary of keys and layer titles To update manually please run get_capabilities() to retrieve all current layer details """ rmdict = { "resolution_arcsec": 3.6, "layernames": { "radmap2019_grid_dose_terr_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 unfiltered terrestrial dose rate", "radmap2019_grid_dose_terr_filtered_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 filtered terrestrial xf", "radmap2019_grid_k_conc_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 unfiltered pct potassium", "radmap2019_grid_k_conc_filtered_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 filtered pct potassium grid", "radmap2019_grid_th_conc_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 unfiltered ppm thorium", "radmap2019_grid_th_conc_filtered_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 filtered ppm thorium", "radmap2019_grid_thk_ratio_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 ratio thorium over potassium", "radmap2019_grid_u2th_ratio_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 ratio uranium squared over thorium", "radmap2019_grid_u_conc_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 unfiltered ppm uranium", "radmap2019_grid_u_conc_filtered_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 filtered ppm uranium", "radmap2019_grid_uk_ratio_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 ratio uranium over potassium", "radmap2019_grid_uth_ratio_awags_rad_2019": "Radiometric Grid of Australia (Radmap) v4 2019 ratio uranium over thorium", }, } return rmdict def get_times(url, layername, year=None)- 
Return available dates for layer.
Parameters
url:str, layer urllayername:str, nameoflayer idyear:intorstr, yearofinterest (if None, times for all available years are returned)
Return
list of dates
Expand source code
def get_times(url, layername, year=None): """ Return available dates for layer. Parameters ---------- url: str, layer url layername: str, name of layer id year: int or str, year of interest (if None, times for all available years are returned) Return ------ list of dates """ wcs = WebCoverageService(url, version="1.0.0", timeout=300) times = wcs[layername].timepositions if year is None: return times else: year = int(year) dates = [] for time in times: if datetime.fromisoformat(time[:-1]).astimezone(timezone.utc).year == year: dates.append(time) return dates def getdict_license()- 
Retrieves the Geoscience Australia data license and NCI attribution information as dict
Expand source code
def getdict_license(): """ Retrieves the Geoscience Australia data license and NCI attribution information as dict """ dict = { "name": "Geoscience Australia National Geophysical Compilation Sub-collection Radiometrics", "source_url": "https://opus.nci.org.au/display/Help/Datasets", "license": "CC BY 4.0", "license_title": "Creative Commons Attribution 4.0 International (CC BY 4.0)", "license_url": "https://creativecommons.org/licenses/by/4.0/", "copyright": "© Copyright 2017-2022, Geoscience Australia", "attribution": "Geoscience Australia. The WCS service relies on GSKY - A Scalable, Distributed Geospatial Data Service \ from the National Centre for Environmental Information (NCI).", } return dict def plot_raster(infname)- 
Read in raster tif with rasterio and visualise as map.
Parameters
infname:str
Expand source code
def plot_raster(infname): """ Read in raster tif with rasterio and visualise as map. Parameters ---------- infname : str """ data = rasterio.open(infname) # show image show(data)