# This file was automatically generated by SWIG (http://www.swig.org).
# Version 3.0.5
#
# Do not make changes to this file unless you know what you are doing--modify
# the SWIG interface file instead.
package Geo::GDAL;
use base qw(Exporter);
use base qw(DynaLoader);
require Geo::OGR;
require Geo::OSR;
package Geo::GDALc;
bootstrap Geo::GDAL;
package Geo::GDAL;
@EXPORT = qw();
# ---------- BASE METHODS -------------
package Geo::GDAL;
sub TIEHASH {
my ($classname,$obj) = @_;
return bless $obj, $classname;
}
sub CLEAR { }
sub FIRSTKEY { }
sub NEXTKEY { }
sub FETCH {
my ($self,$field) = @_;
my $member_func = "swig_${field}_get";
$self->$member_func();
}
sub STORE {
my ($self,$field,$newval) = @_;
my $member_func = "swig_${field}_set";
$self->$member_func($newval);
}
sub this {
my $ptr = shift;
return tied(%$ptr);
}
# ------- FUNCTION WRAPPERS --------
package Geo::GDAL;
*callback_d_cp_vp = *Geo::GDALc::callback_d_cp_vp;
*UseExceptions = *Geo::GDALc::UseExceptions;
*DontUseExceptions = *Geo::GDALc::DontUseExceptions;
*Debug = *Geo::GDALc::Debug;
*SetErrorHandler = *Geo::GDALc::SetErrorHandler;
*Error = *Geo::GDALc::Error;
*GOA2GetAuthorizationURL = *Geo::GDALc::GOA2GetAuthorizationURL;
*GOA2GetRefreshToken = *Geo::GDALc::GOA2GetRefreshToken;
*GOA2GetAccessToken = *Geo::GDALc::GOA2GetAccessToken;
*PushErrorHandler = *Geo::GDALc::PushErrorHandler;
*PopErrorHandler = *Geo::GDALc::PopErrorHandler;
*ErrorReset = *Geo::GDALc::ErrorReset;
*EscapeString = *Geo::GDALc::EscapeString;
*GetLastErrorNo = *Geo::GDALc::GetLastErrorNo;
*GetLastErrorType = *Geo::GDALc::GetLastErrorType;
*GetLastErrorMsg = *Geo::GDALc::GetLastErrorMsg;
*PushFinderLocation = *Geo::GDALc::PushFinderLocation;
*PopFinderLocation = *Geo::GDALc::PopFinderLocation;
*FinderClean = *Geo::GDALc::FinderClean;
*FindFile = *Geo::GDALc::FindFile;
*ReadDir = *Geo::GDALc::ReadDir;
*ReadDirRecursive = *Geo::GDALc::ReadDirRecursive;
*SetConfigOption = *Geo::GDALc::SetConfigOption;
*GetConfigOption = *Geo::GDALc::GetConfigOption;
*CPLBinaryToHex = *Geo::GDALc::CPLBinaryToHex;
*CPLHexToBinary = *Geo::GDALc::CPLHexToBinary;
*FileFromMemBuffer = *Geo::GDALc::FileFromMemBuffer;
*Unlink = *Geo::GDALc::Unlink;
*HasThreadSupport = *Geo::GDALc::HasThreadSupport;
*Mkdir = *Geo::GDALc::Mkdir;
*Rmdir = *Geo::GDALc::Rmdir;
*Rename = *Geo::GDALc::Rename;
*Stat = *Geo::GDALc::Stat;
*VSIFOpenL = *Geo::GDALc::VSIFOpenL;
*VSIFCloseL = *Geo::GDALc::VSIFCloseL;
*VSIFSeekL = *Geo::GDALc::VSIFSeekL;
*VSIFTellL = *Geo::GDALc::VSIFTellL;
*VSIFTruncateL = *Geo::GDALc::VSIFTruncateL;
*VSIFWriteL = *Geo::GDALc::VSIFWriteL;
*VSIFReadL = *Geo::GDALc::VSIFReadL;
*GDAL_GCP_GCPX_get = *Geo::GDALc::GDAL_GCP_GCPX_get;
*GDAL_GCP_GCPX_set = *Geo::GDALc::GDAL_GCP_GCPX_set;
*GDAL_GCP_GCPY_get = *Geo::GDALc::GDAL_GCP_GCPY_get;
*GDAL_GCP_GCPY_set = *Geo::GDALc::GDAL_GCP_GCPY_set;
*GDAL_GCP_GCPZ_get = *Geo::GDALc::GDAL_GCP_GCPZ_get;
*GDAL_GCP_GCPZ_set = *Geo::GDALc::GDAL_GCP_GCPZ_set;
*GDAL_GCP_GCPPixel_get = *Geo::GDALc::GDAL_GCP_GCPPixel_get;
*GDAL_GCP_GCPPixel_set = *Geo::GDALc::GDAL_GCP_GCPPixel_set;
*GDAL_GCP_GCPLine_get = *Geo::GDALc::GDAL_GCP_GCPLine_get;
*GDAL_GCP_GCPLine_set = *Geo::GDALc::GDAL_GCP_GCPLine_set;
*GDAL_GCP_Info_get = *Geo::GDALc::GDAL_GCP_Info_get;
*GDAL_GCP_Info_set = *Geo::GDALc::GDAL_GCP_Info_set;
*GDAL_GCP_Id_get = *Geo::GDALc::GDAL_GCP_Id_get;
*GDAL_GCP_Id_set = *Geo::GDALc::GDAL_GCP_Id_set;
*GCPsToGeoTransform = *Geo::GDALc::GCPsToGeoTransform;
*TermProgress_nocb = *Geo::GDALc::TermProgress_nocb;
*_ComputeMedianCutPCT = *Geo::GDALc::_ComputeMedianCutPCT;
*_DitherRGB2PCT = *Geo::GDALc::_DitherRGB2PCT;
*_ReprojectImage = *Geo::GDALc::_ReprojectImage;
*_ComputeProximity = *Geo::GDALc::_ComputeProximity;
*_RasterizeLayer = *Geo::GDALc::_RasterizeLayer;
*_Polygonize = *Geo::GDALc::_Polygonize;
*FillNodata = *Geo::GDALc::FillNodata;
*_SieveFilter = *Geo::GDALc::_SieveFilter;
*_RegenerateOverviews = *Geo::GDALc::_RegenerateOverviews;
*_RegenerateOverview = *Geo::GDALc::_RegenerateOverview;
*ContourGenerate = *Geo::GDALc::ContourGenerate;
*_AutoCreateWarpedVRT = *Geo::GDALc::_AutoCreateWarpedVRT;
*ApplyGeoTransform = *Geo::GDALc::ApplyGeoTransform;
*InvGeoTransform = *Geo::GDALc::InvGeoTransform;
*VersionInfo = *Geo::GDALc::VersionInfo;
*AllRegister = *Geo::GDALc::AllRegister;
*GDALDestroyDriverManager = *Geo::GDALc::GDALDestroyDriverManager;
*GetCacheMax = *Geo::GDALc::GetCacheMax;
*GetCacheUsed = *Geo::GDALc::GetCacheUsed;
*SetCacheMax = *Geo::GDALc::SetCacheMax;
*_GetDataTypeSize = *Geo::GDALc::_GetDataTypeSize;
*_DataTypeIsComplex = *Geo::GDALc::_DataTypeIsComplex;
*GetDataTypeName = *Geo::GDALc::GetDataTypeName;
*GetDataTypeByName = *Geo::GDALc::GetDataTypeByName;
*GetColorInterpretationName = *Geo::GDALc::GetColorInterpretationName;
*GetPaletteInterpretationName = *Geo::GDALc::GetPaletteInterpretationName;
*DecToDMS = *Geo::GDALc::DecToDMS;
*PackedDMSToDec = *Geo::GDALc::PackedDMSToDec;
*DecToPackedDMS = *Geo::GDALc::DecToPackedDMS;
*ParseXMLString = *Geo::GDALc::ParseXMLString;
*SerializeXMLTree = *Geo::GDALc::SerializeXMLTree;
*GetJPEG2000StructureAsString = *Geo::GDALc::GetJPEG2000StructureAsString;
*GetDriverCount = *Geo::GDALc::GetDriverCount;
*GetDriverByName = *Geo::GDALc::GetDriverByName;
*_GetDriver = *Geo::GDALc::_GetDriver;
*_Open = *Geo::GDALc::_Open;
*OpenEx = *Geo::GDALc::OpenEx;
*_OpenShared = *Geo::GDALc::_OpenShared;
*IdentifyDriver = *Geo::GDALc::IdentifyDriver;
*GeneralCmdLineProcessor = *Geo::GDALc::GeneralCmdLineProcessor;
############# Class : Geo::GDAL::MajorObject ##############
package Geo::GDAL::MajorObject;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( Geo::GDAL );
%OWNER = ();
*GetDescription = *Geo::GDALc::MajorObject_GetDescription;
*SetDescription = *Geo::GDALc::MajorObject_SetDescription;
*GetMetadataDomainList = *Geo::GDALc::MajorObject_GetMetadataDomainList;
*GetMetadata = *Geo::GDALc::MajorObject_GetMetadata;
*SetMetadata = *Geo::GDALc::MajorObject_SetMetadata;
*GetMetadataItem = *Geo::GDALc::MajorObject_GetMetadataItem;
*SetMetadataItem = *Geo::GDALc::MajorObject_SetMetadataItem;
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
############# Class : Geo::GDAL::Driver ##############
package Geo::GDAL::Driver;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( Geo::GDAL::MajorObject Geo::GDAL );
%OWNER = ();
%ITERATORS = ();
*swig_ShortName_get = *Geo::GDALc::Driver_ShortName_get;
*swig_ShortName_set = *Geo::GDALc::Driver_ShortName_set;
*swig_LongName_get = *Geo::GDALc::Driver_LongName_get;
*swig_LongName_set = *Geo::GDALc::Driver_LongName_set;
*swig_HelpTopic_get = *Geo::GDALc::Driver_HelpTopic_get;
*swig_HelpTopic_set = *Geo::GDALc::Driver_HelpTopic_set;
*_Create = *Geo::GDALc::Driver__Create;
*CreateCopy = *Geo::GDALc::Driver_CreateCopy;
*Delete = *Geo::GDALc::Driver_Delete;
*Rename = *Geo::GDALc::Driver_Rename;
*CopyFiles = *Geo::GDALc::Driver_CopyFiles;
*Register = *Geo::GDALc::Driver_Register;
*Deregister = *Geo::GDALc::Driver_Deregister;
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
############# Class : Geo::GDAL::GCP ##############
package Geo::GDAL::GCP;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( Geo::GDAL );
%OWNER = ();
%ITERATORS = ();
*swig_X_get = *Geo::GDALc::GCP_X_get;
*swig_X_set = *Geo::GDALc::GCP_X_set;
*swig_Y_get = *Geo::GDALc::GCP_Y_get;
*swig_Y_set = *Geo::GDALc::GCP_Y_set;
*swig_Z_get = *Geo::GDALc::GCP_Z_get;
*swig_Z_set = *Geo::GDALc::GCP_Z_set;
*swig_Column_get = *Geo::GDALc::GCP_Column_get;
*swig_Column_set = *Geo::GDALc::GCP_Column_set;
*swig_Row_get = *Geo::GDALc::GCP_Row_get;
*swig_Row_set = *Geo::GDALc::GCP_Row_set;
*swig_Info_get = *Geo::GDALc::GCP_Info_get;
*swig_Info_set = *Geo::GDALc::GCP_Info_set;
*swig_Id_get = *Geo::GDALc::GCP_Id_get;
*swig_Id_set = *Geo::GDALc::GCP_Id_set;
sub new {
my $pkg = shift;
my $self = Geo::GDALc::new_GCP(@_);
bless $self, $pkg if defined($self);
}
sub DESTROY {
my $self;
if ($_[0]->isa('SCALAR')) {
$self = $_[0];
} else {
return unless $_[0]->isa('HASH');
$self = tied(%{$_[0]});
return unless defined $self;
}
delete $ITERATORS{$self};
if (exists $OWNER{$self}) {
Geo::GDALc::delete_GCP($self);
delete $OWNER{$self};
}
$self->RELEASE_PARENTS();
}
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
############# Class : Geo::GDAL::AsyncReader ##############
package Geo::GDAL::AsyncReader;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( Geo::GDAL );
%OWNER = ();
%ITERATORS = ();
sub DESTROY {
return unless $_[0]->isa('HASH');
my $self = tied(%{$_[0]});
return unless defined $self;
delete $ITERATORS{$self};
if (exists $OWNER{$self}) {
Geo::GDALc::delete_AsyncReader($self);
delete $OWNER{$self};
}
}
*GetNextUpdatedRegion = *Geo::GDALc::AsyncReader_GetNextUpdatedRegion;
*LockBuffer = *Geo::GDALc::AsyncReader_LockBuffer;
*UnlockBuffer = *Geo::GDALc::AsyncReader_UnlockBuffer;
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
############# Class : Geo::GDAL::Dataset ##############
package Geo::GDAL::Dataset;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( Geo::GDAL::MajorObject Geo::GDAL );
%OWNER = ();
%ITERATORS = ();
*swig_RasterXSize_get = *Geo::GDALc::Dataset_RasterXSize_get;
*swig_RasterXSize_set = *Geo::GDALc::Dataset_RasterXSize_set;
*swig_RasterYSize_get = *Geo::GDALc::Dataset_RasterYSize_get;
*swig_RasterYSize_set = *Geo::GDALc::Dataset_RasterYSize_set;
*swig_RasterCount_get = *Geo::GDALc::Dataset_RasterCount_get;
*swig_RasterCount_set = *Geo::GDALc::Dataset_RasterCount_set;
sub DESTROY {
my $self;
if ($_[0]->isa('SCALAR')) {
$self = $_[0];
} else {
return unless $_[0]->isa('HASH');
$self = tied(%{$_[0]});
return unless defined $self;
}
delete $ITERATORS{$self};
if (exists $OWNER{$self}) {
Geo::GDALc::delete_Dataset($self);
delete $OWNER{$self};
}
$self->RELEASE_PARENTS();
}
*_GetDriver = *Geo::GDALc::Dataset__GetDriver;
*_GetRasterBand = *Geo::GDALc::Dataset__GetRasterBand;
*GetProjection = *Geo::GDALc::Dataset_GetProjection;
*GetProjectionRef = *Geo::GDALc::Dataset_GetProjectionRef;
*SetProjection = *Geo::GDALc::Dataset_SetProjection;
*GetGeoTransform = *Geo::GDALc::Dataset_GetGeoTransform;
*SetGeoTransform = *Geo::GDALc::Dataset_SetGeoTransform;
*_BuildOverviews = *Geo::GDALc::Dataset__BuildOverviews;
*GetGCPCount = *Geo::GDALc::Dataset_GetGCPCount;
*GetGCPProjection = *Geo::GDALc::Dataset_GetGCPProjection;
*GetGCPs = *Geo::GDALc::Dataset_GetGCPs;
*SetGCPs = *Geo::GDALc::Dataset_SetGCPs;
*FlushCache = *Geo::GDALc::Dataset_FlushCache;
*_AddBand = *Geo::GDALc::Dataset__AddBand;
*_CreateMaskBand = *Geo::GDALc::Dataset__CreateMaskBand;
*GetFileList = *Geo::GDALc::Dataset_GetFileList;
*_WriteRaster = *Geo::GDALc::Dataset__WriteRaster;
*_ReadRaster = *Geo::GDALc::Dataset__ReadRaster;
*StartTransaction = *Geo::GDALc::Dataset_StartTransaction;
*CommitTransaction = *Geo::GDALc::Dataset_CommitTransaction;
*RollbackTransaction = *Geo::GDALc::Dataset_RollbackTransaction;
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
############# Class : Geo::GDAL::Band ##############
package Geo::GDAL::Band;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( Geo::GDAL::MajorObject Geo::GDAL );
%OWNER = ();
%ITERATORS = ();
*swig_XSize_get = *Geo::GDALc::Band_XSize_get;
*swig_XSize_set = *Geo::GDALc::Band_XSize_set;
*swig_YSize_get = *Geo::GDALc::Band_YSize_get;
*swig_YSize_set = *Geo::GDALc::Band_YSize_set;
*swig_DataType_get = *Geo::GDALc::Band_DataType_get;
*swig_DataType_set = *Geo::GDALc::Band_DataType_set;
*GetDataset = *Geo::GDALc::Band_GetDataset;
*GetBand = *Geo::GDALc::Band_GetBand;
*GetBlockSize = *Geo::GDALc::Band_GetBlockSize;
*GetColorInterpretation = *Geo::GDALc::Band_GetColorInterpretation;
*GetRasterColorInterpretation = *Geo::GDALc::Band_GetRasterColorInterpretation;
*SetColorInterpretation = *Geo::GDALc::Band_SetColorInterpretation;
*SetRasterColorInterpretation = *Geo::GDALc::Band_SetRasterColorInterpretation;
*GetNoDataValue = *Geo::GDALc::Band_GetNoDataValue;
*SetNoDataValue = *Geo::GDALc::Band_SetNoDataValue;
*GetUnitType = *Geo::GDALc::Band_GetUnitType;
*SetUnitType = *Geo::GDALc::Band_SetUnitType;
*GetRasterCategoryNames = *Geo::GDALc::Band_GetRasterCategoryNames;
*SetRasterCategoryNames = *Geo::GDALc::Band_SetRasterCategoryNames;
*GetMinimum = *Geo::GDALc::Band_GetMinimum;
*GetMaximum = *Geo::GDALc::Band_GetMaximum;
*GetOffset = *Geo::GDALc::Band_GetOffset;
*GetScale = *Geo::GDALc::Band_GetScale;
*SetOffset = *Geo::GDALc::Band_SetOffset;
*SetScale = *Geo::GDALc::Band_SetScale;
*GetStatistics = *Geo::GDALc::Band_GetStatistics;
*ComputeStatistics = *Geo::GDALc::Band_ComputeStatistics;
*SetStatistics = *Geo::GDALc::Band_SetStatistics;
*GetOverviewCount = *Geo::GDALc::Band_GetOverviewCount;
*GetOverview = *Geo::GDALc::Band_GetOverview;
*Checksum = *Geo::GDALc::Band_Checksum;
*ComputeRasterMinMax = *Geo::GDALc::Band_ComputeRasterMinMax;
*ComputeBandStats = *Geo::GDALc::Band_ComputeBandStats;
*Fill = *Geo::GDALc::Band_Fill;
*_ReadRaster = *Geo::GDALc::Band__ReadRaster;
*_WriteRaster = *Geo::GDALc::Band__WriteRaster;
*FlushCache = *Geo::GDALc::Band_FlushCache;
*GetRasterColorTable = *Geo::GDALc::Band_GetRasterColorTable;
*GetColorTable = *Geo::GDALc::Band_GetColorTable;
*SetRasterColorTable = *Geo::GDALc::Band_SetRasterColorTable;
*SetColorTable = *Geo::GDALc::Band_SetColorTable;
*GetDefaultRAT = *Geo::GDALc::Band_GetDefaultRAT;
*SetDefaultRAT = *Geo::GDALc::Band_SetDefaultRAT;
*GetMaskBand = *Geo::GDALc::Band_GetMaskBand;
*_GetMaskFlags = *Geo::GDALc::Band__GetMaskFlags;
*_CreateMaskBand = *Geo::GDALc::Band__CreateMaskBand;
*_GetHistogram = *Geo::GDALc::Band__GetHistogram;
*GetDefaultHistogram = *Geo::GDALc::Band_GetDefaultHistogram;
*SetDefaultHistogram = *Geo::GDALc::Band_SetDefaultHistogram;
*HasArbitraryOverviews = *Geo::GDALc::Band_HasArbitraryOverviews;
*GetCategoryNames = *Geo::GDALc::Band_GetCategoryNames;
*SetCategoryNames = *Geo::GDALc::Band_SetCategoryNames;
*ContourGenerate = *Geo::GDALc::Band_ContourGenerate;
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
############# Class : Geo::GDAL::ColorTable ##############
package Geo::GDAL::ColorTable;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( Geo::GDAL );
%OWNER = ();
use Carp;
sub new {
my($pkg, $pi) = @_;
$pi = $PALETTE_INTERPRETATION_STRING2INT{$pi} if defined $pi and exists $PALETTE_INTERPRETATION_STRING2INT{$pi};
my $self = Geo::GDALc::new_ColorTable($pi);
bless $self, $pkg if defined($self);
}
sub DESTROY {
my $self;
if ($_[0]->isa('SCALAR')) {
$self = $_[0];
} else {
return unless $_[0]->isa('HASH');
$self = tied(%{$_[0]});
return unless defined $self;
}
delete $ITERATORS{$self};
if (exists $OWNER{$self}) {
Geo::GDALc::delete_ColorTable($self);
delete $OWNER{$self};
}
$self->RELEASE_PARENTS();
}
*Clone = *Geo::GDALc::ColorTable_Clone;
*_GetPaletteInterpretation = *Geo::GDALc::ColorTable__GetPaletteInterpretation;
*GetCount = *Geo::GDALc::ColorTable_GetCount;
*GetColorEntry = *Geo::GDALc::ColorTable_GetColorEntry;
*GetColorEntryAsRGB = *Geo::GDALc::ColorTable_GetColorEntryAsRGB;
*_SetColorEntry = *Geo::GDALc::ColorTable__SetColorEntry;
*CreateColorRamp = *Geo::GDALc::ColorTable_CreateColorRamp;
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
############# Class : Geo::GDAL::RasterAttributeTable ##############
package Geo::GDAL::RasterAttributeTable;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( Geo::GDAL );
%OWNER = ();
sub new {
my $pkg = shift;
my $self = Geo::GDALc::new_RasterAttributeTable(@_);
bless $self, $pkg if defined($self);
}
sub DESTROY {
my $self;
if ($_[0]->isa('SCALAR')) {
$self = $_[0];
} else {
return unless $_[0]->isa('HASH');
$self = tied(%{$_[0]});
return unless defined $self;
}
delete $ITERATORS{$self};
if (exists $OWNER{$self}) {
Geo::GDALc::delete_RasterAttributeTable($self);
delete $OWNER{$self};
}
$self->RELEASE_PARENTS();
}
*Clone = *Geo::GDALc::RasterAttributeTable_Clone;
*GetColumnCount = *Geo::GDALc::RasterAttributeTable_GetColumnCount;
*GetNameOfCol = *Geo::GDALc::RasterAttributeTable_GetNameOfCol;
*_GetUsageOfCol = *Geo::GDALc::RasterAttributeTable__GetUsageOfCol;
*_GetTypeOfCol = *Geo::GDALc::RasterAttributeTable__GetTypeOfCol;
*_GetColOfUsage = *Geo::GDALc::RasterAttributeTable__GetColOfUsage;
*GetRowCount = *Geo::GDALc::RasterAttributeTable_GetRowCount;
*GetValueAsString = *Geo::GDALc::RasterAttributeTable_GetValueAsString;
*GetValueAsInt = *Geo::GDALc::RasterAttributeTable_GetValueAsInt;
*GetValueAsDouble = *Geo::GDALc::RasterAttributeTable_GetValueAsDouble;
*SetValueAsString = *Geo::GDALc::RasterAttributeTable_SetValueAsString;
*SetValueAsInt = *Geo::GDALc::RasterAttributeTable_SetValueAsInt;
*SetValueAsDouble = *Geo::GDALc::RasterAttributeTable_SetValueAsDouble;
*SetRowCount = *Geo::GDALc::RasterAttributeTable_SetRowCount;
*_CreateColumn = *Geo::GDALc::RasterAttributeTable__CreateColumn;
*GetLinearBinning = *Geo::GDALc::RasterAttributeTable_GetLinearBinning;
*SetLinearBinning = *Geo::GDALc::RasterAttributeTable_SetLinearBinning;
*GetRowOfValue = *Geo::GDALc::RasterAttributeTable_GetRowOfValue;
*ChangesAreWrittenToFile = *Geo::GDALc::RasterAttributeTable_ChangesAreWrittenToFile;
*DumpReadable = *Geo::GDALc::RasterAttributeTable_DumpReadable;
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
############# Class : Geo::GDAL::Transformer ##############
package Geo::GDAL::Transformer;
use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
@ISA = qw( Geo::GDAL );
%OWNER = ();
%ITERATORS = ();
sub new {
my $pkg = shift;
my $self = Geo::GDALc::new_Transformer(@_);
bless $self, $pkg if defined($self);
}
sub DESTROY {
return unless $_[0]->isa('HASH');
my $self = tied(%{$_[0]});
return unless defined $self;
delete $ITERATORS{$self};
if (exists $OWNER{$self}) {
Geo::GDALc::delete_Transformer($self);
delete $OWNER{$self};
}
}
*TransformPoint = *Geo::GDALc::Transformer_TransformPoint;
*_TransformPoints = *Geo::GDALc::Transformer__TransformPoints;
*TransformGeolocations = *Geo::GDALc::Transformer_TransformGeolocations;
sub DISOWN {
my $self = shift;
my $ptr = tied(%$self);
delete $OWNER{$ptr};
}
sub ACQUIRE {
my $self = shift;
my $ptr = tied(%$self);
$OWNER{$ptr} = 1;
}
# ------- VARIABLE STUBS --------
package Geo::GDAL;
*TermProgress = *Geo::GDALc::TermProgress;
package Geo::GDAL;
use strict;
use warnings;
use Carp;
use Encode;
use Geo::GDAL::Const;
use Geo::OGR;
use Geo::OSR;
# $VERSION is the Perl module (CPAN) version number, which must be
# an increasing floating point number. $GDAL_VERSION is the
# version number of the GDAL that this module is a part of. It is
# used in build time to check the version of GDAL against which we
# build.
# For GDAL 2.0 or above, GDAL X.Y.Z should then
# VERSION = X + Y / 100.0 + Z / 10000.0
our $VERSION = '2.00004';
our $GDAL_VERSION = '2.0.0';
=pod
=head1 NAME
Geo::GDAL - Perl extension for the GDAL library for geospatial data
=head1 SYNOPSIS
use Geo::GDAL;
my $raster_file = shift @ARGV;
my $raster_dataset = Geo::GDAL::Open($file);
my $raster_data = $dataset->GetRasterBand(1)->ReadTile;
my $vector_datasource = Geo::OGR::Open('./');
my $vector_layer = $datasource->Layer('borders'); # e.g. a shapefile borders.shp in current directory
$vector_layer->ResetReading();
while (my $feature = $vector_layer->GetNextFeature()) {
my $geometry = $feature->GetGeometry();
my $value = $feature->GetField($field);
}
=head1 DESCRIPTION
This Perl module lets you to manage (read, analyse, write) geospatial
data stored in several formats.
=head2 EXPORT
None by default.
=head1 SEE ALSO
The GDAL home page is L<http://gdal.org/>
The documentation of this module is written in Doxygen format. See
L<http://ajolma.net/Geo-GDAL/snapshot/>
=head1 AUTHOR
Ari Jolma
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2005- by Ari Jolma and GDAL bindings developers.
This library is free software; you can redistribute it and/or modify
it under the terms of MIT License
L<https://opensource.org/licenses/MIT>
=head1 REPOSITORY
L<https://trac.osgeo.org/gdal>
=cut
use vars qw/
@DATA_TYPES @ACCESS_TYPES @RESAMPLING_TYPES @RIO_RESAMPLING_TYPES @NODE_TYPES
%TYPE_STRING2INT %TYPE_INT2STRING
%ACCESS_STRING2INT %ACCESS_INT2STRING
%RESAMPLING_STRING2INT %RESAMPLING_INT2STRING
%RIO_RESAMPLING_STRING2INT %RIO_RESAMPLING_INT2STRING
%NODE_TYPE_STRING2INT %NODE_TYPE_INT2STRING
/;
for (keys %Geo::GDAL::Const::) {
next if /TypeCount/;
push(@DATA_TYPES, $1), next if /^GDT_(\w+)/;
push(@ACCESS_TYPES, $1), next if /^GA_(\w+)/;
push(@RESAMPLING_TYPES, $1), next if /^GRA_(\w+)/;
push(@RIO_RESAMPLING_TYPES, $1), next if /^GRIORA_(\w+)/;
push(@NODE_TYPES, $1), next if /^CXT_(\w+)/;
}
for my $string (@DATA_TYPES) {
my $int = eval "\$Geo::GDAL::Const::GDT_$string";
$TYPE_STRING2INT{$string} = $int;
$TYPE_INT2STRING{$int} = $string;
}
for my $string (@ACCESS_TYPES) {
my $int = eval "\$Geo::GDAL::Const::GA_$string";
$ACCESS_STRING2INT{$string} = $int;
$ACCESS_INT2STRING{$int} = $string;
}
for my $string (@RESAMPLING_TYPES) {
my $int = eval "\$Geo::GDAL::Const::GRA_$string";
$RESAMPLING_STRING2INT{$string} = $int;
$RESAMPLING_INT2STRING{$int} = $string;
}
for my $string (@RIO_RESAMPLING_TYPES) {
my $int = eval "\$Geo::GDAL::Const::GRIORA_$string";
$RIO_RESAMPLING_STRING2INT{$string} = $int;
$RIO_RESAMPLING_INT2STRING{$int} = $string;
}
for my $string (@NODE_TYPES) {
my $int = eval "\$Geo::GDAL::Const::CXT_$string";
$NODE_TYPE_STRING2INT{$string} = $int;
$NODE_TYPE_INT2STRING{$int} = $string;
}
sub RELEASE_PARENTS {
}
sub DataTypes {
return @DATA_TYPES;
}
sub AccessTypes {
return @ACCESS_TYPES;
}
sub ResamplingTypes {
return @RESAMPLING_TYPES;
}
sub RIOResamplingTypes {
return @RIO_RESAMPLING_TYPES;
}
sub NodeTypes {
return @NODE_TYPES;
}
sub NodeType {
my $type = shift;
return $NODE_TYPE_INT2STRING{$type} if $type =~ /^\d/;
return $NODE_TYPE_STRING2INT{$type};
}
sub NodeData {
my $node = shift;
return (Geo::GDAL::NodeType($node->[0]), $node->[1]);
}
sub Children {
my $node = shift;
return @$node[2..$#$node];
}
sub Child {
my($node, $child) = @_;
return $node->[2+$child];
}
sub GetDataTypeSize {
my $t = shift;
my $t2 = $t;
$t2 = $TYPE_STRING2INT{$t} if exists $TYPE_STRING2INT{$t};
confess "Unknown data type: '$t'." unless exists $TYPE_INT2STRING{$t2};
return _GetDataTypeSize($t2);
}
sub DataTypeValueRange {
my $t = shift;
confess "Unknown data type: '$t'." unless exists $TYPE_STRING2INT{$t};
# these values are from gdalrasterband.cpp
return (0,255) if $t =~ /Byte/;
return (0,65535) if $t =~/UInt16/;
return (-32768,32767) if $t =~/Int16/;
return (0,4294967295) if $t =~/UInt32/;
return (-2147483648,2147483647) if $t =~/Int32/;
return (-4294967295.0,4294967295.0) if $t =~/Float32/;
return (-4294967295.0,4294967295.0) if $t =~/Float64/;
}
sub DataTypeIsComplex {
my $t = shift;
my $t2 = $t;
$t2 = $TYPE_STRING2INT{$t} if exists $TYPE_STRING2INT{$t};
confess "Unknown data type: '$t'." unless exists $TYPE_INT2STRING{$t2};
return _DataTypeIsComplex($t2);
}
sub PackCharacter {
my $t = shift;
$t = $TYPE_INT2STRING{$t} if exists $TYPE_INT2STRING{$t};
confess "Unknown data type: '$t'." unless exists $TYPE_STRING2INT{$t};
my $is_big_endian = unpack("h*", pack("s", 1)) =~ /01/; # from Programming Perl
return 'C' if $t =~ /^Byte$/;
return ($is_big_endian ? 'n': 'v') if $t =~ /^UInt16$/;
return 's' if $t =~ /^Int16$/;
return ($is_big_endian ? 'N' : 'V') if $t =~ /^UInt32$/;
return 'l' if $t =~ /^Int32$/;
return 'f' if $t =~ /^Float32$/;
return 'd' if $t =~ /^Float64$/;
}
sub GetDriverNames {
my @names;
for my $i (0..GetDriverCount()-1) {
my $driver = _GetDriver($i);
my $md = $driver->GetMetadata;
next unless $md->{DCAP_RASTER} and $md->{DCAP_RASTER} eq 'YES';
push @names, _GetDriver($i)->Name;
}
return @names;
}
sub Drivers {
my @drivers;
for my $i (0..GetDriverCount()-1) {
my $driver = _GetDriver($i);
my $md = $driver->GetMetadata;
next unless $md->{DCAP_RASTER} and $md->{DCAP_RASTER} eq 'YES';
push @drivers, _GetDriver($i);
}
return @drivers;
}
sub GetDriver {
my($name) = @_;
$name = 0 unless defined $name;
my $driver;
$driver = _GetDriver($name) if $name =~ /^\d+$/; # is the name an index to driver list?
$driver = GetDriverByName("$name") unless $driver;
if ($driver) {
my $md = $driver->GetMetadata;
confess "Driver exists but does not have raster capabilities."
unless $md->{DCAP_RASTER} and $md->{DCAP_RASTER} eq 'YES';
return $driver;
}
confess "Driver not found: '$name'. Maybe support for it was not built in?";
}
*Driver = *GetDriver;
sub Open {
my @p = @_;
if (defined $p[1]) {
confess "Unknown access type: '$p[1]'." unless exists $Geo::GDAL::ACCESS_STRING2INT{$p[1]};
$p[1] = $Geo::GDAL::ACCESS_STRING2INT{$p[1]};
}
return _Open(@p);
}
sub OpenShared {
my @p = @_;
if (defined $p[1]) {
confess "Unknown access type: '$p[1]'." unless exists $Geo::GDAL::ACCESS_STRING2INT{$p[1]};
$p[1] = $Geo::GDAL::ACCESS_STRING2INT{$p[1]};
}
return _OpenShared(@p);
}
sub ComputeMedianCutPCT {
my @p = @_;
$p[6] = 1 if $p[5] and not defined $p[6];
_ComputeMedianCutPCT(@p);
}
sub DitherRGB2PCT {
my @p = @_;
$p[6] = 1 if $p[5] and not defined $p[6];
_DitherRGB2PCT(@p);
}
sub ComputeProximity {
my @p = @_;
$p[4] = 1 if $p[3] and not defined $p[4];
_ComputeProximity(@p);
}
sub RasterizeLayer {
my @p = @_;
$p[8] = 1 if $p[7] and not defined $p[8];
_RasterizeLayer(@p);
}
sub Polygonize {
my @params = @_;
$params[6] = 1 if $params[5] and not defined $params[6];
$params[3] = $params[2]->GetLayerDefn->GetFieldIndex($params[3]) unless $params[3] =~ /^\d/;
_Polygonize(@params);
}
sub SieveFilter {
my @p = @_;
$p[7] = 1 if $p[6] and not defined $p[7];
_SieveFilter(@p);
}
sub RegenerateOverviews {
my @p = @_;
$p[2] = uc($p[2]) if $p[2]; # see overview.cpp:2030
$p[4] = 1 if $p[3] and not defined $p[4];
_RegenerateOverviews(@p);
}
sub RegenerateOverview {
my @p = @_;
$p[2] = uc($p[2]) if $p[2]; # see overview.cpp:2030
$p[4] = 1 if $p[3] and not defined $p[4];
_RegenerateOverview(@p);
}
sub ReprojectImage {
my @p = @_;
$p[8] = 1 if $p[7] and not defined $p[8];
if (defined $p[4]) {
confess "Unknown data type: '$p[4]'." unless exists $Geo::GDAL::RESAMPLING_STRING2INT{$p[4]};
$p[4] = $Geo::GDAL::RESAMPLING_STRING2INT{$p[4]};
}
return _ReprojectImage(@p);
}
sub AutoCreateWarpedVRT {
my @p = @_;
for my $i (1..2) {
if (defined $p[$i] and ref($p[$i])) {
$p[$i] = $p[$i]->ExportToWkt;
}
}
if (defined $p[3]) {
confess "Unknown data type: '$p[3]'." unless exists $Geo::GDAL::RESAMPLING_STRING2INT{$p[3]};
$p[3] = $Geo::GDAL::RESAMPLING_STRING2INT{$p[3]};
}
return _AutoCreateWarpedVRT(@p);
}
package Geo::GDAL::MajorObject;
use strict;
use warnings;
use vars qw/@DOMAINS/;
sub Domains {
return @DOMAINS;
}
sub Description {
my($self, $desc) = @_;
SetDescription($self, $desc) if defined $desc;
GetDescription($self) if defined wantarray;
}
sub Metadata {
my $self = shift;
my $metadata;
$metadata = shift if ref $_[0];
my $domain = shift;
$domain = '' unless defined $domain;
SetMetadata($self, $metadata, $domain) if defined $metadata;
GetMetadata($self, $domain) if defined wantarray;
}
package Geo::GDAL::Driver;
use strict;
use warnings;
use Carp;
use vars qw/@CAPABILITIES @DOMAINS/;
for (keys %Geo::GDAL::Const::) {
next if /TypeCount/;
push(@CAPABILITIES, $1), next if /^DCAP_(\w+)/;
}
sub Domains {
return @DOMAINS;
}
sub Name {
my $self = shift;
return $self->{ShortName};
}
sub Capabilities {
my $self = shift;
return @CAPABILITIES unless $self;
my $h = $self->GetMetadata;
my @cap;
for my $cap (@CAPABILITIES) {
my $test = $h->{'DCAP_'.uc($cap)};
push @cap, $cap if defined($test) and $test eq 'YES';
}
return @cap;
}
sub TestCapability {
my($self, $cap) = @_;
my $h = $self->GetMetadata->{'DCAP_'.uc($cap)};
return (defined($h) and $h eq 'YES') ? 1 : undef;
}
sub Extension {
my $self = shift;
my $h = $self->GetMetadata;
return $h->{DMD_EXTENSION};
}
sub MIMEType {
my $self = shift;
my $h = $self->GetMetadata;
return $h->{DMD_MIMETYPE};
}
sub CreationOptionList {
my $self = shift;
my @options;
my $h = $self->GetMetadata->{DMD_CREATIONOPTIONLIST};
if ($h) {
$h = Geo::GDAL::ParseXMLString($h);
my($type, $value) = Geo::GDAL::NodeData($h);
if ($value eq 'CreationOptionList') {
for my $o (Geo::GDAL::Children($h)) {
my %option;
for my $a (Geo::GDAL::Children($o)) {
my(undef, $key) = Geo::GDAL::NodeData($a);
my(undef, $value) = Geo::GDAL::NodeData(Geo::GDAL::Child($a, 0));
if ($key eq 'Value') {
push @{$option{$key}}, $value;
} else {
$option{$key} = $value;
}
}
push @options, \%option;
}
}
}
return @options;
}
sub CreationDataTypes {
my $self = shift;
my $h = $self->GetMetadata;
return split /\s+/, $h->{DMD_CREATIONDATATYPES} if $h->{DMD_CREATIONDATATYPES};
}
sub Create {
my $self = shift;
my %defaults = ( Name => 'unnamed',
Width => 256,
Height => 256,
Bands => 1,
Type => 'Byte',
Options => {} );
my %params;
if (@_ == 0) {
} elsif (ref($_[0]) eq 'HASH') {
%params = %{$_[0]};
} elsif (exists $defaults{$_[0]} and @_ % 2 == 0) {
%params = @_;
} else {
($params{Name}, $params{Width}, $params{Height}, $params{Bands}, $params{Type}, $params{Options}) = @_;
}
for my $k (keys %params) {
carp "Create: unrecognized named parameter '$k'." unless exists $defaults{$k};
}
for my $k (keys %defaults) {
$params{$k} = $defaults{$k} unless defined $params{$k};
}
my $type;
confess "Unknown data type: '$params{Type}'." unless exists $Geo::GDAL::TYPE_STRING2INT{$params{Type}};
$type = $Geo::GDAL::TYPE_STRING2INT{$params{Type}};
return $self->_Create($params{Name}, $params{Width}, $params{Height}, $params{Bands}, $type, $params{Options});
}
*CreateDataset = *Create;
*Copy = *CreateCopy;
package Geo::GDAL::Dataset;
use strict;
use warnings;
use Carp;
use vars qw/%BANDS @DOMAINS/;
@DOMAINS = qw/IMAGE_STRUCTURE SUBDATASETS GEOLOCATION/;
sub Domains {
return @DOMAINS;
}
*GetDriver = *_GetDriver;
sub Open {
return Geo::GDAL::Open(@_);
}
sub OpenShared {
return Geo::GDAL::OpenShared(@_);
}
sub Size {
my $self = shift;
return ($self->{RasterXSize}, $self->{RasterYSize});
}
sub Bands {
my $self = shift;
my @bands;
for my $i (1..$self->{RasterCount}) {
push @bands, GetRasterBand($self, $i);
}
return @bands;
}
sub GetRasterBand {
my($self, $index) = @_;
$index = 1 unless defined $index;
my $band = _GetRasterBand($self, $index);
$BANDS{tied(%{$band})} = $self;
return $band;
}
*Band = *GetRasterBand;
sub AddBand {
my @p = @_;
if (defined $p[1]) {
confess "Unknown data type: '$p[1]'." unless exists $Geo::GDAL::TYPE_STRING2INT{$p[1]};
$p[1] = $Geo::GDAL::TYPE_STRING2INT{$p[1]};
}
return _AddBand(@p);
}
sub Projection {
my($self, $proj) = @_;
SetProjection($self, $proj) if defined $proj;
GetProjection($self) if defined wantarray;
}
sub SpatialReference {
my($self, $sr) = @_;
SetProjection($self, $sr->As('WKT')) if defined $sr;
return Geo::OSR::SpatialReference->new(GetProjection($self)) if defined wantarray;
}
sub GeoTransform {
my $self = shift;
eval {
if (@_ == 1) {
SetGeoTransform($self, $_[0]);
} elsif (@_ > 1) {
SetGeoTransform($self, \@_);
}
};
confess $@ if $@;
return unless defined wantarray;
my $t = GetGeoTransform($self);
if (wantarray) {
return @$t;
} else {
return Geo::GDAL::GeoTransform->new($t);
}
}
sub GCPs {
my $self = shift;
if (@_ > 0) {
my $proj = pop @_;
$proj = $proj->Export('WKT') if $proj and ref($proj);
SetGCPs($self, \@_, $proj);
}
return unless defined wantarray;
my $proj = Geo::OSR::SpatialReference->new(GetGCPProjection($self));
my $GCPs = GetGCPs($self);
return (@$GCPs, $proj);
}
sub ReadRaster {
my $self = shift;
my ($width, $height) = $self->Size;
my ($type) = $self->Band->DataType;
my %d = (
XOFF => 0,
YOFF => 0,
XSIZE => $width,
YSIZE => $height,
BUFXSIZE => undef,
BUFYSIZE => undef,
BUFTYPE => $type,
BANDLIST => [1],
BUFPIXELSPACE => 0,
BUFLINESPACE => 0,
BUFBANDSPACE => 0,
RESAMPLEALG => 'NearestNeighbour',
PROGRESS => undef,
PROGRESSDATA => undef
);
my %p;
my $t;
if (defined $_[0]) {
$t = uc($_[0]);
$t =~ s/_//g;
}
if (@_ == 0) {
} elsif (ref($_[0]) eq 'HASH') {
%p = %{$_[0]};
} elsif (@_ % 2 == 0 and (defined $t and exists $d{$t})) {
%p = @_;
} else {
($p{xoff},$p{yoff},$p{xsize},$p{ysize},$p{buf_xsize},$p{buf_ysize},$p{buf_type},$p{band_list},$p{buf_pixel_space},$p{buf_line_space},$p{buf_band_space},$p{resample_alg},$p{progress},$p{progress_data}) = @_;
}
for (keys %p) {
my $u = uc($_);
$u =~ s/_//g;
carp "Unknown named parameter '$_'." unless exists $d{$u};
$p{$u} = $p{$_};
}
for (keys %d) {
$p{$_} = $d{$_} unless defined $p{$_};
}
confess "Unknown resampling algorithm: '$p{RESAMPLEALG}'."
unless exists $Geo::GDAL::RIO_RESAMPLING_STRING2INT{$p{RESAMPLEALG}};
$p{RESAMPLEALG} = $Geo::GDAL::RIO_RESAMPLING_STRING2INT{$p{RESAMPLEALG}};
unless ($Geo::GDAL::TYPE_INT2STRING{$p{BUFTYPE}}) {
confess "Unknown data type: '$p{BUFTYPE}'."
unless exists $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
$p{BUFTYPE} = $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
}
$self->_ReadRaster($p{XOFF},$p{YOFF},$p{XSIZE},$p{YSIZE},$p{BUFXSIZE},$p{BUFYSIZE},$p{BUFTYPE},$p{BANDLIST},$p{BUFPIXELSPACE},$p{BUFLINESPACE},$p{BUFBANDSPACE},$p{RESAMPLEALG},$p{PROGRESS},$p{PROGRESSDATA});
}
sub WriteRaster {
my $self = shift;
my ($width, $height) = $self->Size;
my ($type) = $self->Band->DataType;
my %d = (
XOFF => 0,
YOFF => 0,
XSIZE => $width,
YSIZE => $height,
BUF => undef,
BUFXSIZE => undef,
BUFYSIZE => undef,
BUFTYPE => $type,
BANDLIST => [1],
BUFPIXELSPACE => 0,
BUFLINESPACE => 0,
BUFBANDSPACE => 0
);
my %p;
my $t;
if (defined $_[0]) {
$t = uc($_[0]);
$t =~ s/_//g;
}
if (@_ == 0) {
} elsif (ref($_[0]) eq 'HASH') {
%p = %{$_[0]};
} elsif (@_ % 2 == 0 and (defined $t and exists $d{$t})) {
%p = @_;
} else {
($p{xoff},$p{yoff},$p{xsize},$p{ysize},$p{buf},$p{buf_xsize},$p{buf_ysize},$p{buf_type},$p{band_list},$p{buf_pixel_space},$p{buf_line_space},$p{buf_band_space}) = @_;
}
for (keys %p) {
my $u = uc($_);
$u =~ s/_//g;
carp "Unknown named parameter '$_'." unless exists $d{$u};
$p{$u} = $p{$_};
}
for (keys %d) {
$p{$_} = $d{$_} unless defined $p{$_};
}
unless ($Geo::GDAL::TYPE_INT2STRING{$p{BUFTYPE}}) {
confess "Unknown data type: '$p{BUFTYPE}'."
unless exists $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
$p{BUFTYPE} = $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
}
$self->_WriteRaster($p{XOFF},$p{YOFF},$p{XSIZE},$p{YSIZE},$p{BUF},$p{BUFXSIZE},$p{BUFYSIZE},$p{BUFTYPE},$p{BANDLIST},$p{BUFPIXELSPACE},$p{BUFLINESPACE},$p{BUFBANDSPACE});
}
sub BuildOverviews {
my $self = shift;
my @p = @_;
$p[0] = uc($p[0]) if $p[0];
eval {
$self->_BuildOverviews(@p);
};
confess $@ if $@;
}
package Geo::GDAL::Band;
use strict;
use warnings;
use POSIX;
use Carp;
use Scalar::Util 'blessed';
use vars qw/
@COLOR_INTERPRETATIONS
%COLOR_INTERPRETATION_STRING2INT %COLOR_INTERPRETATION_INT2STRING @DOMAINS
%MASK_FLAGS
/;
for (keys %Geo::GDAL::Const::) {
next if /TypeCount/;
push(@COLOR_INTERPRETATIONS, $1), next if /^GCI_(\w+)/;
}
for my $string (@COLOR_INTERPRETATIONS) {
my $int = eval "\$Geo::GDAL::Constc::GCI_$string";
$COLOR_INTERPRETATION_STRING2INT{$string} = $int;
$COLOR_INTERPRETATION_INT2STRING{$int} = $string;
}
@DOMAINS = qw/IMAGE_STRUCTURE RESAMPLING/;
%MASK_FLAGS = (AllValid => 1, PerDataset => 2, Alpha => 4, NoData => 8);
sub Domains {
return @DOMAINS;
}
sub ColorInterpretations {
return @COLOR_INTERPRETATIONS;
}
sub MaskFlags {
my @f = sort {$MASK_FLAGS{$a} <=> $MASK_FLAGS{$b}} keys %MASK_FLAGS;
return @f;
}
sub DESTROY {
my $self;
if ($_[0]->isa('SCALAR')) {
$self = $_[0];
} else {
return unless $_[0]->isa('HASH');
$self = tied(%{$_[0]});
return unless defined $self;
}
delete $ITERATORS{$self};
if (exists $OWNER{$self}) {
delete $OWNER{$self};
}
$self->RELEASE_PARENTS();
}
sub RELEASE_PARENTS {
my $self = shift;
delete $Geo::GDAL::Dataset::BANDS{$self};
}
sub Size {
my $self = shift;
return ($self->{XSize}, $self->{YSize});
}
sub DataType {
my $self = shift;
return $Geo::GDAL::TYPE_INT2STRING{$self->{DataType}};
}
sub PackCharacter {
my $self = shift;
return Geo::GDAL::PackCharacter($self->DataType);
}
sub NoDataValue {
my $self = shift;
if (@_ > 0) {
if (defined $_[0]) {
SetNoDataValue($self, $_[0]);
} else {
SetNoDataValue($self, POSIX::FLT_MAX); # hopefully an "out of range" value
}
}
GetNoDataValue($self);
}
sub Unit {
my $self = shift;
if (@_ > 0) {
my $unit = shift;
$unit = '' unless defined $unit;
SetUnitType($self, $unit);
}
return unless defined wantarray;
GetUnitType($self);
}
sub ScaleAndOffset {
my $self = shift;
SetScale($self, $_[0]) if @_ > 0 and defined $_[0];
SetOffset($self, $_[1]) if @_ > 1 and defined $_[1];
return unless defined wantarray;
my $scale = GetScale($self);
my $offset = GetOffset($self);
return ($scale, $offset);
}
sub ReadTile {
my($self, $xoff, $yoff, $xsize, $ysize) = @_;
$xoff = 0 unless defined $xoff;
$yoff = 0 unless defined $yoff;
$xsize = $self->{XSize} - $xoff unless defined $xsize;
$ysize = $self->{YSize} - $yoff unless defined $ysize;
my $buf = $self->ReadRaster($xoff, $yoff, $xsize, $ysize);
my $pc = Geo::GDAL::PackCharacter($self->{DataType});
my $w = $xsize * Geo::GDAL::GetDataTypeSize($self->{DataType})/8;
my $offset = 0;
my @data;
for (0..$ysize-1) {
my $sub = substr($buf, $offset, $w);
my @d = unpack($pc."[$xsize]", $sub);
push @data, \@d;
$offset += $w;
}
return \@data;
}
sub WriteTile {
my($self, $data, $xoff, $yoff) = @_;
$xoff = 0 unless defined $xoff;
$yoff = 0 unless defined $yoff;
my $xsize = @{$data->[0]};
$xsize = $self->{XSize} - $xoff if $xsize > $self->{XSize} - $xoff;
my $ysize = @{$data};
$ysize = $self->{YSize} - $yoff if $ysize > $self->{YSize} - $yoff;
my $pc = Geo::GDAL::PackCharacter($self->{DataType});
for my $i (0..$ysize-1) {
my $scanline = pack($pc."[$xsize]", @{$data->[$i]});
$self->WriteRaster( $xoff, $yoff+$i, $xsize, 1, $scanline );
}
}
sub ColorInterpretation {
my($self, $ci) = @_;
if (defined $ci) {
my $ci2 = $ci;
$ci2 = $COLOR_INTERPRETATION_STRING2INT{$ci} if exists $COLOR_INTERPRETATION_STRING2INT{$ci};
confess "Unknown color interpretation: '$ci'." unless exists $COLOR_INTERPRETATION_INT2STRING{$ci2};
SetRasterColorInterpretation($self, $ci2);
return $ci;
} else {
return $COLOR_INTERPRETATION_INT2STRING{GetRasterColorInterpretation($self)};
}
}
sub ColorTable {
my $self = shift;
SetRasterColorTable($self, $_[0]) if @_ and defined $_[0];
return unless defined wantarray;
GetRasterColorTable($self);
}
sub CategoryNames {
my $self = shift;
SetRasterCategoryNames($self, \@_) if @_;
return unless defined wantarray;
my $n = GetRasterCategoryNames($self);
return @$n;
}
sub AttributeTable {
my $self = shift;
SetDefaultRAT($self, $_[0]) if @_ and defined $_[0];
return unless defined wantarray;
my $r = GetDefaultRAT($self);
$Geo::GDAL::RasterAttributeTable::BANDS{$r} = $self if $r;
return $r;
}
sub GetHistogram {
my $self = shift;
my %defaults = (Min => -0.5,
Max => 255.5,
Buckets => 256,
IncludeOutOfRange => 0,
ApproxOK => 0,
Progress => undef,
ProgressData => undef);
my %params = @_;
for (keys %params) {
carp "unknown parameter $_ in Geo::GDAL::Band::GetHistogram" unless exists $defaults{$_};
}
for (keys %defaults) {
$params{$_} = $defaults{$_} unless defined $params{$_};
}
$params{ProgressData} = 1 if $params{Progress} and not defined $params{ProgressData};
_GetHistogram($self, $params{Min}, $params{Max}, $params{Buckets},
$params{IncludeOutOfRange}, $params{ApproxOK},
$params{Progress}, $params{ProgressData});
}
sub Contours {
my $self = shift;
my %defaults = (DataSource => undef,
LayerConstructor => {Name => 'contours'},
ContourInterval => 100,
ContourBase => 0,
FixedLevels => [],
NoDataValue => undef,
IDField => -1,
ElevField => -1,
Progress => undef,
ProgressData => undef);
my %params;
if (!defined($_[0]) or (blessed($_[0]) and $_[0]->isa('Geo::OGR::DataSource'))) {
($params{DataSource}, $params{LayerConstructor},
$params{ContourInterval}, $params{ContourBase},
$params{FixedLevels}, $params{NoDataValue},
$params{IDField}, $params{ElevField},
$params{Progress}, $params{ProgressData}) = @_;
} else {
%params = @_;
if (exists $params{progress}) {
$params{Progress} = $params{progress};
delete $params{progress};
}
if (exists $params{progress_data}) {
$params{ProgressData} = $params{progress_data};
delete $params{progress_data};
}
}
for (keys %params) {
carp "unknown parameter $_ in Geo::GDAL::Band::Contours" unless exists $defaults{$_};
}
for (keys %defaults) {
$params{$_} = $defaults{$_} unless defined $params{$_};
}
$params{DataSource} = Geo::OGR::GetDriver('Memory')->CreateDataSource('ds')
unless defined $params{DataSource};
$params{LayerConstructor}->{Schema} = {} unless $params{LayerConstructor}->{Schema};
$params{LayerConstructor}->{Schema}{Fields} = [] unless $params{LayerConstructor}->{Schema}{Fields};
my %fields;
unless ($params{IDField} =~ /^[+-]?\d+$/ or $fields{$params{IDField}}) {
push @{$params{LayerConstructor}->{Schema}{Fields}}, {Name => $params{IDField}, Type => 'Integer'};
}
unless ($params{ElevField} =~ /^[+-]?\d+$/ or $fields{$params{ElevField}}) {
my $type = $self->DataType() =~ /Float/ ? 'Real' : 'Integer';
push @{$params{LayerConstructor}->{Schema}{Fields}}, {Name => $params{ElevField}, Type => $type};
}
my $layer = $params{DataSource}->CreateLayer($params{LayerConstructor});
my $schema = $layer->GetLayerDefn;
for ('IDField', 'ElevField') {
$params{$_} = $schema->GetFieldIndex($params{$_}) unless $params{$_} =~ /^[+-]?\d+$/;
}
$params{ProgressData} = 1 if $params{Progress} and not defined $params{ProgressData};
ContourGenerate($self, $params{ContourInterval}, $params{ContourBase}, $params{FixedLevels},
$params{NoDataValue}, $layer, $params{IDField}, $params{ElevField},
$params{Progress}, $params{ProgressData});
return $layer;
}
sub FillNodata {
my $self = shift;
my $mask = shift;
$mask = $self->GetMaskBand unless $mask;
my @p = @_;
$p[0] = 10 unless defined $p[0];
$p[1] = 0 unless defined $p[1];
$p[2] = undef unless defined $p[2];
$p[3] = undef unless defined $p[3];
$p[4] = undef unless defined $p[1];
Geo::GDAL::FillNodata($self, $mask, @p);
}
*GetBandNumber = *GetBand;
sub ReadRaster {
my $self = shift;
my ($width, $height) = $self->Size;
my ($type) = $self->DataType;
my %d = (
XOFF => 0,
YOFF => 0,
XSIZE => $width,
YSIZE => $height,
BUFXSIZE => undef,
BUFYSIZE => undef,
BUFTYPE => $type,
BUFPIXELSPACE => 0,
BUFLINESPACE => 0,
RESAMPLEALG => 'NearestNeighbour',
PROGRESS => undef,
PROGRESSDATA => undef
);
my %p;
my $t;
if (defined $_[0]) {
$t = uc($_[0]);
$t =~ s/_//g;
}
if (@_ == 0) {
} elsif (ref($_[0]) eq 'HASH') {
%p = %{$_[0]};
} elsif (@_ % 2 == 0 and (defined $t and exists $d{$t})) {
%p = @_;
} else {
($p{xoff},$p{yoff},$p{xsize},$p{ysize},$p{buf_xsize},$p{buf_ysize},$p{buf_type},$p{buf_pixel_space},$p{buf_line_space},$p{resample_alg},$p{progress},$p{progress_data}) = @_;
}
for (keys %p) {
my $u = uc($_);
$u =~ s/_//g;
carp "Unknown named parameter '$_'." unless exists $d{$u};
$p{$u} = $p{$_};
}
for (keys %d) {
$p{$_} = $d{$_} unless defined $p{$_};
}
confess "Unknown resampling algorithm: '$p{RESAMPLEALG}'."
unless exists $Geo::GDAL::RIO_RESAMPLING_STRING2INT{$p{RESAMPLEALG}};
$p{RESAMPLEALG} = $Geo::GDAL::RIO_RESAMPLING_STRING2INT{$p{RESAMPLEALG}};
unless ($Geo::GDAL::TYPE_INT2STRING{$p{BUFTYPE}}) {
confess "Unknown data type: '$p{BUFTYPE}'."
unless exists $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
$p{BUFTYPE} = $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
}
$self->_ReadRaster($p{XOFF},$p{YOFF},$p{XSIZE},$p{YSIZE},$p{BUFXSIZE},$p{BUFYSIZE},$p{BUFTYPE},$p{BUFPIXELSPACE},$p{BUFLINESPACE},$p{RESAMPLEALG},$p{PROGRESS},$p{PROGRESSDATA});
}
sub WriteRaster {
my $self = shift;
my ($width, $height) = $self->Size;
my ($type) = $self->DataType;
my %d = (
XOFF => 0,
YOFF => 0,
XSIZE => $width,
YSIZE => $height,
BUF => undef,
BUFXSIZE => undef,
BUFYSIZE => undef,
BUFTYPE => $type,
BUFPIXELSPACE => 0,
BUFLINESPACE => 0
);
my %p;
my $t;
if (defined $_[0]) {
$t = uc($_[0]);
$t =~ s/_//g;
}
if (@_ == 0) {
} elsif (ref($_[0]) eq 'HASH') {
%p = %{$_[0]};
} elsif (@_ % 2 == 0 and (defined $t and exists $d{$t})) {
%p = @_;
} else {
($p{xoff},$p{yoff},$p{xsize},$p{ysize},$p{buf},$p{buf_xsize},$p{buf_ysize},$p{buf_type},$p{buf_pixel_space},$p{buf_line_space}) = @_;
}
for (keys %p) {
my $u = uc($_);
$u =~ s/_//g;
carp "Unknown named parameter '$_'." unless exists $d{$u};
$p{$u} = $p{$_};
}
for (keys %d) {
$p{$_} = $d{$_} unless defined $p{$_};
}
unless ($Geo::GDAL::TYPE_INT2STRING{$p{BUFTYPE}}) {
confess "Unknown data type: '$p{BUFTYPE}'."
unless exists $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
$p{BUFTYPE} = $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
}
$self->_WriteRaster($p{XOFF},$p{YOFF},$p{XSIZE},$p{YSIZE},$p{BUF},$p{BUFXSIZE},$p{BUFYSIZE},$p{BUFTYPE},$p{BUFPIXELSPACE},$p{BUFLINESPACE});
}
sub GetMaskFlags {
my $self = shift;
my $f = $self->_GetMaskFlags;
my @f;
for my $flag (keys %MASK_FLAGS) {
push @f, $flag if $f & $MASK_FLAGS{$flag};
}
return wantarray ? @f : $f;
}
sub CreateMaskBand {
my $self = shift;
my $f = 0;
if (@_ and $_[0] =~ /^\d$/) {
$f = shift;
} else {
for my $flag (@_) {
carp "Unknown mask flag: '$flag'." unless $MASK_FLAGS{$flag};
$f |= $MASK_FLAGS{$flag};
}
}
$self->_CreateMaskBand($f);
}
# GetMaskBand should be redefined and the result should be put into
# %Geo::GDAL::Dataset::BANDS
# GetOverview should be redefined and the result should be put into
# %Geo::GDAL::Dataset::BANDS
sub RegenerateOverview {
my $self = shift;
#Geo::GDAL::Band overview, scalar resampling, subref callback, scalar callback_data
my @p = @_;
Geo::GDAL::RegenerateOverview($self, @p);
}
sub RegenerateOverviews {
my $self = shift;
#arrayref overviews, scalar resampling, subref callback, scalar callback_data
my @p = @_;
Geo::GDAL::RegenerateOverviews($self, @p);
}
package Geo::GDAL::ColorTable;
use strict;
use warnings;
use Carp;
use vars qw/
%PALETTE_INTERPRETATION_STRING2INT %PALETTE_INTERPRETATION_INT2STRING
/;
for my $string (qw/Gray RGB CMYK HLS/) {
my $int = eval "\$Geo::GDAL::Constc::GPI_$string";
$PALETTE_INTERPRETATION_STRING2INT{$string} = $int;
$PALETTE_INTERPRETATION_INT2STRING{$int} = $string;
}
sub GetPaletteInterpretation {
my $self = shift;
return $PALETTE_INTERPRETATION_INT2STRING{GetPaletteInterpretation($self)};
}
sub SetColorEntry {
my $self = shift;
my $index = shift;
my $color;
if (ref($_[0]) eq 'ARRAY') {
$color = shift;
} else {
$color = [@_];
}
eval {
$self->_SetColorEntry($index, $color);
};
confess $@ if $@;
}
sub ColorEntry {
my $self = shift;
my $index = shift;
SetColorEntry($self, $index, @_) if @_ > 0;
GetColorEntry($self, $index) if defined wantarray;
}
sub ColorTable {
my $self = shift;
my @table;
if (@_) {
my $index = 0;
for my $color (@_) {
push @table, [ColorEntry($self, $index, @$color)];
$index++;
}
} else {
for (my $index = 0; $index < GetCount($self); $index++) {
push @table, [ColorEntry($self, $index)];
}
}
return @table;
}
*ColorEntries = *ColorTable;
package Geo::GDAL::RasterAttributeTable;
use strict;
use warnings;
use Carp;
use vars qw/ %BANDS
@FIELD_TYPES @FIELD_USAGES
%FIELD_TYPE_STRING2INT %FIELD_TYPE_INT2STRING
%FIELD_USAGE_STRING2INT %FIELD_USAGE_INT2STRING
/;
for (keys %Geo::GDAL::Const::) {
next if /TypeCount/;
push(@FIELD_TYPES, $1), next if /^GFT_(\w+)/;
push(@FIELD_USAGES, $1), next if /^GFU_(\w+)/;
}
for my $string (@FIELD_TYPES) {
my $int = eval "\$Geo::GDAL::Constc::GFT_$string";
$FIELD_TYPE_STRING2INT{$string} = $int;
$FIELD_TYPE_INT2STRING{$int} = $string;
}
for my $string (@FIELD_USAGES) {
my $int = eval "\$Geo::GDAL::Constc::GFU_$string";
$FIELD_USAGE_STRING2INT{$string} = $int;
$FIELD_USAGE_INT2STRING{$int} = $string;
}
sub FieldTypes {
return @FIELD_TYPES;
}
sub FieldUsages {
return @FIELD_USAGES;
}
sub RELEASE_PARENTS {
my $self = shift;
delete $BANDS{$self};
}
sub GetUsageOfCol {
my($self, $col) = @_;
$FIELD_USAGE_INT2STRING{_GetUsageOfCol($self, $col)};
}
sub GetColOfUsage {
my($self, $usage) = @_;
_GetColOfUsage($self, $FIELD_USAGE_STRING2INT{$usage});
}
sub GetTypeOfCol {
my($self, $col) = @_;
$FIELD_TYPE_INT2STRING{_GetTypeOfCol($self, $col)};
}
sub Columns {
my $self = shift;
my %columns;
if (@_) { # create columns
%columns = @_;
for my $name (keys %columns) {
$self->CreateColumn($name, $columns{$name}{Type}, $columns{$name}{Usage});
}
}
%columns = ();
for my $c (0..$self->GetColumnCount-1) {
my $name = $self->GetNameOfCol($c);
$columns{$name}{Type} = $self->GetTypeOfCol($c);
$columns{$name}{Usage} = $self->GetUsageOfCol($c);
}
return %columns;
}
sub CreateColumn {
my($self, $name, $type, $usage) = @_;
confess "Unknown RAT column type: '$type'." unless exists $FIELD_TYPE_STRING2INT{$type};
confess "Unknown RAT column usage: '$usage'." unless exists $FIELD_USAGE_STRING2INT{$usage};
for my $color (qw/Red Green Blue Alpha/) {
carp "RAT column type will be 'Integer' for usage '$color'." if $usage eq $color and $type ne 'Integer';
}
$type = $FIELD_TYPE_STRING2INT{$type};
$usage = $FIELD_USAGE_STRING2INT{$usage};
_CreateColumn($self, $name, $type, $usage);
}
sub Value {
my($self, $row, $column) = @_;
SetValueAsString($self, $row, $column, $_[3]) if defined $_[3];
return unless defined wantarray;
GetValueAsString($self, $row, $column);
}
sub LinearBinning {
my $self = shift;
SetLinearBinning($self, @_) if @_ > 0;
return unless defined wantarray;
my @a = GetLinearBinning($self);
return $a[0] ? ($a[1], $a[2]) : ();
}
package Geo::GDAL::GCP;
*swig_Pixel_get = *Geo::GDALc::GCP_Column_get;
*swig_Pixel_set = *Geo::GDALc::GCP_Column_set;
*swig_Line_get = *Geo::GDALc::GCP_Row_get;
*swig_Line_set = *Geo::GDALc::GCP_Row_set;
package Geo::GDAL::VSIF;
use strict;
use warnings;
use Carp;
sub Open {
my ($path, $mode) = @_;
my $self = Geo::GDAL::VSIFOpenL($path, $mode);
bless $self, 'Geo::GDAL::VSIF';
}
sub Write {
my ($self, $data) = @_;
Geo::GDAL::VSIFWriteL($data, $self);
}
sub Close {
my ($self, $data) = @_;
eval {
Geo::GDAL::VSIFCloseL($self);
};
if ($@) {
confess "Cannot close file: $@.";
}
}
sub Read {
my ($self, $count) = @_;
Geo::GDAL::VSIFReadL($count, $self);
}
sub Seek {
my ($self, $offset, $whence) = @_;
Geo::GDAL::VSIFSeekL($self, $offset, $whence);
}
sub Tell {
my ($self) = @_;
Geo::GDAL::VSIFTellL($self);
}
sub Truncate {
my ($self, $new_size) = @_;
eval {
Geo::GDAL::VSIFTruncateL($self, $new_size);
};
if ($@) {
confess "Cannot truncate file: $@.";
}
}
sub MkDir {
my ($path) = @_;
my $mode = 0; # unused in CPL
eval {
Geo::GDAL::Mkdir($path, $mode);
};
if ($@) {
confess "Cannot make directory \"$path\": $@.";
}
}
*Mkdir = *MkDir;
sub ReadDir {
my ($path) = @_;
Geo::GDAL::ReadDir($path);
}
sub ReadDirRecursive {
my ($path) = @_;
Geo::GDAL::ReadDirRecursive($path);
}
sub Rename {
my ($old, $new) = @_;
eval {
Geo::GDAL::Rename($old, $new);
};
if ($@) {
confess "Cannot rename file \"$old\": $@.";
}
}
sub RmDir {
my ($dirname, $recursive) = @_;
eval {
if (!$recursive) {
Geo::GDAL::Rmdir($dirname);
} else {
for my $f (ReadDir($dirname)) {
next if $f eq '..' or $f eq '.';
my @s = Stat($dirname.'/'.$f);
if ($s[0] eq 'f') {
Unlink($dirname.'/'.$f);
} elsif ($s[0] eq 'd') {
Rmdir($dirname.'/'.$f, 1);
Rmdir($dirname.'/'.$f);
}
}
RmDir($dirname);
}
};
if ($@) {
my $r = $recursive ? ' recursively' : '';
confess "Cannot remove directory \"$dirname\"$r: $@.";
}
}
*Rmdir = *RmDir;
sub Stat {
my ($path) = @_;
eval {
Geo::GDAL::Stat($path);
};
if ($@) {
confess "Cannot stat file \"$path\": $@.";
}
}
sub Unlink {
my ($filename) = @_;
eval {
Geo::GDAL::Unlink($filename);
};
if ($@) {
confess "Cannot unlink file \"$filename\": $@.";
}
}
package Geo::GDAL::GeoTransform;
use strict;
use warnings;
use Carp;
sub new {
my $class = shift;
my $self;
if (@_ == 0) {
$self = [0,1,0,0,0,1];
} elsif (@_ == 1) {
$self = $_[0];
} else {
my @a = @_;
$self = \@a;
}
bless $self, $class;
return $self;
}
sub FromGCPs {
my @GCPs;
my $ApproxOK = 1;
if (ref($_[0]) eq 'ARRAY') {
@GCPs = @{$_[0]};
$ApproxOK = $_[1] if defined $_[1];
} else {
@GCPs = @_;
$ApproxOK = pop @GCPs if !ref($GCPs[$#GCPs]);
}
my $self = Geo::GDAL::GCPsToGeoTransform(\@GCPs, $ApproxOK);
bless $self, 'Geo::GDAL::GetTransform';
return $self;
}
sub Apply {
my ($self, $columns, $rows) = @_;
my (@x, @y);
for my $i (0..$#$columns) {
($x[$i], $y[$i]) =
Geo::GDAL::ApplyGeoTransform($self, $columns->[$i], $rows->[$i]);
}
return (\@x, \@y);
}
sub Inv {
my $self = shift;
my @inv = Geo::GDAL::InvGeoTransform($self);
unless (defined wantarray) {
@$self = @inv;
} else {
return new(@inv);
}
}
1;