This package implements a library and associated command-line tool called mergetiff
that provides functionality to merge raster bands from multiple GeoTiff files into a single dataset. Metadata (including geospatial reference and projection data) will be copied from the first input dataset (when using the command-line tool) or from the dataset passed as the second argument to the createMergedDataset()
function.
Functionality is also provided for converting between GDAL datasets and NumPy arrays, to facilitate interoperability with other image processing libraries.
- Requirements
- Installing the GDAL 2.x Python bindings
- Installation
- Using the command-line tool
- Using the library
- Python 2.7 or Python 3.4+
- Python bindings for GDAL 2.0+
- NumPy
GDAL binary wheels for Windows are maintained by Christoph Gohlke and can be downloaded from https://www.lfd.uci.edu/~gohlke/pythonlibs/#gdal.
OSGeo maintains a Homebrew tap which provides packages that can be installed via Homebrew:
brew tap osgeo/osgeo4mac
brew install gdal2
brew link --force gdal2
pip install gdal
The official package repositories for these older Ubuntu versions only contain GDAL 1.x. GDAL 2.x can be installed via the UbuntuGIS PPA:
sudo add-apt-repository -y ppa:ubuntugis/ubuntugis-unstable
sudo apt update
sudo apt install gdal-bin python-gdal python3-gdal
The official package repositories for newer Ubuntu versions already contain GDAL 2.x, making it extremely simple to install:
sudo apt install gdal-bin python-gdal python3-gdal
Once the GDAL Python bindings have been installed, mergetiff
can be installed by simply running:
pip install mergetiff
If we have one GeoTiff called rgb.tif
containing 3 raster bands and another GeoTiff called alpha.tif
containing a single raster band, we can merge them by running:
mergetiff out.tif rgb.tif 1,2,3 alpha.tif 1
Alternatively, if we only want to copy the metadata from the first file without including any of its raster bands, the band specifier -
can be used to exclude all bands:
mergetiff out.tif rgb.tif - alpha.tif 1
This will copy all of the metadata from rgb.tif
and the first raster band from alpha.tif
into the output file.
To perform the same merge described in the section above using the library directly:
import mergetiff
# Open both datasets
dataset1 = mergetiff.openDataset('rgb.tif')
dataset2 = mergetiff.openDataset('alpha.tif')
# Include the raster bands that we want
# (Note that the dataset we use for metadata does not have to be included)
bands = []
bands.extend( mergetiff.getRasterBands(dataset1, [1,2,3]) )
bands.extend( mergetiff.getRasterBands(dataset2, [1]) )
# Perform the merge, using the metadata from the first dataset
mergetiff.createMergedDataset('merged.tif', dataset1, bands)
If we want to perform image processing on raster data, we can use the NumPy interoperability functionality of the library:
import mergetiff
# Open the dataset and read the raster data into a NumPy ndarray
dataset = mergetiff.openDataset('rgb.tif')
rasterArray = mergetiff.rasterFromDataset(dataset)
# Manipulate the raster array here
# ...
# Convert the modified raster data back into a GDAL dataset
modifiedDataset = mergetiff.datasetFromRaster(rasterArray)
# Merge the modified raster bands with the original metadata
bands = mergetiff.getRasterBands(modifiedDataset, [1,2,3])
mergetiff.createMergedDataset('modified.tif', dataset, bands)
Alternatively, if we are working with individual subsets of a dataset's raster data and we anticipate that the overall data may be too large to fit in the amount of available system memory, we can use the RasterReader
class to safely read data. If there is enough available memory to hold the entirety of the dataset's raster data it will be stored in memory to improve performance, otherwise it will be read from file as needed:
# Open the dataset, reading the entirety of its raster data into memory
# if there is sufficient system memory available to hold it
reader = mergetiff.RasterReader('rgb.tif')
# Retrieve the top-left 256x256 subset of the raster data
subsetArray = reader[0:256, 0:256]
# Manipulate the raster array here
# ...