aws.osml.gdal

The gdal package contains utilities that assist with loading imagery and metadata using the OSGeo GDAL library.

Loading Imagery and Sensor Models with OSML

OSML provides utilities to load a dataset and automatically construct an appropriate sensor model from metadata available in the image. Metadata handled by GDAL (e.g. GeoTIFF tags or NITF segment metadata and TREs) is available through the dataset accessors.

Example of loading a dataset and sensor model using OSML
from aws.osml.gdal import load_gdal_dataset

# Load the image and create a sensor model
dataset, sensor_model = load_gdal_dataset("./imagery/sample.nitf")
width = dataset.RasterXSize
height = dataset.RasterYSize

print(f"Loaded image with dimensions: ({height}, {width}) (rows, cols)")
print(f"Using Sensor Model Implementation: {type(sensor_model).__name__}")
print(dataset.GetMetadata())

Access to NITF Data Extension Segments

SICD and SIDD imagery contains additional metadata in a XML Data Extension Segment that is not currently processed by GDAL. This information can be accessed with the help of the NITFDESAccessor.

Example of loading a dataset and sensor model using OSML
import base64
import xml.dom.minidom
from aws.osml.gdal import load_gdal_dataset, NITFDESAccessor

dataset, sensor_model = load_gdal_dataset("./sample-sicd.nitf")

des_accessor = NITFDESAccessor(dataset.GetMetadata("xml:DES"))
xml_data_content_segments = des_accessor.get_segments_by_name("XML_DATA_CONTENT")
if xml_data_content_segments is not None:
    for xml_data_segment in xml_data_content_segments:
        xml_str = des_accessor.extract_desdata_xml(xml_data_segment)
        if "SICD" in xml_str:
            temp = xml.dom.minidom.parseString(xml_str)
            new_xml = temp.toprettyxml()
            print(new_xml)
            break

APIs

aws.osml.gdal.set_gdal_default_configuration() None[source]

This function sets GDAL configuration options to support efficient reading of large raster datasets using the /vsis3 virtual file system.

Returns:

None

aws.osml.gdal.load_gdal_dataset(image_path: str) Tuple[Dataset, SensorModel | None][source]

This function loads a GDAL raster dataset from the path provided and constructs a camera model abstraction used to georeference locations on this image.

Parameters:

image_path – the path to the raster data, may be a local path or a virtual file system (e.g. /vsis3/…)

Returns:

the raster dataset and sensor model

aws.osml.gdal.get_image_extension(image_path: str) str[source]

Get the image extension based on the provided image path

Parameters:

image_path – an image path

Returns:

image extension

aws.osml.gdal.get_type_and_scales(raster_dataset: Dataset, desired_output_type: int | None = None, range_adjustment: RangeAdjustmentType = RangeAdjustmentType.NONE) Tuple[int, List[List[int]]][source]

Get type and scales of a provided raster dataset

Parameters:
  • raster_dataset – the raster dataset containing the region

  • desired_output_type – type to be output after dynamic range adjustments

  • range_adjustment – the type of pixel scaling effort to

Returns:

a tuple containing type and scales

class aws.osml.gdal.GDALCompressionOptions(value)[source]

Bases: str, Enum

Enumeration defining compression algorithms for image.

NONE = 'NONE'
JPEG = 'JPEG'
J2K = 'J2K'
LZW = 'LZW'
class aws.osml.gdal.GDALConfigEnv(options: Dict | None = None)[source]

Bases: object

This class provides a way to setup a temporary GDAL environment using Python’s “with” statement. GDAL configuration options will be set inside the scope of the with statement and then reverted to previously set values on exit. This will commonly be used to set AWS security credentials (e.g. AWS_SECRET_ACCESS_KEY) for use by other GDAL operations.

See: https://gdal.org/user/configoptions.html#gdal-configuration-file for additional options.

with_aws_credentials(aws_credentials: Dict[str, str] | None) GDALConfigEnv[source]

This method sets the GDAL configuration options for the AWS credentials from the credentials object returned by a boto3 call to sts.assume_role(…).

Parameters:

aws_credentials – the dictionary of values from the sts.assume_role() response[‘Credentials’]

Returns:

self to facilitate a simple builder constructor pattern

class aws.osml.gdal.GDALDigitalElevationModelTileFactory(tile_directory: str)[source]

Bases: DigitalElevationModelTileFactory

This tile factory uses GDAL to load elevation data into numpy arrays. Any raster format supported by GDAL is fair game but the format must have sufficient metadata to populate the GDAL geo transform.

