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