Skip to main content

Access GeoTIFFs from Raster Analytics with GDAL

You can access Raster Analytics directly with GDAL from command line tools or Python bindings.

GDAL command line tools

From your command line, you can get image information and data from Raster Analytics.

List information about a geotiff dataset with gdalinfo:

gdalinfo "/vsicurl/https://api.maxar.com/analytics/v1/raster/ortho/geotiff?function=ortho&p=collect_identifier=%2210300100E3AA2C00%22&p=crs=%22EPSG:4326%22&p=bands=%22red,green,blue%22&p=interpolation=%22Bilinear%22&p=dra=true&maxar_api_key=<YOUR_KEY>

This shows interesting information such as image extents.

Driver: GTiff/GeoTIFF
Files: /vsicurl/https://api.maxar.com/analytics/v1/raster/ortho/geotiff?function=ortho&p=collect_identifier=%2210300100E3AA2C00%22&p=crs=%22EPSG:4326%22&p=bands=%22red,green,blue%22&p=interpolation=%22Bilinear%22&p=dra=true&maxar_api_key=<YOUR_KEY>
Size is 8314, 27703
Coordinate System is:
GEOGCRS["WGS 84",
ENSEMBLE["World Geodetic System 1984 ensemble",
MEMBER["World Geodetic System 1984 (Transit)"],
MEMBER["World Geodetic System 1984 (G730)"],
MEMBER["World Geodetic System 1984 (G873)"],
MEMBER["World Geodetic System 1984 (G1150)"],
MEMBER["World Geodetic System 1984 (G1674)"],
MEMBER["World Geodetic System 1984 (G1762)"],
MEMBER["World Geodetic System 1984 (G2139)"],
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]],
ENSEMBLEACCURACY[2.0]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
CS[ellipsoidal,2],
AXIS["geodetic latitude (Lat)",north,
ORDER[1],
ANGLEUNIT["degree",0.0174532925199433]],
AXIS["geodetic longitude (Lon)",east,
ORDER[2],
ANGLEUNIT["degree",0.0174532925199433]],
USAGE[
SCOPE["Horizontal component of 3D system."],
AREA["World."],
BBOX[-90,-180,90,180]],
ID["EPSG",4326]]
Data axis to CRS axis mapping: 2,1
Origin = (-90.466438981152280,-0.950168331419574)
Pixel Size = (0.000022642990425,-0.000022789955301)
Metadata:
AREA_OR_POINT=Area
TIFFTAG_COPYRIGHT=Maxar Inc. 2024
TIFFTAG_IMAGEDESCRIPTION=Maxar Inc.
TIFFTAG_SOFTWARE=RDA modified Apache Commons Imaging
Image Structure Metadata:
INTERLEAVE=PIXEL
Corner Coordinates:
Upper Left ( -90.4664390, -0.9501683) ( 90d27'59.18"W, 0d57' 0.61"S)
Lower Left ( -90.4664390, -1.5815185) ( 90d27'59.18"W, 1d34'53.47"S)
Upper Right ( -90.2781852, -0.9501683) ( 90d16'41.47"W, 0d57' 0.61"S)
Lower Right ( -90.2781852, -1.5815185) ( 90d16'41.47"W, 1d34'53.47"S)
Center ( -90.3723121, -1.2658434) ( 90d22'20.32"W, 1d15'57.04"S)
Band 1 Block=256x256 Type=Byte, ColorInterp=Gray
Band 2 Block=256x256 Type=Byte, ColorInterp=Undefined
Band 3 Block=256x256 Type=Byte, ColorInterp=Undefined

Create a raster locally by pixel coordinates with gdal_translate:

 gdal_translate -srcwin 15300 64000 1000 1000 "/vsicurl/https://api.maxar.com/analytics/v1/raster/ortho/geotiff?function=pansharp_ortho&p=collect_identifier=%2210300100E3AA2C00%22&p=crs=%22EPSG:4326%22&p=bands=%22red,green,blue%22&p=dra=true&maxar_api_key=<YOUR KEY>" /tmp/translated.tif

All bands and bits are available with Raster Analytics but we are showing a view-ready 8 bit and 3 band image:

Instead of pixel coordinates, create a raster locally by georeferenced extents with gdalwarp:

gdalwarp "/vsicurl/https://api.maxar.com/analytics/v1/raster/ortho/geotiff?function=pansharp_ortho&p=collect_identifier=%2210300100E3AA2C00%22&p=crs=%22EPSG:4326%22&p=bands=%22red,green,blue%22&p=dra=true&maxar_api_key=<YOUR KEY>" /tmp/warp.png -te  -90.40520 -1.34697 -90.39955 -1.34343

Note: we are not reprojecting the image here which would resample and degrade the image quality.

GDAL Python bindings

Python has GDAL bindings that make accessing Raster Analytic GeoTIFFs easy. The data can be assembled into numpy arrays for further processing. An example program below pulls data from Raster Analytics and prints the buffer. For more information about GDAL and Python, please visit these docs.

Usage

usage: main.py [-h] [--image IMAGE_URL] --offset OFFSET --fetch FETCH

Pull data from the geotiff endpoint.

options:
-h, --help show this help message and exit
--image IMAGE_URL image url
--offset OFFSET num pixels to offset
--fetch FETCH num pixels to fetch

Example

Example command:

python3 main.py --image "/vsicurl/https://api.maxar.com/analytics/v1/raster/ortho-image/geotiff?function=pansharp_ortho&p=collect_identifier=%2210300100E3AA2C00%22&p=crs=%22EPSG:4326%22&p=bands=%22red,green,blue%22&p=dra=true&maxar_api_key=<YOUR KEY>" --offset 100 --fetch 256

Result:

[[ 6  7  0 ...  0  6  6]
[ 7 0 0 ... 6 0 6]
[ 7 8 0 ... 6 0 4]
...
[ 7 13 7 ... 8 0 4]
[ 4 8 13 ... 0 4 4]
[14 8 9 ... 0 9 0]]
[[52 55 51 ... 51 54 56]
[55 49 52 ... 56 45 54]
[57 58 50 ... 54 48 51]
...
[53 58 53 ... 59 44 54]
[52 55 60 ... 51 56 54]
[61 55 58 ... 51 59 51]]
[[91 95 88 ... 88 91 92]
[93 86 89 ... 92 79 91]
[94 95 87 ... 91 83 88]
...
[91 95 91 ... 95 79 91]
[88 93 97 ... 86 93 90]
[99 91 95 ... 87 96 88]]

File

Example program:

import argparse
from osgeo import gdal

# simple gdal fetch example
def fetch_array(image_url, offset, pixel_rect_size):
dataset = gdal.Open(image_url)
arrays = []
for band_index in range(dataset.RasterCount):
band = dataset.GetRasterBand(band_index+1)
band_as_array = band.ReadAsArray(offset, offset, pixel_rect_size, pixel_rect_size)
arrays.append(band_as_array)
return arrays


def gdal_config():
gdal.UseExceptions()
gdal.SetConfigOption('GDAL_CACHEMAX', '512') # size in MB
gdal.SetConfigOption('GDAL_NUM_THREADS', "ALL_CPUS")
gdal.SetConfigOption('GDAL_HTTP_TIMEOUT', '600')
gdal.SetConfigOption('GTIFF_VIRTUAL_MEM_IO', "IF_ENOUGH_RAM")
gdal.SetConfigOption('VSI_CACHE', 'True')
gdal.SetConfigOption('VSI_CACHE_SIZE', '536870912') # size in bytes


if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Pull data from the geotiff endpoint.')
parser.add_argument('--image', dest='image_url', help='image url')
parser.add_argument('--offset', dest='offset', help='num pixels to offset', type=int, required=True)
parser.add_argument('--fetch', dest='fetch', help='num pixels to fetch', type=int, required=True)
args = parser.parse_args()

# fetch the pixels
# make the interface easy and just offset/fetch the same number of pixels in both X and Y direction
pixel_arrays = fetch_array(args.image_url, args.offset, args.fetch)

for array in pixel_arrays:
print(array)