get_tile(tile_path: str) Tuple[Any | None, GDALAffineSensorModel | None, ElevationRegionSummary | None][source]

Retrieve a numpy array of elevation values and a sensor model.

TODO: Replace Any with numpy.typing.ArrayLike once we move to numpy >1.20

Parameters:

tile_path – the location of the tile to load

Returns:

an array of elevation values, a sensor model, and a summary or (None, None, None)

class aws.osml.gdal.GDALImageFormats(value)[source]

Bases: str, Enum

Subset of GDAL supported image formats commonly used by this software. See https://gdal.org/drivers/raster/index.html for a complete listing of the formats.

NITF = 'NITF'
JPEG = 'JPEG'
PNG = 'PNG'
GTIFF = 'GTiff'
class aws.osml.gdal.RangeAdjustmentType(value)[source]

Bases: str, Enum

Enumeration defining ways to scale raw image pixels to an output value range.

  • NONE indicates that the full range available to the input type will be used.

  • MINMAX chooses the portion of the input range that actually contains values.

  • DRA is a dynamic range adjustment that attempts to select the most important portion of the input range. It differs from MINMAX in that it can exclude outliers to reduce the impact of unusually bright/dark spots in an image.

NONE = 'NONE'
MINMAX = 'MINMAX'
DRA = 'DRA'
class aws.osml.gdal.NITFDESAccessor(gdal_xml_des_metadata: List[str])[source]

Bases: object

This class is a facade that makes it easier to work with the XML formatted Data Extension Segments parsed by GDAL.

get_segments_by_name(des_name: str) List[Element][source]

This method searches through the GDAL xml:DES metadata and returns the XML structure for any segments matching the provided name. This is equivalent to retrieving all segments that have a matching DESID.

Parameters:

des_name – the DESID (e.g. XML_DATA_CONTENT)

Returns:

the list of segments, multiple items in the list will occur if the NITF has multiple matching segments

static extract_des_header(des_element: Element) str[source]

This function encodes the existing values from the Data Extension Segment header into a fields appropriately sized for including in a NITF image. The DESDATA field is not copied because the assumption is that the data itself will be updated. The DE and DESID fields are not included either because GDAL adds them itself when writing the segment.

Parameters:

des_element – the Data Extension Segment containing current segment

Returns:

the encoded DESVER through DESSHF fields.

static extract_desdata_xml(des_element: Element) str | None[source]

This function attempts to extract a block of XML from the field element named DESDATA. Versions of GDAL before 3.9 returned the XML data base64 encoded as a value attribute. Versions >=3.9 are automatically expanding the xml into the text area of an <xml_content> element.

Parameters:

des_element – the root xml:DES metadata element

Returns:

the xml content if it is found and can be extracted

static parse_field_value(des_element: Element, field_name: str, type_conversion: Callable[[str], T]) T[source]

This is method will find a named “field” element in the children of a TRE Element and return the “value” attribute of that named field. A type conversion function can be provided to convert the attribute value to a specific Python type (e.g. int, float, or str)

Parameters:
  • des_element – the root element to find the named field in

  • field_name – the name of the field element

  • type_conversion – the desired type of the output, must support construction from a string

Returns:

the value converted to the requested type

class aws.osml.gdal.ChippedImageInfoFacade(ichipb_tre: Element)[source]

Bases: object

This is a facade class that can be initialized with an ICHIPB TRE. It provides accessors for the values so that they can easily be used to create an ChippedImageSensorModel

class aws.osml.gdal.SensorModelFactory(actual_image_width: int, actual_image_height: int, xml_tres: Element | None = None, xml_dess: List[str] | None = None, geo_transform: List[float] | None = None, proj_wkt: str | None = None, ground_control_points: List[GCP] | None = None, selected_sensor_model_types: List[SensorModelTypes] | None = None)[source]

Bases: object

This class encapsulates the logic necessary to construct SensorModels from imagery metadata parsed using GDAL. Users initialize the builder by providing whatever metadata is available and this class will decide how to create the most accurate SensorModel from the available information.

build() SensorModel | None[source]

Constructs the sensor model from the available information. Note that in cases where not enough information is available to provide any solution this method will return None.

Returns:

the highest quality sensor model available given the information provided

class aws.osml.gdal.SensorModelTypes(value)[source]

Bases: Enum

This enumeration defines the various sensor model types this factory can build.

AFFINE = 'AFFINE'
PROJECTIVE = 'PROJECTIVE'
RPC = 'RPC'
RSM = 'RSM'
SICD = 'SICD'