Skip to content

Commit

Permalink
[WIP] Handle TIFFs with more than one image
Browse files Browse the repository at this point in the history
  • Loading branch information
eliascarv committed Dec 9, 2024
1 parent 5d1c283 commit 6492eba
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/GeoTIFF.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

module GeoTIFF

using TiffImages: AbstractTIFF, DenseTaggedImage, WidePixel
using TiffImages: AbstractTIFF, DenseTaggedImage, StridedTaggedImage, IFD, WidePixel
using ColorTypes: Colorant, Gray
using MappedArrays: mappedarray
using StaticArrays: SVector, SMatrix, SA
Expand Down
36 changes: 34 additions & 2 deletions src/image.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ to get the metadata and the image with corrected axes, respectively.
* The [`GeoTIFF.image`](@ref) function is necessary because
the GeoTIFF format swaps the order of the image axes;
"""
struct GeoTIFFImage{T,N,I<:AbstractTIFF{T,N}} <: AbstractArray{T,N}
struct GeoTIFFImage{T,I<:AbstractMatrix{T}} <: AbstractMatrix{T}
tiff::I
metadata::Metadata
end
Expand Down Expand Up @@ -59,4 +59,36 @@ channel(geotiff::GeoTIFFImage, i) = mappedarray(c -> channel(c, i), image(geotif
Base.size(geotiff::GeoTIFFImage) = size(geotiff.tiff)
Base.getindex(geotiff::GeoTIFFImage, i...) = getindex(geotiff.tiff, i...)
Base.setindex!(geotiff::GeoTIFFImage, v, i...) = setindex!(geotiff.tiff, v, i...)
Base.IndexStyle(::Type{GeoTIFFImage{T,N,I}}) where {T,N,I} = IndexStyle(I)
Base.IndexStyle(::Type{GeoTIFFImage{T,I}}) where {T,I} = IndexStyle(I)

abstract type MultiGeoTIFF end

function getgeotiff end

function ngeotiffs end

# Iterator interface
Base.length(geotiff::MultiGeoTIFF) = ngeotiffs(geotiff)
Base.iterate(geotiff::MultiGeoTIFF, state=1) =
state > length(geotiff) ? nothing : (getgeotiff(geotiff, state), state + 1)

# Indexing interface
Base.getindex(geotiff::MultiGeoTIFF, i) = getgeotiff(geotiff, i)
Base.firstindex(geotiff::MultiGeoTIFF) = 1
Base.lastindex(geotiff::MultiGeoTIFF) = ngeotiffs(geotiff)

struct StridedGeoTIFF{I<:StridedTaggedImage} <: MultiGeoTIFF
tiff::I
metadata::Vector{Metadata}
end

ngeotiffs(geotiff::StridedGeoTIFF) = length(geotiff.tiff)
getgeotiff(geotiff::StridedGeoTIFF, i) = GeoTIFFImage(geotiff.tiff[i], geotiff.metadata[i])

struct SlicedGeoTIFF{T,I<:AbstractTIFF{T,3}} <: MultiGeoTIFF
tiff::I
metadata::Vector{Metadata}
end

ngeotiffs(geotiff::SlicedGeoTIFF) = size(geotiff.tiff, 3)
getgeotiff(geotiff::SlicedGeoTIFF, i) = GeoTIFFImage(@view(geotiff.tiff[:, :, i]), geotiff.metadata[i])
14 changes: 10 additions & 4 deletions src/load.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,22 @@ The keyword arguments are forward to the `TiffImages.load` function.
"""
function load(fname; kwargs...)
tiff = TiffImages.load(fname; kwargs...)
metadata = _getmetadata(tiff)
GeoTIFFImage(tiff, metadata)
ifds = TiffImages.ifds(tiff)
metadata = ifds isa IFD ? _getmetadata(ifds) : _getmetadata.(ifds)
if tiff isa StridedTaggedImage
StridedGeoTIFF(tiff, metadata)
elseif ndims(tiff) == 3
SlicedGeoTIFF(tiff, metadata)
else
GeoTIFFImage(tiff, metadata)
end
end

# -----------------
# HELPER FUNCTIONS
# -----------------

function _getmetadata(tiff)
ifd = TiffImages.ifds(tiff)
function _getmetadata(ifd)
geokeydirectory = _gettag(ifd, GeoKeyDirectoryTag, GeoKeyDirectory)
geodoubleparams = _gettag(ifd, GeoDoubleParamsTag, GeoDoubleParams)
geoasciiparams = _gettag(ifd, GeoAsciiParamsTag, GeoAsciiParams)
Expand Down

0 comments on commit 6492eba

Please sign in to comment.