Geo::GDAL  2.4
all.pm
Go to the documentation of this file.
1 #** @class Geo::GDAL
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.
7 #*
8 package Geo::GDAL;
9 
10 #** @method ApplyVerticalShiftGrid()
11 #*
12 sub ApplyVerticalShiftGrid {
13 }
14 
15 #** @method BuildVRT()
16 #*
17 sub BuildVRT {
18  for (keys %Geo::GDAL::Const::) {
19  next if /TypeCount/;
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+)/;
25  }
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;
30  }
31  for my $string (@OPEN_FLAGS) {
32  my $int = eval "\$Geo::GDAL::Const::OF_$string";
33  $S2I{open_flag}{$string} = $int;
34  }
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;
39  }
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;
44  }
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;
49  }
50  our $HAVE_PDL;
51  eval 'require PDL';
52  $HAVE_PDL = 1 unless $@;
53 }
54 
55 #** @method CPLBinaryToHex()
56 #*
57 sub CPLBinaryToHex {
58 }
59 
60 #** @method CPLHexToBinary()
61 #*
62 sub CPLHexToBinary {
63 }
64 
65 #** @method CreatePansharpenedVRT()
66 #*
67 sub CreatePansharpenedVRT {
68 }
69 
70 #** @method scalar DataTypeIsComplex($DataType)
71 # Package subroutine.
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.
74 #*
75 sub DataTypeIsComplex {
76  return _DataTypeIsComplex(s2i(data_type => shift));
77 }
78 
79 #** @method list DataTypeValueRange($DataType)
80 # Package subroutine.
81 # @param DataType Data type (one of those listed by Geo::GDAL::DataTypes).
82 # @note Some returned values are inaccurate.
83 #
84 # @return the minimum, maximum range of the data type.
85 #*
86 sub DataTypeValueRange {
87  my $t = shift;
88  s2i(data_type => $t);
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/;
97 }
98 
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.
103 #*
104 sub DataTypes {
105  return @DATA_TYPES;
106 }
107 
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').
113 # @param precision
114 # @return a string nndnn'nn.nn'"L where n is a number and L is either
115 # N or E
116 #*
117 sub DecToDMS {
118 }
119 
120 #** @method scalar DecToPackedDMS($dec)
121 # Package subroutine.
122 # @param dec Decimal degrees
123 # @return packed DMS, i.e., a number DDDMMMSSS.SS
124 #*
125 sub DecToPackedDMS {
126 }
127 
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.
132 #*
133 sub DontUseExceptions {
134 }
135 
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.
144 #*
145 sub Driver {
146  return 'Geo::GDAL::Driver' unless @_;
147  my $name = shift;
148  my $driver = GetDriver($name);
149  error("Driver \"$name\" not found. Is it built in? Check with Geo::GDAL::Drivers or Geo::OGR::Drivers.")
150  unless $driver;
151  return $driver;
152 }
153 
154 #** @method list DriverNames()
155 # Package subroutine.
156 # Available raster format drivers.
157 # \code
158 # perl -MGeo::GDAL -e '@d=Geo::GDAL::DriverNames;print "@d\n"'
159 # \endcode
160 # @note Use Geo::OGR::DriverNames for vector drivers.
161 # @return a list of the short names of all available GDAL raster drivers.
162 #*
163 sub DriverNames {
164 }
165 
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.
170 #*
171 sub Drivers {
172  my @drivers;
173  for my $i (0..GetDriverCount()-1) {
174  my $driver = GetDriver($i);
175  push @drivers, $driver if $driver->TestCapability('RASTER');
176  }
177  return @drivers;
178 }
179 
180 #** @method EscapeString()
181 #*
182 sub EscapeString {
183 }
184 
185 #** @method scalar FindFile($basename)
186 # Package subroutine.
187 # Search for GDAL support files.
188 #
189 # An example:
190 # \code
191 # use Geo::GDAL;
192 # $a = Geo::GDAL::FindFile('pcs.csv');
193 # print STDERR "$a\n";
194 # \endcode
195 # Prints (for example):
196 # \code
197 # c:\msys\1.0\local\share\gdal\pcs.csv
198 # \endcode
199 #
200 # @param basename The name of the file to search for. For example
201 # 'pcs.csv'.
202 # @return the path to the searched file or undef.
203 #*
204 sub FindFile {
205  if (@_ == 1) {
206  _FindFile('', @_);
207  } else {
208  _FindFile(@_);
209  }
210 }
211 
212 #** @method FinderClean()
213 # Package subroutine.
214 # Clear the set of support file search paths.
215 #*
216 sub FinderClean {
217 }
218 
219 #** @method GOA2GetAccessToken()
220 #*
221 sub GOA2GetAccessToken {
222 }
223 
224 #** @method GOA2GetAuthorizationURL()
225 #*
226 sub GOA2GetAuthorizationURL {
227 }
228 
229 #** @method GOA2GetRefreshToken()
230 #*
231 sub GOA2GetRefreshToken {
232 }
233 
234 #** @method GetActualURL()
235 #*
236 sub GetActualURL {
237 }
238 
239 #** @method scalar GetCacheMax()
240 # Package subroutine.
241 # @return maximum amount of memory (as bytes) for caching within GDAL.
242 #*
243 sub GetCacheMax {
244 }
245 
246 #** @method scalar GetCacheUsed()
247 # Package subroutine.
248 # @return the amount of memory currently used for caching within GDAL.
249 #*
250 sub GetCacheUsed {
251 }
252 
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.
259 #*
260 sub GetConfigOption {
261 }
262 
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.
267 #*
268 sub GetDataTypeSize {
269  return _GetDataTypeSize(s2i(data_type => shift, 1));
270 }
271 
272 #** @method GetErrorCounter()
273 #*
274 sub GetErrorCounter {
275 }
276 
277 #** @method GetFileSystemOptions()
278 #*
279 sub GetFileSystemOptions {
280 }
281 
282 #** @method GetFileSystemsPrefixes()
283 #*
284 sub GetFileSystemsPrefixes {
285 }
286 
287 #** @method GetJPEG2000StructureAsString()
288 #*
289 sub GetJPEG2000StructureAsString {
290 }
291 
292 #** @method GetSignedURL()
293 #*
294 sub GetSignedURL {
295 }
296 
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.
302 #*
303 sub IdentifyDriver {
304 }
305 
306 #** @method IdentifyDriverEx()
307 #*
308 sub IdentifyDriverEx {
309 }
310 
311 #** @method MkdirRecursive()
312 #*
313 sub MkdirRecursive {
314 }
315 
316 #** @method Geo::GDAL::Dataset Open(%params)
317 # Package subroutine.
318 # Open a dataset.
319 # An example, which opens an existing raster dataset for editing:
320 # \code
321 # use Geo::GDAL qw/:all/;
322 # $ds = Open(Name => 'existing.tiff', Access => 'Update');
323 # \endcode
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 [].
330 #
331 # @note This subroutine is imported into the main namespace if Geo::GDAL
332 # is use'd with qw/:all/.
333 #
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.
337 #
338 # @return a new Geo::GDAL::Dataset object if success.
339 #*
340 sub Open {
341  my $p = named_parameters(\@_, Name => '.', Access => 'ReadOnly', Type => 'Any', Options => {}, Files => []);
342  my @flags;
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});
350  unless ($dataset) {
351  my $t = "Failed to open $p->{name}.";
352  $t .= " Is it a ".lc($p->{type})." dataset?" unless uc($p->{type}) eq 'ANY';
353  error($t);
354  }
355  return $dataset;
356 }
357 
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 [])
367 #
368 # An example
369 # \code
370 # $ds = Geo::GDAL::OpenEx(Name => 'existing.tiff', Flags => [qw/RASTER UPDATE/]);
371 # \endcode
372 # @return a new Geo::GDAL::Dataset object.
373 #*
374 sub OpenEx {
375  my $p = named_parameters(\@_, Name => '.', Flags => [], Drivers => [], Options => {}, Files => []);
376  unless ($p) {
377  my $name = shift // '';
378  my @flags = @_;
379  $p = {name => $name, flags => \@flags, drivers => [], options => {}, files => []};
380  }
381  if ($p->{flags}) {
382  my $f = 0;
383  for my $flag (@{$p->{flags}}) {
384  $f |= s2i(open_flag => $flag);
385  }
386  $p->{flags} = $f;
387  }
388  return _OpenEx($p->{name}, $p->{flags}, $p->{drivers}, $p->{options}, $p->{files});
389 }
390 
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.
395 #*
396 sub OpenFlags {
397  return @DATA_TYPES;
398 }
399 
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.
409 #*
410 sub PackCharacter {
411  my $t = shift;
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$/;
422 }
423 
424 #** @method scalar PackedDMSToDec($packed)
425 # Package subroutine.
426 # @param packed DMS as a number DDDMMMSSS.SS
427 # @return decimal degrees
428 #*
429 sub PackedDMSToDec {
430 }
431 
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
436 # into the finder.
437 #*
438 sub PopFinderLocation {
439 }
440 
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).
450 #*
451 sub PushFinderLocation {
452 }
453 
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.
458 #*
459 sub RIOResamplingTypes {
460  return @RIO_RESAMPLING_TYPES;
461 }
462 
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.
467 #*
468 sub ResamplingTypes {
469  return @RESAMPLING_TYPES;
470 }
471 
472 #** @method RmdirRecursive()
473 #*
474 sub RmdirRecursive {
475 }
476 
477 #** @method SetCacheMax($Bytes)
478 # Package subroutine.
479 # @param Bytes New maximum amount of memory for caching within GDAL.
480 #*
481 sub SetCacheMax {
482 }
483 
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.
491 #*
492 sub SetConfigOption {
493 }
494 
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.
500 #*
501 sub UseExceptions {
502 }
503 
504 #** @method VSICurlClearCache()
505 #*
506 sub VSICurlClearCache {
507 }
508 
509 #** @method VSIFEofL()
510 #*
511 sub VSIFEofL {
512 }
513 
514 #** @method VSIFOpenExL()
515 #*
516 sub VSIFOpenExL {
517 }
518 
519 #** @method VSIGetLastErrorMsg()
520 #*
521 sub VSIGetLastErrorMsg {
522 }
523 
524 #** @method VSIGetLastErrorNo()
525 #*
526 sub VSIGetLastErrorNo {
527 }
528 
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.
535 #*
536 sub VersionInfo {
537 }
538 
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.
543 #*
544 sub errstr {
545  my @stack = @error;
546  chomp(@stack);
547  @error = ();
548  return join("\n", @stack);
549 }
550 # usage: named_parameters(\@_, key value list of default parameters);
551 # returns parameters in a hash with low-case-without-_ keys
552 }
553 
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.
558 #*
559 package Geo::GDAL::AsyncReader;
560 
561 use base qw(Geo::GDAL)
562 
563 #** @method GetNextUpdatedRegion()
564 #*
565 sub GetNextUpdatedRegion {
566 }
567 
568 #** @method LockBuffer()
569 #*
570 sub LockBuffer {
571 }
572 
573 #** @method UnlockBuffer()
574 #*
575 sub UnlockBuffer {
576 }
577 
578 #** @class Geo::GDAL::Band
579 # @brief A raster band.
580 # @details
581 #*
582 package Geo::GDAL::Band;
583 
584 use base qw(Geo::GDAL::MajorObject Geo::GDAL)
585 
586 #** @attr $XSize
587 # Object attribute.
588 # scalar (access as $band->{XSize})
589 #*
590 
591 #** @attr $YSize
592 # Object attribute.
593 # scalar (access as $band->{YSize})
594 #*
595 
596 #** @method AdviseRead()
597 #*
598 sub AdviseRead {
599 }
600 
601 #** @method Geo::GDAL::RasterAttributeTable AttributeTable($AttributeTable)
602 # Object method.
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.
606 #*
607 sub AttributeTable {
608  my $self = shift;
609  SetDefaultRAT($self, $_[0]) if @_ and defined $_[0];
610  return unless defined wantarray;
611  my $r = GetDefaultRAT($self);
612  keep($r, $self) if $r;
613 }
614 
615 #** @method list BlockSize()
616 # Object method.
617 # A.k.a GetBlockSize
618 # @return The size of a preferred i/o raster block size as a list
619 # (width, height).
620 #*
621 sub BlockSize {
622 }
623 
624 #** @method list CategoryNames(@names)
625 # Object method.
626 # @param names [optional]
627 # @return
628 #*
629 sub CategoryNames {
630  my $self = shift;
631  SetRasterCategoryNames($self, \@_) if @_;
632  return unless defined wantarray;
633  my $n = GetRasterCategoryNames($self);
634  return @$n;
635 }
636 
637 #** @method scalar Checksum($xoff = 0, $yoff = 0, $xsize = undef, $ysize = undef)
638 # Object method.
639 # Computes a checksum from the raster or a part of it.
640 # @param xoff
641 # @param yoff
642 # @param xsize
643 # @param ysize
644 # @return the checksum.
645 #*
646 sub Checksum {
647 }
648 
649 #** @method hashref ClassCounts($classifier, $progress = undef, $progress_data = undef)
650 # Object method.
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.
655 #
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.
663 #
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.
669 # \code
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];
676 # }
677 # push @$classifier, $tree;
678 # \endcode
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
682 # error is raised.
683 #*
684 sub ClassCounts {
685 }
686 
687 #** @method scalar ColorInterpretation($color_interpretation)
688 # Object method.
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.
695 #*
696 sub ColorInterpretation {
697  my($self, $ci) = @_;
698  if (defined $ci) {
699  $ci = s2i(color_interpretation => $ci);
700  SetRasterColorInterpretation($self, $ci);
701  }
702  return unless defined wantarray;
703  i2s(color_interpretation => GetRasterColorInterpretation($self));
704 }
705 
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.
711 #*
712 sub ColorInterpretations {
713  return @COLOR_INTERPRETATIONS;
714 }
715 
716 #** @method Geo::GDAL::ColorTable ColorTable($ColorTable)
717 # Object method.
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.
723 #*
724 sub ColorTable {
725  my $self = shift;
726  SetRasterColorTable($self, $_[0]) if @_ and defined $_[0];
727  return unless defined wantarray;
728  GetRasterColorTable($self);
729 }
730 
731 #** @method ComputeBandStats($samplestep = 1)
732 # Object method.
733 # @param samplestep the row increment in computing the statistics.
734 # @note Returns uncorrected sample standard deviation.
735 #
736 # See also Geo::GDAL::Band::ComputeStatistics.
737 # @return a list (mean, stddev).
738 #*
739 sub ComputeBandStats {
740 }
741 
742 #** @method ComputeRasterMinMax($approx_ok = 0)
743 # Object method.
744 # @return arrayref MinMax = [min, max]
745 #*
746 sub ComputeRasterMinMax {
747 }
748 
749 #** @method list ComputeStatistics($approx_ok, $progress = undef, $progress_data = undef)
750 # Object method.
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.
754 #
755 # See also Geo::GDAL::Band::ComputeBandStats.
756 # @return a list ($min, $max, $mean, $stddev).
757 #*
758 sub ComputeStatistics {
759 }
760 
761 #** @method Geo::OGR::Layer Contours($DataSource, hashref LayerConstructor, $ContourInterval, $ContourBase, arrayref FixedLevels, $NoDataValue, $IDField, $ElevField, coderef Progress, $ProgressData)
762 # Object method.
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.
765 #
766 # An example:
767 # \code
768 # use Geo::GDAL;
769 # $dem = Geo::GDAL::Open('dem.gtiff');
770 # $contours = $dem->Band->Contours(ContourInterval => 10, ElevField => 'z');
771 # $n = $contours->GetFeatureCount;
772 # \endcode
773 #
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]
785 # @return
786 #*
787 sub Contours {
788  my $self = shift;
789  my $p = named_parameters(\@_,
790  DataSource => undef,
791  LayerConstructor => {Name => 'contours'},
792  ContourInterval => 100,
793  ContourBase => 0,
794  FixedLevels => [],
795  NoDataValue => undef,
796  IDField => -1,
797  ElevField => -1,
798  Progress => undef,
799  ProgressData => undef);
800  $p->{datasource} //= Geo::OGR::GetDriver('Memory')->CreateDataSource('ds');
801  $p->{layerconstructor}->{Schema} //= {};
802  $p->{layerconstructor}->{Schema}{Fields} //= [];
803  my %fields;
804  unless ($p->{idfield} =~ /^[+-]?\d+$/ or $fields{$p->{idfield}}) {
805  push @{$p->{layerconstructor}->{Schema}{Fields}}, {Name => $p->{idfield}, Type => 'Integer'};
806  }
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};
810  }
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+$/;
815  }
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});
820  return $layer;
821 }
822 
823 #** @method CreateMaskBand(@flags)
824 # Object method.
825 # @note May invalidate any previous mask band obtained with Geo::GDAL::Band::GetMaskBand.
826 #
827 # @param flags one or more mask flags. The flags are Geo::GDAL::Band::MaskFlags.
828 #*
829 sub CreateMaskBand {
830  my $self = shift;
831  my $f = 0;
832  if (@_ and $_[0] =~ /^\d$/) {
833  $f = shift;
834  } else {
835  for my $flag (@_) {
836  carp "Unknown mask flag: '$flag'." unless $MASK_FLAGS{$flag};
837  $f |= $MASK_FLAGS{$flag};
838  }
839  }
840  $self->_CreateMaskBand($f);
841 }
842 
843 #** @method scalar DataType()
844 # Object method.
845 # @return The data type of this band. One of Geo::GDAL::DataTypes.
846 #*
847 sub DataType {
848  my $self = shift;
849  return i2s(data_type => $self->{DataType});
850 }
851 
852 #** @method Geo::GDAL::Dataset Dataset()
853 # Object method.
854 # @return The dataset which this band belongs to.
855 #*
856 sub Dataset {
857  my $self = shift;
858  parent($self);
859 }
860 
861 #** @method scalar DeleteNoDataValue()
862 # Object method.
863 #*
864 sub DeleteNoDataValue {
865 }
866 
867 #** @method Geo::GDAL::Band Distance(%params)
868 # Object method.
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.
882 #
883 # @note This GDAL function behind this API is called GDALComputeProximity.
884 #
885 # @return The distance raster.
886 #*
887 sub Distance {
888  my $self = shift;
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};
892  }
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;
897  }
898  Geo::GDAL::ComputeProximity($self, $p->{distance}, $p->{options}, $p->{progress}, $p->{progressdata});
899  return $p->{distance};
900 }
901 
902 #** @method Domains()
903 #*
904 sub Domains {
905  return @DOMAINS;
906 }
907 
908 #** @method Fill($real_part, $imag_part = 0.0)
909 # Object method.
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.
913 #
914 #*
915 sub Fill {
916 }
917 
918 #** @method FillNoData($mask, $max_search_dist, $smoothing_iterations, $options, coderef progress, $progress_data)
919 # Object method.
920 # Interpolate values for cells in this raster. The cells to fill
921 # should be marked in the mask band with zero.
922 #
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).
931 #
932 # <a href="http://www.gdal.org/gdal__alg_8h.html">Documentation for GDAL algorithms</a>
933 #*
934 sub FillNoData {
935 }
936 
937 #** @method FlushCache()
938 # Object method.
939 # Write cached data to disk. There is usually no need to call this
940 # method.
941 #*
942 sub FlushCache {
943 }
944 
945 #** @method scalar GetBandNumber()
946 # Object method.
947 # @return The index of this band in the parent dataset list of bands.
948 #*
949 sub GetBandNumber {
950 }
951 
952 #** @method GetBlockSize()
953 #*
954 sub GetBlockSize {
955 }
956 
957 #** @method list GetDefaultHistogram($force = 1, coderef progress = undef, $progress_data = undef)
958 # Object method.
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).
965 #*
966 sub GetDefaultHistogram {
967 }
968 
969 #** @method list GetHistogram(%parameters)
970 # Object method.
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
987 # use Math::BigInt.
988 # @return a list which contains the count of values in each bucket
989 #*
990 sub GetHistogram {
991  my $self = shift;
992  my $p = named_parameters(\@_,
993  Min => -0.5,
994  Max => 255.5,
995  Buckets => 256,
996  IncludeOutOfRange => 0,
997  ApproxOK => 0,
998  Progress => undef,
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});
1004 }
1005 
1006 #** @method Geo::GDAL::Band GetMaskBand()
1007 # Object method.
1008 # @return the mask band associated with this
1009 # band.
1010 #*
1011 sub GetMaskBand {
1012  my $self = shift;
1013  my $band = _GetMaskBand($self);
1014  keep($band, $self);
1015 }
1016 
1017 #** @method list GetMaskFlags()
1018 # Object method.
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.
1021 #*
1022 sub GetMaskFlags {
1023  my $self = shift;
1024  my $f = $self->_GetMaskFlags;
1025  my @f;
1026  for my $flag (keys %MASK_FLAGS) {
1027  push @f, $flag if $f & $MASK_FLAGS{$flag};
1028  }
1029  return wantarray ? @f : $f;
1030 }
1031 
1032 #** @method scalar GetMaximum()
1033 # Object method.
1034 # @note Call Geo::GDAL::Band::ComputeStatistics before calling
1035 # GetMaximum to make sure the value is computed.
1036 #
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).
1042 #*
1043 sub GetMaximum {
1044 }
1045 
1046 #** @method scalar GetMinimum()
1047 # Object method.
1048 # @note Call Geo::GDAL::Band::ComputeStatistics before calling
1049 # GetMinimum to make sure the value is computed.
1050 #
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).
1056 #*
1057 sub GetMinimum {
1058 }
1059 
1060 #** @method Geo::GDAL::Band GetOverview($index)
1061 # Object method.
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.
1065 #*
1066 sub GetOverview {
1067  my ($self, $index) = @_;
1068  my $band = _GetOverview($self, $index);
1069  keep($band, $self);
1070 }
1071 
1072 #** @method scalar GetOverviewCount()
1073 # Object method.
1074 # @return the number of overviews available of the band.
1075 #*
1076 sub GetOverviewCount {
1077 }
1078 
1079 #** @method list GetStatistics($approx_ok, $force)
1080 # Object method.
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.
1085 #
1086 # @return a list ($min, $max, $mean, $stddev).
1087 #*
1088 sub GetStatistics {
1089 }
1090 
1091 #** @method HasArbitraryOverviews()
1092 # Object method.
1093 # @return true or false.
1094 #*
1095 sub HasArbitraryOverviews {
1096 }
1097 
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).
1108 #*
1109 sub MaskFlags {
1110  my @f = sort {$MASK_FLAGS{$a} <=> $MASK_FLAGS{$b}} keys %MASK_FLAGS;
1111  return @f;
1112 }
1113 
1114 #** @method scalar NoDataValue($NoDataValue)
1115 # Object method.
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
1123 # band.
1124 #*
1125 sub NoDataValue {
1126  my $self = shift;
1127  if (@_ > 0) {
1128  if (defined $_[0]) {
1129  SetNoDataValue($self, $_[0]);
1130  } else {
1131  SetNoDataValue($self, POSIX::FLT_MAX); # hopefully an "out of range" value
1132  }
1133  }
1134  GetNoDataValue($self);
1135 }
1136 
1137 #** @method scalar PackCharacter()
1138 # Object method.
1139 # @return The character to use in Perl pack and unpack for the data of this band.
1140 #*
1141 sub PackCharacter {
1142  my $self = shift;
1143  return Geo::GDAL::PackCharacter($self->DataType);
1144 }
1145 
1146 #** @method Piddle($piddle, $xoff = 0, $yoff = 0, $xsize = <width>, $ysize = <height>, $xdim, $ydim)
1147 # Object method.
1148 # Read or write band data from/into a piddle.
1149 #
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.
1152 #
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).
1158 #*
1159 sub Piddle {
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;
1162  my $self = shift;
1163  my $t = $self->{DataType};
1164  unless (defined wantarray) {
1165  my $pdl = shift;
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) = @_;
1169  $xoff //= 0;
1170  $yoff //= 0;
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;
1176  }
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).";
1180  }
1181  $xsize //= $xdim;
1182  $ysize //= $ydim;
1183  $self->_WriteRaster($xoff, $yoff, $xsize, $ysize, $data, $xdim, $ydim, $t, 0, 0);
1184  return;
1185  }
1186  my ($xoff, $yoff, $xsize, $ysize, $xdim, $ydim, $alg) = @_;
1187  $xoff //= 0;
1188  $yoff //= 0;
1189  $xsize //= $self->{XSize} - $xoff;
1190  $ysize //= $self->{YSize} - $yoff;
1191  $xdim //= $xsize;
1192  $ydim //= $ysize;
1193  $alg //= 'NearestNeighbour';
1194  $alg = s2i(rio_resampling => $alg);
1195  my $buf = $self->_ReadRaster($xoff, $yoff, $xsize, $ysize, $xdim, $ydim, $t, 0, 0, $alg);
1196  my $pdl = PDL->new;
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();
1202  $$data = $buf;
1203  $pdl->upd_data;
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;
1207  return $pdl;
1208 }
1209 
1210 #** @method Geo::OGR::Layer Polygonize(%params)
1211 # Object method.
1212 # Polygonize this raster band.
1213 #
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
1223 # buffer is used.
1224 # - \a Progress Progress function.
1225 # - \a ProgressData Additional parameter for the progress function.
1226 #
1227 # @return Output vector layer.
1228 #*
1229 sub Polygonize {
1230  my $self = shift;
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};
1235  }
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});
1248  } else {
1249  Geo::GDAL::FPolygonize($self, $p->{mask}, $p->{outlayer}, $p->{pixvalfield}, $p->{options}, $p->{progress}, $p->{progressdata});
1250  }
1251  set the srs of the outlayer if it was created here
1252  return $p->{outlayer};
1253 }
1254 
1255 #** @method RasterAttributeTable()
1256 #*
1257 sub RasterAttributeTable {
1258 }
1259 
1260 #** @method scalar ReadRaster(%params)
1261 # Object method.
1262 # Read data from the band.
1263 #
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)
1277 #
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.
1280 #*
1281 sub ReadRaster {
1282  my $self = shift;
1283  my ($width, $height) = $self->Size;
1284  my ($type) = $self->DataType;
1285  my $p = named_parameters(\@_,
1286  XOff => 0,
1287  YOff => 0,
1288  XSize => $width,
1289  YSize => $height,
1290  BufXSize => undef,
1291  BufYSize => undef,
1292  BufType => $type,
1293  BufPixelSpace => 0,
1294  BufLineSpace => 0,
1295  ResampleAlg => 'NearestNeighbour',
1296  Progress => undef,
1297  ProgressData => undef
1298  );
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});
1302 }
1303 
1304 #** @method array reference ReadTile($xoff = 0, $yoff = 0, $xsize = <width>, $ysize = <height>)
1305 # Object method.
1306 # Read band data into a Perl array.
1307 #
1308 # \note Accessing band data in this way is slow. Consider using PDL and Geo::GDAL::Band::Piddle.
1309 #
1310 # Usage example (print the data from a band):
1311 # \code
1312 # print "@$_\n" for ( @{ $band->ReadTile() } );
1313 # \endcode
1314 # Another usage example (process the data of a large dataset that has one band):
1315 # \code
1316 # my($W,$H) = $dataset->Band()->Size();
1317 # my($xoff,$yoff,$w,$h) = (0,0,200,200);
1318 # while (1) {
1319 # if ($xoff >= $W) {
1320 # $xoff = 0;
1321 # $yoff += $h;
1322 # last if $yoff >= $H;
1323 # }
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);
1327 # $xoff += $w;
1328 # }
1329 #
1330 # sub min {
1331 # return $_[0] < $_[1] ? $_[0] : $_[1];
1332 # }
1333 # \endcode
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.
1340 #*
1341 sub ReadTile {
1342  my($self, $xoff, $yoff, $xsize, $ysize, $w_tile, $h_tile, $alg) = @_;
1343  $xoff //= 0;
1344  $yoff //= 0;
1345  $xsize //= $self->{XSize} - $xoff;
1346  $ysize //= $self->{YSize} - $yoff;
1347  $w_tile //= $xsize;
1348  $h_tile //= $ysize;
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;
1355  my $offset = 0;
1356  my @data;
1357  for my $y (0..$h_tile-1) {
1358  my @d = unpack($pc."[$w_tile]", substr($buf, $offset, $w));
1359  push @data, \@d;
1360  $offset += $w;
1361  }
1362  return \@data;
1363 }
1364 
1365 #** @method Reclassify($classifier, $progress = undef, $progress_data = undef)
1366 # Object method.
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
1374 # error is raised.
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.
1381 #*
1382 sub Reclassify {
1383 }
1384 
1385 #** @method RegenerateOverview(Geo::GDAL::Band overview, $resampling, coderef progress, $progress_data)
1386 # Object method.
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]
1392 #*
1393 sub RegenerateOverview {
1394  my $self = shift;
1395  #Geo::GDAL::Band overview, scalar resampling, subref callback, scalar callback_data
1396  my @p = @_;
1397  Geo::GDAL::RegenerateOverview($self, @p);
1398 }
1399 
1400 #** @method RegenerateOverviews(arrayref overviews, $resampling, coderef progress, $progress_data)
1401 # Object method.
1402 # @todo This is not yet available
1403 #
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]
1409 #*
1410 sub RegenerateOverviews {
1411  my $self = shift;
1412  #arrayref overviews, scalar resampling, subref callback, scalar callback_data
1413  my @p = @_;
1414  Geo::GDAL::RegenerateOverviews($self, @p);
1415 }
1416 
1417 #** @method ScaleAndOffset($scale, $offset)
1418 # Object method.
1419 # Scale and offset are used to transform raw cell values into the
1420 # units returned by GetUnits(). The conversion function is:
1421 # \code
1422 # Units value = (raw value * scale) + offset
1423 # \endcode
1424 # @return a list ($scale, $offset), the values are undefined if they
1425 # are not set.
1426 # @since version 1.9 of the bindings.
1427 #*
1428 sub ScaleAndOffset {
1429  my $self = shift;
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);
1436 }
1437 
1438 #** @method list SetDefaultHistogram($min, $max, $histogram)
1439 # Object method.
1440 # @param min
1441 # @param max
1442 # @note See Note in Geo::GDAL::Band::GetHistogram.
1443 # @param histogram reference to an array containing the histogram
1444 #*
1445 sub SetDefaultHistogram {
1446 }
1447 
1448 #** @method SetStatistics($min, $max, $mean, $stddev)
1449 # Object method.
1450 # Save the statistics of the band if possible (the format can save
1451 # arbitrary metadata).
1452 # @param min
1453 # @param max
1454 # @param mean
1455 # @param stddev
1456 #*
1457 sub SetStatistics {
1458 }
1459 
1460 #** @method Geo::GDAL::Band Sieve(%params)
1461 # Object method.
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.
1470 #
1471 # @return The filtered raster band.
1472 #*
1473 sub Sieve {
1474  my $self = shift;
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;
1479  }
1480  my $c = 8;
1481  if ($p->{options}{Connectedness}) {
1482  $c = $p->{options}{Connectedness};
1483  delete $p->{options}{Connectedness};
1484  }
1485  Geo::GDAL::SieveFilter($self, $p->{mask}, $p->{dest}, $p->{threshold}, $c, $p->{options}, $p->{progress}, $p->{progressdata});
1486  return $p->{dest};
1487 }
1488 
1489 #** @method list Size()
1490 # Object method.
1491 # @return The size of the band as a list (width, height).
1492 #*
1493 sub Size {
1494  my $self = shift;
1495  return ($self->{XSize}, $self->{YSize});
1496 }
1497 
1498 #** @method Unit($type)
1499 # Object method.
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.
1504 #*
1505 sub Unit {
1506  my $self = shift;
1507  if (@_ > 0) {
1508  my $unit = shift;
1509  $unit //= '';
1510  SetUnitType($self, $unit);
1511  }
1512  return unless defined wantarray;
1513  GetUnitType($self);
1514 }
1515 
1516 #** @method WriteRaster(%params)
1517 # Object method.
1518 # Write data into the band.
1519 #
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)
1531 #
1532 # <a href="http://www.gdal.org/classGDALDataset.html">Entry in GDAL docs (method RasterIO)</a>
1533 #*
1534 sub WriteRaster {
1535  my $self = shift;
1536  my ($width, $height) = $self->Size;
1537  my ($type) = $self->DataType;
1538  my $p = named_parameters(\@_,
1539  XOff => 0,
1540  YOff => 0,
1541  XSize => $width,
1542  YSize => $height,
1543  Buf => undef,
1544  BufXSize => undef,
1545  BufYSize => undef,
1546  BufType => $type,
1547  BufPixelSpace => 0,
1548  BufLineSpace => 0
1549  );
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});
1553 }
1554 
1555 #** @method WriteTile($data, $xoff = 0, $yoff = 0)
1556 # Object method.
1557 # Write band data from a Perl array.
1558 #
1559 # \note Accessing band data in this way is slow. Consider using PDL and Geo::GDAL::Band::Piddle.
1560 #
1561 # @param data A two-dimensional Perl array, organizes as data->[y][x], y =
1562 # 0..height-1, x = 0..width-1.
1563 # @param xoff
1564 # @param yoff
1565 #
1566 #*
1567 sub WriteTile {
1568  my($self, $data, $xoff, $yoff) = @_;
1569  $xoff //= 0;
1570  $yoff //= 0;
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;
1576  }
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).";
1581  }
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 );
1586  }
1587 }
1588 
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.
1591 # @details
1592 #*
1593 package Geo::GDAL::ColorTable;
1594 
1595 use base qw(Geo::GDAL)
1596 
1597 #** @method Geo::GDAL::ColorTable Clone()
1598 # Object method.
1599 # Clone an existing color table.
1600 # @return a new Geo::GDAL::ColorTable object
1601 #*
1602 sub Clone {
1603 }
1604 
1605 #** @method list Color($index, @color)
1606 # Object method.
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.
1619 #*
1620 sub Color {
1621 }
1622 
1623 #** @method list Colors(@colors)
1624 # Object method.
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).
1630 #*
1631 sub Colors {
1632 }
1633 
1634 #** @method CreateColorRamp($start_index, arrayref start_color, $end_index, arrayref end_color)
1635 # Object method.
1636 # @param start_index
1637 # @param start_color
1638 # @param end_index
1639 # @param end_color
1640 #*
1641 sub CreateColorRamp {
1642 }
1643 
1644 #** @method scalar GetCount()
1645 # Object method.
1646 # @return The number of colors in this color table.
1647 #*
1648 sub GetCount {
1649 }
1650 
1651 #** @method scalar GetPaletteInterpretation()
1652 # Object method.
1653 # @return palette interpretation (string)
1654 #*
1655 sub GetPaletteInterpretation {
1656  my $self = shift;
1657  return i2s(palette_interpretation => GetPaletteInterpretation($self));
1658 }
1659 
1660 #** @method Geo::GDAL::ColorTable new($GDALPaletteInterp = 'RGB')
1661 # Class method.
1662 # Create a new empty color table.
1663 # @return a new Geo::GDAL::ColorTable object
1664 #*
1665 sub new {
1666  my($pkg, $pi) = @_;
1667  $pi //= 'RGB';
1668  $pi = s2i(palette_interpretation => $pi);
1669  my $self = Geo::GDALc::new_ColorTable($pi);
1670  bless $self, $pkg if defined($self);
1671 }
1672 
1673 #** @class Geo::GDAL::Dataset
1674 # @brief A set of associated raster bands or vector layer source.
1675 # @details
1676 #*
1677 package Geo::GDAL::Dataset;
1678 
1679 use base qw(Geo::GDAL::MajorObject Geo::GDAL)
1680 
1681 #** @attr $RasterCount
1682 # scalar (access as $dataset->{RasterCount})
1683 #*
1684 
1685 #** @attr $RasterXSize
1686 # scalar (access as $dataset->{RasterXSize})
1687 #*
1688 
1689 #** @attr $RasterYSize
1690 # scalar (access as $dataset->{RasterYSize})
1691 #*
1692 
1693 #** @method AddBand($datatype = 'Byte', hashref options = {})
1694 # Object method.
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.
1699 #*
1700 sub AddBand {
1701  my ($self, $type, $options) = @_;
1702  $type //= 'Byte';
1703  $type = s2i(data_type => $type);
1704  $self->_AddBand($type, $options);
1705  return unless defined wantarray;
1706  return $self->GetRasterBand($self->{RasterCount});
1707 }
1708 
1709 #** @method AdviseRead()
1710 #*
1711 sub AdviseRead {
1712 }
1713 
1714 #** @method Geo::GDAL::Band Band($index)
1715 # Object method.
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
1720 #*
1721 sub Band {
1722 }
1723 
1724 #** @method list Bands()
1725 # Object method.
1726 # @return a list of new Geo::GDAL::Band objects
1727 #*
1728 sub Bands {
1729  my $self = shift;
1730  my @bands;
1731  for my $i (1..$self->{RasterCount}) {
1732  push @bands, GetRasterBand($self, $i);
1733  }
1734  return @bands;
1735 }
1736 
1737 #** @method BuildOverviews($resampling, arrayref overviews, coderef progress, $progress_data)
1738 # Object method.
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]
1745 #*
1746 sub BuildOverviews {
1747  my $self = shift;
1748  my @p = @_;
1749  $p[0] = uc($p[0]) if $p[0];
1750  eval {
1751  $self->_BuildOverviews(@p);
1752  };
1753  confess(last_error()) if $@;
1754 }
1755 
1756 #** @method Geo::GDAL::Dataset BuildVRT($Dest, arrayref Sources, hashref Options, coderef progress, $progress_data)
1757 # Object method.
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
1762 # dataset objects.
1763 # @param Options See section \ref index_processing_options.
1764 # @return Dataset object
1765 #
1766 # @note This subroutine is imported into the main namespace if Geo::GDAL
1767 # is use'd with qw/:all/.
1768 #*
1769 sub BuildVRT {
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);
1777  } else {
1778  return Geo::GDAL::wrapper_GDALBuildVRT_names($dest, $sources, $options, $progress, $progress_data);
1779  }
1780  } else {
1781  if (blessed($sources->[0])) {
1782  return stdout_redirection_wrapper(
1783  $sources, $dest,
1784  \&Geo::GDAL::wrapper_GDALBuildVRT_objects,
1785  $options, $progress, $progress_data);
1786  } else {
1787  return stdout_redirection_wrapper(
1788  $sources, $dest,
1789  \&Geo::GDAL::wrapper_GDALBuildVRT_names,
1790  $options, $progress, $progress_data);
1791  }
1792  }
1793 }
1794 
1795 #** @method CommitTransaction()
1796 #*
1797 sub CommitTransaction {
1798 }
1799 
1800 #** @method Geo::GDAL::ColorTable ComputeColorTable(%params)
1801 # Object method.
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.
1811 #
1812 # @return a new color table object.
1813 #*
1814 sub ComputeColorTable {
1815  my $self = shift;
1816  my $p = named_parameters(\@_,
1817  Red => undef,
1818  Green => undef,
1819  Blue => undef,
1820  NumColors => 256,
1821  Progress => undef,
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; }
1829  }
1830  }
1831  my $ct = Geo::GDAL::ColorTable->new;
1832  Geo::GDAL::ComputeMedianCutPCT($p->{red},
1833  $p->{green},
1834  $p->{blue},
1835  $p->{numcolors},
1836  $ct, $p->{progress},
1837  $p->{progressdata});
1838  return $ct;
1839 }
1840 
1841 #** @method Geo::OGR::Layer CopyLayer($layer, $name, hashref options = undef)
1842 # Object method.
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.
1847 #*
1848 sub CopyLayer {
1849 }
1850 
1851 #** @method Geo::OGR::Layer CreateLayer(%params)
1852 # Object method.
1853 # @brief Create a new vector layer into this dataset.
1854 #
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'.
1865 #
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.
1870 #
1871 # Example:
1872 # \code
1873 # my $roads = Geo::OGR::Driver('Memory')->Create('road')->
1874 # CreateLayer(
1875 # Fields => [ { Name => 'class',
1876 # Type => 'Integer' },
1877 # { Name => 'geom',
1878 # Type => 'LineString25D' } ] );
1879 # \endcode
1880 #
1881 # @note Many formats allow only one spatial field, which currently
1882 # requires the use of GeometryType.
1883 #
1884 # @return a new Geo::OGR::Layer object.
1885 #*
1886 sub CreateLayer {
1887  my $self = shift;
1888  my $p = named_parameters(\@_,
1889  Name => 'unnamed',
1890  SRS => undef,
1891  GeometryType => 'Unknown',
1892  Options => {},
1893  Schema => undef,
1894  Fields => undef,
1895  ApproxOK => 1);
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};
1902  }
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';
1909  last;
1910  }
1911  }
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);
1916  }
1917  keep($layer, $self);
1918 }
1919 
1920 #** @method CreateMaskBand()
1921 # Object method.
1922 # Add a mask band to the dataset.
1923 #*
1924 sub CreateMaskBand {
1925  return _CreateMaskBand(@_);
1926 }
1927 
1928 #** @method Geo::GDAL::Dataset DEMProcessing($Dest, $Processing, $ColorFilename, hashref Options, coderef progress, $progress_data)
1929 # Object method.
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]
1938 #
1939 #*
1940 sub DEMProcessing {
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(
1944  $dest,
1945  \&Geo::GDAL::wrapper_GDALDEMProcessing,
1946  $Processing, $ColorFilename, $options, $progress, $progress_data
1947  );
1948 }
1949 
1950 #** @method Dataset()
1951 #*
1952 sub Dataset {
1953  my $self = shift;
1954  parent($self);
1955 }
1956 
1957 #** @method DeleteLayer($name)
1958 # Object method.
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.
1962 #*
1963 sub DeleteLayer {
1964  my ($self, $name) = @_;
1965  my $index;
1966  for my $i (0..$self->GetLayerCount-1) {
1967  my $layer = GetLayerByIndex($self, $i);
1968  $index = $i, last if $layer->GetName eq $name;
1969  }
1970  error(2, $name, 'Layer') unless defined $index;
1971  _DeleteLayer($self, $index);
1972 }
1973 
1974 #** @method Geo::GDAL::Band Dither(%params)
1975 # Object method.
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)
1985 #
1986 # @return the destination band.
1987 #
1988 # Usage example. This code converts an RGB JPEG image into a one band PNG image with a color table.
1989 # \code
1990 # my $d = Geo::GDAL::Open('pic.jpg');
1991 # Geo::GDAL::Driver('PNG')->Copy(Name => 'test.png', Src => $d->Dither->Dataset);
1992 # \endcode
1993 #*
1994 sub Dither {
1995  my $self = shift;
1996  my $p = named_parameters(\@_,
1997  Red => undef,
1998  Green => undef,
1999  Blue => undef,
2000  Dest => undef,
2001  ColorTable => undef,
2002  Progress => 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; }
2009  }
2010  }
2011  my ($w, $h) = $self->Size;
2012  $p->{dest} //= Geo::GDAL::Driver('MEM')->Create(Name => 'dithered',
2013  Width => $w,
2014  Height => $h,
2015  Type => 'Byte')->Band;
2016  $p->{colortable}
2017  //= $p->{dest}->ColorTable
2018  // $self->ComputeColorTable(Red => $p->{red},
2019  Green => $p->{green},
2020  Blue => $p->{blue},
2021  Progress => $p->{progress},
2022  ProgressData => $p->{progressdata});
2023  Geo::GDAL::DitherRGB2PCT($p->{red},
2024  $p->{green},
2025  $p->{blue},
2026  $p->{dest},
2027  $p->{colortable},
2028  $p->{progress},
2029  $p->{progressdata});
2030  $p->{dest}->ColorTable($p->{colortable});
2031  return $p->{dest};
2032 }
2033 
2034 #** @method Domains()
2035 #*
2036 sub Domains {
2037  return @DOMAINS;
2038 }
2039 
2040 #** @method Geo::GDAL::Driver Driver()
2041 # Object method.
2042 # @note a.k.a. GetDriver
2043 # @return a Geo::GDAL::Driver object that was used to open or create this dataset.
2044 #*
2045 sub Driver {
2046 }
2047 
2048 #** @method Geo::OGR::Layer ExecuteSQL($statement, $geom = undef, $dialect = "")
2049 # Object method.
2050 # @param statement A SQL statement.
2051 # @param geom A Geo::OGR::Geometry object.
2052 # @param dialect
2053 # @return a new Geo::OGR::Layer object. The data source object will
2054 # exist as long as the layer object exists.
2055 #*
2056 sub ExecuteSQL {
2057  my $self = shift;
2058  my $layer = $self->_ExecuteSQL(@_);
2059  note($layer, "is result set");
2060  keep($layer, $self);
2061 }
2062 
2063 #** @method Geo::GDAL::Extent Extent(@params)
2064 # Object method.
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.
2068 #*
2069 sub Extent {
2070  my $self = shift;
2071  my $t = $self->GeoTransform;
2072  my $extent = $t->Extent($self->Size);
2073  if (@_) {
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;
2077  my $xmax = $xmin;
2078  for my $x (@$x) {
2079  $xmin = $x if $x < $xmin;
2080  $xmax = $x if $x > $xmax;
2081  }
2082  my $ymin = shift @$y;
2083  my $ymax = $ymin;
2084  for my $y (@$y) {
2085  $ymin = $y if $y < $ymin;
2086  $ymax = $y if $y > $ymax;
2087  }
2088  $extent = Geo::GDAL::Extent->new($xmin, $ymin, $xmax, $ymax);
2089  }
2090  return $extent;
2091 }
2092 
2093 #** @method list GCPs(@GCPs, Geo::OSR::SpatialReference sr)
2094 # Object method.
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.
2099 #*
2100 sub GCPs {
2101  my $self = shift;
2102  if (@_ > 0) {
2103  my $proj = pop @_;
2104  $proj = $proj->Export('WKT') if $proj and ref($proj);
2105  SetGCPs($self, \@_, $proj);
2106  }
2107  return unless defined wantarray;
2108  my $proj = Geo::OSR::SpatialReference->new(GetGCPProjection($self));
2109  my $GCPs = GetGCPs($self);
2110  return (@$GCPs, $proj);
2111 }
2112 
2113 #** @method Geo::GDAL::GeoTransform GeoTransform(Geo::GDAL::GeoTransform $geo_transform)
2114 # Object method.
2115 # Transformation from cell coordinates (column,row) to projection
2116 # coordinates (x,y)
2117 # \code
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]
2120 # \endcode
2121 # @param geo_transform [optional]
2122 # @return the geo transform in a non-void context.
2123 #*
2124 sub GeoTransform {
2125  my $self = shift;
2126  eval {
2127  if (@_ == 1) {
2128  SetGeoTransform($self, $_[0]);
2129  } elsif (@_ > 1) {
2130  SetGeoTransform($self, \@_);
2131  }
2132  };
2133  confess(last_error()) if $@;
2134  return unless defined wantarray;
2135  my $t = GetGeoTransform($self);
2136  if (wantarray) {
2137  return @$t;
2138  } else {
2139  return Geo::GDAL::GeoTransform->new($t);
2140  }
2141 }
2142 
2143 #** @method GetDriver()
2144 #*
2145 sub GetDriver {
2146 }
2147 
2148 #** @method list GetFileList()
2149 # Object method.
2150 # @return list of files GDAL believes to be part of this dataset.
2151 #*
2152 sub GetFileList {
2153 }
2154 
2155 #** @method scalar GetGCPProjection()
2156 # Object method.
2157 # @return projection string.
2158 #*
2159 sub GetGCPProjection {
2160 }
2161 
2162 #** @method Geo::OGR::Layer GetLayer($name)
2163 # Object method.
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.
2168 #*
2169 sub GetLayer {
2170  my($self, $name) = @_;
2171  my $layer = defined $name ? GetLayerByName($self, "$name") : GetLayerByIndex($self, 0);
2172  $name //= '';
2173  error(2, $name, 'Layer') unless $layer;
2174  keep($layer, $self);
2175 }
2176 
2177 #** @method list GetLayerNames()
2178 # Object method.
2179 # @note Delivers the functionality of undocumented method GetLayerCount.
2180 # @return a list of the names of the layers this data source provides.
2181 #*
2182 sub GetLayerNames {
2183  my $self = shift;
2184  my @names;
2185  for my $i (0..$self->GetLayerCount-1) {
2186  my $layer = GetLayerByIndex($self, $i);
2187  push @names, $layer->GetName;
2188  }
2189  return @names;
2190 }
2191 
2192 #** @method GetNextFeature()
2193 #*
2194 sub GetNextFeature {
2195 }
2196 
2197 #** @method GetStyleTable()
2198 #*
2199 sub GetStyleTable {
2200 }
2201 
2202 #** @method Geo::GDAL::Dataset Grid($Dest, hashref Options)
2203 # Object method.
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.
2209 #*
2210 sub Grid {
2211  my ($self, $dest, $options, $progress, $progress_data) = @_;
2212  $options = Geo::GDAL::GDALGridOptions->new(make_processing_options($options));
2213  return $self->stdout_redirection_wrapper(
2214  $dest,
2215  \&Geo::GDAL::wrapper_GDALGrid,
2216  $options, $progress, $progress_data
2217  );
2218 }
2219 
2220 #** @method scalar Info(hashref Options)
2221 # Object method.
2222 # Information about this dataset.
2223 # @param Options See section \ref index_processing_options.
2224 #*
2225 sub Info {
2226  my ($self, $o) = @_;
2227  $o = Geo::GDAL::GDALInfoOptions->new(make_processing_options($o));
2228  return GDALInfo($self, $o);
2229 }
2230 
2231 #** @method Geo::GDAL::Dataset Nearblack($Dest, hashref Options, coderef progress, $progress_data)
2232 # Object method.
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
2240 # was an error.
2241 #*
2242 sub Nearblack {
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);
2248  } else {
2249  return $self->stdout_redirection_wrapper(
2250  $dest,
2251  \&Geo::GDAL::wrapper_GDALNearblackDestName,
2252  $options, $progress, $progress_data
2253  );
2254  }
2255 }
2256 
2257 #** @method Geo::GDAL::Dataset Open()
2258 # Package subroutine.
2259 # The same as Geo::GDAL::Open
2260 #*
2261 sub Open {
2262 }
2263 
2264 #** @method Geo::GDAL::Dataset OpenShared()
2265 # Package subroutine.
2266 # The same as Geo::GDAL::OpenShared
2267 #*
2268 sub OpenShared {
2269 }
2270 
2271 #** @method Geo::GDAL::Dataset Rasterize($Dest, hashref Options, coderef progress, $progress_data)
2272 # Object method.
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
2279 # was an error.
2280 #
2281 #*
2282 sub Rasterize {
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);
2288  } else {
2289  # TODO: options need to force a new raster be made, otherwise segfault
2290  return $self->stdout_redirection_wrapper(
2291  $dest,
2292  \&Geo::GDAL::wrapper_GDALRasterizeDestName,
2293  $options, $progress, $progress_data
2294  );
2295  }
2296 }
2297 
2298 #** @method scalar ReadRaster(%params)
2299 # Object method.
2300 # Read data from the dataset.
2301 #
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)
2317 #
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.
2320 #*
2321 sub ReadRaster {
2322  my $self = shift;
2323  my ($width, $height) = $self->Size;
2324  my ($type) = $self->Band->DataType;
2325  my $p = named_parameters(\@_,
2326  XOff => 0,
2327  YOff => 0,
2328  XSize => $width,
2329  YSize => $height,
2330  BufXSize => undef,
2331  BufYSize => undef,
2332  BufType => $type,
2333  BandList => [1],
2334  BufPixelSpace => 0,
2335  BufLineSpace => 0,
2336  BufBandSpace => 0,
2337  ResampleAlg => 'NearestNeighbour',
2338  Progress => undef,
2339  ProgressData => undef
2340  );
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});
2344 }
2345 
2346 #** @method ReadTile()
2347 #*
2348 sub ReadTile {
2349  my ($self, $xoff, $yoff, $xsize, $ysize, $w_tile, $h_tile, $alg) = @_;
2350  my @data;
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);
2353  }
2354  return \@data;
2355 }
2356 
2357 #** @method ReleaseResultSet($layer)
2358 # Object method.
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.
2362 #*
2363 sub ReleaseResultSet {
2364  # a no-op, _ReleaseResultSet is called from Layer::DESTROY
2365 }
2366 
2367 #** @method ResetReading()
2368 #*
2369 sub ResetReading {
2370 }
2371 
2372 #** @method RollbackTransaction()
2373 #*
2374 sub RollbackTransaction {
2375 }
2376 
2377 #** @method SetStyleTable()
2378 #*
2379 sub SetStyleTable {
2380 }
2381 
2382 #** @method list Size()
2383 # Object method.
2384 # @return (width, height)
2385 #*
2386 sub Size {
2387  my $self = shift;
2388  return ($self->{RasterXSize}, $self->{RasterYSize});
2389 }
2390 
2391 #** @method Geo::OSR::SpatialReference SpatialReference(Geo::OSR::SpatialReference sr)
2392 # Object method.
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.
2399 #*
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);
2405  return unless $p;
2406  return Geo::OSR::SpatialReference->new(WKT => $p);
2407  }
2408 }
2409 
2410 #** @method StartTransaction()
2411 #*
2412 sub StartTransaction {
2413 }
2414 
2415 #** @method TestCapability()
2416 #*
2417 sub TestCapability {
2418  return _TestCapability(@_);
2419 }
2420 
2421 #** @method Tile(Geo::GDAL::Extent e)
2422 # Object method.
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).
2428 #*
2429 sub Tile {
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);
2443 }
2444 
2445 #** @method Geo::GDAL::Dataset Translate($Dest, hashref Options, coderef progress, $progress_data)
2446 # Object method.
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.
2454 #*
2455 sub Translate {
2456  my ($self, $dest, $options, $progress, $progress_data) = @_;
2457  return $self->stdout_redirection_wrapper(
2458  $dest,
2459 }
2460 
2461 #** @method Geo::GDAL::Dataset Warp($Dest, hashref Options, coderef progress, $progress_data)
2462 # Object method.
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.
2469 #*
2470 sub Warp {
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);
2478  } else {
2479  return stdout_redirection_wrapper(
2480  $self,
2481  $dest,
2482  \&Geo::GDAL::wrapper_GDALWarpDestName,
2483  $options, $progress, $progress_data
2484  );
2485  }
2486 }
2487 
2488 #** @method Geo::GDAL::Dataset Warped(%params)
2489 # Object method.
2490 # Create a virtual warped dataset from this dataset.
2491 #
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).
2497 #
2498 # # <a href="http://www.gdal.org/gdalwarper_8h.html">Documentation for GDAL warper.</a>
2499 #
2500 # @return a new Geo::GDAL::Dataset object
2501 #*
2502 sub Warped {
2503  my $self = shift;
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};
2507  }
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
2511 }
2512 
2513 #** @method WriteRaster(%params)
2514 # Object method.
2515 # Write data into the dataset.
2516 #
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)
2530 #
2531 # <a href="http://www.gdal.org/classGDALDataset.html">Entry in GDAL docs (method RasterIO)</a>
2532 #*
2533 sub WriteRaster {
2534  my $self = shift;
2535  my ($width, $height) = $self->Size;
2536  my ($type) = $self->Band->DataType;
2537  my $p = named_parameters(\@_,
2538  XOff => 0,
2539  YOff => 0,
2540  XSize => $width,
2541  YSize => $height,
2542  Buf => undef,
2543  BufXSize => undef,
2544  BufYSize => undef,
2545  BufType => $type,
2546  BandList => [1],
2547  BufPixelSpace => 0,
2548  BufLineSpace => 0,
2549  BufBandSpace => 0
2550  );
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});
2553 }
2554 
2555 #** @method WriteTile()
2556 #*
2557 sub WriteTile {
2558  my ($self, $data, $xoff, $yoff) = @_;
2559  $xoff //= 0;
2560  $yoff //= 0;
2561  for my $i (0..$self->Bands-1) {
2562  $self->Band($i+1)->WriteTile($data->[$i], $xoff, $yoff);
2563  }
2564 }
2565 
2566 #** @class Geo::GDAL::Driver
2567 # @brief A driver for a specific dataset format.
2568 # @details
2569 #*
2570 package Geo::GDAL::Driver;
2571 
2572 use base qw(Geo::GDAL::MajorObject Geo::GDAL)
2573 
2574 #** @attr $HelpTopic
2575 # $driver->{HelpTopic}
2576 #*
2577 
2578 #** @attr $LongName
2579 # $driver->{LongName}
2580 #*
2581 
2582 #** @attr $ShortName
2583 # $driver->{ShortName}
2584 #*
2585 
2586 #** @method list Capabilities()
2587 # Object method.
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
2591 # driver has.
2592 #
2593 # Currently capabilities are:
2594 # CREATE, CREATECOPY, DEFAULT_FIELDS, NOTNULL_FIELDS, NOTNULL_GEOMFIELDS, OPEN, RASTER, VECTOR, and VIRTUALIO.
2595 #
2596 # Examples.
2597 # \code
2598 # @all_capabilities = Geo::GDAL::Driver::Capabilities;
2599 # @capabilities_of_the_geotiff_driver = Geo::GDAL::Driver('GTiff')->Capabilities;
2600 # \endcode
2601 #*
2602 sub Capabilities {
2603  my $self = shift;
2604  return @CAPABILITIES unless $self;
2605  my $h = $self->GetMetadata;
2606  my @cap;
2607  for my $cap (@CAPABILITIES) {
2608  my $test = $h->{'DCAP_'.uc($cap)};
2609  push @cap, $cap if defined($test) and $test eq 'YES';
2610  }
2611  return @cap;
2612 }
2613 
2614 #** @method Geo::GDAL::Dataset Copy(%params)
2615 # Object method.
2616 # Create a new raster Geo::GDAL::Dataset as a copy of an existing dataset.
2617 # @note a.k.a. CreateCopy
2618 #
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.
2628 #*
2629 sub Copy {
2630  my $self = shift;
2631  my $p = named_parameters(\@_, Name => 'unnamed', Src => undef, Strict => 1, Options => {}, Progress => undef, ProgressData => undef);
2632  return $self->stdout_redirection_wrapper(
2633  $p->{name},
2634  $self->can('_CreateCopy'),
2635  $p->{src}, $p->{strict}, $p->{options}, $p->{progress}, $p->{progressdata});
2636 }
2637 
2638 #** @method CopyFiles($NewName, $OldName)
2639 # Object method.
2640 # Copy the files of a dataset.
2641 # @param NewName String.
2642 # @param OldName String.
2643 #*
2644 sub CopyFiles {
2645 }
2646 
2647 #** @method Geo::GDAL::Dataset Create(%params)
2648 # Object method.
2649 # Create a raster dataset using this driver.
2650 # @note a.k.a. CreateDataset
2651 #
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 {}).
2659 #
2660 # @return A new Geo::GDAL::Dataset object.
2661 #*
2662 sub Create {
2663  my $self = shift;
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(
2667  $p->{name},
2668  $self->can('_Create'),
2669  $p->{width}, $p->{height}, $p->{bands}, $type, $p->{options}
2670  );
2671 }
2672 
2673 #** @method list CreationDataTypes()
2674 # Object method.
2675 # @return a list of data types that can be used for new datasets of this format. A subset of Geo::GDAL::DataTypes
2676 #*
2677 sub CreationDataTypes {
2678  my $self = shift;
2679  my $h = $self->GetMetadata;
2680  return split /\s+/, $h->{DMD_CREATIONDATATYPES} if $h->{DMD_CREATIONDATATYPES};
2681 }
2682 
2683 #** @method list CreationOptionList()
2684 # Object method.
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.
2687 #*
2688 sub CreationOptionList {
2689  my $self = shift;
2690  my @options;
2691  my $h = $self->GetMetadata->{DMD_CREATIONOPTIONLIST};
2692  if ($h) {
2693  $h = ParseXMLString($h);
2694  my($type, $value) = NodeData($h);
2695  if ($value eq 'CreationOptionList') {
2696  for my $o (Children($h)) {
2697  my %option;
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;
2703  } else {
2704  $option{$key} = $value;
2705  }
2706  }
2707  push @options, \%option;
2708  }
2709  }
2710  }
2711  return @options;
2712 }
2713 
2714 #** @method Delete($name)
2715 # Object method.
2716 # @param name
2717 #*
2718 sub Delete {
2719 }
2720 
2721 #** @method Domains()
2722 #*
2723 sub Domains {
2724  return @DOMAINS;
2725 }
2726 
2727 #** @method scalar Extension()
2728 # Object method.
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.
2732 #*
2733 sub Extension {
2734  my $self = shift;
2735  my $h = $self->GetMetadata;
2736  if (wantarray) {
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
2742  }
2743  return @e;
2744  } else {
2745  my $e = $h->{DMD_EXTENSION};
2746  return '' if $e =~ /\//; # ILWIS returns mpr/mpl
2747  $e =~ s/^\.//;
2748  return $e;
2749  }
2750 }
2751 
2752 #** @method scalar MIMEType()
2753 # Object method.
2754 # @return a suggested MIME type for datasets.
2755 #*
2756 sub MIMEType {
2757  my $self = shift;
2758  my $h = $self->GetMetadata;
2759  return $h->{DMD_MIMETYPE};
2760 }
2761 
2762 #** @method scalar Name()
2763 # Object method.
2764 # @return The short name of the driver.
2765 #*
2766 sub Name {
2767  my $self = shift;
2768  return $self->{ShortName};
2769 }
2770 
2771 #** @method Open()
2772 # Object method.
2773 # The same as Geo::GDAL::Open except that only this driver is allowed.
2774 #*
2775 sub Open {
2776  my $self = shift;
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;
2783  return $dataset;
2784 }
2785 
2786 #** @method Rename($NewName, $OldName)
2787 # Object method.
2788 # Rename (move) a GDAL dataset.
2789 # @param NewName String.
2790 # @param OldName String.
2791 #*
2792 sub Rename {
2793 }
2794 
2795 #** @method scalar TestCapability($cap)
2796 # Object method.
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.
2800 #*
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;
2805 }
2806 
2807 #** @method stdout_redirection_wrapper()
2808 #*
2809 sub stdout_redirection_wrapper {
2810  my ($self, $name, $sub, @params) = @_;
2811  my $object = 0;
2812  if ($name && blessed $name) {
2813  $object = $name;
2814  my $ref = $object->can('write');
2815  VSIStdoutSetRedirection($ref);
2816  $name = '/vsistdout/';
2817  }
2818  my $ds;
2819  eval {
2820  $ds = $sub->($self, $name, @params);
2821  };
2822  if ($object) {
2823  if ($ds) {
2824  $Geo::GDAL::stdout_redirection{tied(%$ds)} = $object;
2825  } else {
2826  VSIStdoutUnsetRedirection();
2827  $object->close;
2828  }
2829  }
2830  confess(last_error()) if $@;
2831  confess("Failed. Use Geo::OGR::Driver for vector drivers.") unless $ds;
2832  return $ds;
2833 }
2834 
2835 #** @class Geo::GDAL::Extent
2836 # @brief A rectangular area in projection coordinates: xmin, ymin, xmax, ymax.
2837 #*
2838 package Geo::GDAL::Extent;
2839 
2840 #** @method ExpandToInclude($extent)
2841 # Package subroutine.
2842 # Extends this extent to include the other extent.
2843 # @param extent Another Geo::GDAL::Extent object.
2844 #*
2845 sub ExpandToInclude {
2846  my ($self, $e) = @_;
2847  return if $e->IsEmpty;
2848  if ($self->IsEmpty) {
2849  @$self = @$e;
2850  } else {
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];
2855  }
2856 }
2857 
2858 #** @method IsEmpty()
2859 #*
2860 sub IsEmpty {
2861  my $self = shift;
2862  return $self->[2] < $self->[0];
2863 }
2864 
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.
2870 #*
2871 sub Overlap {
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];
2879  return $ret;
2880 }
2881 
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.
2886 #*
2887 sub Overlaps {
2888  my ($self, $e) = @_;
2889  return $self->[0] < $e->[2] && $self->[2] > $e->[0] && $self->[1] < $e->[3] && $self->[3] > $e->[1];
2890 }
2891 
2892 #** @method list Size()
2893 # Package subroutine.
2894 # @return A list ($width, $height).
2895 #*
2896 sub Size {
2897  my $self = shift;
2898  return (0,0) if $self->IsEmpty;
2899  return ($self->[2] - $self->[0], $self->[3] - $self->[1]);
2900 }
2901 
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).
2906 #*
2907 sub new {
2908  my $class = shift;
2909  my $self;
2910  if (@_ == 0) {
2911  $self = [0,0,-1,0];
2912  } elsif (ref $_[0]) {
2913  @$self = @{$_[0]};
2914  } else {
2915  @$self = @_;
2916  }
2917  bless $self, $class;
2918  return $self;
2919 }
2920 
2921 #** @class Geo::GDAL::GCP
2922 # @brief A ground control point for georeferencing rasters.
2923 # @details
2924 #*
2925 package Geo::GDAL::GCP;
2926 
2927 use base qw(Geo::GDAL)
2928 
2929 #** @attr $Column
2930 # cell x coordinate (access as $gcp->{Column})
2931 #*
2932 
2933 #** @attr $Id
2934 # unique identifier (string) (access as $gcp->{Id})
2935 #*
2936 
2937 #** @attr $Info
2938 # informational message (access as $gcp->{Info})
2939 #*
2940 
2941 #** @attr $Row
2942 # cell y coordinate (access as $gcp->{Row})
2943 #*
2944 
2945 #** @attr $X
2946 # projection coordinate (access as $gcp->{X})
2947 #*
2948 
2949 #** @attr $Y
2950 # projection coordinate (access as $gcp->{Y})
2951 #*
2952 
2953 #** @attr $Z
2954 # projection coordinate (access as $gcp->{Z})
2955 #*
2956 
2957 #** @method scalar new($x = 0.0, $y = 0.0, $z = 0.0, $column = 0.0, $row = 0.0, $info = "", $id = "")
2958 # Class method.
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
2967 #*
2968 sub new {
2969  my $pkg = shift;
2970  my $self = Geo::GDALc::new_GCP(@_);
2971  bless $self, $pkg if defined($self);
2972 }
2973 
2974 #** @class Geo::GDAL::GeoTransform
2975 # @brief An array of affine transformation coefficients.
2976 # @details The geo transformation has the form
2977 # \code
2978 # x = a + column * b + row * c
2979 # y = d + column * e + row * f
2980 # \endcode
2981 # where
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].
2985 #*
2986 package Geo::GDAL::GeoTransform;
2987 
2988 #** @method Apply($x, $y)
2989 # Object method.
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.
2994 #*
2995 sub Apply {
2996  my ($self, $columns, $rows) = @_;
2997  return Geo::GDAL::ApplyGeoTransform($self, $columns, $rows) unless ref($columns) eq 'ARRAY';
2998  my (@x, @y);
2999  for my $i (0..$#$columns) {
3000  ($x[$i], $y[$i]) =
3001  Geo::GDAL::ApplyGeoTransform($self, $columns->[$i], $rows->[$i]);
3002  }
3003  return (\@x, \@y);
3004 }
3005 
3006 #** @method Inv()
3007 # Object method.
3008 # @return a new Geo::GDAL::GeoTransform object, which is the inverse
3009 # of this one (in void context changes this object).
3010 #*
3011 sub Inv {
3012  my $self = shift;
3013  my @inv = Geo::GDAL::InvGeoTransform($self);
3014  return Geo::GDAL::GeoTransform->new(@inv) if defined wantarray;
3015  @$self = @inv;
3016 }
3017 
3018 #** @method NorthUp()
3019 #*
3020 sub NorthUp {
3021  my $self = shift;
3022  return $self->[2] == 0 && $self->[4] == 0;
3023 }
3024 
3025 #** @method new(@params)
3026 # Class method.
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).
3033 #
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.
3039 #*
3040 sub new {
3041  my $class = shift;
3042  my $self;
3043  if (@_ == 0) {
3044  $self = [0,1,0,0,0,1];
3045  } elsif (ref $_[0]) {
3046  @$self = @{$_[0]};
3047  } elsif ($_[0] =~ /^[a-zA-Z]/i) {
3048  my $p = named_parameters(\@_, GCPs => undef, ApproxOK => 1, Extent => undef, CellSize => 1);
3049  if ($p->{gcps}) {
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});
3053  } else {
3054  error("Missing GCPs or Extent");
3055  }
3056  } else {
3057  my @a = @_;
3058  $self = \@a;
3059  }
3060  bless $self, $class;
3061 }
3062 
3063 #** @class Geo::GDAL::MajorObject
3064 # @brief An object, which holds meta data.
3065 # @details
3066 #*
3067 package Geo::GDAL::MajorObject;
3068 
3069 use base qw(Geo::GDAL)
3070 
3071 #** @method scalar Description($description)
3072 # Object method.
3073 # @param description [optional]
3074 # @return the description in a non-void context.
3075 #*
3076 sub Description {
3077  my($self, $desc) = @_;
3078  SetDescription($self, $desc) if defined $desc;
3079  GetDescription($self) if defined wantarray;
3080 }
3081 
3082 #** @method Domains()
3083 # Package subroutine.
3084 # @return the class specific DOMAINS list
3085 #*
3086 sub Domains {
3087  return @DOMAINS;
3088 }
3089 
3090 #** @method scalar GetDescription()
3091 # Object method.
3092 # @return
3093 #*
3094 sub GetDescription {
3095 }
3096 
3097 #** @method hash reference GetMetadata($domain = "")
3098 # Object method.
3099 # @note see Metadata
3100 # @param domain
3101 # @return
3102 #*
3103 sub GetMetadata {
3104 }
3105 
3106 #** @method GetMetadataDomainList()
3107 #*
3108 sub GetMetadataDomainList {
3109 }
3110 
3111 #** @method hash reference Metadata(hashref metadata = undef, $domain = '')
3112 # Object method.
3113 # @param metadata
3114 # @param domain
3115 # @return the metadata in a non-void context.
3116 #*
3117 sub Metadata {
3118  my $self = shift,
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;
3123 }
3124 
3125 #** @method SetDescription($NewDesc)
3126 # Object method.
3127 # @param NewDesc
3128 #
3129 #*
3130 sub SetDescription {
3131 }
3132 
3133 #** @method SetMetadata(hashref metadata, $domain = "")
3134 # Object method.
3135 # @note see Metadata
3136 # @param metadata
3137 # @param domain
3138 #
3139 #*
3140 sub SetMetadata {
3141 }
3142 
3143 #** @class Geo::GDAL::RasterAttributeTable
3144 # @brief An attribute table in a raster band.
3145 # @details
3146 #*
3147 package Geo::GDAL::RasterAttributeTable;
3148 
3149 use base qw(Geo::GDAL)
3150 
3151 #** @method Band()
3152 #*
3153 sub Band {
3154  my $self = shift;
3155  parent($self);
3156 }
3157 
3158 #** @method ChangesAreWrittenToFile()
3159 #*
3160 sub ChangesAreWrittenToFile {
3161 }
3162 
3163 #** @method Geo::GDAL::RasterAttributeTable Clone()
3164 # Object method.
3165 # @return a new Geo::GDAL::RasterAttributeTable object
3166 #*
3167 sub Clone {
3168 }
3169 
3170 #** @method hash Columns(%columns)
3171 # Object method.
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
3176 #*
3177 sub Columns {
3178  my $self = shift;
3179  my %columns;
3180  if (@_) { # create columns
3181  %columns = @_;
3182  for my $name (keys %columns) {
3183  $self->CreateColumn($name, $columns{$name}{Type}, $columns{$name}{Usage});
3184  }
3185  }
3186  %columns = ();
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);
3191  }
3192  return %columns;
3193 }
3194 
3195 #** @method CreateColumn($name, $type, $usage)
3196 # Object method.
3197 # @param name
3198 # @param type one of FieldTypes
3199 # @param usage one of FieldUsages
3200 #*
3201 sub CreateColumn {
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';
3205  }
3206  $type = s2i(rat_field_type => $type);
3207  $usage = s2i(rat_field_usage => $usage);
3208  _CreateColumn($self, $name, $type, $usage);
3209 }
3210 
3211 #** @method DumpReadable()
3212 #*
3213 sub DumpReadable {
3214 }
3215 
3216 #** @method list FieldTypes()
3217 # Package subroutine.
3218 # @return
3219 #*
3220 sub FieldTypes {
3221  return @FIELD_TYPES;
3222 }
3223 
3224 #** @method list FieldUsages()
3225 # Package subroutine.
3226 # @return
3227 #*
3228 sub FieldUsages {
3229  return @FIELD_USAGES;
3230 }
3231 
3232 #** @method scalar GetColOfUsage($usage)
3233 # Object method.
3234 # @param usage
3235 # @return
3236 #*
3237 sub GetColOfUsage {
3238  my($self, $usage) = @_;
3239  _GetColOfUsage($self, s2i(rat_field_usage => $usage));
3240 }
3241 
3242 #** @method scalar GetColumnCount()
3243 # Object method.
3244 # @return
3245 #*
3246 sub GetColumnCount {
3247 }
3248 
3249 #** @method scalar GetNameOfCol($column)
3250 # Object method.
3251 # @param column
3252 # @return
3253 #*
3254 sub GetNameOfCol {
3255 }
3256 
3257 #** @method scalar GetRowCount()
3258 # Object method.
3259 #*
3260 sub GetRowCount {
3261 }
3262 
3263 #** @method scalar GetRowOfValue($value)
3264 # Object method.
3265 # @param value a cell value
3266 # @return row index or -1
3267 #*
3268 sub GetRowOfValue {
3269 }
3270 
3271 #** @method scalar GetTypeOfCol($column)
3272 # Object method.
3273 # @param column
3274 # @return
3275 #*
3276 sub GetTypeOfCol {
3277  my($self, $col) = @_;
3278  i2s(rat_field_type => _GetTypeOfCol($self, $col));
3279 }
3280 
3281 #** @method scalar GetUsageOfCol($column)
3282 # Object method.
3283 # @param column
3284 # @return
3285 #*
3286 sub GetUsageOfCol {
3287  my($self, $col) = @_;
3288  i2s(rat_field_usage => _GetUsageOfCol($self, $col));
3289 }
3290 
3291 #** @method scalar GetValueAsDouble($row, $column)
3292 # Object method.
3293 # @param row
3294 # @param column
3295 # @return
3296 #*
3297 sub GetValueAsDouble {
3298 }
3299 
3300 #** @method scalar GetValueAsInt($row, $column)
3301 # Object method.
3302 # @param row
3303 # @param column
3304 # @return
3305 #*
3306 sub GetValueAsInt {
3307 }
3308 
3309 #** @method scalar GetValueAsString($row, $column)
3310 # Object method.
3311 # @param row
3312 # @param column
3313 # @return
3314 #*
3315 sub GetValueAsString {
3316 }
3317 
3318 #** @method LinearBinning($Row0MinIn, $BinSizeIn)
3319 # Object method.
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.
3323 #*
3324 sub LinearBinning {
3325  my $self = shift;
3326  SetLinearBinning($self, @_) if @_ > 0;
3327  return unless defined wantarray;
3328  my @a = GetLinearBinning($self);
3329  return $a[0] ? ($a[1], $a[2]) : ();
3330 }
3331 
3332 #** @method SetRowCount($count)
3333 # Object method.
3334 # @param count
3335 #
3336 #*
3337 sub SetRowCount {
3338 }
3339 
3340 #** @method SetValueAsDouble($row, $column, $value)
3341 # Object method.
3342 # @param row
3343 # @param column
3344 # @param value
3345 #
3346 #*
3347 sub SetValueAsDouble {
3348 }
3349 
3350 #** @method SetValueAsInt($row, $column, $value)
3351 # Object method.
3352 # @param row
3353 # @param column
3354 # @param value
3355 #
3356 #*
3357 sub SetValueAsInt {
3358 }
3359 
3360 #** @method SetValueAsString($row, $column, $value)
3361 # Object method.
3362 # @param row
3363 # @param column
3364 # @param value
3365 #
3366 #*
3367 sub SetValueAsString {
3368 }
3369 
3370 #** @method scalar Value($row, $column, $value)
3371 # Object method.
3372 # @param row
3373 # @param column
3374 # @param value [optional]
3375 # @return
3376 #*
3377 sub Value {
3378  my($self, $row, $column) = @_;
3379  SetValueAsString($self, $row, $column, $_[3]) if defined $_[3];
3380  return unless defined wantarray;
3381  GetValueAsString($self, $row, $column);
3382 }
3383 
3384 #** @method Geo::GDAL::RasterAttributeTable new()
3385 # Class method.
3386 # @return a new Geo::GDAL::RasterAttributeTable object
3387 #*
3388 sub new {
3389  my $pkg = shift;
3390  my $self = Geo::GDALc::new_RasterAttributeTable(@_);
3391  bless $self, $pkg if defined($self);
3392 }
3393 
3394 #** @class Geo::GDAL::Transformer
3395 # @brief
3396 # @details This class is not yet documented for the GDAL Perl bindings.
3397 # @todo Test and document.
3398 #*
3399 package Geo::GDAL::Transformer;
3400 
3401 use base qw(Geo::GDAL)
3402 
3403 #** @method TransformGeolocations()
3404 #*
3405 sub TransformGeolocations {
3406 }
3407 
3408 #** @method TransformPoint()
3409 #*
3410 sub TransformPoint {
3411 }
3412 
3413 #** @method new()
3414 #*
3415 sub new {
3416  my $pkg = shift;
3417  my $self = Geo::GDALc::new_Transformer(@_);
3418  bless $self, $pkg if defined($self);
3419 }
3420 
3421 #** @class Geo::GDAL::VSIF
3422 # @brief A GDAL virtual file system.
3423 # @details
3424 #*
3425 package Geo::GDAL::VSIF;
3426 
3427 use base qw(Exporter)
3428 
3429 #** @method Close()
3430 # Object method.
3431 #*
3432 sub Close {
3433  my ($self) = @_;
3434  Geo::GDAL::VSIFCloseL($self);
3435 }
3436 
3437 #** @method MkDir($path)
3438 # Package subroutine.
3439 # Make a directory.
3440 # @param path The directory to make.
3441 # @note The name of this method is VSIMkdir in GDAL.
3442 #*
3443 sub MkDir {
3444  my ($path) = @_;
3445  # mode unused in CPL
3446  Geo::GDAL::Mkdir($path, 0);
3447 }
3448 
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.
3454 #*
3455 sub Open {
3456  my ($path, $mode) = @_;
3457  my $self = Geo::GDAL::VSIFOpenL($path, $mode);
3458  bless $self, 'Geo::GDAL::VSIF';
3459 }
3460 
3461 #** @method scalar Read($count)
3462 # Object method.
3463 # @param count The number of bytes to read from the file.
3464 # @return A byte string.
3465 #*
3466 sub Read {
3467  my ($self, $count) = @_;
3468  Geo::GDAL::VSIFReadL($count, $self);
3469 }
3470 
3471 #** @method list ReadDir($dir)
3472 # Package subroutine.
3473 # @return Contents of a directory in an anonymous array or as a list.
3474 #*
3475 sub ReadDir {
3476  my ($path) = @_;
3477  Geo::GDAL::ReadDir($path);
3478 }
3479 
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.
3484 #*
3485 sub ReadDirRecursive {
3486  my ($path) = @_;
3487  Geo::GDAL::ReadDirRecursive($path);
3488 }
3489 
3490 #** @method Rename($old, $new)
3491 # Package subroutine.
3492 # Rename a file.
3493 # @note The name of this method is VSIRename in GDAL.
3494 #*
3495 sub Rename {
3496  my ($old, $new) = @_;
3497  Geo::GDAL::Rename($old, $new);
3498 }
3499 
3500 #** @method RmDir($path)
3501 # Package subroutine.
3502 # Remove a directory.
3503 # @note The name of this method is VSIRmdir in GDAL.
3504 #*
3505 sub RmDir {
3506  my ($dirname, $recursive) = @_;
3507  eval {
3508  if (!$recursive) {
3509  Geo::GDAL::Rmdir($dirname);
3510  } else {
3511  for my $f (ReadDir($dirname)) {
3512  next if $f eq '..' or $f eq '.';
3513  my @s = Stat($dirname.'/'.$f);
3514  if ($s[0] eq 'f') {
3515  Unlink($dirname.'/'.$f);
3516  } elsif ($s[0] eq 'd') {
3517  Rmdir($dirname.'/'.$f, 1);
3518  Rmdir($dirname.'/'.$f);
3519  }
3520  }
3521  RmDir($dirname);
3522  }
3523  };
3524  if ($@) {
3525  my $r = $recursive ? ' recursively' : '';
3526  error("Cannot remove directory \"$dirname\"$r.");
3527  }
3528 }
3529 
3530 #** @method Seek($offset, $whence)
3531 # Object method.
3532 #*
3533 sub Seek {
3534  my ($self, $offset, $whence) = @_;
3535  Geo::GDAL::VSIFSeekL($self, $offset, $whence);
3536 }
3537 
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
3543 # special file.
3544 #*
3545 sub Stat {
3546  my ($path) = @_;
3547  Geo::GDAL::Stat($path);
3548 }
3549 
3550 #** @method scalar Tell()
3551 # Object method.
3552 #*
3553 sub Tell {
3554  my ($self) = @_;
3555  Geo::GDAL::VSIFTellL($self);
3556 }
3557 
3558 #** @method Truncate($new_size)
3559 # Object method.
3560 #*
3561 sub Truncate {
3562  my ($self, $new_size) = @_;
3563  Geo::GDAL::VSIFTruncateL($self, $new_size);
3564 }
3565 
3566 #** @method Unlink($filename)
3567 # Package subroutine.
3568 # @param filename The file to delete.
3569 # @return 0 on success and -1 on an error.
3570 #*
3571 sub Unlink {
3572  my ($filename) = @_;
3573  Geo::GDAL::Unlink($filename);
3574 }
3575 
3576 #** @method Write($scalar)
3577 # Object method.
3578 # @param scalar The byte string to write to the file.
3579 # @return Number of bytes written into the file.
3580 #*
3581 sub Write {
3582  my ($self, $data) = @_;
3583  Geo::GDAL::VSIFWriteL($data, $self);
3584 }
3585 
3586 #** @class Geo::GDAL::VSILFILE
3587 #*
3588 package Geo::GDAL::VSILFILE;
3589 
3590 use base qw(Geo::GDAL)
3591 
3592 #** @class Geo::GDAL::XML
3593 # @brief A simple XML parser
3594 # @details
3595 #*
3596 package Geo::GDAL::XML;
3597 
3598 #** @method new($string)
3599 # Object method.
3600 # @param string String containing XML.
3601 # @return A new Geo::GDAL::XML object, which is a reference to an anonymous array.
3602 #*
3603 sub new {
3604  my $class = shift;
3605  my $xml = shift // '';
3606  my $self = ParseXMLString($xml);
3607  bless $self, $class;
3608  $self->traverse(sub {my $node = shift; bless $node, $class});
3609  return $self;
3610 }
3611 
3612 #** @method serialize()
3613 # Object method.
3614 # @return The XML serialized into a string.
3615 #*
3616 sub serialize {
3617  my $self = shift;
3618  return SerializeXMLTree($self);
3619 }
3620 1;
3621 # This file was automatically generated by SWIG (http://www.swig.org).
3622 # Version 3.0.8
3623 #
3624 # Do not make changes to this file unless you know what you are doing--modify
3625 # the SWIG interface file instead.
3626 }
3627 
3628 #** @method traverse(coderef subroutine)
3629 # Object method.
3630 # @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.
3631 #*
3632 sub traverse {
3633  my ($self, $sub) = @_;
3634  my $type = $self->[0];
3635  my $data = $self->[1];
3636  $type = NodeType($type);
3637  $sub->($self, $type, $data);
3638  for my $child (@{$self}[2..$#$self]) {
3639  traverse($child, $sub);
3640  }
3641 }
3642 
3643 #** @class Geo::GNM
3644 # @brief Base class for geographical networks in GDAL.
3645 # @details
3646 #*
3647 package Geo::GNM;
3648 
3649 #** @method CastToGenericNetwork()
3650 #*
3651 sub CastToGenericNetwork {
3652 }
3653 
3654 #** @method CastToNetwork()
3655 #*
3656 sub CastToNetwork {
3657 }
3658 
3659 #** @method GATConnectedComponents()
3660 #*
3661 sub GATConnectedComponents {
3662 }
3663 
3664 #** @method GATDijkstraShortestPath()
3665 #*
3666 sub GATDijkstraShortestPath {
3667 }
3668 
3669 #** @method GATKShortestPath()
3670 #*
3671 sub GATKShortestPath {
3672 }
3673 
3674 #** @method GNM_EDGE_DIR_BOTH()
3675 #*
3676 sub GNM_EDGE_DIR_BOTH {
3677 }
3678 
3679 #** @method GNM_EDGE_DIR_SRCTOTGT()
3680 #*
3681 sub GNM_EDGE_DIR_SRCTOTGT {
3682 }
3683 
3684 #** @method GNM_EDGE_DIR_TGTTOSRC()
3685 #*
3686 sub GNM_EDGE_DIR_TGTTOSRC {
3687  1;
3688 }
3689 
3690 #** @class Geo::GNM::GenericNetwork
3691 # @details
3692 #*
3693 package Geo::GNM::GenericNetwork;
3694 
3695 use base qw(Geo::GNM::Network Geo::GNM)
3696 
3697 #** @method ChangeAllBlockState()
3698 #*
3699 sub ChangeAllBlockState {
3700 }
3701 
3702 #** @method ChangeBlockState()
3703 #*
3704 sub ChangeBlockState {
3705 }
3706 
3707 #** @method ConnectFeatures()
3708 #*
3709 sub ConnectFeatures {
3710 }
3711 
3712 #** @method ConnectPointsByLines()
3713 #*
3714 sub ConnectPointsByLines {
3715 }
3716 
3717 #** @method CreateRule()
3718 #*
3719 sub CreateRule {
3720 }
3721 
3722 #** @method DeleteAllRules()
3723 #*
3724 sub DeleteAllRules {
3725 }
3726 
3727 #** @method DeleteRule()
3728 #*
3729 sub DeleteRule {
3730 }
3731 
3732 #** @method DisconnectFeatures()
3733 #*
3734 sub DisconnectFeatures {
3735 }
3736 
3737 #** @method DisconnectFeaturesWithId()
3738 #*
3739 sub DisconnectFeaturesWithId {
3740 }
3741 
3742 #** @method GetRules()
3743 #*
3744 sub GetRules {
3745 }
3746 
3747 #** @method ReconnectFeatures()
3748 #*
3749 sub ReconnectFeatures {
3750 }
3751 
3752 #** @class Geo::GNM::MajorObject
3753 # @details
3754 #*
3755 package Geo::GNM::MajorObject;
3756 
3757 #** @class Geo::GNM::Network
3758 # @details
3759 #*
3760 package Geo::GNM::Network;
3761 
3762 use base qw(Geo::GDAL::MajorObject Geo::GNM)
3763 
3764 #** @method CommitTransaction()
3765 #*
3766 sub CommitTransaction {
3767 }
3768 
3769 #** @method CopyLayer()
3770 #*
3771 sub CopyLayer {
3772 }
3773 
3774 #** @method DisconnectAll()
3775 #*
3776 sub DisconnectAll {
3777 }
3778 
3779 #** @method GetFeatureByGlobalFID()
3780 #*
3781 sub GetFeatureByGlobalFID {
3782 }
3783 
3784 #** @method GetFileList()
3785 #*
3786 sub GetFileList {
3787 }
3788 
3789 #** @method GetLayerByIndex()
3790 #*
3791 sub GetLayerByIndex {
3792 }
3793 
3794 #** @method GetLayerByName()
3795 #*
3796 sub GetLayerByName {
3797 }
3798 
3799 #** @method GetLayerCount()
3800 #*
3801 sub GetLayerCount {
3802 }
3803 
3804 #** @method GetName()
3805 #*
3806 sub GetName {
3807 }
3808 
3809 #** @method GetPath()
3810 #*
3811 sub GetPath {
3812 }
3813 
3814 #** @method GetProjection()
3815 #*
3816 sub GetProjection {
3817 }
3818 
3819 #** @method GetProjectionRef()
3820 #*
3821 sub GetProjectionRef {
3822 }
3823 
3824 #** @method GetVersion()
3825 #*
3826 sub GetVersion {
3827 }
3828 
3829 #** @method RollbackTransaction()
3830 #*
3831 sub RollbackTransaction {
3832 }
3833 
3834 #** @method StartTransaction()
3835 #*
3836 sub StartTransaction {
3837 }
3838 
3839 #** @class Geo::OGR
3840 # @brief OGR utility functions.
3841 # @details A wrapper for many OGR utility functions and a root class for all
3842 # OGR classes.
3843 #*
3844 package Geo::OGR;
3845 
3846 #** @method list ByteOrders()
3847 # Package subroutine.
3848 # @return a list of byte order types, XDR and NDR. XDR denotes
3849 # big-endian and NDR denotes little-endian.
3850 #*
3851 sub ByteOrders {
3852 }
3853 
3854 #** @method Geo::GDAL::Driver Driver($name)
3855 # Package subroutine.
3856 # A.k.a GetDriver.
3857 # @param name the short name of the driver.
3858 # @note No check is made that the driver is actually a vector driver.
3859 # @return a Geo::GDAL::Driver object.
3860 #*
3861 sub Driver {
3862  return 'Geo::GDAL::Driver' unless @_;
3863  bless Geo::GDAL::Driver(@_), 'Geo::OGR::Driver';
3864 }
3865 
3866 #** @method list DriverNames()
3867 # Package subroutine.
3868 # A.k.a GetDriverNames
3869 # \code
3870 # perl -MGeo::GDAL -e '@d=Geo::OGR::DriverNames;print "@d\n"'
3871 # \endcode
3872 # @note Use Geo::GDAL::DriverNames for raster drivers.
3873 # @return a list of the short names of all available GDAL vector drivers.
3874 #*
3875 sub DriverNames {
3876 }
3877 
3878 #** @method list Drivers()
3879 # Package subroutine.
3880 # @note Use Geo::GDAL::Drivers for raster drivers.
3881 # @return a list of all available GDAL vector drivers.
3882 #*
3883 sub Drivers {
3884  my @drivers;
3885  for my $i (0..GetDriverCount()-1) {
3886  my $driver = Geo::GDAL::GetDriver($i);
3887  push @drivers, $driver if $driver->TestCapability('VECTOR');
3888  }
3889  return @drivers;
3890 }
3891 
3892 #** @method Flatten()
3893 #*
3894 sub Flatten {
3895 }
3896 
3897 #** @method scalar GeometryTypeModify($type, $modifier)
3898 # Object method.
3899 # @param type a geometry type (one of Geo::OGR::GeometryTypes).
3900 # @param modifier one of 'flatten', 'set_Z', 'make_collection', 'make_curve', or 'make_linear'.
3901 # @return modified geometry type.
3902 #*
3903 sub GeometryTypeModify {
3904  my($type, $modifier) = @_;
3905  $type = s2i(geometry_type => $type);
3906  return i2s(geometry_type => GT_Flatten($type)) if $modifier =~ /flat/i;
3907  return i2s(geometry_type => GT_SetZ($type)) if $modifier =~ /z/i;
3908  return i2s(geometry_type => GT_GetCollection($type)) if $modifier =~ /collection/i;
3909  return i2s(geometry_type => GT_GetCurve($type)) if $modifier =~ /curve/i;
3910  return i2s(geometry_type => GT_GetLinear($type)) if $modifier =~ /linear/i;
3911  error(1, $modifier, {Flatten => 1, SetZ => 1, GetCollection => 1, GetCurve => 1, GetLinear => 1});
3912 }
3913 
3914 #** @method scalar GeometryTypeTest($type, $test, $type2)
3915 # Object method.
3916 # @param type a geometry type (one of Geo::OGR::GeometryTypes).
3917 # @param test one of 'has_z', 'is_subclass_of', 'is_curve', 'is_surface', or 'is_non_linear'.
3918 # @param type2 a geometry type (one of Geo::OGR::GeometryTypes). Required for 'is_subclass_of' test.
3919 # @return result of the test.
3920 #*
3921 sub GeometryTypeTest {
3922  my($type, $test, $type2) = @_;
3923  $type = s2i(geometry_type => $type);
3924  if (defined $type2) {
3925  $type = s2i(geometry_type => $type);
3926  } else {
3927  error("Usage: GeometryTypeTest(type1, 'is_subclass_of', type2).") if $test =~ /subclass/i;
3928  }
3929  return GT_HasZ($type) if $test =~ /z/i;
3930  return GT_IsSubClassOf($type, $type2) if $test =~ /subclass/i;
3931  return GT_IsCurve($type) if $test =~ /curve/i;
3932  return GT_IsSurface($type) if $test =~ /surface/i;
3933  return GT_IsNonLinear($type) if $test =~ /linear/i;
3934  error(1, $test, {HasZ => 1, IsSubClassOf => 1, IsCurve => 1, IsSurface => 1, IsNonLinear => 1});
3935 }
3936 
3937 #** @method list GeometryTypes()
3938 # Package subroutine.
3939 # @return a list of all geometry types, currently:
3940 # 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.
3941 #*
3942 sub GeometryTypes {
3943  1;
3944  # This file was automatically generated by SWIG (http://www.swig.org).
3945  # Version 3.0.8
3946  #
3947  # Do not make changes to this file unless you know what you are doing--modify
3948  # the SWIG interface file instead.
3949 }
3950 
3951 #** @method GetNonLinearGeometriesEnabledFlag()
3952 #*
3953 sub GetNonLinearGeometriesEnabledFlag {
3954 }
3955 
3956 #** @method GetOpenDSCount()
3957 #*
3958 sub GetOpenDSCount {
3959 }
3960 
3961 #** @method HasM()
3962 #*
3963 sub HasM {
3964 }
3965 
3966 #** @method HasZ()
3967 #*
3968 sub HasZ {
3969 }
3970 
3971 #** @method Geo::GDAL::Dataset Open($name, $update = 0)
3972 # Object method.
3973 # Open a vector data source.
3974 # @param name The data source string (directory, filename, etc.).
3975 # @param update Whether to open the data source in update mode (default is not).
3976 # @return a new Geo::GDAL::Dataset object.
3977 #*
3978 sub Open {
3979  my @p = @_; # name, update
3980  my @flags = qw/VECTOR/;
3981  push @flags, qw/UPDATE/ if $p[1];
3982  my $dataset = Geo::GDAL::OpenEx($p[0], \@flags);
3983  error("Failed to open $p[0]. Is it a vector dataset?") unless $dataset;
3984  return $dataset;
3985 }
3986 
3987 #** @method Geo::GDAL::Dataset OpenShared($name, $update = 0)
3988 # Object method.
3989 # Open a vector data source in shared mode.
3990 # @param name The data source string (directory, filename, etc.).
3991 # @param update Whether to open the data source in update mode.
3992 # @return a new Geo::GDAL::Dataset object.
3993 #*
3994 sub OpenShared {
3995  my @p = @_; # name, update
3996  my @flags = qw/VECTOR SHARED/;
3997  push @flags, qw/UPDATE/ if $p[1];
3998  my $dataset = Geo::GDAL::OpenEx($p[0], \@flags);
3999  error("Failed to open $p[0]. Is it a vector dataset?") unless $dataset;
4000  return $dataset;
4001 }
4002 
4003 #** @method SetGenerate_DB2_V72_BYTE_ORDER($Generate_DB2_V72_BYTE_ORDER)
4004 # Object method.
4005 # Needed only on IBM DB2.
4006 #*
4007 sub SetGenerate_DB2_V72_BYTE_ORDER {
4008 }
4009 
4010 #** @method SetNonLinearGeometriesEnabledFlag()
4011 #*
4012 sub SetNonLinearGeometriesEnabledFlag {
4013 }
4014 
4015 #** @class Geo::OGR::DataSource
4016 # @brief A vector dataset.
4017 # @details This is a legacy class which should not be
4018 # used in new code. Use Geo::GDAL::Dataset.
4019 #*
4020 package Geo::OGR::DataSource;
4021 
4022 #** @method Geo::GDAL::Dataset Open()
4023 # Package subroutine.
4024 # The same as Geo::OGR::Open
4025 #*
4026 sub Open {
4027 }
4028 
4029 #** @method Geo::GDAL::Dataset OpenShared()
4030 # Package subroutine.
4031 # The same as Geo::OGR::OpenShared
4032 #*
4033 sub OpenShared {
4034 }
4035 
4036 #** @class Geo::OGR::Driver
4037 # @brief A vector format driver.
4038 # @details This is a legacy class which
4039 # should not be used in new code. Use Geo::GDAL::Driver.
4040 #*
4041 package Geo::OGR::Driver;
4042 
4043 use base qw(Geo::GDAL::Driver)
4044 
4045 #** @method Geo::GDAL::Dataset Copy(Geo::GDAL::Dataset source, $name, arrayref options = undef)
4046 # Object method.
4047 # Copy a vector data source into a new data source with this driver.
4048 # @param source The Geo::GDAL::Dataset object to be copied.
4049 # @param name The name for the new data source.
4050 # @param options Driver specific options. In addition to options
4051 # specified in GDAL documentation the option STRICT can be set to 'NO'
4052 # for a more relaxed copy. Otherwise the STRICT is 'YES'.
4053 # @note The order of the first two parameters is different from that in Geo::GDAL::Driver::Copy.
4054 # @return a new Geo::GDAL::Dataset object.
4055 #*
4056 sub Copy {
4057  my ($self, @p) = @_; # src, name, options
4058  my $strict = 1; # the default in bindings
4059  $strict = 0 if $p[2] && $p[2]->{STRICT} eq 'NO';
4060  $self->SUPER::Copy($p[1], $p[0], $strict, @{$p[2..4]}); # path, src, strict, options, cb, cb_data
4061 }
4062 
4063 #** @method Geo::GDAL::Dataset Create($name, hashref options = undef )
4064 # Object method.
4065 # Create a new vector data source using this driver.
4066 # @param name The data source name.
4067 # @param options Driver specific dataset creation options.
4068 #*
4069 sub Create {
4070  my ($self, $name, $options) = @_; # name, options
4071  $options //= {};
4072  $self->SUPER::Create(Name => $name, Width => 0, Height => 0, Bands => 0, Type => 'Byte', Options => $options);
4073 }
4074 
4075 #** @method Open()
4076 # Object method.
4077 # The same as Geo::OGR::Open except that only this driver is allowed.
4078 #*
4079 sub Open {
4080  my $self = shift;
4081  my @p = @_; # name, update
4082  my @flags = qw/VECTOR/;
4083  push @flags, qw/UPDATE/ if $p[1];
4084  my $dataset = Geo::GDAL::OpenEx($p[0], \@flags, [$self->Name()]);
4085  error("Failed to open $p[0]. Is it a vector dataset?") unless $dataset;
4086  return $dataset;
4087 }
4088 
4089 #** @class Geo::OGR::Feature
4090 # @brief A collection of non-spatial and spatial attributes.
4091 # @details A feature is a collection of non-spatial and spatial attributes and
4092 # an id, which is a special attribute, and data records according to
4093 # this data model. Attributes are called fields and some fields are
4094 # spatial, i.e., their value is a geometry. Fields have at least a
4095 # name and a type. Features may exist within a layer or
4096 # separetely. The data model of a feature is a definition object.
4097 #*
4098 package Geo::OGR::Feature;
4099 
4100 use base qw(Geo::OGR)
4101 
4102 #** @method Geo::OGR::Feature Clone()
4103 # Object method.
4104 # @return a new Geo::OGR::Feature object
4105 #*
4106 sub Clone {
4107 }
4108 
4109 #** @method DumpReadable()
4110 # Object method.
4111 # Write the contents of this feature to stdout.
4112 #*
4113 sub DumpReadable {
4114 }
4115 
4116 #** @method scalar Equal($feature)
4117 # Object method.
4118 # @param feature a Geo::OGR::Feature object for comparison
4119 # @return boolean
4120 #*
4121 sub Equal {
4122 }
4123 
4124 #** @method scalar FID($id)
4125 # Object method.
4126 # @brief Get or set the id of this feature.
4127 # @param id [optional] the id to set for this feature.
4128 # @return integer the id of this feature.
4129 #*
4130 sub FID {
4131  my $self = shift;
4132  $self->SetFID($_[0]) if @_;
4133  return unless defined wantarray;
4134  $self->GetFID;
4135 }
4136 
4137 #** @method Field($name, $value, ...)
4138 # Object method.
4139 # @brief Get, set, or unset the field value.
4140 # @param name the name (or the index) of the field.
4141 # @param value a scalar, a list of scalars or a reference to a
4142 # list. If undef, the field is unset. If a scalar or a list of
4143 # scalars, the field is set from them.
4144 # @note Non-scalar fields (for example Date) can be set either from a
4145 # scalar, which is then assumed to be a string and parsed, or from a
4146 # list of values (for example year, month, day for Date).
4147 # @note Setting and getting Integer64 fields requires 'use bigint' if
4148 # \$Config{ivsize} is smaller than 8, i.e., in a 32 bit machine.
4149 # @return in non-void context the value of the field, which may be a
4150 # scalar or a list, depending on the field type. For unset fields the
4151 # undef value is returned.
4152 #*
4153 sub Field {
4154  my $self = shift;
4155  my $field = $self->GetFieldIndex(shift // 0);
4156  $self->SetField($field, @_) if @_;
4157  $self->GetField($field) if defined wantarray;
4158 }
4159 
4160 #** @method FillUnsetWithDefault()
4161 #*
4162 sub FillUnsetWithDefault {
4163 }
4164 
4165 #** @method Geometry($name, $geometry)
4166 # Object method.
4167 # @brief Get or set the value of a geometry field.
4168 # @note This method delivers the functionality of undocumented methods
4169 # SetGeometry($geometry), SetGeometryDirectly, SetGeomField,
4170 # SetGeomFieldDirectly, GetGeometry, GetGeometryRef.
4171 #
4172 # Set or get the geometry in the feature. When setting, does a check
4173 # against the schema (GeometryType) of the feature. If the parameter
4174 # is a geometry object, it is cloned.
4175 # @param name [optional] the name of the spatial field,
4176 # whose geometry is to be set. If not given, sets or gets the geometry
4177 # of the first (or the single) spatial field.
4178 # @param geometry [optional] a Geo::OGR::Geometry object or a
4179 # reference to a hash from which such can be created (using
4180 # Geo::OGR::Geometry::new).
4181 # @return in a non-void context the indicated geometry in the feature
4182 # as a Geo::OGR::Geometry object. The returned object contains a
4183 # reference to the actual geometry data in the feature (the geometry
4184 # is not cloned) and to the feature object, thus keeping the feature
4185 # object from being destroyed while the geometry object exists.
4186 #*
4187 sub Geometry {
4188  my $self = shift;
4189  my $field = ((@_ > 0 and ref($_[0]) eq '') or (@_ > 2 and @_ % 2 == 1)) ? shift : 0;
4190  $field = $self->GetGeomFieldIndex($field);
4191  my $geometry;
4192  if (@_ and @_ % 2 == 0) {
4193  %$geometry = @_;
4194  } else {
4195  $geometry = shift;
4196  }
4197  if ($geometry) {
4198  my $type = $self->GetDefn->GetGeomFieldDefn($field)->Type;
4199  if (blessed($geometry) and $geometry->isa('Geo::OGR::Geometry')) {
4200  my $gtype = $geometry->GeometryType;
4201  error("The type of the inserted geometry ('$gtype') is not the same as the type of the field ('$type').")
4202  if $type ne 'Unknown' and $type ne $gtype;
4203  eval {
4204  $self->SetGeomFieldDirectly($field, $geometry->Clone);
4205  };
4206  confess last_error() if $@;
4207  } elsif (ref($geometry) eq 'HASH') {
4208  $geometry->{GeometryType} //= $type;
4209  eval {
4210  $geometry = Geo::OGR::Geometry->new($geometry);
4211  };
4212  confess last_error() if $@;
4213  my $gtype = $geometry->GeometryType;
4214  error("The type of the inserted geometry ('$gtype') is not the same as the type of the field ('$type').")
4215  if $type ne 'Unknown' and $type ne $gtype;
4216  eval {
4217  $self->SetGeomFieldDirectly($field, $geometry);
4218  };
4219  confess last_error() if $@;
4220  } else {
4221  error("Usage: \$feature->Geometry([field],[geometry])");
4222  }
4223  }
4224  return unless defined wantarray;
4225  $geometry = $self->GetGeomFieldRef($field);
4226  return unless $geometry;
4227  keep($geometry, $self);
4228 }
4229 
4230 #** @method Geo::OGR::FeatureDefn GetDefn()
4231 # Object method.
4232 # @note A.k.a GetDefnRef.
4233 # @return a Geo::OGR::FeatureDefn object, which represents the definition of this feature.
4234 #*
4235 sub GetDefn {
4236  my $self = shift;
4237  my $defn = $self->GetDefnRef;
4238  keep($defn, $self);
4239 }
4240 
4241 #** @method scalar GetFID()
4242 # Object method.
4243 # @return the feature id (an integer).
4244 #*
4245 sub GetFID {
4246 }
4247 
4248 #** @method list GetField($name)
4249 # Object method.
4250 # See Field().
4251 #*
4252 sub GetField {
4253  my ($self, $field) = @_;
4254  $field = $self->GetFieldIndex($field);
4255  return unless IsFieldSet($self, $field);
4256  my $type = GetFieldType($self, $field);
4257  return GetFieldAsInteger($self, $field) if $type == $Geo::OGR::OFTInteger;
4258  return GetFieldAsInteger64($self, $field) if $type == $Geo::OGR::OFTInteger64;
4259  return GetFieldAsDouble($self, $field) if $type == $Geo::OGR::OFTReal;
4260  return GetFieldAsString($self, $field) if $type == $Geo::OGR::OFTString;
4261  if ($type == $Geo::OGR::OFTIntegerList) {
4262  my $ret = GetFieldAsIntegerList($self, $field);
4263  return wantarray ? @$ret : $ret;
4264  }
4265  if ($type == $Geo::OGR::OFTInteger64List) {
4266  my $ret = GetFieldAsInteger64List($self, $field);
4267  return wantarray ? @$ret : $ret;
4268  }
4269  if ($type == $Geo::OGR::OFTRealList) {
4270  my $ret = GetFieldAsDoubleList($self, $field);
4271  return wantarray ? @$ret : $ret;
4272  }
4273  if ($type == $Geo::OGR::OFTStringList) {
4274  my $ret = GetFieldAsStringList($self, $field);
4275  return wantarray ? @$ret : $ret;
4276  }
4277  if ($type == $Geo::OGR::OFTBinary) {
4278  return GetFieldAsBinary($self, $field);
4279  }
4280  if ($type == $Geo::OGR::OFTDate) {
4281  my @ret = GetFieldAsDateTime($self, $field);
4282  # year, month, day, hour, minute, second, timezone
4283  return wantarray ? @ret[0..2] : [@ret[0..2]];
4284  }
4285  if ($type == $Geo::OGR::OFTTime) {
4286  my @ret = GetFieldAsDateTime($self, $field);
4287  return wantarray ? @ret[3..6] : [@ret[3..6]];
4288  }
4289  if ($type == $Geo::OGR::OFTDateTime) {
4290  my @ret = GetFieldAsDateTime($self, $field);
4291  return wantarray ? @ret : [@ret];
4292  }
4293  error("Perl bindings do not support the field type '".i2s(field_type => $type)."'.");
4294 }
4295 
4296 #** @method scalar GetFieldDefn($name)
4297 # Object method.
4298 # Get the definition of a field.
4299 # @param name the name of the field.
4300 # @return a Geo::OGR::FieldDefn object.
4301 #*
4302 sub GetFieldDefn {
4303  my $self = shift;
4304  my $field = $self->GetFieldIndex(shift);
4305  return $self->GetFieldDefnRef($field);
4306 }
4307 
4308 #** @method list GetFieldNames()
4309 # Object method.
4310 # Get the names of the fields in this feature.
4311 #*
4312 sub GetFieldNames {
4313 }
4314 
4315 #** @method scalar GetGeomFieldDefn($name)
4316 # Object method.
4317 # Get the definition of a spatial field.
4318 # @param name the name of the spatial field.
4319 # @return a Geo::OGR::GeomFieldDefn object.
4320 #*
4321 sub GetGeomFieldDefn {
4322  my $self = shift;
4323  my $field = $self->GetGeomFieldIndex(shift);
4324  return $self->GetGeomFieldDefnRef($field);
4325 }
4326 
4327 #** @method GetNativeData()
4328 #*
4329 sub GetNativeData {
4330 }
4331 
4332 #** @method GetNativeMediaType()
4333 #*
4334 sub GetNativeMediaType {
4335 }
4336 
4337 #** @method hash reference GetSchema()
4338 # Object method.
4339 # @brief Get the schema of this feature.
4340 #
4341 # @return the schema as a hash whose keywords are Name, StyleIgnored
4342 # and Fields. Fields is an anonymous array of first non-spatial and
4343 # then spatial field schemas as in Geo::OGR::FieldDefn::Schema() and
4344 # Geo::OGR::GeomFieldDefn::Schema().
4345 #*
4346 sub GetSchema {
4347  my $self = shift;
4348  error("Schema of a feature cannot be set directly.") if @_;
4349  return $self->GetDefnRef->Schema;
4350 }
4351 
4352 #** @method scalar GetStyleString()
4353 # Object method.
4354 # @return a string
4355 #*
4356 sub GetStyleString {
4357 }
4358 
4359 #** @method IsFieldNull()
4360 #*
4361 sub IsFieldNull {
4362 }
4363 
4364 #** @method IsFieldSetAndNotNull()
4365 #*
4366 sub IsFieldSetAndNotNull {
4367 }
4368 
4369 #** @method Geo::OGR::Layer Layer()
4370 # Object method.
4371 # @return the layer to which this feature belongs to or undef.
4372 #*
4373 sub Layer {
4374  my $self = shift;
4375  parent($self);
4376 }
4377 
4378 #** @method hash reference Row(%row)
4379 # Object method.
4380 # @note This method discards the data the destination feature (or
4381 # layer) does not support. Changes in data due to differences between
4382 # field types may also occur.
4383 #
4384 # Get and/or set the data of the feature. The key of the (key,value)
4385 # pairs of the row is the field name. Special field names FID and
4386 # Geometry are used for feature id and (single) geometry
4387 # respectively. The geometry/ies is/are set and get using the
4388 # Geo::OGR::Feature::Geometry method. Field values are set using the
4389 # Geo::OGR::Feature::Field method.
4390 # @param row [optional] feature data in a hash.
4391 # @return a reference to feature data in a hash. Spatial fields are
4392 # returned as Geo::OGR::Geometry objects.
4393 #*
4394 sub Row {
4395  my $self = shift;
4396  my $nf = $self->GetFieldCount;
4397  my $ngf = $self->GetGeomFieldCount;
4398  if (@_) { # update
4399  my %row;
4400  if (@_ == 1 and ref($_[0]) eq 'HASH') {
4401  %row = %{$_[0]};
4402  } elsif (@_ and @_ % 2 == 0) {
4403  %row = @_;
4404  } else {
4405  error('Usage: $feature->Row(%FeatureData).');
4406  }
4407  $self->SetFID($row{FID}) if defined $row{FID};
4408  #$self->Geometry($schema, $row{Geometry}) if $row{Geometry};
4409  for my $name (keys %row) {
4410  next if $name eq 'FID';
4411  if ($name eq 'Geometry') {
4412  $self->Geometry(0, $row{$name});
4413  next;
4414  }
4415  my $f = 0;
4416  for my $i (0..$nf-1) {
4417  if ($self->GetFieldDefnRef($i)->Name eq $name) {
4418  $self->SetField($i, $row{$name});
4419  $f = 1;
4420  last;
4421  }
4422  }
4423  next if $f;
4424  for my $i (0..$ngf-1) {
4425  if ($self->GetGeomFieldDefnRef($i)->Name eq $name) {
4426  $self->Geometry($i, $row{$name});
4427  $f = 1;
4428  last;
4429  }
4430  }
4431  next if $f;
4432  carp "Unknown field: '$name'.";
4433  }
4434  }
4435  return unless defined wantarray;
4436  my %row = ();
4437  for my $i (0..$nf-1) {
4438  my $name = $self->GetFieldDefnRef($i)->Name;
4439  $row{$name} = $self->GetField($i);
4440  }
4441  for my $i (0..$ngf-1) {
4442  my $name = $self->GetGeomFieldDefnRef($i)->Name || 'Geometry';
4443  $row{$name} = $self->GetGeometry($i);
4444  }
4445  $row{FID} = $self->GetFID;
4446  return \%row;
4447 }
4448 
4449 #** @method SetFID($id)
4450 # Object method.
4451 # @param id the feature id.
4452 #*
4453 sub SetFID {
4454 }
4455 
4456 #** @method SetField($name, @Value)
4457 # Object method.
4458 # See Field().
4459 #*
4460 sub SetField {
4461  my $self = shift;
4462  my $field = $self->GetFieldIndex(shift);
4463  my $arg = $_[0];
4464  if (@_ == 0 or !defined($arg)) {
4465  _UnsetField($self, $field);
4466  return;
4467  }
4468  $arg = [@_] if @_ > 1;
4469  my $type = $self->GetFieldType($field);
4470  if (ref($arg)) {
4471  if ($type == $Geo::OGR::OFTIntegerList) {
4472  SetFieldIntegerList($self, $field, $arg);
4473  }
4474  elsif ($type == $Geo::OGR::OFTInteger64List) {
4475  SetFieldInteger64List($self, $field, $arg);
4476  }
4477  elsif ($type == $Geo::OGR::OFTRealList) {
4478  SetFieldDoubleList($self, $field, $arg);
4479  }
4480  elsif ($type == $Geo::OGR::OFTStringList) {
4481  SetFieldStringList($self, $field, $arg);
4482  }
4483  elsif ($type == $Geo::OGR::OFTDate) {
4484  _SetField($self, $field, @$arg[0..2], 0, 0, 0, 0);
4485  }
4486  elsif ($type == $Geo::OGR::OFTTime) {
4487  $arg->[3] //= 0;
4488  _SetField($self, $field, 0, 0, 0, @$arg[0..3]);
4489  }
4490  elsif ($type == $Geo::OGR::OFTDateTime) {
4491  $arg->[6] //= 0;
4492  _SetField($self, $field, @$arg[0..6]);
4493  }
4494  elsif ($type == $Geo::OGR::OFTInteger64)
4495  {
4496  SetFieldInteger64($self, $field, $arg);
4497  }
4498  else {
4499  $type = i2s(field_type => $type);
4500  my $name = $self->GetFieldDefnRef($field)->Name;
4501  error("'$arg' is not a suitable value for field $name($type).");
4502  }
4503  } else {
4504  if ($type == $Geo::OGR::OFTBinary) {
4505  #$arg = unpack('H*', $arg); # remove when SetFieldBinary is available
4506  $self->SetFieldBinary($field, $arg);
4507  }
4508  elsif ($type == $Geo::OGR::OFTInteger64)
4509  {
4510  SetFieldInteger64($self, $field, $arg);
4511  }
4512  elsif ($type == $Geo::OGR::OFTInteger or $type == $Geo::OGR::OFTReal or $type == $Geo::OGR::OFTString)
4513  {
4514  _SetField($self, $field, $arg);
4515  }
4516  else {
4517  $type = i2s(field_type => $type);
4518  my $name = $self->GetFieldDefnRef($field)->Name;
4519  error("'$arg' is not a suitable value for field $name($type).");
4520  }
4521  }
4522 }
4523 
4524 #** @method SetFieldNull()
4525 #*
4526 sub SetFieldNull {
4527 }
4528 
4529 #** @method SetFrom($other, $forgiving = 1, hashref map)
4530 # Object method.
4531 # @param other a Geo::OGR::Feature object
4532 # @param forgiving [optional] set to false if the operation should not
4533 # continue if output fields do not match some of the source fields
4534 # @param map [optional] a mapping from output field indexes to source
4535 # fields, include into the hash all field indexes of this feature
4536 # which should be set
4537 #*
4538 sub SetFrom {
4539  my($self, $other) = @_;
4540  _SetFrom($self, $other), return if @_ <= 2;
4541  my $forgiving = $_[2];
4542  _SetFrom($self, $other, $forgiving), return if @_ <= 3;
4543  my $map = $_[3];
4544  my @list;
4545  for my $i (1..GetFieldCount($self)) {
4546  push @list, ($map->{$i} || -1);
4547  }
4548  SetFromWithMap($self, $other, 1, \@list);
4549 }
4550 
4551 #** @method SetNativeData()
4552 #*
4553 sub SetNativeData {
4554 }
4555 
4556 #** @method SetNativeMediaType()
4557 #*
4558 sub SetNativeMediaType {
4559 }
4560 
4561 #** @method SetStyleString($string)
4562 # Object method.
4563 # @param string
4564 #*
4565 sub SetStyleString {
4566 }
4567 
4568 #** @method list Tuple(@tuple)
4569 # Object method.
4570 # @note This method discards the data the destination feature (or
4571 # layer) does not support. Changes in data due to differences between
4572 # field types may also occur.
4573 #
4574 # @note The schema of the tuple needs to be the same as that of the
4575 # feature.
4576 #
4577 # Get and/set the data of the feature. The expected data in the tuple
4578 # is ([feature_id,] non-spatial fields, spatial fields). The fields in
4579 # the tuple are in the order they are in the schema. Field values are
4580 # set using the Geo::OGR::Feature::Field method. Geometries are set
4581 # and get using the Geo::OGR::Feature::Geometry method.
4582 # @param tuple [optional] feature data in an array
4583 # @return feature data in an array
4584 #*
4585 sub Tuple {
4586  my $self = shift;
4587  my $nf = $self->GetFieldCount;
4588  my $ngf = $self->GetGeomFieldCount;
4589  if (@_) {
4590  my $values = ref $_[0] ? $_[0] : \@_;
4591  my $FID;
4592  $FID = shift @$values if @$values == $nf + $ngf + 1;
4593  $self->SetFID($FID) if defined $FID;
4594  if (@$values != $nf + $ngf) {
4595  my $n = $nf + $ngf;
4596  error("Too many or too few attribute values for a feature (need $n).");
4597  }
4598  my $index = 0; # index to non-geometry and geometry fields
4599  for my $i (0..$nf-1) {
4600  $self->SetField($i, $values->[$i]);
4601  }
4602  for my $i (0..$ngf-1) {
4603  $self->Geometry($i, $values->[$nf+$i]);
4604  }
4605  }
4606  return unless defined wantarray;
4607  my @ret = ($self->GetFID);
4608  for my $i (0..$nf-1) {
4609  my $v = $self->GetField($i);
4610  push @ret, $v;
4611  }
4612  for my $i (0..$ngf-1) {
4613  my $v = $self->GetGeometry($i);
4614  push @ret, $v;
4615  }
4616  return @ret;
4617 }
4618 
4619 #** @method scalar Validate(list flags)
4620 # Object method.
4621 # @param flags one of more of null, geom_type, width,
4622 # allow_null_when_default, or all.
4623 # @exception croaks with an error message if the feature is not valid.
4624 # @return integer denoting the validity of the feature object.
4625 #*
4626 sub Validate {
4627  my $self = shift;
4628  my $flags = 0;
4629  for my $flag (@_) {
4630  my $f = eval '$Geo::OGR::'.uc($flag);
4631  $flags |= $f;
4632  }
4633  _Validate($self, $flags);
4634 }
4635 
4636 #** @method Geo::OGR::Feature new(%schema)
4637 # Class method.
4638 # @brief Create a new feature.
4639 # @param Named parameters:
4640 # - \a Schema a reference to a schema hash, or a Geo::OGR::Layer,
4641 # Geo::OGR::Feature, or Geo::OGR::FeatureDefn object.
4642 # - \a Values values for the feature attributes.
4643 # - \a StyleIgnored whether the style can be omitted when fetching
4644 # features. (default is false)
4645 #
4646 # Schema is a hash with the following keys:
4647 # - \a Name name of the schema (not used).
4648 # - \a Fields a list of Geo::OGR::FieldDefn or Geo::OGR::GeomFieldDefn
4649 # objects or references to hashes from which fields can be created.
4650 # - \a GeometryType the geometry type if the feature has only one spatial field.
4651 #
4652 # @note Do not mix GeometryType and geometry fields in Fields list.
4653 # @note Old syntax where the argument is a Geo::OGR::FeatureDefn
4654 # object or Schema hash is supported.
4655 #
4656 # @return a new Geo::OGR::Feature object.
4657 #*
4658 sub new {
4659  my $pkg = shift;
4660  my $arg;
4661  if (ref $_[0]) {
4662  if (ref $_[0] eq 'HASH' && $_[0]->{Schema}) {
4663  $arg = $_[0];
4664  } else {
4665  $arg = {Schema => $_[0]};
4666  }
4667  } elsif (@_ and @_ % 2 == 0) {
4668  %$arg = @_;
4669  unless ($arg->{Schema}) {
4670  my %tmp = @_;
4671  $arg->{Schema} = \%tmp;
4672  }
4673  } else {
4674  error("The argument must be either a schema or a hash.");
4675  }
4676  error("Missing schema.") unless $arg->{Schema};
4677  my $defn;
4678  for (ref $arg->{Schema}) {
4679  (/Geo::OGR::Layer$/ || /Geo::OGR::Feature$/) && do {
4680  $defn = $arg->{Schema}->GetDefn;
4681  last;
4682  };
4683  /Geo::OGR::FeatureDefn$/ && do {
4684  $defn = $arg->{Schema};
4685  last;
4686  };
4687  $defn = Geo::OGR::FeatureDefn->new($arg->{Schema});
4688  }
4689  my $self = Geo::OGRc::new_Feature($defn);
4690  error("Feature creation failed.") unless $self;
4691  bless $self, $pkg;
4692  for (ref $arg->{Values}) {
4693  /ARRAY/ && do {
4694  $self->Tuple($arg->{Values});
4695  last;
4696  };
4697  /HASH/ && do {
4698  $self->Row($arg->{Values});
4699  last;
4700  };
4701  /Geo::OGR::Feature$/ && do {
4702  $self->Tuple($arg->{Values}->Tuple);
4703  last;
4704  };
4705  /^$/ && do {
4706  last;
4707  };
4708  error("Value parameter must be an array, hash, or another feature. Not $_.");
4709  }
4710  return $self;
4711 }
4712 
4713 #** @class Geo::OGR::FeatureDefn
4714 # @brief The schema of a feature or a layer.
4715 # @details A FeatureDefn object is a collection of field definition objects. A
4716 # read-only FeatureDefn object can be obtained from a layer
4717 # (Geo::OGR::Layer::GetDefn()) or a feature
4718 # (Geo::OGR::Feature::GetDefn()).
4719 #*
4720 package Geo::OGR::FeatureDefn;
4721 
4722 use base qw(Geo::OGR)
4723 
4724 #** @method AddField(%params)
4725 # Object method.
4726 # @param params Named parameters to create a new Geo::OGR::FieldDefn
4727 # or Geo::OGR::GeomFieldDefn object.
4728 #*
4729 sub AddField {
4730  my $self = shift;
4731  error("Read-only definition.") if parent($self);
4732  my %params;
4733  if (@_ == 0) {
4734  } elsif (ref($_[0]) eq 'HASH') {
4735  %params = %{$_[0]};
4736  } elsif (@_ % 2 == 0) {
4737  %params = @_;
4738  }
4739  $params{Type} //= '';
4740  if (s_exists(field_type => $params{Type})) {
4741  my $fd = Geo::OGR::FieldDefn->new(%params);
4742  $self->AddFieldDefn($fd);
4743  } else {
4744  my $fd = Geo::OGR::GeomFieldDefn->new(%params);
4745  $self->AddGeomFieldDefn($fd);
4746  }
4747 }
4748 
4749 #** @method DeleteField($name)
4750 # Object method.
4751 # @note Currently only geometry fields can be deleted.
4752 # @param index the index of the geometry field to be deleted.
4753 #*
4754 sub DeleteField {
4755  my ($self, $name) = @_;
4756  error("Read-only definition.") if parent($self);
4757  for my $i (0..$self->GetFieldCount-1) {
4758  error("Non-spatial fields cannot be deleted.") if $self->_GetFieldDefn($i)->Name eq $name;
4759  }
4760  for my $i (0..$self->GetGeomFieldCount-1) {
4761  $self->DeleteGeomFieldDefn($i) if $self->_GetGeomFieldDefn($i)->Name eq $name;
4762  }
4763  error(2, $name, 'Field');
4764 }
4765 
4766 #** @method Feature()
4767 #*
4768 sub Feature {
4769  my $self = shift;
4770  return parent($self);
4771 }
4772 
4773 #** @method scalar GetFieldDefn($name)
4774 # Object method.
4775 # Get the definition of a field.
4776 # @param name the name of the field.
4777 # @return a Geo::OGR::FieldDefn object.
4778 #*
4779 sub GetFieldDefn {
4780  my $self = shift;
4781  my $field = $self->GetFieldIndex(shift);
4782  return $self->_GetFieldDefn($field);
4783 }
4784 
4785 #** @method list GetFieldNames()
4786 # Object method.
4787 # The names of the fields in this layer or feature definition.
4788 # @return the list of field names.
4789 #*
4790 sub GetFieldNames {
4791  my $self = shift;
4792  my @names = ();
4793  for my $i (0..$self->GetFieldCount-1) {
4794  push @names, $self->_GetFieldDefn($i)->Name;
4795  }
4796  for my $i (0..$self->GetGeomFieldCount-1) {
4797  push @names, $self->_GetGeomFieldDefn($i)->Name;
4798  }
4799  return @names;
4800 }
4801 
4802 #** @method scalar GetGeomFieldDefn($name)
4803 # Object method.
4804 # Get the definition of a spatial field.
4805 # @param name the name of the spatial field.
4806 # @return a Geo::OGR::GeomFieldDefn object.
4807 #*
4808 sub GetGeomFieldDefn {
4809  my $self = shift;
4810  my $field = $self->GetGeomFieldIndex(shift);
4811  return $self->_GetGeomFieldDefn($field);
4812 }
4813 
4814 #** @method scalar GetName()
4815 # Object method.
4816 # @return the name of this layer or feature definition.
4817 #*
4818 sub GetName {
4819 }
4820 
4821 #** @method hash reference GetSchema()
4822 # Object method.
4823 # @brief Get the schema of this feature or layer definition.
4824 #
4825 # @return the schema as a hash whose keywords are Name, StyleIgnored
4826 # and Fields. Fields is an anonymous array of first non-spatial and
4827 # then spatial field schemas as in Geo::OGR::FieldDefn::Schema() and
4828 # Geo::OGR::GeomFieldDefn::Schema().
4829 #*
4830 sub GetSchema {
4831  my $self = shift;
4832  carp "Schema of a feature definition should not be set directly." if @_;
4833  if (@_ and @_ % 2 == 0) {
4834  my %schema = @_;
4835  if ($schema{Fields}) {
4836  for my $field (@{$schema{Fields}}) {
4837  $self->AddField($field);
4838  }
4839  }
4840  }
4841  my %schema;
4842  $schema{Name} = $self->Name();
4843  $schema{StyleIgnored} = $self->StyleIgnored();
4844  $schema{Fields} = [];
4845  for my $i (0..$self->GetFieldCount-1) {
4846  my $s = $self->_GetFieldDefn($i)->Schema;
4847  push @{$schema{Fields}}, $s;
4848  }
4849  for my $i (0..$self->GetGeomFieldCount-1) {
4850  my $s = $self->_GetGeomFieldDefn($i)->Schema;
4851  push @{$schema{Fields}}, $s;
4852  }
4853  return wantarray ? %schema : \%schema;
4854 }
4855 
4856 #** @method IsSame(Geo::OGR::FeatureDefn defn)
4857 # Object method.
4858 # @return true if this definition is similar to the other definition,
4859 # false otherwise.
4860 #*
4861 sub IsSame {
4862 }
4863 
4864 #** @method scalar IsStyleIgnored()
4865 # Object method.
4866 # Get the ignore status of style information when fetching features.
4867 # @return the ignore status of style information
4868 # @since 1.9.0
4869 #*
4870 sub IsStyleIgnored {
4871 }
4872 
4873 #** @method SetStyleIgnored($IgnoreState)
4874 # Object method.
4875 # Set the ignore status of style information when fetching features.
4876 # @since 1.9.0
4877 #*
4878 sub SetStyleIgnored {
4879 }
4880 
4881 #** @method Geo::OGR::FeatureDefn new(%schema)
4882 # Class method.
4883 # Creates a new layer or feature definition. The new definition is
4884 # either initialized to the given schema or it will contain no
4885 # non-spatial fields and one spatial field, whose Name is '' and
4886 # GeometryType is 'Unknown' or the value of the named parameter
4887 # GeometryType.
4888 # @param schema [optional] The schema for the new feature definition,
4889 # as in Geo::OGR::FeatureDefn::Schema().
4890 # @return a Geo::OGR::FeatureDefn object
4891 #
4892 # Example usage:
4893 # \code
4894 # $fd = Geo::OGR::FeatureDefn->new(
4895 # Name => "name",
4896 # Fields => [{ Name => 'field1', Type => 'String' },
4897 # { Name => 'geom', GeometryType => 'Point' }] );
4898 # \endcode
4899 #*
4900 sub new {
4901  my $pkg = shift;
4902  my %schema;
4903  if (@_ == 1 and ref($_[0]) eq 'HASH') {
4904  %schema = %{$_[0]};
4905  } elsif (@_ and @_ % 2 == 0) {
4906  %schema = @_;
4907  }
4908  my $fields = $schema{Fields};
4909  error("The 'Fields' argument must be an array reference.") if $fields and ref($fields) ne 'ARRAY';
4910  $schema{Name} //= '';
4911  my $self = Geo::OGRc::new_FeatureDefn($schema{Name});
4912  bless $self, $pkg;
4913  my $gt = $schema{GeometryType};
4914  if ($gt) {
4915  $self->GeometryType($gt);
4916  } elsif ($fields) {
4917  $self->DeleteGeomFieldDefn(0);
4918  }
4919  $self->StyleIgnored($schema{StyleIgnored}) if exists $schema{StyleIgnored};
4920  for my $fd (@{$fields}) {
4921  my $d = $fd;
4922  if (ref($fd) eq 'HASH') {
4923  # if Name and Type are missing, assume Name => Type
4924  if (!(exists $fd->{Name} && exists $fd->{Type})) {
4925  for my $key (sort keys %$fd) {
4926  if (s_exists(field_type => $fd->{$key}) ||
4927  s_exists(geometry_type => $fd->{$key}))
4928  {
4929  $fd->{Name} = $key;
4930  $fd->{Type} = $fd->{$key};
4931  delete $fd->{$key};
4932  last;
4933  }
4934  }
4935  }
4936  if ($fd->{GeometryType} or ($fd->{Type} && s_exists(geometry_type => $fd->{Type}))) {
4937  $d = Geo::OGR::GeomFieldDefn->new(%$fd);
4938  } else {
4939  $d = Geo::OGR::FieldDefn->new(%$fd);
4940  }
4941  }
4942  if (blessed($d) and $d->isa('Geo::OGR::FieldDefn')) {
4943  AddFieldDefn($self, $d);
4944  } elsif (blessed($d) and $d->isa('Geo::OGR::GeomFieldDefn')) {
4945  error("Do not mix GeometryType and geometry fields in Fields.") if $gt;
4946  AddGeomFieldDefn($self, $d);
4947  } else {
4948  error("Item in field list does not define a field.");
4949  }
4950  }
4951  return $self;
4952 }
4953 
4954 #** @class Geo::OGR::FieldDefn
4955 # @brief A definition of a non-spatial attribute.
4956 # @details
4957 #*
4958 package Geo::OGR::FieldDefn;
4959 
4960 use base qw(Geo::OGR)
4961 
4962 #** @method scalar Default($value)
4963 # Object method.
4964 # Get or set the default value for this field.
4965 # @note a.k.a. GetDefault and SetDefault
4966 # @param value [optional]
4967 # @return the default value of this field in non-void context.
4968 #*
4969 sub Default {
4970  my $self = shift;
4971  SetDefault($self, $_[0]) if @_;
4972  GetDefault($self) if defined wantarray;
4973 }
4974 
4975 #** @method GetSchema()
4976 #*
4977 sub GetSchema {
4978 }
4979 
4980 #** @method scalar Ignored($ignore)
4981 # Object method.
4982 # Get and/or set the ignore status (whether this field should be
4983 # omitted when fetching features) of this field.
4984 # @note a.k.a. IsIgnored, SetIgnored
4985 # @param ignore [optional]
4986 # @return the ignore status of this field in non-void context.
4987 # @since 1.9.0
4988 #*
4989 sub Ignored {
4990  my $self = shift;
4991  SetIgnored($self, $_[0]) if @_;
4992  IsIgnored($self) if defined wantarray;
4993 }
4994 
4995 #** @method IsDefaultDriverSpecific()
4996 #*
4997 sub IsDefaultDriverSpecific {
4998 }
4999 
5000 #** @method scalar Justify($justify)
5001 # Object method.
5002 # Get and/or set the justification of this field.
5003 # @note a.k.a. GetJustify, SetJustify
5004 # @param justify [optional] One of field justify types (Geo::OGR::FieldDefn::JustifyValues).
5005 # @return the justify value of this field in non-void context.
5006 #*
5007 sub Justify {
5008  my($self, $justify) = @_;
5009  if (defined $justify) {
5010  $justify = s2i(justify => $justify);
5011  SetJustify($self, $justify);
5012  }
5013  return i2s(justify => GetJustify($self)) if defined wantarray;
5014 }
5015 
5016 #** @method list JustifyValues()
5017 # Package subroutine.
5018 # Justify values supported by GDAL. Current list is
5019 # Left, Right, and Undefined.
5020 #*
5021 sub JustifyValues {
5022  return @JUSTIFY;
5023 }
5024 
5025 #** @method scalar Name($name)
5026 # Object method.
5027 # Get and/or set the name of the field.
5028 # @note a.k.a. GetName, GetNameRef, SetName
5029 # @param name [optional]
5030 # @return the name in non-void context
5031 #*
5032 sub Name {
5033  my $self = shift;
5034  SetName($self, $_[0]) if @_;
5035  GetName($self) if defined wantarray;
5036 }
5037 
5038 #** @method scalar Nullable($nullable)
5039 # Object method.
5040 # Get or set the nullable constraint for this field.
5041 # @note a.k.a. IsNullable and SetNullable
5042 # @param nullable [optional]
5043 # @return the nullable value of this field in non-void context.
5044 #*
5045 sub Nullable {
5046  my $self = shift;
5047  SetNullable($self, $_[0]) if @_;
5048  IsNullable($self) if defined wantarray;
5049 }
5050 
5051 #** @method scalar Precision($precision)
5052 # Object method.
5053 # Get and/or set the precision of this field.
5054 # @note a.k.a. GetPrecision, SetPrecision
5055 # @param precision [optional]
5056 # @return the precision of this field in non-void context.
5057 #*
5058 sub Precision {
5059  my $self = shift;
5060  SetPrecision($self, $_[0]) if @_;
5061  GetPrecision($self) if defined wantarray;
5062 }
5063 
5064 #** @method hash reference Schema(%params)
5065 # Object method.
5066 # Get the schema or set parts of the schema
5067 # @param params [optional] as those in Geo::OGR::FieldDefn::new.
5068 # @return a reference to a hash whose keys are as those in Geo::OGR::FieldDefn::new.
5069 #*
5070 sub Schema {
5071  my $self = shift;
5072  if (@_) {
5073  my $params = @_ % 2 == 0 ? {@_} : shift;
5074  for my $key (keys %SCHEMA_KEYS) {
5075  next unless exists $params->{$key};
5076  eval "\$self->$key(\$params->{$key})";
5077  confess(last_error()) if $@;
5078  }
5079  }
5080  return unless defined wantarray;
5081  my %schema = ();
5082  for my $key (keys %SCHEMA_KEYS) {
5083  $schema{$key} = eval '$self->'.$key;
5084  }
5085  return wantarray ? %schema : \%schema;
5086 }
5087 
5088 #** @method SetSchema()
5089 #*
5090 sub SetSchema {
5091 }
5092 
5093 #** @method scalar SubType($SubType)
5094 # Object method.
5095 # @note a.k.a. GetSubType, SetSubType
5096 # @param SubType [optional] One of field sub types (Geo::OGR::FieldDefn::SubTypes).
5097 # @return the sub type of this field in non-void context.
5098 #*
5099 sub SubType {
5100  my($self, $subtype) = @_;
5101  if (defined $subtype) {
5102  $subtype = s2i(field_subtype => $subtype);
5103  SetSubType($self, $subtype);
5104  }
5105  return i2s(field_subtype => GetSubType($self)) if defined wantarray;
5106 }
5107 
5108 #** @method SubTypes()
5109 #*
5110 sub SubTypes {
5111  return @SUBTYPES;
5112 }
5113 
5114 #** @method scalar Type($type)
5115 # Object method.
5116 # Get and/or set the type of the field.
5117 # @note a.k.a. GetFieldTypeName, GetTypeName, GetType, SetType
5118 # @param type [optional] One of field types (Geo::OGR::FieldDefn::Types).
5119 # @return one of field types in non-void context.
5120 #*
5121 sub Type {
5122  my($self, $type) = @_;
5123  if (defined $type) {
5124  $type = s2i(field_type => $type);
5125  SetType($self, $type);
5126  }
5127  return i2s(field_type => GetType($self)) if defined wantarray;
5128 }
5129 
5130 #** @method list Types()
5131 # Package subroutine.
5132 # Field types supported by GDAL. Current list is
5133 # Binary, Date, DateTime, Integer, Integer64, Integer64List, IntegerList, Real, RealList, String, StringList, Time, WideString, and WideStringList.
5134 # (However, WideString is not supported.)
5135 #*
5136 sub Types {
5137  return @TYPES;
5138 }
5139 
5140 #** @method scalar Width($width)
5141 # Object method.
5142 # Get and/or set the field width.
5143 # @note a.k.a. GetWidth, SetWidth
5144 # @param width [optional]
5145 # @return the width of this field in non-void context.
5146 #*
5147 sub Width {
5148  my $self = shift;
5149  SetWidth($self, $_[0]) if @_;
5150  GetWidth($self) if defined wantarray;
5151 }
5152 
5153 #** @method Geo::OGR::FieldDefn new(%params)
5154 # Class method.
5155 # @brief Create a new field definition.
5156 #
5157 # @param Named parameters:
5158 # - \a Name Field name (default is 'unnamed').
5159 # - \a Type Field type, one of Geo::OGR::FieldDefn::Types (default is 'String').
5160 # - \a SubType Field sub type, one of Geo::OGR::FieldDefn::SubTypes.
5161 # - \a Justify Justify value, one of Geo::OGR::FieldDefn::JustifyValues
5162 # - \a Width
5163 # - \a Precision
5164 # - \a Nullable (default is true)
5165 # - \a Default
5166 # - \a Ignored (default is false)
5167 #
5168 # @note Simplified parameters Name => 'Type' are also supported.
5169 #
5170 # @return a new Geo::OGR::FieldDefn object
5171 #*
5172 sub new {
5173  my $pkg = shift;
5174  my $params = {Name => 'unnamed', Type => 'String'};
5175  if (@_ == 0) {
5176  } elsif (@_ == 1 and not ref $_[0]) {
5177  $params->{Name} = shift;
5178  } elsif (@_ == 2 and not $Geo::OGR::FieldDefn::SCHEMA_KEYS{$_[0]}) {
5179  $params->{Name} = shift;
5180  $params->{Type} = shift;
5181  } else {
5182  my $tmp = @_ % 2 == 0 ? {@_} : shift;
5183  for my $key (keys %$tmp) {
5184  if ($Geo::OGR::FieldDefn::SCHEMA_KEYS{$key}) {
5185  $params->{$key} = $tmp->{$key};
5186  } else {
5187  carp "Unknown parameter: '$key'." if $key ne 'Index';
5188  }
5189  }
5190  }
5191  $params->{Type} = s2i(field_type => $params->{Type});
5192  my $self = Geo::OGRc::new_FieldDefn($params->{Name}, $params->{Type});
5193  bless $self, $pkg;
5194  delete $params->{Name};
5195  delete $params->{Type};
5196  $self->Schema($params);
5197  return $self;
5198 }
5199 
5200 #** @class Geo::OGR::GeomFieldDefn
5201 # @brief A definition of a spatial attribute.
5202 # @details
5203 #*
5204 package Geo::OGR::GeomFieldDefn;
5205 
5206 use base qw(Geo::OGR)
5207 
5208 #** @method scalar GeometryType($type)
5209 # Object method.
5210 # @note a.k.a. GetType, SetType
5211 # @return the geometry type of the field.
5212 #*
5213 sub GeometryType {
5214 }
5215 
5216 #** @method GetSchema()
5217 #*
5218 sub GetSchema {
5219 }
5220 
5221 #** @method scalar Ignored($ignore)
5222 # Object method.
5223 # @note a.k.a. IsIgnored, SetIgnored
5224 # @return the ignore status of the field.
5225 #*
5226 sub Ignored {
5227  my $self = shift;
5228  SetIgnored($self, $_[0]) if @_;
5229  IsIgnored($self) if defined wantarray;
5230 }
5231 
5232 #** @method scalar Name($name)
5233 # Object method.
5234 # @note a.k.a. GetName, GetNameRef, SetName
5235 # @return the name of the field.
5236 #*
5237 sub Name {
5238  my $self = shift;
5239  SetName($self, $_[0]) if @_;
5240  GetName($self) if defined wantarray;
5241 }
5242 
5243 #** @method scalar Nullable($nullable)
5244 # Object method.
5245 # @note a.k.a. IsNullable, SetNullable
5246 # @return the nullable status of the field.
5247 #*
5248 sub Nullable {
5249  my $self = shift;
5250  SetNullable($self, $_[0]) if @_;
5251  IsNullable($self) if defined wantarray;
5252 }
5253 
5254 #** @method hash reference Schema(%params)
5255 # Object method.
5256 # Get the schema or set parts of the schema.
5257 # @param params [optional] as those in Geo::OGR::GeomFieldDefn::new.
5258 # @return a reference to a hash whose keys are as those in Geo::OGR::GeomFieldDefn::new.
5259 #*
5260 sub Schema {
5261  my $self = shift;
5262  if (@_) {
5263  my $params = @_ % 2 == 0 ? {@_} : shift;
5264  for my $key (keys %SCHEMA_KEYS) {
5265  next unless exists $params->{$key};
5266  eval "\$self->$key(\$params->{$key})";
5267  confess last_error() if $@;
5268  }
5269  }
5270  return unless defined wantarray;
5271  my %schema = ();
5272  for my $key (keys %SCHEMA_KEYS) {
5273  $schema{$key} = eval '$self->'.$key;
5274  }
5275  return wantarray ? %schema : \%schema;
5276 }
5277 
5278 #** @method SetSchema()
5279 #*
5280 sub SetSchema {
5281 }
5282 
5283 #** @method scalar SpatialReference($sr)
5284 # Object method.
5285 # @note a.k.a. GetSpatialRef, SetSpatialRef
5286 # @return the spatial reference of the field as a Geo::OSR::SpatialReference object.
5287 #*
5288 sub SpatialReference {
5289  my $self = shift;
5290  SetSpatialRef($self, $_[0]) if @_;
5291  GetSpatialRef($self) if defined wantarray;
5292 }
5293 
5294 #** @method Type()
5295 # Object method.
5296 # @return the type of this geometry field. One of Geo::OGR::GeomFieldDefn::Types
5297 #*
5298 sub Type {
5299  my($self, $type) = @_;
5300  if (defined $type) {
5301  $type = s2i(geometry_type => $type);
5302  SetType($self, $type);
5303  }
5304  i2s(geometry_type => GetType($self)) if defined wantarray;
5305 }
5306 
5307 #** @method Types()
5308 # Package subroutine.
5309 # @return a list of all geometry types, currently:
5310 # 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.
5311 #*
5312 sub Types {
5313  return Geo::OGR::Geometry::GeometryTypes();
5314 }
5315 
5316 #** @method Geo::OGR::GeomFieldDefn new(%params)
5317 # Class method.
5318 # @brief Create a new spatial field definition.
5319 #
5320 # @param params one or more of:
5321 # - \a Name name for the field (default is 'geom').
5322 # - \a GeometryType type for the field type, one of Geo::OGR::GeomFieldDefn::Types (default is 'Unknown').
5323 # - \a SpatialReference a Geo::OSR::SpatialReference object.
5324 # - \a Nullable (default is true)
5325 # - \a Ignored (default is false)
5326 #
5327 # @note Simplified parameters <name> => <type> is also supported.
5328 #
5329 # @return a new Geo::OGR::GeomFieldDefn object
5330 #*
5331 sub new {
5332  my $pkg = shift;
5333  my $params = {Name => 'geom', Type => 'Unknown'};
5334  if (@_ == 0) {
5335  } elsif (@_ == 1) {
5336  $params->{Name} = shift;
5337  } elsif (@_ == 2 and not $Geo::OGR::GeomFieldDefn::SCHEMA_KEYS{$_[0]}) {
5338  $params->{Name} = shift;
5339  $params->{Type} = shift;
5340  } else {
5341  my $tmp = @_ % 2 == 0 ? {@_} : shift;
5342  for my $key (keys %$tmp) {
5343  if ($Geo::OGR::GeomFieldDefn::SCHEMA_KEYS{$key}) {
5344  $params->{$key} = $tmp->{$key};
5345  } else {
5346  carp "Unknown parameter: '$key'." if $key ne 'Index' && $key ne 'GeometryType';
5347  }
5348  }
5349  $params->{Type} //= $tmp->{GeometryType};
5350  }
5351  $params->{Type} = s2i(geometry_type => $params->{Type});
5352  my $self = Geo::OGRc::new_GeomFieldDefn($params->{Name}, $params->{Type});
5353  bless $self, $pkg;
5354  delete $params->{Name};
5355  delete $params->{Type};
5356  $self->Schema($params);
5357  return $self;
5358 }
5359 
5360 #** @class Geo::OGR::Geometry
5361 # @brief Spatial data.
5362 # @details A geometry is spatial data (coordinate values, and a reference to a
5363 # spatial reference system) organized into one of the geometry
5364 # types. Geometries can be created from several type of data including
5365 # a Perl data structure. There are several methods, which modify,
5366 # compare, test, or compute values from geometries.
5367 # @note Most spatial analysis methods require <a
5368 # href="http://geos.osgeo.org/doxygen/">GEOS</a> to work rigorously.
5369 #*
5370 package Geo::OGR::Geometry;
5371 
5372 use base qw(Geo::OGR)
5373 
5374 #** @method AddGeometry($other)
5375 # Object method.
5376 # Add a copy of another geometry to a geometry collection
5377 # @param other a Geo::OGR::Geometry object
5378 #*
5379 sub AddGeometry {
5380 }
5381 
5382 #** @method AddGeometryDirectly($other)
5383 # Object method.
5384 # @param other a Geo::OGR::Geometry object
5385 #*
5386 sub AddGeometryDirectly {
5387 }
5388 
5389 #** @method AddPoint($x, $y, $z)
5390 # Object method.
5391 # Set the data of a point or add a point to a line string. Consider
5392 # using Geo::OGR::Geometry::Points. Note that the coordinate
5393 # dimension is automatically upgraded to 25D (3) if z is given.
5394 # @param x
5395 # @param y
5396 # @param z [optional]
5397 # Calls internally the 2D or 3D version depending on the number of parameters.
5398 #*
5399 sub AddPoint {
5400  my $self = shift;
5401  my $t = $self->GetGeometryType;
5402  my $has_z = HasZ($t);
5403  my $has_m = HasM($t);
5404  if (!$has_z && !$has_m) {
5405  $self->AddPoint_2D(@_[0..1]);
5406  } elsif ($has_z && !$has_m) {
5407  $self->AddPoint_3D(@_[0..2]);
5408  } elsif (!$has_z && $has_m) {
5409  $self->AddPointM(@_[0..2]);
5410  } else {
5411  $self->AddPointZM(@_[0..3]);
5412  }
5413 }
5414 
5415 #** @method AddPointM()
5416 #*
5417 sub AddPointM {
5418 }
5419 
5420 #** @method AddPointZM()
5421 #*
5422 sub AddPointZM {
5423 }
5424 
5425 #** @method AddPoint_2D($x, $y)
5426 # Object method.
5427 # Set the data of a point or add a point to a line string. Consider
5428 # using Geo::OGR::Geometry::Points.
5429 # @param x
5430 # @param y
5431 #*
5432 sub AddPoint_2D {
5433 }
5434 
5435 #** @method AddPoint_3D($x, $y, $z)
5436 # Object method.
5437 # Set the data of a point or add a point to a line string. Note that
5438 # the coordinate dimension is automatically upgraded to 25D (3). Consider
5439 # using Geo::OGR::Geometry::Points.
5440 # @param x
5441 # @param y
5442 # @param z
5443 #*
5444 sub AddPoint_3D {
5445 }
5446 
5447 #** @method Geo::OGR::Geometry ApproximateArcAngles(%params)
5448 # Package subroutine.
5449 # Create a line string, which approximates an arc.
5450 # @note All angles are in degrees.
5451 #
5452 # @param %params Named parameters:
5453 # - \a Center center point (default is [0, 0, 0])
5454 # - \a PrimaryRadius default is 1.
5455 # - \a SecondaryAxis default is 1.
5456 # - \a Rotation default is 0.
5457 # - \a StartAngle default is 0.
5458 # - \a EndAngle default is 360.
5459 # - \a MaxAngleStepSizeDegrees default is 4.
5460 # @return a new Geo::OGR::Geometry object.
5461 #*
5462 sub ApproximateArcAngles {
5463  my %p = @_;
5464  my %default = ( Center => [0,0,0],
5465  PrimaryRadius => 1,
5466  SecondaryAxis => 1,
5467  Rotation => 0,
5468  StartAngle => 0,
5469  EndAngle => 360,
5470  MaxAngleStepSizeDegrees => 4
5471  );
5472  for my $p (keys %p) {
5473  if (exists $default{$p}) {
5474  $p{$p} //= $default{$p};
5475  } else {
5476  carp "Unknown parameter: '$p'.";
5477  }
5478  }
5479  for my $p (keys %default) {
5480  $p{$p} //= $default{$p};
5481  }
5482  error("Usage: Center => [x,y,z].") unless ref($p{Center}) eq 'ARRAY';
5483  for my $i (0..2) {
5484  $p{Center}->[$i] //= 0;
5485  }
5486  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});
5487 }
5488 
5489 #** @method scalar Area()
5490 # Object method.
5491 # @note a.k.a. GetArea
5492 # @return the area of the polygon or multipolygon
5493 #*
5494 sub Area {
5495 }
5496 
5497 #** @method scalar As(%params)
5498 # Object method.
5499 # Export the geometry into a known format.
5500 #
5501 # @param params Named parameters:
5502 # - \a Format One of
5503 # - \a WKT Well Known Text.
5504 # - <em>ISO WKT</em>
5505 # - \a Text Same as WKT.
5506 # - \a WKB Well Known Binary.
5507 # - <em>ISO WKB</em>
5508 # - \a Binary Same as WKB.
5509 # - \a HEXWKB
5510 # - \a HEXEWKB
5511 # - \a GML
5512 # - \a GeoJSON
5513 # - \a ByteOrder Byte order for binary formats. Default is 'XDR'.
5514 # - \a SRID Spatial reference id for HEXEWKB.
5515 # - \a Options GML generation options.
5516 # - \a AltitudeMode For KML.
5517 #
5518 # @return the geometry in a given format.
5519 #*
5520 sub As {
5521  my $self = shift;
5522  my $p = named_parameters(\@_, Format => undef, ByteOrder => 'XDR', SRID => undef, Options => undef, AltitudeMode => undef);
5523  my $f = $p->{format};
5524  if ($f =~ /text/i) {
5525  return $self->AsText;
5526  } elsif ($f =~ /wkt/i) {
5527  if ($f =~ /iso/i) {
5528  return $self->ExportToIsoWkt;
5529  } else {
5530  return $self->AsText;
5531  }
5532  } elsif ($f =~ /binary/i) {
5533  return $self->ExportToWkb($p->{byteorder});
5534  } elsif ($f =~ /wkb/i) {
5535  if ($f =~ /iso/i) {
5536  $p->{byteorder} = s2i(byte_order => $p->{byteorder});
5537  return $self->ExportToIsoWkb($p->{byteorder});
5538  } elsif ($f =~ /ewkb/i) {
5539  return $self->AsHEXEWKB($p->{srid});
5540  } elsif ($f =~ /hex/i) {
5541  return $self->AsHEXWKB;
5542  } else {
5543  return $self->ExportToWkb($p->{byteorder});
5544  }
5545  } elsif ($f =~ /gml/i) {
5546  return $self->ExportToGML($p->{options});
5547  } elsif ($f =~ /kml/i) {
5548  return $self->ExportToKML($p->{altitudemode});
5549  } elsif ($f =~ /json/i) {
5550  return $self->AsJSON;
5551  } else {
5552  error(1, $f, map {$_=>1} qw/Text WKT ISO_WKT ISO_WKB HEX_WKB HEX_EWKB Binary GML KML JSON/);
5553  }
5554 }
5555 
5556 #** @method scalar AsBinary()
5557 # Object method.
5558 # Export the geometry into WKB.
5559 # @sa Geo::OGR::Geometry::As
5560 # @return the geometry as WKB.
5561 #*
5562 sub AsBinary {
5563 }
5564 
5565 #** @method scalar AsText()
5566 # Object method.
5567 # Export the geometry into WKT.
5568 # @sa Geo::OGR::Geometry::As
5569 # @return the geometry as WKT.
5570 #*
5571 sub AsText {
5572 }
5573 
5574 #** @method AssignSpatialReference($srs)
5575 # Object method.
5576 # @param srs a Geo::OSR::SpatialReference object
5577 #*
5578 sub AssignSpatialReference {
5579 }
5580 
5581 #** @method Geo::OGR::Geometry Boundary()
5582 # Object method.
5583 # @note a.k.a. GetBoundary
5584 # @return the boundary of this geometry as a geometry
5585 # @since 1.8.0
5586 #*
5587 sub Boundary {
5588 }
5589 
5590 #** @method Geo::OGR::Geometry Buffer($distance, $quadsecs = 30)
5591 # Object method.
5592 # @param distance
5593 # @param quadsecs
5594 # @return a new Geo::OGR::Geometry object
5595 #*
5596 sub Buffer {
5597 }
5598 
5599 #** @method Geo::OGR::Geometry BuildPolygonFromEdges($BestEffort = 0, $AutoClose = 0, $Tolerance = 0)
5600 # Object method.
5601 # Attempt to create a polygon from a collection of lines or from a multilinestring.
5602 # @param BestEffort For future
5603 # @param AutoClose Assure the first and last points of rings are same.
5604 # @param Tolerance Snap distance.
5605 # @exception Several possibilities, some are reported, some are general errors.
5606 # @return a new Geo::OGR::Geometry object (Polygon)
5607 #*
5608 sub BuildPolygonFromEdges {
5609 }
5610 
5611 #** @method list ByteOrders()
5612 # Package subroutine.
5613 # Same as Geo::OGR::ByteOrders
5614 #*
5615 sub ByteOrders {
5616  return @BYTE_ORDER_TYPES;
5617 }
5618 
5619 #** @method Geo::OGR::Geometry Centroid()
5620 # Object method.
5621 # @return a new Geo::OGR::Geometry object
5622 # @since 1.8.0
5623 #*
5624 sub Centroid {
5625 }
5626 
5627 #** @method Geo::OGR::Geometry Clone()
5628 # Object method.
5629 # @return a new Geo::OGR::Geometry object
5630 #*
5631 sub Clone {
5632 }
5633 
5634 #** @method CloseRings()
5635 # Object method.
5636 #*
5637 sub CloseRings {
5638 }
5639 
5640 #** @method Geo::OGR::Geometry Collect(@geometries)
5641 # Object method.
5642 # Create a geometrycollection from this and possibly other geometries.
5643 # @param geometries [optional] More geometries to add to the collection.
5644 # @return a new Geo::OGR::Geometry object of type geometrycollection.
5645 #*
5646 sub Collect {
5647 }
5648 
5649 #** @method scalar Contains($other)
5650 # Object method.
5651 # @param other a Geo::OGR::Geometry object
5652 # @return true if this geometry contains the other geometry, false otherwise
5653 #*
5654 sub Contains {
5655 }
5656 
5657 #** @method Geo::OGR::Geometry ConvexHull()
5658 # Object method.
5659 # @return a new Geo::OGR::Geometry object
5660 #*
5661 sub ConvexHull {
5662 }
5663 
5664 #** @method scalar CoordinateDimension($dimension)
5665 # Object method.
5666 # @param dimension [optional]
5667 # @return 2 or 3
5668 #*
5669 sub CoordinateDimension {
5670  my $self = shift;
5671  SetCoordinateDimension($self, $_[0]) if @_;
5672  GetCoordinateDimension($self) if defined wantarray;
5673 }
5674 
5675 #** @method scalar Crosses($other)
5676 # Object method.
5677 # @param other a Geo::OGR::Geometry object
5678 # @return true if this geometry crosses the other geometry, false otherwise
5679 #*
5680 sub Crosses {
5681 }
5682 
5683 #** @method DelaunayTriangulation()
5684 #*
5685 sub DelaunayTriangulation {
5686 }
5687 
5688 #** @method Geo::OGR::Geometry Difference($other)
5689 # Object method.
5690 # @param other a Geo::OGR::Geometry object
5691 # @return a new Geo::OGR::Geometry object
5692 #*
5693 sub Difference {
5694 }
5695 
5696 #** @method scalar Disjoint($other)
5697 # Object method.
5698 # @param other a Geo::OGR::Geometry object
5699 # @return true if this geometry is disjoint from the other geometry, false otherwise
5700 #*
5701 sub Disjoint {
5702 }
5703 
5704 #** @method list Dissolve()
5705 # Object method.
5706 # Dissolve a geometrycollection into separate geometries.
5707 # @return a list of new Geo::OGR::Geometry objects cloned from the collection.
5708 #*
5709 sub Dissolve {
5710  my $self = shift;
5711  my @c;
5712  my $n = $self->GetGeometryCount;
5713  if ($n > 0) {
5714  for my $i (0..$n-1) {
5715  push @c, $self->GetGeometryRef($i)->Clone;
5716  }
5717  } else {
5718  push @c, $self;
5719  }
5720  return @c;
5721 }
5722 
5723 #** @method scalar Distance($other)
5724 # Object method.
5725 # @param other a Geo::OGR::Geometry object
5726 # @return the distance to the other geometry
5727 #*
5728 sub Distance {
5729 }
5730 
5731 #** @method Distance3D()
5732 #*
5733 sub Distance3D {
5734 }
5735 
5736 #** @method Empty()
5737 # Object method.
5738 # Clear geometry data, i.e., remove all points, or, for a point, set
5739 # the coordinate dimension as zero.
5740 #*
5741 sub Empty {
5742 }
5743 
5744 #** @method scalar Equals($other)
5745 # Object method.
5746 # @note a.k.a. Equal (deprecated)
5747 # @param other a Geo::OGR::Geometry object
5748 # @return true if this geometry is equivalent to the other geometry, false otherwise
5749 #*
5750 sub Equals {
5751 }
5752 
5753 #** @method Extent()
5754 #*
5755 sub Extent {
5756  my $self = shift;
5757  return Geo::GDAL::Extent->new($self->GetEnvelope);
5758 }
5759 
5760 #** @method Feature()
5761 #*
5762 sub Feature {
5763  my $self = shift;
5764  parent($self);
5765 }
5766 
5767 #** @method FlattenTo2D()
5768 # Object method.
5769 #*
5770 sub FlattenTo2D {
5771 }
5772 
5773 #** @method Geo::OGR::Geometry ForceTo($type, ref options)
5774 # Object method.
5775 # Attempt to make a geometry of type 'type' out of this geometry.
5776 # @param type target geometry type. One of Geo::OGR::GeometryTypes.
5777 # @param options not used currently.
5778 # @return a new Geo::OGR::Geometry object.
5779 #*
5780 sub ForceTo {
5781  my $self = shift;
5782  my $type = shift;
5783  $type = s2i(geometry_type => $type);
5784  eval {
5785  $self = Geo::OGR::ForceTo($self, $type, @_);
5786  };
5787  confess last_error() if $@;
5788  return $self;
5789 }
5790 
5791 #** @method Geo::OGR::Geometry ForceToCollection(@geometries)
5792 # Object method.
5793 # Create a geometrycollection from the geometry.
5794 # @param geometries [optional] More geometries to add to the collection.
5795 # @return a new Geo::OGR::Geometry object of type geometrycollection.
5796 #*
5797 sub ForceToCollection {
5798  my $self = Geo::OGR::Geometry->new(GeometryType => 'GeometryCollection');
5799  for my $g (@_) {
5800  $self->AddGeometry($g);
5801  }
5802  return $self;
5803 }
5804 
5805 #** @method Geo::OGR::Geometry ForceToLineString()
5806 # Object method.
5807 # Attempt to create a line string from this geometry.
5808 # @return a new Geo::OGR::Geometry object.
5809 #*
5810 sub ForceToLineString {
5811  my $self = shift;
5812  return Geo::OGR::ForceToLineString($self);
5813 }
5814 
5815 #** @method Geo::OGR::Geometry ForceToMultiLineString(@linestrings)
5816 # Object method.
5817 # Attempt to create a multilinestring from the geometry, which must be a linestring.
5818 # @param linestrings [optional] More linestrings to add to the collection.
5819 # @return a new Geo::OGR::Geometry object of type multilinestring.
5820 #*
5821 sub ForceToMultiLineString {
5822  my $self = shift;
5823  $self = Geo::OGR::ForceToMultiLineString($self);
5824  for my $g (@_) {
5825  $self->AddGeometry($g);
5826  }
5827  return $self;
5828 }
5829 
5830 #** @method Geo::OGR::Geometry ForceToMultiPoint(@points)
5831 # Object method.
5832 # Attempt to create a multipoint from the geometry, which must be a point.
5833 # @param points [optional] More points to add to the collection.
5834 # @return a new Geo::OGR::Geometry object of type multipoint.
5835 #*
5836 sub ForceToMultiPoint {
5837  my $self = shift;
5838  $self = Geo::OGR::ForceToMultiPoint($self);
5839  for my $g (@_) {
5840  $self->AddGeometry($g);
5841  }
5842  return $self;
5843 }
5844 
5845 #** @method Geo::OGR::Geometry ForceToMultiPolygon(@polygons)
5846 # Object method.
5847 # Attempt to create a multipolygon from the geometry, which must be a polygon.
5848 # @param polygons [optional] More polygons to add to the collection.
5849 # @return a new Geo::OGR::Geometry object of type multipolygon.
5850 #*
5851 sub ForceToMultiPolygon {
5852  my $self = shift;
5853  $self = Geo::OGR::ForceToMultiPolygon($self);
5854  for my $g (@_) {
5855  $self->AddGeometry($g);
5856  }
5857  return $self;
5858 }
5859 
5860 #** @method Geo::OGR::Geometry ForceToPolygon()
5861 # Object method.
5862 # Attempt to create a polygon from this geometry.
5863 # @exception None reported. If this method fails, just a copy is returned.
5864 # @return a new Geo::OGR::Geometry object.
5865 #*
5866 sub ForceToPolygon {
5867 }
5868 
5869 #** @method scalar Geometry($n)
5870 # Object method.
5871 # Return the n:th (note zero-based index) element in this geometry or
5872 # geometry in this collection.
5873 # @note a.k.a. GetGeometryRef
5874 # @param n index to the geometry, which is a part of this geometry
5875 # @return a new Geo::OGR::Geometry object whose data is a part of the
5876 # parent geometry (this geometry is kept alive while the returned
5877 # geometry exists)
5878 #*
5879 sub Geometry {
5880 }
5881 
5882 #** @method scalar GeometryCount()
5883 # Object method.
5884 # Return the number of elements in this geometry or geometries in this collection.
5885 # @note a.k.a. GetGeometryCount
5886 # @return an integer
5887 #*
5888 sub GeometryCount {
5889 }
5890 
5891 #** @method scalar GeometryType()
5892 # Object method.
5893 #
5894 # @note The deprecated method GetGeometryType returns the
5895 # type as an integer
5896 #
5897 # @return the geometry type of this geometry (one of Geo::OGR::GeometryTypes).
5898 #*
5899 sub GeometryType {
5900  my $self = shift;
5901  return i2s(geometry_type => $self->GetGeometryType);
5902 }
5903 
5904 #** @method list GeometryTypes()
5905 # Package subroutine.
5906 # Same as Geo::OGR::GeometryTypes
5907 #*
5908 sub GeometryTypes {
5909  return @GEOMETRY_TYPES;
5910 }
5911 
5912 #** @method scalar GetCoordinateDimension()
5913 # Object method.
5914 # @return an integer
5915 #*
5916 sub GetCoordinateDimension {
5917 }
5918 
5919 #** @method GetCurveGeometry()
5920 #*
5921 sub GetCurveGeometry {
5922 }
5923 
5924 #** @method scalar GetDimension()
5925 # Object method.
5926 # @return 0, 1, or 2
5927 #*
5928 sub GetDimension {
5929 }
5930 
5931 #** @method list GetEnvelope()
5932 # Object method.
5933 # @note In scalar context returns a reference to an anonymous array
5934 # containing the envelope.
5935 # @return the envelope ($minx, $maxx, $miny, $maxy)
5936 #*
5937 sub GetEnvelope {
5938 }
5939 
5940 #** @method list GetEnvelope3D()
5941 # Object method.
5942 # @note In scalar context returns a reference to an anonymous array
5943 # containing the envelope.
5944 # @return the 3-D envelope ($minx, $maxx, $miny, $maxy, $minz, $maxz)
5945 # @since 1.9.0
5946 #*
5947 sub GetEnvelope3D {
5948 }
5949 
5950 #** @method scalar GetGeometryRef($index)
5951 # Object method.
5952 # @deprecated Use Geo::OGR::Geometry
5953 #*
5954 sub GetGeometryRef {
5955  my ($self, $i) = @_;
5956  my $ref = $self->_GetGeometryRef($i);
5957  keep($ref, $self);
5958  return $ref;
5959 }
5960 
5961 #** @method GetLinearGeometry()
5962 #*
5963 sub GetLinearGeometry {
5964 }
5965 
5966 #** @method GetM()
5967 #*
5968 sub GetM {
5969 }
5970 
5971 #** @method list GetPoint($index = 0)
5972 # Object method.
5973 # @param index
5974 # @return (x,y) or a list with more coordinates
5975 #*
5976 sub GetPoint {
5977  my($self, $i) = @_;
5978  $i //= 0;
5979  my $t = $self->GetGeometryType;
5980  my $has_z = HasZ($t);
5981  my $has_m = HasM($t);
5982  my $point;
5983  if (!$has_z && !$has_m) {
5984  $point = $self->GetPoint_2D($i);
5985  } elsif ($has_z && !$has_m) {
5986  $point = $self->GetPoint_3D($i);
5987  } elsif (!$has_z && $has_m) {
5988  $point = $self->GetPointZM($i);
5989  @$point = ($point->[0], $point->[1], $point->[3]);
5990  } else {
5991  $point = $self->GetPointZM($i);
5992  }
5993  return wantarray ? @$point : $point;
5994 }
5995 
5996 #** @method scalar GetPointCount()
5997 # Object method.
5998 # @return an integer
5999 #*
6000 sub GetPointCount {
6001 }
6002 
6003 #** @method GetPointZM()
6004 #*
6005 sub GetPointZM {
6006 }
6007 
6008 #** @method scalar GetPoint_2D($index = 0)
6009 # Object method.
6010 # @param index
6011 # @return (x,y) or a list with more coordinates
6012 #*
6013 sub GetPoint_2D {
6014 }
6015 
6016 #** @method scalar GetPoint_3D($index = 0)
6017 # Object method.
6018 # @param index
6019 # @return (x,y) or a list with more coordinates
6020 #*
6021 sub GetPoint_3D {
6022 }
6023 
6024 #** @method Geo::OSR::SpatialReference GetSpatialReference()
6025 # Object method.
6026 # @return a new Geo::OSR::SpatialReference object
6027 #*
6028 sub GetSpatialReference {
6029 }
6030 
6031 #** @method scalar GetX($index = 0)
6032 # Object method.
6033 # @param index
6034 # @return a number
6035 #*
6036 sub GetX {
6037 }
6038 
6039 #** @method scalar GetY($index = 0)
6040 # Object method.
6041 # @param index
6042 # @return a number
6043 #*
6044 sub GetY {
6045 }
6046 
6047 #** @method scalar GetZ($index = 0)
6048 # Object method.
6049 # @param index
6050 # @return a number
6051 #*
6052 sub GetZ {
6053 }
6054 
6055 #** @method HasCurveGeometry()
6056 #*
6057 sub HasCurveGeometry {
6058 }
6059 
6060 #** @method Geo::OGR::Geometry Intersection($other)
6061 # Object method.
6062 # @param other a Geo::OGR::Geometry object
6063 # @return a new Geo::OGR::Geometry object
6064 #*
6065 sub Intersection {
6066 }
6067 
6068 #** @method scalar Intersects($other)
6069 # Object method.
6070 # @note a.k.a. Intersect (deprecated)
6071 # @param other a Geo::OGR::Geometry object
6072 # @return true if this geometry intersects with the other geometry, false otherwise
6073 #*
6074 sub Intersects {
6075 }
6076 
6077 #** @method Is3D()
6078 #*
6079 sub Is3D {
6080 }
6081 
6082 #** @method scalar IsEmpty()
6083 # Object method.
6084 # Test whether the geometry is empty (has no points, or, for a point,
6085 # has coordinate dimension of zero).
6086 # @return boolean
6087 #*
6088 sub IsEmpty {
6089 }
6090 
6091 #** @method IsMeasured()
6092 #*
6093 sub IsMeasured {
6094 }
6095 
6096 #** @method scalar IsRing()
6097 # Object method.
6098 # Test if the geometry is a ring. Requires GEOS in GDAL.
6099 # @return boolean
6100 #*
6101 sub IsRing {
6102 }
6103 
6104 #** @method scalar IsSimple()
6105 # Object method.
6106 # Test the simplicity of the geometry (OGC sense). Requires GEOS in GDAL.
6107 # @return boolean
6108 #*
6109 sub IsSimple {
6110 }
6111 
6112 #** @method scalar IsValid()
6113 # Object method.
6114 # Test the validity of the geometry (OGC sense). Requires GEOS in GDAL.
6115 # @return boolean
6116 #*
6117 sub IsValid {
6118 }
6119 
6120 #** @method scalar Length()
6121 # Object method.
6122 # @return the length of the linestring
6123 #*
6124 sub Length {
6125 }
6126 
6127 #** @method Move($dx, $dy, $dz)
6128 # Object method.
6129 # Move every point of the object as defined by the parameters.
6130 # @param dx
6131 # @param dy
6132 # @param dz [optional]
6133 #*
6134 sub Move {
6135 }
6136 
6137 #** @method scalar Overlaps($other)
6138 # Object method.
6139 # @param other a Geo::OGR::Geometry object
6140 # @return true if this geometry overlaps the other geometry, false otherwise
6141 #*
6142 sub Overlaps {
6143 }
6144 
6145 #** @method list Point($index, $x, $y, $z)
6146 # Object method.
6147 # Get or set the point
6148 # @param index The index of the point. Optional (ignored if given) for
6149 # Point and Point25D geometries.
6150 # @param x [optional]
6151 # @param y [optional]
6152 # @param z [optional]
6153 # @return
6154 #*
6155 sub Point {
6156  my $self = shift;
6157  my $i;
6158  if (@_) {
6159  my $t = $self->GetGeometryType;
6160  my $i;
6161  if (Flatten($t) == $Geo::OGR::wkbPoint) {
6162  my $has_z = HasZ($t);
6163  my $has_m = HasM($t);
6164  if (!$has_z && !$has_m) {
6165  shift if @_ > 2;
6166  $i = 0;
6167  } elsif ($has_z || $has_m) {
6168  shift if @_ > 3;
6169  $i = 0;
6170  } else {
6171  shift if @_ > 4;
6172  $i = 0;
6173  }
6174  }
6175  $i = shift unless defined $i;
6176  $self->SetPoint($i, @_);
6177  }
6178  return unless defined wantarray;
6179  my $point = $self->GetPoint;
6180  return wantarray ? @$point : $point;
6181 }
6182 
6183 #** @method PointOnSurface()
6184 #*
6185 sub PointOnSurface {
6186 }
6187 
6188 #** @method array reference Points(arrayref points)
6189 # Object method.
6190 # Get or set the points of the geometry. The points (vertices) are
6191 # stored in obvious lists of lists. When setting, the geometry is
6192 # first emptied. The method uses internally either AddPoint_2D or
6193 # AddPoint_3D depending on the coordinate dimension of the input data.
6194 #
6195 # @note The same structure may represent different geometries
6196 # depending on the actual geometry type of the object.
6197 #
6198 # @param points [optional] A reference to an array. A point is a reference to an
6199 # array of numbers, a linestring or a ring is a reference to an array of points,
6200 # a polygon is a reference to an array of rings, etc.
6201 #
6202 # @return A reference to an array.
6203 #*
6204 sub Points {
6205  my $self = shift;
6206  my $t = $self->GetGeometryType;
6207  my $has_z = HasZ($t);
6208  my $has_m = HasM($t);
6209  my $postfix = '';
6210  $postfix .= 'Z' if HasZ($t);
6211  $postfix .= 'M' if HasM($t);
6212  $t = i2s(geometry_type => Flatten($t));
6213  my $points = shift;
6214  if ($points) {
6215  Empty($self);
6216  if ($t eq 'Unknown' or $t eq 'None' or $t eq 'GeometryCollection') {
6217  error("Can't set points of a geometry of type '$t'.");
6218  } elsif ($t eq 'Point') {
6219  # support both "Point" as a list of one point and one point
6220  if (ref($points->[0])) {
6221  $self->AddPoint(@{$points->[0]});
6222  } else {
6223  $self->AddPoint(@$points);
6224  }
6225  } elsif ($t eq 'LineString' or $t eq 'LinearRing' or $t eq 'CircularString') {
6226  for my $p (@$points) {
6227  $self->AddPoint(@$p);
6228  }
6229  } elsif ($t eq 'Polygon') {
6230  for my $r (@$points) {
6231  my $ring = Geo::OGR::Geometry->new('LinearRing');
6232  $ring->Set3D(1) if $has_z;
6233  $ring->SetMeasured(1) if $has_m;
6234  $ring->Points($r);
6235  $self->AddGeometryDirectly($ring);
6236  }
6237  } elsif ($t eq 'MultiPoint') {
6238  for my $p (@$points) {
6239  my $point = Geo::OGR::Geometry->new('Point'.$postfix);
6240  $point->Points($p);
6241  $self->AddGeometryDirectly($point);
6242  }
6243  } elsif ($t eq 'MultiLineString') {
6244  for my $l (@$points) {
6245  my $linestring = Geo::OGR::Geometry->new('LineString'.$postfix);
6246  $linestring->Points($l);
6247  $self->AddGeometryDirectly($linestring);
6248  }
6249  } elsif ($t eq 'MultiPolygon') {
6250  for my $p (@$points) {
6251  my $polygon = Geo::OGR::Geometry->new('Polygon'.$postfix);
6252  $polygon->Points($p);
6253  $self->AddGeometryDirectly($polygon);
6254  }
6255  }
6256  }
6257  return unless defined wantarray;
6258  $self->_GetPoints();
6259 }
6260 
6261 #** @method Polygonize()
6262 #*
6263 sub Polygonize {
6264 }
6265 
6266 #** @method RemoveGeometry()
6267 #*
6268 sub RemoveGeometry {
6269 }
6270 
6271 #** @method Segmentize($MaxLength)
6272 # Object method.
6273 # Modify the geometry such it has no segment longer than the given length.
6274 # @param MaxLength the given length
6275 #*
6276 sub Segmentize {
6277 }
6278 
6279 #** @method Set3D()
6280 #*
6281 sub Set3D {
6282 }
6283 
6284 #** @method SetCoordinateDimension($dimension)
6285 # Object method.
6286 # @param dimension
6287 #*
6288 sub SetCoordinateDimension {
6289 }
6290 
6291 #** @method SetMeasured()
6292 #*
6293 sub SetMeasured {
6294 }
6295 
6296 #** @method SetPoint($index, $x, $y, $z)
6297 # Object method.
6298 # Set the data of a point or a line string. Note that the coordinate
6299 # dimension is automatically upgraded to 25D (3) if z is given.
6300 # @param index
6301 # @param x
6302 # @param y
6303 # @param z [optional]
6304 #*
6305 sub SetPoint {
6306  my $self = shift;
6307  my $t = $self->GetGeometryType;
6308  my $has_z = HasZ($t);
6309  my $has_m = HasM($t);
6310  if (!$has_z && !$has_m) {
6311  $self->SetPoint_2D(@_[0..2]);
6312  } elsif ($has_z && !$has_m) {
6313  $self->SetPoint_3D(@_[0..3]);
6314  } elsif (!$has_z && $has_m) {
6315  $self->SetPointM(@_[0..3]);
6316  } else {
6317  $self->SetPointZM(@_[0..4]);
6318  }
6319 }
6320 
6321 #** @method SetPointM()
6322 #*
6323 sub SetPointM {
6324 }
6325 
6326 #** @method SetPointZM()
6327 #*
6328 sub SetPointZM {
6329 }
6330 
6331 #** @method SetPoint_2D($index, $x, $y)
6332 # Object method.
6333 # @param index
6334 # @param x
6335 # @param y
6336 #*
6337 sub SetPoint_2D {
6338 }
6339 
6340 #** @method SetPoint_3D($index, $x, $y, $z)
6341 # Object method.
6342 # Set the data of a point or a line string. Note that the coordinate
6343 # dimension is automatically upgraded to 25D (3).
6344 # @param index
6345 # @param x
6346 # @param y
6347 # @param z
6348 #*
6349 sub SetPoint_3D {
6350 }
6351 
6352 #** @method Geo::OGR::Geometry Simplify($Tolerance)
6353 # Object method.
6354 # Simplify the geometry.
6355 # @param Tolerance the length tolerance for the simplification
6356 # @since 1.8.0
6357 # @return a new Geo::OSR::Geometry object
6358 #*
6359 sub Simplify {
6360 }
6361 
6362 #** @method SimplifyPreserveTopology()
6363 #*
6364 sub SimplifyPreserveTopology {
6365 }
6366 
6367 #** @method SwapXY()
6368 #*
6369 sub SwapXY {
6370 }
6371 
6372 #** @method Geo::OGR::Geometry SymDifference($other)
6373 # Object method.
6374 # Compute symmetric difference.
6375 # @note a.k.a. SymmetricDifference
6376 # @param other a Geo::OGR::Geometry object
6377 # @return a new Geo::OGR::Geometry object
6378 # @since 1.8.0
6379 #*
6380 sub SymDifference {
6381 }
6382 
6383 #** @method scalar Touches($other)
6384 # Object method.
6385 # @param other a Geo::OGR::Geometry object
6386 # @return true if this geometry touches the other geometry, false otherwise
6387 #*
6388 sub Touches {
6389 }
6390 
6391 #** @method Transform($trans)
6392 # Object method.
6393 # @param trans a Geo::OSR::CoordinateTransformation object
6394 #*
6395 sub Transform {
6396 }
6397 
6398 #** @method TransformTo($srs)
6399 # Object method.
6400 # @param srs a Geo::OSR::SpatialReference object
6401 #*
6402 sub TransformTo {
6403 }
6404 
6405 #** @method Geo::OGR::Geometry Union($other)
6406 # Object method.
6407 # @param other a Geo::OGR::Geometry object
6408 # @return a new Geo::OGR::Geometry object
6409 #*
6410 sub Union {
6411 }
6412 
6413 #** @method Geo::OGR::Geometry UnionCascaded()
6414 # Object method.
6415 # @return a new Geo::OGR::Geometry object
6416 # @since 1.8.0
6417 #*
6418 sub UnionCascaded {
6419 }
6420 
6421 #** @method Value()
6422 #*
6423 sub Value {
6424 }
6425 
6426 #** @method scalar Within($other)
6427 # Object method.
6428 # @param other a Geo::OGR::Geometry object
6429 # @return true if this geometry is within the other geometry, false otherwise
6430 #*
6431 sub Within {
6432 }
6433 
6434 #** @method scalar WkbSize()
6435 # Object method.
6436 # @return an integer
6437 #*
6438 sub WkbSize {
6439 }
6440 
6441 #** @method Geo::OGR::Geometry new(%params)
6442 # Class method.
6443 # @param %params A named parameter, one of:
6444 # - \a GeometryType one the supported geometry types, see Geo::OGR::GeometryTypes.
6445 # - \a WKT a well known text string, which defines a geometry.
6446 # - \a WKB a well known binary string, which defines a geometry.
6447 # - \a HEXWKB WKB in hexadecimal.
6448 # - \a HEXEWKB PostGIS extended WKB.
6449 # - \a GML geometry written in Geographic Markup Language.
6450 # - \a GeoJSON geometry written in GeoJSON (JavaScript Object Notation for Geographic data).
6451 # - \a arc a reference to a list of values defining an arc: [CenterX,
6452 # CenterY, CenterZ, PrimaryRadius, SecondaryRadius, Rotation,
6453 # StartAngle, EndAngle, MaxAngleStepSizeDegrees] (see also Geo::OGR::Geometry::ApproximateArcAngles)
6454 # - \a Points An anonymous array as in method
6455 # Geo::OGR::Geometry::Points; Note: requires also GeometryType
6456 # parameter
6457 #
6458 # @return a new Geo::OGR::Geometry object.
6459 #*
6460 sub new {
6461  my $pkg = shift;
6462  my %param;
6463  if (@_ == 1 and ref($_[0]) eq 'HASH') {
6464  %param = %{$_[0]};
6465  } elsif (@_ % 2 == 0) {
6466  %param = @_;
6467  } else {
6468  ($param{GeometryType}) = @_;
6469  }
6470  my $type = $param{GeometryType} // $param{Type} // $param{type};
6471  my $srs = $param{SRS} // $param{srs};
6472  my $wkt = $param{WKT} // $param{wkt};
6473  my $wkb = $param{WKB} // $param{wkb};
6474  my $hex = $param{HEXEWKB} // $param{HEX_EWKB} // $param{hexewkb} // $param{hex_ewkb};
6475  my $srid;
6476  if ($hex) {
6477  # EWKB contains SRID
6478  $srid = substr($hex, 10, 8);
6479  substr($hex, 10, 8) = '';
6480  } else {
6481  $hex = $param{HEXWKB} // $param{HEX_WKB} // $param{hexwkb} // $param{hex_wkb};
6482  }
6483  if ($hex) {
6484  $wkb = '';
6485  for (my $i = 0; $i < length($hex); $i+=2) {
6486  $wkb .= chr(hex(substr($hex,$i,2)));
6487  }
6488  }
6489  my $gml = $param{GML} // $param{gml};
6490  my $json = $param{GeoJSON} // $param{geojson} // $param{JSON} // $param{json};
6491  my $points = $param{Points} // $param{points};
6492  my $arc = $param{Arc} // $param{arc};
6493  my $self;
6494  if (defined $wkt) {
6495  $self = Geo::OGRc::CreateGeometryFromWkt($wkt, $srs);
6496  } elsif (defined $wkb) {
6497  $self = Geo::OGRc::CreateGeometryFromWkb($wkb, $srs);
6498  } elsif (defined $gml) {
6499  $self = Geo::OGRc::CreateGeometryFromGML($gml);
6500  } elsif (defined $json) {
6501  $self = Geo::OGRc::CreateGeometryFromJson($json);
6502  } elsif (defined $type) {
6503  $type = s2i(geometry_type => $type);
6504  $self = Geo::OGRc::new_Geometry($type); # flattens the type
6505  $self->Set3D(1) if HasZ($type);
6506  $self->SetMeasured(1) if HasM($type);
6507  } elsif (defined $arc) {
6508  $self = Geo::OGRc::ApproximateArcAngles(@$arc);
6509  } else {
6510  error(1, undef, map {$_=>1} qw/GeometryType WKT WKB HEXEWKB HEXWKB GML GeoJSON Arc/);
6511  }
6512  bless $self, $pkg if defined $self;
6513  $self->Points($points) if $points;
6514  return $self;
6515 }
6516 
6517 #** @class Geo::OGR::Layer
6518 # @brief A collection of similar features.
6519 # @details A layer object is typically obtained with a data source object. A
6520 # layer has a data model (a schema), which is maintained in a
6521 # definition object, and a set of features, which contain data
6522 # according to the data model. The schema is typically set when the
6523 # layer is created or opened, but it may be altered somewhat with
6524 # methods Geo::OGR::Layer::CreateField,
6525 # Geo::OGR::Layer::AlterFieldDefn, and
6526 # Geo::OGR::Layer::DeleteField. Features and/or their data can be
6527 # read, inserted and deleted. Reading can be filtered. Layers can be
6528 # compared to each other with methods Clip, Erase, Identity,
6529 # Intersection, SymDifference, Union, and Update.
6530 # A layer may have metadata OLMD_FID64 => 'YES' if it holds features
6531 # with 64 bit FIDs. The metadata of a layer can be obtained with
6532 # GetMetadata method.
6533 #*
6534 package Geo::OGR::Layer;
6535 
6536 use base qw(Geo::GDAL::MajorObject Geo::OGR)
6537 
6538 #** @method AlterFieldDefn($name, %params)
6539 # Object method.
6540 # @param field the name of the field to be altered.
6541 # @param params as in Geo::OGR::FieldDefn::new. Width and
6542 # Precision should be both or neither.
6543 # @note Only non-spatial fields can be altered.
6544 # @note Also the deprecated form AlterFieldDefn($field,
6545 # Geo::OGR::FieldDefn $Defn, $Flags) works.
6546 #*
6547 sub AlterFieldDefn {
6548  my $self = shift;
6549  my $index = $self->GetLayerDefn->GetFieldIndex(shift // 0);
6550  my $param = @_ % 2 == 0 ? {@_} : shift;
6551  if (blessed($param) and $param->isa('Geo::OGR::FieldDefn')) {
6552  _AlterFieldDefn($self, $index, @_);
6553  } else {
6554  my $definition = Geo::OGR::FieldDefn->new($param);
6555  my $flags = 0;
6556  $flags |= 1 if exists $param->{Name};
6557  $flags |= 2 if exists $param->{Type};
6558  $flags |= 4 if exists $param->{Width} or exists $param->{Precision};
6559  $flags |= 8 if exists $param->{Nullable};
6560  $flags |= 16 if exists $param->{Default};
6561  _AlterFieldDefn($self, $index, $definition, $flags);
6562  }
6563 }
6564 
6565 #** @method list Capabilities()
6566 # Object method.
6567 # Both a package subroutine and an object method.
6568 # @return a list of capabilities. The object method returns a list of
6569 # the capabilities the layer has. The package subroutine returns a list of
6570 # all potential capabilities a layer may have. These are currently:
6571 # AlterFieldDefn, CreateField, CreateGeomField, CurveGeometries, DeleteFeature, DeleteField, FastFeatureCount, FastGetExtent, FastSetNextByIndex, FastSpatialFilter, IgnoreFields, MeasuredGeometries, RandomRead, RandomWrite, ReorderFields, SequentialWrite, StringsAsUTF8, and Transactions.
6572 #
6573 # Examples:
6574 # \code
6575 # @cap = Geo::OGR::Layer::Capabilities(); # the package subroutine
6576 # @cap = $layer->Capabilities(); # the object method
6577 # \endcode
6578 #*
6579 sub Capabilities {
6580  return @CAPABILITIES if @_ == 0;
6581  my $self = shift;
6582  my @cap;
6583  for my $cap (@CAPABILITIES) {
6584  push @cap, $cap if _TestCapability($self, $CAPABILITIES{$cap});
6585  }
6586  return @cap;
6587 }
6588 
6589 #** @method Clip(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
6590 # Object method.
6591 # Clip off areas that are not covered by the method layer. The schema
6592 # of the result layer can be set before calling this method, or is
6593 # initialized to to contain all fields from
6594 # this and method layer.
6595 # @param method method layer.
6596 # @param result result layer.
6597 # @param options a reference to an options hash.
6598 # @param callback [optional] a reference to a subroutine, which will
6599 # be called with parameters (number progress, string msg, callback_data)
6600 # @param callback_data [optional]
6601 #*
6602 sub Clip {
6603 }
6604 
6605 #** @method CommitTransaction()
6606 # Object method.
6607 #*
6608 sub CommitTransaction {
6609 }
6610 
6611 #** @method CreateFeature()
6612 #*
6613 sub CreateFeature {
6614 }
6615 
6616 #** @method CreateField(%params)
6617 # Object method.
6618 # Create a field.
6619 # @param params as in Geo::OGR::FieldDefn::new or
6620 # Geo::OGR::GeomFieldDefn::new, plus ApproxOK (whose default is true).
6621 #*
6622 sub CreateField {
6623  my $self = shift;
6624  my %defaults = ( ApproxOK => 1,
6625  Type => '' );
6626  my %params;
6627  if (@_ == 0) {
6628  } elsif (ref($_[0]) eq 'HASH') {
6629  %params = %{$_[0]};
6630  } elsif (@_ % 2 == 0) {
6631  %params = @_;
6632  } else {
6633  ($params{Defn}) = @_;
6634  }
6635  for my $k (keys %defaults) {
6636  $params{$k} //= $defaults{$k};
6637  }
6638  if (blessed($params{Defn}) and $params{Defn}->isa('Geo::OGR::FieldDefn')) {
6639  $self->_CreateField($params{Defn}, $params{ApproxOK});
6640  } elsif (blessed($_[0]) and $params{Defn}->isa('Geo::OGR::GeomFieldDefn')) {
6641  $self->CreateGeomField($params{Defn}, $params{ApproxOK});
6642  } else {
6643  # if Name and Type are missing, assume Name => Type
6644  if (!(exists $params{Name} && exists $params{Type})) {
6645  for my $key (sort keys %params) {
6646  if (s_exists(field_type => $params{$key}) ||
6647  s_exists(geometry_type => $params{$key}))
6648  {
6649  $params{Name} = $key;
6650  $params{Type} = $params{$key};
6651  delete $params{$key};
6652  last;
6653  }
6654  }
6655  }
6656  my $a = $params{ApproxOK};
6657  delete $params{ApproxOK};
6658  if (exists $params{GeometryType}) {
6659  $params{Type} = $params{GeometryType};
6660  delete $params{GeometryType};
6661  }
6662  if (s_exists(field_type => $params{Type})) {
6663  my $fd = Geo::OGR::FieldDefn->new(%params);
6664  _CreateField($self, $fd, $a);
6665  } elsif (s_exists(geometry_type => $params{Type})) {
6666  my $fd = Geo::OGR::GeomFieldDefn->new(%params);
6667  CreateGeomField($self, $fd, $a);
6668  } elsif ($params{Type} ) {
6669  error("Invalid field type: $params{Type}.")
6670  } elsif ($params{Name} ) {
6671  error("Missing type for field: $params{Name}.")
6672  } else {
6673  error("Missing name and type for a field.")
6674  }
6675  }
6676 }
6677 
6678 #** @method DataSource()
6679 #*
6680 sub DataSource {
6681 }
6682 
6683 #** @method Dataset()
6684 #*
6685 sub Dataset {
6686  my $self = shift;
6687  parent($self);
6688 }
6689 
6690 #** @method DeleteFeature($fid)
6691 # Object method.
6692 # @param fid feature id
6693 #*
6694 sub DeleteFeature {
6695 }
6696 
6697 #** @method DeleteField($field)
6698 # Object method.
6699 # Delete an existing field from a layer.
6700 # @param field name (or index) of the field which is deleted
6701 # @note Only non-spatial fields can be deleted.
6702 #*
6703 sub DeleteField {
6704  my ($self, $field) = @_;
6705  my $index = $self->GetLayerDefn->GetFieldIndex($field // 0);
6706  _DeleteField($self, $index);
6707 }
6708 
6709 #** @method Erase(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
6710 # Object method.
6711 # The result layer contains features whose geometries represent areas
6712 # that are in the input layer but not in the method layer. The
6713 # features in the result layer have attributes from the input
6714 # layer. The schema of the result layer can be set by the user or, if
6715 # it is empty, is initialized to contain all fields in the input
6716 # layer.
6717 # @param method method layer.
6718 # @param result result layer.
6719 # @param options a reference to an options hash.
6720 # @param callback [optional] a reference to a subroutine, which will
6721 # be called with parameters (number progress, string msg, callback_data)
6722 # @param callback_data [optional]
6723 #*
6724 sub Erase {
6725 }
6726 
6727 #** @method Geo::OGR::Feature Feature($f)
6728 # Object method.
6729 #
6730 # @param f [optional] feature id, a feature, a row, or a tuple
6731 #
6732 # @note If the argument feature has a null FID (FID not set) the
6733 # feature is inserted into the layer as a new feature. If the FID is
6734 # non null, then the feature replaces the feature in the layer with
6735 # that FID.
6736 #
6737 # @return a new Geo::OGR::Feature object that represents the feature
6738 # in the layer.
6739 #*
6740 sub Feature {
6741  my $self = shift;
6742  my $x = shift;
6743  return $self->GetFeature($x) unless $x && ref $x;
6744  # Insert or Set depending on the FID
6745  my $fid;
6746  if (ref $x eq 'ARRAY') {
6747  # FID is the first item in the array
6748  $fid = $x->[0];
6749  } elsif (ref $x eq 'HASH') {
6750  # FID is FID
6751  $fid = $x->{FID};
6752  } else {
6753  $fid = $x->FID;
6754  }
6755  # OGRNullFID is -1
6756  if (!defined $fid || $fid < 0) {
6757  $self->InsertFeature($x);
6758  } else {
6759  $self->SetFeature($x);
6760  }
6761 }
6762 
6763 #** @method scalar FeatureCount($force = 1)
6764 # Object method.
6765 # A.k.a GetFeatureCount
6766 # @param force
6767 # @return integer
6768 #*
6769 sub FeatureCount {
6770 }
6771 
6772 #** @method Features()
6773 #*
6774 sub Features {
6775  my $self = shift;
6776  $self->ResetReading;
6777  return sub {
6778  return $self->GetNextFeature;
6779  }
6780 }
6781 
6782 #** @method ForFeatures($code, $in_place)
6783 # Object method.
6784 # @note experimental, the syntax may change
6785 #
6786 # Call code for all features. This is a simple wrapper for
6787 # ResetReading and while(GetNextFeature).
6788 #
6789 # Example usage:
6790 # \code
6791 # $layer->ForFeatures(sub {my $f = shift; $self->DeleteFeature($f->FID)}); # empties the layer
6792 # \endcode
6793 #
6794 # @param code a reference to a subroutine, which is called with each
6795 # feature as an argument
6796 # @param in_place if set to true, the feature is stored back to the
6797 # layer
6798 #*
6799 sub ForFeatures {
6800  my $self = shift;
6801  my $code = shift;
6802  my $in_place = shift;
6803  $self->ResetReading;
6804  while (my $f = $self->GetNextFeature) {
6805  keep($f, $self);
6806  $code->($f);
6807  $self->SetFeature($f) if $in_place;
6808  };
6809 }
6810 
6811 #** @method ForGeometries($code, $in_place)
6812 # Object method.
6813 # @note experimental, the syntax may change
6814 #
6815 # Call code for all geometries. This is a simple wrapper for
6816 # ResetReading and while(GetNextFeature).
6817 #
6818 # Example usage:
6819 # \code
6820 # my $area = 0;
6821 # $layer->ForGeometries(sub {my $g = shift; $area += $g->Area}); # computes the total area
6822 # \endcode
6823 #
6824 # @param code a reference to a subroutine, which is called with each
6825 # geometry as an argument
6826 # @param in_place if set to true, the geometry is stored back to the
6827 # layer
6828 #*
6829 sub ForGeometries {
6830  my $self = shift;
6831  my $code = shift;
6832  my $in_place = shift;
6833  $self->ResetReading;
6834  while (my $f = $self->GetNextFeature) {
6835  my $g = $f->Geometry();
6836  $code->($g);
6837  if ($in_place) {
6838  $f->Geometry($g);
6839  $self->SetFeature($f);
6840  }
6841  }
6842 }
6843 
6844 #** @method Geometries()
6845 #*
6846 sub Geometries {
6847  my $self = shift;
6848  $self->ResetReading;
6849  return sub {
6850  my $f = $self->GetNextFeature;
6851  return 0 unless $f;
6852  return $f->Geometry;
6853  }
6854 }
6855 
6856 #** @method scalar GeometryType($field)
6857 # Object method.
6858 # @param field the name or index of the spatial field.
6859 # @return the geometry type of the spatial field.
6860 #*
6861 sub GeometryType {
6862  my $self = shift;
6863  my $d = $self->GetDefn;
6864  my $field = $d->GetGeomFieldIndex(shift // 0);
6865  my $fd = $d->_GetGeomFieldDefn($field);
6866  return $fd->Type if $fd;
6867 }
6868 
6869 #** @method Geo::OGR::DataSource GetDataSource()
6870 # Object method.
6871 # @return the data source object to which this layer object belongs to.
6872 #*
6873 sub GetDataSource {
6874  my $self = shift;
6875  parent($self);
6876 }
6877 
6878 #** @method Geo::OGR::FeatureDefn GetDefn()
6879 # Object method.
6880 # A.k.a GetLayerDefn.
6881 # @return a Geo::OGR::FeatureDefn object.
6882 #*
6883 sub GetDefn {
6884  my $self = shift;
6885  my $defn = $self->GetLayerDefn;
6886  keep($defn, $self);
6887 }
6888 
6889 #** @method list GetExtent($force = 1)
6890 # Object method.
6891 # @param force compute the extent even if it is expensive
6892 # @note In scalar context returns a reference to an anonymous array
6893 # containing the extent.
6894 # @return the extent ($minx, $maxx, $miny, $maxy)
6895 # @param force
6896 # @return the extent = ($minx, $maxx, $miny, $maxy) as a listref
6897 #*
6898 sub GetExtent {
6899 }
6900 
6901 #** @method scalar GetFIDColumn()
6902 # Object method.
6903 # @return the name of the underlying database column being used as the
6904 # FID column, or "" if not supported.
6905 #*
6906 sub GetFIDColumn {
6907 }
6908 
6909 #** @method Geo::OGR::Feature GetFeature($fid)
6910 # Object method.
6911 # @param fid feature id
6912 # @return a new Geo::OGR::Feature object that represents the feature in the layer.
6913 #*
6914 sub GetFeature {
6915  my ($self, $fid) = @_;
6916  $fid //= 0;
6917  my $f = $self->_GetFeature($fid);
6918  error(2, "FID=$fid", '"Feature') unless ref $f eq 'Geo::OGR::Feature';
6919  keep($f, $self);
6920 }
6921 
6922 #** @method GetFeatureCount()
6923 #*
6924 sub GetFeatureCount {
6925 }
6926 
6927 #** @method scalar GetFeaturesRead()
6928 # Object method.
6929 # @return integer
6930 #*
6931 sub GetFeaturesRead {
6932 }
6933 
6934 #** @method scalar GetFieldDefn($name)
6935 # Object method.
6936 # Get the definition of a field.
6937 # @param name the name of the field.
6938 # @return a Geo::OGR::FieldDefn object.
6939 #*
6940 sub GetFieldDefn {
6941  my $self = shift;
6942  my $d = $self->GetDefn;
6943  my $field = $d->GetFieldIndex(shift // 0);
6944  return $d->_GetFieldDefn($field);
6945 }
6946 
6947 #** @method list GetFieldNames()
6948 # Object method.
6949 # @return a list of the names of the fields in this layer. The
6950 # non-geometry field names are first in the list and then the geometry
6951 # fields.
6952 #*
6953 sub GetFieldNames {
6954  my $self = shift;
6955  my $d = $self->GetDefn;
6956  my @ret;
6957  for (my $i = 0; $i < $d->GetFieldCount; $i++) {
6958  push @ret, $d->GetFieldDefn($i)->Name();
6959  }
6960  for (my $i = 0; $i < $d->GetGeomFieldCount; $i++) {
6961  push @ret, $d->GetGeomFieldDefn($i)->Name();
6962  }
6963  return @ret;
6964 }
6965 
6966 #** @method scalar GetGeomFieldDefn($name)
6967 # Object method.
6968 # Get the definition of a spatial field.
6969 # @param name the name of the spatial field.
6970 # @return a Geo::OGR::GeomFieldDefn object.
6971 #*
6972 sub GetGeomFieldDefn {
6973  my $self = shift;
6974  my $d = $self->GetDefn;
6975  my $field = $d->GetGeomFieldIndex(shift // 0);
6976  return $d->_GetGeomFieldDefn($field);
6977 }
6978 
6979 #** @method scalar GetName()
6980 # Object method.
6981 # @return the name of the layer.
6982 #*
6983 sub GetName {
6984 }
6985 
6986 #** @method Geo::OGR::Feature GetNextFeature()
6987 # Object method.
6988 # @return iteratively Geo::OGR::Feature objects from the layer. The
6989 # iteration obeys the spatial and the attribute filter.
6990 #*
6991 sub GetNextFeature {
6992 }
6993 
6994 #** @method hash reference GetSchema()
6995 # Object method.
6996 # @brief Get the schema of this layer.
6997 # @note The schema of a layer cannot be set with this method. If you
6998 # have a Geo::OGR::FeatureDefn object before creating the layer, use
6999 # its schema in the Geo::OGR::CreateLayer method.
7000 # @return the schema of this layer, as in Geo::OGR::FeatureDefn::Schema.
7001 #*
7002 sub GetSchema {
7003  my $self = shift;
7004  carp "Schema of a layer should not be set directly." if @_;
7005  if (@_ and @_ % 2 == 0) {
7006  my %schema = @_;
7007  if ($schema{Fields}) {
7008  for my $field (@{$schema{Fields}}) {
7009  $self->CreateField($field);
7010  }
7011  }
7012  }
7013  return $self->GetDefn->Schema;
7014 }
7015 
7016 #** @method Geo::OGR::Geometry GetSpatialFilter()
7017 # Object method.
7018 # @return a new Geo::OGR::Geometry object
7019 #*
7020 sub GetSpatialFilter {
7021 }
7022 
7023 #** @method GetStyleTable()
7024 #*
7025 sub GetStyleTable {
7026 }
7027 
7028 #** @method Identity(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7029 # Object method.
7030 # The result layer contains features whose geometries represent areas
7031 # that are in the input layer. The features in the result layer have
7032 # attributes from both input and method layers. The schema of the
7033 # result layer can be set by the user or, if it is empty, is
7034 # initialized to contain all fields in input and method layers.
7035 # @param method method layer.
7036 # @param result result layer.
7037 # @param options a reference to an options hash.
7038 # @param callback [optional] a reference to a subroutine, which will
7039 # be called with parameters (number progress, string msg, callback_data)
7040 # @param callback_data [optional]
7041 #*
7042 sub Identity {
7043 }
7044 
7045 #** @method InsertFeature($feature)
7046 # Object method.
7047 # Creates a new feature which has the schema of the layer and
7048 # initializes it with data from the argument. Then inserts the feature
7049 # into the layer (using CreateFeature). Uses Geo::OGR::Feature::Row or
7050 # Geo::OGR::Feature::Tuple.
7051 # @param feature a Geo::OGR::Feature object or reference to feature
7052 # data in a hash (as in Geo::OGR::Feature::Row) or in an array (as in
7053 # Geo::OGR::Feature::Tuple)
7054 # @return the new feature.
7055 #*
7056 sub InsertFeature {
7057  my $self = shift;
7058  my $feature = shift;
7059  error("Usage: \$feature->InsertFeature(reference to a hash or array).") unless ref($feature);
7060  my $new = Geo::OGR::Feature->new(Schema => $self, Values => $feature);
7061  $self->CreateFeature($new);
7062  return unless defined wantarray;
7063  keep($new, $self);
7064 }
7065 
7066 #** @method Intersection(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7067 # Object method.
7068 # The result layer contains features whose geometries represent areas
7069 # that are common between features in the input layer and in the
7070 # method layer. The schema of the result layer can be set before
7071 # calling this method, or is initialized to contain all fields from
7072 # this and method layer.
7073 # @param method method layer.
7074 # @param result result layer.
7075 # @param options a reference to an options hash.
7076 # @param callback [optional] a reference to a subroutine, which will
7077 # be called with parameters (number progress, string msg, callback_data)
7078 # @param callback_data [optional]
7079 #*
7080 sub Intersection {
7081 }
7082 
7083 #** @method ReorderField()
7084 #*
7085 sub ReorderField {
7086 }
7087 
7088 #** @method ReorderFields()
7089 #*
7090 sub ReorderFields {
7091 }
7092 
7093 #** @method ResetReading()
7094 # Object method.
7095 # Initialize the layer object for iterative reading.
7096 #*
7097 sub ResetReading {
7098 }
7099 
7100 #** @method RollbackTransaction()
7101 # Object method.
7102 #*
7103 sub RollbackTransaction {
7104 }
7105 
7106 #** @method hash reference Row(%row)
7107 # Object method.
7108 # Get and/or set the data of a feature that has the supplied feature
7109 # id (the next feature obtained with GetNextFeature is used if feature
7110 # id is not given). Calls Geo::OGR::Feature::Row.
7111 # @param row [optional] feature data
7112 # @return a reference to feature data in a hash
7113 #*
7114 sub Row {
7115  my $self = shift;
7116  my $update = @_ > 0;
7117  my %row = @_;
7118  my $feature = defined $row{FID} ? $self->GetFeature($row{FID}) : $self->GetNextFeature;
7119  return unless $feature;
7120  my $ret;
7121  if (defined wantarray) {
7122  $ret = $feature->Row(@_);
7123  } else {
7124  $feature->Row(@_);
7125  }
7126  $self->SetFeature($feature) if $update;
7127  return unless defined wantarray;
7128  return $ret;
7129 }
7130 
7131 #** @method SetAttributeFilter($filter_string)
7132 # Object method.
7133 # Set or clear the attribute filter.
7134 # @param filter_string a SQL WHERE clause or undef to clear the
7135 # filter.
7136 #*
7137 sub SetAttributeFilter {
7138 }
7139 
7140 #** @method SetFeature($feature)
7141 # Object method.
7142 # @note The feature should have the same schema as the layer.
7143 #
7144 # Replaces a feature in the layer based on the given feature's
7145 # id. Requires RandomWrite capability.
7146 # @param feature a Geo::OGR::Feature object
7147 #*
7148 sub SetFeature {
7149 }
7150 
7151 #** @method SetIgnoredFields(@fields)
7152 # Object method.
7153 # @param fields a list of field names
7154 #*
7155 sub SetIgnoredFields {
7156 }
7157 
7158 #** @method SetNextByIndex($new_index)
7159 # Object method.
7160 # @param new_index the index to which set the read cursor in the
7161 # current iteration
7162 #*
7163 sub SetNextByIndex {
7164 }
7165 
7166 #** @method SetSpatialFilter($filter)
7167 # Object method.
7168 # @param filter [optional] a Geo::OGR::Geometry object. If not given,
7169 # removes the filter if there is one.
7170 #*
7171 sub SetSpatialFilter {
7172 }
7173 
7174 #** @method SetSpatialFilterRect($minx, $miny, $maxx, $maxy)
7175 # Object method.
7176 # @param minx
7177 # @param miny
7178 # @param maxx
7179 # @param maxy
7180 #*
7181 sub SetSpatialFilterRect {
7182 }
7183 
7184 #** @method SetStyleTable()
7185 #*
7186 sub SetStyleTable {
7187 }
7188 
7189 #** @method Geo::OGR::Geometry SpatialFilter(@filter)
7190 # Object method.
7191 # @param filter [optional] a Geo::OGR::Geometry object or a string. An
7192 # undefined value removes the filter if there is one.
7193 # @return a new Geo::OGR::Geometry object
7194 # @param filter [optional] a rectangle ($minx, $miny, $maxx, $maxy).
7195 # @return a new Geo::OGR::Geometry object
7196 #*
7197 sub SpatialFilter {
7198  my $self = shift;
7199  $self->SetSpatialFilter($_[0]) if @_ == 1;
7200  $self->SetSpatialFilterRect(@_) if @_ == 4;
7201  return unless defined wantarray;
7202  $self->GetSpatialFilter;
7203 }
7204 
7205 #** @method Geo::OSR::SpatialReference SpatialReference($name, Geo::OSR::SpatialReference sr)
7206 # Object method.
7207 # @note A.k.a GetSpatialRef.
7208 # Get or set the projection of a spatial field of this layer. Gets or
7209 # sets the projection of the first field if no field name is given.
7210 # @param name [optional] a name of a spatial field in this layer.
7211 # @param sr [optional] a Geo::OSR::SpatialReference object,
7212 # which replaces the existing projection.
7213 # @return a Geo::OSR::SpatialReference object, which represents the
7214 # projection in the given spatial field.
7215 #*
7216 sub SpatialReference {
7217  my $self = shift;
7218  my $d = $self->GetDefn;
7219  my $field = @_ == 2 ? $d->GetGeomFieldIndex(shift // 0) : 0;
7220  my $sr = shift;
7221  my $d2 = $d->_GetGeomFieldDefn($field);
7222  $d2->SpatialReference($sr) if defined $sr;
7223  return $d2->SpatialReference() if defined wantarray;
7224 }
7225 
7226 #** @method StartTransaction()
7227 # Object method.
7228 #*
7229 sub StartTransaction {
7230 }
7231 
7232 #** @method SymDifference(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7233 # Object method.
7234 # The result layer contains features whose geometries represent areas
7235 # that are in either in the input layer or in the method layer but not
7236 # in both. The features in the result layer have attributes from both
7237 # input and method layers. For features which represent areas that are
7238 # only in the input or in the method layer the respective attributes
7239 # have undefined values. The schema of the result layer can be set by
7240 # the user or, if it is empty, is initialized to contain all fields in
7241 # the input and method layers.
7242 # @param method method layer.
7243 # @param result result layer.
7244 # @param options a reference to an options hash.
7245 # @param callback [optional] a reference to a subroutine, which will
7246 # be called with parameters (number progress, string msg, callback_data)
7247 # @param callback_data [optional]
7248 #*
7249 sub SymDifference {
7250 }
7251 
7252 #** @method SyncToDisk()
7253 # Object method.
7254 #*
7255 sub SyncToDisk {
7256 }
7257 
7258 #** @method scalar TestCapability($cap)
7259 # Object method.
7260 # @param cap A capability string.
7261 # @return a boolean value indicating whether the layer has the
7262 # specified capability.
7263 #*
7264 sub TestCapability {
7265  my($self, $cap) = @_;
7266  return _TestCapability($self, $CAPABILITIES{$cap});
7267 }
7268 
7269 #** @method list Tuple(@tuple)
7270 # Object method.
7271 # Get and/set the data of a feature that has the supplied feature id
7272 # (the next feature obtained with GetNextFeature is used if feature id
7273 # is not given). The expected data in the tuple is: ([feature id,]
7274 # non-spatial fields, spatial fields). Calls Geo::OGR::Feature::Tuple.
7275 # @param tuple [optional] feature data
7276 # @note The schema of the tuple needs to be the same as that of the
7277 # layer.
7278 # @return a reference to feature data in an array
7279 #*
7280 sub Tuple {
7281  my $self = shift;
7282  my $FID = shift;
7283  my $feature = defined $FID ? $self->GetFeature($FID) : $self->GetNextFeature;
7284  return unless $feature;
7285  my $set = @_ > 0;
7286  unshift @_, $feature->GetFID if $set;
7287  my @ret;
7288  if (defined wantarray) {
7289  @ret = $feature->Tuple(@_);
7290  } else {
7291  $feature->Tuple(@_);
7292  }
7293  $self->SetFeature($feature) if $set;
7294  return unless defined wantarray;
7295  return @ret;
7296 }
7297 
7298 #** @method Union(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7299 # Object method.
7300 # The result layer contains features whose geometries represent areas
7301 # that are in either in the input layer or in the method layer. The
7302 # schema of the result layer can be set before calling this method, or
7303 # is initialized to contain all fields from this and method layer.
7304 # @param method method layer.
7305 # @param result result layer.
7306 # @param options a reference to an options hash.
7307 # @param callback [optional] a reference to a subroutine, which will
7308 # be called with parameters (number progress, string msg, callback_data)
7309 # @param callback_data [optional]
7310 #*
7311 sub Union {
7312 }
7313 
7314 #** @method Update(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7315 # Object method.
7316 # The result layer contains features whose geometries represent areas
7317 # that are either in the input layer or in the method layer. The
7318 # features in the result layer have areas of the features of the
7319 # method layer or those ares of the features of the input layer that
7320 # are not covered by the method layer. The features of the result
7321 # layer get their attributes from the input layer. The schema of the
7322 # result layer can be set by the user or, if it is empty, is
7323 # initialized to contain all fields in the input layer.
7324 # @param method method layer.
7325 # @param result result layer.
7326 # @param options a reference to an options hash.
7327 # @param callback [optional] a reference to a subroutine, which will
7328 # be called with parameters (number progress, string msg, callback_data)
7329 # @param callback_data [optional]
7330 #*
7331 sub Update {
7332 }
7333 
7334 #** @class Geo::OGR::StyleTable
7335 #*
7336 package Geo::OGR::StyleTable;
7337 
7338 use base qw(Geo::OGR)
7339 
7340 #** @method AddStyle()
7341 #*
7342 sub AddStyle {
7343 }
7344 
7345 #** @method Find()
7346 #*
7347 sub Find {
7348 }
7349 
7350 #** @method GetLastStyleName()
7351 #*
7352 sub GetLastStyleName {
7353 }
7354 
7355 #** @method GetNextStyle()
7356 #*
7357 sub GetNextStyle {
7358 }
7359 
7360 #** @method LoadStyleTable()
7361 #*
7362 sub LoadStyleTable {
7363 }
7364 
7365 #** @method ResetStyleStringReading()
7366 #*
7367 sub ResetStyleStringReading {
7368 }
7369 
7370 #** @method SaveStyleTable()
7371 #*
7372 sub SaveStyleTable {
7373 }
7374 
7375 #** @method new()
7376 #*
7377 sub new {
7378  my $pkg = shift;
7379  my $self = Geo::OGRc::new_StyleTable(@_);
7380  bless $self, $pkg if defined($self);
7381 }
7382 
7383 #** @class Geo::OSR
7384 # @brief Base class for projection related classes.
7385 # @details
7386 #*
7387 package Geo::OSR;
7388 
7389 #** @method list AngularUnits()
7390 # Package subroutine.
7391 # @return list of known angular units.
7392 #*
7393 sub AngularUnits {
7394  return keys %ANGULAR_UNITS;
7395 }
7396 
7397 #** @method CreateCoordinateTransformation()
7398 #*
7399 sub CreateCoordinateTransformation {
7400 }
7401 
7402 #** @method list Datums()
7403 # Package subroutine.
7404 # @return list of known datums.
7405 #*
7406 sub Datums {
7407  return keys %DATUMS;
7408 }
7409 
7410 #** @method list GetProjectionMethodParamInfo($projection, $parameter)
7411 # Package subroutine.
7412 # @param projection one of Geo::OSR::Projections
7413 # @param parameter one of Geo::OSR::Parameters
7414 # @return a list ($user_friendly_name, $type, $default_value).
7415 #*
7416 sub GetProjectionMethodParamInfo {
7417 }
7418 
7419 #** @method list GetProjectionMethodParameterList($projection)
7420 # Package subroutine.
7421 # @param projection one of Geo::OSR::Projections
7422 # @return a list (arrayref parameters, $projection_name).
7423 #*
7424 sub GetProjectionMethodParameterList {
7425 }
7426 
7427 #** @method array reference GetProjectionMethods()
7428 # Package subroutine.
7429 # @deprecated Use Geo::OSR::Projections.
7430 #
7431 # @return reference to an array of possible projection methods.
7432 #*
7433 sub GetProjectionMethods {
7434 }
7435 
7436 #** @method scalar GetUserInputAsWKT($name)
7437 # Package subroutine.
7438 # @param name the user input
7439 # @return a WKT string.
7440 #*
7441 sub GetUserInputAsWKT {
7442 }
7443 
7444 #** @method scalar GetWellKnownGeogCSAsWKT($name)
7445 # Package subroutine.
7446 # @brief Get well known geographic coordinate system as WKT
7447 # @param name a well known name
7448 # @return a WKT string.
7449 #*
7450 sub GetWellKnownGeogCSAsWKT {
7451 }
7452 
7453 #** @method list LinearUnits()
7454 # Package subroutine.
7455 # @return list of known linear units.
7456 #*
7457 sub LinearUnits {
7458  return keys %LINEAR_UNITS;
7459 }
7460 
7461 #** @method OAO_Down()
7462 #*
7463 sub OAO_Down {
7464 }
7465 
7466 #** @method OAO_East()
7467 #*
7468 sub OAO_East {
7469 }
7470 
7471 #** @method OAO_North()
7472 #*
7473 sub OAO_North {
7474 }
7475 
7476 #** @method OAO_Other()
7477 #*
7478 sub OAO_Other {
7479 }
7480 
7481 #** @method OAO_South()
7482 #*
7483 sub OAO_South {
7484 }
7485 
7486 #** @method OAO_Up()
7487 #*
7488 sub OAO_Up {
7489 }
7490 
7491 #** @method OAO_West()
7492 #*
7493 sub OAO_West {
7494 }
7495 
7496 #** @method list Parameters()
7497 # Package subroutine.
7498 # @return list of known projection parameters.
7499 #*
7500 sub Parameters {
7501  return keys %PARAMETERS;
7502 }
7503 
7504 #** @method list Projections()
7505 # Package subroutine.
7506 # @return list of known projections.
7507 #*
7508 sub Projections {
7509  return keys %PROJECTIONS;
7510 }
7511 
7512 #** @method SRS_PM_GREENWICH()
7513 #*
7514 sub SRS_PM_GREENWICH {
7515 }
7516 
7517 #** @method SRS_WGS84_INVFLATTENING()
7518 #*
7519 sub SRS_WGS84_INVFLATTENING {
7520 }
7521 
7522 #** @method SRS_WGS84_SEMIMAJOR()
7523 #*
7524 sub SRS_WGS84_SEMIMAJOR {
7525 }
7526 
7527 #** @method SRS_WKT_WGS84()
7528 #*
7529 sub SRS_WKT_WGS84 {
7530 }
7531 
7532 #** @class Geo::OSR::CoordinateTransformation
7533 # @brief An object for transforming from one projection to another.
7534 # @details
7535 #*
7536 package Geo::OSR::CoordinateTransformation;
7537 
7538 use base qw(Geo::OSR)
7539 
7540 #** @method array reference TransformPoint($x, $y, $z)
7541 # Object method.
7542 # @param x
7543 # @param y
7544 # @param z [optional]
7545 # @return arrayref = [$x, $y, $z]
7546 #*
7547 sub TransformPoint {
7548 }
7549 
7550 #** @method TransformPoints(arrayref points)
7551 # Object method.
7552 # @param points [in/out] a reference to a list of points (line string
7553 # or ring) that is modified in-place. A list of points is: ([x, y, z],
7554 # [x, y, z], ...), where z is optional. Supports also lists of line
7555 # strings and polygons.
7556 #*
7557 sub TransformPoints {
7558  my($self, $points) = @_;
7559  _TransformPoints($self, $points), return unless ref($points->[0]->[0]);
7560  for my $p (@$points) {
7561  TransformPoints($self, $p);
7562  }
7563 }
7564 1;
7565 # This file was automatically generated by SWIG (http://www.swig.org).
7566 # Version 3.0.8
7567 #
7568 # Do not make changes to this file unless you know what you are doing--modify
7569 # the SWIG interface file instead.
7570 }
7571 
7572 #** @method Geo::OSR::CoordinateTransformation new($src, $dst)
7573 # Class method.
7574 # @param src a Geo::OSR::SpatialReference object
7575 # @param dst a Geo::OSR::SpatialReference object
7576 # @return a new Geo::OSR::CoordinateTransformation object
7577 #*
7578 sub new {
7579  my $pkg = shift;
7580  my $self = Geo::OSRc::new_CoordinateTransformation(@_);
7581  bless $self, $pkg if defined($self);
7582 }
7583 
7584 #** @class Geo::OSR::SpatialReference
7585 # @brief A spatial reference system.
7586 # @details <a href="http://www.gdal.org/classOGRSpatialReference.html">Documentation
7587 # of the underlying C++ class at www.gdal.org</a>
7588 #*
7589 package Geo::OSR::SpatialReference;
7590 
7591 use base qw(Geo::OSR)
7592 
7593 #** @method As()
7594 #*
7595 sub As {
7596 }
7597 
7598 #** @method AutoIdentifyEPSG()
7599 # Object method.
7600 # Set EPSG authority info if possible.
7601 #*
7602 sub AutoIdentifyEPSG {
7603 }
7604 
7605 #** @method Geo::OSR::SpatialReference Clone()
7606 # Object method.
7607 # Make a duplicate of this SpatialReference object.
7608 # @return a new Geo::OSR::SpatialReference object
7609 #*
7610 sub Clone {
7611 }
7612 
7613 #** @method Geo::OSR::SpatialReference CloneGeogCS()
7614 # Object method.
7615 # Make a duplicate of the GEOGCS node of this SpatialReference object.
7616 # @return a new Geo::OSR::SpatialReference object
7617 #*
7618 sub CloneGeogCS {
7619 }
7620 
7621 #** @method ConvertToOtherProjection()
7622 #*
7623 sub ConvertToOtherProjection {
7624 }
7625 
7626 #** @method CopyGeogCSFrom($rhs)
7627 # Object method.
7628 # @param rhs Geo::OSR::SpatialReference
7629 #*
7630 sub CopyGeogCSFrom {
7631 }
7632 
7633 #** @method EPSGTreatsAsLatLong()
7634 # Object method.
7635 # Returns TRUE if EPSG feels this geographic coordinate system should be treated as having lat/long coordinate ordering.
7636 #*
7637 sub EPSGTreatsAsLatLong {
7638 }
7639 
7640 #** @method EPSGTreatsAsNorthingEasting()
7641 #*
7642 sub EPSGTreatsAsNorthingEasting {
7643 }
7644 
7645 #** @method Export($format)
7646 # Object method.
7647 # Export the spatial reference to a selected format.
7648 # @note a.k.a. As
7649 #
7650 # @param format One of the following. The return value is explained
7651 # after the format. Other arguments are explained in parenthesis.
7652 # - WKT (Text): Well Known Text string
7653 # - PrettyWKT: Well Known Text string nicely formatted (simplify)
7654 # - Proj4: PROJ.4 string
7655 # - PCI: a list: ($proj_string, $units, [$parms1, ...])
7656 # - USGS: a list: ($code, $zone, [$parms1, ...], $datum)
7657 # - GML (XML): GML based string (dialect)
7658 # - MapInfoCS (MICoordSys): MapInfo style co-ordinate system definition
7659 #
7660 # @note The named parameter syntax also works and is needed is those
7661 # cases when other arguments need or may be given. The format should
7662 # be given using key as, 'to' or 'format'.
7663 #
7664 # @note ExportTo* and AsText methods also exist but are not documented here.
7665 #
7666 # @return a scalar or a list depending on the export format
7667 #*
7668 sub Export {
7669  my $self = shift;
7670  my $format;
7671  $format = pop if @_ == 1;
7672  my %params = @_;
7673  $format //= $params{to} //= $params{format} //= $params{as} //= '';
7674  my $simplify = $params{simplify} // 0;
7675  my $dialect = $params{dialect} // '';
7676  my %converters = (
7677  WKT => sub { return ExportToWkt($self) },
7678  Text => sub { return ExportToWkt($self) },
7679  PrettyWKT => sub { return ExportToPrettyWkt($self, $simplify) },
7680  Proj4 => sub { return ExportToProj4($self) },
7681  PCI => sub { return ExportToPCI($self) },
7682  USGS => sub { return ExportToUSGS($self) },
7683  GML => sub { return ExportToXML($self, $dialect) },
7684  XML => sub { return ExportToXML($self, $dialect) },
7685  MICoordSys => sub { return ExportToMICoordSys() },
7686  MapInfoCS => sub { return ExportToMICoordSys() },
7687  );
7688  error(1, $format, \%converters) unless $converters{$format};
7689  return $converters{$format}->();
7690 }
7691 
7692 #** @method Fixup()
7693 # Object method.
7694 #*
7695 sub Fixup {
7696 }
7697 
7698 #** @method FixupOrdering()
7699 # Object method.
7700 #*
7701 sub FixupOrdering {
7702 }
7703 
7704 #** @method scalar GetAngularUnits()
7705 # Object method.
7706 # @return a number
7707 #*
7708 sub GetAngularUnits {
7709 }
7710 
7711 #** @method GetAngularUnitsName()
7712 #*
7713 sub GetAngularUnitsName {
7714 }
7715 
7716 #** @method scalar GetAttrValue($name, $child = 0)
7717 # Object method.
7718 # @param name
7719 # @param child
7720 # @return string
7721 #*
7722 sub GetAttrValue {
7723 }
7724 
7725 #** @method scalar GetAuthorityCode($target_key)
7726 # Object method.
7727 # @param target_key
7728 # @return string
7729 #*
7730 sub GetAuthorityCode {
7731 }
7732 
7733 #** @method scalar GetAuthorityName($target_key)
7734 # Object method.
7735 # @param target_key
7736 # @return string
7737 #*
7738 sub GetAuthorityName {
7739 }
7740 
7741 #** @method GetAxisName()
7742 #*
7743 sub GetAxisName {
7744 }
7745 
7746 #** @method GetAxisOrientation()
7747 #*
7748 sub GetAxisOrientation {
7749 }
7750 
7751 #** @method GetInvFlattening()
7752 # Object method.
7753 #*
7754 sub GetInvFlattening {
7755 }
7756 
7757 #** @method scalar GetLinearUnits()
7758 # Object method.
7759 # @return a number
7760 #*
7761 sub GetLinearUnits {
7762 }
7763 
7764 #** @method scalar GetLinearUnitsName()
7765 # Object method.
7766 # @return string
7767 #*
7768 sub GetLinearUnitsName {
7769 }
7770 
7771 #** @method scalar GetNormProjParm($name, $default_val = 0.0)
7772 # Object method.
7773 # @param name
7774 # @param default_val
7775 # @return a number
7776 #*
7777 sub GetNormProjParm {
7778 }
7779 
7780 #** @method scalar GetProjParm($name, $default_val = 0.0)
7781 # Object method.
7782 # @param name
7783 # @param default_val
7784 # @return a number
7785 #*
7786 sub GetProjParm {
7787 }
7788 
7789 #** @method GetSemiMajor()
7790 # Object method.
7791 #*
7792 sub GetSemiMajor {
7793 }
7794 
7795 #** @method GetSemiMinor()
7796 # Object method.
7797 #*
7798 sub GetSemiMinor {
7799 }
7800 
7801 #** @method GetTOWGS84()
7802 # Object method.
7803 # @return array = ($p1, $p2, $p3, $p4, $p5, $p6, $p7)
7804 #*
7805 sub GetTOWGS84 {
7806 }
7807 
7808 #** @method GetTargetLinearUnits()
7809 #*
7810 sub GetTargetLinearUnits {
7811 }
7812 
7813 #** @method GetUTMZone()
7814 # Object method.
7815 # Get UTM zone information.
7816 # @return The UTM zone (integer). In scalar context the returned value
7817 # is negative for southern hemisphere zones. In list context returns
7818 # two values ($zone, $north), where $zone is always non-negative and
7819 # $north is true or false.
7820 #*
7821 sub GetUTMZone {
7822  my $self = shift;
7823  my $zone = _GetUTMZone($self);
7824  if (wantarray) {
7825  my $north = 1;
7826  if ($zone < 0) {
7827  $zone *= -1;
7828  $north = 0;
7829  }
7830  return ($zone, $north);
7831  } else {
7832  return $zone;
7833  }
7834 }
7835 
7836 #** @method ImportFromOzi()
7837 #*
7838 sub ImportFromOzi {
7839 }
7840 
7841 #** @method scalar IsCompound()
7842 # Object method.
7843 # @return boolean
7844 #*
7845 sub IsCompound {
7846 }
7847 
7848 #** @method scalar IsGeocentric()
7849 # Object method.
7850 # @return boolean
7851 #*
7852 sub IsGeocentric {
7853 }
7854 
7855 #** @method scalar IsGeographic()
7856 # Object method.
7857 # @return boolean
7858 #*
7859 sub IsGeographic {
7860 }
7861 
7862 #** @method scalar IsLocal()
7863 # Object method.
7864 # @return boolean
7865 #*
7866 sub IsLocal {
7867 }
7868 
7869 #** @method scalar IsProjected()
7870 # Object method.
7871 # @return boolean
7872 #*
7873 sub IsProjected {
7874 }
7875 
7876 #** @method scalar IsSame($rs)
7877 # Object method.
7878 # @param rs a Geo::OSR::SpatialReference object
7879 # @return boolean
7880 #*
7881 sub IsSame {
7882 }
7883 
7884 #** @method scalar IsSameGeogCS($rs)
7885 # Object method.
7886 # @param rs a Geo::OSR::SpatialReference object
7887 # @return boolean
7888 #*
7889 sub IsSameGeogCS {
7890 }
7891 
7892 #** @method scalar IsSameVertCS($rs)
7893 # Object method.
7894 # @param rs a Geo::OSR::SpatialReference object
7895 # @return boolean
7896 #*
7897 sub IsSameVertCS {
7898 }
7899 
7900 #** @method scalar IsVertical()
7901 # Object method.
7902 # @return boolean
7903 #*
7904 sub IsVertical {
7905 }
7906 
7907 #** @method MorphFromESRI()
7908 # Object method.
7909 #*
7910 sub MorphFromESRI {
7911 }
7912 
7913 #** @method MorphToESRI()
7914 # Object method.
7915 #*
7916 sub MorphToESRI {
7917 }
7918 
7919 #** @method Set(%params)
7920 # Object method.
7921 # Set a parameter or parameters in the spatial reference object.
7922 # @param params Named parameters. Recognized keys and respective
7923 # values are the following.
7924 # - Authority: authority name (give also TargetKey, Node and Code)
7925 # - TargetKey:
7926 # - Node: partial or complete path to the target node (Node and Value together sets an attribute value)
7927 # - Code: code for value with an authority
7928 # - Value: value to be assigned to a node, a projection parameter or an object
7929 # - AngularUnits: angular units for the geographic coordinate system (give also Value) (one of Geo::OSR::LinearUnits)
7930 # - LinearUnits: linear units for the target node or the object (give also Value and optionally Node) (one of Geo::OSR::LinearUnits)
7931 # - Parameter: projection parameter to set (give also Value and Normalized) (one of Geo::OSR::Parameters)
7932 # - Normalized: set to true to indicate that the Value argument is in "normalized" form
7933 # - Name: a well known name of a geographic coordinate system (e.g. WGS84)
7934 # - GuessFrom: arbitrary text that specifies a projection ("user input")
7935 # - LOCAL_CS: name of a local coordinate system
7936 # - GeocentricCS: name of a geocentric coordinate system
7937 # - VerticalCS: name of a vertical coordinate system (give also Datum and optionally VertDatumType [default is 2005])
7938 # - Datum: a known (OGC or EPSG) name (or(?) one of Geo::OSR::Datums)
7939 # - 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
7940 # - Parameters: a reference to a list containing the coordinate system or projection parameters
7941 # - Zone: zone for setting up UTM or State Plane coordinate systems (State Plane zone in USGS numbering scheme)
7942 # - North: set false for southern hemisphere
7943 # - NAD83: set false if the NAD27 zone definition should be used instead of NAD83
7944 # - UnitName: to override the legal definition for a zone
7945 # - UnitConversionFactor: to override the legal definition for a zone
7946 # - Spheroid: user visible name
7947 # - HorizontalCS: Horizontal coordinate system name
7948 # - Projection: name of a projection, one of Geo::OSR::Projections (give also optionally Parameters and Variant)
7949 #
7950 # @note Numerous Set* methods also exist but are not documented here.
7951 #*
7952 sub Set {
7953  my($self, %params) = @_;
7954  if (exists $params{Authority} and exists $params{TargetKey} and exists $params{Node} and exists $params{Code}) {
7955  SetAuthority($self, $params{TargetKey}, $params{Authority}, $params{Code});
7956  } elsif (exists $params{Node} and exists $params{Value}) {
7957  SetAttrValue($self, $params{Node}, $params{Value});
7958  } elsif (exists $params{AngularUnits} and exists $params{Value}) {
7959  SetAngularUnits($self, $params{AngularUnits}, $params{Value});
7960  } elsif (exists $params{LinearUnits} and exists $params{Node} and exists $params{Value}) {
7961  SetTargetLinearUnits($self, $params{Node}, $params{LinearUnits}, $params{Value});
7962  } elsif (exists $params{LinearUnits} and exists $params{Value}) {
7963  SetLinearUnitsAndUpdateParameters($self, $params{LinearUnits}, $params{Value});
7964  } elsif ($params{Parameter} and exists $params{Value}) {
7965  error(1, $params{Parameter}, \%Geo::OSR::PARAMETERS) unless exists $Geo::OSR::PARAMETERS{$params{Parameter}};
7966  $params{Normalized} ?
7967  SetNormProjParm($self, $params{Parameter}, $params{Value}) :
7968  SetProjParm($self, $params{Parameter}, $params{Value});
7969  } elsif (exists $params{Name}) {
7970  SetWellKnownGeogCS($self, $params{Name});
7971  } elsif (exists $params{GuessFrom}) {
7972  SetFromUserInput($self, $params{GuessFrom});
7973  } elsif (exists $params{LOCAL_CS}) {
7974  SetLocalCS($self, $params{LOCAL_CS});
7975  } elsif (exists $params{GeocentricCS}) {
7976  SetGeocCS($self, $params{GeocentricCS});
7977  } elsif (exists $params{VerticalCS} and $params{Datum}) {
7978  my $type = $params{VertDatumType} || 2005;
7979  SetVertCS($self, $params{VerticalCS}, $params{Datum}, $type);
7980  } elsif (exists $params{CoordinateSystem}) {
7981  my @parameters = ();
7982  @parameters = @{$params{Parameters}} if ref($params{Parameters});
7983  if ($params{CoordinateSystem} eq 'State Plane' and exists $params{Zone}) {
7984  my $NAD83 = exists $params{NAD83} ? $params{NAD83} : 1;
7985  my $name = exists $params{UnitName} ? $params{UnitName} : undef;
7986  my $c = exists $params{UnitConversionFactor} ? $params{UnitConversionFactor} : 0.0;
7987  SetStatePlane($self, $params{Zone}, $NAD83, $name, $c);
7988  } elsif ($params{CoordinateSystem} eq 'UTM' and exists $params{Zone} and exists $params{North}) {
7989  my $north = exists $params{North} ? $params{North} : 1;
7990  SetUTM($self, $params{Zone}, $north);
7991  } elsif ($params{CoordinateSystem} eq 'WGS') {
7992  SetTOWGS84($self, @parameters);
7993  } elsif ($params{CoordinateSystem} and $params{Datum} and $params{Spheroid}) {
7994  SetGeogCS($self, $params{CoordinateSystem}, $params{Datum}, $params{Spheroid}, @parameters);
7995  } elsif ($params{CoordinateSystem} and $params{HorizontalCS} and $params{VerticalCS}) {
7996  SetCompoundCS($self, $params{CoordinateSystem}, $params{HorizontalCS}, $params{VerticalCS});
7997  } else {
7998  SetProjCS($self, $params{CoordinateSystem});
7999  }
8000  } elsif (exists $params{Projection}) {
8001  error(1, $params{Projection}, \%Geo::OSR::PROJECTIONS) unless exists $Geo::OSR::PROJECTIONS{$params{Projection}};
8002  my @parameters = ();
8003  @parameters = @{$params{Parameters}} if ref($params{Parameters});
8004  if ($params{Projection} eq 'Albers_Conic_Equal_Area') {
8005  SetACEA($self, @parameters);
8006  } elsif ($params{Projection} eq 'Azimuthal_Equidistant') {
8007  SetAE($self, @parameters);
8008  } elsif ($params{Projection} eq 'Bonne') {
8009  SetBonne($self, @parameters);
8010  } elsif ($params{Projection} eq 'Cylindrical_Equal_Area') {
8011  SetCEA($self, @parameters);
8012  } elsif ($params{Projection} eq 'Cassini_Soldner') {
8013  SetCS($self, @parameters);
8014  } elsif ($params{Projection} eq 'Equidistant_Conic') {
8015  SetEC($self, @parameters);
8016  # Eckert_I, Eckert_II, Eckert_III, Eckert_V ?
8017  } elsif ($params{Projection} eq 'Eckert_IV') {
8018  SetEckertIV($self, @parameters);
8019  } elsif ($params{Projection} eq 'Eckert_VI') {
8020  SetEckertVI($self, @parameters);
8021  } elsif ($params{Projection} eq 'Equirectangular') {
8022  @parameters == 4 ?
8023  SetEquirectangular($self, @parameters) :
8024  SetEquirectangular2($self, @parameters);
8025  } elsif ($params{Projection} eq 'Gauss_Schreiber_Transverse_Mercator') {
8026  SetGaussSchreiberTMercator($self, @parameters);
8027  } elsif ($params{Projection} eq 'Gall_Stereographic') {
8028  SetGS($self, @parameters);
8029  } elsif ($params{Projection} eq 'Goode_Homolosine') {
8030  SetGH($self, @parameters);
8031  } elsif ($params{Projection} eq 'Interrupted_Goode_Homolosine') {
8032  SetIGH($self);
8033  } elsif ($params{Projection} eq 'Geostationary_Satellite') {
8034  SetGEOS($self, @parameters);
8035  } elsif ($params{Projection} eq 'Gnomonic') {
8036  SetGnomonic($self, @parameters);
8037  } elsif ($params{Projection} eq 'Hotine_Oblique_Mercator') {
8038  # Hotine_Oblique_Mercator_Azimuth_Center ?
8039  SetHOM($self, @parameters);
8040  } elsif ($params{Projection} eq 'Hotine_Oblique_Mercator_Two_Point_Natural_Origin') {
8041  SetHOM2PNO($self, @parameters);
8042  } elsif ($params{Projection} eq 'Krovak') {
8043  SetKrovak($self, @parameters);
8044  } elsif ($params{Projection} eq 'Lambert_Azimuthal_Equal_Area') {
8045  SetLAEA($self, @parameters);
8046  } elsif ($params{Projection} eq 'Lambert_Conformal_Conic_2SP') {
8047  SetLCC($self, @parameters);
8048  } elsif ($params{Projection} eq 'Lambert_Conformal_Conic_1SP') {
8049  SetLCC1SP($self, @parameters);
8050  } elsif ($params{Projection} eq 'Lambert_Conformal_Conic_2SP_Belgium') {
8051  SetLCCB($self, @parameters);
8052  } elsif ($params{Projection} eq 'miller_cylindrical') {
8053  SetMC($self, @parameters);
8054  } elsif ($params{Projection} =~ /^Mercator/) {
8055  # Mercator_1SP, Mercator_2SP, Mercator_Auxiliary_Sphere ?
8056  # variant is in Variant (or Name)
8057  SetMercator($self, @parameters);
8058  } elsif ($params{Projection} eq 'Mollweide') {
8059  SetMollweide($self, @parameters);
8060  } elsif ($params{Projection} eq 'New_Zealand_Map_Grid') {
8061  SetNZMG($self, @parameters);
8062  } elsif ($params{Projection} eq 'Oblique_Stereographic') {
8063  SetOS($self, @parameters);
8064  } elsif ($params{Projection} eq 'Orthographic') {
8065  SetOrthographic($self, @parameters);
8066  } elsif ($params{Projection} eq 'Polyconic') {
8067  SetPolyconic($self, @parameters);
8068  } elsif ($params{Projection} eq 'Polar_Stereographic') {
8069  SetPS($self, @parameters);
8070  } elsif ($params{Projection} eq 'Robinson') {
8071  SetRobinson($self, @parameters);
8072  } elsif ($params{Projection} eq 'Sinusoidal') {
8073  SetSinusoidal($self, @parameters);
8074  } elsif ($params{Projection} eq 'Stereographic') {
8075  SetStereographic($self, @parameters);
8076  } elsif ($params{Projection} eq 'Swiss_Oblique_Cylindrical') {
8077  SetSOC($self, @parameters);
8078  } elsif ($params{Projection} eq 'Transverse_Mercator_South_Orientated') {
8079  SetTMSO($self, @parameters);
8080  } elsif ($params{Projection} =~ /^Transverse_Mercator/) {
8081  my($variant) = $params{Projection} =~ /^Transverse_Mercator_(\w+)/;
8082  $variant //= $params{Variant} //= $params{Name};
8083  $variant ?
8084  SetTMVariant($self, $variant, @parameters) :
8085  SetTM($self, @parameters);
8086  } elsif ($params{Projection} eq 'Tunisia_Mining_Grid') {
8087  SetTMG($self, @parameters);
8088  } elsif ($params{Projection} eq 'VanDerGrinten') {
8089  SetVDG($self, @parameters);
8090  } else {
8091  # Aitoff, Craster_Parabolic, International_Map_of_the_World_Polyconic, Laborde_Oblique_Mercator
8092  # Loximuthal, Miller_Cylindrical, Quadrilateralized_Spherical_Cube, Quartic_Authalic, Two_Point_Equidistant
8093  # Wagner_I, Wagner_II, Wagner_III, Wagner_IV, Wagner_V, Wagner_VI, Wagner_VII
8094  # Winkel_I, Winkel_II, Winkel_Tripel
8095  # ?
8096  SetProjection($self, $params{Projection});
8097  }
8098  } else {
8099  error("Not enough information to create a spatial reference object.");
8100  }
8101 }
8102 
8103 #** @method SetMercator2SP()
8104 #*
8105 sub SetMercator2SP {
8106 }
8107 
8108 #** @method StripCTParms()
8109 # Object method.
8110 #*
8111 sub StripCTParms {
8112 }
8113 
8114 #** @method Validate()
8115 # Object method.
8116 #*
8117 sub Validate {
8118 }
8119 
8120 #** @method Geo::OSR::SpatialReference new(%params)
8121 # Class method.
8122 # Create a new spatial reference object using a named parameter. This
8123 # constructor recognizes the following key words (alternative in
8124 # parenthesis): WKT (Text), Proj4, ESRI, EPSG, EPSGA, PCI, USGS, GML
8125 # (XML), URL, ERMapper (ERM), MapInfoCS (MICoordSys). The value
8126 # depends on the key.
8127 # - WKT: Well Known Text string
8128 # - Proj4: PROJ.4 string
8129 # - ESRI: reference to a list of strings (contents of ESRI .prj file)
8130 # - EPSG: EPSG code number
8131 # - EPSGA: EPSG code number (the resulting CS will have EPSG preferred axis ordering)
8132 # - PCI: listref: [PCI_projection_string, Grid_units_code, [17 cs parameters]]
8133 # - USGS: listref: [Projection_system_code, Zone, [15 cs parameters], Datum_code, Format_flag]
8134 # - GML: GML string
8135 # - URL: URL for downloading the spatial reference from
8136 # - ERMapper: listref: [Projection, Datum, Units]
8137 # - MapInfoCS: MapInfo style co-ordinate system definition
8138 #
8139 # For more information, consult the import methods in <a href="http://www.gdal.org/classOGRSpatialReference.html">OGR documentation</a>.
8140 #
8141 # @note ImportFrom* methods also exist but are not documented here.
8142 #
8143 # Usage:
8144 # \code
8145 # $sr = Geo::OSR::SpatialReference->new( key => value );
8146 # \endcode
8147 # @return a new Geo::OSR::SpatialReference object
8148 #*
8149 sub new {
8150  my $pkg = shift;
8151  my %param = @_;
8152  my $self = Geo::OSRc::new_SpatialReference();
8153  if (exists $param{WKT}) {
8154  ImportFromWkt($self, $param{WKT});
8155  } elsif (exists $param{Text}) {
8156  ImportFromWkt($self, $param{Text});
8157  } elsif (exists $param{Proj4}) {
8158  ImportFromProj4($self, $param{Proj4});
8159  } elsif (exists $param{ESRI}) {
8160  ImportFromESRI($self, @{$param{ESRI}});
8161  } elsif (exists $param{EPSG}) {
8162  ImportFromEPSG($self, $param{EPSG});
8163  } elsif (exists $param{EPSGA}) {
8164  ImportFromEPSGA($self, $param{EPSGA});
8165  } elsif (exists $param{PCI}) {
8166  ImportFromPCI($self, @{$param{PCI}});
8167  } elsif (exists $param{USGS}) {
8168  ImportFromUSGS($self, @{$param{USGS}});
8169  } elsif (exists $param{XML}) {
8170  ImportFromXML($self, $param{XML});
8171  } elsif (exists $param{GML}) {
8172  ImportFromGML($self, $param{GML});
8173  } elsif (exists $param{URL}) {
8174  ImportFromUrl($self, $param{URL});
8175  } elsif (exists $param{ERMapper}) {
8176  ImportFromERM($self, @{$param{ERMapper}});
8177  } elsif (exists $param{ERM}) {
8178  ImportFromERM($self, @{$param{ERM}});
8179  } elsif (exists $param{MICoordSys}) {
8180  ImportFromMICoordSys($self, $param{MICoordSys});
8181  } elsif (exists $param{MapInfoCS}) {
8182  ImportFromMICoordSys($self, $param{MapInfoCS});
8183  } elsif (exists $param{WGS}) {
8184  eval {
8185  SetWellKnownGeogCS($self, 'WGS'.$param{WGS});
8186  };
8187  confess last_error() if $@;
8188  } else {
8189  error("Unrecognized/missing parameters: @_.");
8190  }
8191  bless $self, $pkg if defined $self;
8192 }
8193