2 # @brief GDAL utility functions and a root class for raster classes.
3 # @details Geo::GDAL wraps many GDAL utility functions and is as a root class
4 # for all GDAL raster classes. A "raster" is an object, whose core is
5 # a rectagular grid of cells, called a "band" in GDAL. Each cell
6 # contains a numeric value of a specific data type.
10 #** @method ApplyVerticalShiftGrid()
12 sub ApplyVerticalShiftGrid {
15 #** @method BuildVRT()
18 for (keys %Geo::GDAL::Const::) {
20 push(@DATA_TYPES, $1), next if /^GDT_(\w+)/;
21 push(@OPEN_FLAGS, $1), next if /^OF_(\w+)/;
22 push(@RESAMPLING_TYPES, $1), next if /^GRA_(\w+)/;
23 push(@RIO_RESAMPLING_TYPES, $1), next if /^GRIORA_(\w+)/;
24 push(@NODE_TYPES, $1), next if /^CXT_(\w+)/;
26 for my $string (@DATA_TYPES) {
27 my $int = eval "\$Geo::GDAL::Const::GDT_$string";
28 $S2I{data_type}{$string} = $int;
29 $I2S{data_type}{$int} = $string;
31 for my $string (@OPEN_FLAGS) {
32 my $int = eval "\$Geo::GDAL::Const::OF_$string";
33 $S2I{open_flag}{$string} = $int;
35 for my $string (@RESAMPLING_TYPES) {
36 my $int = eval "\$Geo::GDAL::Const::GRA_$string";
37 $S2I{resampling}{$string} = $int;
38 $I2S{resampling}{$int} = $string;
40 for my $string (@RIO_RESAMPLING_TYPES) {
41 my $int = eval "\$Geo::GDAL::Const::GRIORA_$string";
42 $S2I{rio_resampling}{$string} = $int;
43 $I2S{rio_resampling}{$int} = $string;
45 for my $string (@NODE_TYPES) {
46 my $int = eval "\$Geo::GDAL::Const::CXT_$string";
47 $S2I{node_type}{$string} = $int;
48 $I2S{node_type}{$int} = $string;
52 $HAVE_PDL = 1 unless $@;
55 #** @method CPLBinaryToHex()
60 #** @method CPLHexToBinary()
65 #** @method CreatePansharpenedVRT()
67 sub CreatePansharpenedVRT {
70 #** @method scalar DataTypeIsComplex($DataType)
72 # @param DataType A GDAL raster cell data type (one of those listed by Geo::GDAL::DataTypes).
73 # @return true if the data type is a complex number.
75 sub DataTypeIsComplex {
76 return _DataTypeIsComplex(s2i(data_type => shift));
79 #** @method list DataTypeValueRange($DataType)
81 # @param DataType Data type (one of those listed by Geo::GDAL::DataTypes).
82 # @note Some returned values are inaccurate.
84 # @return the minimum, maximum range of the data type.
86 sub DataTypeValueRange {
89 # these values are from gdalrasterband.cpp
90 return (0,255) if $t =~ /Byte/;
91 return (0,65535) if $t =~/UInt16/;
92 return (-32768,32767) if $t =~/Int16/;
93 return (0,4294967295) if $t =~/UInt32/;
94 return (-2147483648,2147483647) if $t =~/Int32/;
95 return (-4294967295.0,4294967295.0) if $t =~/Float32/;
96 return (-4294967295.0,4294967295.0) if $t =~/Float64/;
99 #** @method list DataTypes()
100 # Package subroutine.
101 # @return a list of GDAL raster cell data types. These are currently:
102 # Byte, CFloat32, CFloat64, CInt16, CInt32, Float32, Float64, Int16, Int32, UInt16, UInt32, and Unknown.
108 #** @method scalar DecToDMS($angle, $axis, $precision=2)
109 # Package subroutine.
110 # Convert decimal degrees to degrees, minutes, and seconds string
111 # @param angle A number
112 # @param axis A string specifying latitude or longitude ('Long').
114 # @return a string nndnn'nn.nn'"L where n is a number and L is either
120 #** @method scalar DecToPackedDMS($dec)
121 # Package subroutine.
122 # @param dec Decimal degrees
123 # @return packed DMS, i.e., a number DDDMMMSSS.SS
128 #** @method DontUseExceptions()
129 # Package subroutine.
130 # Do not use the Perl exception mechanism for GDAL messages. Instead
131 # the messages are printed to standard error.
133 sub DontUseExceptions {
136 #** @method Geo::GDAL::Driver Driver($Name)
137 # Package subroutine.
138 # Access a format driver.
139 # @param Name The short name of the driver. One of
140 # Geo::GDAL::DriverNames or Geo::OGR::DriverNames.
141 # @note This subroutine is imported into the main namespace if Geo::GDAL
142 # is used with qw/:all/.
143 # @return a Geo::GDAL::Driver object.
146 return 'Geo::GDAL::Driver' unless @_;
148 my $driver = GetDriver($name);
149 error("Driver \"$name\" not found. Is it built in? Check with Geo::GDAL::Drivers or Geo::OGR::Drivers.")
154 #** @method list DriverNames()
155 # Package subroutine.
156 # Available raster format drivers.
158 # perl -MGeo::GDAL -e '@d=Geo::GDAL::DriverNames;print "@d\n"'
160 # @note Use Geo::OGR::DriverNames for vector drivers.
161 # @return a list of the short names of all available GDAL raster drivers.
166 #** @method list Drivers()
167 # Package subroutine.
168 # @note Use Geo::OGR::Drivers for vector drivers.
169 # @return a list of all available GDAL raster drivers.
173 for my $i (0..GetDriverCount()-1) {
174 my $driver = GetDriver($i);
175 push @drivers, $driver if $driver->TestCapability('RASTER');
180 #** @method EscapeString()
185 #** @method scalar FindFile($basename)
186 # Package subroutine.
187 # Search for GDAL support files.
192 # $a = Geo::GDAL::FindFile('pcs.csv');
193 # print STDERR "$a\n";
195 # Prints (for example):
197 # c:\msys\1.0\local\share\gdal\pcs.csv
200 # @param basename The name of the file to search for. For example
202 # @return the path to the searched file or undef.
212 #** @method FinderClean()
213 # Package subroutine.
214 # Clear the set of support file search paths.
219 #** @method GOA2GetAccessToken()
221 sub GOA2GetAccessToken {
224 #** @method GOA2GetAuthorizationURL()
226 sub GOA2GetAuthorizationURL {
229 #** @method GOA2GetRefreshToken()
231 sub GOA2GetRefreshToken {
234 #** @method GetActualURL()
239 #** @method scalar GetCacheMax()
240 # Package subroutine.
241 # @return maximum amount of memory (as bytes) for caching within GDAL.
246 #** @method scalar GetCacheUsed()
247 # Package subroutine.
248 # @return the amount of memory currently used for caching within GDAL.
253 #** @method scalar GetConfigOption($key)
254 # Package subroutine.
255 # @param key A GDAL config option. Consult <a
256 # href="https://trac.osgeo.org/gdal/wiki/ConfigOptions">the GDAL
257 # documentation</a> for available options and their use.
258 # @return the value of the GDAL config option.
260 sub GetConfigOption {
263 #** @method scalar GetDataTypeSize($DataType)
264 # Package subroutine.
265 # @param DataType A GDAL raster cell data type (one of those listed by Geo::GDAL::DataTypes).
266 # @return the size as the number of bits.
268 sub GetDataTypeSize {
269 return _GetDataTypeSize(s2i(data_type => shift, 1));
272 #** @method GetErrorCounter()
274 sub GetErrorCounter {
277 #** @method GetFileSystemOptions()
279 sub GetFileSystemOptions {
282 #** @method GetFileSystemsPrefixes()
284 sub GetFileSystemsPrefixes {
287 #** @method GetJPEG2000StructureAsString()
289 sub GetJPEG2000StructureAsString {
292 #** @method GetSignedURL()
297 #** @method Geo::GDAL::Driver IdentifyDriver($path, $siblings)
298 # Package subroutine.
299 # @param path a dataset path.
300 # @param siblings [optional] A list of names of files that belong to the data format.
301 # @return a Geo::GDAL::Driver.
306 #** @method IdentifyDriverEx()
308 sub IdentifyDriverEx {
311 #** @method MkdirRecursive()
316 #** @method Geo::GDAL::Dataset Open(%params)
317 # Package subroutine.
319 # An example, which opens an existing raster dataset for editing:
321 # use Geo::GDAL qw/:all/;
322 # $ds = Open(Name => 'existing.tiff', Access => 'Update');
324 # @param params Named parameters:
325 # - \a Name Dataset string (typically a filename). Default is '.'.
326 # - \a Access Access type, either 'ReadOnly' or 'Update'. Default is 'ReadOnly'.
327 # - \a Type Dataset type, either 'Raster', 'Vector', or 'Any'. Default is 'Any'.
328 # - \a Options A hash of GDAL open options passed to candidate drivers. Default is {}.
329 # - \a Files A list of names of files that are auxiliary to the main file. Default is [].
331 # @note This subroutine is imported into the main namespace if Geo::GDAL
332 # is use'd with qw/:all/.
334 # @note Some datasets / dataset strings do not explicitly imply the
335 # dataset type (for example a PostGIS database). If the type is not
336 # specified in such a case the returned dataset may be of either type.
338 # @return a new Geo::GDAL::Dataset object if success.
341 my $p = named_parameters(\@_, Name => '.', Access => 'ReadOnly', Type => 'Any', Options => {}, Files => []);
343 my %o = (READONLY => 1, UPDATE => 1);
344 error(1, $p->{access}, \%o) unless $o{uc($p->{access})};
345 push @flags, uc($p->{access});
346 %o = (RASTER => 1, VECTOR => 1, ANY => 1);
347 error(1, $p->{type}, \%o) unless $o{uc($p->{type})};
348 push @flags, uc($p->{type}) unless uc($p->{type}) eq 'ANY';
349 my $dataset = OpenEx(Name => $p->{name}, Flags => \@flags, Options => $p->{options}, Files => $p->{files});
351 my $t = "Failed to open $p->{name}.";
352 $t .= " Is it a ".lc($p->{type})." dataset?" unless uc($p->{type}) eq 'ANY';
358 #** @method Geo::GDAL::Dataset OpenEx(%params)
359 # Package subroutine.
360 # The generic dataset open method, used internally by all Open and OpenShared methods.
361 # @param params Named parameters:
362 # - \a Name The name of the data set or source to open. (Default is '.')
363 # - \a Flags A list of access mode flags. Available flags are listed by Geo::GDAL::OpenFlags(). (Default is [])
364 # - \a Drivers A list of short names of drivers that may be used. Empty list means all. (Default is [])
365 # - \a Options A hash of GDAL open options passed to candidate drivers. (Default is {})
366 # - \a Files A list of names of files that are auxiliary to the main file. (Default is [])
370 # $ds = Geo::GDAL::OpenEx(Name => 'existing.tiff', Flags => [qw/RASTER UPDATE/]);
372 # @return a new Geo::GDAL::Dataset object.
375 my $p = named_parameters(\@_, Name => '.', Flags => [], Drivers => [], Options => {}, Files => []);
377 my $name = shift // '';
379 $p = {name => $name, flags => \@flags, drivers => [], options => {}, files => []};
383 for my $flag (@{$p->{flags}}) {
384 $f |= s2i(open_flag => $flag);
388 return _OpenEx($p->{name}, $p->{flags}, $p->{drivers}, $p->{options}, $p->{files});
391 #** @method list OpenFlags()
392 # Package subroutine.
393 # @return a list of GDAL data set open modes. These are currently:
394 # ALL, GNM, RASTER, READONLY, SHARED, UPDATE, VECTOR, and VERBOSE_ERROR.
400 #** @method scalar PackCharacter($DataType)
401 # Package subroutine.
402 # Get the character that is needed for Perl's pack and unpack when
403 # they are used with Geo::GDAL::Band::ReadRaster and
404 # Geo::GDAL::Band::WriteRaster. Note that Geo::GDAL::Band::ReadTile
405 # and Geo::GDAL::Band::WriteTile have simpler interfaces that do not
406 # require pack and unpack.
407 # @param DataType A GDAL raster cell data type, typically from $band->DataType.
408 # @return a character which can be used in Perl's pack and unpack.
412 $t = i2s(data_type => $t);
413 s2i(data_type => $t); # test
414 my $is_big_endian = unpack("h*", pack("s", 1)) =~ /01/; # from Programming Perl
415 return 'C' if $t =~ /^Byte$/;
416 return ($is_big_endian ? 'n': 'v') if $t =~ /^UInt16$/;
417 return 's' if $t =~ /^Int16$/;
418 return ($is_big_endian ? 'N' : 'V') if $t =~ /^UInt32$/;
419 return 'l' if $t =~ /^Int32$/;
420 return 'f' if $t =~ /^Float32$/;
421 return 'd' if $t =~ /^Float64$/;
424 #** @method scalar PackedDMSToDec($packed)
425 # Package subroutine.
426 # @param packed DMS as a number DDDMMMSSS.SS
427 # @return decimal degrees
432 #** @method PopFinderLocation()
433 # Package subroutine.
434 # Remove the latest addition from the set of support file search
435 # paths. Note that calling this subroutine may remove paths GDAL put
438 sub PopFinderLocation {
441 #** @method PushFinderLocation($path)
442 # Package subroutine.
443 # Add a path to the set of paths from where GDAL support files are
444 # sought. Note that GDAL puts initially into the finder the current
445 # directory and value of GDAL_DATA environment variable (if it
446 # exists), installation directory (prepended with '/share/gdal' or
447 # '/Resources/gdal'), or '/usr/local/share/gdal'. It is usually only
448 # needed to add paths to the finder if using an alternate set of data
449 # files or a non-installed GDAL is used (as in testing).
451 sub PushFinderLocation {
454 #** @method list RIOResamplingTypes()
455 # Package subroutine.
456 # @return a list of GDAL raster IO resampling methods. These are currently:
457 # Average, Bilinear, Cubic, CubicSpline, Gauss, Lanczos, Mode, and NearestNeighbour.
459 sub RIOResamplingTypes {
460 return @RIO_RESAMPLING_TYPES;
463 #** @method list ResamplingTypes()
464 # Package subroutine.
465 # @return a list of GDAL resampling methods. These are currently:
466 # Average, Bilinear, Cubic, CubicSpline, Lanczos, Max, Med, Min, Mode, NearestNeighbour, Q1, and Q3.
468 sub ResamplingTypes {
469 return @RESAMPLING_TYPES;
472 #** @method RmdirRecursive()
477 #** @method SetCacheMax($Bytes)
478 # Package subroutine.
479 # @param Bytes New maximum amount of memory for caching within GDAL.
484 #** @method SetConfigOption($key, $value)
485 # Package subroutine.
486 # @param key A GDAL config option. Consult <a
487 # href="https://trac.osgeo.org/gdal/wiki/ConfigOptions">the GDAL
488 # documentation</a> for available options and their use.
489 # @param value A value for the option, typically 'YES', 'NO',
490 # undef, path, numeric value, or a filename.
492 sub SetConfigOption {
495 #** @method UseExceptions()
496 # Package subroutine.
497 # Use the Perl exception mechanism for GDAL messages (failures are
498 # confessed and warnings are warned) and collect the messages
499 # into \@Geo::GDAL::error. This is the default.
504 #** @method VSICurlClearCache()
506 sub VSICurlClearCache {
509 #** @method VSIFEofL()
514 #** @method VSIFOpenExL()
519 #** @method VSIGetLastErrorMsg()
521 sub VSIGetLastErrorMsg {
524 #** @method VSIGetLastErrorNo()
526 sub VSIGetLastErrorNo {
529 #** @method scalar VersionInfo($request = 'VERSION_NUM')
530 # Package subroutine.
531 # @param request A string specifying the request. Currently either
532 # "VERSION_NUM", "RELEASE_DATE", "RELEASE_NAME", or
533 # "--version". Default is "VERSION_NUM".
534 # @return Requested information.
539 #** @method scalar errstr()
540 # Package subroutine.
541 # Clear the error stack and return all generated GDAL error messages in one (possibly multiline) string.
542 # @return the chomped error stack joined with newlines.
548 return join("\n", @stack);
550 # usage: named_parameters(\@_, key value list of default parameters);
551 # returns parameters in a hash with low-case-without-_ keys
554 #** @class Geo::GDAL::AsyncReader
555 # @brief Enable asynchronous requests.
556 # @details This class is not yet documented nor tested in the GDAL Perl wrappers
557 # @todo Test and document.
559 package Geo::GDAL::AsyncReader;
561 use base qw(Geo::GDAL)
563 #** @method GetNextUpdatedRegion()
565 sub GetNextUpdatedRegion {
568 #** @method LockBuffer()
573 #** @method UnlockBuffer()
578 #** @class Geo::GDAL::Band
579 # @brief A raster band.
582 package Geo::GDAL::Band;
584 use base qw(Geo::GDAL::MajorObject Geo::GDAL)
588 # scalar (access as $band->{XSize})
593 # scalar (access as $band->{YSize})
596 #** @method AdviseRead()
601 #** @method Geo::GDAL::RasterAttributeTable AttributeTable($AttributeTable)
603 # @param AttributeTable [optional] A Geo::GDAL::RasterAttributeTable object.
604 # @return a new Geo::GDAL::RasterAttributeTable object, whose data is
605 # contained within the band.
609 SetDefaultRAT($self, $_[0]) if @_ and defined $_[0];
610 return unless defined wantarray;
611 my $r = GetDefaultRAT($self);
612 keep($r, $self) if $r;
615 #** @method list BlockSize()
618 # @return The size of a preferred i/o raster block size as a list
624 #** @method list CategoryNames(@names)
626 # @param names [optional]
631 SetRasterCategoryNames($self, \@_) if @_;
632 return unless defined wantarray;
633 my $n = GetRasterCategoryNames($self);
637 #** @method scalar Checksum($xoff = 0, $yoff = 0, $xsize = undef, $ysize = undef)
639 # Computes a checksum from the raster or a part of it.
644 # @return the checksum.
649 #** @method hashref ClassCounts($classifier, $progress = undef, $progress_data = undef)
651 # Compute the counts of cell values or number of cell values in ranges.
652 # @note Classifier is required only for float bands.
653 # @note NoData values are counted similar to other values when
654 # classifier is not defined for integer rasters.
656 # @param classifier Anonymous array of format [ $comparison,
657 # $classifier ], where $comparison is a string '<', '<=', '>', or '>='
658 # and $classifier is an anonymous array of format [ $value,
659 # $value|$classifier, $value|$classifier ], where $value is a numeric
660 # value against which the reclassified value is compared to. If the
661 # comparison returns true, then the second $value or $classifier is
662 # applied, and if not then the third $value or $classifier.
664 # In the example below, the line is divided into ranges
665 # [-inf..3), [3..5), and [5..inf], i.e., three ranges with class
666 # indexes 0, 1, and 2. Note that the indexes are used as keys for
667 # class counts and not the class values (here 1.0, 2.0, and 3.0),
668 # which are used in Geo::GDAL::Band::Reclassify.
670 # $classifier = [ '<', [5.0, [3.0, 1.0, 2.0], 3.0] ];
671 # # Howto create this $classifier from @class_boundaries:
672 # my $classifier = ['<='];
673 # my $tree = [$class_boundaries[0], 0, 1];
674 # for my $i (1 .. $#class_boundaries) {
675 # $tree = [$class_boundaries[$i], [@$tree], $i+1];
677 # push @$classifier, $tree;
679 # @return a reference to an anonymous hash, which contains the class
680 # values (indexes) as keys and the number of cells with that value or
681 # in that range as values. If the subroutine is user terminated an
687 #** @method scalar ColorInterpretation($color_interpretation)
689 # @note a.k.a. GetRasterColorInterpretation and GetColorInterpretation
690 # (get only and returns an integer), SetRasterColorInterpretation and
691 # SetColorInterpretation (set only and requires an integer)
692 # @param color_interpretation [optional] new color interpretation, one
693 # of Geo::GDAL::Band::ColorInterpretations.
694 # @return The color interpretation of this band. One of Geo::GDAL::Band::ColorInterpretations.
696 sub ColorInterpretation {
699 $ci = s2i(color_interpretation => $ci);
700 SetRasterColorInterpretation($self, $ci);
702 return unless defined wantarray;
703 i2s(color_interpretation => GetRasterColorInterpretation($self));
706 #** @method ColorInterpretations()
707 # Package subroutine.
708 # @return a list of types of color interpretation for raster
709 # bands. These are currently:
710 # AlphaBand, BlackBand, BlueBand, CyanBand, GrayIndex, GreenBand, HueBand, LightnessBand, MagentaBand, PaletteIndex, RedBand, SaturationBand, Undefined, YCbCr_CbBand, YCbCr_CrBand, YCbCr_YBand, and YellowBand.
712 sub ColorInterpretations {
713 return @COLOR_INTERPRETATIONS;
716 #** @method Geo::GDAL::ColorTable ColorTable($ColorTable)
718 # Get or set the color table of this band.
719 # @param ColorTable [optional] a Geo::GDAL::ColorTable object
720 # @return A new Geo::GDAL::ColorTable object which represents the
721 # internal color table associated with this band. Returns undef this
722 # band does not have an associated color table.
726 SetRasterColorTable($self, $_[0]) if @_ and defined $_[0];
727 return unless defined wantarray;
728 GetRasterColorTable($self);
731 #** @method ComputeBandStats($samplestep = 1)
733 # @param samplestep the row increment in computing the statistics.
734 # @note Returns uncorrected sample standard deviation.
736 # See also Geo::GDAL::Band::ComputeStatistics.
737 # @return a list (mean, stddev).
739 sub ComputeBandStats {
742 #** @method ComputeRasterMinMax($approx_ok = 0)
744 # @return arrayref MinMax = [min, max]
746 sub ComputeRasterMinMax {
749 #** @method list ComputeStatistics($approx_ok, $progress = undef, $progress_data = undef)
751 # @param approx_ok Whether it is allowed to compute the statistics
752 # based on overviews or similar.
753 # @note Returns uncorrected sample standard deviation.
755 # See also Geo::GDAL::Band::ComputeBandStats.
756 # @return a list ($min, $max, $mean, $stddev).
758 sub ComputeStatistics {
761 #** @method Geo::OGR::Layer Contours($DataSource, hashref LayerConstructor, $ContourInterval, $ContourBase, arrayref FixedLevels, $NoDataValue, $IDField, $ElevField, coderef Progress, $ProgressData)
763 # Generate contours for this raster band. This method can also be used with named parameters.
764 # @note This method is a wrapper for ContourGenerate.
769 # $dem = Geo::GDAL::Open('dem.gtiff');
770 # $contours = $dem->Band->Contours(ContourInterval => 10, ElevField => 'z');
771 # $n = $contours->GetFeatureCount;
774 # @param DataSource a Geo::OGR::DataSource object, default is a Memory data source
775 # @param LayerConstructor data for Geo::OGR::DataSource::CreateLayer, default is {Name => 'contours'}
776 # @param ContourInterval default is 100
777 # @param ContourBase default is 0
778 # @param FixedLevels a reference to a list of fixed contour levels, default is []
779 # @param NoDataValue default is undef
780 # @param IDField default is '', i.e., no field (the field is created if this is given)
781 # @param ElevField default is '', i.e., no field (the field is created if this is given)
782 # @param progress [optional] a reference to a subroutine, which will
783 # be called with parameters (number progress, string msg, progress_data)
784 # @param progress_data [optional]
789 my $p = named_parameters(\@_,
791 LayerConstructor => {Name => 'contours'},
792 ContourInterval => 100,
795 NoDataValue => undef,
799 ProgressData => undef);
800 $p->{datasource} //= Geo::OGR::GetDriver('Memory')->CreateDataSource('ds');
801 $p->{layerconstructor}->{Schema} //= {};
802 $p->{layerconstructor}->{Schema}{Fields} //= [];
804 unless ($p->{idfield} =~ /^[+-]?\d+$/ or $fields{$p->{idfield}}) {
805 push @{$p->{layerconstructor}->{Schema}{Fields}}, {Name => $p->{idfield}, Type => 'Integer'};
807 unless ($p->{elevfield} =~ /^[+-]?\d+$/ or $fields{$p->{elevfield}}) {
808 my $type = $self->DataType() =~ /Float/ ? 'Real' : 'Integer';
809 push @{$p->{layerconstructor}->{Schema}{Fields}}, {Name => $p->{elevfield}, Type => $type};
811 my $layer = $p->{datasource}->CreateLayer($p->{layerconstructor});
812 my $schema = $layer->GetLayerDefn;
813 for ('idfield', 'elevfield') {
814 $p->{$_} = $schema->GetFieldIndex($p->{$_}) unless $p->{$_} =~ /^[+-]?\d+$/;
816 $p->{progressdata} = 1 if $p->{progress} and not defined $p->{progressdata};
817 ContourGenerate($self, $p->{contourinterval}, $p->{contourbase}, $p->{fixedlevels},
818 $p->{nodatavalue}, $layer, $p->{idfield}, $p->{elevfield},
819 $p->{progress}, $p->{progressdata});
823 #** @method CreateMaskBand(@flags)
825 # @note May invalidate any previous mask band obtained with Geo::GDAL::Band::GetMaskBand.
827 # @param flags one or more mask flags. The flags are Geo::GDAL::Band::MaskFlags.
832 if (@_ and $_[0] =~ /^\d$/) {
836 carp "Unknown mask flag: '$flag'." unless $MASK_FLAGS{$flag};
837 $f |= $MASK_FLAGS{$flag};
840 $self->_CreateMaskBand($f);
843 #** @method scalar DataType()
845 # @return The data type of this band. One of Geo::GDAL::DataTypes.
849 return i2s(data_type => $self->{DataType});
852 #** @method Geo::GDAL::Dataset Dataset()
854 # @return The dataset which this band belongs to.
861 #** @method scalar DeleteNoDataValue()
864 sub DeleteNoDataValue {
867 #** @method Geo::GDAL::Band Distance(%params)
869 # Compute distances to specific cells of this raster.
870 # @param params Named parameters:
871 # - \a Distance A raster band, into which the distances are computed. If not given, a not given, a new in-memory raster band is created and returned. The data type of the raster can be given in the options.
872 # - \a Options Hash of options. Options are:
873 # - \a Values A list of cell values in this band to measure the distance from. If this option is not provided, the distance will be computed to non-zero pixel values. Currently pixel values are internally processed as integers.
874 # - \a DistUnits=PIXEL|GEO Indicates whether distances will be computed in cells or in georeferenced units. The default is pixel units. This also determines the interpretation of MaxDist.
875 # - \a MaxDist=n The maximum distance to search. Distances greater than this value will not be computed. Instead output cells will be set to a NoData value.
876 # - \a NoData=n The NoData value to use on the distance band for cells that are beyond MaxDist. If not provided, the distance band will be queried for a NoData value. If one is not found, 65535 will be used (255 if the type is Byte).
877 # - \a Use_Input_NoData=YES|NO If this option is set, the NoData value of this band will be respected. Leaving NoData cells in the input as NoData pixels in the distance raster.
878 # - \a Fixed_Buf_Val=n If this option is set, all cells within the MaxDist threshold are set to this value instead of the distance value.
879 # - \a DataType The data type for the result if it is not given.
880 # - \a Progress Progress function.
881 # - \a ProgressData Additional parameter for the progress function.
883 # @note This GDAL function behind this API is called GDALComputeProximity.
885 # @return The distance raster.
889 my $p = named_parameters(\@_, Distance => undef, Options => undef, Progress => undef, ProgressData => undef);
890 for my $key (keys %{$p->{options}}) {
891 $p->{options}{uc($key)} = $p->{options}{$key};
893 $p->{options}{TYPE} //= $p->{options}{DATATYPE} //= 'Float32';
894 unless ($p->{distance}) {
895 my ($w, $h) = $self->Size;
896 $p->{distance} = Geo::GDAL::Driver('MEM')->Create(Name => 'distance', Width => $w, Height => $h, Type => $p->{options}{TYPE})->Band;
898 Geo::GDAL::ComputeProximity($self, $p->{distance}, $p->{options}, $p->{progress}, $p->{progressdata});
899 return $p->{distance};
902 #** @method Domains()
908 #** @method Fill($real_part, $imag_part = 0.0)
910 # Fill the band with a constant value.
911 # @param real_part Real component of fill value.
912 # @param imag_part Imaginary component of fill value.
918 #** @method FillNoData($mask, $max_search_dist, $smoothing_iterations, $options, coderef progress, $progress_data)
920 # Interpolate values for cells in this raster. The cells to fill
921 # should be marked in the mask band with zero.
923 # @param mask [optional] a mask band indicating cells to be interpolated (zero valued) (default is to get it with Geo::GDAL::Band::GetMaskBand).
924 # @param max_search_dist [optional] the maximum number of cells to
925 # search in all directions to find values to interpolate from (default is 10).
926 # @param smoothing_iterations [optional] the number of 3x3 smoothing filter passes to run (0 or more) (default is 0).
927 # @param options [optional] A reference to a hash. No options have been defined so far for this algorithm (default is {}).
928 # @param progress [optional] a reference to a subroutine, which will
929 # be called with parameters (number progress, string msg, progress_data) (default is undef).
930 # @param progress_data [optional] (default is undef).
932 # <a href="http://www.gdal.org/gdal__alg_8h.html">Documentation for GDAL algorithms</a>
937 #** @method FlushCache()
939 # Write cached data to disk. There is usually no need to call this
945 #** @method scalar GetBandNumber()
947 # @return The index of this band in the parent dataset list of bands.
952 #** @method GetBlockSize()
957 #** @method list GetDefaultHistogram($force = 1, coderef progress = undef, $progress_data = undef)
959 # @param force true to force the computation
960 # @param progress [optional] a reference to a subroutine, which will
961 # be called with parameters (number progress, string msg, progress_data)
962 # @param progress_data [optional]
963 # @note See Note in Geo::GDAL::Band::GetHistogram.
964 # @return a list: ($min, $max, arrayref histogram).
966 sub GetDefaultHistogram {
969 #** @method list GetHistogram(%parameters)
971 # Compute histogram from the raster.
972 # @param parameters Named parameters:
973 # - \a Min the lower bound, default is -0.5
974 # - \a Max the upper bound, default is 255.5
975 # - \a Buckets the number of buckets in the histogram, default is 256
976 # - \a IncludeOutOfRange whether to use the first and last values in the returned list
977 # for out of range values, default is false;
978 # the bucket size is (Max-Min) / Buckets if this is false and
979 # (Max-Min) / (Buckets-2) if this is true
980 # - \a ApproxOK if histogram can be computed from overviews, default is false
981 # - \a Progress an optional progress function, the default is undef
982 # - \a ProgressData data for the progress function, the default is undef
983 # @note Histogram counts are treated as strings in the bindings to be
984 # able to use large integers (if GUIntBig is larger than Perl IV). In
985 # practice this is only important if you have a 32 bit machine and
986 # very large bucket counts. In those cases it may also be necessary to
988 # @return a list which contains the count of values in each bucket
992 my $p = named_parameters(\@_,
996 IncludeOutOfRange => 0,
999 ProgressData => undef);
1000 $p->{progressdata} = 1 if $p->{progress} and not defined $p->{progressdata};
1001 _GetHistogram($self, $p->{min}, $p->{max}, $p->{buckets},
1002 $p->{includeoutofrange}, $p->{approxok},
1003 $p->{progress}, $p->{progressdata});
1006 #** @method Geo::GDAL::Band GetMaskBand()
1008 # @return the mask band associated with this
1013 my $band = _GetMaskBand($self);
1017 #** @method list GetMaskFlags()
1019 # @return the mask flags of the mask band associated with this
1020 # band. The flags are one or more of Geo::GDAL::Band::MaskFlags.
1024 my $f = $self->_GetMaskFlags;
1026 for my $flag (keys %MASK_FLAGS) {
1027 push @f, $flag if $f & $MASK_FLAGS{$flag};
1029 return wantarray ? @f : $f;
1032 #** @method scalar GetMaximum()
1034 # @note Call Geo::GDAL::Band::ComputeStatistics before calling
1035 # GetMaximum to make sure the value is computed.
1037 # @return statistical minimum of the band or undef if statistics are
1038 # not kept or computed in scalar context. In list context returns the
1039 # maximum value or a (kind of) maximum value supported by the data
1040 # type and a boolean value, which indicates which is the case (true is
1041 # first, false is second).
1046 #** @method scalar GetMinimum()
1048 # @note Call Geo::GDAL::Band::ComputeStatistics before calling
1049 # GetMinimum to make sure the value is computed.
1051 # @return statistical minimum of the band or undef if statistics are
1052 # not kept or computed in scalar context. In list context returns the
1053 # minimum value or a (kind of) minimum value supported by the data
1054 # type and a boolean value, which indicates which is the case (true is
1055 # first, false is second).
1060 #** @method Geo::GDAL::Band GetOverview($index)
1062 # @param index 0..GetOverviewCount-1
1063 # @return a Geo::GDAL::Band object, which represents the internal
1064 # overview band, or undef. if the index is out of bounds.
1067 my ($self, $index) = @_;
1068 my $band = _GetOverview($self, $index);
1072 #** @method scalar GetOverviewCount()
1074 # @return the number of overviews available of the band.
1076 sub GetOverviewCount {
1079 #** @method list GetStatistics($approx_ok, $force)
1081 # @param approx_ok Whether it is allowed to compute the statistics
1082 # based on overviews or similar.
1083 # @param force Whether to force scanning of the whole raster.
1084 # @note Uses Geo::GDAL::Band::ComputeStatistics internally.
1086 # @return a list ($min, $max, $mean, $stddev).
1091 #** @method HasArbitraryOverviews()
1093 # @return true or false.
1095 sub HasArbitraryOverviews {
1098 #** @method list MaskFlags()
1099 # Package subroutine.
1100 # @return the list of mask flags. These are
1101 # - \a AllValid: There are no invalid cell, all mask values will be 255.
1102 # When used this will normally be the only flag set.
1103 # - \a PerDataset: The mask band is shared between all bands on the dataset.
1104 # - \a Alpha: The mask band is actually an alpha band and may have values
1105 # other than 0 and 255.
1106 # - \a NoData: Indicates the mask is actually being generated from NoData values.
1107 # (mutually exclusive of Alpha).
1110 my @f = sort {$MASK_FLAGS{$a} <=> $MASK_FLAGS{$b}} keys %MASK_FLAGS;
1114 #** @method scalar NoDataValue($NoDataValue)
1116 # Get or set the "no data" value.
1117 # @param NoDataValue [optional]
1118 # @note $band->NoDataValue(undef) sets the NoData value to the
1119 # Posix floating point maximum. Use Geo::GDAL::Band::DeleteNoDataValue
1120 # to stop this band using a NoData value.
1121 # @return The NoData value or undef in scalar context. An undef
1122 # value indicates that there is no NoData value associated with this
1128 if (defined $_[0]) {
1129 SetNoDataValue($self, $_[0]);
1131 SetNoDataValue($self, POSIX::FLT_MAX); # hopefully an "out of range" value
1134 GetNoDataValue($self);
1137 #** @method scalar PackCharacter()
1139 # @return The character to use in Perl pack and unpack for the data of this band.
1143 return Geo::GDAL::PackCharacter($self->DataType);
1146 #** @method Piddle($piddle, $xoff = 0, $yoff = 0, $xsize = <width>, $ysize = <height>, $xdim, $ydim)
1148 # Read or write band data from/into a piddle.
1150 # \note The PDL module must be available for this method to work. Also, you
1151 # should 'use PDL' in the code that you use this method.
1153 # @param piddle [only when writing] The piddle from which to read the data to be written into the band.
1154 # @param xoff, yoff The offset for data in the band, default is top left (0, 0).
1155 # @param xsize, ysize [optional] The size of the window in the band.
1156 # @param xdim, ydim [optional, only when reading from a band] The size of the piddle to create.
1157 # @return A new piddle when reading from a band (no not use when writing into a band).
1160 # TODO: add Piddle sub to dataset too to make Width x Height x Bands piddles
1161 error("PDL is not available.") unless $Geo::GDAL::HAVE_PDL;
1163 my $t = $self->{DataType};
1164 unless (defined wantarray) {
1166 error("The datatype of the Piddle and the band do not match.")
1167 unless $PDL2DATATYPE{$pdl->get_datatype} == $t;
1168 my ($xoff, $yoff, $xsize, $ysize) = @_;
1171 my $data = $pdl->get_dataref();
1172 my ($xdim, $ydim) = $pdl->dims();
1173 if ($xdim > $self->{XSize} - $xoff) {
1174 warn "Piddle XSize too large ($xdim) for this raster band (width = $self->{XSize}, offset = $xoff).";
1175 $xdim = $self->{XSize} - $xoff;
1177 if ($ydim > $self->{YSize} - $yoff) {
1178 $ydim = $self->{YSize} - $yoff;
1179 warn "Piddle YSize too large ($ydim) for this raster band (height = $self->{YSize}, offset = $yoff).";
1183 $self->_WriteRaster($xoff, $yoff, $xsize, $ysize, $data, $xdim, $ydim, $t, 0, 0);
1186 my ($xoff, $yoff, $xsize, $ysize, $xdim, $ydim, $alg) = @_;
1189 $xsize //= $self->{XSize} - $xoff;
1190 $ysize //= $self->{YSize} - $yoff;
1193 $alg //= 'NearestNeighbour';
1194 $alg = s2i(rio_resampling => $alg);
1195 my $buf = $self->_ReadRaster($xoff, $yoff, $xsize, $ysize, $xdim, $ydim, $t, 0, 0, $alg);
1197 my $datatype = $DATATYPE2PDL{$t};
1198 error("The band datatype is not supported by PDL.") if $datatype < 0;
1199 $pdl->set_datatype($datatype);
1200 $pdl->setdims([$xdim, $ydim]);
1201 my $data = $pdl->get_dataref();
1204 # FIXME: we want approximate equality since no data value can be very large floating point value
1205 my $bad = GetNoDataValue($self);
1206 return $pdl->setbadif($pdl == $bad) if defined $bad;
1210 #** @method Geo::OGR::Layer Polygonize(%params)
1212 # Polygonize this raster band.
1214 # @param params Named parameters:
1215 # - \a Mask A raster band, which is used as a mask to select polygonized areas. Default is undef.
1216 # - \a OutLayer A vector layer into which the polygons are written. If not given, an in-memory layer 'polygonized' is created and returned.
1217 # - \a PixValField The name of the field in the output layer into which the cell value of the polygon area is stored. Default is 'val'.
1218 # - \a Options Hash or list of options. Connectedness can be set to 8
1219 # to use 8-connectedness, otherwise 4-connectedness is
1220 # used. ForceIntPixel can be set to 1 to force using a 32 bit int buffer
1221 # for cell values in the process. If this is not set and the data type
1222 # of this raster does not fit into a 32 bit int buffer, a 32 bit float
1224 # - \a Progress Progress function.
1225 # - \a ProgressData Additional parameter for the progress function.
1227 # @return Output vector layer.
1231 my $p = named_parameters(\@_, Mask => undef, OutLayer => undef, PixValField => 'val', Options => undef, Progress => undef, ProgressData => undef);
1232 my %known_options = (Connectedness => 1, ForceIntPixel => 1, DATASET_FOR_GEOREF => 1, '8CONNECTED' => 1);
1233 for my $option (keys %{$p->{options}}) {
1234 error(1, $option, \%known_options) unless exists $known_options{$option};
1236 my $dt = $self->DataType;
1237 my %leInt32 = (Byte => 1, Int16 => 1, Int32 => 1, UInt16 => 1);
1238 my $leInt32 = $leInt32{$dt};
1239 $dt = $dt =~ /Float/ ? 'Real' : 'Integer';
1240 $p->{outlayer} //= Geo::OGR::Driver('Memory')->Create()->
1241 CreateLayer(Name => 'polygonized',
1242 Fields => [{Name => 'val', Type => $dt},
1243 {Name => 'geom', Type => 'Polygon'}]);
1244 $p->{pixvalfield} = $p->{outlayer}->GetLayerDefn->GetFieldIndex($p->{pixvalfield});
1245 $p->{options}{'8CONNECTED'} = 1 if $p->{options}{Connectedness} && $p->{options}{Connectedness} == 8;
1246 if ($leInt32 || $p->{options}{ForceIntPixel}) {
1247 Geo::GDAL::_Polygonize($self, $p->{mask}, $p->{outlayer}, $p->{pixvalfield}, $p->{options}, $p->{progress}, $p->{progressdata});
1249 Geo::GDAL::FPolygonize($self, $p->{mask}, $p->{outlayer}, $p->{pixvalfield}, $p->{options}, $p->{progress}, $p->{progressdata});
1251 set the srs of the outlayer if it was created here
1252 return $p->{outlayer};
1255 #** @method RasterAttributeTable()
1257 sub RasterAttributeTable {
1260 #** @method scalar ReadRaster(%params)
1262 # Read data from the band.
1264 # @param params Named parameters:
1265 # - \a XOff x offset (cell coordinates) (default is 0)
1266 # - \a YOff y offset (cell coordinates) (default is 0)
1267 # - \a XSize width of the area to read (default is the width of the band)
1268 # - \a YSize height of the area to read (default is the height of the band)
1269 # - \a BufXSize (default is undef, i.e., the same as XSize)
1270 # - \a BufYSize (default is undef, i.e., the same as YSize)
1271 # - \a BufType data type of the buffer (default is the data type of the band)
1272 # - \a BufPixelSpace (default is 0)
1273 # - \a BufLineSpace (default is 0)
1274 # - \a ResampleAlg one of Geo::GDAL::RIOResamplingTypes (default is 'NearestNeighbour'),
1275 # - \a Progress reference to a progress function (default is undef)
1276 # - \a ProgressData (default is undef)
1278 # <a href="http://www.gdal.org/classGDALDataset.html">Entry in GDAL docs (method RasterIO)</a>
1279 # @return a buffer, open the buffer with \a unpack function of Perl. See Geo::GDAL::Band::PackCharacter.
1283 my ($width, $height) = $self->Size;
1284 my ($type) = $self->DataType;
1285 my $p = named_parameters(\@_,
1295 ResampleAlg => 'NearestNeighbour',
1297 ProgressData => undef
1299 $p->{resamplealg} = s2i(rio_resampling => $p->{resamplealg});
1300 $p->{buftype} = s2i(data_type => $p->{buftype}, 1);
1301 $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});
1304 #** @method array reference ReadTile($xoff = 0, $yoff = 0, $xsize = <width>, $ysize = <height>)
1306 # Read band data into a Perl array.
1308 # \note Accessing band data in this way is slow. Consider using PDL and Geo::GDAL::Band::Piddle.
1310 # Usage example (print the data from a band):
1312 # print "@$_\n" for ( @{ $band->ReadTile() } );
1314 # Another usage example (process the data of a large dataset that has one band):
1316 # my($W,$H) = $dataset->Band()->Size();
1317 # my($xoff,$yoff,$w,$h) = (0,0,200,200);
1319 # if ($xoff >= $W) {
1322 # last if $yoff >= $H;
1324 # my $data = $dataset->Band(1)->ReadTile($xoff,$yoff,min($W-$xoff,$w),min($H-$yoff,$h));
1325 # # add your data processing code here
1326 # $dataset->Band(1)->WriteTile($data,$xoff,$yoff);
1331 # return $_[0] < $_[1] ? $_[0] : $_[1];
1334 # @param xoff Number of cell to skip before starting to read from a row. Pixels are read from left to right.
1335 # @param yoff Number of cells to skip before starting to read from a column. Pixels are read from top to bottom.
1336 # @param xsize Number of cells to read from each row.
1337 # @param ysize Number of cells to read from each column.
1338 # @return a two-dimensional Perl array, organizes as data->[y][x], y =
1339 # 0..height-1, x = 0..width-1. I.e., y is row and x is column.
1342 my($self, $xoff, $yoff, $xsize, $ysize, $w_tile, $h_tile, $alg) = @_;
1345 $xsize //= $self->{XSize} - $xoff;
1346 $ysize //= $self->{YSize} - $yoff;
1349 $alg //= 'NearestNeighbour';
1350 $alg = s2i(rio_resampling => $alg);
1351 my $t = $self->{DataType};
1352 my $buf = $self->_ReadRaster($xoff, $yoff, $xsize, $ysize, $w_tile, $h_tile, $t, 0, 0, $alg);
1353 my $pc = Geo::GDAL::PackCharacter($t);
1354 my $w = $w_tile * Geo::GDAL::GetDataTypeSize($t)/8;
1357 for my $y (0..$h_tile-1) {
1358 my @d = unpack($pc."[$w_tile]", substr($buf, $offset, $w));
1365 #** @method Reclassify($classifier, $progress = undef, $progress_data = undef)
1367 # Reclassify the cells in the band.
1368 # @note NoData values in integer rasters are reclassified if
1369 # explicitly specified in the hash classifier. However, they are not
1370 # reclassified to the default value, if one is specified. In real
1371 # valued rasters nodata cells are not reclassified.
1372 # @note If the subroutine is user terminated or the classifier is
1373 # incorrect, already reclassified cells will stay reclassified but an
1375 # @param classifier For integer rasters an anonymous hash, which
1376 # contains old class values as keys and new class values as values, or
1377 # an array classifier as in Geo::GDAL::Band::ClassCounts. In a hash
1378 # classifier a special key '*' (star) can be used as default, to act
1379 # as a fallback new class value. For real valued rasters the
1380 # classifier is as in Geo::GDAL::Band::ClassCounts.
1385 #** @method RegenerateOverview(Geo::GDAL::Band overview, $resampling, coderef progress, $progress_data)
1387 # @param overview a Geo::GDAL::Band object for the overview.
1388 # @param resampling [optional] the resampling method (one of Geo::GDAL::RIOResamplingTypes) (default is Average).
1389 # @param progress [optional] a reference to a subroutine, which will
1390 # be called with parameters (number progress, string msg, progress_data)
1391 # @param progress_data [optional]
1393 sub RegenerateOverview {
1395 #Geo::GDAL::Band overview, scalar resampling, subref callback, scalar callback_data
1397 Geo::GDAL::RegenerateOverview($self, @p);
1400 #** @method RegenerateOverviews(arrayref overviews, $resampling, coderef progress, $progress_data)
1402 # @todo This is not yet available
1404 # @param overviews a list of Geo::GDAL::Band objects for the overviews.
1405 # @param resampling [optional] the resampling method (one of Geo::GDAL::RIOResamplingTypes) (default is Average).
1406 # @param progress [optional] a reference to a subroutine, which will
1407 # be called with parameters (number progress, string msg, progress_data)
1408 # @param progress_data [optional]
1410 sub RegenerateOverviews {
1412 #arrayref overviews, scalar resampling, subref callback, scalar callback_data
1414 Geo::GDAL::RegenerateOverviews($self, @p);
1417 #** @method ScaleAndOffset($scale, $offset)
1419 # Scale and offset are used to transform raw cell values into the
1420 # units returned by GetUnits(). The conversion function is:
1422 # Units value = (raw value * scale) + offset
1424 # @return a list ($scale, $offset), the values are undefined if they
1426 # @since version 1.9 of the bindings.
1428 sub ScaleAndOffset {
1430 SetScale($self, $_[0]) if @_ > 0 and defined $_[0];
1431 SetOffset($self, $_[1]) if @_ > 1 and defined $_[1];
1432 return unless defined wantarray;
1433 my $scale = GetScale($self);
1434 my $offset = GetOffset($self);
1435 return ($scale, $offset);
1438 #** @method list SetDefaultHistogram($min, $max, $histogram)
1442 # @note See Note in Geo::GDAL::Band::GetHistogram.
1443 # @param histogram reference to an array containing the histogram
1445 sub SetDefaultHistogram {
1448 #** @method SetStatistics($min, $max, $mean, $stddev)
1450 # Save the statistics of the band if possible (the format can save
1451 # arbitrary metadata).
1460 #** @method Geo::GDAL::Band Sieve(%params)
1462 # Remove small areas by merging them into the largest neighbour area.
1463 # @param params Named parameters:
1464 # - \a Mask A raster band, which is used as a mask to select sieved areas. Default is undef.
1465 # - \a Dest A raster band into which the result is written. If not given, an new in-memory raster band is created and returned.
1466 # - \a Threshold The smallest area size (in number of cells) which are not sieved away.
1467 # - \a Options Hash or list of options. {Connectedness => 4} can be specified to use 4-connectedness, otherwise 8-connectedness is used.
1468 # - \a Progress Progress function.
1469 # - \a ProgressData Additional parameter for the progress function.
1471 # @return The filtered raster band.
1475 my $p = named_parameters(\@_, Mask => undef, Dest => undef, Threshold => 10, Options => undef, Progress => undef, ProgressData => undef);
1476 unless ($p->{dest}) {
1477 my ($w, $h) = $self->Size;
1478 $p->{dest} = Geo::GDAL::Driver('MEM')->Create(Name => 'sieved', Width => $w, Height => $h, Type => $self->DataType)->Band;
1481 if ($p->{options}{Connectedness}) {
1482 $c = $p->{options}{Connectedness};
1483 delete $p->{options}{Connectedness};
1485 Geo::GDAL::SieveFilter($self, $p->{mask}, $p->{dest}, $p->{threshold}, $c, $p->{options}, $p->{progress}, $p->{progressdata});
1489 #** @method list Size()
1491 # @return The size of the band as a list (width, height).
1495 return ($self->{XSize}, $self->{YSize});
1498 #** @method Unit($type)
1500 # @param type [optional] the unit (a string).
1501 # @note $band->Unit(undef) sets the unit value to an empty string.
1502 # @return the unit (a string).
1503 # @since version 1.9 of the bindings.
1510 SetUnitType($self, $unit);
1512 return unless defined wantarray;
1516 #** @method WriteRaster(%params)
1518 # Write data into the band.
1520 # @param params Named parameters:
1521 # - \a XOff x offset (cell coordinates) (default is 0)
1522 # - \a YOff y offset (cell coordinates) (default is 0)
1523 # - \a XSize width of the area to write (default is the width of the band)
1524 # - \a YSize height of the area to write (default is the height of the band)
1525 # - \a Buf a buffer (or a reference to a buffer) containing the data. Create the buffer with \a pack function of Perl. See Geo::GDAL::Band::PackCharacter.
1526 # - \a BufXSize (default is undef, i.e., the same as XSize)
1527 # - \a BufYSize (default is undef, i.e., the same as YSize)
1528 # - \a BufType data type of the buffer (default is the data type of the band)
1529 # - \a BufPixelSpace (default is 0)
1530 # - \a BufLineSpace (default is 0)
1532 # <a href="http://www.gdal.org/classGDALDataset.html">Entry in GDAL docs (method RasterIO)</a>
1536 my ($width, $height) = $self->Size;
1537 my ($type) = $self->DataType;
1538 my $p = named_parameters(\@_,
1550 confess "Usage: \$band->WriteRaster( Buf => \$data, ... )" unless defined $p->{buf};
1551 $p->{buftype} = s2i(data_type => $p->{buftype}, 1);
1552 $self->_WriteRaster($p->{xoff},$p->{yoff},$p->{xsize},$p->{ysize},$p->{buf},$p->{bufxsize},$p->{bufysize},$p->{buftype},$p->{bufpixelspace},$p->{buflinespace});
1555 #** @method WriteTile($data, $xoff = 0, $yoff = 0)
1557 # Write band data from a Perl array.
1559 # \note Accessing band data in this way is slow. Consider using PDL and Geo::GDAL::Band::Piddle.
1561 # @param data A two-dimensional Perl array, organizes as data->[y][x], y =
1562 # 0..height-1, x = 0..width-1.
1568 my($self, $data, $xoff, $yoff) = @_;
1571 error('The data must be in a two-dimensional array') unless ref $data eq 'ARRAY' && ref $data->[0] eq 'ARRAY';
1572 my $xsize = @{$data->[0]};
1573 if ($xsize > $self->{XSize} - $xoff) {
1574 warn "Buffer XSize too large ($xsize) for this raster band (width = $self->{XSize}, offset = $xoff).";
1575 $xsize = $self->{XSize} - $xoff;
1577 my $ysize = @{$data};
1578 if ($ysize > $self->{YSize} - $yoff) {
1579 $ysize = $self->{YSize} - $yoff;
1580 warn "Buffer YSize too large ($ysize) for this raster band (height = $self->{YSize}, offset = $yoff).";
1582 my $pc = Geo::GDAL::PackCharacter($self->{DataType});
1583 for my $i (0..$ysize-1) {
1584 my $scanline = pack($pc."[$xsize]", @{$data->[$i]});
1585 $self->WriteRaster( $xoff, $yoff+$i, $xsize, 1, $scanline );
1589 #** @class Geo::GDAL::ColorTable
1590 # @brief A color table from a raster band or a color table, which can be used for a band.
1593 package Geo::GDAL::ColorTable;
1595 use base qw(Geo::GDAL)
1597 #** @method Geo::GDAL::ColorTable Clone()
1599 # Clone an existing color table.
1600 # @return a new Geo::GDAL::ColorTable object
1605 #** @method list Color($index, @color)
1607 # Get or set a color in this color table.
1608 # @param index The index of the color in the table. Note that the
1609 # color table may expand if the index is larger than the current max
1610 # index of this table and a color is given. An attempt to retrieve a
1611 # color out of the current size of the table causes an error.
1612 # @param color [optional] The color, either a list or a reference to a
1613 # list. If the list is too short or has undef values, the undef values
1614 # are taken as 0 except for alpha, which is taken as 255.
1615 # @note A color is an array of four integers having a value between 0
1616 # and 255: (gray, red, cyan or hue; green, magenta, or lightness;
1617 # blue, yellow, or saturation; alpha or blackband)
1618 # @return A color, in list context a list and in scalar context a reference to an anonymous array.
1623 #** @method list Colors(@colors)
1625 # Get or set the colors in this color table.
1626 # @note The color table will expand to the size of the input list but
1627 # it will not shrink.
1628 # @param colors [optional] A list of all colors (a list of lists) for this color table.
1629 # @return A list of colors (a list of lists).
1634 #** @method CreateColorRamp($start_index, arrayref start_color, $end_index, arrayref end_color)
1636 # @param start_index
1637 # @param start_color
1641 sub CreateColorRamp {
1644 #** @method scalar GetCount()
1646 # @return The number of colors in this color table.
1651 #** @method scalar GetPaletteInterpretation()
1653 # @return palette interpretation (string)
1655 sub GetPaletteInterpretation {
1657 return i2s(palette_interpretation => GetPaletteInterpretation($self));
1660 #** @method Geo::GDAL::ColorTable new($GDALPaletteInterp = 'RGB')
1662 # Create a new empty color table.
1663 # @return a new Geo::GDAL::ColorTable object
1668 $pi = s2i(palette_interpretation => $pi);
1669 my $self = Geo::GDALc::new_ColorTable($pi);
1670 bless $self, $pkg if defined($self);
1673 #** @class Geo::GDAL::Dataset
1674 # @brief A set of associated raster bands or vector layer source.
1677 package Geo::GDAL::Dataset;
1679 use base qw(Geo::GDAL::MajorObject Geo::GDAL)
1681 #** @attr $RasterCount
1682 # scalar (access as $dataset->{RasterCount})
1685 #** @attr $RasterXSize
1686 # scalar (access as $dataset->{RasterXSize})
1689 #** @attr $RasterYSize
1690 # scalar (access as $dataset->{RasterYSize})
1693 #** @method AddBand($datatype = 'Byte', hashref options = {})
1695 # Add a new band to the dataset. The driver must support the action.
1696 # @param datatype GDAL raster cell data type (one of those listed by Geo::GDAL::DataTypes).
1697 # @param options reference to a hash of format specific options.
1698 # @return The added band.
1701 my ($self, $type, $options) = @_;
1703 $type = s2i(data_type => $type);
1704 $self->_AddBand($type, $options);
1705 return unless defined wantarray;
1706 return $self->GetRasterBand($self->{RasterCount});
1709 #** @method AdviseRead()
1714 #** @method Geo::GDAL::Band Band($index)
1716 # Create a band object for the band within the dataset.
1717 # @note a.k.a. GetRasterBand
1718 # @param index 1...RasterCount, default is 1.
1719 # @return a new Geo::GDAL::Band object
1724 #** @method list Bands()
1726 # @return a list of new Geo::GDAL::Band objects
1731 for my $i (1..$self->{RasterCount}) {
1732 push @bands, GetRasterBand($self, $i);
1737 #** @method BuildOverviews($resampling, arrayref overviews, coderef progress, $progress_data)
1739 # @param resampling the resampling method, one of Geo::GDAL::RIOResamplingTypes.
1740 # @param overviews The list of overview decimation factors to
1741 # build. For example [2,4,8].
1742 # @param progress [optional] a reference to a subroutine, which will
1743 # be called with parameters (number progress, string msg, progress_data)
1744 # @param progress_data [optional]
1746 sub BuildOverviews {
1749 $p[0] = uc($p[0]) if $p[0];
1751 $self->_BuildOverviews(@p);
1753 confess(last_error()) if $@;
1756 #** @method Geo::GDAL::Dataset BuildVRT($Dest, arrayref Sources, hashref Options, coderef progress, $progress_data)
1758 # Build a virtual dataset from a set of datasets.
1759 # @param Dest Destination raster dataset definition string (typically
1760 # filename), or an object, which implements write and close.
1761 # @param Sources A list of filenames of input datasets or a list of
1763 # @param Options See section \ref index_processing_options.
1764 # @return Dataset object
1766 # @note This subroutine is imported into the main namespace if Geo::GDAL
1767 # is use'd with qw/:all/.
1770 my ($dest, $sources, $options, $progress, $progress_data) = @_;
1771 $options = Geo::GDAL::GDALBuildVRTOptions->new(make_processing_options($options));
1772 error("Usage: Geo::GDAL::DataSet::BuildVRT(\$vrt_file_name, \\\@sources)")
1773 unless ref $sources eq 'ARRAY' && defined $sources->[0];
1774 unless (blessed($dest)) {
1775 if (blessed($sources->[0])) {
1776 return Geo::GDAL::wrapper_GDALBuildVRT_objects($dest, $sources, $options, $progress, $progress_data);
1778 return Geo::GDAL::wrapper_GDALBuildVRT_names($dest, $sources, $options, $progress, $progress_data);
1781 if (blessed($sources->[0])) {
1782 return stdout_redirection_wrapper(
1784 \&Geo::GDAL::wrapper_GDALBuildVRT_objects,
1785 $options, $progress, $progress_data);
1787 return stdout_redirection_wrapper(
1789 \&Geo::GDAL::wrapper_GDALBuildVRT_names,
1790 $options, $progress, $progress_data);
1795 #** @method CommitTransaction()
1797 sub CommitTransaction {
1800 #** @method Geo::GDAL::ColorTable ComputeColorTable(%params)
1802 # Compute a color table from an RGB image
1803 # @param params Named parameters:
1804 # - \a Red The red band, the default is to use the red band of this dataset.
1805 # - \a Green The green band, the default is to use the green band of this dataset.
1806 # - \a Blue The blue band, the default is to use the blue band of this dataset.
1807 # - \a NumColors The number of colors in the computed color table. Default is 256.
1808 # - \a Progress reference to a progress function (default is undef)
1809 # - \a ProgressData (default is undef)
1810 # - \a Method The computation method. The default and currently only option is the median cut algorithm.
1812 # @return a new color table object.
1814 sub ComputeColorTable {
1816 my $p = named_parameters(\@_,
1822 ProgressData => undef,
1823 Method => 'MedianCut');
1824 for my $b ($self->Bands) {
1825 for my $cion ($b->ColorInterpretation) {
1826 if ($cion eq 'RedBand') { $p->{red} //= $b; last; }
1827 if ($cion eq 'GreenBand') { $p->{green} //= $b; last; }
1828 if ($cion eq 'BlueBand') { $p->{blue} //= $b; last; }
1831 my $ct = Geo::GDAL::ColorTable->new;
1832 Geo::GDAL::ComputeMedianCutPCT($p->{red},
1836 $ct, $p->{progress},
1837 $p->{progressdata});
1841 #** @method Geo::OGR::Layer CopyLayer($layer, $name, hashref options = undef)
1843 # @param layer A Geo::OGR::Layer object to be copied.
1844 # @param name A name for the new layer.
1845 # @param options A ref to a hash of format specific options.
1846 # @return a new Geo::OGR::Layer object.
1851 #** @method Geo::OGR::Layer CreateLayer(%params)
1853 # @brief Create a new vector layer into this dataset.
1855 # @param %params Named parameters:
1856 # - \a Name (scalar) name for the new layer.
1857 # - \a Fields (array reference) a list of (scalar and geometry) field definitions as in
1858 # Geo::OGR::Layer::CreateField.
1859 # - \a ApproxOK (boolean value, default is true) a flag, which is forwarded to Geo::OGR::Layer::CreateField.
1860 # - \a Options (hash reference) driver specific hash of layer creation options.
1861 # - \a Schema (hash reference, deprecated, use \a Fields and \a Name) may contain keys Name, Fields, GeomFields, GeometryType.
1862 # - \a SRS (scalar) the spatial reference for the default geometry field.
1863 # - \a GeometryType (scalar) the type of the default geometry field
1864 # (if only one geometry field). Default is 'Unknown'.
1866 # @note If Fields or Schema|Fields is not given, a default geometry
1867 # field (Name => '', GeometryType => 'Unknown') is created. If it is
1868 # given and it contains spatial fields, both GeometryType and SRS are
1869 # ignored. The type can be also set with the named parameter.
1873 # my $roads = Geo::OGR::Driver('Memory')->Create('road')->
1875 # Fields => [ { Name => 'class',
1876 # Type => 'Integer' },
1878 # Type => 'LineString25D' } ] );
1881 # @note Many formats allow only one spatial field, which currently
1882 # requires the use of GeometryType.
1884 # @return a new Geo::OGR::Layer object.
1888 my $p = named_parameters(\@_,
1891 GeometryType => 'Unknown',
1896 error("The 'Fields' argument must be an array reference.") if $p->{fields} && ref($p->{fields}) ne 'ARRAY';
1897 if (defined $p->{schema}) {
1898 my $s = $p->{schema};
1899 $p->{geometrytype} = $s->{GeometryType} if exists $s->{GeometryType};
1900 $p->{fields} = $s->{Fields} if exists $s->{Fields};
1901 $p->{name} = $s->{Name} if exists $s->{Name};
1903 $p->{fields} = [] unless ref($p->{fields}) eq 'ARRAY';
1904 # if fields contains spatial fields, then do not create default one
1905 for my $f (@{$p->{fields}}) {
1906 error("Field definitions must be hash references.") unless ref $f eq 'HASH';
1907 if ($f->{GeometryType} || ($f->{Type} && s_exists(geometry_type => $f->{Type}))) {
1908 $p->{geometrytype} = 'None';
1912 my $gt = s2i(geometry_type => $p->{geometrytype});
1913 my $layer = _CreateLayer($self, $p->{name}, $p->{srs}, $gt, $p->{options});
1914 for my $f (@{$p->{fields}}) {
1915 $layer->CreateField($f);
1917 keep($layer, $self);
1920 #** @method CreateMaskBand()
1922 # Add a mask band to the dataset.
1924 sub CreateMaskBand {
1925 return _CreateMaskBand(@_);
1928 #** @method Geo::GDAL::Dataset DEMProcessing($Dest, $Processing, $ColorFilename, hashref Options, coderef progress, $progress_data)
1930 # Apply a DEM processing to this dataset.
1931 # @param Dest Destination raster dataset definition string (typically filename) or an object, which implements write and close.
1932 # @param Processing Processing to apply, one of "hillshade", "slope", "aspect", "color-relief", "TRI", "TPI", or "Roughness".
1933 # @param ColorFilename The color palette for color-relief.
1934 # @param Options See section \ref index_processing_options.
1935 # @param progress [optional] A reference to a subroutine, which will
1936 # be called with parameters (number progress, string msg, progress_data).
1937 # @param progress_data [optional]
1941 my ($self, $dest, $Processing, $ColorFilename, $options, $progress, $progress_data) = @_;
1942 $options = Geo::GDAL::GDALDEMProcessingOptions->new(make_processing_options($options));
1943 return $self->stdout_redirection_wrapper(
1945 \&Geo::GDAL::wrapper_GDALDEMProcessing,
1946 $Processing, $ColorFilename, $options, $progress, $progress_data
1950 #** @method Dataset()
1957 #** @method DeleteLayer($name)
1959 # Deletes a layer from the data source. Note that if there is a layer
1960 # object for the deleted layer, it becomes unusable.
1961 # @param name name of the layer to delete.
1964 my ($self, $name) = @_;
1966 for my $i (0..$self->GetLayerCount-1) {
1967 my $layer = GetLayerByIndex($self, $i);
1968 $index = $i, last if $layer->GetName eq $name;
1970 error(2, $name, 'Layer') unless defined $index;
1971 _DeleteLayer($self, $index);
1974 #** @method Geo::GDAL::Band Dither(%params)
1976 # Compute one band with color table image from an RGB image
1977 # @params params Named parameters:
1978 # - \a Red The red band, the default is to use the red band of this dataset.
1979 # - \a Green The green band, the default is to use the green band of this dataset.
1980 # - \a Blue The blue band, the default is to use the blue band of this dataset.
1981 # - \a Dest The destination band. If this is not defined, a new in-memory band (and a dataset) will be created.
1982 # - \a ColorTable The color table for the result. If this is not defined, and the destination band does not contain one, it will be computed with the ComputeColorTable method.
1983 # - \a Progress Reference to a progress function (default is undef). Note that if ColorTable is computed using ComputeColorTable method, the progress will run twice from 0 to 1.
1984 # - \a ProgressData (default is undef)
1986 # @return the destination band.
1988 # Usage example. This code converts an RGB JPEG image into a one band PNG image with a color table.
1990 # my $d = Geo::GDAL::Open('pic.jpg');
1991 # Geo::GDAL::Driver('PNG')->Copy(Name => 'test.png', Src => $d->Dither->Dataset);
1996 my $p = named_parameters(\@_,
2001 ColorTable => undef,
2003 ProgressData => undef);
2004 for my $b ($self->Bands) {
2005 for my $cion ($b->ColorInterpretation) {
2006 if ($cion eq 'RedBand') { $p->{red} //= $b; last; }
2007 if ($cion eq 'GreenBand') { $p->{green} //= $b; last; }
2008 if ($cion eq 'BlueBand') { $p->{blue} //= $b; last; }
2011 my ($w, $h) = $self->Size;
2012 $p->{dest} //= Geo::GDAL::Driver('MEM')->Create(Name => 'dithered',
2015 Type => 'Byte')->Band;
2017 //= $p->{dest}->ColorTable
2018 // $self->ComputeColorTable(Red => $p->{red},
2019 Green => $p->{green},
2021 Progress => $p->{progress},
2022 ProgressData => $p->{progressdata});
2023 Geo::GDAL::DitherRGB2PCT($p->{red},
2029 $p->{progressdata});
2030 $p->{dest}->ColorTable($p->{colortable});
2034 #** @method Domains()
2040 #** @method Geo::GDAL::Driver Driver()
2042 # @note a.k.a. GetDriver
2043 # @return a Geo::GDAL::Driver object that was used to open or create this dataset.
2048 #** @method Geo::OGR::Layer ExecuteSQL($statement, $geom = undef, $dialect = "")
2050 # @param statement A SQL statement.
2051 # @param geom A Geo::OGR::Geometry object.
2053 # @return a new Geo::OGR::Layer object. The data source object will
2054 # exist as long as the layer object exists.
2058 my $layer = $self->_ExecuteSQL(@_);
2059 note($layer, "is result set");
2060 keep($layer, $self);
2063 #** @method Geo::GDAL::Extent Extent(@params)
2065 # @param params nothing, or a list ($xoff, $yoff, $w, $h)
2066 # @return A new Geo::GDAL::Extent object that represents the area that
2067 # this raster or the specified tile covers.
2071 my $t = $self->GeoTransform;
2072 my $extent = $t->Extent($self->Size);
2074 my ($xoff, $yoff, $w, $h) = @_;
2075 my ($x, $y) = $t->Apply([$xoff, $xoff+$w, $xoff+$w, $xoff], [$yoff, $yoff, $yoff+$h, $yoff+$h]);
2076 my $xmin = shift @$x;
2079 $xmin = $x if $x < $xmin;
2080 $xmax = $x if $x > $xmax;
2082 my $ymin = shift @$y;
2085 $ymin = $y if $y < $ymin;
2086 $ymax = $y if $y > $ymax;
2088 $extent = Geo::GDAL::Extent->new($xmin, $ymin, $xmax, $ymax);
2093 #** @method list GCPs(@GCPs, Geo::OSR::SpatialReference sr)
2095 # Get or set the GCPs and their projection.
2096 # @param GCPs [optional] a list of Geo::GDAL::GCP objects
2097 # @param sr [optional] the projection of the GCPs.
2098 # @return a list of Geo::GDAL::GCP objects followed by a Geo::OSR::SpatialReference object.
2104 $proj = $proj->Export('WKT') if $proj and ref($proj);
2105 SetGCPs($self, \@_, $proj);
2107 return unless defined wantarray;
2108 my $proj = Geo::OSR::SpatialReference->new(GetGCPProjection($self));
2109 my $GCPs = GetGCPs($self);
2110 return (@$GCPs, $proj);
2113 #** @method Geo::GDAL::GeoTransform GeoTransform(Geo::GDAL::GeoTransform $geo_transform)
2115 # Transformation from cell coordinates (column,row) to projection
2118 # x = geo_transform[0] + column*geo_transform[1] + row*geo_transform[2]
2119 # y = geo_transform[3] + column*geo_transform[4] + row*geo_transform[5]
2121 # @param geo_transform [optional]
2122 # @return the geo transform in a non-void context.
2128 SetGeoTransform($self, $_[0]);
2130 SetGeoTransform($self, \@_);
2133 confess(last_error()) if $@;
2134 return unless defined wantarray;
2135 my $t = GetGeoTransform($self);
2139 return Geo::GDAL::GeoTransform->new($t);
2143 #** @method GetDriver()
2148 #** @method list GetFileList()
2150 # @return list of files GDAL believes to be part of this dataset.
2155 #** @method scalar GetGCPProjection()
2157 # @return projection string.
2159 sub GetGCPProjection {
2162 #** @method Geo::OGR::Layer GetLayer($name)
2164 # @param name the name of the requested layer. If not given, then
2165 # returns the first layer in the data source.
2166 # @return a new Geo::OGR::Layer object that represents the layer
2167 # in the data source.
2170 my($self, $name) = @_;
2171 my $layer = defined $name ? GetLayerByName($self, "$name") : GetLayerByIndex($self, 0);
2173 error(2, $name, 'Layer') unless $layer;
2174 keep($layer, $self);
2177 #** @method list GetLayerNames()
2179 # @note Delivers the functionality of undocumented method GetLayerCount.
2180 # @return a list of the names of the layers this data source provides.
2185 for my $i (0..$self->GetLayerCount-1) {
2186 my $layer = GetLayerByIndex($self, $i);
2187 push @names, $layer->GetName;
2192 #** @method GetNextFeature()
2194 sub GetNextFeature {
2197 #** @method GetStyleTable()
2202 #** @method Geo::GDAL::Dataset Grid($Dest, hashref Options)
2204 # Creates a regular raster grid from this data source.
2205 # This is equivalent to the gdal_grid utility.
2206 # @param Dest Destination raster dataset definition string (typically
2207 # filename) or an object, which implements write and close.
2208 # @param Options See section \ref index_processing_options.
2211 my ($self, $dest, $options, $progress, $progress_data) = @_;
2212 $options = Geo::GDAL::GDALGridOptions->new(make_processing_options($options));
2213 return $self->stdout_redirection_wrapper(
2215 \&Geo::GDAL::wrapper_GDALGrid,
2216 $options, $progress, $progress_data
2220 #** @method scalar Info(hashref Options)
2222 # Information about this dataset.
2223 # @param Options See section \ref index_processing_options.
2226 my ($self, $o) = @_;
2227 $o = Geo::GDAL::GDALInfoOptions->new(make_processing_options($o));
2228 return GDALInfo($self, $o);
2231 #** @method Geo::GDAL::Dataset Nearblack($Dest, hashref Options, coderef progress, $progress_data)
2233 # Convert nearly black/white pixels to black/white.
2234 # @param Dest Destination raster dataset definition string (typically
2235 # filename), destination dataset to which to add an alpha or mask
2236 # band, or an object, which implements write and close.
2237 # @param Options See section \ref index_processing_options.
2238 # @return Dataset if destination dataset definition string was given,
2239 # otherwise a boolean for success/fail but the method croaks if there
2243 my ($self, $dest, $options, $progress, $progress_data) = @_;
2244 $options = Geo::GDAL::GDALNearblackOptions->new(make_processing_options($options));
2245 my $b = blessed($dest);
2246 if ($b && $b eq 'Geo::GDAL::Dataset') {
2247 Geo::GDAL::wrapper_GDALNearblackDestDS($dest, $self, $options, $progress, $progress_data);
2249 return $self->stdout_redirection_wrapper(
2251 \&Geo::GDAL::wrapper_GDALNearblackDestName,
2252 $options, $progress, $progress_data
2257 #** @method Geo::GDAL::Dataset Open()
2258 # Package subroutine.
2259 # The same as Geo::GDAL::Open
2264 #** @method Geo::GDAL::Dataset OpenShared()
2265 # Package subroutine.
2266 # The same as Geo::GDAL::OpenShared
2271 #** @method Geo::GDAL::Dataset Rasterize($Dest, hashref Options, coderef progress, $progress_data)
2273 # Render data from this data source into a raster.
2274 # @param Dest Destination raster dataset definition string (typically
2275 # filename), destination dataset, or an object, which implements write and close.
2276 # @param Options See section \ref index_processing_options.
2277 # @return Dataset if destination dataset definition string was given,
2278 # otherwise a boolean for success/fail but the method croaks if there
2283 my ($self, $dest, $options, $progress, $progress_data) = @_;
2284 $options = Geo::GDAL::GDALRasterizeOptions->new(make_processing_options($options));
2285 my $b = blessed($dest);
2286 if ($b && $b eq 'Geo::GDAL::Dataset') {
2287 Geo::GDAL::wrapper_GDALRasterizeDestDS($dest, $self, $options, $progress, $progress_data);
2289 # TODO: options need to force a new raster be made, otherwise segfault
2290 return $self->stdout_redirection_wrapper(
2292 \&Geo::GDAL::wrapper_GDALRasterizeDestName,
2293 $options, $progress, $progress_data
2298 #** @method scalar ReadRaster(%params)
2300 # Read data from the dataset.
2302 # @param params Named parameters:
2303 # - \a XOff x offset (cell coordinates) (default is 0)
2304 # - \a YOff y offset (cell coordinates) (default is 0)
2305 # - \a XSize width of the area to read (default is the width of the dataset)
2306 # - \a YSize height of the area to read (default is the height of the dataset)
2307 # - \a BufXSize (default is undef, i.e., the same as XSize)
2308 # - \a BufYSize (default is undef, i.e., the same as YSize)
2309 # - \a BufType data type of the buffer (default is the data type of the first band)
2310 # - \a BandList a reference to an array of band indices (default is [1])
2311 # - \a BufPixelSpace (default is 0)
2312 # - \a BufLineSpace (default is 0)
2313 # - \a BufBandSpace (default is 0)
2314 # - \a ResampleAlg one of Geo::GDAL::RIOResamplingTypes (default is 'NearestNeighbour'),
2315 # - \a Progress reference to a progress function (default is undef)
2316 # - \a ProgressData (default is undef)
2318 # <a href="http://www.gdal.org/classGDALDataset.html">Entry in GDAL docs (method RasterIO)</a>
2319 # @return a buffer, open the buffer with \a unpack function of Perl. See Geo::GDAL::Band::PackCharacter.
2323 my ($width, $height) = $self->Size;
2324 my ($type) = $self->Band->DataType;
2325 my $p = named_parameters(\@_,
2337 ResampleAlg => 'NearestNeighbour',
2339 ProgressData => undef
2341 $p->{resamplealg} = s2i(rio_resampling => $p->{resamplealg});
2342 $p->{buftype} = s2i(data_type => $p->{buftype}, 1);
2343 $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});
2346 #** @method ReadTile()
2349 my ($self, $xoff, $yoff, $xsize, $ysize, $w_tile, $h_tile, $alg) = @_;
2351 for my $i (0..$self->Bands-1) {
2352 $data[$i] = $self->Band($i+1)->ReadTile($xoff, $yoff, $xsize, $ysize, $w_tile, $h_tile, $alg);
2357 #** @method ReleaseResultSet($layer)
2359 # @param layer A layer the has been created with ExecuteSQL.
2360 # @note There is no need to call this method. The result set layer is
2361 # released in the destructor of the layer that was created with SQL.
2363 sub ReleaseResultSet {
2364 # a no-op, _ReleaseResultSet is called from Layer::DESTROY
2367 #** @method ResetReading()
2372 #** @method RollbackTransaction()
2374 sub RollbackTransaction {
2377 #** @method SetStyleTable()
2382 #** @method list Size()
2384 # @return (width, height)
2388 return ($self->{RasterXSize}, $self->{RasterYSize});
2391 #** @method Geo::OSR::SpatialReference SpatialReference(Geo::OSR::SpatialReference sr)
2393 # Get or set the projection of this dataset.
2394 # @param sr [optional] a Geo::OSR::SpatialReference object,
2395 # which replaces the existing projection definition of this dataset.
2396 # @return a Geo::OSR::SpatialReference object, which represents the
2397 # projection of this dataset.
2398 # @note Methods GetProjection, SetProjection, and Projection return WKT strings.
2400 sub SpatialReference {
2401 my($self, $sr) = @_;
2402 SetProjection($self, $sr->As('WKT')) if defined $sr;
2403 if (defined wantarray) {
2404 my $p = GetProjection($self);
2406 return Geo::OSR::SpatialReference->new(WKT => $p);
2410 #** @method StartTransaction()
2412 sub StartTransaction {
2415 #** @method TestCapability()
2417 sub TestCapability {
2418 return _TestCapability(@_);
2421 #** @method Tile(Geo::GDAL::Extent e)
2423 # Compute the top left cell coordinates and width and height of the
2424 # tile that covers the given extent.
2425 # @param e The extent whose tile is needed.
2426 # @note Requires that the raster is a strictly north up one.
2427 # @return A list ($xoff, $yoff, $xsize, $ysize).
2430 my ($self, $e) = @_;
2431 my ($w, $h) = $self->Size;
2432 my $t = $self->GeoTransform;
2433 confess "GeoTransform is not \"north up\"." unless $t->NorthUp;
2434 my $xoff = floor(($e->[0] - $t->[0])/$t->[1]);
2435 $xoff = 0 if $xoff < 0;
2436 my $yoff = floor(($e->[1] - $t->[3])/$t->[5]);
2437 $yoff = 0 if $yoff < 0;
2438 my $xsize = ceil(($e->[2] - $t->[0])/$t->[1]) - $xoff;
2439 $xsize = $w - $xoff if $xsize > $w - $xoff;
2440 my $ysize = ceil(($e->[3] - $t->[3])/$t->[5]) - $yoff;
2441 $ysize = $h - $yoff if $ysize > $h - $yoff;
2442 return ($xoff, $yoff, $xsize, $ysize);
2445 #** @method Geo::GDAL::Dataset Translate($Dest, hashref Options, coderef progress, $progress_data)
2447 # Convert this dataset into another format.
2448 # @param Dest Destination dataset definition string (typically
2449 # filename) or an object, which implements write and close.
2450 # @param Options See section \ref index_processing_options.
2451 # @return New dataset object if destination dataset definition
2452 # string was given, otherwise a boolean for success/fail but the
2453 # method croaks if there was an error.
2456 my ($self, $dest, $options, $progress, $progress_data) = @_;
2457 return $self->stdout_redirection_wrapper(
2461 #** @method Geo::GDAL::Dataset Warp($Dest, hashref Options, coderef progress, $progress_data)
2463 # Reproject this dataset.
2464 # @param Dest Destination raster dataset definition string (typically
2465 # filename) or an object, which implements write and close.
2466 # @param Options See section \ref index_processing_options.
2467 # @note This method can be run as a package subroutine with a list of
2468 # datasets as the first argument to mosaic several datasets.
2471 my ($self, $dest, $options, $progress, $progress_data) = @_;
2472 # can be run as object method (one dataset) and as package sub (a list of datasets)
2473 $options = Geo::GDAL::GDALWarpAppOptions->new(make_processing_options($options));
2474 my $b = blessed($dest);
2475 $self = [$self] unless ref $self eq 'ARRAY';
2476 if ($b && $b eq 'Geo::GDAL::Dataset') {
2477 Geo::GDAL::wrapper_GDALWarpDestDS($dest, $self, $options, $progress, $progress_data);
2479 return stdout_redirection_wrapper(
2482 \&Geo::GDAL::wrapper_GDALWarpDestName,
2483 $options, $progress, $progress_data
2488 #** @method Geo::GDAL::Dataset Warped(%params)
2490 # Create a virtual warped dataset from this dataset.
2492 # @param params Named parameters:
2493 # - \a SrcSRS Override the spatial reference system of this dataset if there is one (default is undef).
2494 # - \a DstSRS The target spatial reference system of the result (default is undef).
2495 # - \a ResampleAlg The resampling algorithm (default is 'NearestNeighbour').
2496 # - \a MaxError Maximum error measured in input cellsize that is allowed in approximating the transformation (default is 0 for exact calculations).
2498 # # <a href="http://www.gdal.org/gdalwarper_8h.html">Documentation for GDAL warper.</a>
2500 # @return a new Geo::GDAL::Dataset object
2504 my $p = named_parameters(\@_, SrcSRS => undef, DstSRS => undef, ResampleAlg => 'NearestNeighbour', MaxError => 0);
2505 for my $srs (qw/srcsrs dstsrs/) {
2506 $p->{$srs} = $p->{$srs}->ExportToWkt if $p->{$srs} && blessed $p->{$srs};
2508 $p->{resamplealg} = s2i(resampling => $p->{resamplealg});
2509 my $warped = Geo::GDAL::_AutoCreateWarpedVRT($self, $p->{srcsrs}, $p->{dstsrs}, $p->{resamplealg}, $p->{maxerror});
2510 keep($warped, $self) if $warped; # self must live as long as warped
2513 #** @method WriteRaster(%params)
2515 # Write data into the dataset.
2517 # @param params Named parameters:
2518 # - \a XOff x offset (cell coordinates) (default is 0)
2519 # - \a YOff y offset (cell coordinates) (default is 0)
2520 # - \a XSize width of the area to write (default is the width of the dataset)
2521 # - \a YSize height of the area to write (default is the height of the dataset)
2522 # - \a Buf a buffer (or a reference to a buffer) containing the data. Create the buffer with \a pack function of Perl. See Geo::GDAL::Band::PackCharacter.
2523 # - \a BufXSize (default is undef, i.e., the same as XSize)
2524 # - \a BufYSize (default is undef, i.e., the same as YSize)
2525 # - \a BufType data type of the buffer (default is the data type of the first band)
2526 # - \a BandList a reference to an array of band indices (default is [1])
2527 # - \a BufPixelSpace (default is 0)
2528 # - \a BufLineSpace (default is 0)
2529 # - \a BufBandSpace (default is 0)
2531 # <a href="http://www.gdal.org/classGDALDataset.html">Entry in GDAL docs (method RasterIO)</a>
2535 my ($width, $height) = $self->Size;
2536 my ($type) = $self->Band->DataType;
2537 my $p = named_parameters(\@_,
2551 $p->{buftype} = s2i(data_type => $p->{buftype}, 1);
2552 $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});
2555 #** @method WriteTile()
2558 my ($self, $data, $xoff, $yoff) = @_;
2561 for my $i (0..$self->Bands-1) {
2562 $self->Band($i+1)->WriteTile($data->[$i], $xoff, $yoff);
2566 #** @class Geo::GDAL::Driver
2567 # @brief A driver for a specific dataset format.
2570 package Geo::GDAL::Driver;
2572 use base qw(Geo::GDAL::MajorObject Geo::GDAL)
2574 #** @attr $HelpTopic
2575 # $driver->{HelpTopic}
2579 # $driver->{LongName}
2582 #** @attr $ShortName
2583 # $driver->{ShortName}
2586 #** @method list Capabilities()
2588 # @return A list of capabilities. When executed as a package subroutine
2589 # returns a list of all potential capabilities a driver may have. When
2590 # executed as an object method returns a list of all capabilities the
2593 # Currently capabilities are:
2594 # CREATE, CREATECOPY, DEFAULT_FIELDS, NOTNULL_FIELDS, NOTNULL_GEOMFIELDS, OPEN, RASTER, VECTOR, and VIRTUALIO.
2598 # @all_capabilities = Geo::GDAL::Driver::Capabilities;
2599 # @capabilities_of_the_geotiff_driver = Geo::GDAL::Driver('GTiff')->Capabilities;
2604 return @CAPABILITIES unless $self;
2605 my $h = $self->GetMetadata;
2607 for my $cap (@CAPABILITIES) {
2608 my $test = $h->{'DCAP_'.uc($cap)};
2609 push @cap, $cap if defined($test) and $test eq 'YES';
2614 #** @method Geo::GDAL::Dataset Copy(%params)
2616 # Create a new raster Geo::GDAL::Dataset as a copy of an existing dataset.
2617 # @note a.k.a. CreateCopy
2619 # @param params Named parameters:
2620 # - \a Name name for the new raster dataset.
2621 # - \a Src the source Geo::GDAL::Dataset object.
2622 # - \a Strict 1 (default) if the copy must be strictly equivalent, or 0 if the copy may adapt.
2623 # - \a Options an anonymous hash of driver specific options.
2624 # - \a Progress [optional] a reference to a subroutine, which will
2625 # be called with parameters (number progress, string msg, progress_data).
2626 # - \a ProgressData [optional]
2627 # @return a new Geo::GDAL::Dataset object.
2631 my $p = named_parameters(\@_, Name => 'unnamed', Src => undef, Strict => 1, Options => {}, Progress => undef, ProgressData => undef);
2632 return $self->stdout_redirection_wrapper(
2634 $self->can('_CreateCopy'),
2635 $p->{src}, $p->{strict}, $p->{options}, $p->{progress}, $p->{progressdata});
2638 #** @method CopyFiles($NewName, $OldName)
2640 # Copy the files of a dataset.
2641 # @param NewName String.
2642 # @param OldName String.
2647 #** @method Geo::GDAL::Dataset Create(%params)
2649 # Create a raster dataset using this driver.
2650 # @note a.k.a. CreateDataset
2652 # @param params Named parameters:
2653 # - \a Name The name for the dataset (default is 'unnamed') or an object, which implements write and close.
2654 # - \a Width The width for the raster dataset (default is 256).
2655 # - \a Height The height for the raster dataset (default is 256).
2656 # - \a Bands The number of bands to create into the raster dataset (default is 1).
2657 # - \a Type The data type for the raster cells (default is 'Byte'). One of Geo::GDAL::Driver::CreationDataTypes.
2658 # - \a Options Driver creation options as a reference to a hash (default is {}).
2660 # @return A new Geo::GDAL::Dataset object.
2664 my $p = named_parameters(\@_, Name => 'unnamed', Width => 256, Height => 256, Bands => 1, Type => 'Byte', Options => {});
2665 my $type = s2i(data_type => $p->{type});
2666 return $self->stdout_redirection_wrapper(
2668 $self->can('_Create'),
2669 $p->{width}, $p->{height}, $p->{bands}, $type, $p->{options}
2673 #** @method list CreationDataTypes()
2675 # @return a list of data types that can be used for new datasets of this format. A subset of Geo::GDAL::DataTypes
2677 sub CreationDataTypes {
2679 my $h = $self->GetMetadata;
2680 return split /\s+/, $h->{DMD_CREATIONDATATYPES} if $h->{DMD_CREATIONDATATYPES};
2683 #** @method list CreationOptionList()
2685 # @return a list of options, each option is a hashref, the keys are
2686 # name, type and description or Value. Value is a listref.
2688 sub CreationOptionList {
2691 my $h = $self->GetMetadata->{DMD_CREATIONOPTIONLIST};
2693 $h = ParseXMLString($h);
2694 my($type, $value) = NodeData($h);
2695 if ($value eq 'CreationOptionList') {
2696 for my $o (Children($h)) {
2698 for my $a (Children($o)) {
2699 my(undef, $key) = NodeData($a);
2700 my(undef, $value) = NodeData(Child($a, 0));
2701 if ($key eq 'Value') {
2702 push @{$option{$key}}, $value;
2704 $option{$key} = $value;
2707 push @options, \%option;
2714 #** @method Delete($name)
2721 #** @method Domains()
2727 #** @method scalar Extension()
2729 # @note The returned extension does not contain a '.' prefix.
2730 # @return a suggested single extension or a list of extensions (in
2731 # list context) for datasets.
2735 my $h = $self->GetMetadata;
2737 my $e = $h->{DMD_EXTENSIONS};
2738 my @e = split / /, $e;
2739 @e = split /\//, $e if $e =~ /\//; # ILWIS returns mpr/mpl
2740 for my $i (0..$#e) {
2741 $e[$i] =~ s/^\.//; # CALS returns extensions with a dot prefix
2745 my $e = $h->{DMD_EXTENSION};
2746 return '' if $e =~ /\//; # ILWIS returns mpr/mpl
2752 #** @method scalar MIMEType()
2754 # @return a suggested MIME type for datasets.
2758 my $h = $self->GetMetadata;
2759 return $h->{DMD_MIMETYPE};
2762 #** @method scalar Name()
2764 # @return The short name of the driver.
2768 return $self->{ShortName};
2773 # The same as Geo::GDAL::Open except that only this driver is allowed.
2777 my @p = @_; # name, update
2778 my @flags = qw/RASTER/;
2779 push @flags, qw/READONLY/ if $p[1] eq 'ReadOnly';
2780 push @flags, qw/UPDATE/ if $p[1] eq 'Update';
2781 my $dataset = OpenEx($p[0], \@flags, [$self->Name()]);
2782 error("Failed to open $p[0]. Is it a raster dataset?") unless $dataset;
2786 #** @method Rename($NewName, $OldName)
2788 # Rename (move) a GDAL dataset.
2789 # @param NewName String.
2790 # @param OldName String.
2795 #** @method scalar TestCapability($cap)
2797 # Test whether the driver has the specified capability.
2798 # @param cap A capability string (one of those returned by Capabilities).
2799 # @return a boolean value.
2801 sub TestCapability {
2802 my($self, $cap) = @_;
2803 my $h = $self->GetMetadata->{'DCAP_'.uc($cap)};
2804 return (defined($h) and $h eq 'YES') ? 1 : undef;
2807 #** @method stdout_redirection_wrapper()
2809 sub stdout_redirection_wrapper {
2810 my ($self, $name, $sub, @params) = @_;
2812 if ($name && blessed $name) {
2814 my $ref = $object->can('write');
2815 VSIStdoutSetRedirection($ref);
2816 $name = '/vsistdout/';
2820 $ds = $sub->($self, $name, @params);
2824 $Geo::GDAL::stdout_redirection{tied(%$ds)} = $object;
2826 VSIStdoutUnsetRedirection();
2830 confess(last_error()) if $@;
2831 confess("Failed. Use Geo::OGR::Driver for vector drivers.") unless $ds;
2835 #** @class Geo::GDAL::Extent
2836 # @brief A rectangular area in projection coordinates: xmin, ymin, xmax, ymax.
2838 package Geo::GDAL::Extent;
2840 #** @method ExpandToInclude($extent)
2841 # Package subroutine.
2842 # Extends this extent to include the other extent.
2843 # @param extent Another Geo::GDAL::Extent object.
2845 sub ExpandToInclude {
2846 my ($self, $e) = @_;
2847 return if $e->IsEmpty;
2848 if ($self->IsEmpty) {
2851 $self->[0] = $e->[0] if $e->[0] < $self->[0];
2852 $self->[1] = $e->[1] if $e->[1] < $self->[1];
2853 $self->[2] = $e->[2] if $e->[2] > $self->[2];
2854 $self->[3] = $e->[3] if $e->[3] > $self->[3];
2858 #** @method IsEmpty()
2862 return $self->[2] < $self->[0];
2865 #** @method scalar Overlap($extent)
2866 # Package subroutine.
2867 # @param extent Another Geo::GDAL::Extent object.
2868 # @return A new, possibly empty, Geo::GDAL::Extent object, which
2869 # represents the joint area of the two extents.
2872 my ($self, $e) = @_;
2873 return Geo::GDAL::Extent->new() unless $self->Overlaps($e);
2874 my $ret = Geo::GDAL::Extent->new($self);
2875 $ret->[0] = $e->[0] if $self->[0] < $e->[0];
2876 $ret->[1] = $e->[1] if $self->[1] < $e->[1];
2877 $ret->[2] = $e->[2] if $self->[2] > $e->[2];
2878 $ret->[3] = $e->[3] if $self->[3] > $e->[3];
2882 #** @method scalar Overlaps($extent)
2883 # Package subroutine.
2884 # @param extent Another Geo::GDAL::Extent object.
2885 # @return True if this extent overlaps the other extent, false otherwise.
2888 my ($self, $e) = @_;
2889 return $self->[0] < $e->[2] && $self->[2] > $e->[0] && $self->[1] < $e->[3] && $self->[3] > $e->[1];
2892 #** @method list Size()
2893 # Package subroutine.
2894 # @return A list ($width, $height).
2898 return (0,0) if $self->IsEmpty;
2899 return ($self->[2] - $self->[0], $self->[3] - $self->[1]);
2902 #** @method Geo::GDAL::Extent new(@params)
2903 # Package subroutine.
2904 # @param params nothing, a list ($xmin, $ymin, $xmax, $ymax), or an Extent object
2905 # @return A new Extent object (empty if no parameters, a copy of the parameter if it is an Extent object).
2912 } elsif (ref $_[0]) {
2917 bless $self, $class;
2921 #** @class Geo::GDAL::GCP
2922 # @brief A ground control point for georeferencing rasters.
2925 package Geo::GDAL::GCP;
2927 use base qw(Geo::GDAL)
2930 # cell x coordinate (access as $gcp->{Column})
2934 # unique identifier (string) (access as $gcp->{Id})
2938 # informational message (access as $gcp->{Info})
2942 # cell y coordinate (access as $gcp->{Row})
2946 # projection coordinate (access as $gcp->{X})
2950 # projection coordinate (access as $gcp->{Y})
2954 # projection coordinate (access as $gcp->{Z})
2957 #** @method scalar new($x = 0.0, $y = 0.0, $z = 0.0, $column = 0.0, $row = 0.0, $info = "", $id = "")
2959 # @param x projection coordinate
2960 # @param y projection coordinate
2961 # @param z projection coordinate
2962 # @param column cell x coordinate
2963 # @param row cell y coordinate
2964 # @param info informational message
2965 # @param id unique identifier (string)
2966 # @return a new Geo::GDAL::GCP object
2970 my $self = Geo::GDALc::new_GCP(@_);
2971 bless $self, $pkg if defined($self);
2974 #** @class Geo::GDAL::GeoTransform
2975 # @brief An array of affine transformation coefficients.
2976 # @details The geo transformation has the form
2978 # x = a + column * b + row * c
2979 # y = d + column * e + row * f
2982 # (column,row) is the location in cell coordinates, and
2983 # (x,y) is the location in projection coordinates, or vice versa.
2984 # A Geo::GDAL::GeoTransform object is a reference to an anonymous array [a,b,c,d,e,f].
2986 package Geo::GDAL::GeoTransform;
2988 #** @method Apply($x, $y)
2990 # @param x Column or x, or a reference to an array of columns or x's
2991 # @param y Row or y, or a reference to an array of rows or y's
2992 # @return a list (x, y), where x and y are the transformed coordinates
2993 # or references to arrays of transformed coordinates.
2996 my ($self, $columns, $rows) = @_;
2997 return Geo::GDAL::ApplyGeoTransform($self, $columns, $rows) unless ref($columns) eq 'ARRAY';
2999 for my $i (0..$#$columns) {
3001 Geo::GDAL::ApplyGeoTransform($self, $columns->[$i], $rows->[$i]);
3008 # @return a new Geo::GDAL::GeoTransform object, which is the inverse
3009 # of this one (in void context changes this object).
3013 my @inv = Geo::GDAL::InvGeoTransform($self);
3014 return Geo::GDAL::GeoTransform->new(@inv) if defined wantarray;
3018 #** @method NorthUp()
3022 return $self->[2] == 0 && $self->[4] == 0;
3025 #** @method new(@params)
3027 # @param params nothing, a reference to an array [a,b,c,d,e,f], a list
3028 # (a,b,c,d,e,f), or named parameters
3029 # - \a GCPs A reference to an array of Geo::GDAL::GCP objects.
3030 # - \a ApproxOK Minimize the error in the coefficients (integer, default is 1 (true), used with GCPs).
3031 # - \a Extent A Geo::GDAL::Extent object used to obtain the coordinates of the up left corner position.
3032 # - \a CellSize The cell size (width and height) (default is 1, used with Extent).
3034 # @note When Extent is specifid, the created geo transform will be
3035 # north up, have square cells, and coefficient f will be -1 times the
3036 # cell size (image y - row - will increase downwards and projection y
3037 # will increase upwards).
3038 # @return a new Geo::GDAL::GeoTransform object.
3044 $self = [0,1,0,0,0,1];
3045 } elsif (ref $_[0]) {
3047 } elsif ($_[0] =~ /^[a-zA-Z]/i) {
3048 my $p = named_parameters(\@_, GCPs => undef, ApproxOK => 1, Extent => undef, CellSize => 1);
3050 $self = Geo::GDAL::GCPsToGeoTransform($p->{gcps}, $p->{approxok});
3051 } elsif ($p->{extent}) {
3052 $self = Geo::GDAL::GeoTransform->new($p->{extent}[0], $p->{cellsize}, 0, $p->{extent}[2], 0, -$p->{cellsize});
3054 error("Missing GCPs or Extent");
3060 bless $self, $class;
3063 #** @class Geo::GDAL::MajorObject
3064 # @brief An object, which holds meta data.
3067 package Geo::GDAL::MajorObject;
3069 use base qw(Geo::GDAL)
3071 #** @method scalar Description($description)
3073 # @param description [optional]
3074 # @return the description in a non-void context.
3077 my($self, $desc) = @_;
3078 SetDescription($self, $desc) if defined $desc;
3079 GetDescription($self) if defined wantarray;
3082 #** @method Domains()
3083 # Package subroutine.
3084 # @return the class specific DOMAINS list
3090 #** @method scalar GetDescription()
3094 sub GetDescription {
3097 #** @method hash reference GetMetadata($domain = "")
3099 # @note see Metadata
3106 #** @method GetMetadataDomainList()
3108 sub GetMetadataDomainList {
3111 #** @method hash reference Metadata(hashref metadata = undef, $domain = '')
3115 # @return the metadata in a non-void context.
3119 my $metadata = ref $_[0] ? shift : undef;
3120 my $domain = shift // '';
3121 SetMetadata($self, $metadata, $domain) if defined $metadata;
3122 GetMetadata($self, $domain) if defined wantarray;
3125 #** @method SetDescription($NewDesc)
3130 sub SetDescription {
3133 #** @method SetMetadata(hashref metadata, $domain = "")
3135 # @note see Metadata
3143 #** @class Geo::GDAL::RasterAttributeTable
3144 # @brief An attribute table in a raster band.
3147 package Geo::GDAL::RasterAttributeTable;
3149 use base qw(Geo::GDAL)
3158 #** @method ChangesAreWrittenToFile()
3160 sub ChangesAreWrittenToFile {
3163 #** @method Geo::GDAL::RasterAttributeTable Clone()
3165 # @return a new Geo::GDAL::RasterAttributeTable object
3170 #** @method hash Columns(%columns)
3172 # A get/set method for the columns of the RAT
3173 # @param columns optional, a the keys are column names and the values are anonymous
3174 # hashes with keys Type and Usage
3175 # @return a hash similar to the optional input parameter
3180 if (@_) { # create columns
3182 for my $name (keys %columns) {
3183 $self->CreateColumn($name, $columns{$name}{Type}, $columns{$name}{Usage});
3187 for my $c (0..$self->GetColumnCount-1) {
3188 my $name = $self->GetNameOfCol($c);
3189 $columns{$name}{Type} = $self->GetTypeOfCol($c);
3190 $columns{$name}{Usage} = $self->GetUsageOfCol($c);
3195 #** @method CreateColumn($name, $type, $usage)
3198 # @param type one of FieldTypes
3199 # @param usage one of FieldUsages
3202 my($self, $name, $type, $usage) = @_;
3203 for my $color (qw/Red Green Blue Alpha/) {
3204 carp "RAT column type will be 'Integer' for usage '$color'." if $usage eq $color and $type ne 'Integer';
3206 $type = s2i(rat_field_type => $type);
3207 $usage = s2i(rat_field_usage => $usage);
3208 _CreateColumn($self, $name, $type, $usage);
3211 #** @method DumpReadable()
3216 #** @method list FieldTypes()
3217 # Package subroutine.
3221 return @FIELD_TYPES;
3224 #** @method list FieldUsages()
3225 # Package subroutine.
3229 return @FIELD_USAGES;
3232 #** @method scalar GetColOfUsage($usage)
3238 my($self, $usage) = @_;
3239 _GetColOfUsage($self, s2i(rat_field_usage => $usage));
3242 #** @method scalar GetColumnCount()
3246 sub GetColumnCount {
3249 #** @method scalar GetNameOfCol($column)
3257 #** @method scalar GetRowCount()
3263 #** @method scalar GetRowOfValue($value)
3265 # @param value a cell value
3266 # @return row index or -1
3271 #** @method scalar GetTypeOfCol($column)
3277 my($self, $col) = @_;
3278 i2s(rat_field_type => _GetTypeOfCol($self, $col));
3281 #** @method scalar GetUsageOfCol($column)
3287 my($self, $col) = @_;
3288 i2s(rat_field_usage => _GetUsageOfCol($self, $col));
3291 #** @method scalar GetValueAsDouble($row, $column)
3297 sub GetValueAsDouble {
3300 #** @method scalar GetValueAsInt($row, $column)
3309 #** @method scalar GetValueAsString($row, $column)
3315 sub GetValueAsString {
3318 #** @method LinearBinning($Row0MinIn, $BinSizeIn)
3320 # @param Row0MinIn [optional] the lower bound (cell value) of the first category.
3321 # @param BinSizeIn [optional] the width of each category (in cell value units).
3322 # @return ($Row0MinIn, $BinSizeIn) or an empty list if LinearBinning is not set.
3326 SetLinearBinning($self, @_) if @_ > 0;
3327 return unless defined wantarray;
3328 my @a = GetLinearBinning($self);
3329 return $a[0] ? ($a[1], $a[2]) : ();
3332 #** @method SetRowCount($count)
3340 #** @method SetValueAsDouble($row, $column, $value)
3347 sub SetValueAsDouble {
3350 #** @method SetValueAsInt($row, $column, $value)
3360 #** @method SetValueAsString($row, $column, $value)
3367 sub SetValueAsString {
3370 #** @method scalar Value($row, $column, $value)
3374 # @param value [optional]
3378 my($self, $row, $column) = @_;
3379 SetValueAsString($self, $row, $column, $_[3]) if defined $_[3];
3380 return unless defined wantarray;
3381 GetValueAsString($self, $row, $column);
3384 #** @method Geo::GDAL::RasterAttributeTable new()
3386 # @return a new Geo::GDAL::RasterAttributeTable object
3390 my $self = Geo::GDALc::new_RasterAttributeTable(@_);
3391 bless $self, $pkg if defined($self);
3394 #** @class Geo::GDAL::Transformer
3396 # @details This class is not yet documented for the GDAL Perl bindings.
3397 # @todo Test and document.
3399 package Geo::GDAL::Transformer;
3401 use base qw(Geo::GDAL)
3403 #** @method TransformGeolocations()
3405 sub TransformGeolocations {
3408 #** @method TransformPoint()
3410 sub TransformPoint {
3417 my $self = Geo::GDALc::new_Transformer(@_);
3418 bless $self, $pkg if defined($self);
3421 #** @class Geo::GDAL::VSIF
3422 # @brief A GDAL virtual file system.
3425 package Geo::GDAL::VSIF;
3427 use base qw(Exporter)
3434 Geo::GDAL::VSIFCloseL($self);
3437 #** @method MkDir($path)
3438 # Package subroutine.
3440 # @param path The directory to make.
3441 # @note The name of this method is VSIMkdir in GDAL.
3445 # mode unused in CPL
3446 Geo::GDAL::Mkdir($path, 0);
3449 #** @method Geo::GDAL::VSIF Open($filename, $mode)
3450 # Package subroutine.
3451 # @param filename Name of the file to open. For example "/vsimem/x".
3452 # @param mode Access mode. 'r', 'r+', 'w', etc.
3453 # @return A file handle on success.
3456 my ($path, $mode) = @_;
3457 my $self = Geo::GDAL::VSIFOpenL($path, $mode);
3458 bless $self, 'Geo::GDAL::VSIF';
3461 #** @method scalar Read($count)
3463 # @param count The number of bytes to read from the file.
3464 # @return A byte string.
3467 my ($self, $count) = @_;
3468 Geo::GDAL::VSIFReadL($count, $self);
3471 #** @method list ReadDir($dir)
3472 # Package subroutine.
3473 # @return Contents of a directory in an anonymous array or as a list.
3477 Geo::GDAL::ReadDir($path);
3480 #** @method scalar ReadDirRecursive($dir)
3481 # Package subroutine.
3482 # @note Give the directory in the form '/vsimem', i.e., without trailing '/'.
3483 # @return Contents of a directory tree in an anonymous array.
3485 sub ReadDirRecursive {
3487 Geo::GDAL::ReadDirRecursive($path);
3490 #** @method Rename($old, $new)
3491 # Package subroutine.
3493 # @note The name of this method is VSIRename in GDAL.
3496 my ($old, $new) = @_;
3497 Geo::GDAL::Rename($old, $new);
3500 #** @method RmDir($path)
3501 # Package subroutine.
3502 # Remove a directory.
3503 # @note The name of this method is VSIRmdir in GDAL.
3506 my ($dirname, $recursive) = @_;
3509 Geo::GDAL::Rmdir($dirname);
3511 for my $f (ReadDir($dirname)) {
3512 next if $f eq '..' or $f eq '.';
3513 my @s = Stat($dirname.'/'.$f);
3515 Unlink($dirname.'/'.$f);
3516 } elsif ($s[0] eq 'd') {
3517 Rmdir($dirname.'/'.$f, 1);
3518 Rmdir($dirname.'/'.$f);
3525 my $r = $recursive ? ' recursively' : '';
3526 error("Cannot remove directory \"$dirname\"$r.");
3530 #** @method Seek($offset, $whence)
3534 my ($self, $offset, $whence) = @_;
3535 Geo::GDAL::VSIFSeekL($self, $offset, $whence);
3538 #** @method list Stat($filename)
3539 # Package subroutine.
3540 # @return ($filemode, $filesize). filemode is f for a plain file, d
3541 # for a directory, l for a symbolic link, p for a named pipe (FIFO), S
3542 # for a socket, b for a block special file, and c for a character
3547 Geo::GDAL::Stat($path);
3550 #** @method scalar Tell()
3555 Geo::GDAL::VSIFTellL($self);
3558 #** @method Truncate($new_size)
3562 my ($self, $new_size) = @_;
3563 Geo::GDAL::VSIFTruncateL($self, $new_size);
3566 #** @method Unlink($filename)
3567 # Package subroutine.
3568 # @param filename The file to delete.
3569 # @return 0 on success and -1 on an error.
3572 my ($filename) = @_;
3573 Geo::GDAL::Unlink($filename);
3576 #** @method Write($scalar)
3578 # @param scalar The byte string to write to the file.
3579 # @return Number of bytes written into the file.
3582 my ($self, $data) = @_;
3583 Geo::GDAL::VSIFWriteL($data, $self);
3586 #** @class Geo::GDAL::XML
3587 # @brief A simple XML parser
3590 package Geo::GDAL::XML;
3592 #** @method new($string)
3594 # @param string String containing XML.
3595 # @return A new Geo::GDAL::XML object, which is a reference to an anonymous array.
3599 my $xml = shift // '';
3600 my $self = ParseXMLString($xml);
3601 bless $self, $class;
3602 $self->traverse(sub {my $node = shift; bless $node, $class});
3606 #** @method serialize()
3608 # @return The XML serialized into a string.
3612 return SerializeXMLTree($self);
3615 # This file was automatically generated by SWIG (http://www.swig.org).
3618 # Do not make changes to this file unless you know what you are doing--modify
3619 # the SWIG interface file instead.
3622 #** @method traverse(coderef subroutine)
3624 # @param subroutine Code reference, which will be called for each node in the XML with parameters: node, node_type, node_value. Node type is either Attribute, Comment, Element, Literal, or Text.
3627 my ($self, $sub) = @_;
3628 my $type = $self->[0];
3629 my $data = $self->[1];
3630 $type = NodeType($type);
3631 $sub->($self, $type, $data);
3632 for my $child (@{$self}[2..$#$self]) {
3633 traverse($child, $sub);
3638 # @brief Base class for geographical networks in GDAL.
3643 #** @method CastToGenericNetwork()
3645 sub CastToGenericNetwork {
3648 #** @method CastToNetwork()
3653 #** @method GATConnectedComponents()
3655 sub GATConnectedComponents {
3658 #** @method GATDijkstraShortestPath()
3660 sub GATDijkstraShortestPath {
3663 #** @method GATKShortestPath()
3665 sub GATKShortestPath {
3668 #** @method GNM_EDGE_DIR_BOTH()
3670 sub GNM_EDGE_DIR_BOTH {
3673 #** @method GNM_EDGE_DIR_SRCTOTGT()
3675 sub GNM_EDGE_DIR_SRCTOTGT {
3678 #** @method GNM_EDGE_DIR_TGTTOSRC()
3680 sub GNM_EDGE_DIR_TGTTOSRC {
3684 #** @class Geo::GNM::GenericNetwork
3687 package Geo::GNM::GenericNetwork;
3689 use base qw(Geo::GNM::Network Geo::GNM)
3691 #** @method ChangeAllBlockState()
3693 sub ChangeAllBlockState {
3696 #** @method ChangeBlockState()
3698 sub ChangeBlockState {
3701 #** @method ConnectFeatures()
3703 sub ConnectFeatures {
3706 #** @method ConnectPointsByLines()
3708 sub ConnectPointsByLines {
3711 #** @method CreateRule()
3716 #** @method DeleteAllRules()
3718 sub DeleteAllRules {
3721 #** @method DeleteRule()
3726 #** @method DisconnectFeatures()
3728 sub DisconnectFeatures {
3731 #** @method DisconnectFeaturesWithId()
3733 sub DisconnectFeaturesWithId {
3736 #** @method GetRules()
3741 #** @method ReconnectFeatures()
3743 sub ReconnectFeatures {
3746 #** @class Geo::GNM::MajorObject
3749 package Geo::GNM::MajorObject;
3751 #** @class Geo::GNM::Network
3754 package Geo::GNM::Network;
3756 use base qw(Geo::GDAL::MajorObject Geo::GNM)
3758 #** @method CommitTransaction()
3760 sub CommitTransaction {
3763 #** @method CopyLayer()
3768 #** @method DisconnectAll()
3773 #** @method GetFeatureByGlobalFID()
3775 sub GetFeatureByGlobalFID {
3778 #** @method GetFileList()
3783 #** @method GetLayerByIndex()
3785 sub GetLayerByIndex {
3788 #** @method GetLayerByName()
3790 sub GetLayerByName {
3793 #** @method GetLayerCount()
3798 #** @method GetName()
3803 #** @method GetPath()
3808 #** @method GetProjection()
3813 #** @method GetProjectionRef()
3815 sub GetProjectionRef {
3818 #** @method GetVersion()
3823 #** @method RollbackTransaction()
3825 sub RollbackTransaction {
3828 #** @method StartTransaction()
3830 sub StartTransaction {
3834 # @brief OGR utility functions.
3835 # @details A wrapper for many OGR utility functions and a root class for all
3840 #** @method list ByteOrders()
3841 # Package subroutine.
3842 # @return a list of byte order types, XDR and NDR. XDR denotes
3843 # big-endian and NDR denotes little-endian.
3848 #** @method Geo::GDAL::Driver Driver($name)
3849 # Package subroutine.
3851 # @param name the short name of the driver.
3852 # @note No check is made that the driver is actually a vector driver.
3853 # @return a Geo::GDAL::Driver object.
3856 return 'Geo::GDAL::Driver' unless @_;
3857 bless Geo::GDAL::Driver(@_), 'Geo::OGR::Driver';
3860 #** @method list DriverNames()
3861 # Package subroutine.
3862 # A.k.a GetDriverNames
3864 # perl -MGeo::GDAL -e '@d=Geo::OGR::DriverNames;print "@d\n"'
3866 # @note Use Geo::GDAL::DriverNames for raster drivers.
3867 # @return a list of the short names of all available GDAL vector drivers.
3872 #** @method list Drivers()
3873 # Package subroutine.
3874 # @note Use Geo::GDAL::Drivers for raster drivers.
3875 # @return a list of all available GDAL vector drivers.
3879 for my $i (0..GetDriverCount()-1) {
3880 my $driver = Geo::GDAL::GetDriver($i);
3881 push @drivers, $driver if $driver->TestCapability('VECTOR');
3886 #** @method Flatten()
3891 #** @method scalar GeometryTypeModify($type, $modifier)
3893 # @param type a geometry type (one of Geo::OGR::GeometryTypes).
3894 # @param modifier one of 'flatten', 'set_Z', 'make_collection', 'make_curve', or 'make_linear'.
3895 # @return modified geometry type.
3897 sub GeometryTypeModify {
3898 my($type, $modifier) = @_;
3899 $type = s2i(geometry_type => $type);
3900 return i2s(geometry_type => GT_Flatten($type)) if $modifier =~ /flat/i;
3901 return i2s(geometry_type => GT_SetZ($type)) if $modifier =~ /z/i;
3902 return i2s(geometry_type => GT_GetCollection($type)) if $modifier =~ /collection/i;
3903 return i2s(geometry_type => GT_GetCurve($type)) if $modifier =~ /curve/i;
3904 return i2s(geometry_type => GT_GetLinear($type)) if $modifier =~ /linear/i;
3905 error(1, $modifier, {Flatten => 1, SetZ => 1, GetCollection => 1, GetCurve => 1, GetLinear => 1});
3908 #** @method scalar GeometryTypeTest($type, $test, $type2)
3910 # @param type a geometry type (one of Geo::OGR::GeometryTypes).
3911 # @param test one of 'has_z', 'is_subclass_of', 'is_curve', 'is_surface', or 'is_non_linear'.
3912 # @param type2 a geometry type (one of Geo::OGR::GeometryTypes). Required for 'is_subclass_of' test.
3913 # @return result of the test.
3915 sub GeometryTypeTest {
3916 my($type, $test, $type2) = @_;
3917 $type = s2i(geometry_type => $type);
3918 if (defined $type2) {
3919 $type = s2i(geometry_type => $type);
3921 error("Usage: GeometryTypeTest(type1, 'is_subclass_of', type2).") if $test =~ /subclass/i;
3923 return GT_HasZ($type) if $test =~ /z/i;
3924 return GT_IsSubClassOf($type, $type2) if $test =~ /subclass/i;
3925 return GT_IsCurve($type) if $test =~ /curve/i;
3926 return GT_IsSurface($type) if $test =~ /surface/i;
3927 return GT_IsNonLinear($type) if $test =~ /linear/i;
3928 error(1, $test, {HasZ => 1, IsSubClassOf => 1, IsCurve => 1, IsSurface => 1, IsNonLinear => 1});
3931 #** @method list GeometryTypes()
3932 # Package subroutine.
3933 # @return a list of all geometry types, currently:
3934 # CircularString, CircularStringM, CircularStringZ, CircularStringZM, CompoundCurve, CompoundCurveM, CompoundCurveZ, CompoundCurveZM, Curve, CurveM, CurvePolygon, CurvePolygonM, CurvePolygonZ, CurvePolygonZM, CurveZ, CurveZM, GeometryCollection, GeometryCollection25D, GeometryCollectionM, GeometryCollectionZM, LineString, LineString25D, LineStringM, LineStringZM, LinearRing, MultiCurve, MultiCurveM, MultiCurveZ, MultiCurveZM, MultiLineString, MultiLineString25D, MultiLineStringM, MultiLineStringZM, MultiPoint, MultiPoint25D, MultiPointM, MultiPointZM, MultiPolygon, MultiPolygon25D, MultiPolygonM, MultiPolygonZM, MultiSurface, MultiSurfaceM, MultiSurfaceZ, MultiSurfaceZM, None, Point, Point25D, PointM, PointZM, Polygon, Polygon25D, PolygonM, PolygonZM, PolyhedralSurface, PolyhedralSurfaceM, PolyhedralSurfaceZ, PolyhedralSurfaceZM, Surface, SurfaceM, SurfaceZ, SurfaceZM, TIN, TINM, TINZ, TINZM, Triangle, TriangleM, TriangleZ, TriangleZM, and Unknown.
3938 # This file was automatically generated by SWIG (http://www.swig.org).
3941 # Do not make changes to this file unless you know what you are doing--modify
3942 # the SWIG interface file instead.
3945 #** @method GetNonLinearGeometriesEnabledFlag()
3947 sub GetNonLinearGeometriesEnabledFlag {
3950 #** @method GetOpenDSCount()
3952 sub GetOpenDSCount {
3965 #** @method Geo::GDAL::Dataset Open($name, $update = 0)
3967 # Open a vector data source.
3968 # @param name The data source string (directory, filename, etc.).
3969 # @param update Whether to open the data source in update mode (default is not).
3970 # @return a new Geo::GDAL::Dataset object.
3973 my @p = @_; # name, update
3974 my @flags = qw/VECTOR/;
3975 push @flags, qw/UPDATE/ if $p[1];
3976 my $dataset = Geo::GDAL::OpenEx($p[0], \@flags);
3977 error("Failed to open $p[0]. Is it a vector dataset?") unless $dataset;
3981 #** @method Geo::GDAL::Dataset OpenShared($name, $update = 0)
3983 # Open a vector data source in shared mode.
3984 # @param name The data source string (directory, filename, etc.).
3985 # @param update Whether to open the data source in update mode.
3986 # @return a new Geo::GDAL::Dataset object.
3989 my @p = @_; # name, update
3990 my @flags = qw/VECTOR SHARED/;
3991 push @flags, qw/UPDATE/ if $p[1];
3992 my $dataset = Geo::GDAL::OpenEx($p[0], \@flags);
3993 error("Failed to open $p[0]. Is it a vector dataset?") unless $dataset;
3997 #** @method SetGenerate_DB2_V72_BYTE_ORDER($Generate_DB2_V72_BYTE_ORDER)
3999 # Needed only on IBM DB2.
4001 sub SetGenerate_DB2_V72_BYTE_ORDER {
4004 #** @method SetNonLinearGeometriesEnabledFlag()
4006 sub SetNonLinearGeometriesEnabledFlag {
4009 #** @class Geo::OGR::DataSource
4010 # @brief A vector dataset.
4011 # @details This is a legacy class which should not be
4012 # used in new code. Use Geo::GDAL::Dataset.
4014 package Geo::OGR::DataSource;
4016 #** @method Geo::GDAL::Dataset Open()
4017 # Package subroutine.
4018 # The same as Geo::OGR::Open
4023 #** @method Geo::GDAL::Dataset OpenShared()
4024 # Package subroutine.
4025 # The same as Geo::OGR::OpenShared
4030 #** @class Geo::OGR::Driver
4031 # @brief A vector format driver.
4032 # @details This is a legacy class which
4033 # should not be used in new code. Use Geo::GDAL::Driver.
4035 package Geo::OGR::Driver;
4037 use base qw(Geo::GDAL::Driver)
4039 #** @method Geo::GDAL::Dataset Copy(Geo::GDAL::Dataset source, $name, arrayref options = undef)
4041 # Copy a vector data source into a new data source with this driver.
4042 # @param source The Geo::GDAL::Dataset object to be copied.
4043 # @param name The name for the new data source.
4044 # @param options Driver specific options. In addition to options
4045 # specified in GDAL documentation the option STRICT can be set to 'NO'
4046 # for a more relaxed copy. Otherwise the STRICT is 'YES'.
4047 # @note The order of the first two parameters is different from that in Geo::GDAL::Driver::Copy.
4048 # @return a new Geo::GDAL::Dataset object.
4051 my ($self, @p) = @_; # src, name, options
4052 my $strict = 1; # the default in bindings
4053 $strict = 0 if $p[2] && $p[2]->{STRICT} eq 'NO';
4054 $self->SUPER::Copy($p[1], $p[0], $strict, @{$p[2..4]}); # path, src, strict, options, cb, cb_data
4057 #** @method Geo::GDAL::Dataset Create($name, hashref options = undef )
4059 # Create a new vector data source using this driver.
4060 # @param name The data source name.
4061 # @param options Driver specific dataset creation options.
4064 my ($self, $name, $options) = @_; # name, options
4066 $self->SUPER::Create(Name => $name, Width => 0, Height => 0, Bands => 0, Type => 'Byte', Options => $options);
4071 # The same as Geo::OGR::Open except that only this driver is allowed.
4075 my @p = @_; # name, update
4076 my @flags = qw/VECTOR/;
4077 push @flags, qw/UPDATE/ if $p[1];
4078 my $dataset = Geo::GDAL::OpenEx($p[0], \@flags, [$self->Name()]);
4079 error("Failed to open $p[0]. Is it a vector dataset?") unless $dataset;
4083 #** @class Geo::OGR::Feature
4084 # @brief A collection of non-spatial and spatial attributes.
4085 # @details A feature is a collection of non-spatial and spatial attributes and
4086 # an id, which is a special attribute, and data records according to
4087 # this data model. Attributes are called fields and some fields are
4088 # spatial, i.e., their value is a geometry. Fields have at least a
4089 # name and a type. Features may exist within a layer or
4090 # separetely. The data model of a feature is a definition object.
4092 package Geo::OGR::Feature;
4094 use base qw(Geo::OGR)
4096 #** @method Geo::OGR::Feature Clone()
4098 # @return a new Geo::OGR::Feature object
4103 #** @method DumpReadable()
4105 # Write the contents of this feature to stdout.
4110 #** @method scalar Equal($feature)
4112 # @param feature a Geo::OGR::Feature object for comparison
4118 #** @method scalar FID($id)
4120 # @brief Get or set the id of this feature.
4121 # @param id [optional] the id to set for this feature.
4122 # @return integer the id of this feature.
4126 $self->SetFID($_[0]) if @_;
4127 return unless defined wantarray;
4131 #** @method Field($name, $value, ...)
4133 # @brief Get, set, or unset the field value.
4134 # @param name the name (or the index) of the field.
4135 # @param value a scalar, a list of scalars or a reference to a
4136 # list. If undef, the field is unset. If a scalar or a list of
4137 # scalars, the field is set from them.
4138 # @note Non-scalar fields (for example Date) can be set either from a
4139 # scalar, which is then assumed to be a string and parsed, or from a
4140 # list of values (for example year, month, day for Date).
4141 # @note Setting and getting Integer64 fields requires 'use bigint' if
4142 # \$Config{ivsize} is smaller than 8, i.e., in a 32 bit machine.
4143 # @return in non-void context the value of the field, which may be a
4144 # scalar or a list, depending on the field type. For unset fields the
4145 # undef value is returned.
4149 my $field = $self->GetFieldIndex(shift // 0);
4150 $self->SetField($field, @_) if @_;
4151 $self->GetField($field) if defined wantarray;
4154 #** @method FillUnsetWithDefault()
4156 sub FillUnsetWithDefault {
4159 #** @method Geometry($name, $geometry)
4161 # @brief Get or set the value of a geometry field.
4162 # @note This method delivers the functionality of undocumented methods
4163 # SetGeometry($geometry), SetGeometryDirectly, SetGeomField,
4164 # SetGeomFieldDirectly, GetGeometry, GetGeometryRef.
4166 # Set or get the geometry in the feature. When setting, does a check
4167 # against the schema (GeometryType) of the feature. If the parameter
4168 # is a geometry object, it is cloned.
4169 # @param name [optional] the name of the spatial field,
4170 # whose geometry is to be set. If not given, sets or gets the geometry
4171 # of the first (or the single) spatial field.
4172 # @param geometry [optional] a Geo::OGR::Geometry object or a
4173 # reference to a hash from which such can be created (using
4174 # Geo::OGR::Geometry::new).
4175 # @return in a non-void context the indicated geometry in the feature
4176 # as a Geo::OGR::Geometry object. The returned object contains a
4177 # reference to the actual geometry data in the feature (the geometry
4178 # is not cloned) and to the feature object, thus keeping the feature
4179 # object from being destroyed while the geometry object exists.
4183 my $field = ((@_ > 0 and ref($_[0]) eq '') or (@_ > 2 and @_ % 2 == 1)) ? shift : 0;
4184 $field = $self->GetGeomFieldIndex($field);
4186 if (@_ and @_ % 2 == 0) {
4192 my $type = $self->GetDefn->GetGeomFieldDefn($field)->Type;
4193 if (blessed($geometry) and $geometry->isa('Geo::OGR::Geometry')) {
4194 my $gtype = $geometry->GeometryType;
4195 error("The type of the inserted geometry ('$gtype') is not the same as the type of the field ('$type').")
4196 if $type ne 'Unknown' and $type ne $gtype;
4198 $self->SetGeomFieldDirectly($field, $geometry->Clone);
4200 confess last_error() if $@;
4201 } elsif (ref($geometry) eq 'HASH') {
4202 $geometry->{GeometryType} //= $type;
4204 $geometry = Geo::OGR::Geometry->new($geometry);
4206 confess last_error() if $@;
4207 my $gtype = $geometry->GeometryType;
4208 error("The type of the inserted geometry ('$gtype') is not the same as the type of the field ('$type').")
4209 if $type ne 'Unknown' and $type ne $gtype;
4211 $self->SetGeomFieldDirectly($field, $geometry);
4213 confess last_error() if $@;
4215 error("Usage: \$feature->Geometry([field],[geometry])");
4218 return unless defined wantarray;
4219 $geometry = $self->GetGeomFieldRef($field);
4220 return unless $geometry;
4221 keep($geometry, $self);
4224 #** @method Geo::OGR::FeatureDefn GetDefn()
4226 # @note A.k.a GetDefnRef.
4227 # @return a Geo::OGR::FeatureDefn object, which represents the definition of this feature.
4231 my $defn = $self->GetDefnRef;
4235 #** @method scalar GetFID()
4237 # @return the feature id (an integer).
4242 #** @method list GetField($name)
4247 my ($self, $field) = @_;
4248 $field = $self->GetFieldIndex($field);
4249 return unless IsFieldSet($self, $field);
4250 my $type = GetFieldType($self, $field);
4251 return GetFieldAsInteger($self, $field) if $type == $Geo::OGR::OFTInteger;
4252 return GetFieldAsInteger64($self, $field) if $type == $Geo::OGR::OFTInteger64;
4253 return GetFieldAsDouble($self, $field) if $type == $Geo::OGR::OFTReal;
4254 return GetFieldAsString($self, $field) if $type == $Geo::OGR::OFTString;
4255 if ($type == $Geo::OGR::OFTIntegerList) {
4256 my $ret = GetFieldAsIntegerList($self, $field);
4257 return wantarray ? @$ret : $ret;
4259 if ($type == $Geo::OGR::OFTInteger64List) {
4260 my $ret = GetFieldAsInteger64List($self, $field);
4261 return wantarray ? @$ret : $ret;
4263 if ($type == $Geo::OGR::OFTRealList) {
4264 my $ret = GetFieldAsDoubleList($self, $field);
4265 return wantarray ? @$ret : $ret;
4267 if ($type == $Geo::OGR::OFTStringList) {
4268 my $ret = GetFieldAsStringList($self, $field);
4269 return wantarray ? @$ret : $ret;
4271 if ($type == $Geo::OGR::OFTBinary) {
4272 return GetFieldAsBinary($self, $field);
4274 if ($type == $Geo::OGR::OFTDate) {
4275 my @ret = GetFieldAsDateTime($self, $field);
4276 # year, month, day, hour, minute, second, timezone
4277 return wantarray ? @ret[0..2] : [@ret[0..2]];
4279 if ($type == $Geo::OGR::OFTTime) {
4280 my @ret = GetFieldAsDateTime($self, $field);
4281 return wantarray ? @ret[3..6] : [@ret[3..6]];
4283 if ($type == $Geo::OGR::OFTDateTime) {
4284 my @ret = GetFieldAsDateTime($self, $field);
4285 return wantarray ? @ret : [@ret];
4287 error("Perl bindings do not support the field type '".i2s(field_type => $type)."'.");
4290 #** @method scalar GetFieldDefn($name)
4292 # Get the definition of a field.
4293 # @param name the name of the field.
4294 # @return a Geo::OGR::FieldDefn object.
4298 my $field = $self->GetFieldIndex(shift);
4299 return $self->GetFieldDefnRef($field);
4302 #** @method list GetFieldNames()
4304 # Get the names of the fields in this feature.
4309 #** @method scalar GetGeomFieldDefn($name)
4311 # Get the definition of a spatial field.
4312 # @param name the name of the spatial field.
4313 # @return a Geo::OGR::GeomFieldDefn object.
4315 sub GetGeomFieldDefn {
4317 my $field = $self->GetGeomFieldIndex(shift);
4318 return $self->GetGeomFieldDefnRef($field);
4321 #** @method GetNativeData()
4326 #** @method GetNativeMediaType()
4328 sub GetNativeMediaType {
4331 #** @method hash reference GetSchema()
4333 # @brief Get the schema of this feature.
4335 # @return the schema as a hash whose keywords are Name, StyleIgnored
4336 # and Fields. Fields is an anonymous array of first non-spatial and
4337 # then spatial field schemas as in Geo::OGR::FieldDefn::Schema() and
4338 # Geo::OGR::GeomFieldDefn::Schema().
4342 error("Schema of a feature cannot be set directly.") if @_;
4343 return $self->GetDefnRef->Schema;
4346 #** @method scalar GetStyleString()
4350 sub GetStyleString {
4353 #** @method IsFieldNull()
4358 #** @method IsFieldSetAndNotNull()
4360 sub IsFieldSetAndNotNull {
4363 #** @method Geo::OGR::Layer Layer()
4365 # @return the layer to which this feature belongs to or undef.
4372 #** @method hash reference Row(%row)
4374 # @note This method discards the data the destination feature (or
4375 # layer) does not support. Changes in data due to differences between
4376 # field types may also occur.
4378 # Get and/or set the data of the feature. The key of the (key,value)
4379 # pairs of the row is the field name. Special field names FID and
4380 # Geometry are used for feature id and (single) geometry
4381 # respectively. The geometry/ies is/are set and get using the
4382 # Geo::OGR::Feature::Geometry method. Field values are set using the
4383 # Geo::OGR::Feature::Field method.
4384 # @param row [optional] feature data in a hash.
4385 # @return a reference to feature data in a hash. Spatial fields are
4386 # returned as Geo::OGR::Geometry objects.
4390 my $nf = $self->GetFieldCount;
4391 my $ngf = $self->GetGeomFieldCount;
4394 if (@_ == 1 and ref($_[0]) eq 'HASH') {
4396 } elsif (@_ and @_ % 2 == 0) {
4399 error('Usage: $feature->Row(%FeatureData).');
4401 $self->SetFID($row{FID}) if defined $row{FID};
4402 #$self->Geometry($schema, $row{Geometry}) if $row{Geometry};
4403 for my $name (keys %row) {
4404 next if $name eq 'FID';
4405 if ($name eq 'Geometry') {
4406 $self->Geometry(0, $row{$name});
4410 for my $i (0..$nf-1) {
4411 if ($self->GetFieldDefnRef($i)->Name eq $name) {
4412 $self->SetField($i, $row{$name});
4418 for my $i (0..$ngf-1) {
4419 if ($self->GetGeomFieldDefnRef($i)->Name eq $name) {
4420 $self->Geometry($i, $row{$name});
4426 carp "Unknown field: '$name'.";
4429 return unless defined wantarray;
4431 for my $i (0..$nf-1) {
4432 my $name = $self->GetFieldDefnRef($i)->Name;
4433 $row{$name} = $self->GetField($i);
4435 for my $i (0..$ngf-1) {
4436 my $name = $self->GetGeomFieldDefnRef($i)->Name || 'Geometry';
4437 $row{$name} = $self->GetGeometry($i);
4439 $row{FID} = $self->GetFID;
4443 #** @method SetFID($id)
4445 # @param id the feature id.
4450 #** @method SetField($name, @Value)
4456 my $field = $self->GetFieldIndex(shift);
4458 if (@_ == 0 or !defined($arg)) {
4459 _UnsetField($self, $field);
4462 $arg = [@_] if @_ > 1;
4463 my $type = $self->GetFieldType($field);
4465 if ($type == $Geo::OGR::OFTIntegerList) {
4466 SetFieldIntegerList($self, $field, $arg);
4468 elsif ($type == $Geo::OGR::OFTInteger64List) {
4469 SetFieldInteger64List($self, $field, $arg);
4471 elsif ($type == $Geo::OGR::OFTRealList) {
4472 SetFieldDoubleList($self, $field, $arg);
4474 elsif ($type == $Geo::OGR::OFTStringList) {
4475 SetFieldStringList($self, $field, $arg);
4477 elsif ($type == $Geo::OGR::OFTDate) {
4478 _SetField($self, $field, @$arg[0..2], 0, 0, 0, 0);
4480 elsif ($type == $Geo::OGR::OFTTime) {
4482 _SetField($self, $field, 0, 0, 0, @$arg[0..3]);
4484 elsif ($type == $Geo::OGR::OFTDateTime) {
4486 _SetField($self, $field, @$arg[0..6]);
4488 elsif ($type == $Geo::OGR::OFTInteger64)
4490 SetFieldInteger64($self, $field, $arg);
4493 $type = i2s(field_type => $type);
4494 my $name = $self->GetFieldDefnRef($field)->Name;
4495 error("'$arg' is not a suitable value for field $name($type).");
4498 if ($type == $Geo::OGR::OFTBinary) {
4499 #$arg = unpack('H*', $arg); # remove when SetFieldBinary is available
4500 $self->SetFieldBinary($field, $arg);
4502 elsif ($type == $Geo::OGR::OFTInteger64)
4504 SetFieldInteger64($self, $field, $arg);
4506 elsif ($type == $Geo::OGR::OFTInteger or $type == $Geo::OGR::OFTReal or $type == $Geo::OGR::OFTString)
4508 _SetField($self, $field, $arg);
4511 $type = i2s(field_type => $type);
4512 my $name = $self->GetFieldDefnRef($field)->Name;
4513 error("'$arg' is not a suitable value for field $name($type).");
4518 #** @method SetFieldNull()
4523 #** @method SetFrom($other, $forgiving = 1, hashref map)
4525 # @param other a Geo::OGR::Feature object
4526 # @param forgiving [optional] set to false if the operation should not
4527 # continue if output fields do not match some of the source fields
4528 # @param map [optional] a mapping from output field indexes to source
4529 # fields, include into the hash all field indexes of this feature
4530 # which should be set
4533 my($self, $other) = @_;
4534 _SetFrom($self, $other), return if @_ <= 2;
4535 my $forgiving = $_[2];
4536 _SetFrom($self, $other, $forgiving), return if @_ <= 3;
4539 for my $i (1..GetFieldCount($self)) {
4540 push @list, ($map->{$i} || -1);
4542 SetFromWithMap($self, $other, 1, \@list);
4545 #** @method SetNativeData()
4550 #** @method SetNativeMediaType()
4552 sub SetNativeMediaType {
4555 #** @method SetStyleString($string)
4559 sub SetStyleString {
4562 #** @method list Tuple(@tuple)
4564 # @note This method discards the data the destination feature (or
4565 # layer) does not support. Changes in data due to differences between
4566 # field types may also occur.
4568 # @note The schema of the tuple needs to be the same as that of the
4571 # Get and/set the data of the feature. The expected data in the tuple
4572 # is ([feature_id,] non-spatial fields, spatial fields). The fields in
4573 # the tuple are in the order they are in the schema. Field values are
4574 # set using the Geo::OGR::Feature::Field method. Geometries are set
4575 # and get using the Geo::OGR::Feature::Geometry method.
4576 # @param tuple [optional] feature data in an array
4577 # @return feature data in an array
4581 my $nf = $self->GetFieldCount;
4582 my $ngf = $self->GetGeomFieldCount;
4584 my $values = ref $_[0] ? $_[0] : \@_;
4586 $FID = shift @$values if @$values == $nf + $ngf + 1;
4587 $self->SetFID($FID) if defined $FID;
4588 if (@$values != $nf + $ngf) {
4590 error("Too many or too few attribute values for a feature (need $n).");
4592 my $index = 0; # index to non-geometry and geometry fields
4593 for my $i (0..$nf-1) {
4594 $self->SetField($i, $values->[$i]);
4596 for my $i (0..$ngf-1) {
4597 $self->Geometry($i, $values->[$nf+$i]);
4600 return unless defined wantarray;
4601 my @ret = ($self->GetFID);
4602 for my $i (0..$nf-1) {
4603 my $v = $self->GetField($i);
4606 for my $i (0..$ngf-1) {
4607 my $v = $self->GetGeometry($i);
4613 #** @method scalar Validate(list flags)
4615 # @param flags one of more of null, geom_type, width,
4616 # allow_null_when_default, or all.
4617 # @exception croaks with an error message if the feature is not valid.
4618 # @return integer denoting the validity of the feature object.
4624 my $f = eval '$Geo::OGR::'.uc($flag);
4627 _Validate($self, $flags);
4630 #** @method Geo::OGR::Feature new(%schema)
4632 # @brief Create a new feature.
4633 # @param Named parameters:
4634 # - \a Schema a reference to a schema hash, or a Geo::OGR::Layer,
4635 # Geo::OGR::Feature, or Geo::OGR::FeatureDefn object.
4636 # - \a Values values for the feature attributes.
4637 # - \a StyleIgnored whether the style can be omitted when fetching
4638 # features. (default is false)
4640 # Schema is a hash with the following keys:
4641 # - \a Name name of the schema (not used).
4642 # - \a Fields a list of Geo::OGR::FieldDefn or Geo::OGR::GeomFieldDefn
4643 # objects or references to hashes from which fields can be created.
4644 # - \a GeometryType the geometry type if the feature has only one spatial field.
4646 # @note Do not mix GeometryType and geometry fields in Fields list.
4647 # @note Old syntax where the argument is a Geo::OGR::FeatureDefn
4648 # object or Schema hash is supported.
4650 # @return a new Geo::OGR::Feature object.
4656 if (ref $_[0] eq 'HASH' && $_[0]->{Schema}) {
4659 $arg = {Schema => $_[0]};
4661 } elsif (@_ and @_ % 2 == 0) {
4663 unless ($arg->{Schema}) {
4665 $arg->{Schema} = \%tmp;
4668 error("The argument must be either a schema or a hash.");
4670 error("Missing schema.") unless $arg->{Schema};
4672 for (ref $arg->{Schema}) {
4673 (/Geo::OGR::Layer$/ || /Geo::OGR::Feature$/) && do {
4674 $defn = $arg->{Schema}->GetDefn;
4677 /Geo::OGR::FeatureDefn$/ && do {
4678 $defn = $arg->{Schema};
4681 $defn = Geo::OGR::FeatureDefn->new($arg->{Schema});
4683 my $self = Geo::OGRc::new_Feature($defn);
4684 error("Feature creation failed.") unless $self;
4686 for (ref $arg->{Values}) {
4688 $self->Tuple($arg->{Values});
4692 $self->Row($arg->{Values});
4695 /Geo::OGR::Feature$/ && do {
4696 $self->Tuple($arg->{Values}->Tuple);
4702 error("Value parameter must be an array, hash, or another feature. Not $_.");
4707 #** @class Geo::OGR::FeatureDefn
4708 # @brief The schema of a feature or a layer.
4709 # @details A FeatureDefn object is a collection of field definition objects. A
4710 # read-only FeatureDefn object can be obtained from a layer
4711 # (Geo::OGR::Layer::GetDefn()) or a feature
4712 # (Geo::OGR::Feature::GetDefn()).
4714 package Geo::OGR::FeatureDefn;
4716 use base qw(Geo::OGR)
4718 #** @method AddField(%params)
4720 # @param params Named parameters to create a new Geo::OGR::FieldDefn
4721 # or Geo::OGR::GeomFieldDefn object.
4725 error("Read-only definition.") if parent($self);
4728 } elsif (ref($_[0]) eq 'HASH') {
4730 } elsif (@_ % 2 == 0) {
4733 $params{Type} //= '';
4734 if (s_exists(field_type => $params{Type})) {
4735 my $fd = Geo::OGR::FieldDefn->new(%params);
4736 $self->AddFieldDefn($fd);
4738 my $fd = Geo::OGR::GeomFieldDefn->new(%params);
4739 $self->AddGeomFieldDefn($fd);
4743 #** @method DeleteField($name)
4745 # @note Currently only geometry fields can be deleted.
4746 # @param index the index of the geometry field to be deleted.
4749 my ($self, $name) = @_;
4750 error("Read-only definition.") if parent($self);
4751 for my $i (0..$self->GetFieldCount-1) {
4752 error("Non-spatial fields cannot be deleted.") if $self->_GetFieldDefn($i)->Name eq $name;
4754 for my $i (0..$self->GetGeomFieldCount-1) {
4755 $self->DeleteGeomFieldDefn($i) if $self->_GetGeomFieldDefn($i)->Name eq $name;
4757 error(2, $name, 'Field');
4760 #** @method Feature()
4764 return parent($self);
4767 #** @method scalar GetFieldDefn($name)
4769 # Get the definition of a field.
4770 # @param name the name of the field.
4771 # @return a Geo::OGR::FieldDefn object.
4775 my $field = $self->GetFieldIndex(shift);
4776 return $self->_GetFieldDefn($field);
4779 #** @method list GetFieldNames()
4781 # The names of the fields in this layer or feature definition.
4782 # @return the list of field names.
4787 for my $i (0..$self->GetFieldCount-1) {
4788 push @names, $self->_GetFieldDefn($i)->Name;
4790 for my $i (0..$self->GetGeomFieldCount-1) {
4791 push @names, $self->_GetGeomFieldDefn($i)->Name;
4796 #** @method scalar GetGeomFieldDefn($name)
4798 # Get the definition of a spatial field.
4799 # @param name the name of the spatial field.
4800 # @return a Geo::OGR::GeomFieldDefn object.
4802 sub GetGeomFieldDefn {
4804 my $field = $self->GetGeomFieldIndex(shift);
4805 return $self->_GetGeomFieldDefn($field);
4808 #** @method scalar GetName()
4810 # @return the name of this layer or feature definition.
4815 #** @method hash reference GetSchema()
4817 # @brief Get the schema of this feature or layer definition.
4819 # @return the schema as a hash whose keywords are Name, StyleIgnored
4820 # and Fields. Fields is an anonymous array of first non-spatial and
4821 # then spatial field schemas as in Geo::OGR::FieldDefn::Schema() and
4822 # Geo::OGR::GeomFieldDefn::Schema().
4826 carp "Schema of a feature definition should not be set directly." if @_;
4827 if (@_ and @_ % 2 == 0) {
4829 if ($schema{Fields}) {
4830 for my $field (@{$schema{Fields}}) {
4831 $self->AddField($field);
4836 $schema{Name} = $self->Name();
4837 $schema{StyleIgnored} = $self->StyleIgnored();
4838 $schema{Fields} = [];
4839 for my $i (0..$self->GetFieldCount-1) {
4840 my $s = $self->_GetFieldDefn($i)->Schema;
4841 push @{$schema{Fields}}, $s;
4843 for my $i (0..$self->GetGeomFieldCount-1) {
4844 my $s = $self->_GetGeomFieldDefn($i)->Schema;
4845 push @{$schema{Fields}}, $s;
4847 return wantarray ? %schema : \%schema;
4850 #** @method IsSame(Geo::OGR::FeatureDefn defn)
4852 # @return true if this definition is similar to the other definition,
4858 #** @method scalar IsStyleIgnored()
4860 # Get the ignore status of style information when fetching features.
4861 # @return the ignore status of style information
4864 sub IsStyleIgnored {
4867 #** @method SetStyleIgnored($IgnoreState)
4869 # Set the ignore status of style information when fetching features.
4872 sub SetStyleIgnored {
4875 #** @method Geo::OGR::FeatureDefn new(%schema)
4877 # Creates a new layer or feature definition. The new definition is
4878 # either initialized to the given schema or it will contain no
4879 # non-spatial fields and one spatial field, whose Name is '' and
4880 # GeometryType is 'Unknown' or the value of the named parameter
4882 # @param schema [optional] The schema for the new feature definition,
4883 # as in Geo::OGR::FeatureDefn::Schema().
4884 # @return a Geo::OGR::FeatureDefn object
4888 # $fd = Geo::OGR::FeatureDefn->new(
4890 # Fields => [{ Name => 'field1', Type => 'String' },
4891 # { Name => 'geom', GeometryType => 'Point' }] );
4897 if (@_ == 1 and ref($_[0]) eq 'HASH') {
4899 } elsif (@_ and @_ % 2 == 0) {
4902 my $fields = $schema{Fields};
4903 error("The 'Fields' argument must be an array reference.") if $fields and ref($fields) ne 'ARRAY';
4904 $schema{Name} //= '';
4905 my $self = Geo::OGRc::new_FeatureDefn($schema{Name});
4907 my $gt = $schema{GeometryType};
4909 $self->GeometryType($gt);
4911 $self->DeleteGeomFieldDefn(0);
4913 $self->StyleIgnored($schema{StyleIgnored}) if exists $schema{StyleIgnored};
4914 for my $fd (@{$fields}) {
4916 if (ref($fd) eq 'HASH') {
4917 # if Name and Type are missing, assume Name => Type
4918 if (!(exists $fd->{Name} && exists $fd->{Type})) {
4919 for my $key (sort keys %$fd) {
4920 if (s_exists(field_type => $fd->{$key}) ||
4921 s_exists(geometry_type => $fd->{$key}))
4924 $fd->{Type} = $fd->{$key};
4930 if ($fd->{GeometryType} or ($fd->{Type} && s_exists(geometry_type => $fd->{Type}))) {
4931 $d = Geo::OGR::GeomFieldDefn->new(%$fd);
4933 $d = Geo::OGR::FieldDefn->new(%$fd);
4936 if (blessed($d) and $d->isa('Geo::OGR::FieldDefn')) {
4937 AddFieldDefn($self, $d);
4938 } elsif (blessed($d) and $d->isa('Geo::OGR::GeomFieldDefn')) {
4939 error("Do not mix GeometryType and geometry fields in Fields.") if $gt;
4940 AddGeomFieldDefn($self, $d);
4942 error("Item in field list does not define a field.");
4948 #** @class Geo::OGR::FieldDefn
4949 # @brief A definition of a non-spatial attribute.
4952 package Geo::OGR::FieldDefn;
4954 use base qw(Geo::OGR)
4956 #** @method scalar Default($value)
4958 # Get or set the default value for this field.
4959 # @note a.k.a. GetDefault and SetDefault
4960 # @param value [optional]
4961 # @return the default value of this field in non-void context.
4965 SetDefault($self, $_[0]) if @_;
4966 GetDefault($self) if defined wantarray;
4969 #** @method GetSchema()
4974 #** @method scalar Ignored($ignore)
4976 # Get and/or set the ignore status (whether this field should be
4977 # omitted when fetching features) of this field.
4978 # @note a.k.a. IsIgnored, SetIgnored
4979 # @param ignore [optional]
4980 # @return the ignore status of this field in non-void context.
4985 SetIgnored($self, $_[0]) if @_;
4986 IsIgnored($self) if defined wantarray;
4989 #** @method IsDefaultDriverSpecific()
4991 sub IsDefaultDriverSpecific {
4994 #** @method scalar Justify($justify)
4996 # Get and/or set the justification of this field.
4997 # @note a.k.a. GetJustify, SetJustify
4998 # @param justify [optional] One of field justify types (Geo::OGR::FieldDefn::JustifyValues).
4999 # @return the justify value of this field in non-void context.
5002 my($self, $justify) = @_;
5003 if (defined $justify) {
5004 $justify = s2i(justify => $justify);
5005 SetJustify($self, $justify);
5007 return i2s(justify => GetJustify($self)) if defined wantarray;
5010 #** @method list JustifyValues()
5011 # Package subroutine.
5012 # Justify values supported by GDAL. Current list is
5013 # Left, Right, and Undefined.
5019 #** @method scalar Name($name)
5021 # Get and/or set the name of the field.
5022 # @note a.k.a. GetName, GetNameRef, SetName
5023 # @param name [optional]
5024 # @return the name in non-void context
5028 SetName($self, $_[0]) if @_;
5029 GetName($self) if defined wantarray;
5032 #** @method scalar Nullable($nullable)
5034 # Get or set the nullable constraint for this field.
5035 # @note a.k.a. IsNullable and SetNullable
5036 # @param nullable [optional]
5037 # @return the nullable value of this field in non-void context.
5041 SetNullable($self, $_[0]) if @_;
5042 IsNullable($self) if defined wantarray;
5045 #** @method scalar Precision($precision)
5047 # Get and/or set the precision of this field.
5048 # @note a.k.a. GetPrecision, SetPrecision
5049 # @param precision [optional]
5050 # @return the precision of this field in non-void context.
5054 SetPrecision($self, $_[0]) if @_;
5055 GetPrecision($self) if defined wantarray;
5058 #** @method hash reference Schema(%params)
5060 # Get the schema or set parts of the schema
5061 # @param params [optional] as those in Geo::OGR::FieldDefn::new.
5062 # @return a reference to a hash whose keys are as those in Geo::OGR::FieldDefn::new.
5067 my $params = @_ % 2 == 0 ? {@_} : shift;
5068 for my $key (keys %SCHEMA_KEYS) {
5069 next unless exists $params->{$key};
5070 eval "\$self->$key(\$params->{$key})";
5071 confess(last_error()) if $@;
5074 return unless defined wantarray;
5076 for my $key (keys %SCHEMA_KEYS) {
5077 $schema{$key} = eval '$self->'.$key;
5079 return wantarray ? %schema : \%schema;
5082 #** @method SetSchema()
5087 #** @method scalar SubType($SubType)
5089 # @note a.k.a. GetSubType, SetSubType
5090 # @param SubType [optional] One of field sub types (Geo::OGR::FieldDefn::SubTypes).
5091 # @return the sub type of this field in non-void context.
5094 my($self, $subtype) = @_;
5095 if (defined $subtype) {
5096 $subtype = s2i(field_subtype => $subtype);
5097 SetSubType($self, $subtype);
5099 return i2s(field_subtype => GetSubType($self)) if defined wantarray;
5102 #** @method SubTypes()
5108 #** @method scalar Type($type)
5110 # Get and/or set the type of the field.
5111 # @note a.k.a. GetFieldTypeName, GetTypeName, GetType, SetType
5112 # @param type [optional] One of field types (Geo::OGR::FieldDefn::Types).
5113 # @return one of field types in non-void context.
5116 my($self, $type) = @_;
5117 if (defined $type) {
5118 $type = s2i(field_type => $type);
5119 SetType($self, $type);
5121 return i2s(field_type => GetType($self)) if defined wantarray;
5124 #** @method list Types()
5125 # Package subroutine.
5126 # Field types supported by GDAL. Current list is
5127 # Binary, Date, DateTime, Integer, Integer64, Integer64List, IntegerList, Real, RealList, String, StringList, Time, WideString, and WideStringList.
5128 # (However, WideString is not supported.)
5134 #** @method scalar Width($width)
5136 # Get and/or set the field width.
5137 # @note a.k.a. GetWidth, SetWidth
5138 # @param width [optional]
5139 # @return the width of this field in non-void context.
5143 SetWidth($self, $_[0]) if @_;
5144 GetWidth($self) if defined wantarray;
5147 #** @method Geo::OGR::FieldDefn new(%params)
5149 # @brief Create a new field definition.
5151 # @param Named parameters:
5152 # - \a Name Field name (default is 'unnamed').
5153 # - \a Type Field type, one of Geo::OGR::FieldDefn::Types (default is 'String').
5154 # - \a SubType Field sub type, one of Geo::OGR::FieldDefn::SubTypes.
5155 # - \a Justify Justify value, one of Geo::OGR::FieldDefn::JustifyValues
5158 # - \a Nullable (default is true)
5160 # - \a Ignored (default is false)
5162 # @note Simplified parameters Name => 'Type' are also supported.
5164 # @return a new Geo::OGR::FieldDefn object
5168 my $params = {Name => 'unnamed', Type => 'String'};
5170 } elsif (@_ == 1 and not ref $_[0]) {
5171 $params->{Name} = shift;
5172 } elsif (@_ == 2 and not $Geo::OGR::FieldDefn::SCHEMA_KEYS{$_[0]}) {
5173 $params->{Name} = shift;
5174 $params->{Type} = shift;
5176 my $tmp = @_ % 2 == 0 ? {@_} : shift;
5177 for my $key (keys %$tmp) {
5178 if ($Geo::OGR::FieldDefn::SCHEMA_KEYS{$key}) {
5179 $params->{$key} = $tmp->{$key};
5181 carp "Unknown parameter: '$key'." if $key ne 'Index';
5185 $params->{Type} = s2i(field_type => $params->{Type});
5186 my $self = Geo::OGRc::new_FieldDefn($params->{Name}, $params->{Type});
5188 delete $params->{Name};
5189 delete $params->{Type};
5190 $self->Schema($params);
5194 #** @class Geo::OGR::GeomFieldDefn
5195 # @brief A definition of a spatial attribute.
5198 package Geo::OGR::GeomFieldDefn;
5200 use base qw(Geo::OGR)
5202 #** @method scalar GeometryType($type)
5204 # @note a.k.a. GetType, SetType
5205 # @return the geometry type of the field.
5210 #** @method GetSchema()
5215 #** @method scalar Ignored($ignore)
5217 # @note a.k.a. IsIgnored, SetIgnored
5218 # @return the ignore status of the field.
5222 SetIgnored($self, $_[0]) if @_;
5223 IsIgnored($self) if defined wantarray;
5226 #** @method scalar Name($name)
5228 # @note a.k.a. GetName, GetNameRef, SetName
5229 # @return the name of the field.
5233 SetName($self, $_[0]) if @_;
5234 GetName($self) if defined wantarray;
5237 #** @method scalar Nullable($nullable)
5239 # @note a.k.a. IsNullable, SetNullable
5240 # @return the nullable status of the field.
5244 SetNullable($self, $_[0]) if @_;
5245 IsNullable($self) if defined wantarray;
5248 #** @method hash reference Schema(%params)
5250 # Get the schema or set parts of the schema.
5251 # @param params [optional] as those in Geo::OGR::GeomFieldDefn::new.
5252 # @return a reference to a hash whose keys are as those in Geo::OGR::GeomFieldDefn::new.
5257 my $params = @_ % 2 == 0 ? {@_} : shift;
5258 for my $key (keys %SCHEMA_KEYS) {
5259 next unless exists $params->{$key};
5260 eval "\$self->$key(\$params->{$key})";
5261 confess last_error() if $@;
5264 return unless defined wantarray;
5266 for my $key (keys %SCHEMA_KEYS) {
5267 $schema{$key} = eval '$self->'.$key;
5269 return wantarray ? %schema : \%schema;
5272 #** @method SetSchema()
5277 #** @method scalar SpatialReference($sr)
5279 # @note a.k.a. GetSpatialRef, SetSpatialRef
5280 # @return the spatial reference of the field as a Geo::OSR::SpatialReference object.
5282 sub SpatialReference {
5284 SetSpatialRef($self, $_[0]) if @_;
5285 GetSpatialRef($self) if defined wantarray;
5290 # @return the type of this geometry field. One of Geo::OGR::GeomFieldDefn::Types
5293 my($self, $type) = @_;
5294 if (defined $type) {
5295 $type = s2i(geometry_type => $type);
5296 SetType($self, $type);
5298 i2s(geometry_type => GetType($self)) if defined wantarray;
5302 # Package subroutine.
5303 # @return a list of all geometry types, currently:
5304 # CircularString, CircularStringM, CircularStringZ, CircularStringZM, CompoundCurve, CompoundCurveM, CompoundCurveZ, CompoundCurveZM, Curve, CurveM, CurvePolygon, CurvePolygonM, CurvePolygonZ, CurvePolygonZM, CurveZ, CurveZM, GeometryCollection, GeometryCollection25D, GeometryCollectionM, GeometryCollectionZM, LineString, LineString25D, LineStringM, LineStringZM, LinearRing, MultiCurve, MultiCurveM, MultiCurveZ, MultiCurveZM, MultiLineString, MultiLineString25D, MultiLineStringM, MultiLineStringZM, MultiPoint, MultiPoint25D, MultiPointM, MultiPointZM, MultiPolygon, MultiPolygon25D, MultiPolygonM, MultiPolygonZM, MultiSurface, MultiSurfaceM, MultiSurfaceZ, MultiSurfaceZM, None, Point, Point25D, PointM, PointZM, Polygon, Polygon25D, PolygonM, PolygonZM, PolyhedralSurface, PolyhedralSurfaceM, PolyhedralSurfaceZ, PolyhedralSurfaceZM, Surface, SurfaceM, SurfaceZ, SurfaceZM, TIN, TINM, TINZ, TINZM, Triangle, TriangleM, TriangleZ, TriangleZM, and Unknown.
5307 return Geo::OGR::Geometry::GeometryTypes();
5310 #** @method Geo::OGR::GeomFieldDefn new(%params)
5312 # @brief Create a new spatial field definition.
5314 # @param params one or more of:
5315 # - \a Name name for the field (default is 'geom').
5316 # - \a GeometryType type for the field type, one of Geo::OGR::GeomFieldDefn::Types (default is 'Unknown').
5317 # - \a SpatialReference a Geo::OSR::SpatialReference object.
5318 # - \a Nullable (default is true)
5319 # - \a Ignored (default is false)
5321 # @note Simplified parameters <name> => <type> is also supported.
5323 # @return a new Geo::OGR::GeomFieldDefn object
5327 my $params = {Name => 'geom', Type => 'Unknown'};
5330 $params->{Name} = shift;
5331 } elsif (@_ == 2 and not $Geo::OGR::GeomFieldDefn::SCHEMA_KEYS{$_[0]}) {
5332 $params->{Name} = shift;
5333 $params->{Type} = shift;
5335 my $tmp = @_ % 2 == 0 ? {@_} : shift;
5336 for my $key (keys %$tmp) {
5337 if ($Geo::OGR::GeomFieldDefn::SCHEMA_KEYS{$key}) {
5338 $params->{$key} = $tmp->{$key};
5340 carp "Unknown parameter: '$key'." if $key ne 'Index' && $key ne 'GeometryType';
5343 $params->{Type} //= $tmp->{GeometryType};
5345 $params->{Type} = s2i(geometry_type => $params->{Type});
5346 my $self = Geo::OGRc::new_GeomFieldDefn($params->{Name}, $params->{Type});
5348 delete $params->{Name};
5349 delete $params->{Type};
5350 $self->Schema($params);
5354 #** @class Geo::OGR::Geometry
5355 # @brief Spatial data.
5356 # @details A geometry is spatial data (coordinate values, and a reference to a
5357 # spatial reference system) organized into one of the geometry
5358 # types. Geometries can be created from several type of data including
5359 # a Perl data structure. There are several methods, which modify,
5360 # compare, test, or compute values from geometries.
5361 # @note Most spatial analysis methods require <a
5362 # href="http://geos.osgeo.org/doxygen/">GEOS</a> to work rigorously.
5364 package Geo::OGR::Geometry;
5366 use base qw(Geo::OGR)
5368 #** @method AddGeometry($other)
5370 # Add a copy of another geometry to a geometry collection
5371 # @param other a Geo::OGR::Geometry object
5376 #** @method AddGeometryDirectly($other)
5378 # @param other a Geo::OGR::Geometry object
5380 sub AddGeometryDirectly {
5383 #** @method AddPoint($x, $y, $z)
5385 # Set the data of a point or add a point to a line string. Consider
5386 # using Geo::OGR::Geometry::Points. Note that the coordinate
5387 # dimension is automatically upgraded to 25D (3) if z is given.
5390 # @param z [optional]
5391 # Calls internally the 2D or 3D version depending on the number of parameters.
5395 my $t = $self->GetGeometryType;
5396 my $has_z = HasZ($t);
5397 my $has_m = HasM($t);
5398 if (!$has_z && !$has_m) {
5399 $self->AddPoint_2D(@_[0..1]);
5400 } elsif ($has_z && !$has_m) {
5401 $self->AddPoint_3D(@_[0..2]);
5402 } elsif (!$has_z && $has_m) {
5403 $self->AddPointM(@_[0..2]);
5405 $self->AddPointZM(@_[0..3]);
5409 #** @method AddPointM()
5414 #** @method AddPointZM()
5419 #** @method AddPoint_2D($x, $y)
5421 # Set the data of a point or add a point to a line string. Consider
5422 # using Geo::OGR::Geometry::Points.
5429 #** @method AddPoint_3D($x, $y, $z)
5431 # Set the data of a point or add a point to a line string. Note that
5432 # the coordinate dimension is automatically upgraded to 25D (3). Consider
5433 # using Geo::OGR::Geometry::Points.
5441 #** @method Geo::OGR::Geometry ApproximateArcAngles(%params)
5442 # Package subroutine.
5443 # Create a line string, which approximates an arc.
5444 # @note All angles are in degrees.
5446 # @param %params Named parameters:
5447 # - \a Center center point (default is [0, 0, 0])
5448 # - \a PrimaryRadius default is 1.
5449 # - \a SecondaryAxis default is 1.
5450 # - \a Rotation default is 0.
5451 # - \a StartAngle default is 0.
5452 # - \a EndAngle default is 360.
5453 # - \a MaxAngleStepSizeDegrees default is 4.
5454 # @return a new Geo::OGR::Geometry object.
5456 sub ApproximateArcAngles {
5458 my %default = ( Center => [0,0,0],
5464 MaxAngleStepSizeDegrees => 4
5466 for my $p (keys %p) {
5467 if (exists $default{$p}) {
5468 $p{$p} //= $default{$p};
5470 carp "Unknown parameter: '$p'.";
5473 for my $p (keys %default) {
5474 $p{$p} //= $default{$p};
5476 error("Usage: Center => [x,y,z].") unless ref($p{Center}) eq 'ARRAY';
5478 $p{Center}->[$i] //= 0;
5480 return Geo::OGR::ApproximateArcAngles($p{Center}->[0], $p{Center}->[1], $p{Center}->[2], $p{PrimaryRadius}, $p{SecondaryAxis}, $p{Rotation}, $p{StartAngle}, $p{EndAngle}, $p{MaxAngleStepSizeDegrees});
5483 #** @method scalar Area()
5485 # @note a.k.a. GetArea
5486 # @return the area of the polygon or multipolygon
5491 #** @method scalar As(%params)
5493 # Export the geometry into a known format.
5495 # @param params Named parameters:
5496 # - \a Format One of
5497 # - \a WKT Well Known Text.
5498 # - <em>ISO WKT</em>
5499 # - \a Text Same as WKT.
5500 # - \a WKB Well Known Binary.
5501 # - <em>ISO WKB</em>
5502 # - \a Binary Same as WKB.
5507 # - \a ByteOrder Byte order for binary formats. Default is 'XDR'.
5508 # - \a SRID Spatial reference id for HEXEWKB.
5509 # - \a Options GML generation options.
5510 # - \a AltitudeMode For KML.
5512 # @return the geometry in a given format.
5516 my $p = named_parameters(\@_, Format => undef, ByteOrder => 'XDR', SRID => undef, Options => undef, AltitudeMode => undef);
5517 my $f = $p->{format};
5518 if ($f =~ /text/i) {
5519 return $self->AsText;
5520 } elsif ($f =~ /wkt/i) {
5522 return $self->ExportToIsoWkt;
5524 return $self->AsText;
5526 } elsif ($f =~ /binary/i) {
5527 return $self->ExportToWkb($p->{byteorder});
5528 } elsif ($f =~ /wkb/i) {
5530 $p->{byteorder} = s2i(byte_order => $p->{byteorder});
5531 return $self->ExportToIsoWkb($p->{byteorder});
5532 } elsif ($f =~ /ewkb/i) {
5533 return $self->AsHEXEWKB($p->{srid});
5534 } elsif ($f =~ /hex/i) {
5535 return $self->AsHEXWKB;
5537 return $self->ExportToWkb($p->{byteorder});
5539 } elsif ($f =~ /gml/i) {
5540 return $self->ExportToGML($p->{options});
5541 } elsif ($f =~ /kml/i) {
5542 return $self->ExportToKML($p->{altitudemode});
5543 } elsif ($f =~ /json/i) {
5544 return $self->AsJSON;
5546 error(1, $f, map {$_=>1} qw/Text WKT ISO_WKT ISO_WKB HEX_WKB HEX_EWKB Binary GML KML JSON/);
5550 #** @method scalar AsBinary()
5552 # Export the geometry into WKB.
5553 # @sa Geo::OGR::Geometry::As
5554 # @return the geometry as WKB.
5559 #** @method scalar AsText()
5561 # Export the geometry into WKT.
5562 # @sa Geo::OGR::Geometry::As
5563 # @return the geometry as WKT.
5568 #** @method AssignSpatialReference($srs)
5570 # @param srs a Geo::OSR::SpatialReference object
5572 sub AssignSpatialReference {
5575 #** @method Geo::OGR::Geometry Boundary()
5577 # @note a.k.a. GetBoundary
5578 # @return the boundary of this geometry as a geometry
5584 #** @method Geo::OGR::Geometry Buffer($distance, $quadsecs = 30)
5588 # @return a new Geo::OGR::Geometry object
5593 #** @method Geo::OGR::Geometry BuildPolygonFromEdges($BestEffort = 0, $AutoClose = 0, $Tolerance = 0)
5595 # Attempt to create a polygon from a collection of lines or from a multilinestring.
5596 # @param BestEffort For future
5597 # @param AutoClose Assure the first and last points of rings are same.
5598 # @param Tolerance Snap distance.
5599 # @exception Several possibilities, some are reported, some are general errors.
5600 # @return a new Geo::OGR::Geometry object (Polygon)
5602 sub BuildPolygonFromEdges {
5605 #** @method list ByteOrders()
5606 # Package subroutine.
5607 # Same as Geo::OGR::ByteOrders
5610 return @BYTE_ORDER_TYPES;
5613 #** @method Geo::OGR::Geometry Centroid()
5615 # @return a new Geo::OGR::Geometry object
5621 #** @method Geo::OGR::Geometry Clone()
5623 # @return a new Geo::OGR::Geometry object
5628 #** @method CloseRings()
5634 #** @method Geo::OGR::Geometry Collect(@geometries)
5636 # Create a geometrycollection from this and possibly other geometries.
5637 # @param geometries [optional] More geometries to add to the collection.
5638 # @return a new Geo::OGR::Geometry object of type geometrycollection.
5643 #** @method scalar Contains($other)
5645 # @param other a Geo::OGR::Geometry object
5646 # @return true if this geometry contains the other geometry, false otherwise
5651 #** @method Geo::OGR::Geometry ConvexHull()
5653 # @return a new Geo::OGR::Geometry object
5658 #** @method scalar CoordinateDimension($dimension)
5660 # @param dimension [optional]
5663 sub CoordinateDimension {
5665 SetCoordinateDimension($self, $_[0]) if @_;
5666 GetCoordinateDimension($self) if defined wantarray;
5669 #** @method scalar Crosses($other)
5671 # @param other a Geo::OGR::Geometry object
5672 # @return true if this geometry crosses the other geometry, false otherwise
5677 #** @method DelaunayTriangulation()
5679 sub DelaunayTriangulation {
5682 #** @method Geo::OGR::Geometry Difference($other)
5684 # @param other a Geo::OGR::Geometry object
5685 # @return a new Geo::OGR::Geometry object
5690 #** @method scalar Disjoint($other)
5692 # @param other a Geo::OGR::Geometry object
5693 # @return true if this geometry is disjoint from the other geometry, false otherwise
5698 #** @method list Dissolve()
5700 # Dissolve a geometrycollection into separate geometries.
5701 # @return a list of new Geo::OGR::Geometry objects cloned from the collection.
5706 my $n = $self->GetGeometryCount;
5708 for my $i (0..$n-1) {
5709 push @c, $self->GetGeometryRef($i)->Clone;
5717 #** @method scalar Distance($other)
5719 # @param other a Geo::OGR::Geometry object
5720 # @return the distance to the other geometry
5725 #** @method Distance3D()
5732 # Clear geometry data, i.e., remove all points, or, for a point, set
5733 # the coordinate dimension as zero.
5738 #** @method scalar Equals($other)
5740 # @note a.k.a. Equal (deprecated)
5741 # @param other a Geo::OGR::Geometry object
5742 # @return true if this geometry is equivalent to the other geometry, false otherwise
5747 #** @method Extent()
5751 return Geo::GDAL::Extent->new($self->GetEnvelope);
5754 #** @method Feature()
5761 #** @method FlattenTo2D()
5767 #** @method Geo::OGR::Geometry ForceTo($type, ref options)
5769 # Attempt to make a geometry of type 'type' out of this geometry.
5770 # @param type target geometry type. One of Geo::OGR::GeometryTypes.
5771 # @param options not used currently.
5772 # @return a new Geo::OGR::Geometry object.
5777 $type = s2i(geometry_type => $type);
5779 $self = Geo::OGR::ForceTo($self, $type, @_);
5781 confess last_error() if $@;
5785 #** @method Geo::OGR::Geometry ForceToCollection(@geometries)
5787 # Create a geometrycollection from the geometry.
5788 # @param geometries [optional] More geometries to add to the collection.
5789 # @return a new Geo::OGR::Geometry object of type geometrycollection.
5791 sub ForceToCollection {
5792 my $self = Geo::OGR::Geometry->new(GeometryType => 'GeometryCollection');
5794 $self->AddGeometry($g);
5799 #** @method Geo::OGR::Geometry ForceToLineString()
5801 # Attempt to create a line string from this geometry.
5802 # @return a new Geo::OGR::Geometry object.
5804 sub ForceToLineString {
5806 return Geo::OGR::ForceToLineString($self);
5809 #** @method Geo::OGR::Geometry ForceToMultiLineString(@linestrings)
5811 # Attempt to create a multilinestring from the geometry, which must be a linestring.
5812 # @param linestrings [optional] More linestrings to add to the collection.
5813 # @return a new Geo::OGR::Geometry object of type multilinestring.
5815 sub ForceToMultiLineString {
5817 $self = Geo::OGR::ForceToMultiLineString($self);
5819 $self->AddGeometry($g);
5824 #** @method Geo::OGR::Geometry ForceToMultiPoint(@points)
5826 # Attempt to create a multipoint from the geometry, which must be a point.
5827 # @param points [optional] More points to add to the collection.
5828 # @return a new Geo::OGR::Geometry object of type multipoint.
5830 sub ForceToMultiPoint {
5832 $self = Geo::OGR::ForceToMultiPoint($self);
5834 $self->AddGeometry($g);
5839 #** @method Geo::OGR::Geometry ForceToMultiPolygon(@polygons)
5841 # Attempt to create a multipolygon from the geometry, which must be a polygon.
5842 # @param polygons [optional] More polygons to add to the collection.
5843 # @return a new Geo::OGR::Geometry object of type multipolygon.
5845 sub ForceToMultiPolygon {
5847 $self = Geo::OGR::ForceToMultiPolygon($self);
5849 $self->AddGeometry($g);
5854 #** @method Geo::OGR::Geometry ForceToPolygon()
5856 # Attempt to create a polygon from this geometry.
5857 # @exception None reported. If this method fails, just a copy is returned.
5858 # @return a new Geo::OGR::Geometry object.
5860 sub ForceToPolygon {
5863 #** @method scalar Geometry($n)
5865 # Return the n:th (note zero-based index) element in this geometry or
5866 # geometry in this collection.
5867 # @note a.k.a. GetGeometryRef
5868 # @param n index to the geometry, which is a part of this geometry
5869 # @return a new Geo::OGR::Geometry object whose data is a part of the
5870 # parent geometry (this geometry is kept alive while the returned
5876 #** @method scalar GeometryCount()
5878 # Return the number of elements in this geometry or geometries in this collection.
5879 # @note a.k.a. GetGeometryCount
5880 # @return an integer
5885 #** @method scalar GeometryType()
5888 # @note The deprecated method GetGeometryType returns the
5889 # type as an integer
5891 # @return the geometry type of this geometry (one of Geo::OGR::GeometryTypes).
5895 return i2s(geometry_type => $self->GetGeometryType);
5898 #** @method list GeometryTypes()
5899 # Package subroutine.
5900 # Same as Geo::OGR::GeometryTypes
5903 return @GEOMETRY_TYPES;
5906 #** @method scalar GetCoordinateDimension()
5908 # @return an integer
5910 sub GetCoordinateDimension {
5913 #** @method GetCurveGeometry()
5915 sub GetCurveGeometry {
5918 #** @method scalar GetDimension()
5920 # @return 0, 1, or 2
5925 #** @method list GetEnvelope()
5927 # @note In scalar context returns a reference to an anonymous array
5928 # containing the envelope.
5929 # @return the envelope ($minx, $maxx, $miny, $maxy)
5934 #** @method list GetEnvelope3D()
5936 # @note In scalar context returns a reference to an anonymous array
5937 # containing the envelope.
5938 # @return the 3-D envelope ($minx, $maxx, $miny, $maxy, $minz, $maxz)
5944 #** @method scalar GetGeometryRef($index)
5946 # @deprecated Use Geo::OGR::Geometry
5948 sub GetGeometryRef {
5949 my ($self, $i) = @_;
5950 my $ref = $self->_GetGeometryRef($i);
5955 #** @method GetLinearGeometry()
5957 sub GetLinearGeometry {
5965 #** @method list GetPoint($index = 0)
5968 # @return (x,y) or a list with more coordinates
5973 my $t = $self->GetGeometryType;
5974 my $has_z = HasZ($t);
5975 my $has_m = HasM($t);
5977 if (!$has_z && !$has_m) {
5978 $point = $self->GetPoint_2D($i);
5979 } elsif ($has_z && !$has_m) {
5980 $point = $self->GetPoint_3D($i);
5981 } elsif (!$has_z && $has_m) {
5982 $point = $self->GetPointZM($i);
5983 @$point = ($point->[0], $point->[1], $point->[3]);
5985 $point = $self->GetPointZM($i);
5987 return wantarray ? @$point : $point;
5990 #** @method scalar GetPointCount()
5992 # @return an integer
5997 #** @method GetPointZM()
6002 #** @method scalar GetPoint_2D($index = 0)
6005 # @return (x,y) or a list with more coordinates
6010 #** @method scalar GetPoint_3D($index = 0)
6013 # @return (x,y) or a list with more coordinates
6018 #** @method Geo::OSR::SpatialReference GetSpatialReference()
6020 # @return a new Geo::OSR::SpatialReference object
6022 sub GetSpatialReference {
6025 #** @method scalar GetX($index = 0)
6033 #** @method scalar GetY($index = 0)
6041 #** @method scalar GetZ($index = 0)
6049 #** @method HasCurveGeometry()
6051 sub HasCurveGeometry {
6054 #** @method Geo::OGR::Geometry Intersection($other)
6056 # @param other a Geo::OGR::Geometry object
6057 # @return a new Geo::OGR::Geometry object
6062 #** @method scalar Intersects($other)
6064 # @note a.k.a. Intersect (deprecated)
6065 # @param other a Geo::OGR::Geometry object
6066 # @return true if this geometry intersects with the other geometry, false otherwise
6076 #** @method scalar IsEmpty()
6078 # Test whether the geometry is empty (has no points, or, for a point,
6079 # has coordinate dimension of zero).
6085 #** @method IsMeasured()
6090 #** @method scalar IsRing()
6092 # Test if the geometry is a ring. Requires GEOS in GDAL.
6098 #** @method scalar IsSimple()
6100 # Test the simplicity of the geometry (OGC sense). Requires GEOS in GDAL.
6106 #** @method scalar IsValid()
6108 # Test the validity of the geometry (OGC sense). Requires GEOS in GDAL.
6114 #** @method scalar Length()
6116 # @return the length of the linestring
6121 #** @method Move($dx, $dy, $dz)
6123 # Move every point of the object as defined by the parameters.
6126 # @param dz [optional]
6131 #** @method scalar Overlaps($other)
6133 # @param other a Geo::OGR::Geometry object
6134 # @return true if this geometry overlaps the other geometry, false otherwise
6139 #** @method list Point($index, $x, $y, $z)
6141 # Get or set the point
6142 # @param index The index of the point. Optional (ignored if given) for
6143 # Point and Point25D geometries.
6144 # @param x [optional]
6145 # @param y [optional]
6146 # @param z [optional]
6153 my $t = $self->GetGeometryType;
6155 if (Flatten($t) == $Geo::OGR::wkbPoint) {
6156 my $has_z = HasZ($t);
6157 my $has_m = HasM($t);
6158 if (!$has_z && !$has_m) {
6161 } elsif ($has_z || $has_m) {
6169 $i = shift unless defined $i;
6170 $self->SetPoint($i, @_);
6172 return unless defined wantarray;
6173 my $point = $self->GetPoint;
6174 return wantarray ? @$point : $point;
6177 #** @method PointOnSurface()
6179 sub PointOnSurface {
6182 #** @method array reference Points(arrayref points)
6184 # Get or set the points of the geometry. The points (vertices) are
6185 # stored in obvious lists of lists. When setting, the geometry is
6186 # first emptied. The method uses internally either AddPoint_2D or
6187 # AddPoint_3D depending on the coordinate dimension of the input data.
6189 # @note The same structure may represent different geometries
6190 # depending on the actual geometry type of the object.
6192 # @param points [optional] A reference to an array. A point is a reference to an
6193 # array of numbers, a linestring or a ring is a reference to an array of points,
6194 # a polygon is a reference to an array of rings, etc.
6196 # @return A reference to an array.
6200 my $t = $self->GetGeometryType;
6201 my $has_z = HasZ($t);
6202 my $has_m = HasM($t);
6204 $postfix .= 'Z' if HasZ($t);
6205 $postfix .= 'M' if HasM($t);
6206 $t = i2s(geometry_type => Flatten($t));
6210 if ($t eq 'Unknown' or $t eq 'None' or $t eq 'GeometryCollection') {
6211 error("Can't set points of a geometry of type '$t'.");
6212 } elsif ($t eq 'Point') {
6213 # support both "Point" as a list of one point and one point
6214 if (ref($points->[0])) {
6215 $self->AddPoint(@{$points->[0]});
6217 $self->AddPoint(@$points);
6219 } elsif ($t eq 'LineString' or $t eq 'LinearRing' or $t eq 'CircularString') {
6220 for my $p (@$points) {
6221 $self->AddPoint(@$p);
6223 } elsif ($t eq 'Polygon') {
6224 for my $r (@$points) {
6225 my $ring = Geo::OGR::Geometry->new('LinearRing');
6226 $ring->Set3D(1) if $has_z;
6227 $ring->SetMeasured(1) if $has_m;
6229 $self->AddGeometryDirectly($ring);
6231 } elsif ($t eq 'MultiPoint') {
6232 for my $p (@$points) {
6233 my $point = Geo::OGR::Geometry->new('Point'.$postfix);
6235 $self->AddGeometryDirectly($point);
6237 } elsif ($t eq 'MultiLineString') {
6238 for my $l (@$points) {
6239 my $linestring = Geo::OGR::Geometry->new('LineString'.$postfix);
6240 $linestring->Points($l);
6241 $self->AddGeometryDirectly($linestring);
6243 } elsif ($t eq 'MultiPolygon') {
6244 for my $p (@$points) {
6245 my $polygon = Geo::OGR::Geometry->new('Polygon'.$postfix);
6246 $polygon->Points($p);
6247 $self->AddGeometryDirectly($polygon);
6251 return unless defined wantarray;
6252 $self->_GetPoints();
6255 #** @method Polygonize()
6260 #** @method RemoveGeometry()
6262 sub RemoveGeometry {
6265 #** @method Segmentize($MaxLength)
6267 # Modify the geometry such it has no segment longer than the given length.
6268 # @param MaxLength the given length
6278 #** @method SetCoordinateDimension($dimension)
6282 sub SetCoordinateDimension {
6285 #** @method SetMeasured()
6290 #** @method SetPoint($index, $x, $y, $z)
6292 # Set the data of a point or a line string. Note that the coordinate
6293 # dimension is automatically upgraded to 25D (3) if z is given.
6297 # @param z [optional]
6301 my $t = $self->GetGeometryType;
6302 my $has_z = HasZ($t);
6303 my $has_m = HasM($t);
6304 if (!$has_z && !$has_m) {
6305 $self->SetPoint_2D(@_[0..2]);
6306 } elsif ($has_z && !$has_m) {
6307 $self->SetPoint_3D(@_[0..3]);
6308 } elsif (!$has_z && $has_m) {
6309 $self->SetPointM(@_[0..3]);
6311 $self->SetPointZM(@_[0..4]);
6315 #** @method SetPointM()
6320 #** @method SetPointZM()
6325 #** @method SetPoint_2D($index, $x, $y)
6334 #** @method SetPoint_3D($index, $x, $y, $z)
6336 # Set the data of a point or a line string. Note that the coordinate
6337 # dimension is automatically upgraded to 25D (3).
6346 #** @method Geo::OGR::Geometry Simplify($Tolerance)
6348 # Simplify the geometry.
6349 # @param Tolerance the length tolerance for the simplification
6351 # @return a new Geo::OSR::Geometry object
6356 #** @method SimplifyPreserveTopology()
6358 sub SimplifyPreserveTopology {
6361 #** @method SwapXY()
6366 #** @method Geo::OGR::Geometry SymDifference($other)
6368 # Compute symmetric difference.
6369 # @note a.k.a. SymmetricDifference
6370 # @param other a Geo::OGR::Geometry object
6371 # @return a new Geo::OGR::Geometry object
6377 #** @method scalar Touches($other)
6379 # @param other a Geo::OGR::Geometry object
6380 # @return true if this geometry touches the other geometry, false otherwise
6385 #** @method Transform($trans)
6387 # @param trans a Geo::OSR::CoordinateTransformation object
6392 #** @method TransformTo($srs)
6394 # @param srs a Geo::OSR::SpatialReference object
6399 #** @method Geo::OGR::Geometry Union($other)
6401 # @param other a Geo::OGR::Geometry object
6402 # @return a new Geo::OGR::Geometry object
6407 #** @method Geo::OGR::Geometry UnionCascaded()
6409 # @return a new Geo::OGR::Geometry object
6420 #** @method scalar Within($other)
6422 # @param other a Geo::OGR::Geometry object
6423 # @return true if this geometry is within the other geometry, false otherwise
6428 #** @method scalar WkbSize()
6430 # @return an integer
6435 #** @method Geo::OGR::Geometry new(%params)
6437 # @param %params A named parameter, one of:
6438 # - \a GeometryType one the supported geometry types, see Geo::OGR::GeometryTypes.
6439 # - \a WKT a well known text string, which defines a geometry.
6440 # - \a WKB a well known binary string, which defines a geometry.
6441 # - \a HEXWKB WKB in hexadecimal.
6442 # - \a HEXEWKB PostGIS extended WKB.
6443 # - \a GML geometry written in Geographic Markup Language.
6444 # - \a GeoJSON geometry written in GeoJSON (JavaScript Object Notation for Geographic data).
6445 # - \a arc a reference to a list of values defining an arc: [CenterX,
6446 # CenterY, CenterZ, PrimaryRadius, SecondaryRadius, Rotation,
6447 # StartAngle, EndAngle, MaxAngleStepSizeDegrees] (see also Geo::OGR::Geometry::ApproximateArcAngles)
6448 # - \a Points An anonymous array as in method
6449 # Geo::OGR::Geometry::Points; Note: requires also GeometryType
6452 # @return a new Geo::OGR::Geometry object.
6457 if (@_ == 1 and ref($_[0]) eq 'HASH') {
6459 } elsif (@_ % 2 == 0) {
6462 ($param{GeometryType}) = @_;
6464 my $type = $param{GeometryType} // $param{Type} // $param{type};
6465 my $srs = $param{SRS} // $param{srs};
6466 my $wkt = $param{WKT} // $param{wkt};
6467 my $wkb = $param{WKB} // $param{wkb};
6468 my $hex = $param{HEXEWKB} // $param{HEX_EWKB} // $param{hexewkb} // $param{hex_ewkb};
6471 # EWKB contains SRID
6472 $srid = substr($hex, 10, 8);
6473 substr($hex, 10, 8) = '';
6475 $hex = $param{HEXWKB} // $param{HEX_WKB} // $param{hexwkb} // $param{hex_wkb};
6479 for (my $i = 0; $i < length($hex); $i+=2) {
6480 $wkb .= chr(hex(substr($hex,$i,2)));
6483 my $gml = $param{GML} // $param{gml};
6484 my $json = $param{GeoJSON} // $param{geojson} // $param{JSON} // $param{json};
6485 my $points = $param{Points} // $param{points};
6486 my $arc = $param{Arc} // $param{arc};
6489 $self = Geo::OGRc::CreateGeometryFromWkt($wkt, $srs);
6490 } elsif (defined $wkb) {
6491 $self = Geo::OGRc::CreateGeometryFromWkb($wkb, $srs);
6492 } elsif (defined $gml) {
6493 $self = Geo::OGRc::CreateGeometryFromGML($gml);
6494 } elsif (defined $json) {
6495 $self = Geo::OGRc::CreateGeometryFromJson($json);
6496 } elsif (defined $type) {
6497 $type = s2i(geometry_type => $type);
6498 $self = Geo::OGRc::new_Geometry($type); # flattens the type
6499 $self->Set3D(1) if HasZ($type);
6500 $self->SetMeasured(1) if HasM($type);
6501 } elsif (defined $arc) {
6502 $self = Geo::OGRc::ApproximateArcAngles(@$arc);
6504 error(1, undef, map {$_=>1} qw/GeometryType WKT WKB HEXEWKB HEXWKB GML GeoJSON Arc/);
6506 bless $self, $pkg if defined $self;
6507 $self->Points($points) if $points;
6511 #** @class Geo::OGR::Layer
6512 # @brief A collection of similar features.
6513 # @details A layer object is typically obtained with a data source object. A
6514 # layer has a data model (a schema), which is maintained in a
6515 # definition object, and a set of features, which contain data
6516 # according to the data model. The schema is typically set when the
6517 # layer is created or opened, but it may be altered somewhat with
6518 # methods Geo::OGR::Layer::CreateField,
6519 # Geo::OGR::Layer::AlterFieldDefn, and
6520 # Geo::OGR::Layer::DeleteField. Features and/or their data can be
6521 # read, inserted and deleted. Reading can be filtered. Layers can be
6522 # compared to each other with methods Clip, Erase, Identity,
6523 # Intersection, SymDifference, Union, and Update.
6524 # A layer may have metadata OLMD_FID64 => 'YES' if it holds features
6525 # with 64 bit FIDs. The metadata of a layer can be obtained with
6526 # GetMetadata method.
6528 package Geo::OGR::Layer;
6530 use base qw(Geo::GDAL::MajorObject Geo::OGR)
6532 #** @method AlterFieldDefn($name, %params)
6534 # @param field the name of the field to be altered.
6535 # @param params as in Geo::OGR::FieldDefn::new. Width and
6536 # Precision should be both or neither.
6537 # @note Only non-spatial fields can be altered.
6538 # @note Also the deprecated form AlterFieldDefn($field,
6539 # Geo::OGR::FieldDefn $Defn, $Flags) works.
6541 sub AlterFieldDefn {
6543 my $index = $self->GetLayerDefn->GetFieldIndex(shift // 0);
6544 my $param = @_ % 2 == 0 ? {@_} : shift;
6545 if (blessed($param) and $param->isa('Geo::OGR::FieldDefn')) {
6546 _AlterFieldDefn($self, $index, @_);
6548 my $definition = Geo::OGR::FieldDefn->new($param);
6550 $flags |= 1 if exists $param->{Name};
6551 $flags |= 2 if exists $param->{Type};
6552 $flags |= 4 if exists $param->{Width} or exists $param->{Precision};
6553 $flags |= 8 if exists $param->{Nullable};
6554 $flags |= 16 if exists $param->{Default};
6555 _AlterFieldDefn($self, $index, $definition, $flags);
6559 #** @method list Capabilities()
6561 # Both a package subroutine and an object method.
6562 # @return a list of capabilities. The object method returns a list of
6563 # the capabilities the layer has. The package subroutine returns a list of
6564 # all potential capabilities a layer may have. These are currently:
6565 # AlterFieldDefn, CreateField, CreateGeomField, CurveGeometries, DeleteFeature, DeleteField, FastFeatureCount, FastGetExtent, FastSetNextByIndex, FastSpatialFilter, IgnoreFields, MeasuredGeometries, RandomRead, RandomWrite, ReorderFields, SequentialWrite, StringsAsUTF8, and Transactions.
6569 # @cap = Geo::OGR::Layer::Capabilities(); # the package subroutine
6570 # @cap = $layer->Capabilities(); # the object method
6574 return @CAPABILITIES if @_ == 0;
6577 for my $cap (@CAPABILITIES) {
6578 push @cap, $cap if _TestCapability($self, $CAPABILITIES{$cap});
6583 #** @method Clip(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
6585 # Clip off areas that are not covered by the method layer. The schema
6586 # of the result layer can be set before calling this method, or is
6587 # initialized to to contain all fields from
6588 # this and method layer.
6589 # @param method method layer.
6590 # @param result result layer.
6591 # @param options a reference to an options hash.
6592 # @param callback [optional] a reference to a subroutine, which will
6593 # be called with parameters (number progress, string msg, callback_data)
6594 # @param callback_data [optional]
6599 #** @method CommitTransaction()
6602 sub CommitTransaction {
6605 #** @method CreateFeature()
6610 #** @method CreateField(%params)
6613 # @param params as in Geo::OGR::FieldDefn::new or
6614 # Geo::OGR::GeomFieldDefn::new, plus ApproxOK (whose default is true).
6618 my %defaults = ( ApproxOK => 1,
6622 } elsif (ref($_[0]) eq 'HASH') {
6624 } elsif (@_ % 2 == 0) {
6627 ($params{Defn}) = @_;
6629 for my $k (keys %defaults) {
6630 $params{$k} //= $defaults{$k};
6632 if (blessed($params{Defn}) and $params{Defn}->isa('Geo::OGR::FieldDefn')) {
6633 $self->_CreateField($params{Defn}, $params{ApproxOK});
6634 } elsif (blessed($_[0]) and $params{Defn}->isa('Geo::OGR::GeomFieldDefn')) {
6635 $self->CreateGeomField($params{Defn}, $params{ApproxOK});
6637 # if Name and Type are missing, assume Name => Type
6638 if (!(exists $params{Name} && exists $params{Type})) {
6639 for my $key (sort keys %params) {
6640 if (s_exists(field_type => $params{$key}) ||
6641 s_exists(geometry_type => $params{$key}))
6643 $params{Name} = $key;
6644 $params{Type} = $params{$key};
6645 delete $params{$key};
6650 my $a = $params{ApproxOK};
6651 delete $params{ApproxOK};
6652 if (exists $params{GeometryType}) {
6653 $params{Type} = $params{GeometryType};
6654 delete $params{GeometryType};
6656 if (s_exists(field_type => $params{Type})) {
6657 my $fd = Geo::OGR::FieldDefn->new(%params);
6658 _CreateField($self, $fd, $a);
6659 } elsif (s_exists(geometry_type => $params{Type})) {
6660 my $fd = Geo::OGR::GeomFieldDefn->new(%params);
6661 CreateGeomField($self, $fd, $a);
6662 } elsif ($params{Type} ) {
6663 error("Invalid field type: $params{Type}.")
6664 } elsif ($params{Name} ) {
6665 error("Missing type for field: $params{Name}.")
6667 error("Missing name and type for a field.")
6672 #** @method DataSource()
6677 #** @method Dataset()
6684 #** @method DeleteFeature($fid)
6686 # @param fid feature id
6691 #** @method DeleteField($field)
6693 # Delete an existing field from a layer.
6694 # @param field name (or index) of the field which is deleted
6695 # @note Only non-spatial fields can be deleted.
6698 my ($self, $field) = @_;
6699 my $index = $self->GetLayerDefn->GetFieldIndex($field // 0);
6700 _DeleteField($self, $index);
6703 #** @method Erase(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
6705 # The result layer contains features whose geometries represent areas
6706 # that are in the input layer but not in the method layer. The
6707 # features in the result layer have attributes from the input
6708 # layer. The schema of the result layer can be set by the user or, if
6709 # it is empty, is initialized to contain all fields in the input
6711 # @param method method layer.
6712 # @param result result layer.
6713 # @param options a reference to an options hash.
6714 # @param callback [optional] a reference to a subroutine, which will
6715 # be called with parameters (number progress, string msg, callback_data)
6716 # @param callback_data [optional]
6721 #** @method Geo::OGR::Feature Feature($f)
6724 # @param f [optional] feature id, a feature, a row, or a tuple
6726 # @note If the argument feature has a null FID (FID not set) the
6727 # feature is inserted into the layer as a new feature. If the FID is
6728 # non null, then the feature replaces the feature in the layer with
6731 # @return a new Geo::OGR::Feature object that represents the feature
6737 return $self->GetFeature($x) unless $x && ref $x;
6738 # Insert or Set depending on the FID
6740 if (ref $x eq 'ARRAY') {
6741 # FID is the first item in the array
6743 } elsif (ref $x eq 'HASH') {
6750 if (!defined $fid || $fid < 0) {
6751 $self->InsertFeature($x);
6753 $self->SetFeature($x);
6757 #** @method scalar FeatureCount($force = 1)
6759 # A.k.a GetFeatureCount
6766 #** @method Features()
6770 $self->ResetReading;
6772 return $self->GetNextFeature;
6776 #** @method ForFeatures($code, $in_place)
6778 # @note experimental, the syntax may change
6780 # Call code for all features. This is a simple wrapper for
6781 # ResetReading and while(GetNextFeature).
6785 # $layer->ForFeatures(sub {my $f = shift; $self->DeleteFeature($f->FID)}); # empties the layer
6788 # @param code a reference to a subroutine, which is called with each
6789 # feature as an argument
6790 # @param in_place if set to true, the feature is stored back to the
6796 my $in_place = shift;
6797 $self->ResetReading;
6798 while (my $f = $self->GetNextFeature) {
6801 $self->SetFeature($f) if $in_place;
6805 #** @method ForGeometries($code, $in_place)
6807 # @note experimental, the syntax may change
6809 # Call code for all geometries. This is a simple wrapper for
6810 # ResetReading and while(GetNextFeature).
6815 # $layer->ForGeometries(sub {my $g = shift; $area += $g->Area}); # computes the total area
6818 # @param code a reference to a subroutine, which is called with each
6819 # geometry as an argument
6820 # @param in_place if set to true, the geometry is stored back to the
6826 my $in_place = shift;
6827 $self->ResetReading;
6828 while (my $f = $self->GetNextFeature) {
6829 my $g = $f->Geometry();
6833 $self->SetFeature($f);
6838 #** @method Geometries()
6842 $self->ResetReading;
6844 my $f = $self->GetNextFeature;
6846 return $f->Geometry;
6850 #** @method scalar GeometryType($field)
6852 # @param field the name or index of the spatial field.
6853 # @return the geometry type of the spatial field.
6857 my $d = $self->GetDefn;
6858 my $field = $d->GetGeomFieldIndex(shift // 0);
6859 my $fd = $d->_GetGeomFieldDefn($field);
6860 return $fd->Type if $fd;
6863 #** @method Geo::OGR::DataSource GetDataSource()
6865 # @return the data source object to which this layer object belongs to.
6872 #** @method Geo::OGR::FeatureDefn GetDefn()
6874 # A.k.a GetLayerDefn.
6875 # @return a Geo::OGR::FeatureDefn object.
6879 my $defn = $self->GetLayerDefn;
6883 #** @method list GetExtent($force = 1)
6885 # @param force compute the extent even if it is expensive
6886 # @note In scalar context returns a reference to an anonymous array
6887 # containing the extent.
6888 # @return the extent ($minx, $maxx, $miny, $maxy)
6890 # @return the extent = ($minx, $maxx, $miny, $maxy) as a listref
6895 #** @method scalar GetFIDColumn()
6897 # @return the name of the underlying database column being used as the
6898 # FID column, or "" if not supported.
6903 #** @method Geo::OGR::Feature GetFeature($fid)
6905 # @param fid feature id
6906 # @return a new Geo::OGR::Feature object that represents the feature in the layer.
6909 my ($self, $fid) = @_;
6911 my $f = $self->_GetFeature($fid);
6912 error(2, "FID=$fid", '"Feature') unless ref $f eq 'Geo::OGR::Feature';
6916 #** @method GetFeatureCount()
6918 sub GetFeatureCount {
6921 #** @method scalar GetFeaturesRead()
6925 sub GetFeaturesRead {
6928 #** @method scalar GetFieldDefn($name)
6930 # Get the definition of a field.
6931 # @param name the name of the field.
6932 # @return a Geo::OGR::FieldDefn object.
6936 my $d = $self->GetDefn;
6937 my $field = $d->GetFieldIndex(shift // 0);
6938 return $d->_GetFieldDefn($field);
6941 #** @method list GetFieldNames()
6943 # @return a list of the names of the fields in this layer. The
6944 # non-geometry field names are first in the list and then the geometry
6949 my $d = $self->GetDefn;
6951 for (my $i = 0; $i < $d->GetFieldCount; $i++) {
6952 push @ret, $d->GetFieldDefn($i)->Name();
6954 for (my $i = 0; $i < $d->GetGeomFieldCount; $i++) {
6955 push @ret, $d->GetGeomFieldDefn($i)->Name();
6960 #** @method scalar GetGeomFieldDefn($name)
6962 # Get the definition of a spatial field.
6963 # @param name the name of the spatial field.
6964 # @return a Geo::OGR::GeomFieldDefn object.
6966 sub GetGeomFieldDefn {
6968 my $d = $self->GetDefn;
6969 my $field = $d->GetGeomFieldIndex(shift // 0);
6970 return $d->_GetGeomFieldDefn($field);
6973 #** @method scalar GetName()
6975 # @return the name of the layer.
6980 #** @method Geo::OGR::Feature GetNextFeature()
6982 # @return iteratively Geo::OGR::Feature objects from the layer. The
6983 # iteration obeys the spatial and the attribute filter.
6985 sub GetNextFeature {
6988 #** @method hash reference GetSchema()
6990 # @brief Get the schema of this layer.
6991 # @note The schema of a layer cannot be set with this method. If you
6992 # have a Geo::OGR::FeatureDefn object before creating the layer, use
6993 # its schema in the Geo::OGR::CreateLayer method.
6994 # @return the schema of this layer, as in Geo::OGR::FeatureDefn::Schema.
6998 carp "Schema of a layer should not be set directly." if @_;
6999 if (@_ and @_ % 2 == 0) {
7001 if ($schema{Fields}) {
7002 for my $field (@{$schema{Fields}}) {
7003 $self->CreateField($field);
7007 return $self->GetDefn->Schema;
7010 #** @method Geo::OGR::Geometry GetSpatialFilter()
7012 # @return a new Geo::OGR::Geometry object
7014 sub GetSpatialFilter {
7017 #** @method GetStyleTable()
7022 #** @method Identity(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7024 # The result layer contains features whose geometries represent areas
7025 # that are in the input layer. The features in the result layer have
7026 # attributes from both input and method layers. The schema of the
7027 # result layer can be set by the user or, if it is empty, is
7028 # initialized to contain all fields in input and method layers.
7029 # @param method method layer.
7030 # @param result result layer.
7031 # @param options a reference to an options hash.
7032 # @param callback [optional] a reference to a subroutine, which will
7033 # be called with parameters (number progress, string msg, callback_data)
7034 # @param callback_data [optional]
7039 #** @method InsertFeature($feature)
7041 # Creates a new feature which has the schema of the layer and
7042 # initializes it with data from the argument. Then inserts the feature
7043 # into the layer (using CreateFeature). Uses Geo::OGR::Feature::Row or
7044 # Geo::OGR::Feature::Tuple.
7045 # @param feature a Geo::OGR::Feature object or reference to feature
7046 # data in a hash (as in Geo::OGR::Feature::Row) or in an array (as in
7047 # Geo::OGR::Feature::Tuple)
7048 # @return the new feature.
7052 my $feature = shift;
7053 error("Usage: \$feature->InsertFeature(reference to a hash or array).") unless ref($feature);
7054 my $new = Geo::OGR::Feature->new(Schema => $self, Values => $feature);
7055 $self->CreateFeature($new);
7056 return unless defined wantarray;
7060 #** @method Intersection(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7062 # The result layer contains features whose geometries represent areas
7063 # that are common between features in the input layer and in the
7064 # method layer. The schema of the result layer can be set before
7065 # calling this method, or is initialized to contain all fields from
7066 # this and method layer.
7067 # @param method method layer.
7068 # @param result result layer.
7069 # @param options a reference to an options hash.
7070 # @param callback [optional] a reference to a subroutine, which will
7071 # be called with parameters (number progress, string msg, callback_data)
7072 # @param callback_data [optional]
7077 #** @method ReorderField()
7082 #** @method ReorderFields()
7087 #** @method ResetReading()
7089 # Initialize the layer object for iterative reading.
7094 #** @method RollbackTransaction()
7097 sub RollbackTransaction {
7100 #** @method hash reference Row(%row)
7102 # Get and/or set the data of a feature that has the supplied feature
7103 # id (the next feature obtained with GetNextFeature is used if feature
7104 # id is not given). Calls Geo::OGR::Feature::Row.
7105 # @param row [optional] feature data
7106 # @return a reference to feature data in a hash
7110 my $update = @_ > 0;
7112 my $feature = defined $row{FID} ? $self->GetFeature($row{FID}) : $self->GetNextFeature;
7113 return unless $feature;
7115 if (defined wantarray) {
7116 $ret = $feature->Row(@_);
7120 $self->SetFeature($feature) if $update;
7121 return unless defined wantarray;
7125 #** @method SetAttributeFilter($filter_string)
7127 # Set or clear the attribute filter.
7128 # @param filter_string a SQL WHERE clause or undef to clear the
7131 sub SetAttributeFilter {
7134 #** @method SetFeature($feature)
7136 # @note The feature should have the same schema as the layer.
7138 # Replaces a feature in the layer based on the given feature's
7139 # id. Requires RandomWrite capability.
7140 # @param feature a Geo::OGR::Feature object
7145 #** @method SetIgnoredFields(@fields)
7147 # @param fields a list of field names
7149 sub SetIgnoredFields {
7152 #** @method SetNextByIndex($new_index)
7154 # @param new_index the index to which set the read cursor in the
7157 sub SetNextByIndex {
7160 #** @method SetSpatialFilter($filter)
7162 # @param filter [optional] a Geo::OGR::Geometry object. If not given,
7163 # removes the filter if there is one.
7165 sub SetSpatialFilter {
7168 #** @method SetSpatialFilterRect($minx, $miny, $maxx, $maxy)
7175 sub SetSpatialFilterRect {
7178 #** @method SetStyleTable()
7183 #** @method Geo::OGR::Geometry SpatialFilter(@filter)
7185 # @param filter [optional] a Geo::OGR::Geometry object or a string. An
7186 # undefined value removes the filter if there is one.
7187 # @return a new Geo::OGR::Geometry object
7188 # @param filter [optional] a rectangle ($minx, $miny, $maxx, $maxy).
7189 # @return a new Geo::OGR::Geometry object
7193 $self->SetSpatialFilter($_[0]) if @_ == 1;
7194 $self->SetSpatialFilterRect(@_) if @_ == 4;
7195 return unless defined wantarray;
7196 $self->GetSpatialFilter;
7199 #** @method Geo::OSR::SpatialReference SpatialReference($name, Geo::OSR::SpatialReference sr)
7201 # @note A.k.a GetSpatialRef.
7202 # Get or set the projection of a spatial field of this layer. Gets or
7203 # sets the projection of the first field if no field name is given.
7204 # @param name [optional] a name of a spatial field in this layer.
7205 # @param sr [optional] a Geo::OSR::SpatialReference object,
7206 # which replaces the existing projection.
7207 # @return a Geo::OSR::SpatialReference object, which represents the
7208 # projection in the given spatial field.
7210 sub SpatialReference {
7212 my $d = $self->GetDefn;
7213 my $field = @_ == 2 ? $d->GetGeomFieldIndex(shift // 0) : 0;
7215 my $d2 = $d->_GetGeomFieldDefn($field);
7216 $d2->SpatialReference($sr) if defined $sr;
7217 return $d2->SpatialReference() if defined wantarray;
7220 #** @method StartTransaction()
7223 sub StartTransaction {
7226 #** @method SymDifference(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7228 # The result layer contains features whose geometries represent areas
7229 # that are in either in the input layer or in the method layer but not
7230 # in both. The features in the result layer have attributes from both
7231 # input and method layers. For features which represent areas that are
7232 # only in the input or in the method layer the respective attributes
7233 # have undefined values. The schema of the result layer can be set by
7234 # the user or, if it is empty, is initialized to contain all fields in
7235 # the input and method layers.
7236 # @param method method layer.
7237 # @param result result layer.
7238 # @param options a reference to an options hash.
7239 # @param callback [optional] a reference to a subroutine, which will
7240 # be called with parameters (number progress, string msg, callback_data)
7241 # @param callback_data [optional]
7246 #** @method SyncToDisk()
7252 #** @method scalar TestCapability($cap)
7254 # @param cap A capability string.
7255 # @return a boolean value indicating whether the layer has the
7256 # specified capability.
7258 sub TestCapability {
7259 my($self, $cap) = @_;
7260 return _TestCapability($self, $CAPABILITIES{$cap});
7263 #** @method list Tuple(@tuple)
7265 # Get and/set the data of a feature that has the supplied feature id
7266 # (the next feature obtained with GetNextFeature is used if feature id
7267 # is not given). The expected data in the tuple is: ([feature id,]
7268 # non-spatial fields, spatial fields). Calls Geo::OGR::Feature::Tuple.
7269 # @param tuple [optional] feature data
7270 # @note The schema of the tuple needs to be the same as that of the
7272 # @return a reference to feature data in an array
7277 my $feature = defined $FID ? $self->GetFeature($FID) : $self->GetNextFeature;
7278 return unless $feature;
7280 unshift @_, $feature->GetFID if $set;
7282 if (defined wantarray) {
7283 @ret = $feature->Tuple(@_);
7285 $feature->Tuple(@_);
7287 $self->SetFeature($feature) if $set;
7288 return unless defined wantarray;
7292 #** @method Union(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7294 # The result layer contains features whose geometries represent areas
7295 # that are in either in the input layer or in the method layer. The
7296 # schema of the result layer can be set before calling this method, or
7297 # is initialized to contain all fields from this and method layer.
7298 # @param method method layer.
7299 # @param result result layer.
7300 # @param options a reference to an options hash.
7301 # @param callback [optional] a reference to a subroutine, which will
7302 # be called with parameters (number progress, string msg, callback_data)
7303 # @param callback_data [optional]
7308 #** @method Update(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7310 # The result layer contains features whose geometries represent areas
7311 # that are either in the input layer or in the method layer. The
7312 # features in the result layer have areas of the features of the
7313 # method layer or those ares of the features of the input layer that
7314 # are not covered by the method layer. The features of the result
7315 # layer get their attributes from the input layer. The schema of the
7316 # result layer can be set by the user or, if it is empty, is
7317 # initialized to contain all fields in the input layer.
7318 # @param method method layer.
7319 # @param result result layer.
7320 # @param options a reference to an options hash.
7321 # @param callback [optional] a reference to a subroutine, which will
7322 # be called with parameters (number progress, string msg, callback_data)
7323 # @param callback_data [optional]
7328 #** @class Geo::OGR::StyleTable
7330 package Geo::OGR::StyleTable;
7332 use base qw(Geo::OGR)
7334 #** @method AddStyle()
7344 #** @method GetLastStyleName()
7346 sub GetLastStyleName {
7349 #** @method GetNextStyle()
7354 #** @method LoadStyleTable()
7356 sub LoadStyleTable {
7359 #** @method ResetStyleStringReading()
7361 sub ResetStyleStringReading {
7364 #** @method SaveStyleTable()
7366 sub SaveStyleTable {
7373 my $self = Geo::OGRc::new_StyleTable(@_);
7374 bless $self, $pkg if defined($self);
7378 # @brief Base class for projection related classes.
7383 #** @method list AngularUnits()
7384 # Package subroutine.
7385 # @return list of known angular units.
7388 return keys %ANGULAR_UNITS;
7391 #** @method CreateCoordinateTransformation()
7393 sub CreateCoordinateTransformation {
7396 #** @method list Datums()
7397 # Package subroutine.
7398 # @return list of known datums.
7401 return keys %DATUMS;
7404 #** @method list GetProjectionMethodParamInfo($projection, $parameter)
7405 # Package subroutine.
7406 # @param projection one of Geo::OSR::Projections
7407 # @param parameter one of Geo::OSR::Parameters
7408 # @return a list ($user_friendly_name, $type, $default_value).
7410 sub GetProjectionMethodParamInfo {
7413 #** @method list GetProjectionMethodParameterList($projection)
7414 # Package subroutine.
7415 # @param projection one of Geo::OSR::Projections
7416 # @return a list (arrayref parameters, $projection_name).
7418 sub GetProjectionMethodParameterList {
7421 #** @method array reference GetProjectionMethods()
7422 # Package subroutine.
7423 # @deprecated Use Geo::OSR::Projections.
7425 # @return reference to an array of possible projection methods.
7427 sub GetProjectionMethods {
7430 #** @method scalar GetUserInputAsWKT($name)
7431 # Package subroutine.
7432 # @param name the user input
7433 # @return a WKT string.
7435 sub GetUserInputAsWKT {
7438 #** @method scalar GetWellKnownGeogCSAsWKT($name)
7439 # Package subroutine.
7440 # @brief Get well known geographic coordinate system as WKT
7441 # @param name a well known name
7442 # @return a WKT string.
7444 sub GetWellKnownGeogCSAsWKT {
7447 #** @method list LinearUnits()
7448 # Package subroutine.
7449 # @return list of known linear units.
7452 return keys %LINEAR_UNITS;
7455 #** @method OAO_Down()
7460 #** @method OAO_East()
7465 #** @method OAO_North()
7470 #** @method OAO_Other()
7475 #** @method OAO_South()
7480 #** @method OAO_Up()
7485 #** @method OAO_West()
7490 #** @method list Parameters()
7491 # Package subroutine.
7492 # @return list of known projection parameters.
7495 return keys %PARAMETERS;
7498 #** @method list Projections()
7499 # Package subroutine.
7500 # @return list of known projections.
7503 return keys %PROJECTIONS;
7506 #** @method SRS_PM_GREENWICH()
7508 sub SRS_PM_GREENWICH {
7511 #** @method SRS_WGS84_INVFLATTENING()
7513 sub SRS_WGS84_INVFLATTENING {
7516 #** @method SRS_WGS84_SEMIMAJOR()
7518 sub SRS_WGS84_SEMIMAJOR {
7521 #** @method SRS_WKT_WGS84()
7526 #** @class Geo::OSR::CoordinateTransformation
7527 # @brief An object for transforming from one projection to another.
7530 package Geo::OSR::CoordinateTransformation;
7532 use base qw(Geo::OSR)
7534 #** @method array reference TransformPoint($x, $y, $z)
7538 # @param z [optional]
7539 # @return arrayref = [$x, $y, $z]
7541 sub TransformPoint {
7544 #** @method TransformPoints(arrayref points)
7546 # @param points [in/out] a reference to a list of points (line string
7547 # or ring) that is modified in-place. A list of points is: ([x, y, z],
7548 # [x, y, z], ...), where z is optional. Supports also lists of line
7549 # strings and polygons.
7551 sub TransformPoints {
7552 my($self, $points) = @_;
7553 _TransformPoints($self, $points), return unless ref($points->[0]->[0]);
7554 for my $p (@$points) {
7555 TransformPoints($self, $p);
7559 # This file was automatically generated by SWIG (http://www.swig.org).
7562 # Do not make changes to this file unless you know what you are doing--modify
7563 # the SWIG interface file instead.
7566 #** @method Geo::OSR::CoordinateTransformation new($src, $dst)
7568 # @param src a Geo::OSR::SpatialReference object
7569 # @param dst a Geo::OSR::SpatialReference object
7570 # @return a new Geo::OSR::CoordinateTransformation object
7574 my $self = Geo::OSRc::new_CoordinateTransformation(@_);
7575 bless $self, $pkg if defined($self);
7578 #** @class Geo::OSR::SpatialReference
7579 # @brief A spatial reference system.
7580 # @details <a href="http://www.gdal.org/classOGRSpatialReference.html">Documentation
7581 # of the underlying C++ class at www.gdal.org</a>
7583 package Geo::OSR::SpatialReference;
7585 use base qw(Geo::OSR)
7592 #** @method AutoIdentifyEPSG()
7594 # Set EPSG authority info if possible.
7596 sub AutoIdentifyEPSG {
7599 #** @method Geo::OSR::SpatialReference Clone()
7601 # Make a duplicate of this SpatialReference object.
7602 # @return a new Geo::OSR::SpatialReference object
7607 #** @method Geo::OSR::SpatialReference CloneGeogCS()
7609 # Make a duplicate of the GEOGCS node of this SpatialReference object.
7610 # @return a new Geo::OSR::SpatialReference object
7615 #** @method ConvertToOtherProjection()
7617 sub ConvertToOtherProjection {
7620 #** @method CopyGeogCSFrom($rhs)
7622 # @param rhs Geo::OSR::SpatialReference
7624 sub CopyGeogCSFrom {
7627 #** @method EPSGTreatsAsLatLong()
7629 # Returns TRUE if EPSG feels this geographic coordinate system should be treated as having lat/long coordinate ordering.
7631 sub EPSGTreatsAsLatLong {
7634 #** @method EPSGTreatsAsNorthingEasting()
7636 sub EPSGTreatsAsNorthingEasting {
7639 #** @method Export($format)
7641 # Export the spatial reference to a selected format.
7644 # @param format One of the following. The return value is explained
7645 # after the format. Other arguments are explained in parenthesis.
7646 # - WKT (Text): Well Known Text string
7647 # - PrettyWKT: Well Known Text string nicely formatted (simplify)
7648 # - Proj4: PROJ.4 string
7649 # - PCI: a list: ($proj_string, $units, [$parms1, ...])
7650 # - USGS: a list: ($code, $zone, [$parms1, ...], $datum)
7651 # - GML (XML): GML based string (dialect)
7652 # - MapInfoCS (MICoordSys): MapInfo style co-ordinate system definition
7654 # @note The named parameter syntax also works and is needed is those
7655 # cases when other arguments need or may be given. The format should
7656 # be given using key as, 'to' or 'format'.
7658 # @note ExportTo* and AsText methods also exist but are not documented here.
7660 # @return a scalar or a list depending on the export format
7665 $format = pop if @_ == 1;
7667 $format //= $params{to} //= $params{format} //= $params{as} //= '';
7668 my $simplify = $params{simplify} // 0;
7669 my $dialect = $params{dialect} // '';
7671 WKT => sub { return ExportToWkt($self) },
7672 Text => sub { return ExportToWkt($self) },
7673 PrettyWKT => sub { return ExportToPrettyWkt($self, $simplify) },
7674 Proj4 => sub { return ExportToProj4($self) },
7675 PCI => sub { return ExportToPCI($self) },
7676 USGS => sub { return ExportToUSGS($self) },
7677 GML => sub { return ExportToXML($self, $dialect) },
7678 XML => sub { return ExportToXML($self, $dialect) },
7679 MICoordSys => sub { return ExportToMICoordSys() },
7680 MapInfoCS => sub { return ExportToMICoordSys() },
7682 error(1, $format, \%converters) unless $converters{$format};
7683 return $converters{$format}->();
7692 #** @method FixupOrdering()
7698 #** @method scalar GetAngularUnits()
7702 sub GetAngularUnits {
7705 #** @method GetAngularUnitsName()
7707 sub GetAngularUnitsName {
7710 #** @method scalar GetAttrValue($name, $child = 0)
7719 #** @method scalar GetAuthorityCode($target_key)
7724 sub GetAuthorityCode {
7727 #** @method scalar GetAuthorityName($target_key)
7732 sub GetAuthorityName {
7735 #** @method GetAxisName()
7740 #** @method GetAxisOrientation()
7742 sub GetAxisOrientation {
7745 #** @method GetInvFlattening()
7748 sub GetInvFlattening {
7751 #** @method scalar GetLinearUnits()
7755 sub GetLinearUnits {
7758 #** @method scalar GetLinearUnitsName()
7762 sub GetLinearUnitsName {
7765 #** @method scalar GetNormProjParm($name, $default_val = 0.0)
7768 # @param default_val
7771 sub GetNormProjParm {
7774 #** @method scalar GetProjParm($name, $default_val = 0.0)
7777 # @param default_val
7783 #** @method GetSemiMajor()
7789 #** @method GetSemiMinor()
7795 #** @method GetTOWGS84()
7797 # @return array = ($p1, $p2, $p3, $p4, $p5, $p6, $p7)
7802 #** @method GetTargetLinearUnits()
7804 sub GetTargetLinearUnits {
7807 #** @method GetUTMZone()
7809 # Get UTM zone information.
7810 # @return The UTM zone (integer). In scalar context the returned value
7811 # is negative for southern hemisphere zones. In list context returns
7812 # two values ($zone, $north), where $zone is always non-negative and
7813 # $north is true or false.
7817 my $zone = _GetUTMZone($self);
7824 return ($zone, $north);
7830 #** @method ImportFromOzi()
7835 #** @method scalar IsCompound()
7842 #** @method scalar IsGeocentric()
7849 #** @method scalar IsGeographic()
7856 #** @method scalar IsLocal()
7863 #** @method scalar IsProjected()
7870 #** @method scalar IsSame($rs)
7872 # @param rs a Geo::OSR::SpatialReference object
7878 #** @method scalar IsSameGeogCS($rs)
7880 # @param rs a Geo::OSR::SpatialReference object
7886 #** @method scalar IsSameVertCS($rs)
7888 # @param rs a Geo::OSR::SpatialReference object
7894 #** @method scalar IsVertical()
7901 #** @method MorphFromESRI()
7907 #** @method MorphToESRI()
7913 #** @method Set(%params)
7915 # Set a parameter or parameters in the spatial reference object.
7916 # @param params Named parameters. Recognized keys and respective
7917 # values are the following.
7918 # - Authority: authority name (give also TargetKey, Node and Code)
7920 # - Node: partial or complete path to the target node (Node and Value together sets an attribute value)
7921 # - Code: code for value with an authority
7922 # - Value: value to be assigned to a node, a projection parameter or an object
7923 # - AngularUnits: angular units for the geographic coordinate system (give also Value) (one of Geo::OSR::LinearUnits)
7924 # - LinearUnits: linear units for the target node or the object (give also Value and optionally Node) (one of Geo::OSR::LinearUnits)
7925 # - Parameter: projection parameter to set (give also Value and Normalized) (one of Geo::OSR::Parameters)
7926 # - Normalized: set to true to indicate that the Value argument is in "normalized" form
7927 # - Name: a well known name of a geographic coordinate system (e.g. WGS84)
7928 # - GuessFrom: arbitrary text that specifies a projection ("user input")
7929 # - LOCAL_CS: name of a local coordinate system
7930 # - GeocentricCS: name of a geocentric coordinate system
7931 # - VerticalCS: name of a vertical coordinate system (give also Datum and optionally VertDatumType [default is 2005])
7932 # - Datum: a known (OGC or EPSG) name (or(?) one of Geo::OSR::Datums)
7933 # - CoordinateSystem: 'WGS', 'UTM', 'State Plane', or a user visible name (give optionally also Parameters, Zone, North, NAD83, UnitName, UnitConversionFactor, Datum, Spheroid, HorizontalCS, and/or VerticalCS
7934 # - Parameters: a reference to a list containing the coordinate system or projection parameters
7935 # - Zone: zone for setting up UTM or State Plane coordinate systems (State Plane zone in USGS numbering scheme)
7936 # - North: set false for southern hemisphere
7937 # - NAD83: set false if the NAD27 zone definition should be used instead of NAD83
7938 # - UnitName: to override the legal definition for a zone
7939 # - UnitConversionFactor: to override the legal definition for a zone
7940 # - Spheroid: user visible name
7941 # - HorizontalCS: Horizontal coordinate system name
7942 # - Projection: name of a projection, one of Geo::OSR::Projections (give also optionally Parameters and Variant)
7944 # @note Numerous Set* methods also exist but are not documented here.
7947 my($self, %params) = @_;
7948 if (exists $params{Authority} and exists $params{TargetKey} and exists $params{Node} and exists $params{Code}) {
7949 SetAuthority($self, $params{TargetKey}, $params{Authority}, $params{Code});
7950 } elsif (exists $params{Node} and exists $params{Value}) {
7951 SetAttrValue($self, $params{Node}, $params{Value});
7952 } elsif (exists $params{AngularUnits} and exists $params{Value}) {
7953 SetAngularUnits($self, $params{AngularUnits}, $params{Value});
7954 } elsif (exists $params{LinearUnits} and exists $params{Node} and exists $params{Value}) {
7955 SetTargetLinearUnits($self, $params{Node}, $params{LinearUnits}, $params{Value});
7956 } elsif (exists $params{LinearUnits} and exists $params{Value}) {
7957 SetLinearUnitsAndUpdateParameters($self, $params{LinearUnits}, $params{Value});
7958 } elsif ($params{Parameter} and exists $params{Value}) {
7959 error(1, $params{Parameter}, \%Geo::OSR::PARAMETERS) unless exists $Geo::OSR::PARAMETERS{$params{Parameter}};
7960 $params{Normalized} ?
7961 SetNormProjParm($self, $params{Parameter}, $params{Value}) :
7962 SetProjParm($self, $params{Parameter}, $params{Value});
7963 } elsif (exists $params{Name}) {
7964 SetWellKnownGeogCS($self, $params{Name});
7965 } elsif (exists $params{GuessFrom}) {
7966 SetFromUserInput($self, $params{GuessFrom});
7967 } elsif (exists $params{LOCAL_CS}) {
7968 SetLocalCS($self, $params{LOCAL_CS});
7969 } elsif (exists $params{GeocentricCS}) {
7970 SetGeocCS($self, $params{GeocentricCS});
7971 } elsif (exists $params{VerticalCS} and $params{Datum}) {
7972 my $type = $params{VertDatumType} || 2005;
7973 SetVertCS($self, $params{VerticalCS}, $params{Datum}, $type);
7974 } elsif (exists $params{CoordinateSystem}) {
7975 my @parameters = ();
7976 @parameters = @{$params{Parameters}} if ref($params{Parameters});
7977 if ($params{CoordinateSystem} eq 'State Plane' and exists $params{Zone}) {
7978 my $NAD83 = exists $params{NAD83} ? $params{NAD83} : 1;
7979 my $name = exists $params{UnitName} ? $params{UnitName} : undef;
7980 my $c = exists $params{UnitConversionFactor} ? $params{UnitConversionFactor} : 0.0;
7981 SetStatePlane($self, $params{Zone}, $NAD83, $name, $c);
7982 } elsif ($params{CoordinateSystem} eq 'UTM' and exists $params{Zone} and exists $params{North}) {
7983 my $north = exists $params{North} ? $params{North} : 1;
7984 SetUTM($self, $params{Zone}, $north);
7985 } elsif ($params{CoordinateSystem} eq 'WGS') {
7986 SetTOWGS84($self, @parameters);
7987 } elsif ($params{CoordinateSystem} and $params{Datum} and $params{Spheroid}) {
7988 SetGeogCS($self, $params{CoordinateSystem}, $params{Datum}, $params{Spheroid}, @parameters);
7989 } elsif ($params{CoordinateSystem} and $params{HorizontalCS} and $params{VerticalCS}) {
7990 SetCompoundCS($self, $params{CoordinateSystem}, $params{HorizontalCS}, $params{VerticalCS});
7992 SetProjCS($self, $params{CoordinateSystem});
7994 } elsif (exists $params{Projection}) {
7995 error(1, $params{Projection}, \%Geo::OSR::PROJECTIONS) unless exists $Geo::OSR::PROJECTIONS{$params{Projection}};
7996 my @parameters = ();
7997 @parameters = @{$params{Parameters}} if ref($params{Parameters});
7998 if ($params{Projection} eq 'Albers_Conic_Equal_Area') {
7999 SetACEA($self, @parameters);
8000 } elsif ($params{Projection} eq 'Azimuthal_Equidistant') {
8001 SetAE($self, @parameters);
8002 } elsif ($params{Projection} eq 'Bonne') {
8003 SetBonne($self, @parameters);
8004 } elsif ($params{Projection} eq 'Cylindrical_Equal_Area') {
8005 SetCEA($self, @parameters);
8006 } elsif ($params{Projection} eq 'Cassini_Soldner') {
8007 SetCS($self, @parameters);
8008 } elsif ($params{Projection} eq 'Equidistant_Conic') {
8009 SetEC($self, @parameters);
8010 # Eckert_I, Eckert_II, Eckert_III, Eckert_V ?
8011 } elsif ($params{Projection} eq 'Eckert_IV') {
8012 SetEckertIV($self, @parameters);
8013 } elsif ($params{Projection} eq 'Eckert_VI') {
8014 SetEckertVI($self, @parameters);
8015 } elsif ($params{Projection} eq 'Equirectangular') {
8017 SetEquirectangular($self, @parameters) :
8018 SetEquirectangular2($self, @parameters);
8019 } elsif ($params{Projection} eq 'Gauss_Schreiber_Transverse_Mercator') {
8020 SetGaussSchreiberTMercator($self, @parameters);
8021 } elsif ($params{Projection} eq 'Gall_Stereographic') {
8022 SetGS($self, @parameters);
8023 } elsif ($params{Projection} eq 'Goode_Homolosine') {
8024 SetGH($self, @parameters);
8025 } elsif ($params{Projection} eq 'Interrupted_Goode_Homolosine') {
8027 } elsif ($params{Projection} eq 'Geostationary_Satellite') {
8028 SetGEOS($self, @parameters);
8029 } elsif ($params{Projection} eq 'Gnomonic') {
8030 SetGnomonic($self, @parameters);
8031 } elsif ($params{Projection} eq 'Hotine_Oblique_Mercator') {
8032 # Hotine_Oblique_Mercator_Azimuth_Center ?
8033 SetHOM($self, @parameters);
8034 } elsif ($params{Projection} eq 'Hotine_Oblique_Mercator_Two_Point_Natural_Origin') {
8035 SetHOM2PNO($self, @parameters);
8036 } elsif ($params{Projection} eq 'Krovak') {
8037 SetKrovak($self, @parameters);
8038 } elsif ($params{Projection} eq 'Lambert_Azimuthal_Equal_Area') {
8039 SetLAEA($self, @parameters);
8040 } elsif ($params{Projection} eq 'Lambert_Conformal_Conic_2SP') {
8041 SetLCC($self, @parameters);
8042 } elsif ($params{Projection} eq 'Lambert_Conformal_Conic_1SP') {
8043 SetLCC1SP($self, @parameters);
8044 } elsif ($params{Projection} eq 'Lambert_Conformal_Conic_2SP_Belgium') {
8045 SetLCCB($self, @parameters);
8046 } elsif ($params{Projection} eq 'miller_cylindrical') {
8047 SetMC($self, @parameters);
8048 } elsif ($params{Projection} =~ /^Mercator/) {
8049 # Mercator_1SP, Mercator_2SP, Mercator_Auxiliary_Sphere ?
8050 # variant is in Variant (or Name)
8051 SetMercator($self, @parameters);
8052 } elsif ($params{Projection} eq 'Mollweide') {
8053 SetMollweide($self, @parameters);
8054 } elsif ($params{Projection} eq 'New_Zealand_Map_Grid') {
8055 SetNZMG($self, @parameters);
8056 } elsif ($params{Projection} eq 'Oblique_Stereographic') {
8057 SetOS($self, @parameters);
8058 } elsif ($params{Projection} eq 'Orthographic') {
8059 SetOrthographic($self, @parameters);
8060 } elsif ($params{Projection} eq 'Polyconic') {
8061 SetPolyconic($self, @parameters);
8062 } elsif ($params{Projection} eq 'Polar_Stereographic') {
8063 SetPS($self, @parameters);
8064 } elsif ($params{Projection} eq 'Robinson') {
8065 SetRobinson($self, @parameters);
8066 } elsif ($params{Projection} eq 'Sinusoidal') {
8067 SetSinusoidal($self, @parameters);
8068 } elsif ($params{Projection} eq 'Stereographic') {
8069 SetStereographic($self, @parameters);
8070 } elsif ($params{Projection} eq 'Swiss_Oblique_Cylindrical') {
8071 SetSOC($self, @parameters);
8072 } elsif ($params{Projection} eq 'Transverse_Mercator_South_Orientated') {
8073 SetTMSO($self, @parameters);
8074 } elsif ($params{Projection} =~ /^Transverse_Mercator/) {
8075 my($variant) = $params{Projection} =~ /^Transverse_Mercator_(\w+)/;
8076 $variant //= $params{Variant} //= $params{Name};
8078 SetTMVariant($self, $variant, @parameters) :
8079 SetTM($self, @parameters);
8080 } elsif ($params{Projection} eq 'Tunisia_Mining_Grid') {
8081 SetTMG($self, @parameters);
8082 } elsif ($params{Projection} eq 'VanDerGrinten') {
8083 SetVDG($self, @parameters);
8085 # Aitoff, Craster_Parabolic, International_Map_of_the_World_Polyconic, Laborde_Oblique_Mercator
8086 # Loximuthal, Miller_Cylindrical, Quadrilateralized_Spherical_Cube, Quartic_Authalic, Two_Point_Equidistant
8087 # Wagner_I, Wagner_II, Wagner_III, Wagner_IV, Wagner_V, Wagner_VI, Wagner_VII
8088 # Winkel_I, Winkel_II, Winkel_Tripel
8090 SetProjection($self, $params{Projection});
8093 error("Not enough information to create a spatial reference object.");
8097 #** @method SetMercator2SP()
8099 sub SetMercator2SP {
8102 #** @method StripCTParms()
8108 #** @method Validate()
8114 #** @method Geo::OSR::SpatialReference new(%params)
8116 # Create a new spatial reference object using a named parameter. This
8117 # constructor recognizes the following key words (alternative in
8118 # parenthesis): WKT (Text), Proj4, ESRI, EPSG, EPSGA, PCI, USGS, GML
8119 # (XML), URL, ERMapper (ERM), MapInfoCS (MICoordSys). The value
8120 # depends on the key.
8121 # - WKT: Well Known Text string
8122 # - Proj4: PROJ.4 string
8123 # - ESRI: reference to a list of strings (contents of ESRI .prj file)
8124 # - EPSG: EPSG code number
8125 # - EPSGA: EPSG code number (the resulting CS will have EPSG preferred axis ordering)
8126 # - PCI: listref: [PCI_projection_string, Grid_units_code, [17 cs parameters]]
8127 # - USGS: listref: [Projection_system_code, Zone, [15 cs parameters], Datum_code, Format_flag]
8129 # - URL: URL for downloading the spatial reference from
8130 # - ERMapper: listref: [Projection, Datum, Units]
8131 # - MapInfoCS: MapInfo style co-ordinate system definition
8133 # For more information, consult the import methods in <a href="http://www.gdal.org/classOGRSpatialReference.html">OGR documentation</a>.
8135 # @note ImportFrom* methods also exist but are not documented here.
8139 # $sr = Geo::OSR::SpatialReference->new( key => value );
8141 # @return a new Geo::OSR::SpatialReference object
8146 my $self = Geo::OSRc::new_SpatialReference();
8147 if (exists $param{WKT}) {
8148 ImportFromWkt($self, $param{WKT});
8149 } elsif (exists $param{Text}) {
8150 ImportFromWkt($self, $param{Text});
8151 } elsif (exists $param{Proj4}) {
8152 ImportFromProj4($self, $param{Proj4});
8153 } elsif (exists $param{ESRI}) {
8154 ImportFromESRI($self, @{$param{ESRI}});
8155 } elsif (exists $param{EPSG}) {
8156 ImportFromEPSG($self, $param{EPSG});
8157 } elsif (exists $param{EPSGA}) {
8158 ImportFromEPSGA($self, $param{EPSGA});
8159 } elsif (exists $param{PCI}) {
8160 ImportFromPCI($self, @{$param{PCI}});
8161 } elsif (exists $param{USGS}) {
8162 ImportFromUSGS($self, @{$param{USGS}});
8163 } elsif (exists $param{XML}) {
8164 ImportFromXML($self, $param{XML});
8165 } elsif (exists $param{GML}) {
8166 ImportFromGML($self, $param{GML});
8167 } elsif (exists $param{URL}) {
8168 ImportFromUrl($self, $param{URL});
8169 } elsif (exists $param{ERMapper}) {
8170 ImportFromERM($self, @{$param{ERMapper}});
8171 } elsif (exists $param{ERM}) {
8172 ImportFromERM($self, @{$param{ERM}});
8173 } elsif (exists $param{MICoordSys}) {
8174 ImportFromMICoordSys($self, $param{MICoordSys});
8175 } elsif (exists $param{MapInfoCS}) {
8176 ImportFromMICoordSys($self, $param{MapInfoCS});
8177 } elsif (exists $param{WGS}) {
8179 SetWellKnownGeogCS($self, 'WGS'.$param{WGS});
8181 confess last_error() if $@;
8183 error("Unrecognized/missing parameters: @_.");
8185 bless $self, $pkg if defined $self;