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