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, and NearestNeighbour.
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, and Q3.
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;
1019 }
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);
1057 }
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});
1202 }
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 #*
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)
1794 
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 AdviseRead()
1913 #*
1914 sub AdviseRead {
1915 }
1916 
1917 #** @method Geo::GDAL::Band Band($index)
1918 # Object method.
1919 # Create a band object for the band within the dataset.
1920 # @note a.k.a. GetRasterBand
1921 # @param index 1...RasterCount, default is 1.
1922 # @return a new Geo::GDAL::Band object
1923 #*
1924 sub Band {
1925 }
1926 
1927 #** @method list Bands()
1928 # Object method.
1929 # @return a list of new Geo::GDAL::Band objects
1930 #*
1931 sub Bands {
1932  my $self = shift;
1933  my @bands;
1934  for my $i (1..$self->{RasterCount}) {
1935  push @bands, GetRasterBand($self, $i);
1936  }
1937  return @bands;
1938 }
1939 
1940 #** @method BuildOverviews($resampling, arrayref overviews, coderef progress, $progress_data)
1941 # Object method.
1942 # @param resampling the resampling method, one of Geo::GDAL::RIOResamplingTypes.
1943 # @param overviews The list of overview decimation factors to
1944 # build. For example [2,4,8].
1945 # @param progress [optional] a reference to a subroutine, which will
1946 # be called with parameters (number progress, string msg, progress_data)
1947 # @param progress_data [optional]
1948 #*
1949 sub BuildOverviews {
1950  my $self = shift;
1951  my @p = @_;
1952  $p[0] = uc($p[0]) if $p[0];
1953  eval {
1954  $self->_BuildOverviews(@p);
1955  };
1956  confess(last_error()) if $@;
1957 }
1958 
1959 #** @method Geo::GDAL::Dataset BuildVRT($Dest, arrayref Sources, hashref Options, coderef progress, $progress_data)
1960 # Object method.
1961 # Build a virtual dataset from a set of datasets.
1962 # @param Dest Destination raster dataset definition string (typically
1963 # filename), or an object, which implements write and close.
1964 # @param Sources A list of filenames of input datasets or a list of
1965 # dataset objects.
1966 # @param Options See section \ref index_processing_options.
1967 # @return Dataset object
1968 #
1969 # @note This subroutine is imported into the main namespace if Geo::GDAL
1970 # is use'd with qw/:all/.
1971 #*
1972 sub BuildVRT {
1973  my ($dest, $sources, $options, $progress, $progress_data) = @_;
1974  $options = Geo::GDAL::GDALBuildVRTOptions->new(make_processing_options($options));
1975  error("Usage: Geo::GDAL::DataSet::BuildVRT(\$vrt_file_name, \\\@sources)")
1976  unless ref $sources eq 'ARRAY' && defined $sources->[0];
1977  unless (blessed($dest)) {
1978  if (blessed($sources->[0])) {
1979  return Geo::GDAL::wrapper_GDALBuildVRT_objects($dest, $sources, $options, $progress, $progress_data);
1980  } else {
1981  return Geo::GDAL::wrapper_GDALBuildVRT_names($dest, $sources, $options, $progress, $progress_data);
1982  }
1983  } else {
1984  if (blessed($sources->[0])) {
1985  return stdout_redirection_wrapper(
1986  $sources, $dest,
1987  \&Geo::GDAL::wrapper_GDALBuildVRT_objects,
1988  $options, $progress, $progress_data);
1989  } else {
1990  return stdout_redirection_wrapper(
1991  $sources, $dest,
1992  \&Geo::GDAL::wrapper_GDALBuildVRT_names,
1993  $options, $progress, $progress_data);
1994  }
1995  }
1996 }
1997 
1998 #** @method ClearStatistics()
1999 #*
2000 sub ClearStatistics {
2001 }
2002 
2003 #** @method CommitTransaction()
2004 #*
2005 sub CommitTransaction {
2006 }
2007 
2008 #** @method Geo::GDAL::ColorTable ComputeColorTable(%params)
2009 # Object method.
2010 # Compute a color table from an RGB image
2011 # @param params Named parameters:
2012 # - \a Red The red band, the default is to use the red band of this dataset.
2013 # - \a Green The green band, the default is to use the green band of this dataset.
2014 # - \a Blue The blue band, the default is to use the blue band of this dataset.
2015 # - \a NumColors The number of colors in the computed color table. Default is 256.
2016 # - \a Progress reference to a progress function (default is undef)
2017 # - \a ProgressData (default is undef)
2018 # - \a Method The computation method. The default and currently only option is the median cut algorithm.
2019 #
2020 # @return a new color table object.
2021 #*
2022 sub ComputeColorTable {
2023  my $self = shift;
2024  my $p = named_parameters(\@_,
2025  Red => undef,
2026  Green => undef,
2027  Blue => undef,
2028  NumColors => 256,
2029  Progress => undef,
2030  ProgressData => undef,
2031  Method => 'MedianCut');
2032  for my $b ($self->Bands) {
2033  for my $cion ($b->ColorInterpretation) {
2034  if ($cion eq 'RedBand') { $p->{red} //= $b; last; }
2035  if ($cion eq 'GreenBand') { $p->{green} //= $b; last; }
2036  if ($cion eq 'BlueBand') { $p->{blue} //= $b; last; }
2037  }
2038  }
2039  my $ct = Geo::GDAL::ColorTable->new;
2040  Geo::GDAL::ComputeMedianCutPCT($p->{red},
2041  $p->{green},
2042  $p->{blue},
2043  $p->{numcolors},
2044  $ct, $p->{progress},
2045  $p->{progressdata});
2046  return $ct;
2047 }
2048 
2049 #** @method Geo::OGR::Layer CopyLayer($layer, $name, hashref options = undef)
2050 # Object method.
2051 # @param layer A Geo::OGR::Layer object to be copied.
2052 # @param name A name for the new layer.
2053 # @param options A ref to a hash of format specific options.
2054 # @return a new Geo::OGR::Layer object.
2055 #*
2056 sub CopyLayer {
2057 }
2058 
2059 #** @method Geo::OGR::Layer CreateLayer(%params)
2060 # Object method.
2061 # @brief Create a new vector layer into this dataset.
2062 #
2063 # @param %params Named parameters:
2064 # - \a Name (scalar) name for the new layer.
2065 # - \a Fields (array reference) a list of (scalar and geometry) field definitions as in
2066 # Geo::OGR::Layer::CreateField.
2067 # - \a ApproxOK (boolean value, default is true) a flag, which is forwarded to Geo::OGR::Layer::CreateField.
2068 # - \a Options (hash reference) driver specific hash of layer creation options.
2069 # - \a Schema (hash reference, deprecated, use \a Fields and \a Name) may contain keys Name, Fields, GeomFields, GeometryType.
2070 # - \a SRS (scalar) the spatial reference for the default geometry field.
2071 # - \a GeometryType (scalar) the type of the default geometry field
2072 # (if only one geometry field). Default is 'Unknown'.
2073 #
2074 # @note If Fields or Schema|Fields is not given, a default geometry
2075 # field (Name => '', GeometryType => 'Unknown') is created. If it is
2076 # given and it contains spatial fields, both GeometryType and SRS are
2077 # ignored. The type can be also set with the named parameter.
2078 #
2079 # Example:
2080 # \code
2081 # my $roads = Geo::OGR::Driver('Memory')->Create('road')->
2082 # CreateLayer(
2083 # Fields => [ { Name => 'class',
2084 # Type => 'Integer' },
2085 # { Name => 'geom',
2086 # Type => 'LineString25D' } ] );
2087 # \endcode
2088 #
2089 # @note Many formats allow only one spatial field, which currently
2090 # requires the use of GeometryType.
2091 #
2092 # @return a new Geo::OGR::Layer object.
2093 #*
2094 sub CreateLayer {
2095  my $self = shift;
2096  my $p = named_parameters(\@_,
2097  Name => 'unnamed',
2098  SRS => undef,
2099  GeometryType => 'Unknown',
2100  Options => {},
2101  Schema => undef,
2102  Fields => undef,
2103  ApproxOK => 1);
2104  error("The 'Fields' argument must be an array reference.") if $p->{fields} && ref($p->{fields}) ne 'ARRAY';
2105  if (defined $p->{schema}) {
2106  my $s = $p->{schema};
2107  $p->{geometrytype} = $s->{GeometryType} if exists $s->{GeometryType};
2108  $p->{fields} = $s->{Fields} if exists $s->{Fields};
2109  $p->{name} = $s->{Name} if exists $s->{Name};
2110  }
2111  $p->{fields} = [] unless ref($p->{fields}) eq 'ARRAY';
2112  # if fields contains spatial fields, then do not create default one
2113  for my $f (@{$p->{fields}}) {
2114  error("Field definitions must be hash references.") unless ref $f eq 'HASH';
2115  if ($f->{GeometryType} || ($f->{Type} && s_exists(geometry_type => $f->{Type}))) {
2116  $p->{geometrytype} = 'None';
2117  last;
2118  }
2119  }
2120  my $gt = s2i(geometry_type => $p->{geometrytype});
2121  my $layer = _CreateLayer($self, $p->{name}, $p->{srs}, $gt, $p->{options});
2122  for my $f (@{$p->{fields}}) {
2123  $layer->CreateField($f);
2124  }
2125  keep($layer, $self);
2126 }
2127 
2128 #** @method CreateMaskBand()
2129 # Object method.
2130 # Add a mask band to the dataset.
2131 #*
2132 sub CreateMaskBand {
2133  return _CreateMaskBand(@_);
2134 }
2135 
2136 #** @method Geo::GDAL::Dataset DEMProcessing($Dest, $Processing, $ColorFilename, hashref Options, coderef progress, $progress_data)
2137 # Object method.
2138 # Apply a DEM processing to this dataset.
2139 # @param Dest Destination raster dataset definition string (typically filename) or an object, which implements write and close.
2140 # @param Processing Processing to apply, one of "hillshade", "slope", "aspect", "color-relief", "TRI", "TPI", or "Roughness".
2141 # @param ColorFilename The color palette for color-relief.
2142 # @param Options See section \ref index_processing_options.
2143 # @param progress [optional] A reference to a subroutine, which will
2144 # be called with parameters (number progress, string msg, progress_data).
2145 # @param progress_data [optional]
2146 #
2147 #*
2148 sub DEMProcessing {
2149  my ($self, $dest, $Processing, $ColorFilename, $options, $progress, $progress_data) = @_;
2150  $options = Geo::GDAL::GDALDEMProcessingOptions->new(make_processing_options($options));
2151  return $self->stdout_redirection_wrapper(
2152  $dest,
2153  \&Geo::GDAL::wrapper_GDALDEMProcessing,
2154  $Processing, $ColorFilename, $options, $progress, $progress_data
2155  );
2156 }
2157 
2158 #** @method Dataset()
2159 #*
2160 sub Dataset {
2161  my $self = shift;
2162  parent($self);
2163 }
2164 
2165 #** @method DeleteLayer($name)
2166 # Object method.
2167 # Deletes a layer from the data source. Note that if there is a layer
2168 # object for the deleted layer, it becomes unusable.
2169 # @param name name of the layer to delete.
2170 #*
2171 sub DeleteLayer {
2172  my ($self, $name) = @_;
2173  my $index;
2174  for my $i (0..$self->GetLayerCount-1) {
2175  my $layer = GetLayerByIndex($self, $i);
2176  $index = $i, last if $layer->GetName eq $name;
2177  }
2178  error(2, $name, 'Layer') unless defined $index;
2179  _DeleteLayer($self, $index);
2180 }
2181 
2182 #** @method Geo::GDAL::Band Dither(%params)
2183 # Object method.
2184 # Compute one band with color table image from an RGB image
2185 # @params params Named parameters:
2186 # - \a Red The red band, the default is to use the red band of this dataset.
2187 # - \a Green The green band, the default is to use the green band of this dataset.
2188 # - \a Blue The blue band, the default is to use the blue band of this dataset.
2189 # - \a Dest The destination band. If this is not defined, a new in-memory band (and a dataset) will be created.
2190 # - \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.
2191 # - \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.
2192 # - \a ProgressData (default is undef)
2193 #
2194 # @return the destination band.
2195 #
2196 # Usage example. This code converts an RGB JPEG image into a one band PNG image with a color table.
2197 # \code
2198 # my $d = Geo::GDAL::Open('pic.jpg');
2199 # Geo::GDAL::Driver('PNG')->Copy(Name => 'test.png', Src => $d->Dither->Dataset);
2200 # \endcode
2201 #*
2202 sub Dither {
2203  my $self = shift;
2204  my $p = named_parameters(\@_,
2205  Red => undef,
2206  Green => undef,
2207  Blue => undef,
2208  Dest => undef,
2209  ColorTable => undef,
2210  Progress => undef,
2211  ProgressData => undef);
2212  for my $b ($self->Bands) {
2213  for my $cion ($b->ColorInterpretation) {
2214  if ($cion eq 'RedBand') { $p->{red} //= $b; last; }
2215  if ($cion eq 'GreenBand') { $p->{green} //= $b; last; }
2216  if ($cion eq 'BlueBand') { $p->{blue} //= $b; last; }
2217  }
2218  }
2219  my ($w, $h) = $self->Size;
2220  $p->{dest} //= Geo::GDAL::Driver('MEM')->Create(Name => 'dithered',
2221  Width => $w,
2222  Height => $h,
2223  Type => 'Byte')->Band;
2224  $p->{colortable}
2225  //= $p->{dest}->ColorTable
2226  // $self->ComputeColorTable(Red => $p->{red},
2227  Green => $p->{green},
2228  Blue => $p->{blue},
2229  Progress => $p->{progress},
2230  ProgressData => $p->{progressdata});
2231  Geo::GDAL::DitherRGB2PCT($p->{red},
2232  $p->{green},
2233  $p->{blue},
2234  $p->{dest},
2235  $p->{colortable},
2236  $p->{progress},
2237  $p->{progressdata});
2238  $p->{dest}->ColorTable($p->{colortable});
2239  return $p->{dest};
2240 }
2241 
2242 #** @method Domains()
2243 #*
2244 sub Domains {
2245  return @DOMAINS;
2246 }
2247 
2248 #** @method Geo::GDAL::Driver Driver()
2249 # Object method.
2250 # @note a.k.a. GetDriver
2251 # @return a Geo::GDAL::Driver object that was used to open or create this dataset.
2252 #*
2253 sub Driver {
2254 }
2255 
2256 #** @method Geo::OGR::Layer ExecuteSQL($statement, $geom = undef, $dialect = "")
2257 # Object method.
2258 # @param statement A SQL statement.
2259 # @param geom A Geo::OGR::Geometry object.
2260 # @param dialect
2261 # @return a new Geo::OGR::Layer object. The data source object will
2262 # exist as long as the layer object exists.
2263 #*
2264 sub ExecuteSQL {
2265  my $self = shift;
2266  my $layer = $self->_ExecuteSQL(@_);
2267  note($layer, "is result set");
2268  keep($layer, $self);
2269 }
2270 
2271 #** @method Geo::GDAL::Extent Extent(@params)
2272 # Object method.
2273 # @param params nothing, or a list ($xoff, $yoff, $w, $h)
2274 # @return A new Geo::GDAL::Extent object that represents the area that
2275 # this raster or the specified tile covers.
2276 #*
2277 sub Extent {
2278  my $self = shift;
2279  my $t = $self->GeoTransform;
2280  my $extent = $t->Extent($self->Size);
2281  if (@_) {
2282  my ($xoff, $yoff, $w, $h) = @_;
2283  my ($x, $y) = $t->Apply([$xoff, $xoff+$w, $xoff+$w, $xoff], [$yoff, $yoff, $yoff+$h, $yoff+$h]);
2284  my $xmin = shift @$x;
2285  my $xmax = $xmin;
2286  for my $x (@$x) {
2287  $xmin = $x if $x < $xmin;
2288  $xmax = $x if $x > $xmax;
2289  }
2290  my $ymin = shift @$y;
2291  my $ymax = $ymin;
2292  for my $y (@$y) {
2293  $ymin = $y if $y < $ymin;
2294  $ymax = $y if $y > $ymax;
2295  }
2296  $extent = Geo::GDAL::Extent->new($xmin, $ymin, $xmax, $ymax);
2297  }
2298  return $extent;
2299 }
2300 
2301 #** @method list GCPs(@GCPs, Geo::OSR::SpatialReference sr)
2302 # Object method.
2303 # Get or set the GCPs and their projection.
2304 # @param GCPs [optional] a list of Geo::GDAL::GCP objects
2305 # @param sr [optional] the projection of the GCPs.
2306 # @return a list of Geo::GDAL::GCP objects followed by a Geo::OSR::SpatialReference object.
2307 #*
2308 sub GCPs {
2309  my $self = shift;
2310  if (@_ > 0) {
2311  my $proj = pop @_;
2312  $proj = $proj->Export('WKT') if $proj and ref($proj);
2313  SetGCPs($self, \@_, $proj);
2314  }
2315  return unless defined wantarray;
2316  my $proj = Geo::OSR::SpatialReference->new(GetGCPProjection($self));
2317  my $GCPs = GetGCPs($self);
2318  return (@$GCPs, $proj);
2319 }
2320 
2321 #** @method Geo::GDAL::GeoTransform GeoTransform(Geo::GDAL::GeoTransform $geo_transform)
2322 # Object method.
2323 # Transformation from cell coordinates (column,row) to projection
2324 # coordinates (x,y)
2325 # \code
2326 # x = geo_transform[0] + column*geo_transform[1] + row*geo_transform[2]
2327 # y = geo_transform[3] + column*geo_transform[4] + row*geo_transform[5]
2328 # \endcode
2329 # @param geo_transform [optional]
2330 # @return the geo transform in a non-void context.
2331 #*
2332 sub GeoTransform {
2333  my $self = shift;
2334  eval {
2335  if (@_ == 1) {
2336  SetGeoTransform($self, $_[0]);
2337  } elsif (@_ > 1) {
2338  SetGeoTransform($self, \@_);
2339  }
2340  };
2341  confess(last_error()) if $@;
2342  return unless defined wantarray;
2343  my $t = GetGeoTransform($self);
2344  if (wantarray) {
2345  return @$t;
2346  } else {
2347  return Geo::GDAL::GeoTransform->new($t);
2348  }
2349 }
2350 
2351 #** @method GetDriver()
2352 #*
2353 sub GetDriver {
2354 }
2355 
2356 #** @method list GetFileList()
2357 # Object method.
2358 # @return list of files GDAL believes to be part of this dataset.
2359 #*
2360 sub GetFileList {
2361 }
2362 
2363 #** @method scalar GetGCPProjection()
2364 # Object method.
2365 # @return projection string.
2366 #*
2367 sub GetGCPProjection {
2368 }
2369 
2370 #** @method GetGCPSpatialRef()
2371 #*
2372 sub GetGCPSpatialRef {
2373 }
2374 
2375 #** @method Geo::OGR::Layer GetLayer($name)
2376 # Object method.
2377 # @param name the name of the requested layer. If not given, then
2378 # returns the first layer in the data source.
2379 # @return a new Geo::OGR::Layer object that represents the layer
2380 # in the data source.
2381 #*
2382 sub GetLayer {
2383  my($self, $name) = @_;
2384  my $layer = defined $name ? GetLayerByName($self, "$name") : GetLayerByIndex($self, 0);
2385  $name //= '';
2386  error(2, $name, 'Layer') unless $layer;
2387  keep($layer, $self);
2388 }
2389 
2390 #** @method list GetLayerNames()
2391 # Object method.
2392 # @note Delivers the functionality of undocumented method GetLayerCount.
2393 # @return a list of the names of the layers this data source provides.
2394 #*
2395 sub GetLayerNames {
2396  my $self = shift;
2397  my @names;
2398  for my $i (0..$self->GetLayerCount-1) {
2399  my $layer = GetLayerByIndex($self, $i);
2400  push @names, $layer->GetName;
2401  }
2402  return @names;
2403 }
2404 
2405 #** @method GetNextFeature()
2406 #*
2407 sub GetNextFeature {
2408 }
2409 
2410 #** @method GetRootGroup()
2411 #*
2412 sub GetRootGroup {
2413 }
2414 
2415 #** @method GetSpatialRef()
2416 #*
2417 sub GetSpatialRef {
2418 }
2419 
2420 #** @method GetStyleTable()
2421 #*
2422 sub GetStyleTable {
2423 }
2424 
2425 #** @method Geo::GDAL::Dataset Grid($Dest, hashref Options)
2426 # Object method.
2427 # Creates a regular raster grid from this data source.
2428 # This is equivalent to the gdal_grid utility.
2429 # @param Dest Destination raster dataset definition string (typically
2430 # filename) or an object, which implements write and close.
2431 # @param Options See section \ref index_processing_options.
2432 #*
2433 sub Grid {
2434  my ($self, $dest, $options, $progress, $progress_data) = @_;
2435  $options = Geo::GDAL::GDALGridOptions->new(make_processing_options($options));
2436  return $self->stdout_redirection_wrapper(
2437  $dest,
2438  \&Geo::GDAL::wrapper_GDALGrid,
2439  $options, $progress, $progress_data
2440  );
2441 }
2442 
2443 #** @method scalar Info(hashref Options)
2444 # Object method.
2445 # Information about this dataset.
2446 # @param Options See section \ref index_processing_options.
2447 #*
2448 sub Info {
2449  my ($self, $o) = @_;
2450  $o = Geo::GDAL::GDALInfoOptions->new(make_processing_options($o));
2451  return GDALInfo($self, $o);
2452 }
2453 
2454 #** @method Geo::GDAL::Dataset Nearblack($Dest, hashref Options, coderef progress, $progress_data)
2455 # Object method.
2456 # Convert nearly black/white pixels to black/white.
2457 # @param Dest Destination raster dataset definition string (typically
2458 # filename), destination dataset to which to add an alpha or mask
2459 # band, or an object, which implements write and close.
2460 # @param Options See section \ref index_processing_options.
2461 # @return Dataset if destination dataset definition string was given,
2462 # otherwise a boolean for success/fail but the method croaks if there
2463 # was an error.
2464 #*
2465 sub Nearblack {
2466  my ($self, $dest, $options, $progress, $progress_data) = @_;
2467  $options = Geo::GDAL::GDALNearblackOptions->new(make_processing_options($options));
2468  my $b = blessed($dest);
2469  if ($b && $b eq 'Geo::GDAL::Dataset') {
2470  Geo::GDAL::wrapper_GDALNearblackDestDS($dest, $self, $options, $progress, $progress_data);
2471  } else {
2472  return $self->stdout_redirection_wrapper(
2473  $dest,
2474  \&Geo::GDAL::wrapper_GDALNearblackDestName,
2475  $options, $progress, $progress_data
2476  );
2477  }
2478 }
2479 
2480 #** @method Geo::GDAL::Dataset Open()
2481 # Package subroutine.
2482 # The same as Geo::GDAL::Open
2483 #*
2484 sub Open {
2485 }
2486 
2487 #** @method Geo::GDAL::Dataset OpenShared()
2488 # Package subroutine.
2489 # The same as Geo::GDAL::OpenShared
2490 #*
2491 sub OpenShared {
2492 }
2493 
2494 #** @method Geo::GDAL::Dataset Rasterize($Dest, hashref Options, coderef progress, $progress_data)
2495 # Object method.
2496 # Render data from this data source into a raster.
2497 # @param Dest Destination raster dataset definition string (typically
2498 # filename), destination dataset, or an object, which implements write and close.
2499 # @param Options See section \ref index_processing_options.
2500 # @return Dataset if destination dataset definition string was given,
2501 # otherwise a boolean for success/fail but the method croaks if there
2502 # was an error.
2503 #
2504 #*
2505 sub Rasterize {
2506  my ($self, $dest, $options, $progress, $progress_data) = @_;
2507  $options = Geo::GDAL::GDALRasterizeOptions->new(make_processing_options($options));
2508  my $b = blessed($dest);
2509  if ($b && $b eq 'Geo::GDAL::Dataset') {
2510  Geo::GDAL::wrapper_GDALRasterizeDestDS($dest, $self, $options, $progress, $progress_data);
2511  } else {
2512  # TODO: options need to force a new raster be made, otherwise segfault
2513  return $self->stdout_redirection_wrapper(
2514  $dest,
2515  \&Geo::GDAL::wrapper_GDALRasterizeDestName,
2516  $options, $progress, $progress_data
2517  );
2518  }
2519 }
2520 
2521 #** @method scalar ReadRaster(%params)
2522 # Object method.
2523 # Read data from the dataset.
2524 #
2525 # @param params Named parameters:
2526 # - \a XOff x offset (cell coordinates) (default is 0)
2527 # - \a YOff y offset (cell coordinates) (default is 0)
2528 # - \a XSize width of the area to read (default is the width of the dataset)
2529 # - \a YSize height of the area to read (default is the height of the dataset)
2530 # - \a BufXSize (default is undef, i.e., the same as XSize)
2531 # - \a BufYSize (default is undef, i.e., the same as YSize)
2532 # - \a BufType data type of the buffer (default is the data type of the first band)
2533 # - \a BandList a reference to an array of band indices (default is [1])
2534 # - \a BufPixelSpace (default is 0)
2535 # - \a BufLineSpace (default is 0)
2536 # - \a BufBandSpace (default is 0)
2537 # - \a ResampleAlg one of Geo::GDAL::RIOResamplingTypes (default is 'NearestNeighbour'),
2538 # - \a Progress reference to a progress function (default is undef)
2539 # - \a ProgressData (default is undef)
2540 #
2541 # <a href="http://www.gdal.org/classGDALDataset.html">Entry in GDAL docs (method RasterIO)</a>
2542 # @return a buffer, open the buffer with \a unpack function of Perl. See Geo::GDAL::Band::PackCharacter.
2543 #*
2544 sub ReadRaster {
2545  my $self = shift;
2546  my ($width, $height) = $self->Size;
2547  my ($type) = $self->Band->DataType;
2548  my $p = named_parameters(\@_,
2549  XOff => 0,
2550  YOff => 0,
2551  XSize => $width,
2552  YSize => $height,
2553  BufXSize => undef,
2554  BufYSize => undef,
2555  BufType => $type,
2556  BandList => [1],
2557  BufPixelSpace => 0,
2558  BufLineSpace => 0,
2559  BufBandSpace => 0,
2560  ResampleAlg => 'NearestNeighbour',
2561  Progress => undef,
2562  ProgressData => undef
2563  );
2564  $p->{resamplealg} = s2i(rio_resampling => $p->{resamplealg});
2565  $p->{buftype} = s2i(data_type => $p->{buftype}, 1);
2566  $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});
2567 }
2568 
2569 #** @method ReadTile()
2570 #*
2571 sub ReadTile {
2572  my ($self, $xoff, $yoff, $xsize, $ysize, $w_tile, $h_tile, $alg) = @_;
2573  my @data;
2574  for my $i (0..$self->Bands-1) {
2575  $data[$i] = $self->Band($i+1)->ReadTile($xoff, $yoff, $xsize, $ysize, $w_tile, $h_tile, $alg);
2576  }
2577  return \@data;
2578 }
2579 
2580 #** @method ReleaseResultSet($layer)
2581 # Object method.
2582 # @param layer A layer the has been created with ExecuteSQL.
2583 # @note There is no need to call this method. The result set layer is
2584 # released in the destructor of the layer that was created with SQL.
2585 #*
2586 sub ReleaseResultSet {
2587  # a no-op, _ReleaseResultSet is called from Layer::DESTROY
2588 }
2589 
2590 #** @method ResetReading()
2591 #*
2592 sub ResetReading {
2593 }
2594 
2595 #** @method RollbackTransaction()
2596 #*
2597 sub RollbackTransaction {
2598 }
2599 
2600 #** @method SetGCPs2()
2601 #*
2602 sub SetGCPs2 {
2603 }
2604 
2605 #** @method SetSpatialRef()
2606 #*
2607 sub SetSpatialRef {
2608 }
2609 
2610 #** @method SetStyleTable()
2611 #*
2612 sub SetStyleTable {
2613 }
2614 
2615 #** @method list Size()
2616 # Object method.
2617 # @return (width, height)
2618 #*
2619 sub Size {
2620  my $self = shift;
2621  return ($self->{RasterXSize}, $self->{RasterYSize});
2622 }
2623 
2624 #** @method Geo::OSR::SpatialReference SpatialReference(Geo::OSR::SpatialReference sr)
2625 # Object method.
2626 # Get or set the projection of this dataset.
2627 # @param sr [optional] a Geo::OSR::SpatialReference object,
2628 # which replaces the existing projection definition of this dataset.
2629 # @return a Geo::OSR::SpatialReference object, which represents the
2630 # projection of this dataset.
2631 # @note Methods GetProjection, SetProjection, and Projection return WKT strings.
2632 #*
2633 sub SpatialReference {
2634  my($self, $sr) = @_;
2635  SetProjection($self, $sr->As('WKT')) if defined $sr;
2636  if (defined wantarray) {
2637  my $p = GetProjection($self);
2638  return unless $p;
2639  return Geo::OSR::SpatialReference->new(WKT => $p);
2640  }
2641 }
2642 
2643 #** @method StartTransaction()
2644 #*
2645 sub StartTransaction {
2646 }
2647 
2648 #** @method TestCapability()
2649 #*
2650 sub TestCapability {
2651  return _TestCapability(@_);
2652 }
2653 
2654 #** @method Tile(Geo::GDAL::Extent e)
2655 # Object method.
2656 # Compute the top left cell coordinates and width and height of the
2657 # tile that covers the given extent.
2658 # @param e The extent whose tile is needed.
2659 # @note Requires that the raster is a strictly north up one.
2660 # @return A list ($xoff, $yoff, $xsize, $ysize).
2661 #*
2662 sub Tile {
2663  my ($self, $e) = @_;
2664  my ($w, $h) = $self->Size;
2665  my $t = $self->GeoTransform;
2666  confess "GeoTransform is not \"north up\"." unless $t->NorthUp;
2667  my $xoff = floor(($e->[0] - $t->[0])/$t->[1]);
2668  $xoff = 0 if $xoff < 0;
2669  my $yoff = floor(($e->[1] - $t->[3])/$t->[5]);
2670  $yoff = 0 if $yoff < 0;
2671  my $xsize = ceil(($e->[2] - $t->[0])/$t->[1]) - $xoff;
2672  $xsize = $w - $xoff if $xsize > $w - $xoff;
2673  my $ysize = ceil(($e->[3] - $t->[3])/$t->[5]) - $yoff;
2674  $ysize = $h - $yoff if $ysize > $h - $yoff;
2675  return ($xoff, $yoff, $xsize, $ysize);
2676 }
2677 
2678 #** @method Geo::GDAL::Dataset Translate($Dest, hashref Options, coderef progress, $progress_data)
2679 # Object method.
2680 # Convert this dataset into another format.
2681 # @param Dest Destination dataset definition string (typically
2682 # filename) or an object, which implements write and close.
2683 # @param Options See section \ref index_processing_options.
2684 # @return New dataset object if destination dataset definition
2685 # string was given, otherwise a boolean for success/fail but the
2686 # method croaks if there was an error.
2687 #*
2688 sub Translate {
2689  my ($self, $dest, $options, $progress, $progress_data) = @_;
2690  return $self->stdout_redirection_wrapper(
2691  $dest,
2692 }
2693 
2694 #** @method Geo::GDAL::Dataset Warp($Dest, hashref Options, coderef progress, $progress_data)
2695 # Object method.
2696 # Reproject this dataset.
2697 # @param Dest Destination raster dataset definition string (typically
2698 # filename) or an object, which implements write and close.
2699 # @param Options See section \ref index_processing_options.
2700 # @note This method can be run as a package subroutine with a list of
2701 # datasets as the first argument to mosaic several datasets.
2702 #*
2703 sub Warp {
2704  my ($self, $dest, $options, $progress, $progress_data) = @_;
2705  # can be run as object method (one dataset) and as package sub (a list of datasets)
2706  $options = Geo::GDAL::GDALWarpAppOptions->new(make_processing_options($options));
2707  my $b = blessed($dest);
2708  $self = [$self] unless ref $self eq 'ARRAY';
2709  if ($b && $b eq 'Geo::GDAL::Dataset') {
2710  Geo::GDAL::wrapper_GDALWarpDestDS($dest, $self, $options, $progress, $progress_data);
2711  } else {
2712  return stdout_redirection_wrapper(
2713  $self,
2714  $dest,
2715  \&Geo::GDAL::wrapper_GDALWarpDestName,
2716  $options, $progress, $progress_data
2717  );
2718  }
2719 }
2720 
2721 #** @method Geo::GDAL::Dataset Warped(%params)
2722 # Object method.
2723 # Create a virtual warped dataset from this dataset.
2724 #
2725 # @param params Named parameters:
2726 # - \a SrcSRS Override the spatial reference system of this dataset if there is one (default is undef).
2727 # - \a DstSRS The target spatial reference system of the result (default is undef).
2728 # - \a ResampleAlg The resampling algorithm (default is 'NearestNeighbour').
2729 # - \a MaxError Maximum error measured in input cellsize that is allowed in approximating the transformation (default is 0 for exact calculations).
2730 #
2731 # # <a href="http://www.gdal.org/gdalwarper_8h.html">Documentation for GDAL warper.</a>
2732 #
2733 # @return a new Geo::GDAL::Dataset object
2734 #*
2735 sub Warped {
2736  my $self = shift;
2737  my $p = named_parameters(\@_, SrcSRS => undef, DstSRS => undef, ResampleAlg => 'NearestNeighbour', MaxError => 0);
2738  for my $srs (qw/srcsrs dstsrs/) {
2739  $p->{$srs} = $p->{$srs}->ExportToWkt if $p->{$srs} && blessed $p->{$srs};
2740  }
2741  $p->{resamplealg} = s2i(resampling => $p->{resamplealg});
2742  my $warped = Geo::GDAL::_AutoCreateWarpedVRT($self, $p->{srcsrs}, $p->{dstsrs}, $p->{resamplealg}, $p->{maxerror});
2743  keep($warped, $self) if $warped; # self must live as long as warped
2744 }
2745 
2746 #** @method WriteRaster(%params)
2747 # Object method.
2748 # Write data into the dataset.
2749 #
2750 # @param params Named parameters:
2751 # - \a XOff x offset (cell coordinates) (default is 0)
2752 # - \a YOff y offset (cell coordinates) (default is 0)
2753 # - \a XSize width of the area to write (default is the width of the dataset)
2754 # - \a YSize height of the area to write (default is the height of the dataset)
2755 # - \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.
2756 # - \a BufXSize (default is undef, i.e., the same as XSize)
2757 # - \a BufYSize (default is undef, i.e., the same as YSize)
2758 # - \a BufType data type of the buffer (default is the data type of the first band)
2759 # - \a BandList a reference to an array of band indices (default is [1])
2760 # - \a BufPixelSpace (default is 0)
2761 # - \a BufLineSpace (default is 0)
2762 # - \a BufBandSpace (default is 0)
2763 #
2764 # <a href="http://www.gdal.org/classGDALDataset.html">Entry in GDAL docs (method RasterIO)</a>
2765 #*
2766 sub WriteRaster {
2767  my $self = shift;
2768  my ($width, $height) = $self->Size;
2769  my ($type) = $self->Band->DataType;
2770  my $p = named_parameters(\@_,
2771  XOff => 0,
2772  YOff => 0,
2773  XSize => $width,
2774  YSize => $height,
2775  Buf => undef,
2776  BufXSize => undef,
2777  BufYSize => undef,
2778  BufType => $type,
2779  BandList => [1],
2780  BufPixelSpace => 0,
2781  BufLineSpace => 0,
2782  BufBandSpace => 0
2783  );
2784  $p->{buftype} = s2i(data_type => $p->{buftype}, 1);
2785  $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});
2786 }
2787 
2788 #** @method WriteTile()
2789 #*
2790 sub WriteTile {
2791  my ($self, $data, $xoff, $yoff) = @_;
2792  $xoff //= 0;
2793  $yoff //= 0;
2794  for my $i (0..$self->Bands-1) {
2795  $self->Band($i+1)->WriteTile($data->[$i], $xoff, $yoff);
2796  }
2797 }
2798 
2799 #** @class Geo::GDAL::Dimension
2800 #*
2801 package Geo::GDAL::Dimension;
2802 
2803 use base qw(Geo::GDAL)
2804 
2805 #** @method GetDirection()
2806 #*
2807 sub GetDirection {
2808 }
2809 
2810 #** @method GetFullName()
2811 #*
2812 sub GetFullName {
2813 }
2814 
2815 #** @method GetIndexingVariable()
2816 #*
2817 sub GetIndexingVariable {
2818 }
2819 
2820 #** @method GetName()
2821 #*
2822 sub GetName {
2823 }
2824 
2825 #** @method GetSize()
2826 #*
2827 sub GetSize {
2828 }
2829 
2830 #** @method GetType()
2831 #*
2832 sub GetType {
2833 }
2834 
2835 #** @method SetIndexingVariable()
2836 #*
2837 sub SetIndexingVariable {
2838 }
2839 
2840 #** @class Geo::GDAL::Driver
2841 # @brief A driver for a specific dataset format.
2842 # @details
2843 #*
2844 package Geo::GDAL::Driver;
2845 
2846 use base qw(Geo::GDAL::MajorObject Geo::GDAL)
2847 
2848 #** @attr $HelpTopic
2849 # $driver->{HelpTopic}
2850 #*
2851 
2852 #** @attr $LongName
2853 # $driver->{LongName}
2854 #*
2855 
2856 #** @attr $ShortName
2857 # $driver->{ShortName}
2858 #*
2859 
2860 #** @method list Capabilities()
2861 # Object method.
2862 # @return A list of capabilities. When executed as a package subroutine
2863 # returns a list of all potential capabilities a driver may have. When
2864 # executed as an object method returns a list of all capabilities the
2865 # driver has.
2866 #
2867 # Currently capabilities are:
2868 # CREATE, CREATECOPY, DEFAULT_FIELDS, NOTNULL_FIELDS, NOTNULL_GEOMFIELDS, OPEN, RASTER, UNIQUE_FIELDS, VECTOR, and VIRTUALIO.
2869 #
2870 # Examples.
2871 # \code
2872 # @all_capabilities = Geo::GDAL::Driver::Capabilities;
2873 # @capabilities_of_the_geotiff_driver = Geo::GDAL::Driver('GTiff')->Capabilities;
2874 # \endcode
2875 #*
2876 sub Capabilities {
2877  my $self = shift;
2878  return @CAPABILITIES unless $self;
2879  my $h = $self->GetMetadata;
2880  my @cap;
2881  for my $cap (@CAPABILITIES) {
2882  my $test = $h->{'DCAP_'.uc($cap)};
2883  push @cap, $cap if defined($test) and $test eq 'YES';
2884  }
2885  return @cap;
2886 }
2887 
2888 #** @method Geo::GDAL::Dataset Copy(%params)
2889 # Object method.
2890 # Create a new raster Geo::GDAL::Dataset as a copy of an existing dataset.
2891 # @note a.k.a. CreateCopy
2892 #
2893 # @param params Named parameters:
2894 # - \a Name name for the new raster dataset.
2895 # - \a Src the source Geo::GDAL::Dataset object.
2896 # - \a Strict 1 (default) if the copy must be strictly equivalent, or 0 if the copy may adapt.
2897 # - \a Options an anonymous hash of driver specific options.
2898 # - \a Progress [optional] a reference to a subroutine, which will
2899 # be called with parameters (number progress, string msg, progress_data).
2900 # - \a ProgressData [optional]
2901 # @return a new Geo::GDAL::Dataset object.
2902 #*
2903 sub Copy {
2904  my $self = shift;
2905  my $p = named_parameters(\@_, Name => 'unnamed', Src => undef, Strict => 1, Options => {}, Progress => undef, ProgressData => undef);
2906  return $self->stdout_redirection_wrapper(
2907  $p->{name},
2908  $self->can('_CreateCopy'),
2909  $p->{src}, $p->{strict}, $p->{options}, $p->{progress}, $p->{progressdata});
2910 }
2911 
2912 #** @method CopyFiles($NewName, $OldName)
2913 # Object method.
2914 # Copy the files of a dataset.
2915 # @param NewName String.
2916 # @param OldName String.
2917 #*
2918 sub CopyFiles {
2919 }
2920 
2921 #** @method Geo::GDAL::Dataset Create(%params)
2922 # Object method.
2923 # Create a raster dataset using this driver.
2924 # @note a.k.a. CreateDataset
2925 #
2926 # @param params Named parameters:
2927 # - \a Name The name for the dataset (default is 'unnamed') or an object, which implements write and close.
2928 # - \a Width The width for the raster dataset (default is 256).
2929 # - \a Height The height for the raster dataset (default is 256).
2930 # - \a Bands The number of bands to create into the raster dataset (default is 1).
2931 # - \a Type The data type for the raster cells (default is 'Byte'). One of Geo::GDAL::Driver::CreationDataTypes.
2932 # - \a Options Driver creation options as a reference to a hash (default is {}).
2933 #
2934 # @return A new Geo::GDAL::Dataset object.
2935 #*
2936 sub Create {
2937  my $self = shift;
2938  my $p = named_parameters(\@_, Name => 'unnamed', Width => 256, Height => 256, Bands => 1, Type => 'Byte', Options => {});
2939  my $type = s2i(data_type => $p->{type});
2940  return $self->stdout_redirection_wrapper(
2941  $p->{name},
2942  $self->can('_Create'),
2943  $p->{width}, $p->{height}, $p->{bands}, $type, $p->{options}
2944  );
2945 }
2946 
2947 #** @method CreateMultiDimensional()
2948 #*
2949 sub CreateMultiDimensional {
2950 }
2951 
2952 #** @method list CreationDataTypes()
2953 # Object method.
2954 # @return a list of data types that can be used for new datasets of this format. A subset of Geo::GDAL::DataTypes
2955 #*
2956 sub CreationDataTypes {
2957  my $self = shift;
2958  my $h = $self->GetMetadata;
2959  return split /\s+/, $h->{DMD_CREATIONDATATYPES} if $h->{DMD_CREATIONDATATYPES};
2960 }
2961 
2962 #** @method list CreationOptionList()
2963 # Object method.
2964 # @return a list of options, each option is a hashref, the keys are
2965 # name, type and description or Value. Value is a listref.
2966 #*
2967 sub CreationOptionList {
2968  my $self = shift;
2969  my @options;
2970  my $h = $self->GetMetadata->{DMD_CREATIONOPTIONLIST};
2971  if ($h) {
2972  $h = ParseXMLString($h);
2973  my($type, $value) = NodeData($h);
2974  if ($value eq 'CreationOptionList') {
2975  for my $o (Children($h)) {
2976  my %option;
2977  for my $a (Children($o)) {
2978  my(undef, $key) = NodeData($a);
2979  my(undef, $value) = NodeData(Child($a, 0));
2980  if ($key eq 'Value') {
2981  push @{$option{$key}}, $value;
2982  } else {
2983  $option{$key} = $value;
2984  }
2985  }
2986  push @options, \%option;
2987  }
2988  }
2989  }
2990  return @options;
2991 }
2992 
2993 #** @method Delete($name)
2994 # Object method.
2995 # @param name
2996 #*
2997 sub Delete {
2998 }
2999 
3000 #** @method Domains()
3001 #*
3002 sub Domains {
3003  return @DOMAINS;
3004 }
3005 
3006 #** @method scalar Extension()
3007 # Object method.
3008 # @note The returned extension does not contain a '.' prefix.
3009 # @return a suggested single extension or a list of extensions (in
3010 # list context) for datasets.
3011 #*
3012 sub Extension {
3013  my $self = shift;
3014  my $h = $self->GetMetadata;
3015  if (wantarray) {
3016  my $e = $h->{DMD_EXTENSIONS};
3017  my @e = split / /, $e;
3018  @e = split /\//, $e if $e =~ /\//; # ILWIS returns mpr/mpl
3019  for my $i (0..$#e) {
3020  $e[$i] =~ s/^\.//; # CALS returns extensions with a dot prefix
3021  }
3022  return @e;
3023  } else {
3024  my $e = $h->{DMD_EXTENSION};
3025  return '' if $e =~ /\//; # ILWIS returns mpr/mpl
3026  $e =~ s/^\.//;
3027  return $e;
3028  }
3029 }
3030 
3031 #** @method scalar MIMEType()
3032 # Object method.
3033 # @return a suggested MIME type for datasets.
3034 #*
3035 sub MIMEType {
3036  my $self = shift;
3037  my $h = $self->GetMetadata;
3038  return $h->{DMD_MIMETYPE};
3039 }
3040 
3041 #** @method scalar Name()
3042 # Object method.
3043 # @return The short name of the driver.
3044 #*
3045 sub Name {
3046  my $self = shift;
3047  return $self->{ShortName};
3048 }
3049 
3050 #** @method Open()
3051 # Object method.
3052 # The same as Geo::GDAL::Open except that only this driver is allowed.
3053 #*
3054 sub Open {
3055  my $self = shift;
3056  my @p = @_; # name, update
3057  my @flags = qw/RASTER/;
3058  push @flags, qw/READONLY/ if $p[1] eq 'ReadOnly';
3059  push @flags, qw/UPDATE/ if $p[1] eq 'Update';
3060  my $dataset = OpenEx($p[0], \@flags, [$self->Name()]);
3061  error("Failed to open $p[0]. Is it a raster dataset?") unless $dataset;
3062  return $dataset;
3063 }
3064 
3065 #** @method Rename($NewName, $OldName)
3066 # Object method.
3067 # Rename (move) a GDAL dataset.
3068 # @param NewName String.
3069 # @param OldName String.
3070 #*
3071 sub Rename {
3072 }
3073 
3074 #** @method scalar TestCapability($cap)
3075 # Object method.
3076 # Test whether the driver has the specified capability.
3077 # @param cap A capability string (one of those returned by Capabilities).
3078 # @return a boolean value.
3079 #*
3080 sub TestCapability {
3081  my($self, $cap) = @_;
3082  my $h = $self->GetMetadata->{'DCAP_'.uc($cap)};
3083  return (defined($h) and $h eq 'YES') ? 1 : undef;
3084 }
3085 
3086 #** @method stdout_redirection_wrapper()
3087 #*
3088 sub stdout_redirection_wrapper {
3089  my ($self, $name, $sub, @params) = @_;
3090  my $object = 0;
3091  if ($name && blessed $name) {
3092  $object = $name;
3093  my $ref = $object->can('write');
3094  VSIStdoutSetRedirection($ref);
3095  $name = '/vsistdout/';
3096  }
3097  my $ds;
3098  eval {
3099  $ds = $sub->($self, $name, @params);
3100  };
3101  if ($object) {
3102  if ($ds) {
3103  $Geo::GDAL::stdout_redirection{tied(%$ds)} = $object;
3104  } else {
3105  VSIStdoutUnsetRedirection();
3106  $object->close;
3107  }
3108  }
3109  confess(last_error()) if $@;
3110  confess("Failed. Use Geo::OGR::Driver for vector drivers.") unless $ds;
3111  return $ds;
3112 }
3113 
3114 #** @class Geo::GDAL::EDTComponent
3115 #*
3116 package Geo::GDAL::EDTComponent;
3117 
3118 use base qw(Geo::GDAL)
3119 
3120 #** @method GetName()
3121 #*
3122 sub GetName {
3123 }
3124 
3125 #** @method GetOffset()
3126 #*
3127 sub GetOffset {
3128 }
3129 
3130 #** @method GetType()
3131 #*
3132 sub GetType {
3133 }
3134 
3135 #** @class Geo::GDAL::ExtendedDataType
3136 #*
3137 package Geo::GDAL::ExtendedDataType;
3138 
3139 use base qw(Geo::GDAL)
3140 
3141 #** @method CanConvertTo()
3142 #*
3143 sub CanConvertTo {
3144 }
3145 
3146 #** @method CreateString()
3147 #*
3148 sub CreateString {
3149 }
3150 
3151 #** @method Equals()
3152 #*
3153 sub Equals {
3154 }
3155 
3156 #** @method GetClass()
3157 #*
3158 sub GetClass {
3159 }
3160 
3161 #** @method GetMaxStringLength()
3162 #*
3163 sub GetMaxStringLength {
3164 }
3165 
3166 #** @method GetName()
3167 #*
3168 sub GetName {
3169 }
3170 
3171 #** @method GetNumericDataType()
3172 #*
3173 sub GetNumericDataType {
3174 }
3175 
3176 #** @method GetSize()
3177 #*
3178 sub GetSize {
3179 }
3180 
3181 #** @class Geo::GDAL::Extent
3182 # @brief A rectangular area in projection coordinates: xmin, ymin, xmax, ymax.
3183 #*
3184 package Geo::GDAL::Extent;
3185 
3186 #** @method ExpandToInclude($extent)
3187 # Package subroutine.
3188 # Extends this extent to include the other extent.
3189 # @param extent Another Geo::GDAL::Extent object.
3190 #*
3191 sub ExpandToInclude {
3192  my ($self, $e) = @_;
3193  return if $e->IsEmpty;
3194  if ($self->IsEmpty) {
3195  @$self = @$e;
3196  } else {
3197  $self->[0] = $e->[0] if $e->[0] < $self->[0];
3198  $self->[1] = $e->[1] if $e->[1] < $self->[1];
3199  $self->[2] = $e->[2] if $e->[2] > $self->[2];
3200  $self->[3] = $e->[3] if $e->[3] > $self->[3];
3201  }
3202 }
3203 
3204 #** @method IsEmpty()
3205 #*
3206 sub IsEmpty {
3207  my $self = shift;
3208  return $self->[2] < $self->[0];
3209 }
3210 
3211 #** @method scalar Overlap($extent)
3212 # Package subroutine.
3213 # @param extent Another Geo::GDAL::Extent object.
3214 # @return A new, possibly empty, Geo::GDAL::Extent object, which
3215 # represents the joint area of the two extents.
3216 #*
3217 sub Overlap {
3218  my ($self, $e) = @_;
3219  return Geo::GDAL::Extent->new() unless $self->Overlaps($e);
3220  my $ret = Geo::GDAL::Extent->new($self);
3221  $ret->[0] = $e->[0] if $self->[0] < $e->[0];
3222  $ret->[1] = $e->[1] if $self->[1] < $e->[1];
3223  $ret->[2] = $e->[2] if $self->[2] > $e->[2];
3224  $ret->[3] = $e->[3] if $self->[3] > $e->[3];
3225  return $ret;
3226 }
3227 
3228 #** @method scalar Overlaps($extent)
3229 # Package subroutine.
3230 # @param extent Another Geo::GDAL::Extent object.
3231 # @return True if this extent overlaps the other extent, false otherwise.
3232 #*
3233 sub Overlaps {
3234  my ($self, $e) = @_;
3235  return $self->[0] < $e->[2] && $self->[2] > $e->[0] && $self->[1] < $e->[3] && $self->[3] > $e->[1];
3236 }
3237 
3238 #** @method list Size()
3239 # Package subroutine.
3240 # @return A list ($width, $height).
3241 #*
3242 sub Size {
3243  my $self = shift;
3244  return (0,0) if $self->IsEmpty;
3245  return ($self->[2] - $self->[0], $self->[3] - $self->[1]);
3246 }
3247 
3248 #** @method Geo::GDAL::Extent new(@params)
3249 # Package subroutine.
3250 # @param params nothing, a list ($xmin, $ymin, $xmax, $ymax), or an Extent object
3251 # @return A new Extent object (empty if no parameters, a copy of the parameter if it is an Extent object).
3252 #*
3253 sub new {
3254  my $class = shift;
3255  my $self;
3256  if (@_ == 0) {
3257  $self = [0,0,-1,0];
3258  } elsif (ref $_[0]) {
3259  @$self = @{$_[0]};
3260  } else {
3261  @$self = @_;
3262  }
3263  bless $self, $class;
3264  return $self;
3265 }
3266 
3267 #** @class Geo::GDAL::GCP
3268 # @brief A ground control point for georeferencing rasters.
3269 # @details
3270 #*
3271 package Geo::GDAL::GCP;
3272 
3273 use base qw(Geo::GDAL)
3274 
3275 #** @attr $Column
3276 # cell x coordinate (access as $gcp->{Column})
3277 #*
3278 
3279 #** @attr $Id
3280 # unique identifier (string) (access as $gcp->{Id})
3281 #*
3282 
3283 #** @attr $Info
3284 # informational message (access as $gcp->{Info})
3285 #*
3286 
3287 #** @attr $Row
3288 # cell y coordinate (access as $gcp->{Row})
3289 #*
3290 
3291 #** @attr $X
3292 # projection coordinate (access as $gcp->{X})
3293 #*
3294 
3295 #** @attr $Y
3296 # projection coordinate (access as $gcp->{Y})
3297 #*
3298 
3299 #** @attr $Z
3300 # projection coordinate (access as $gcp->{Z})
3301 #*
3302 
3303 #** @method scalar new($x = 0.0, $y = 0.0, $z = 0.0, $column = 0.0, $row = 0.0, $info = "", $id = "")
3304 # Class method.
3305 # @param x projection coordinate
3306 # @param y projection coordinate
3307 # @param z projection coordinate
3308 # @param column cell x coordinate
3309 # @param row cell y coordinate
3310 # @param info informational message
3311 # @param id unique identifier (string)
3312 # @return a new Geo::GDAL::GCP object
3313 #*
3314 sub new {
3315  my $pkg = shift;
3316  my $self = Geo::GDALc::new_GCP(@_);
3317  bless $self, $pkg if defined($self);
3318 }
3319 
3320 #** @class Geo::GDAL::GDALMultiDimInfoOptions
3321 #*
3322 package Geo::GDAL::GDALMultiDimInfoOptions;
3323 
3324 use base qw(Geo::GDAL)
3325 
3326 #** @method new()
3327 #*
3328 sub new {
3329  my $pkg = shift;
3330  my $self = Geo::GDALc::new_GDALMultiDimInfoOptions(@_);
3331  bless $self, $pkg if defined($self);
3332 }
3333 
3334 #** @class Geo::GDAL::GDALMultiDimTranslateOptions
3335 #*
3336 package Geo::GDAL::GDALMultiDimTranslateOptions;
3337 
3338 use base qw(Geo::GDAL)
3339 
3340 #** @method new()
3341 #*
3342 sub new {
3343  my $pkg = shift;
3344  my $self = Geo::GDALc::new_GDALMultiDimTranslateOptions(@_);
3345  bless $self, $pkg if defined($self);
3346 }
3347 
3348 #** @class Geo::GDAL::GeoTransform
3349 # @brief An array of affine transformation coefficients.
3350 # @details The geo transformation has the form
3351 # \code
3352 # x = a + column * b + row * c
3353 # y = d + column * e + row * f
3354 # \endcode
3355 # where
3356 # (column,row) is the location in cell coordinates, and
3357 # (x,y) is the location in projection coordinates, or vice versa.
3358 # A Geo::GDAL::GeoTransform object is a reference to an anonymous array [a,b,c,d,e,f].
3359 #*
3360 package Geo::GDAL::GeoTransform;
3361 
3362 #** @method Apply($x, $y)
3363 # Object method.
3364 # @param x Column or x, or a reference to an array of columns or x's
3365 # @param y Row or y, or a reference to an array of rows or y's
3366 # @return a list (x, y), where x and y are the transformed coordinates
3367 # or references to arrays of transformed coordinates.
3368 #*
3369 sub Apply {
3370  my ($self, $columns, $rows) = @_;
3371  return Geo::GDAL::ApplyGeoTransform($self, $columns, $rows) unless ref($columns) eq 'ARRAY';
3372  my (@x, @y);
3373  for my $i (0..$#$columns) {
3374  ($x[$i], $y[$i]) =
3375  Geo::GDAL::ApplyGeoTransform($self, $columns->[$i], $rows->[$i]);
3376  }
3377  return (\@x, \@y);
3378 }
3379 
3380 #** @method Inv()
3381 # Object method.
3382 # @return a new Geo::GDAL::GeoTransform object, which is the inverse
3383 # of this one (in void context changes this object).
3384 #*
3385 sub Inv {
3386  my $self = shift;
3387  my @inv = Geo::GDAL::InvGeoTransform($self);
3388  return Geo::GDAL::GeoTransform->new(@inv) if defined wantarray;
3389  @$self = @inv;
3390 }
3391 
3392 #** @method NorthUp()
3393 #*
3394 sub NorthUp {
3395  my $self = shift;
3396  return $self->[2] == 0 && $self->[4] == 0;
3397 }
3398 
3399 #** @method new(@params)
3400 # Class method.
3401 # @param params nothing, a reference to an array [a,b,c,d,e,f], a list
3402 # (a,b,c,d,e,f), or named parameters
3403 # - \a GCPs A reference to an array of Geo::GDAL::GCP objects.
3404 # - \a ApproxOK Minimize the error in the coefficients (integer, default is 1 (true), used with GCPs).
3405 # - \a Extent A Geo::GDAL::Extent object used to obtain the coordinates of the up left corner position.
3406 # - \a CellSize The cell size (width and height) (default is 1, used with Extent).
3407 #
3408 # @note When Extent is specifid, the created geo transform will be
3409 # north up, have square cells, and coefficient f will be -1 times the
3410 # cell size (image y - row - will increase downwards and projection y
3411 # will increase upwards).
3412 # @return a new Geo::GDAL::GeoTransform object.
3413 #*
3414 sub new {
3415  my $class = shift;
3416  my $self;
3417  if (@_ == 0) {
3418  $self = [0,1,0,0,0,1];
3419  } elsif (ref $_[0]) {
3420  @$self = @{$_[0]};
3421  } elsif ($_[0] =~ /^[a-zA-Z]/i) {
3422  my $p = named_parameters(\@_, GCPs => undef, ApproxOK => 1, Extent => undef, CellSize => 1);
3423  if ($p->{gcps}) {
3424  $self = Geo::GDAL::GCPsToGeoTransform($p->{gcps}, $p->{approxok});
3425  } elsif ($p->{extent}) {
3426  $self = Geo::GDAL::GeoTransform->new($p->{extent}[0], $p->{cellsize}, 0, $p->{extent}[2], 0, -$p->{cellsize});
3427  } else {
3428  error("Missing GCPs or Extent");
3429  }
3430  } else {
3431  my @a = @_;
3432  $self = \@a;
3433  }
3434  bless $self, $class;
3435 }
3436 
3437 #** @class Geo::GDAL::Group
3438 #*
3439 package Geo::GDAL::Group;
3440 
3441 use base qw(Geo::GDAL)
3442 
3443 #** @method CreateAttribute()
3444 #*
3445 sub CreateAttribute {
3446 }
3447 
3448 #** @method CreateDimension()
3449 #*
3450 sub CreateDimension {
3451 }
3452 
3453 #** @method CreateGroup()
3454 #*
3455 sub CreateGroup {
3456 }
3457 
3458 #** @method GetAttribute()
3459 #*
3460 sub GetAttribute {
3461 }
3462 
3463 #** @method GetFullName()
3464 #*
3465 sub GetFullName {
3466 }
3467 
3468 #** @method GetGroupNames()
3469 #*
3470 sub GetGroupNames {
3471 }
3472 
3473 #** @method GetMDArrayNames()
3474 #*
3475 sub GetMDArrayNames {
3476 }
3477 
3478 #** @method GetName()
3479 #*
3480 sub GetName {
3481 }
3482 
3483 #** @method GetStructuralInfo()
3484 #*
3485 sub GetStructuralInfo {
3486 }
3487 
3488 #** @method OpenGroup()
3489 #*
3490 sub OpenGroup {
3491 }
3492 
3493 #** @method OpenGroupFromFullname()
3494 #*
3495 sub OpenGroupFromFullname {
3496 }
3497 
3498 #** @method OpenMDArray()
3499 #*
3500 sub OpenMDArray {
3501 }
3502 
3503 #** @method OpenMDArrayFromFullname()
3504 #*
3505 sub OpenMDArrayFromFullname {
3506 }
3507 
3508 #** @method ResolveMDArray()
3509 #*
3510 sub ResolveMDArray {
3511 }
3512 
3513 #** @class Geo::GDAL::MDArray
3514 #*
3515 package Geo::GDAL::MDArray;
3516 
3517 use base qw(Geo::GDAL)
3518 
3519 #** @method AsClassicDataset()
3520 #*
3521 sub AsClassicDataset {
3522 }
3523 
3524 #** @method ComputeStatistics()
3525 #*
3526 sub ComputeStatistics {
3527 }
3528 
3529 #** @method CreateAttribute()
3530 #*
3531 sub CreateAttribute {
3532 }
3533 
3534 #** @method DeleteNoDataValue()
3535 #*
3536 sub DeleteNoDataValue {
3537 }
3538 
3539 #** @method GetAttribute()
3540 #*
3541 sub GetAttribute {
3542 }
3543 
3544 #** @method GetDataType()
3545 #*
3546 sub GetDataType {
3547 }
3548 
3549 #** @method GetDimensionCount()
3550 #*
3551 sub GetDimensionCount {
3552 }
3553 
3554 #** @method GetFullName()
3555 #*
3556 sub GetFullName {
3557 }
3558 
3559 #** @method GetMask()
3560 #*
3561 sub GetMask {
3562 }
3563 
3564 #** @method GetName()
3565 #*
3566 sub GetName {
3567 }
3568 
3569 #** @method GetNoDataValueAsDouble()
3570 #*
3571 sub GetNoDataValueAsDouble {
3572 }
3573 
3574 #** @method GetOffset()
3575 #*
3576 sub GetOffset {
3577 }
3578 
3579 #** @method GetScale()
3580 #*
3581 sub GetScale {
3582 }
3583 
3584 #** @method GetSpatialRef()
3585 #*
3586 sub GetSpatialRef {
3587 }
3588 
3589 #** @method GetStatistics()
3590 #*
3591 sub GetStatistics {
3592 }
3593 
3594 #** @method GetStructuralInfo()
3595 #*
3596 sub GetStructuralInfo {
3597 }
3598 
3599 #** @method GetTotalElementsCount()
3600 #*
3601 sub GetTotalElementsCount {
3602 }
3603 
3604 #** @method GetUnit()
3605 #*
3606 sub GetUnit {
3607 }
3608 
3609 #** @method GetUnscaled()
3610 #*
3611 sub GetUnscaled {
3612 }
3613 
3614 #** @method GetView()
3615 #*
3616 sub GetView {
3617 }
3618 
3619 #** @method SetNoDataValueDouble()
3620 #*
3621 sub SetNoDataValueDouble {
3622 }
3623 
3624 #** @method SetOffset()
3625 #*
3626 sub SetOffset {
3627 }
3628 
3629 #** @method SetScale()
3630 #*
3631 sub SetScale {
3632 }
3633 
3634 #** @method SetSpatialRef()
3635 #*
3636 sub SetSpatialRef {
3637 }
3638 
3639 #** @method SetUnit()
3640 #*
3641 sub SetUnit {
3642 }
3643 
3644 #** @method Transpose()
3645 #*
3646 sub Transpose {
3647 }
3648 
3649 #** @class Geo::GDAL::MajorObject
3650 # @brief An object, which holds meta data.
3651 # @details
3652 #*
3653 package Geo::GDAL::MajorObject;
3654 
3655 use base qw(Geo::GDAL)
3656 
3657 #** @method scalar Description($description)
3658 # Object method.
3659 # @param description [optional]
3660 # @return the description in a non-void context.
3661 #*
3662 sub Description {
3663  my($self, $desc) = @_;
3664  SetDescription($self, $desc) if defined $desc;
3665  GetDescription($self) if defined wantarray;
3666 }
3667 
3668 #** @method Domains()
3669 # Package subroutine.
3670 # @return the class specific DOMAINS list
3671 #*
3672 sub Domains {
3673  return @DOMAINS;
3674 }
3675 
3676 #** @method scalar GetDescription()
3677 # Object method.
3678 # @return
3679 #*
3680 sub GetDescription {
3681 }
3682 
3683 #** @method hash reference GetMetadata($domain = "")
3684 # Object method.
3685 # @note see Metadata
3686 # @param domain
3687 # @return
3688 #*
3689 sub GetMetadata {
3690 }
3691 
3692 #** @method GetMetadataDomainList()
3693 #*
3694 sub GetMetadataDomainList {
3695 }
3696 
3697 #** @method hash reference Metadata(hashref metadata = undef, $domain = '')
3698 # Object method.
3699 # @param metadata
3700 # @param domain
3701 # @return the metadata in a non-void context.
3702 #*
3703 sub Metadata {
3704  my $self = shift,
3705  my $metadata = ref $_[0] ? shift : undef;
3706  my $domain = shift // '';
3707  SetMetadata($self, $metadata, $domain) if defined $metadata;
3708  GetMetadata($self, $domain) if defined wantarray;
3709 }
3710 
3711 #** @method SetDescription($NewDesc)
3712 # Object method.
3713 # @param NewDesc
3714 #
3715 #*
3716 sub SetDescription {
3717 }
3718 
3719 #** @method SetMetadata(hashref metadata, $domain = "")
3720 # Object method.
3721 # @note see Metadata
3722 # @param metadata
3723 # @param domain
3724 #
3725 #*
3726 sub SetMetadata {
3727 }
3728 
3729 #** @class Geo::GDAL::RasterAttributeTable
3730 # @brief An attribute table in a raster band.
3731 # @details
3732 #*
3733 package Geo::GDAL::RasterAttributeTable;
3734 
3735 use base qw(Geo::GDAL)
3736 
3737 #** @method Band()
3738 #*
3739 sub Band {
3740  my $self = shift;
3741  parent($self);
3742 }
3743 
3744 #** @method ChangesAreWrittenToFile()
3745 #*
3746 sub ChangesAreWrittenToFile {
3747 }
3748 
3749 #** @method Geo::GDAL::RasterAttributeTable Clone()
3750 # Object method.
3751 # @return a new Geo::GDAL::RasterAttributeTable object
3752 #*
3753 sub Clone {
3754 }
3755 
3756 #** @method hash Columns(%columns)
3757 # Object method.
3758 # A get/set method for the columns of the RAT
3759 # @param columns optional, a the keys are column names and the values are anonymous
3760 # hashes with keys Type and Usage
3761 # @return a hash similar to the optional input parameter
3762 #*
3763 sub Columns {
3764  my $self = shift;
3765  my %columns;
3766  if (@_) { # create columns
3767  %columns = @_;
3768  for my $name (keys %columns) {
3769  $self->CreateColumn($name, $columns{$name}{Type}, $columns{$name}{Usage});
3770  }
3771  }
3772  %columns = ();
3773  for my $c (0..$self->GetColumnCount-1) {
3774  my $name = $self->GetNameOfCol($c);
3775  $columns{$name}{Type} = $self->GetTypeOfCol($c);
3776  $columns{$name}{Usage} = $self->GetUsageOfCol($c);
3777  }
3778  return %columns;
3779 }
3780 
3781 #** @method CreateColumn($name, $type, $usage)
3782 # Object method.
3783 # @param name
3784 # @param type one of FieldTypes
3785 # @param usage one of FieldUsages
3786 #*
3787 sub CreateColumn {
3788  my($self, $name, $type, $usage) = @_;
3789  for my $color (qw/Red Green Blue Alpha/) {
3790  carp "RAT column type will be 'Integer' for usage '$color'." if $usage eq $color and $type ne 'Integer';
3791  }
3792  $type = s2i(rat_field_type => $type);
3793  $usage = s2i(rat_field_usage => $usage);
3794  _CreateColumn($self, $name, $type, $usage);
3795 }
3796 
3797 #** @method DumpReadable()
3798 #*
3799 sub DumpReadable {
3800 }
3801 
3802 #** @method list FieldTypes()
3803 # Package subroutine.
3804 # @return
3805 #*
3806 sub FieldTypes {
3807  return @FIELD_TYPES;
3808 }
3809 
3810 #** @method list FieldUsages()
3811 # Package subroutine.
3812 # @return
3813 #*
3814 sub FieldUsages {
3815  return @FIELD_USAGES;
3816 }
3817 
3818 #** @method scalar GetColOfUsage($usage)
3819 # Object method.
3820 # @param usage
3821 # @return
3822 #*
3823 sub GetColOfUsage {
3824  my($self, $usage) = @_;
3825  _GetColOfUsage($self, s2i(rat_field_usage => $usage));
3826 }
3827 
3828 #** @method scalar GetColumnCount()
3829 # Object method.
3830 # @return
3831 #*
3832 sub GetColumnCount {
3833 }
3834 
3835 #** @method scalar GetNameOfCol($column)
3836 # Object method.
3837 # @param column
3838 # @return
3839 #*
3840 sub GetNameOfCol {
3841 }
3842 
3843 #** @method scalar GetRowCount()
3844 # Object method.
3845 #*
3846 sub GetRowCount {
3847 }
3848 
3849 #** @method scalar GetRowOfValue($value)
3850 # Object method.
3851 # @param value a cell value
3852 # @return row index or -1
3853 #*
3854 sub GetRowOfValue {
3855 }
3856 
3857 #** @method GetTableType()
3858 #*
3859 sub GetTableType {
3860 }
3861 
3862 #** @method scalar GetTypeOfCol($column)
3863 # Object method.
3864 # @param column
3865 # @return
3866 #*
3867 sub GetTypeOfCol {
3868  my($self, $col) = @_;
3869  i2s(rat_field_type => _GetTypeOfCol($self, $col));
3870 }
3871 
3872 #** @method scalar GetUsageOfCol($column)
3873 # Object method.
3874 # @param column
3875 # @return
3876 #*
3877 sub GetUsageOfCol {
3878  my($self, $col) = @_;
3879  i2s(rat_field_usage => _GetUsageOfCol($self, $col));
3880 }
3881 
3882 #** @method scalar GetValueAsDouble($row, $column)
3883 # Object method.
3884 # @param row
3885 # @param column
3886 # @return
3887 #*
3888 sub GetValueAsDouble {
3889 }
3890 
3891 #** @method scalar GetValueAsInt($row, $column)
3892 # Object method.
3893 # @param row
3894 # @param column
3895 # @return
3896 #*
3897 sub GetValueAsInt {
3898 }
3899 
3900 #** @method scalar GetValueAsString($row, $column)
3901 # Object method.
3902 # @param row
3903 # @param column
3904 # @return
3905 #*
3906 sub GetValueAsString {
3907 }
3908 
3909 #** @method LinearBinning($Row0MinIn, $BinSizeIn)
3910 # Object method.
3911 # @param Row0MinIn [optional] the lower bound (cell value) of the first category.
3912 # @param BinSizeIn [optional] the width of each category (in cell value units).
3913 # @return ($Row0MinIn, $BinSizeIn) or an empty list if LinearBinning is not set.
3914 #*
3915 sub LinearBinning {
3916  my $self = shift;
3917  SetLinearBinning($self, @_) if @_ > 0;
3918  return unless defined wantarray;
3919  my @a = GetLinearBinning($self);
3920  return $a[0] ? ($a[1], $a[2]) : ();
3921 }
3922 
3923 #** @method SetRowCount($count)
3924 # Object method.
3925 # @param count
3926 #
3927 #*
3928 sub SetRowCount {
3929 }
3930 
3931 #** @method SetTableType()
3932 #*
3933 sub SetTableType {
3934 }
3935 
3936 #** @method SetValueAsDouble($row, $column, $value)
3937 # Object method.
3938 # @param row
3939 # @param column
3940 # @param value
3941 #
3942 #*
3943 sub SetValueAsDouble {
3944 }
3945 
3946 #** @method SetValueAsInt($row, $column, $value)
3947 # Object method.
3948 # @param row
3949 # @param column
3950 # @param value
3951 #
3952 #*
3953 sub SetValueAsInt {
3954 }
3955 
3956 #** @method SetValueAsString($row, $column, $value)
3957 # Object method.
3958 # @param row
3959 # @param column
3960 # @param value
3961 #
3962 #*
3963 sub SetValueAsString {
3964 }
3965 
3966 #** @method scalar Value($row, $column, $value)
3967 # Object method.
3968 # @param row
3969 # @param column
3970 # @param value [optional]
3971 # @return
3972 #*
3973 sub Value {
3974  my($self, $row, $column) = @_;
3975  SetValueAsString($self, $row, $column, $_[3]) if defined $_[3];
3976  return unless defined wantarray;
3977  GetValueAsString($self, $row, $column);
3978 }
3979 
3980 #** @method Geo::GDAL::RasterAttributeTable new()
3981 # Class method.
3982 # @return a new Geo::GDAL::RasterAttributeTable object
3983 #*
3984 sub new {
3985  my $pkg = shift;
3986  my $self = Geo::GDALc::new_RasterAttributeTable(@_);
3987  bless $self, $pkg if defined($self);
3988 }
3989 
3990 #** @class Geo::GDAL::Statistics
3991 #*
3992 package Geo::GDAL::Statistics;
3993 
3994 use base qw(Geo::GDAL)
3995 
3996 #** @method new()
3997 #*
3998 sub new {
3999  my $pkg = shift;
4000  my $self = Geo::GDALc::new_Statistics(@_);
4001  bless $self, $pkg if defined($self);
4002 }
4003 
4004 #** @class Geo::GDAL::Transformer
4005 # @brief
4006 # @details This class is not yet documented for the GDAL Perl bindings.
4007 # @todo Test and document.
4008 #*
4009 package Geo::GDAL::Transformer;
4010 
4011 use base qw(Geo::GDAL)
4012 
4013 #** @method TransformGeolocations()
4014 #*
4015 sub TransformGeolocations {
4016 }
4017 
4018 #** @method TransformPoint()
4019 #*
4020 sub TransformPoint {
4021 }
4022 
4023 #** @method new()
4024 #*
4025 sub new {
4026  my $pkg = shift;
4027  my $self = Geo::GDALc::new_Transformer(@_);
4028  bless $self, $pkg if defined($self);
4029 }
4030 
4031 #** @class Geo::GDAL::VSIF
4032 # @brief A GDAL virtual file system.
4033 # @details
4034 #*
4035 package Geo::GDAL::VSIF;
4036 
4037 use base qw(Exporter)
4038 
4039 #** @method Close()
4040 # Object method.
4041 #*
4042 sub Close {
4043  my ($self) = @_;
4044  Geo::GDAL::VSIFCloseL($self);
4045 }
4046 
4047 #** @method Flush()
4048 #*
4049 sub Flush {
4050  my ($self) = @_;
4051  Geo::GDAL::VSIFFlushL($self);
4053 
4054 #** @method MkDir($path)
4055 # Package subroutine.
4056 # Make a directory.
4057 # @param path The directory to make.
4058 # @note The name of this method is VSIMkdir in GDAL.
4059 #*
4060 sub MkDir {
4061  my ($path) = @_;
4062  # mode unused in CPL
4063  Geo::GDAL::Mkdir($path, 0);
4064 }
4065 
4066 #** @method Geo::GDAL::VSIF Open($filename, $mode)
4067 # Package subroutine.
4068 # @param filename Name of the file to open. For example "/vsimem/x".
4069 # @param mode Access mode. 'r', 'r+', 'w', etc.
4070 # @return A file handle on success.
4071 #*
4072 sub Open {
4073  my ($path, $mode) = @_;
4074  my $self = Geo::GDAL::VSIFOpenL($path, $mode);
4075  bless $self, 'Geo::GDAL::VSIF';
4076 }
4077 
4078 #** @method scalar Read($count)
4079 # Object method.
4080 # @param count The number of bytes to read from the file.
4081 # @return A byte string.
4082 #*
4083 sub Read {
4084  my ($self, $count) = @_;
4085  Geo::GDAL::VSIFReadL($count, $self);
4086 }
4087 
4088 #** @method list ReadDir($dir)
4089 # Package subroutine.
4090 # @return Contents of a directory in an anonymous array or as a list.
4091 #*
4092 sub ReadDir {
4093  my ($path) = @_;
4094  Geo::GDAL::ReadDir($path);
4095 }
4096 
4097 #** @method scalar ReadDirRecursive($dir)
4098 # Package subroutine.
4099 # @note Give the directory in the form '/vsimem', i.e., without trailing '/'.
4100 # @return Contents of a directory tree in an anonymous array.
4101 #*
4102 sub ReadDirRecursive {
4103  my ($path) = @_;
4104  Geo::GDAL::ReadDirRecursive($path);
4105 }
4106 
4107 #** @method Rename($old, $new)
4108 # Package subroutine.
4109 # Rename a file.
4110 # @note The name of this method is VSIRename in GDAL.
4111 #*
4112 sub Rename {
4113  my ($old, $new) = @_;
4114  Geo::GDAL::Rename($old, $new);
4115 }
4116 
4117 #** @method RmDir($path)
4118 # Package subroutine.
4119 # Remove a directory.
4120 # @note The name of this method is VSIRmdir in GDAL.
4121 #*
4122 sub RmDir {
4123  my ($dirname, $recursive) = @_;
4124  eval {
4125  if (!$recursive) {
4126  Geo::GDAL::Rmdir($dirname);
4127  } else {
4128  for my $f (ReadDir($dirname)) {
4129  next if $f eq '..' or $f eq '.';
4130  my @s = Stat($dirname.'/'.$f);
4131  if ($s[0] eq 'f') {
4132  Unlink($dirname.'/'.$f);
4133  } elsif ($s[0] eq 'd') {
4134  Rmdir($dirname.'/'.$f, 1);
4135  Rmdir($dirname.'/'.$f);
4136  }
4137  }
4138  RmDir($dirname);
4139  }
4140  };
4141  if ($@) {
4142  my $r = $recursive ? ' recursively' : '';
4143  error("Cannot remove directory \"$dirname\"$r.");
4144  }
4145 }
4146 
4147 #** @method Seek($offset, $whence)
4148 # Object method.
4149 #*
4150 sub Seek {
4151  my ($self, $offset, $whence) = @_;
4152  Geo::GDAL::VSIFSeekL($self, $offset, $whence);
4153 }
4154 
4155 #** @method list Stat($filename)
4156 # Package subroutine.
4157 # @return ($filemode, $filesize). filemode is f for a plain file, d
4158 # for a directory, l for a symbolic link, p for a named pipe (FIFO), S
4159 # for a socket, b for a block special file, and c for a character
4160 # special file.
4161 #*
4162 sub Stat {
4163  my ($path) = @_;
4164  Geo::GDAL::Stat($path);
4165 }
4166 
4167 #** @method scalar Tell()
4168 # Object method.
4169 #*
4170 sub Tell {
4171  my ($self) = @_;
4172  Geo::GDAL::VSIFTellL($self);
4173 }
4174 
4175 #** @method Truncate($new_size)
4176 # Object method.
4177 #*
4178 sub Truncate {
4179  my ($self, $new_size) = @_;
4180  Geo::GDAL::VSIFTruncateL($self, $new_size);
4181 }
4182 
4183 #** @method Unlink($filename)
4184 # Package subroutine.
4185 # @param filename The file to delete.
4186 # @return 0 on success and -1 on an error.
4187 #*
4188 sub Unlink {
4189  my ($filename) = @_;
4190  Geo::GDAL::Unlink($filename);
4191 }
4192 
4193 #** @method Write($scalar)
4194 # Object method.
4195 # @param scalar The byte string to write to the file.
4196 # @return Number of bytes written into the file.
4197 #*
4198 sub Write {
4199  my ($self, $data) = @_;
4200  Geo::GDAL::VSIFWriteL($data, $self);
4201 }
4202 
4203 #** @class Geo::GDAL::VSILFILE
4204 #*
4205 package Geo::GDAL::VSILFILE;
4206 
4207 use base qw(Geo::GDAL)
4208 
4209 #** @class Geo::GDAL::XML
4210 # @brief A simple XML parser
4211 # @details
4212 #*
4213 package Geo::GDAL::XML;
4214 
4215 #** @method new($string)
4216 # Object method.
4217 # @param string String containing XML.
4218 # @return A new Geo::GDAL::XML object, which is a reference to an anonymous array.
4219 #*
4220 sub new {
4221  my $class = shift;
4222  my $xml = shift // '';
4223  my $self = ParseXMLString($xml);
4224  bless $self, $class;
4225  $self->traverse(sub {my $node = shift; bless $node, $class});
4226  return $self;
4227 }
4228 
4229 #** @method serialize()
4230 # Object method.
4231 # @return The XML serialized into a string.
4232 #*
4233 sub serialize {
4234  my $self = shift;
4235  return SerializeXMLTree($self);
4236 }
4237 1;
4238 # This file was automatically generated by SWIG (http://www.swig.org).
4239 # Version 4.0.1
4240 #
4241 # Do not make changes to this file unless you know what you are doing--modify
4242 # the SWIG interface file instead.
4243 }
4244 
4245 #** @method traverse(coderef subroutine)
4246 # Object method.
4247 # @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.
4248 #*
4249 sub traverse {
4250  my ($self, $sub) = @_;
4251  my $type = $self->[0];
4252  my $data = $self->[1];
4253  $type = NodeType($type);
4254  $sub->($self, $type, $data);
4255  for my $child (@{$self}[2..$#$self]) {
4256  traverse($child, $sub);
4257  }
4258 }
4259 
4260 #** @class Geo::GNM
4261 # @brief Base class for geographical networks in GDAL.
4262 # @details
4263 #*
4264 package Geo::GNM;
4265 
4266 #** @method CastToGenericNetwork()
4267 #*
4268 sub CastToGenericNetwork {
4269 }
4270 
4271 #** @method CastToNetwork()
4272 #*
4273 sub CastToNetwork {
4274 }
4275 
4276 #** @method GATConnectedComponents()
4277 #*
4278 sub GATConnectedComponents {
4279 }
4280 
4281 #** @method GATDijkstraShortestPath()
4282 #*
4283 sub GATDijkstraShortestPath {
4284 }
4285 
4286 #** @method GATKShortestPath()
4287 #*
4288 sub GATKShortestPath {
4289 }
4290 
4291 #** @method GNM_EDGE_DIR_BOTH()
4292 #*
4293 sub GNM_EDGE_DIR_BOTH {
4294 }
4295 
4296 #** @method GNM_EDGE_DIR_SRCTOTGT()
4297 #*
4298 sub GNM_EDGE_DIR_SRCTOTGT {
4299 }
4300 
4301 #** @method GNM_EDGE_DIR_TGTTOSRC()
4302 #*
4303 sub GNM_EDGE_DIR_TGTTOSRC {
4304  1;
4305 }
4306 
4307 #** @class Geo::GNM::GenericNetwork
4308 # @details
4309 #*
4310 package Geo::GNM::GenericNetwork;
4311 
4312 use base qw(Geo::GNM::Network Geo::GNM)
4313 
4314 #** @method ChangeAllBlockState()
4315 #*
4316 sub ChangeAllBlockState {
4317 }
4318 
4319 #** @method ChangeBlockState()
4320 #*
4321 sub ChangeBlockState {
4322 }
4323 
4324 #** @method ConnectFeatures()
4325 #*
4326 sub ConnectFeatures {
4327 }
4328 
4329 #** @method ConnectPointsByLines()
4330 #*
4331 sub ConnectPointsByLines {
4332 }
4333 
4334 #** @method CreateRule()
4335 #*
4336 sub CreateRule {
4337 }
4338 
4339 #** @method DeleteAllRules()
4340 #*
4341 sub DeleteAllRules {
4342 }
4343 
4344 #** @method DeleteRule()
4345 #*
4346 sub DeleteRule {
4347 }
4348 
4349 #** @method DisconnectFeatures()
4350 #*
4351 sub DisconnectFeatures {
4352 }
4353 
4354 #** @method DisconnectFeaturesWithId()
4355 #*
4356 sub DisconnectFeaturesWithId {
4357 }
4358 
4359 #** @method GetRules()
4360 #*
4361 sub GetRules {
4362 }
4363 
4364 #** @method ReconnectFeatures()
4365 #*
4366 sub ReconnectFeatures {
4367 }
4368 
4369 #** @class Geo::GNM::MajorObject
4370 # @details
4371 #*
4372 package Geo::GNM::MajorObject;
4373 
4374 #** @class Geo::GNM::Network
4375 # @details
4376 #*
4377 package Geo::GNM::Network;
4378 
4379 use base qw(Geo::GDAL::MajorObject Geo::GNM)
4380 
4381 #** @method CommitTransaction()
4382 #*
4383 sub CommitTransaction {
4384 }
4385 
4386 #** @method CopyLayer()
4387 #*
4388 sub CopyLayer {
4389 }
4390 
4391 #** @method DisconnectAll()
4392 #*
4393 sub DisconnectAll {
4394 }
4395 
4396 #** @method GetFeatureByGlobalFID()
4397 #*
4398 sub GetFeatureByGlobalFID {
4399 }
4400 
4401 #** @method GetFileList()
4402 #*
4403 sub GetFileList {
4404 }
4405 
4406 #** @method GetLayerByIndex()
4407 #*
4408 sub GetLayerByIndex {
4409 }
4410 
4411 #** @method GetLayerByName()
4412 #*
4413 sub GetLayerByName {
4414 }
4415 
4416 #** @method GetLayerCount()
4417 #*
4418 sub GetLayerCount {
4419 }
4420 
4421 #** @method GetName()
4422 #*
4423 sub GetName {
4424 }
4425 
4426 #** @method GetPath()
4427 #*
4428 sub GetPath {
4429 }
4430 
4431 #** @method GetProjection()
4432 #*
4433 sub GetProjection {
4434 }
4435 
4436 #** @method GetProjectionRef()
4437 #*
4438 sub GetProjectionRef {
4439 }
4440 
4441 #** @method GetVersion()
4442 #*
4443 sub GetVersion {
4444 }
4445 
4446 #** @method RollbackTransaction()
4447 #*
4448 sub RollbackTransaction {
4449 }
4450 
4451 #** @method StartTransaction()
4452 #*
4453 sub StartTransaction {
4454 }
4455 
4456 #** @class Geo::OGR
4457 # @brief OGR utility functions.
4458 # @details A wrapper for many OGR utility functions and a root class for all
4459 # OGR classes.
4460 #*
4461 package Geo::OGR;
4462 
4463 #** @method list ByteOrders()
4464 # Package subroutine.
4465 # @return a list of byte order types, XDR and NDR. XDR denotes
4466 # big-endian and NDR denotes little-endian.
4467 #*
4468 sub ByteOrders {
4469 }
4470 
4471 #** @method CreateGeometryFromEsriJson()
4472 #*
4473 sub CreateGeometryFromEsriJson {
4474 }
4475 
4476 #** @method Geo::GDAL::Driver Driver($name)
4477 # Package subroutine.
4478 # A.k.a GetDriver.
4479 # @param name the short name of the driver.
4480 # @note No check is made that the driver is actually a vector driver.
4481 # @return a Geo::GDAL::Driver object.
4482 #*
4483 sub Driver {
4484  return 'Geo::GDAL::Driver' unless @_;
4485  bless Geo::GDAL::Driver(@_), 'Geo::OGR::Driver';
4486 }
4487 
4488 #** @method list DriverNames()
4489 # Package subroutine.
4490 # A.k.a GetDriverNames
4491 # \code
4492 # perl -MGeo::GDAL -e '@d=Geo::OGR::DriverNames;print "@d\n"'
4493 # \endcode
4494 # @note Use Geo::GDAL::DriverNames for raster drivers.
4495 # @return a list of the short names of all available GDAL vector drivers.
4496 #*
4497 sub DriverNames {
4498 }
4499 
4500 #** @method list Drivers()
4501 # Package subroutine.
4502 # @note Use Geo::GDAL::Drivers for raster drivers.
4503 # @return a list of all available GDAL vector drivers.
4504 #*
4505 sub Drivers {
4506  my @drivers;
4507  for my $i (0..GetDriverCount()-1) {
4508  my $driver = Geo::GDAL::GetDriver($i);
4509  push @drivers, $driver if $driver->TestCapability('VECTOR');
4510  }
4511  return @drivers;
4512 }
4513 
4514 #** @method Flatten()
4515 #*
4516 sub Flatten {
4517 }
4518 
4519 #** @method scalar GeometryTypeModify($type, $modifier)
4520 # Object method.
4521 # @param type a geometry type (one of Geo::OGR::GeometryTypes).
4522 # @param modifier one of 'flatten', 'set_Z', 'make_collection', 'make_curve', or 'make_linear'.
4523 # @return modified geometry type.
4524 #*
4525 sub GeometryTypeModify {
4526  my($type, $modifier) = @_;
4527  $type = s2i(geometry_type => $type);
4528  return i2s(geometry_type => GT_Flatten($type)) if $modifier =~ /flat/i;
4529  return i2s(geometry_type => GT_SetZ($type)) if $modifier =~ /z/i;
4530  return i2s(geometry_type => GT_GetCollection($type)) if $modifier =~ /collection/i;
4531  return i2s(geometry_type => GT_GetCurve($type)) if $modifier =~ /curve/i;
4532  return i2s(geometry_type => GT_GetLinear($type)) if $modifier =~ /linear/i;
4533  error(1, $modifier, {Flatten => 1, SetZ => 1, GetCollection => 1, GetCurve => 1, GetLinear => 1});
4534 }
4535 
4536 #** @method scalar GeometryTypeTest($type, $test, $type2)
4537 # Object method.
4538 # @param type a geometry type (one of Geo::OGR::GeometryTypes).
4539 # @param test one of 'has_z', 'is_subclass_of', 'is_curve', 'is_surface', or 'is_non_linear'.
4540 # @param type2 a geometry type (one of Geo::OGR::GeometryTypes). Required for 'is_subclass_of' test.
4541 # @return result of the test.
4542 #*
4543 sub GeometryTypeTest {
4544  my($type, $test, $type2) = @_;
4545  $type = s2i(geometry_type => $type);
4546  if (defined $type2) {
4547  $type = s2i(geometry_type => $type);
4548  } else {
4549  error("Usage: GeometryTypeTest(type1, 'is_subclass_of', type2).") if $test =~ /subclass/i;
4550  }
4551  return GT_HasZ($type) if $test =~ /z/i;
4552  return GT_IsSubClassOf($type, $type2) if $test =~ /subclass/i;
4553  return GT_IsCurve($type) if $test =~ /curve/i;
4554  return GT_IsSurface($type) if $test =~ /surface/i;
4555  return GT_IsNonLinear($type) if $test =~ /linear/i;
4556  error(1, $test, {HasZ => 1, IsSubClassOf => 1, IsCurve => 1, IsSurface => 1, IsNonLinear => 1});
4557 }
4558 
4559 #** @method list GeometryTypes()
4560 # Package subroutine.
4561 # @return a list of all geometry types, currently:
4562 # 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.
4563 #*
4564 sub GeometryTypes {
4565  1;
4566  # This file was automatically generated by SWIG (http://www.swig.org).
4567  # Version 4.0.1
4568  #
4569  # Do not make changes to this file unless you know what you are doing--modify
4570  # the SWIG interface file instead.
4571 }
4572 
4573 #** @method GetNonLinearGeometriesEnabledFlag()
4574 #*
4575 sub GetNonLinearGeometriesEnabledFlag {
4576 }
4577 
4578 #** @method GetOpenDSCount()
4579 #*
4580 sub GetOpenDSCount {
4581 }
4582 
4583 #** @method HasM()
4584 #*
4585 sub HasM {
4586 }
4587 
4588 #** @method HasZ()
4589 #*
4590 sub HasZ {
4591 }
4592 
4593 #** @method Geo::GDAL::Dataset Open($name, $update = 0)
4594 # Object method.
4595 # Open a vector data source.
4596 # @param name The data source string (directory, filename, etc.).
4597 # @param update Whether to open the data source in update mode (default is not).
4598 # @return a new Geo::GDAL::Dataset object.
4599 #*
4600 sub Open {
4601  my @p = @_; # name, update
4602  my @flags = qw/VECTOR/;
4603  push @flags, qw/UPDATE/ if $p[1];
4604  my $dataset = Geo::GDAL::OpenEx($p[0], \@flags);
4605  error("Failed to open $p[0]. Is it a vector dataset?") unless $dataset;
4606  return $dataset;
4607 }
4608 
4609 #** @method Geo::GDAL::Dataset OpenShared($name, $update = 0)
4610 # Object method.
4611 # Open a vector data source in shared mode.
4612 # @param name The data source string (directory, filename, etc.).
4613 # @param update Whether to open the data source in update mode.
4614 # @return a new Geo::GDAL::Dataset object.
4615 #*
4616 sub OpenShared {
4617  my @p = @_; # name, update
4618  my @flags = qw/VECTOR SHARED/;
4619  push @flags, qw/UPDATE/ if $p[1];
4620  my $dataset = Geo::GDAL::OpenEx($p[0], \@flags);
4621  error("Failed to open $p[0]. Is it a vector dataset?") unless $dataset;
4622  return $dataset;
4623 }
4624 
4625 #** @method SetGenerate_DB2_V72_BYTE_ORDER($Generate_DB2_V72_BYTE_ORDER)
4626 # Object method.
4627 # Needed only on IBM DB2.
4628 #*
4629 sub SetGenerate_DB2_V72_BYTE_ORDER {
4630 }
4631 
4632 #** @method SetNonLinearGeometriesEnabledFlag()
4633 #*
4634 sub SetNonLinearGeometriesEnabledFlag {
4635 }
4636 
4637 #** @class Geo::OGR::DataSource
4638 # @brief A vector dataset.
4639 # @details This is a legacy class which should not be
4640 # used in new code. Use Geo::GDAL::Dataset.
4641 #*
4642 package Geo::OGR::DataSource;
4643 
4644 #** @method Geo::GDAL::Dataset Open()
4645 # Package subroutine.
4646 # The same as Geo::OGR::Open
4647 #*
4648 sub Open {
4649 }
4650 
4651 #** @method Geo::GDAL::Dataset OpenShared()
4652 # Package subroutine.
4653 # The same as Geo::OGR::OpenShared
4654 #*
4655 sub OpenShared {
4656 }
4657 
4658 #** @class Geo::OGR::Driver
4659 # @brief A vector format driver.
4660 # @details This is a legacy class which
4661 # should not be used in new code. Use Geo::GDAL::Driver.
4662 #*
4663 package Geo::OGR::Driver;
4664 
4665 use base qw(Geo::GDAL::Driver)
4666 
4667 #** @method Geo::GDAL::Dataset Copy(Geo::GDAL::Dataset source, $name, arrayref options = undef)
4668 # Object method.
4669 # Copy a vector data source into a new data source with this driver.
4670 # @param source The Geo::GDAL::Dataset object to be copied.
4671 # @param name The name for the new data source.
4672 # @param options Driver specific options. In addition to options
4673 # specified in GDAL documentation the option STRICT can be set to 'NO'
4674 # for a more relaxed copy. Otherwise the STRICT is 'YES'.
4675 # @note The order of the first two parameters is different from that in Geo::GDAL::Driver::Copy.
4676 # @return a new Geo::GDAL::Dataset object.
4677 #*
4678 sub Copy {
4679  my ($self, @p) = @_; # src, name, options
4680  my $strict = 1; # the default in bindings
4681  $strict = 0 if $p[2] && $p[2]->{STRICT} eq 'NO';
4682  $self->SUPER::Copy($p[1], $p[0], $strict, @{$p[2..4]}); # path, src, strict, options, cb, cb_data
4683 }
4684 
4685 #** @method Geo::GDAL::Dataset Create($name, hashref options = undef )
4686 # Object method.
4687 # Create a new vector data source using this driver.
4688 # @param name The data source name.
4689 # @param options Driver specific dataset creation options.
4690 #*
4691 sub Create {
4692  my ($self, $name, $options) = @_; # name, options
4693  $options //= {};
4694  $self->SUPER::Create(Name => $name, Width => 0, Height => 0, Bands => 0, Type => 'Byte', Options => $options);
4695 }
4696 
4697 #** @method Open()
4698 # Object method.
4699 # The same as Geo::OGR::Open except that only this driver is allowed.
4700 #*
4701 sub Open {
4702  my $self = shift;
4703  my @p = @_; # name, update
4704  my @flags = qw/VECTOR/;
4705  push @flags, qw/UPDATE/ if $p[1];
4706  my $dataset = Geo::GDAL::OpenEx($p[0], \@flags, [$self->Name()]);
4707  error("Failed to open $p[0]. Is it a vector dataset?") unless $dataset;
4708  return $dataset;
4709 }
4710 
4711 #** @class Geo::OGR::Feature
4712 # @brief A collection of non-spatial and spatial attributes.
4713 # @details A feature is a collection of non-spatial and spatial attributes and
4714 # an id, which is a special attribute, and data records according to
4715 # this data model. Attributes are called fields and some fields are
4716 # spatial, i.e., their value is a geometry. Fields have at least a
4717 # name and a type. Features may exist within a layer or
4718 # separately. The data model of a feature is a definition object.
4719 #*
4720 package Geo::OGR::Feature;
4721 
4722 use base qw(Geo::OGR)
4723 
4724 #** @method Geo::OGR::Feature Clone()
4725 # Object method.
4726 # @return a new Geo::OGR::Feature object
4727 #*
4728 sub Clone {
4729 }
4730 
4731 #** @method DumpReadable()
4732 # Object method.
4733 # Write the contents of this feature to stdout.
4734 #*
4735 sub DumpReadable {
4736 }
4737 
4738 #** @method scalar Equal($feature)
4739 # Object method.
4740 # @param feature a Geo::OGR::Feature object for comparison
4741 # @return boolean
4742 #*
4743 sub Equal {
4744 }
4745 
4746 #** @method scalar FID($id)
4747 # Object method.
4748 # @brief Get or set the id of this feature.
4749 # @param id [optional] the id to set for this feature.
4750 # @return integer the id of this feature.
4751 #*
4752 sub FID {
4753  my $self = shift;
4754  $self->SetFID($_[0]) if @_;
4755  return unless defined wantarray;
4756  $self->GetFID;
4757 }
4758 
4759 #** @method Field($name, $value, ...)
4760 # Object method.
4761 # @brief Get, set, or unset the field value.
4762 # @param name the name (or the index) of the field.
4763 # @param value a scalar, a list of scalars or a reference to a
4764 # list. If undef, the field is unset. If a scalar or a list of
4765 # scalars, the field is set from them.
4766 # @note Non-scalar fields (for example Date) can be set either from a
4767 # scalar, which is then assumed to be a string and parsed, or from a
4768 # list of values (for example year, month, day for Date).
4769 # @note Setting and getting Integer64 fields requires 'use bigint' if
4770 # \$Config{ivsize} is smaller than 8, i.e., in a 32 bit machine.
4771 # @return in non-void context the value of the field, which may be a
4772 # scalar or a list, depending on the field type. For unset fields the
4773 # undef value is returned.
4774 #*
4775 sub Field {
4776  my $self = shift;
4777  my $field = $self->GetFieldIndex(shift // 0);
4778  $self->SetField($field, @_) if @_;
4779  $self->GetField($field) if defined wantarray;
4780 }
4781 
4782 #** @method FillUnsetWithDefault()
4783 #*
4784 sub FillUnsetWithDefault {
4785 }
4786 
4787 #** @method Geometry($name, $geometry)
4788 # Object method.
4789 # @brief Get or set the value of a geometry field.
4790 # @note This method delivers the functionality of undocumented methods
4791 # SetGeometry($geometry), SetGeometryDirectly, SetGeomField,
4792 # SetGeomFieldDirectly, GetGeometry, GetGeometryRef.
4793 #
4794 # Set or get the geometry in the feature. When setting, does a check
4795 # against the schema (GeometryType) of the feature. If the parameter
4796 # is a geometry object, it is cloned.
4797 # @param name [optional] the name of the spatial field,
4798 # whose geometry is to be set. If not given, sets or gets the geometry
4799 # of the first (or the single) spatial field.
4800 # @param geometry [optional] a Geo::OGR::Geometry object or a
4801 # reference to a hash from which such can be created (using
4802 # Geo::OGR::Geometry::new).
4803 # @return in a non-void context the indicated geometry in the feature
4804 # as a Geo::OGR::Geometry object. The returned object contains a
4805 # reference to the actual geometry data in the feature (the geometry
4806 # is not cloned) and to the feature object, thus keeping the feature
4807 # object from being destroyed while the geometry object exists.
4808 #*
4809 sub Geometry {
4810  my $self = shift;
4811  my $field = ((@_ > 0 and ref($_[0]) eq '') or (@_ > 2 and @_ % 2 == 1)) ? shift : 0;
4812  $field = $self->GetGeomFieldIndex($field);
4813  my $geometry;
4814  if (@_ and @_ % 2 == 0) {
4815  %$geometry = @_;
4816  } else {
4817  $geometry = shift;
4818  }
4819  if ($geometry) {
4820  my $type = $self->GetDefn->GetGeomFieldDefn($field)->Type;
4821  if (blessed($geometry) and $geometry->isa('Geo::OGR::Geometry')) {
4822  my $gtype = $geometry->GeometryType;
4823  error("The type of the inserted geometry ('$gtype') is not the same as the type of the field ('$type').")
4824  if $type ne 'Unknown' and $type ne $gtype;
4825  eval {
4826  $self->SetGeomFieldDirectly($field, $geometry->Clone);
4827  };
4828  confess last_error() if $@;
4829  } elsif (ref($geometry) eq 'HASH') {
4830  $geometry->{GeometryType} //= $type;
4831  eval {
4832  $geometry = Geo::OGR::Geometry->new($geometry);
4833  };
4834  confess last_error() if $@;
4835  my $gtype = $geometry->GeometryType;
4836  error("The type of the inserted geometry ('$gtype') is not the same as the type of the field ('$type').")
4837  if $type ne 'Unknown' and $type ne $gtype;
4838  eval {
4839  $self->SetGeomFieldDirectly($field, $geometry);
4840  };
4841  confess last_error() if $@;
4842  } else {
4843  error("Usage: \$feature->Geometry([field],[geometry])");
4844  }
4845  }
4846  return unless defined wantarray;
4847  $geometry = $self->GetGeomFieldRef($field);
4848  return unless $geometry;
4849  keep($geometry, $self);
4850 }
4851 
4852 #** @method Geo::OGR::FeatureDefn GetDefn()
4853 # Object method.
4854 # @note A.k.a GetDefnRef.
4855 # @return a Geo::OGR::FeatureDefn object, which represents the definition of this feature.
4856 #*
4857 sub GetDefn {
4858  my $self = shift;
4859  my $defn = $self->GetDefnRef;
4860  keep($defn, $self);
4861 }
4862 
4863 #** @method scalar GetFID()
4864 # Object method.
4865 # @return the feature id (an integer).
4866 #*
4867 sub GetFID {
4868 }
4869 
4870 #** @method list GetField($name)
4871 # Object method.
4872 # See Field().
4873 #*
4874 sub GetField {
4875  my ($self, $field) = @_;
4876  $field = $self->GetFieldIndex($field);
4877  return unless IsFieldSet($self, $field);
4878  my $type = GetFieldType($self, $field);
4879  return GetFieldAsInteger($self, $field) if $type == $Geo::OGR::OFTInteger;
4880  return GetFieldAsInteger64($self, $field) if $type == $Geo::OGR::OFTInteger64;
4881  return GetFieldAsDouble($self, $field) if $type == $Geo::OGR::OFTReal;
4882  return GetFieldAsString($self, $field) if $type == $Geo::OGR::OFTString;
4883  if ($type == $Geo::OGR::OFTIntegerList) {
4884  my $ret = GetFieldAsIntegerList($self, $field);
4885  return wantarray ? @$ret : $ret;
4886  }
4887  if ($type == $Geo::OGR::OFTInteger64List) {
4888  my $ret = GetFieldAsInteger64List($self, $field);
4889  return wantarray ? @$ret : $ret;
4890  }
4891  if ($type == $Geo::OGR::OFTRealList) {
4892  my $ret = GetFieldAsDoubleList($self, $field);
4893  return wantarray ? @$ret : $ret;
4894  }
4895  if ($type == $Geo::OGR::OFTStringList) {
4896  my $ret = GetFieldAsStringList($self, $field);
4897  return wantarray ? @$ret : $ret;
4898  }
4899  if ($type == $Geo::OGR::OFTBinary) {
4900  return GetFieldAsBinary($self, $field);
4901  }
4902  if ($type == $Geo::OGR::OFTDate) {
4903  my @ret = GetFieldAsDateTime($self, $field);
4904  # year, month, day, hour, minute, second, timezone
4905  return wantarray ? @ret[0..2] : [@ret[0..2]];
4906  }
4907  if ($type == $Geo::OGR::OFTTime) {
4908  my @ret = GetFieldAsDateTime($self, $field);
4909  return wantarray ? @ret[3..6] : [@ret[3..6]];
4910  }
4911  if ($type == $Geo::OGR::OFTDateTime) {
4912  my @ret = GetFieldAsDateTime($self, $field);
4913  return wantarray ? @ret : [@ret];
4914  }
4915  error("Perl bindings do not support the field type '".i2s(field_type => $type)."'.");
4916 }
4917 
4918 #** @method scalar GetFieldDefn($name)
4919 # Object method.
4920 # Get the definition of a field.
4921 # @param name the name of the field.
4922 # @return a Geo::OGR::FieldDefn object.
4923 #*
4924 sub GetFieldDefn {
4925  my $self = shift;
4926  my $field = $self->GetFieldIndex(shift);
4927  return $self->GetFieldDefnRef($field);
4928 }
4929 
4930 #** @method list GetFieldNames()
4931 # Object method.
4932 # Get the names of the fields in this feature.
4933 #*
4934 sub GetFieldNames {
4935 }
4936 
4937 #** @method scalar GetGeomFieldDefn($name)
4938 # Object method.
4939 # Get the definition of a spatial field.
4940 # @param name the name of the spatial field.
4941 # @return a Geo::OGR::GeomFieldDefn object.
4942 #*
4943 sub GetGeomFieldDefn {
4944  my $self = shift;
4945  my $field = $self->GetGeomFieldIndex(shift);
4946  return $self->GetGeomFieldDefnRef($field);
4947 }
4948 
4949 #** @method GetNativeData()
4950 #*
4951 sub GetNativeData {
4952 }
4953 
4954 #** @method GetNativeMediaType()
4955 #*
4956 sub GetNativeMediaType {
4957 }
4958 
4959 #** @method hash reference GetSchema()
4960 # Object method.
4961 # @brief Get the schema of this feature.
4962 #
4963 # @return the schema as a hash whose keywords are Name, StyleIgnored
4964 # and Fields. Fields is an anonymous array of first non-spatial and
4965 # then spatial field schemas as in Geo::OGR::FieldDefn::Schema() and
4966 # Geo::OGR::GeomFieldDefn::Schema().
4967 #*
4968 sub GetSchema {
4969  my $self = shift;
4970  error("Schema of a feature cannot be set directly.") if @_;
4971  return $self->GetDefnRef->Schema;
4972 }
4973 
4974 #** @method scalar GetStyleString()
4975 # Object method.
4976 # @return a string
4977 #*
4978 sub GetStyleString {
4979 }
4980 
4981 #** @method IsFieldNull()
4982 #*
4983 sub IsFieldNull {
4984 }
4985 
4986 #** @method IsFieldSetAndNotNull()
4987 #*
4988 sub IsFieldSetAndNotNull {
4989 }
4990 
4991 #** @method Geo::OGR::Layer Layer()
4992 # Object method.
4993 # @return the layer to which this feature belongs to or undef.
4994 #*
4995 sub Layer {
4996  my $self = shift;
4997  parent($self);
4998 }
4999 
5000 #** @method hash reference Row(%row)
5001 # Object method.
5002 # @note This method discards the data the destination feature (or
5003 # layer) does not support. Changes in data due to differences between
5004 # field types may also occur.
5005 #
5006 # Get and/or set the data of the feature. The key of the (key,value)
5007 # pairs of the row is the field name. Special field names FID and
5008 # Geometry are used for feature id and (single) geometry
5009 # respectively. The geometry/ies is/are set and get using the
5010 # Geo::OGR::Feature::Geometry method. Field values are set using the
5011 # Geo::OGR::Feature::Field method.
5012 # @param row [optional] feature data in a hash.
5013 # @return a reference to feature data in a hash. Spatial fields are
5014 # returned as Geo::OGR::Geometry objects.
5015 #*
5016 sub Row {
5017  my $self = shift;
5018  my $nf = $self->GetFieldCount;
5019  my $ngf = $self->GetGeomFieldCount;
5020  if (@_) { # update
5021  my %row;
5022  if (@_ == 1 and ref($_[0]) eq 'HASH') {
5023  %row = %{$_[0]};
5024  } elsif (@_ and @_ % 2 == 0) {
5025  %row = @_;
5026  } else {
5027  error('Usage: $feature->Row(%FeatureData).');
5028  }
5029  $self->SetFID($row{FID}) if defined $row{FID};
5030  #$self->Geometry($schema, $row{Geometry}) if $row{Geometry};
5031  for my $name (keys %row) {
5032  next if $name eq 'FID';
5033  if ($name eq 'Geometry') {
5034  $self->Geometry(0, $row{$name});
5035  next;
5036  }
5037  my $f = 0;
5038  for my $i (0..$nf-1) {
5039  if ($self->GetFieldDefnRef($i)->Name eq $name) {
5040  $self->SetField($i, $row{$name});
5041  $f = 1;
5042  last;
5043  }
5044  }
5045  next if $f;
5046  for my $i (0..$ngf-1) {
5047  if ($self->GetGeomFieldDefnRef($i)->Name eq $name) {
5048  $self->Geometry($i, $row{$name});
5049  $f = 1;
5050  last;
5051  }
5052  }
5053  next if $f;
5054  carp "Unknown field: '$name'.";
5055  }
5056  }
5057  return unless defined wantarray;
5058  my %row = ();
5059  for my $i (0..$nf-1) {
5060  my $name = $self->GetFieldDefnRef($i)->Name;
5061  $row{$name} = $self->GetField($i);
5062  }
5063  for my $i (0..$ngf-1) {
5064  my $name = $self->GetGeomFieldDefnRef($i)->Name || 'Geometry';
5065  $row{$name} = $self->GetGeometry($i);
5066  }
5067  $row{FID} = $self->GetFID;
5068  return \%row;
5069 }
5070 
5071 #** @method SetFID($id)
5072 # Object method.
5073 # @param id the feature id.
5074 #*
5075 sub SetFID {
5076 }
5077 
5078 #** @method SetField($name, @Value)
5079 # Object method.
5080 # See Field().
5081 #*
5082 sub SetField {
5083  my $self = shift;
5084  my $field = $self->GetFieldIndex(shift);
5085  my $arg = $_[0];
5086  if (@_ == 0 or !defined($arg)) {
5087  _UnsetField($self, $field);
5088  return;
5089  }
5090  $arg = [@_] if @_ > 1;
5091  my $type = $self->GetFieldType($field);
5092  if (ref($arg)) {
5093  if ($type == $Geo::OGR::OFTIntegerList) {
5094  SetFieldIntegerList($self, $field, $arg);
5095  }
5096  elsif ($type == $Geo::OGR::OFTInteger64List) {
5097  SetFieldInteger64List($self, $field, $arg);
5098  }
5099  elsif ($type == $Geo::OGR::OFTRealList) {
5100  SetFieldDoubleList($self, $field, $arg);
5101  }
5102  elsif ($type == $Geo::OGR::OFTStringList) {
5103  SetFieldStringList($self, $field, $arg);
5104  }
5105  elsif ($type == $Geo::OGR::OFTDate) {
5106  _SetField($self, $field, @$arg[0..2], 0, 0, 0, 0);
5107  }
5108  elsif ($type == $Geo::OGR::OFTTime) {
5109  $arg->[3] //= 0;
5110  _SetField($self, $field, 0, 0, 0, @$arg[0..3]);
5111  }
5112  elsif ($type == $Geo::OGR::OFTDateTime) {
5113  $arg->[6] //= 0;
5114  _SetField($self, $field, @$arg[0..6]);
5115  }
5116  elsif ($type == $Geo::OGR::OFTInteger64)
5117  {
5118  SetFieldInteger64($self, $field, $arg);
5119  }
5120  else {
5121  $type = i2s(field_type => $type);
5122  my $name = $self->GetFieldDefnRef($field)->Name;
5123  error("'$arg' is not a suitable value for field $name($type).");
5124  }
5125  } else {
5126  if ($type == $Geo::OGR::OFTBinary) {
5127  #$arg = unpack('H*', $arg); # remove when SetFieldBinary is available
5128  $self->SetFieldBinary($field, $arg);
5129  }
5130  elsif ($type == $Geo::OGR::OFTInteger64)
5131  {
5132  SetFieldInteger64($self, $field, $arg);
5133  }
5134  elsif ($type == $Geo::OGR::OFTInteger or $type == $Geo::OGR::OFTReal or $type == $Geo::OGR::OFTString)
5135  {
5136  _SetField($self, $field, $arg);
5137  }
5138  else {
5139  $type = i2s(field_type => $type);
5140  my $name = $self->GetFieldDefnRef($field)->Name;
5141  error("'$arg' is not a suitable value for field $name($type).");
5142  }
5143  }
5144 }
5145 
5146 #** @method SetFieldNull()
5147 #*
5148 sub SetFieldNull {
5149 }
5150 
5151 #** @method SetFrom($other, $forgiving = 1, hashref map)
5152 # Object method.
5153 # @param other a Geo::OGR::Feature object
5154 # @param forgiving [optional] set to false if the operation should not
5155 # continue if output fields do not match some of the source fields
5156 # @param map [optional] a mapping from output field indexes to source
5157 # fields, include into the hash all field indexes of this feature
5158 # which should be set
5159 #*
5160 sub SetFrom {
5161  my($self, $other) = @_;
5162  _SetFrom($self, $other), return if @_ <= 2;
5163  my $forgiving = $_[2];
5164  _SetFrom($self, $other, $forgiving), return if @_ <= 3;
5165  my $map = $_[3];
5166  my @list;
5167  for my $i (1..GetFieldCount($self)) {
5168  push @list, ($map->{$i} || -1);
5169  }
5170  SetFromWithMap($self, $other, 1, \@list);
5171 }
5172 
5173 #** @method SetNativeData()
5174 #*
5175 sub SetNativeData {
5176 }
5177 
5178 #** @method SetNativeMediaType()
5179 #*
5180 sub SetNativeMediaType {
5181 }
5182 
5183 #** @method SetStyleString($string)
5184 # Object method.
5185 # @param string
5186 #*
5187 sub SetStyleString {
5188 }
5189 
5190 #** @method list Tuple(@tuple)
5191 # Object method.
5192 # @note This method discards the data the destination feature (or
5193 # layer) does not support. Changes in data due to differences between
5194 # field types may also occur.
5195 #
5196 # @note The schema of the tuple needs to be the same as that of the
5197 # feature.
5198 #
5199 # Get and/set the data of the feature. The expected data in the tuple
5200 # is ([feature_id,] non-spatial fields, spatial fields). The fields in
5201 # the tuple are in the order they are in the schema. Field values are
5202 # set using the Geo::OGR::Feature::Field method. Geometries are set
5203 # and get using the Geo::OGR::Feature::Geometry method.
5204 # @param tuple [optional] feature data in an array
5205 # @return feature data in an array
5206 #*
5207 sub Tuple {
5208  my $self = shift;
5209  my $nf = $self->GetFieldCount;
5210  my $ngf = $self->GetGeomFieldCount;
5211  if (@_) {
5212  my $values = ref $_[0] ? $_[0] : \@_;
5213  my $FID;
5214  $FID = shift @$values if @$values == $nf + $ngf + 1;
5215  $self->SetFID($FID) if defined $FID;
5216  if (@$values != $nf + $ngf) {
5217  my $n = $nf + $ngf;
5218  error("Too many or too few attribute values for a feature (need $n).");
5219  }
5220  my $index = 0; # index to non-geometry and geometry fields
5221  for my $i (0..$nf-1) {
5222  $self->SetField($i, $values->[$i]);
5223  }
5224  for my $i (0..$ngf-1) {
5225  $self->Geometry($i, $values->[$nf+$i]);
5226  }
5227  }
5228  return unless defined wantarray;
5229  my @ret = ($self->GetFID);
5230  for my $i (0..$nf-1) {
5231  my $v = $self->GetField($i);
5232  push @ret, $v;
5233  }
5234  for my $i (0..$ngf-1) {
5235  my $v = $self->GetGeometry($i);
5236  push @ret, $v;
5237  }
5238  return @ret;
5239 }
5240 
5241 #** @method scalar Validate(list flags)
5242 # Object method.
5243 # @param flags one of more of null, geom_type, width,
5244 # allow_null_when_default, or all.
5245 # @exception croaks with an error message if the feature is not valid.
5246 # @return integer denoting the validity of the feature object.
5247 #*
5248 sub Validate {
5249  my $self = shift;
5250  my $flags = 0;
5251  for my $flag (@_) {
5252  my $f = eval '$Geo::OGR::'.uc($flag);
5253  $flags |= $f;
5254  }
5255  _Validate($self, $flags);
5256 }
5257 
5258 #** @method Geo::OGR::Feature new(%schema)
5259 # Class method.
5260 # @brief Create a new feature.
5261 # @param Named parameters:
5262 # - \a Schema a reference to a schema hash, or a Geo::OGR::Layer,
5263 # Geo::OGR::Feature, or Geo::OGR::FeatureDefn object.
5264 # - \a Values values for the feature attributes.
5265 # - \a StyleIgnored whether the style can be omitted when fetching
5266 # features. (default is false)
5267 #
5268 # Schema is a hash with the following keys:
5269 # - \a Name name of the schema (not used).
5270 # - \a Fields a list of Geo::OGR::FieldDefn or Geo::OGR::GeomFieldDefn
5271 # objects or references to hashes from which fields can be created.
5272 # - \a GeometryType the geometry type if the feature has only one spatial field.
5273 #
5274 # @note Do not mix GeometryType and geometry fields in Fields list.
5275 # @note Old syntax where the argument is a Geo::OGR::FeatureDefn
5276 # object or Schema hash is supported.
5277 #
5278 # @return a new Geo::OGR::Feature object.
5279 #*
5280 sub new {
5281  my $pkg = shift;
5282  my $arg;
5283  if (ref $_[0]) {
5284  if (ref $_[0] eq 'HASH' && $_[0]->{Schema}) {
5285  $arg = $_[0];
5286  } else {
5287  $arg = {Schema => $_[0]};
5288  }
5289  } elsif (@_ and @_ % 2 == 0) {
5290  %$arg = @_;
5291  unless ($arg->{Schema}) {
5292  my %tmp = @_;
5293  $arg->{Schema} = \%tmp;
5294  }
5295  } else {
5296  error("The argument must be either a schema or a hash.");
5297  }
5298  error("Missing schema.") unless $arg->{Schema};
5299  my $defn;
5300  for (ref $arg->{Schema}) {
5301  (/Geo::OGR::Layer$/ || /Geo::OGR::Feature$/) && do {
5302  $defn = $arg->{Schema}->GetDefn;
5303  last;
5304  };
5305  /Geo::OGR::FeatureDefn$/ && do {
5306  $defn = $arg->{Schema};
5307  last;
5308  };
5309  $defn = Geo::OGR::FeatureDefn->new($arg->{Schema});
5310  }
5311  my $self = Geo::OGRc::new_Feature($defn);
5312  error("Feature creation failed.") unless $self;
5313  bless $self, $pkg;
5314  for (ref $arg->{Values}) {
5315  /ARRAY/ && do {
5316  $self->Tuple($arg->{Values});
5317  last;
5318  };
5319  /HASH/ && do {
5320  $self->Row($arg->{Values});
5321  last;
5322  };
5323  /Geo::OGR::Feature$/ && do {
5324  $self->Tuple($arg->{Values}->Tuple);
5325  last;
5326  };
5327  /^$/ && do {
5328  last;
5329  };
5330  error("Value parameter must be an array, hash, or another feature. Not $_.");
5331  }
5332  return $self;
5333 }
5334 
5335 #** @class Geo::OGR::FeatureDefn
5336 # @brief The schema of a feature or a layer.
5337 # @details A FeatureDefn object is a collection of field definition objects. A
5338 # read-only FeatureDefn object can be obtained from a layer
5339 # (Geo::OGR::Layer::GetDefn()) or a feature
5340 # (Geo::OGR::Feature::GetDefn()).
5341 #*
5342 package Geo::OGR::FeatureDefn;
5343 
5344 use base qw(Geo::OGR)
5345 
5346 #** @method AddField(%params)
5347 # Object method.
5348 # @param params Named parameters to create a new Geo::OGR::FieldDefn
5349 # or Geo::OGR::GeomFieldDefn object.
5350 #*
5351 sub AddField {
5352  my $self = shift;
5353  error("Read-only definition.") if parent($self);
5354  my %params;
5355  if (@_ == 0) {
5356  } elsif (ref($_[0]) eq 'HASH') {
5357  %params = %{$_[0]};
5358  } elsif (@_ % 2 == 0) {
5359  %params = @_;
5360  }
5361  $params{Type} //= '';
5362  if (s_exists(field_type => $params{Type})) {
5363  my $fd = Geo::OGR::FieldDefn->new(%params);
5364  $self->AddFieldDefn($fd);
5365  } else {
5366  my $fd = Geo::OGR::GeomFieldDefn->new(%params);
5367  $self->AddGeomFieldDefn($fd);
5368  }
5369 }
5370 
5371 #** @method DeleteField($name)
5372 # Object method.
5373 # @note Currently only geometry fields can be deleted.
5374 # @param index the index of the geometry field to be deleted.
5375 #*
5376 sub DeleteField {
5377  my ($self, $name) = @_;
5378  error("Read-only definition.") if parent($self);
5379  for my $i (0..$self->GetFieldCount-1) {
5380  error("Non-spatial fields cannot be deleted.") if $self->_GetFieldDefn($i)->Name eq $name;
5381  }
5382  for my $i (0..$self->GetGeomFieldCount-1) {
5383  $self->DeleteGeomFieldDefn($i) if $self->_GetGeomFieldDefn($i)->Name eq $name;
5384  }
5385  error(2, $name, 'Field');
5386 }
5387 
5388 #** @method Feature()
5389 #*
5390 sub Feature {
5391  my $self = shift;
5392  return parent($self);
5393 }
5394 
5395 #** @method scalar GetFieldDefn($name)
5396 # Object method.
5397 # Get the definition of a field.
5398 # @param name the name of the field.
5399 # @return a Geo::OGR::FieldDefn object.
5400 #*
5401 sub GetFieldDefn {
5402  my $self = shift;
5403  my $field = $self->GetFieldIndex(shift);
5404  return $self->_GetFieldDefn($field);
5405 }
5406 
5407 #** @method list GetFieldNames()
5408 # Object method.
5409 # The names of the fields in this layer or feature definition.
5410 # @return the list of field names.
5411 #*
5412 sub GetFieldNames {
5413  my $self = shift;
5414  my @names = ();
5415  for my $i (0..$self->GetFieldCount-1) {
5416  push @names, $self->_GetFieldDefn($i)->Name;
5417  }
5418  for my $i (0..$self->GetGeomFieldCount-1) {
5419  push @names, $self->_GetGeomFieldDefn($i)->Name;
5420  }
5421  return @names;
5422 }
5423 
5424 #** @method scalar GetGeomFieldDefn($name)
5425 # Object method.
5426 # Get the definition of a spatial field.
5427 # @param name the name of the spatial field.
5428 # @return a Geo::OGR::GeomFieldDefn object.
5429 #*
5430 sub GetGeomFieldDefn {
5431  my $self = shift;
5432  my $field = $self->GetGeomFieldIndex(shift);
5433  return $self->_GetGeomFieldDefn($field);
5434 }
5435 
5436 #** @method scalar GetName()
5437 # Object method.
5438 # @return the name of this layer or feature definition.
5439 #*
5440 sub GetName {
5441 }
5442 
5443 #** @method hash reference GetSchema()
5444 # Object method.
5445 # @brief Get the schema of this feature or layer definition.
5446 #
5447 # @return the schema as a hash whose keywords are Name, StyleIgnored
5448 # and Fields. Fields is an anonymous array of first non-spatial and
5449 # then spatial field schemas as in Geo::OGR::FieldDefn::Schema() and
5450 # Geo::OGR::GeomFieldDefn::Schema().
5451 #*
5452 sub GetSchema {
5453  my $self = shift;
5454  carp "Schema of a feature definition should not be set directly." if @_;
5455  if (@_ and @_ % 2 == 0) {
5456  my %schema = @_;
5457  if ($schema{Fields}) {
5458  for my $field (@{$schema{Fields}}) {
5459  $self->AddField($field);
5460  }
5461  }
5462  }
5463  my %schema;
5464  $schema{Name} = $self->Name();
5465  $schema{StyleIgnored} = $self->StyleIgnored();
5466  $schema{Fields} = [];
5467  for my $i (0..$self->GetFieldCount-1) {
5468  my $s = $self->_GetFieldDefn($i)->Schema;
5469  push @{$schema{Fields}}, $s;
5470  }
5471  for my $i (0..$self->GetGeomFieldCount-1) {
5472  my $s = $self->_GetGeomFieldDefn($i)->Schema;
5473  push @{$schema{Fields}}, $s;
5474  }
5475  return wantarray ? %schema : \%schema;
5476 }
5477 
5478 #** @method IsSame(Geo::OGR::FeatureDefn defn)
5479 # Object method.
5480 # @return true if this definition is similar to the other definition,
5481 # false otherwise.
5482 #*
5483 sub IsSame {
5484 }
5485 
5486 #** @method scalar IsStyleIgnored()
5487 # Object method.
5488 # Get the ignore status of style information when fetching features.
5489 # @return the ignore status of style information
5490 # @since 1.9.0
5491 #*
5492 sub IsStyleIgnored {
5493 }
5494 
5495 #** @method SetStyleIgnored($IgnoreState)
5496 # Object method.
5497 # Set the ignore status of style information when fetching features.
5498 # @since 1.9.0
5499 #*
5500 sub SetStyleIgnored {
5501 }
5502 
5503 #** @method Geo::OGR::FeatureDefn new(%schema)
5504 # Class method.
5505 # Creates a new layer or feature definition. The new definition is
5506 # either initialized to the given schema or it will contain no
5507 # non-spatial fields and one spatial field, whose Name is '' and
5508 # GeometryType is 'Unknown' or the value of the named parameter
5509 # GeometryType.
5510 # @param schema [optional] The schema for the new feature definition,
5511 # as in Geo::OGR::FeatureDefn::Schema().
5512 # @return a Geo::OGR::FeatureDefn object
5513 #
5514 # Example usage:
5515 # \code
5516 # $fd = Geo::OGR::FeatureDefn->new(
5517 # Name => "name",
5518 # Fields => [{ Name => 'field1', Type => 'String' },
5519 # { Name => 'geom', GeometryType => 'Point' }] );
5520 # \endcode
5521 #*
5522 sub new {
5523  my $pkg = shift;
5524  my %schema;
5525  if (@_ == 1 and ref($_[0]) eq 'HASH') {
5526  %schema = %{$_[0]};
5527  } elsif (@_ and @_ % 2 == 0) {
5528  %schema = @_;
5529  }
5530  my $fields = $schema{Fields};
5531  error("The 'Fields' argument must be an array reference.") if $fields and ref($fields) ne 'ARRAY';
5532  $schema{Name} //= '';
5533  my $self = Geo::OGRc::new_FeatureDefn($schema{Name});
5534  bless $self, $pkg;
5535  my $gt = $schema{GeometryType};
5536  if ($gt) {
5537  $self->GeometryType($gt);
5538  } elsif ($fields) {
5539  $self->DeleteGeomFieldDefn(0);
5540  }
5541  $self->StyleIgnored($schema{StyleIgnored}) if exists $schema{StyleIgnored};
5542  for my $fd (@{$fields}) {
5543  my $d = $fd;
5544  if (ref($fd) eq 'HASH') {
5545  # if Name and Type are missing, assume Name => Type
5546  if (!(exists $fd->{Name} && exists $fd->{Type})) {
5547  for my $key (sort keys %$fd) {
5548  if (s_exists(field_type => $fd->{$key}) ||
5549  s_exists(geometry_type => $fd->{$key}))
5550  {
5551  $fd->{Name} = $key;
5552  $fd->{Type} = $fd->{$key};
5553  delete $fd->{$key};
5554  last;
5555  }
5556  }
5557  }
5558  if ($fd->{GeometryType} or ($fd->{Type} && s_exists(geometry_type => $fd->{Type}))) {
5559  $d = Geo::OGR::GeomFieldDefn->new(%$fd);
5560  } else {
5561  $d = Geo::OGR::FieldDefn->new(%$fd);
5562  }
5563  }
5564  if (blessed($d) and $d->isa('Geo::OGR::FieldDefn')) {
5565  AddFieldDefn($self, $d);
5566  } elsif (blessed($d) and $d->isa('Geo::OGR::GeomFieldDefn')) {
5567  error("Do not mix GeometryType and geometry fields in Fields.") if $gt;
5568  AddGeomFieldDefn($self, $d);
5569  } else {
5570  error("Item in field list does not define a field.");
5571  }
5572  }
5573  return $self;
5574 }
5575 
5576 #** @class Geo::OGR::FieldDefn
5577 # @brief A definition of a non-spatial attribute.
5578 # @details
5579 #*
5580 package Geo::OGR::FieldDefn;
5581 
5582 use base qw(Geo::OGR)
5583 
5584 #** @method scalar Default($value)
5585 # Object method.
5586 # Get or set the default value for this field.
5587 # @note a.k.a. GetDefault and SetDefault
5588 # @param value [optional]
5589 # @return the default value of this field in non-void context.
5590 #*
5591 sub Default {
5592  my $self = shift;
5593  SetDefault($self, $_[0]) if @_;
5594  GetDefault($self) if defined wantarray;
5595 }
5596 
5597 #** @method GetAlternativeName()
5598 #*
5599 sub GetAlternativeName {
5600 }
5601 
5602 #** @method GetAlternativeNameRef()
5603 #*
5604 sub GetAlternativeNameRef {
5605 }
5606 
5607 #** @method GetSchema()
5608 #*
5609 sub GetSchema {
5610 }
5611 
5612 #** @method scalar Ignored($ignore)
5613 # Object method.
5614 # Get and/or set the ignore status (whether this field should be
5615 # omitted when fetching features) of this field.
5616 # @note a.k.a. IsIgnored, SetIgnored
5617 # @param ignore [optional]
5618 # @return the ignore status of this field in non-void context.
5619 # @since 1.9.0
5620 #*
5621 sub Ignored {
5622  my $self = shift;
5623  SetIgnored($self, $_[0]) if @_;
5624  IsIgnored($self) if defined wantarray;
5625 }
5626 
5627 #** @method IsDefaultDriverSpecific()
5628 #*
5629 sub IsDefaultDriverSpecific {
5630 }
5631 
5632 #** @method IsUnique()
5633 #*
5634 sub IsUnique {
5635 }
5636 
5637 #** @method scalar Justify($justify)
5638 # Object method.
5639 # Get and/or set the justification of this field.
5640 # @note a.k.a. GetJustify, SetJustify
5641 # @param justify [optional] One of field justify types (Geo::OGR::FieldDefn::JustifyValues).
5642 # @return the justify value of this field in non-void context.
5643 #*
5644 sub Justify {
5645  my($self, $justify) = @_;
5646  if (defined $justify) {
5647  $justify = s2i(justify => $justify);
5648  SetJustify($self, $justify);
5649  }
5650  return i2s(justify => GetJustify($self)) if defined wantarray;
5651 }
5652 
5653 #** @method list JustifyValues()
5654 # Package subroutine.
5655 # Justify values supported by GDAL. Current list is
5656 # Left, Right, and Undefined.
5657 #*
5658 sub JustifyValues {
5659  return @JUSTIFY;
5660 }
5661 
5662 #** @method scalar Name($name)
5663 # Object method.
5664 # Get and/or set the name of the field.
5665 # @note a.k.a. GetName, GetNameRef, SetName
5666 # @param name [optional]
5667 # @return the name in non-void context
5668 #*
5669 sub Name {
5670  my $self = shift;
5671  SetName($self, $_[0]) if @_;
5672  GetName($self) if defined wantarray;
5673 }
5674 
5675 #** @method scalar Nullable($nullable)
5676 # Object method.
5677 # Get or set the nullable constraint for this field.
5678 # @note a.k.a. IsNullable and SetNullable
5679 # @param nullable [optional]
5680 # @return the nullable value of this field in non-void context.
5681 #*
5682 sub Nullable {
5683  my $self = shift;
5684  SetNullable($self, $_[0]) if @_;
5685  IsNullable($self) if defined wantarray;
5686 }
5687 
5688 #** @method scalar Precision($precision)
5689 # Object method.
5690 # Get and/or set the precision of this field.
5691 # @note a.k.a. GetPrecision, SetPrecision
5692 # @param precision [optional]
5693 # @return the precision of this field in non-void context.
5694 #*
5695 sub Precision {
5696  my $self = shift;
5697  SetPrecision($self, $_[0]) if @_;
5698  GetPrecision($self) if defined wantarray;
5699 }
5700 
5701 #** @method hash reference Schema(%params)
5702 # Object method.
5703 # Get the schema or set parts of the schema
5704 # @param params [optional] as those in Geo::OGR::FieldDefn::new.
5705 # @return a reference to a hash whose keys are as those in Geo::OGR::FieldDefn::new.
5706 #*
5707 sub Schema {
5708  my $self = shift;
5709  if (@_) {
5710  my $params = @_ % 2 == 0 ? {@_} : shift;
5711  for my $key (keys %SCHEMA_KEYS) {
5712  next unless exists $params->{$key};
5713  eval "\$self->$key(\$params->{$key})";
5714  confess(last_error()) if $@;
5715  }
5716  }
5717  return unless defined wantarray;
5718  my %schema = ();
5719  for my $key (keys %SCHEMA_KEYS) {
5720  $schema{$key} = eval '$self->'.$key;
5721  }
5722  return wantarray ? %schema : \%schema;
5723 }
5724 
5725 #** @method SetAlternativeName()
5726 #*
5727 sub SetAlternativeName {
5728 }
5729 
5730 #** @method SetSchema()
5731 #*
5732 sub SetSchema {
5733 }
5734 
5735 #** @method SetUnique()
5736 #*
5737 sub SetUnique {
5738 }
5739 
5740 #** @method scalar SubType($SubType)
5741 # Object method.
5742 # @note a.k.a. GetSubType, SetSubType
5743 # @param SubType [optional] One of field sub types (Geo::OGR::FieldDefn::SubTypes).
5744 # @return the sub type of this field in non-void context.
5745 #*
5746 sub SubType {
5747  my($self, $subtype) = @_;
5748  if (defined $subtype) {
5749  $subtype = s2i(field_subtype => $subtype);
5750  SetSubType($self, $subtype);
5751  }
5752  return i2s(field_subtype => GetSubType($self)) if defined wantarray;
5753 }
5754 
5755 #** @method SubTypes()
5756 #*
5757 sub SubTypes {
5758  return @SUBTYPES;
5759 }
5760 
5761 #** @method scalar Type($type)
5762 # Object method.
5763 # Get and/or set the type of the field.
5764 # @note a.k.a. GetFieldTypeName, GetTypeName, GetType, SetType
5765 # @param type [optional] One of field types (Geo::OGR::FieldDefn::Types).
5766 # @return one of field types in non-void context.
5767 #*
5768 sub Type {
5769  my($self, $type) = @_;
5770  if (defined $type) {
5771  $type = s2i(field_type => $type);
5772  SetType($self, $type);
5773  }
5774  return i2s(field_type => GetType($self)) if defined wantarray;
5775 }
5776 
5777 #** @method list Types()
5778 # Package subroutine.
5779 # Field types supported by GDAL. Current list is
5780 # Binary, Date, DateTime, Integer, Integer64, Integer64List, IntegerList, Real, RealList, String, StringList, Time, WideString, and WideStringList.
5781 # (However, WideString is not supported.)
5782 #*
5783 sub Types {
5784  return @TYPES;
5785 }
5786 
5787 #** @method scalar Width($width)
5788 # Object method.
5789 # Get and/or set the field width.
5790 # @note a.k.a. GetWidth, SetWidth
5791 # @param width [optional]
5792 # @return the width of this field in non-void context.
5793 #*
5794 sub Width {
5795  my $self = shift;
5796  SetWidth($self, $_[0]) if @_;
5797  GetWidth($self) if defined wantarray;
5798 }
5799 
5800 #** @method Geo::OGR::FieldDefn new(%params)
5801 # Class method.
5802 # @brief Create a new field definition.
5803 #
5804 # @param Named parameters:
5805 # - \a Name Field name (default is 'unnamed').
5806 # - \a Type Field type, one of Geo::OGR::FieldDefn::Types (default is 'String').
5807 # - \a SubType Field sub type, one of Geo::OGR::FieldDefn::SubTypes.
5808 # - \a Justify Justify value, one of Geo::OGR::FieldDefn::JustifyValues
5809 # - \a Width
5810 # - \a Precision
5811 # - \a Nullable (default is true)
5812 # - \a Default
5813 # - \a Ignored (default is false)
5814 #
5815 # @note Simplified parameters Name => 'Type' are also supported.
5816 #
5817 # @return a new Geo::OGR::FieldDefn object
5818 #*
5819 sub new {
5820  my $pkg = shift;
5821  my $params = {Name => 'unnamed', Type => 'String'};
5822  if (@_ == 0) {
5823  } elsif (@_ == 1 and not ref $_[0]) {
5824  $params->{Name} = shift;
5825  } elsif (@_ == 2 and not $Geo::OGR::FieldDefn::SCHEMA_KEYS{$_[0]}) {
5826  $params->{Name} = shift;
5827  $params->{Type} = shift;
5828  } else {
5829  my $tmp = @_ % 2 == 0 ? {@_} : shift;
5830  for my $key (keys %$tmp) {
5831  if ($Geo::OGR::FieldDefn::SCHEMA_KEYS{$key}) {
5832  $params->{$key} = $tmp->{$key};
5833  } else {
5834  carp "Unknown parameter: '$key'." if $key ne 'Index';
5835  }
5836  }
5837  }
5838  $params->{Type} = s2i(field_type => $params->{Type});
5839  my $self = Geo::OGRc::new_FieldDefn($params->{Name}, $params->{Type});
5840  bless $self, $pkg;
5841  delete $params->{Name};
5842  delete $params->{Type};
5843  $self->Schema($params);
5844  return $self;
5845 }
5846 
5847 #** @class Geo::OGR::GeomFieldDefn
5848 # @brief A definition of a spatial attribute.
5849 # @details
5850 #*
5851 package Geo::OGR::GeomFieldDefn;
5852 
5853 use base qw(Geo::OGR)
5854 
5855 #** @method scalar GeometryType($type)
5856 # Object method.
5857 # @note a.k.a. GetType, SetType
5858 # @return the geometry type of the field.
5859 #*
5860 sub GeometryType {
5861 }
5862 
5863 #** @method GetSchema()
5864 #*
5865 sub GetSchema {
5866 }
5867 
5868 #** @method scalar Ignored($ignore)
5869 # Object method.
5870 # @note a.k.a. IsIgnored, SetIgnored
5871 # @return the ignore status of the field.
5872 #*
5873 sub Ignored {
5874  my $self = shift;
5875  SetIgnored($self, $_[0]) if @_;
5876  IsIgnored($self) if defined wantarray;
5877 }
5878 
5879 #** @method scalar Name($name)
5880 # Object method.
5881 # @note a.k.a. GetName, GetNameRef, SetName
5882 # @return the name of the field.
5883 #*
5884 sub Name {
5885  my $self = shift;
5886  SetName($self, $_[0]) if @_;
5887  GetName($self) if defined wantarray;
5888 }
5889 
5890 #** @method scalar Nullable($nullable)
5891 # Object method.
5892 # @note a.k.a. IsNullable, SetNullable
5893 # @return the nullable status of the field.
5894 #*
5895 sub Nullable {
5896  my $self = shift;
5897  SetNullable($self, $_[0]) if @_;
5898  IsNullable($self) if defined wantarray;
5899 }
5900 
5901 #** @method hash reference Schema(%params)
5902 # Object method.
5903 # Get the schema or set parts of the schema.
5904 # @param params [optional] as those in Geo::OGR::GeomFieldDefn::new.
5905 # @return a reference to a hash whose keys are as those in Geo::OGR::GeomFieldDefn::new.
5906 #*
5907 sub Schema {
5908  my $self = shift;
5909  if (@_) {
5910  my $params = @_ % 2 == 0 ? {@_} : shift;
5911  for my $key (keys %SCHEMA_KEYS) {
5912  next unless exists $params->{$key};
5913  eval "\$self->$key(\$params->{$key})";
5914  confess last_error() if $@;
5915  }
5916  }
5917  return unless defined wantarray;
5918  my %schema = ();
5919  for my $key (keys %SCHEMA_KEYS) {
5920  $schema{$key} = eval '$self->'.$key;
5921  }
5922  return wantarray ? %schema : \%schema;
5923 }
5924 
5925 #** @method SetSchema()
5926 #*
5927 sub SetSchema {
5928 }
5929 
5930 #** @method scalar SpatialReference($sr)
5931 # Object method.
5932 # @note a.k.a. GetSpatialRef, SetSpatialRef
5933 # @return the spatial reference of the field as a Geo::OSR::SpatialReference object.
5934 #*
5935 sub SpatialReference {
5936  my $self = shift;
5937  SetSpatialRef($self, $_[0]) if @_;
5938  GetSpatialRef($self) if defined wantarray;
5939 }
5941 #** @method Type()
5942 # Object method.
5943 # @return the type of this geometry field. One of Geo::OGR::GeomFieldDefn::Types
5944 #*
5945 sub Type {
5946  my($self, $type) = @_;
5947  if (defined $type) {
5948  $type = s2i(geometry_type => $type);
5949  SetType($self, $type);
5950  }
5951  i2s(geometry_type => GetType($self)) if defined wantarray;
5952 }
5953 
5954 #** @method Types()
5955 # Package subroutine.
5956 # @return a list of all geometry types, currently:
5957 # 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.
5958 #*
5959 sub Types {
5961 }
5962 
5963 #** @method Geo::OGR::GeomFieldDefn new(%params)
5964 # Class method.
5965 # @brief Create a new spatial field definition.
5966 #
5967 # @param params one or more of:
5968 # - \a Name name for the field (default is 'geom').
5969 # - \a GeometryType type for the field type, one of Geo::OGR::GeomFieldDefn::Types (default is 'Unknown').
5970 # - \a SpatialReference a Geo::OSR::SpatialReference object.
5971 # - \a Nullable (default is true)
5972 # - \a Ignored (default is false)
5973 #
5974 # @note Simplified parameters <name> => <type> is also supported.
5975 #
5976 # @return a new Geo::OGR::GeomFieldDefn object
5977 #*
5978 sub new {
5979  my $pkg = shift;
5980  my $params = {Name => 'geom', Type => 'Unknown'};
5981  if (@_ == 0) {
5982  } elsif (@_ == 1) {
5983  $params->{Name} = shift;
5984  } elsif (@_ == 2 and not $Geo::OGR::GeomFieldDefn::SCHEMA_KEYS{$_[0]}) {
5985  $params->{Name} = shift;
5986  $params->{Type} = shift;
5987  } else {
5988  my $tmp = @_ % 2 == 0 ? {@_} : shift;
5989  for my $key (keys %$tmp) {
5990  if ($Geo::OGR::GeomFieldDefn::SCHEMA_KEYS{$key}) {
5991  $params->{$key} = $tmp->{$key};
5992  } else {
5993  carp "Unknown parameter: '$key'." if $key ne 'Index' && $key ne 'GeometryType';
5994  }
5995  }
5996  $params->{Type} //= $tmp->{GeometryType};
5997  }
5998  $params->{Type} = s2i(geometry_type => $params->{Type});
5999  my $self = Geo::OGRc::new_GeomFieldDefn($params->{Name}, $params->{Type});
6000  bless $self, $pkg;
6001  delete $params->{Name};
6002  delete $params->{Type};
6003  $self->Schema($params);
6004  return $self;
6005 }
6006 
6007 #** @class Geo::OGR::GeomTransformer
6008 #*
6009 package Geo::OGR::GeomTransformer;
6010 
6011 use base qw(Geo::OGR)
6012 
6013 #** @method Transform()
6014 #*
6015 sub Transform {
6016 }
6017 
6018 #** @method new()
6019 #*
6020 sub new {
6021  my $pkg = shift;
6022  my $self = Geo::OGRc::new_GeomTransformer(@_);
6023  bless $self, $pkg if defined($self);
6024 }
6025 
6026 #** @class Geo::OGR::Geometry
6027 # @brief Spatial data.
6028 # @details A geometry is spatial data (coordinate values, and a reference to a
6029 # spatial reference system) organized into one of the geometry
6030 # types. Geometries can be created from several type of data including
6031 # a Perl data structure. There are several methods, which modify,
6032 # compare, test, or compute values from geometries.
6033 # @note Most spatial analysis methods require <a
6034 # href="http://geos.osgeo.org/doxygen/">GEOS</a> to work rigorously.
6035 #*
6036 package Geo::OGR::Geometry;
6037 
6038 use base qw(Geo::OGR)
6039 
6040 #** @method AddGeometry($other)
6041 # Object method.
6042 # Add a copy of another geometry to a geometry collection
6043 # @param other a Geo::OGR::Geometry object
6044 #*
6045 sub AddGeometry {
6046 }
6047 
6048 #** @method AddGeometryDirectly($other)
6049 # Object method.
6050 # @param other a Geo::OGR::Geometry object
6051 #*
6052 sub AddGeometryDirectly {
6053 }
6054 
6055 #** @method AddPoint($x, $y, $z)
6056 # Object method.
6057 # Set the data of a point or add a point to a line string. Consider
6058 # using Geo::OGR::Geometry::Points. Note that the coordinate
6059 # dimension is automatically upgraded to 25D (3) if z is given.
6060 # @param x
6061 # @param y
6062 # @param z [optional]
6063 # Calls internally the 2D or 3D version depending on the number of parameters.
6064 #*
6065 sub AddPoint {
6066  my $self = shift;
6067  my $t = $self->GetGeometryType;
6068  my $has_z = HasZ($t);
6069  my $has_m = HasM($t);
6070  if (!$has_z && !$has_m) {
6071  $self->AddPoint_2D(@_[0..1]);
6072  } elsif ($has_z && !$has_m) {
6073  $self->AddPoint_3D(@_[0..2]);
6074  } elsif (!$has_z && $has_m) {
6075  $self->AddPointM(@_[0..2]);
6076  } else {
6077  $self->AddPointZM(@_[0..3]);
6078  }
6079 }
6080 
6081 #** @method AddPointM()
6082 #*
6083 sub AddPointM {
6084 }
6085 
6086 #** @method AddPointZM()
6087 #*
6088 sub AddPointZM {
6089 }
6090 
6091 #** @method AddPoint_2D($x, $y)
6092 # Object method.
6093 # Set the data of a point or add a point to a line string. Consider
6094 # using Geo::OGR::Geometry::Points.
6095 # @param x
6096 # @param y
6097 #*
6098 sub AddPoint_2D {
6099 }
6100 
6101 #** @method AddPoint_3D($x, $y, $z)
6102 # Object method.
6103 # Set the data of a point or add a point to a line string. Note that
6104 # the coordinate dimension is automatically upgraded to 25D (3). Consider
6105 # using Geo::OGR::Geometry::Points.
6106 # @param x
6107 # @param y
6108 # @param z
6109 #*
6110 sub AddPoint_3D {
6111 }
6112 
6113 #** @method Geo::OGR::Geometry ApproximateArcAngles(%params)
6114 # Package subroutine.
6115 # Create a line string, which approximates an arc.
6116 # @note All angles are in degrees.
6117 #
6118 # @param %params Named parameters:
6119 # - \a Center center point (default is [0, 0, 0])
6120 # - \a PrimaryRadius default is 1.
6121 # - \a SecondaryAxis default is 1.
6122 # - \a Rotation default is 0.
6123 # - \a StartAngle default is 0.
6124 # - \a EndAngle default is 360.
6125 # - \a MaxAngleStepSizeDegrees default is 4.
6126 # @return a new Geo::OGR::Geometry object.
6127 #*
6128 sub ApproximateArcAngles {
6129  my %p = @_;
6130  my %default = ( Center => [0,0,0],
6131  PrimaryRadius => 1,
6132  SecondaryAxis => 1,
6133  Rotation => 0,
6134  StartAngle => 0,
6135  EndAngle => 360,
6136  MaxAngleStepSizeDegrees => 4
6137  );
6138  for my $p (keys %p) {
6139  if (exists $default{$p}) {
6140  $p{$p} //= $default{$p};
6141  } else {
6142  carp "Unknown parameter: '$p'.";
6143  }
6144  }
6145  for my $p (keys %default) {
6146  $p{$p} //= $default{$p};
6147  }
6148  error("Usage: Center => [x,y,z].") unless ref($p{Center}) eq 'ARRAY';
6149  for my $i (0..2) {
6150  $p{Center}->[$i] //= 0;
6151  }
6152  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});
6153 }
6154 
6155 #** @method scalar Area()
6156 # Object method.
6157 # @note a.k.a. GetArea
6158 # @return the area of the polygon or multipolygon
6159 #*
6160 sub Area {
6161 }
6162 
6163 #** @method scalar As(%params)
6164 # Object method.
6165 # Export the geometry into a known format.
6166 #
6167 # @param params Named parameters:
6168 # - \a Format One of
6169 # - \a WKT Well Known Text.
6170 # - <em>ISO WKT</em>
6171 # - \a Text Same as WKT.
6172 # - \a WKB Well Known Binary.
6173 # - <em>ISO WKB</em>
6174 # - \a Binary Same as WKB.
6175 # - \a HEXWKB
6176 # - \a HEXEWKB
6177 # - \a GML
6178 # - \a GeoJSON
6179 # - \a ByteOrder Byte order for binary formats. Default is 'XDR'.
6180 # - \a SRID Spatial reference id for HEXEWKB.
6181 # - \a Options GML generation options.
6182 # - \a AltitudeMode For KML.
6183 #
6184 # @return the geometry in a given format.
6185 #*
6186 sub As {
6187  my $self = shift;
6188  my $p = named_parameters(\@_, Format => undef, ByteOrder => 'XDR', SRID => undef, Options => undef, AltitudeMode => undef);
6189  my $f = $p->{format};
6190  if ($f =~ /text/i) {
6191  return $self->AsText;
6192  } elsif ($f =~ /wkt/i) {
6193  if ($f =~ /iso/i) {
6194  return $self->ExportToIsoWkt;
6195  } else {
6196  return $self->AsText;
6197  }
6198  } elsif ($f =~ /binary/i) {
6199  return $self->ExportToWkb($p->{byteorder});
6200  } elsif ($f =~ /wkb/i) {
6201  if ($f =~ /iso/i) {
6202  $p->{byteorder} = s2i(byte_order => $p->{byteorder});
6203  return $self->ExportToIsoWkb($p->{byteorder});
6204  } elsif ($f =~ /ewkb/i) {
6205  return $self->AsHEXEWKB($p->{srid});
6206  } elsif ($f =~ /hex/i) {
6207  return $self->AsHEXWKB;
6208  } else {
6209  return $self->ExportToWkb($p->{byteorder});
6210  }
6211  } elsif ($f =~ /gml/i) {
6212  return $self->ExportToGML($p->{options});
6213  } elsif ($f =~ /kml/i) {
6214  return $self->ExportToKML($p->{altitudemode});
6215  } elsif ($f =~ /json/i) {
6216  return $self->AsJSON;
6217  } else {
6218  error(1, $f, map {$_=>1} qw/Text WKT ISO_WKT ISO_WKB HEX_WKB HEX_EWKB Binary GML KML JSON/);
6219  }
6220 }
6221 
6222 #** @method scalar AsBinary()
6223 # Object method.
6224 # Export the geometry into WKB.
6225 # @sa Geo::OGR::Geometry::As
6226 # @return the geometry as WKB.
6227 #*
6228 sub AsBinary {
6229 }
6230 
6231 #** @method scalar AsText()
6232 # Object method.
6233 # Export the geometry into WKT.
6234 # @sa Geo::OGR::Geometry::As
6235 # @return the geometry as WKT.
6236 #*
6237 sub AsText {
6238 }
6239 
6240 #** @method AssignSpatialReference($srs)
6241 # Object method.
6242 # @param srs a Geo::OSR::SpatialReference object
6243 #*
6244 sub AssignSpatialReference {
6245 }
6246 
6247 #** @method Geo::OGR::Geometry Boundary()
6248 # Object method.
6249 # @note a.k.a. GetBoundary
6250 # @return the boundary of this geometry as a geometry
6251 # @since 1.8.0
6252 #*
6253 sub Boundary {
6254 }
6255 
6256 #** @method Geo::OGR::Geometry Buffer($distance, $quadsecs = 30)
6257 # Object method.
6258 # @param distance
6259 # @param quadsecs
6260 # @return a new Geo::OGR::Geometry object
6261 #*
6262 sub Buffer {
6263 }
6264 
6265 #** @method Geo::OGR::Geometry BuildPolygonFromEdges($BestEffort = 0, $AutoClose = 0, $Tolerance = 0)
6266 # Object method.
6267 # Attempt to create a polygon from a collection of lines or from a multilinestring.
6268 # @param BestEffort For future
6269 # @param AutoClose Assure the first and last points of rings are same.
6270 # @param Tolerance Snap distance.
6271 # @exception Several possibilities, some are reported, some are general errors.
6272 # @return a new Geo::OGR::Geometry object (Polygon)
6273 #*
6274 sub BuildPolygonFromEdges {
6275 }
6276 
6277 #** @method list ByteOrders()
6278 # Package subroutine.
6279 # Same as Geo::OGR::ByteOrders
6280 #*
6281 sub ByteOrders {
6282  return @BYTE_ORDER_TYPES;
6283 }
6284 
6285 #** @method Geo::OGR::Geometry Centroid()
6286 # Object method.
6287 # @return a new Geo::OGR::Geometry object
6288 # @since 1.8.0
6289 #*
6290 sub Centroid {
6291 }
6292 
6293 #** @method Geo::OGR::Geometry Clone()
6294 # Object method.
6295 # @return a new Geo::OGR::Geometry object
6296 #*
6297 sub Clone {
6298 }
6299 
6300 #** @method CloseRings()
6301 # Object method.
6302 #*
6303 sub CloseRings {
6304 }
6305 
6306 #** @method Geo::OGR::Geometry Collect(@geometries)
6307 # Object method.
6308 # Create a geometrycollection from this and possibly other geometries.
6309 # @param geometries [optional] More geometries to add to the collection.
6310 # @return a new Geo::OGR::Geometry object of type geometrycollection.
6311 #*
6312 sub Collect {
6313 }
6314 
6315 #** @method scalar Contains($other)
6316 # Object method.
6317 # @param other a Geo::OGR::Geometry object
6318 # @return true if this geometry contains the other geometry, false otherwise
6319 #*
6320 sub Contains {
6321 }
6322 
6323 #** @method Geo::OGR::Geometry ConvexHull()
6324 # Object method.
6325 # @return a new Geo::OGR::Geometry object
6326 #*
6327 sub ConvexHull {
6328 }
6329 
6330 #** @method scalar CoordinateDimension($dimension)
6331 # Object method.
6332 # @param dimension [optional]
6333 # @return 2 or 3
6334 #*
6335 sub CoordinateDimension {
6336  my $self = shift;
6337  SetCoordinateDimension($self, $_[0]) if @_;
6338  GetCoordinateDimension($self) if defined wantarray;
6339 }
6340 
6341 #** @method scalar Crosses($other)
6342 # Object method.
6343 # @param other a Geo::OGR::Geometry object
6344 # @return true if this geometry crosses the other geometry, false otherwise
6345 #*
6346 sub Crosses {
6347 }
6348 
6349 #** @method DelaunayTriangulation()
6350 #*
6351 sub DelaunayTriangulation {
6352 }
6353 
6354 #** @method Geo::OGR::Geometry Difference($other)
6355 # Object method.
6356 # @param other a Geo::OGR::Geometry object
6357 # @return a new Geo::OGR::Geometry object
6358 #*
6359 sub Difference {
6360 }
6361 
6362 #** @method scalar Disjoint($other)
6363 # Object method.
6364 # @param other a Geo::OGR::Geometry object
6365 # @return true if this geometry is disjoint from the other geometry, false otherwise
6366 #*
6367 sub Disjoint {
6368 }
6369 
6370 #** @method list Dissolve()
6371 # Object method.
6372 # Dissolve a geometrycollection into separate geometries.
6373 # @return a list of new Geo::OGR::Geometry objects cloned from the collection.
6374 #*
6375 sub Dissolve {
6376  my $self = shift;
6377  my @c;
6378  my $n = $self->GetGeometryCount;
6379  if ($n > 0) {
6380  for my $i (0..$n-1) {
6381  push @c, $self->GetGeometryRef($i)->Clone;
6382  }
6383  } else {
6384  push @c, $self;
6385  }
6386  return @c;
6387 }
6388 
6389 #** @method scalar Distance($other)
6390 # Object method.
6391 # @param other a Geo::OGR::Geometry object
6392 # @return the distance to the other geometry
6393 #*
6394 sub Distance {
6395 }
6396 
6397 #** @method Distance3D()
6398 #*
6399 sub Distance3D {
6400 }
6401 
6402 #** @method Empty()
6403 # Object method.
6404 # Clear geometry data, i.e., remove all points, or, for a point, set
6405 # the coordinate dimension as zero.
6406 #*
6407 sub Empty {
6408 }
6409 
6410 #** @method scalar Equals($other)
6411 # Object method.
6412 # @note a.k.a. Equal (deprecated)
6413 # @param other a Geo::OGR::Geometry object
6414 # @return true if this geometry is equivalent to the other geometry, false otherwise
6415 #*
6416 sub Equals {
6417 }
6418 
6419 #** @method Extent()
6420 #*
6421 sub Extent {
6422  my $self = shift;
6423  return Geo::GDAL::Extent->new($self->GetEnvelope);
6424 }
6425 
6426 #** @method Feature()
6427 #*
6428 sub Feature {
6429  my $self = shift;
6430  parent($self);
6431 }
6432 
6433 #** @method FlattenTo2D()
6434 # Object method.
6435 #*
6436 sub FlattenTo2D {
6437 }
6438 
6439 #** @method Geo::OGR::Geometry ForceTo($type, ref options)
6440 # Object method.
6441 # Attempt to make a geometry of type 'type' out of this geometry.
6442 # @param type target geometry type. One of Geo::OGR::GeometryTypes.
6443 # @param options not used currently.
6444 # @return a new Geo::OGR::Geometry object.
6445 #*
6446 sub ForceTo {
6447  my $self = shift;
6448  my $type = shift;
6449  $type = s2i(geometry_type => $type);
6450  eval {
6451  $self = Geo::OGR::ForceTo($self, $type, @_);
6452  };
6453  confess last_error() if $@;
6454  return $self;
6456 
6457 #** @method Geo::OGR::Geometry ForceToCollection(@geometries)
6458 # Object method.
6459 # Create a geometrycollection from the geometry.
6460 # @param geometries [optional] More geometries to add to the collection.
6461 # @return a new Geo::OGR::Geometry object of type geometrycollection.
6462 #*
6463 sub ForceToCollection {
6464  my $self = Geo::OGR::Geometry->new(GeometryType => 'GeometryCollection');
6465  for my $g (@_) {
6466  $self->AddGeometry($g);
6467  }
6468  return $self;
6469 }
6470 
6471 #** @method Geo::OGR::Geometry ForceToLineString()
6472 # Object method.
6473 # Attempt to create a line string from this geometry.
6474 # @return a new Geo::OGR::Geometry object.
6475 #*
6476 sub ForceToLineString {
6477  my $self = shift;
6478  return Geo::OGR::ForceToLineString($self);
6479 }
6480 
6481 #** @method Geo::OGR::Geometry ForceToMultiLineString(@linestrings)
6482 # Object method.
6483 # Attempt to create a multilinestring from the geometry, which must be a linestring.
6484 # @param linestrings [optional] More linestrings to add to the collection.
6485 # @return a new Geo::OGR::Geometry object of type multilinestring.
6486 #*
6487 sub ForceToMultiLineString {
6488  my $self = shift;
6489  $self = Geo::OGR::ForceToMultiLineString($self);
6490  for my $g (@_) {
6491  $self->AddGeometry($g);
6492  }
6493  return $self;
6494 }
6495 
6496 #** @method Geo::OGR::Geometry ForceToMultiPoint(@points)
6497 # Object method.
6498 # Attempt to create a multipoint from the geometry, which must be a point.
6499 # @param points [optional] More points to add to the collection.
6500 # @return a new Geo::OGR::Geometry object of type multipoint.
6501 #*
6502 sub ForceToMultiPoint {
6503  my $self = shift;
6504  $self = Geo::OGR::ForceToMultiPoint($self);
6505  for my $g (@_) {
6506  $self->AddGeometry($g);
6507  }
6508  return $self;
6509 }
6510 
6511 #** @method Geo::OGR::Geometry ForceToMultiPolygon(@polygons)
6512 # Object method.
6513 # Attempt to create a multipolygon from the geometry, which must be a polygon.
6514 # @param polygons [optional] More polygons to add to the collection.
6515 # @return a new Geo::OGR::Geometry object of type multipolygon.
6516 #*
6517 sub ForceToMultiPolygon {
6518  my $self = shift;
6519  $self = Geo::OGR::ForceToMultiPolygon($self);
6520  for my $g (@_) {
6521  $self->AddGeometry($g);
6522  }
6523  return $self;
6524 }
6525 
6526 #** @method Geo::OGR::Geometry ForceToPolygon()
6527 # Object method.
6528 # Attempt to create a polygon from this geometry.
6529 # @exception None reported. If this method fails, just a copy is returned.
6530 # @return a new Geo::OGR::Geometry object.
6531 #*
6532 sub ForceToPolygon {
6533 }
6534 
6535 #** @method scalar Geometry($n)
6536 # Object method.
6537 # Return the n:th (note zero-based index) element in this geometry or
6538 # geometry in this collection.
6539 # @note a.k.a. GetGeometryRef
6540 # @param n index to the geometry, which is a part of this geometry
6541 # @return a new Geo::OGR::Geometry object whose data is a part of the
6542 # parent geometry (this geometry is kept alive while the returned
6543 # geometry exists)
6544 #*
6545 sub Geometry {
6546 }
6547 
6548 #** @method scalar GeometryCount()
6549 # Object method.
6550 # Return the number of elements in this geometry or geometries in this collection.
6551 # @note a.k.a. GetGeometryCount
6552 # @return an integer
6553 #*
6554 sub GeometryCount {
6555 }
6556 
6557 #** @method scalar GeometryType()
6558 # Object method.
6559 #
6560 # @note The deprecated method GetGeometryType returns the
6561 # type as an integer
6562 #
6563 # @return the geometry type of this geometry (one of Geo::OGR::GeometryTypes).
6564 #*
6565 sub GeometryType {
6566  my $self = shift;
6567  return i2s(geometry_type => $self->GetGeometryType);
6568 }
6569 
6570 #** @method list GeometryTypes()
6571 # Package subroutine.
6572 # Same as Geo::OGR::GeometryTypes
6573 #*
6574 sub GeometryTypes {
6575  return @GEOMETRY_TYPES;
6576 }
6577 
6578 #** @method scalar GetCoordinateDimension()
6579 # Object method.
6580 # @return an integer
6581 #*
6582 sub GetCoordinateDimension {
6583 }
6584 
6585 #** @method GetCurveGeometry()
6586 #*
6587 sub GetCurveGeometry {
6588 }
6589 
6590 #** @method scalar GetDimension()
6591 # Object method.
6592 # @return 0, 1, or 2
6593 #*
6594 sub GetDimension {
6595 }
6596 
6597 #** @method list GetEnvelope()
6598 # Object method.
6599 # @note In scalar context returns a reference to an anonymous array
6600 # containing the envelope.
6601 # @return the envelope ($minx, $maxx, $miny, $maxy)
6602 #*
6603 sub GetEnvelope {
6604 }
6605 
6606 #** @method list GetEnvelope3D()
6607 # Object method.
6608 # @note In scalar context returns a reference to an anonymous array
6609 # containing the envelope.
6610 # @return the 3-D envelope ($minx, $maxx, $miny, $maxy, $minz, $maxz)
6611 # @since 1.9.0
6612 #*
6613 sub GetEnvelope3D {
6614 }
6615 
6616 #** @method scalar GetGeometryRef($index)
6617 # Object method.
6618 # @deprecated Use Geo::OGR::Geometry
6619 #*
6620 sub GetGeometryRef {
6621  my ($self, $i) = @_;
6622  my $ref = $self->_GetGeometryRef($i);
6623  keep($ref, $self);
6624  return $ref;
6625 }
6626 
6627 #** @method GetLinearGeometry()
6628 #*
6629 sub GetLinearGeometry {
6630 }
6631 
6632 #** @method GetM()
6633 #*
6634 sub GetM {
6635 }
6636 
6637 #** @method list GetPoint($index = 0)
6638 # Object method.
6639 # @param index
6640 # @return (x,y) or a list with more coordinates
6641 #*
6642 sub GetPoint {
6643  my($self, $i) = @_;
6644  $i //= 0;
6645  my $t = $self->GetGeometryType;
6646  my $has_z = HasZ($t);
6647  my $has_m = HasM($t);
6648  my $point;
6649  if (!$has_z && !$has_m) {
6650  $point = $self->GetPoint_2D($i);
6651  } elsif ($has_z && !$has_m) {
6652  $point = $self->GetPoint_3D($i);
6653  } elsif (!$has_z && $has_m) {
6654  $point = $self->GetPointZM($i);
6655  @$point = ($point->[0], $point->[1], $point->[3]);
6656  } else {
6657  $point = $self->GetPointZM($i);
6658  }
6659  return wantarray ? @$point : $point;
6660 }
6661 
6662 #** @method scalar GetPointCount()
6663 # Object method.
6664 # @return an integer
6665 #*
6666 sub GetPointCount {
6667 }
6668 
6669 #** @method GetPointZM()
6670 #*
6671 sub GetPointZM {
6672 }
6673 
6674 #** @method scalar GetPoint_2D($index = 0)
6675 # Object method.
6676 # @param index
6677 # @return (x,y) or a list with more coordinates
6678 #*
6679 sub GetPoint_2D {
6680 }
6681 
6682 #** @method scalar GetPoint_3D($index = 0)
6683 # Object method.
6684 # @param index
6685 # @return (x,y) or a list with more coordinates
6686 #*
6687 sub GetPoint_3D {
6688 }
6689 
6690 #** @method Geo::OSR::SpatialReference GetSpatialReference()
6691 # Object method.
6692 # @return a new Geo::OSR::SpatialReference object
6693 #*
6694 sub GetSpatialReference {
6695 }
6696 
6697 #** @method scalar GetX($index = 0)
6698 # Object method.
6699 # @param index
6700 # @return a number
6701 #*
6702 sub GetX {
6703 }
6704 
6705 #** @method scalar GetY($index = 0)
6706 # Object method.
6707 # @param index
6708 # @return a number
6709 #*
6710 sub GetY {
6711 }
6712 
6713 #** @method scalar GetZ($index = 0)
6714 # Object method.
6715 # @param index
6716 # @return a number
6717 #*
6718 sub GetZ {
6719 }
6720 
6721 #** @method HasCurveGeometry()
6722 #*
6723 sub HasCurveGeometry {
6724 }
6725 
6726 #** @method Geo::OGR::Geometry Intersection($other)
6727 # Object method.
6728 # @param other a Geo::OGR::Geometry object
6729 # @return a new Geo::OGR::Geometry object
6730 #*
6731 sub Intersection {
6732 }
6733 
6734 #** @method scalar Intersects($other)
6735 # Object method.
6736 # @note a.k.a. Intersect (deprecated)
6737 # @param other a Geo::OGR::Geometry object
6738 # @return true if this geometry intersects with the other geometry, false otherwise
6739 #*
6740 sub Intersects {
6741 }
6742 
6743 #** @method Is3D()
6744 #*
6745 sub Is3D {
6746 }
6747 
6748 #** @method scalar IsEmpty()
6749 # Object method.
6750 # Test whether the geometry is empty (has no points, or, for a point,
6751 # has coordinate dimension of zero).
6752 # @return boolean
6753 #*
6754 sub IsEmpty {
6755 }
6756 
6757 #** @method IsMeasured()
6758 #*
6759 sub IsMeasured {
6760 }
6761 
6762 #** @method scalar IsRing()
6763 # Object method.
6764 # Test if the geometry is a ring. Requires GEOS in GDAL.
6765 # @return boolean
6766 #*
6767 sub IsRing {
6768 }
6769 
6770 #** @method scalar IsSimple()
6771 # Object method.
6772 # Test the simplicity of the geometry (OGC sense). Requires GEOS in GDAL.
6773 # @return boolean
6774 #*
6775 sub IsSimple {
6776 }
6777 
6778 #** @method scalar IsValid()
6779 # Object method.
6780 # Test the validity of the geometry (OGC sense). Requires GEOS in GDAL.
6781 # @return boolean
6782 #*
6783 sub IsValid {
6784 }
6785 
6786 #** @method scalar Length()
6787 # Object method.
6788 # @return the length of the linestring
6789 #*
6790 sub Length {
6791 }
6792 
6793 #** @method MakeValid()
6794 #*
6795 sub MakeValid {
6796 }
6797 
6798 #** @method Move($dx, $dy, $dz)
6799 # Object method.
6800 # Move every point of the object as defined by the parameters.
6801 # @param dx
6802 # @param dy
6803 # @param dz [optional]
6804 #*
6805 sub Move {
6806 }
6807 
6808 #** @method scalar Overlaps($other)
6809 # Object method.
6810 # @param other a Geo::OGR::Geometry object
6811 # @return true if this geometry overlaps the other geometry, false otherwise
6812 #*
6813 sub Overlaps {
6814 }
6815 
6816 #** @method list Point($index, $x, $y, $z)
6817 # Object method.
6818 # Get or set the point
6819 # @param index The index of the point. Optional (ignored if given) for
6820 # Point and Point25D geometries.
6821 # @param x [optional]
6822 # @param y [optional]
6823 # @param z [optional]
6824 # @return
6825 #*
6826 sub Point {
6827  my $self = shift;
6828  my $i;
6829  if (@_) {
6830  my $t = $self->GetGeometryType;
6831  my $i;
6832  if (Flatten($t) == $Geo::OGR::wkbPoint) {
6833  my $has_z = HasZ($t);
6834  my $has_m = HasM($t);
6835  if (!$has_z && !$has_m) {
6836  shift if @_ > 2;
6837  $i = 0;
6838  } elsif ($has_z || $has_m) {
6839  shift if @_ > 3;
6840  $i = 0;
6841  } else {
6842  shift if @_ > 4;
6843  $i = 0;
6844  }
6845  }
6846  $i = shift unless defined $i;
6847  $self->SetPoint($i, @_);
6848  }
6849  return unless defined wantarray;
6850  my $point = $self->GetPoint;
6851  return wantarray ? @$point : $point;
6852 }
6853 
6854 #** @method PointOnSurface()
6855 #*
6856 sub PointOnSurface {
6857 }
6858 
6859 #** @method array reference Points(arrayref points)
6860 # Object method.
6861 # Get or set the points of the geometry. The points (vertices) are
6862 # stored in obvious lists of lists. When setting, the geometry is
6863 # first emptied. The method uses internally either AddPoint_2D or
6864 # AddPoint_3D depending on the coordinate dimension of the input data.
6865 #
6866 # @note The same structure may represent different geometries
6867 # depending on the actual geometry type of the object.
6868 #
6869 # @param points [optional] A reference to an array. A point is a reference to an
6870 # array of numbers, a linestring or a ring is a reference to an array of points,
6871 # a polygon is a reference to an array of rings, etc.
6872 #
6873 # @return A reference to an array.
6874 #*
6875 sub Points {
6876  my $self = shift;
6877  my $t = $self->GetGeometryType;
6878  my $has_z = HasZ($t);
6879  my $has_m = HasM($t);
6880  my $postfix = '';
6881  $postfix .= 'Z' if HasZ($t);
6882  $postfix .= 'M' if HasM($t);
6883  $t = i2s(geometry_type => Flatten($t));
6884  my $points = shift;
6885  if ($points) {
6886  Empty($self);
6887  if ($t eq 'Unknown' or $t eq 'None' or $t eq 'GeometryCollection') {
6888  error("Can't set points of a geometry of type '$t'.");
6889  } elsif ($t eq 'Point') {
6890  # support both "Point" as a list of one point and one point
6891  if (ref($points->[0])) {
6892  $self->AddPoint(@{$points->[0]});
6893  } else {
6894  $self->AddPoint(@$points);
6895  }
6896  } elsif ($t eq 'LineString' or $t eq 'LinearRing' or $t eq 'CircularString') {
6897  for my $p (@$points) {
6898  $self->AddPoint(@$p);
6899  }
6900  } elsif ($t eq 'Polygon') {
6901  for my $r (@$points) {
6902  my $ring = Geo::OGR::Geometry->new('LinearRing');
6903  $ring->Set3D(1) if $has_z;
6904  $ring->SetMeasured(1) if $has_m;
6905  $ring->Points($r);
6906  $self->AddGeometryDirectly($ring);
6907  }
6908  } elsif ($t eq 'MultiPoint') {
6909  for my $p (@$points) {
6910  my $point = Geo::OGR::Geometry->new('Point'.$postfix);
6911  $point->Points($p);
6912  $self->AddGeometryDirectly($point);
6913  }
6914  } elsif ($t eq 'MultiLineString') {
6915  for my $l (@$points) {
6916  my $linestring = Geo::OGR::Geometry->new('LineString'.$postfix);
6917  $linestring->Points($l);
6918  $self->AddGeometryDirectly($linestring);
6919  }
6920  } elsif ($t eq 'MultiPolygon') {
6921  for my $p (@$points) {
6922  my $polygon = Geo::OGR::Geometry->new('Polygon'.$postfix);
6923  $polygon->Points($p);
6924  $self->AddGeometryDirectly($polygon);
6925  }
6926  }
6927  }
6928  return unless defined wantarray;
6929  $self->_GetPoints();
6930 }
6931 
6932 #** @method Polygonize()
6933 #*
6934 sub Polygonize {
6935 }
6936 
6937 #** @method RemoveGeometry()
6938 #*
6939 sub RemoveGeometry {
6940 }
6941 
6942 #** @method RemoveLowerDimensionSubGeoms()
6943 #*
6944 sub RemoveLowerDimensionSubGeoms {
6945 }
6946 
6947 #** @method Segmentize($MaxLength)
6948 # Object method.
6949 # Modify the geometry such it has no segment longer than the given length.
6950 # @param MaxLength the given length
6951 #*
6952 sub Segmentize {
6953 }
6954 
6955 #** @method Set3D()
6956 #*
6957 sub Set3D {
6958 }
6959 
6960 #** @method SetCoordinateDimension($dimension)
6961 # Object method.
6962 # @param dimension
6963 #*
6964 sub SetCoordinateDimension {
6965 }
6967 #** @method SetMeasured()
6968 #*
6969 sub SetMeasured {
6970 }
6971 
6972 #** @method SetPoint($index, $x, $y, $z)
6973 # Object method.
6974 # Set the data of a point or a line string. Note that the coordinate
6975 # dimension is automatically upgraded to 25D (3) if z is given.
6976 # @param index
6977 # @param x
6978 # @param y
6979 # @param z [optional]
6980 #*
6981 sub SetPoint {
6982  my $self = shift;
6983  my $t = $self->GetGeometryType;
6984  my $has_z = HasZ($t);
6985  my $has_m = HasM($t);
6986  if (!$has_z && !$has_m) {
6987  $self->SetPoint_2D(@_[0..2]);
6988  } elsif ($has_z && !$has_m) {
6989  $self->SetPoint_3D(@_[0..3]);
6990  } elsif (!$has_z && $has_m) {
6991  $self->SetPointM(@_[0..3]);
6992  } else {
6993  $self->SetPointZM(@_[0..4]);
6994  }
6995 }
6996 
6997 #** @method SetPointM()
6998 #*
6999 sub SetPointM {
7000 }
7001 
7002 #** @method SetPointZM()
7003 #*
7004 sub SetPointZM {
7005 }
7006 
7007 #** @method SetPoint_2D($index, $x, $y)
7008 # Object method.
7009 # @param index
7010 # @param x
7011 # @param y
7012 #*
7013 sub SetPoint_2D {
7014 }
7015 
7016 #** @method SetPoint_3D($index, $x, $y, $z)
7017 # Object method.
7018 # Set the data of a point or a line string. Note that the coordinate
7019 # dimension is automatically upgraded to 25D (3).
7020 # @param index
7021 # @param x
7022 # @param y
7023 # @param z
7024 #*
7025 sub SetPoint_3D {
7026 }
7027 
7028 #** @method Geo::OGR::Geometry Simplify($Tolerance)
7029 # Object method.
7030 # Simplify the geometry.
7031 # @param Tolerance the length tolerance for the simplification
7032 # @since 1.8.0
7033 # @return a new Geo::OSR::Geometry object
7034 #*
7035 sub Simplify {
7036 }
7037 
7038 #** @method SimplifyPreserveTopology()
7039 #*
7040 sub SimplifyPreserveTopology {
7041 }
7042 
7043 #** @method SwapXY()
7044 #*
7045 sub SwapXY {
7046 }
7047 
7048 #** @method Geo::OGR::Geometry SymDifference($other)
7049 # Object method.
7050 # Compute symmetric difference.
7051 # @note a.k.a. SymmetricDifference
7052 # @param other a Geo::OGR::Geometry object
7053 # @return a new Geo::OGR::Geometry object
7054 # @since 1.8.0
7055 #*
7056 sub SymDifference {
7057 }
7058 
7059 #** @method scalar Touches($other)
7060 # Object method.
7061 # @param other a Geo::OGR::Geometry object
7062 # @return true if this geometry touches the other geometry, false otherwise
7063 #*
7064 sub Touches {
7065 }
7066 
7067 #** @method Transform($trans)
7068 # Object method.
7069 # @param trans a Geo::OSR::CoordinateTransformation object
7070 #*
7071 sub Transform {
7072 }
7073 
7074 #** @method TransformTo($srs)
7075 # Object method.
7076 # @param srs a Geo::OSR::SpatialReference object
7077 #*
7078 sub TransformTo {
7079 }
7080 
7081 #** @method Geo::OGR::Geometry Union($other)
7082 # Object method.
7083 # @param other a Geo::OGR::Geometry object
7084 # @return a new Geo::OGR::Geometry object
7085 #*
7086 sub Union {
7087 }
7088 
7089 #** @method Geo::OGR::Geometry UnionCascaded()
7090 # Object method.
7091 # @return a new Geo::OGR::Geometry object
7092 # @since 1.8.0
7093 #*
7094 sub UnionCascaded {
7095 }
7096 
7097 #** @method Value()
7098 #*
7099 sub Value {
7100 }
7101 
7102 #** @method scalar Within($other)
7103 # Object method.
7104 # @param other a Geo::OGR::Geometry object
7105 # @return true if this geometry is within the other geometry, false otherwise
7106 #*
7107 sub Within {
7108 }
7109 
7110 #** @method scalar WkbSize()
7111 # Object method.
7112 # @return an integer
7113 #*
7114 sub WkbSize {
7115 }
7116 
7117 #** @method Geo::OGR::Geometry new(%params)
7118 # Class method.
7119 # @param %params A named parameter, one of:
7120 # - \a GeometryType one the supported geometry types, see Geo::OGR::GeometryTypes.
7121 # - \a WKT a well known text string, which defines a geometry.
7122 # - \a WKB a well known binary string, which defines a geometry.
7123 # - \a HEXWKB WKB in hexadecimal.
7124 # - \a HEXEWKB PostGIS extended WKB.
7125 # - \a GML geometry written in Geographic Markup Language.
7126 # - \a GeoJSON geometry written in GeoJSON (JavaScript Object Notation for Geographic data).
7127 # - \a arc a reference to a list of values defining an arc: [CenterX,
7128 # CenterY, CenterZ, PrimaryRadius, SecondaryRadius, Rotation,
7129 # StartAngle, EndAngle, MaxAngleStepSizeDegrees] (see also Geo::OGR::Geometry::ApproximateArcAngles)
7130 # - \a Points An anonymous array as in method
7131 # Geo::OGR::Geometry::Points; Note: requires also GeometryType
7132 # parameter
7133 #
7134 # @return a new Geo::OGR::Geometry object.
7135 #*
7136 sub new {
7137  my $pkg = shift;
7138  my %param;
7139  if (@_ == 1 and ref($_[0]) eq 'HASH') {
7140  %param = %{$_[0]};
7141  } elsif (@_ % 2 == 0) {
7142  %param = @_;
7143  } else {
7144  ($param{GeometryType}) = @_;
7145  }
7146  my $type = $param{GeometryType} // $param{Type} // $param{type};
7147  my $srs = $param{SRS} // $param{srs};
7148  my $wkt = $param{WKT} // $param{wkt};
7149  my $wkb = $param{WKB} // $param{wkb};
7150  my $hex = $param{HEXEWKB} // $param{HEX_EWKB} // $param{hexewkb} // $param{hex_ewkb};
7151  my $srid;
7152  if ($hex) {
7153  # EWKB contains SRID
7154  $srid = substr($hex, 10, 8);
7155  substr($hex, 10, 8) = '';
7156  } else {
7157  $hex = $param{HEXWKB} // $param{HEX_WKB} // $param{hexwkb} // $param{hex_wkb};
7158  }
7159  if ($hex) {
7160  $wkb = '';
7161  for (my $i = 0; $i < length($hex); $i+=2) {
7162  $wkb .= chr(hex(substr($hex,$i,2)));
7163  }
7164  }
7165  my $gml = $param{GML} // $param{gml};
7166  my $json = $param{GeoJSON} // $param{geojson} // $param{JSON} // $param{json};
7167  my $points = $param{Points} // $param{points};
7168  my $arc = $param{Arc} // $param{arc};
7169  my $self;
7170  if (defined $wkt) {
7171  $self = Geo::OGRc::CreateGeometryFromWkt($wkt, $srs);
7172  } elsif (defined $wkb) {
7173  $self = Geo::OGRc::CreateGeometryFromWkb($wkb, $srs);
7174  } elsif (defined $gml) {
7175  $self = Geo::OGRc::CreateGeometryFromGML($gml);
7176  } elsif (defined $json) {
7177  $self = Geo::OGRc::CreateGeometryFromJson($json);
7178  } elsif (defined $type) {
7179  $type = s2i(geometry_type => $type);
7180  $self = Geo::OGRc::new_Geometry($type); # flattens the type
7181  $self->Set3D(1) if HasZ($type);
7182  $self->SetMeasured(1) if HasM($type);
7183  } elsif (defined $arc) {
7184  $self = Geo::OGRc::ApproximateArcAngles(@$arc);
7185  } else {
7186  error(1, undef, map {$_=>1} qw/GeometryType WKT WKB HEXEWKB HEXWKB GML GeoJSON Arc/);
7187  }
7188  bless $self, $pkg if defined $self;
7189  $self->Points($points) if $points;
7190  return $self;
7191 }
7192 
7193 #** @class Geo::OGR::Layer
7194 # @brief A collection of similar features.
7195 # @details A layer object is typically obtained with a data source object. A
7196 # layer has a data model (a schema), which is maintained in a
7197 # definition object, and a set of features, which contain data
7198 # according to the data model. The schema is typically set when the
7199 # layer is created or opened, but it may be altered somewhat with
7200 # methods Geo::OGR::Layer::CreateField,
7201 # Geo::OGR::Layer::AlterFieldDefn, and
7202 # Geo::OGR::Layer::DeleteField. Features and/or their data can be
7203 # read, inserted and deleted. Reading can be filtered. Layers can be
7204 # compared to each other with methods Clip, Erase, Identity,
7205 # Intersection, SymDifference, Union, and Update.
7206 # A layer may have metadata OLMD_FID64 => 'YES' if it holds features
7207 # with 64 bit FIDs. The metadata of a layer can be obtained with
7208 # GetMetadata method.
7209 #*
7210 package Geo::OGR::Layer;
7211 
7212 use base qw(Geo::GDAL::MajorObject Geo::OGR)
7213 
7214 #** @method AlterFieldDefn($name, %params)
7215 # Object method.
7216 # @param field the name of the field to be altered.
7217 # @param params as in Geo::OGR::FieldDefn::new. Width and
7218 # Precision should be both or neither.
7219 # @note Only non-spatial fields can be altered.
7220 # @note Also the deprecated form AlterFieldDefn($field,
7221 # Geo::OGR::FieldDefn $Defn, $Flags) works.
7222 #*
7223 sub AlterFieldDefn {
7224  my $self = shift;
7225  my $index = $self->GetLayerDefn->GetFieldIndex(shift // 0);
7226  my $param = @_ % 2 == 0 ? {@_} : shift;
7227  if (blessed($param) and $param->isa('Geo::OGR::FieldDefn')) {
7228  _AlterFieldDefn($self, $index, @_);
7229  } else {
7230  my $definition = Geo::OGR::FieldDefn->new($param);
7231  my $flags = 0;
7232  $flags |= 1 if exists $param->{Name};
7233  $flags |= 2 if exists $param->{Type};
7234  $flags |= 4 if exists $param->{Width} or exists $param->{Precision};
7235  $flags |= 8 if exists $param->{Nullable};
7236  $flags |= 16 if exists $param->{Default};
7237  _AlterFieldDefn($self, $index, $definition, $flags);
7238  }
7239 }
7240 
7241 #** @method list Capabilities()
7242 # Object method.
7243 # Both a package subroutine and an object method.
7244 # @return a list of capabilities. The object method returns a list of
7245 # the capabilities the layer has. The package subroutine returns a list of
7246 # all potential capabilities a layer may have. These are currently:
7247 # AlterFieldDefn, CreateField, CreateGeomField, CurveGeometries, DeleteFeature, DeleteField, FastFeatureCount, FastGetExtent, FastSetNextByIndex, FastSpatialFilter, IgnoreFields, MeasuredGeometries, RandomRead, RandomWrite, ReorderFields, SequentialWrite, StringsAsUTF8, and Transactions.
7248 #
7249 # Examples:
7250 # \code
7251 # @cap = Geo::OGR::Layer::Capabilities(); # the package subroutine
7252 # @cap = $layer->Capabilities(); # the object method
7253 # \endcode
7254 #*
7255 sub Capabilities {
7256  return @CAPABILITIES if @_ == 0;
7257  my $self = shift;
7258  my @cap;
7259  for my $cap (@CAPABILITIES) {
7260  push @cap, $cap if _TestCapability($self, $CAPABILITIES{$cap});
7261  }
7262  return @cap;
7263 }
7264 
7265 #** @method Clip(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7266 # Object method.
7267 # Clip off areas that are not covered by the method layer. The schema
7268 # of the result layer can be set before calling this method, or is
7269 # initialized to to contain all fields from
7270 # this and method layer.
7271 # @param method method layer.
7272 # @param result result layer.
7273 # @param options a reference to an options hash.
7274 # @param callback [optional] a reference to a subroutine, which will
7275 # be called with parameters (number progress, string msg, callback_data)
7276 # @param callback_data [optional]
7277 #*
7278 sub Clip {
7279 }
7280 
7281 #** @method CommitTransaction()
7282 # Object method.
7283 #*
7284 sub CommitTransaction {
7285 }
7286 
7287 #** @method CreateFeature()
7288 #*
7289 sub CreateFeature {
7290 }
7291 
7292 #** @method CreateField(%params)
7293 # Object method.
7294 # Create a field.
7295 # @param params as in Geo::OGR::FieldDefn::new or
7296 # Geo::OGR::GeomFieldDefn::new, plus ApproxOK (whose default is true).
7297 #*
7298 sub CreateField {
7299  my $self = shift;
7300  my %defaults = ( ApproxOK => 1,
7301  Type => '' );
7302  my %params;
7303  if (@_ == 0) {
7304  } elsif (ref($_[0]) eq 'HASH') {
7305  %params = %{$_[0]};
7306  } elsif (@_ % 2 == 0) {
7307  %params = @_;
7308  } else {
7309  ($params{Defn}) = @_;
7310  }
7311  for my $k (keys %defaults) {
7312  $params{$k} //= $defaults{$k};
7313  }
7314  if (blessed($params{Defn}) and $params{Defn}->isa('Geo::OGR::FieldDefn')) {
7315  $self->_CreateField($params{Defn}, $params{ApproxOK});
7316  } elsif (blessed($_[0]) and $params{Defn}->isa('Geo::OGR::GeomFieldDefn')) {
7317  $self->CreateGeomField($params{Defn}, $params{ApproxOK});
7318  } else {
7319  # if Name and Type are missing, assume Name => Type
7320  if (!(exists $params{Name} && exists $params{Type})) {
7321  for my $key (sort keys %params) {
7322  if (s_exists(field_type => $params{$key}) ||
7323  s_exists(geometry_type => $params{$key}))
7324  {
7325  $params{Name} = $key;
7326  $params{Type} = $params{$key};
7327  delete $params{$key};
7328  last;
7329  }
7330  }
7331  }
7332  my $a = $params{ApproxOK};
7333  delete $params{ApproxOK};
7334  if (exists $params{GeometryType}) {
7335  $params{Type} = $params{GeometryType};
7336  delete $params{GeometryType};
7337  }
7338  if (s_exists(field_type => $params{Type})) {
7339  my $fd = Geo::OGR::FieldDefn->new(%params);
7340  _CreateField($self, $fd, $a);
7341  } elsif (s_exists(geometry_type => $params{Type})) {
7342  my $fd = Geo::OGR::GeomFieldDefn->new(%params);
7343  CreateGeomField($self, $fd, $a);
7344  } elsif ($params{Type} ) {
7345  error("Invalid field type: $params{Type}.")
7346  } elsif ($params{Name} ) {
7347  error("Missing type for field: $params{Name}.")
7348  } else {
7349  error("Missing name and type for a field.")
7350  }
7351  }
7352 }
7353 
7354 #** @method DataSource()
7355 #*
7356 sub DataSource {
7357 }
7358 
7359 #** @method Dataset()
7360 #*
7361 sub Dataset {
7362  my $self = shift;
7363  parent($self);
7364 }
7365 
7366 #** @method DeleteFeature($fid)
7367 # Object method.
7368 # @param fid feature id
7369 #*
7370 sub DeleteFeature {
7371 }
7372 
7373 #** @method DeleteField($field)
7374 # Object method.
7375 # Delete an existing field from a layer.
7376 # @param field name (or index) of the field which is deleted
7377 # @note Only non-spatial fields can be deleted.
7378 #*
7379 sub DeleteField {
7380  my ($self, $field) = @_;
7381  my $index = $self->GetLayerDefn->GetFieldIndex($field // 0);
7382  _DeleteField($self, $index);
7383 }
7384 
7385 #** @method Erase(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7386 # Object method.
7387 # The result layer contains features whose geometries represent areas
7388 # that are in the input layer but not in the method layer. The
7389 # features in the result layer have attributes from the input
7390 # layer. The schema of the result layer can be set by the user or, if
7391 # it is empty, is initialized to contain all fields in the input
7392 # layer.
7393 # @param method method layer.
7394 # @param result result layer.
7395 # @param options a reference to an options hash.
7396 # @param callback [optional] a reference to a subroutine, which will
7397 # be called with parameters (number progress, string msg, callback_data)
7398 # @param callback_data [optional]
7399 #*
7400 sub Erase {
7401 }
7402 
7403 #** @method Geo::OGR::Feature Feature($f)
7404 # Object method.
7405 #
7406 # @param f [optional] feature id, a feature, a row, or a tuple
7407 #
7408 # @note If the argument feature has a null FID (FID not set) the
7409 # feature is inserted into the layer as a new feature. If the FID is
7410 # non null, then the feature replaces the feature in the layer with
7411 # that FID.
7412 #
7413 # @return a new Geo::OGR::Feature object that represents the feature
7414 # in the layer.
7415 #*
7416 sub Feature {
7417  my $self = shift;
7418  my $x = shift;
7419  return $self->GetFeature($x) unless $x && ref $x;
7420  # Insert or Set depending on the FID
7421  my $fid;
7422  if (ref $x eq 'ARRAY') {
7423  # FID is the first item in the array
7424  $fid = $x->[0];
7425  } elsif (ref $x eq 'HASH') {
7426  # FID is FID
7427  $fid = $x->{FID};
7428  } else {
7429  $fid = $x->FID;
7430  }
7431  # OGRNullFID is -1
7432  if (!defined $fid || $fid < 0) {
7433  $self->InsertFeature($x);
7434  } else {
7435  $self->SetFeature($x);
7436  }
7437 }
7438 
7439 #** @method scalar FeatureCount($force = 1)
7440 # Object method.
7441 # A.k.a GetFeatureCount
7442 # @param force
7443 # @return integer
7444 #*
7445 sub FeatureCount {
7446 }
7447 
7448 #** @method Features()
7449 #*
7450 sub Features {
7451  my $self = shift;
7452  $self->ResetReading;
7453  return sub {
7454  return $self->GetNextFeature;
7455  }
7456 }
7458 #** @method ForFeatures($code, $in_place)
7459 # Object method.
7460 # @note experimental, the syntax may change
7461 #
7462 # Call code for all features. This is a simple wrapper for
7463 # ResetReading and while(GetNextFeature).
7464 #
7465 # Example usage:
7466 # \code
7467 # $layer->ForFeatures(sub {my $f = shift; $self->DeleteFeature($f->FID)}); # empties the layer
7468 # \endcode
7469 #
7470 # @param code a reference to a subroutine, which is called with each
7471 # feature as an argument
7472 # @param in_place if set to true, the feature is stored back to the
7473 # layer
7474 #*
7475 sub ForFeatures {
7476  my $self = shift;
7477  my $code = shift;
7478  my $in_place = shift;
7479  $self->ResetReading;
7480  while (my $f = $self->GetNextFeature) {
7481  keep($f, $self);
7482  $code->($f);
7483  $self->SetFeature($f) if $in_place;
7484  };
7485 }
7486 
7487 #** @method ForGeometries($code, $in_place)
7488 # Object method.
7489 # @note experimental, the syntax may change
7490 #
7491 # Call code for all geometries. This is a simple wrapper for
7492 # ResetReading and while(GetNextFeature).
7493 #
7494 # Example usage:
7495 # \code
7496 # my $area = 0;
7497 # $layer->ForGeometries(sub {my $g = shift; $area += $g->Area}); # computes the total area
7498 # \endcode
7499 #
7500 # @param code a reference to a subroutine, which is called with each
7501 # geometry as an argument
7502 # @param in_place if set to true, the geometry is stored back to the
7503 # layer
7504 #*
7505 sub ForGeometries {
7506  my $self = shift;
7507  my $code = shift;
7508  my $in_place = shift;
7509  $self->ResetReading;
7510  while (my $f = $self->GetNextFeature) {
7511  my $g = $f->Geometry();
7512  $code->($g);
7513  if ($in_place) {
7514  $f->Geometry($g);
7515  $self->SetFeature($f);
7516  }
7517  }
7518 }
7519 
7520 #** @method Geometries()
7521 #*
7522 sub Geometries {
7523  my $self = shift;
7524  $self->ResetReading;
7525  return sub {
7526  my $f = $self->GetNextFeature;
7527  return 0 unless $f;
7528  return $f->Geometry;
7529  }
7530 }
7531 
7532 #** @method scalar GeometryType($field)
7533 # Object method.
7534 # @param field the name or index of the spatial field.
7535 # @return the geometry type of the spatial field.
7536 #*
7537 sub GeometryType {
7538  my $self = shift;
7539  my $d = $self->GetDefn;
7540  my $field = $d->GetGeomFieldIndex(shift // 0);
7541  my $fd = $d->_GetGeomFieldDefn($field);
7542  return $fd->Type if $fd;
7543 }
7544 
7545 #** @method Geo::OGR::DataSource GetDataSource()
7546 # Object method.
7547 # @return the data source object to which this layer object belongs to.
7548 #*
7549 sub GetDataSource {
7550  my $self = shift;
7551  parent($self);
7552 }
7553 
7554 #** @method Geo::OGR::FeatureDefn GetDefn()
7555 # Object method.
7556 # A.k.a GetLayerDefn.
7557 # @return a Geo::OGR::FeatureDefn object.
7558 #*
7559 sub GetDefn {
7560  my $self = shift;
7561  my $defn = $self->GetLayerDefn;
7562  keep($defn, $self);
7563 }
7564 
7565 #** @method list GetExtent($force = 1)
7566 # Object method.
7567 # @param force compute the extent even if it is expensive
7568 # @note In scalar context returns a reference to an anonymous array
7569 # containing the extent.
7570 # @return the extent ($minx, $maxx, $miny, $maxy)
7571 # @param force
7572 # @return the extent = ($minx, $maxx, $miny, $maxy) as a listref
7573 #*
7574 sub GetExtent {
7575 }
7576 
7577 #** @method scalar GetFIDColumn()
7578 # Object method.
7579 # @return the name of the underlying database column being used as the
7580 # FID column, or "" if not supported.
7581 #*
7582 sub GetFIDColumn {
7583 }
7584 
7585 #** @method Geo::OGR::Feature GetFeature($fid)
7586 # Object method.
7587 # @param fid feature id
7588 # @return a new Geo::OGR::Feature object that represents the feature in the layer.
7589 #*
7590 sub GetFeature {
7591  my ($self, $fid) = @_;
7592  $fid //= 0;
7593  my $f = $self->_GetFeature($fid);
7594  error(2, "FID=$fid", '"Feature') unless ref $f eq 'Geo::OGR::Feature';
7595  keep($f, $self);
7596 }
7597 
7598 #** @method GetFeatureCount()
7599 #*
7600 sub GetFeatureCount {
7601 }
7602 
7603 #** @method scalar GetFeaturesRead()
7604 # Object method.
7605 # @return integer
7606 #*
7607 sub GetFeaturesRead {
7608 }
7609 
7610 #** @method scalar GetFieldDefn($name)
7611 # Object method.
7612 # Get the definition of a field.
7613 # @param name the name of the field.
7614 # @return a Geo::OGR::FieldDefn object.
7615 #*
7616 sub GetFieldDefn {
7617  my $self = shift;
7618  my $d = $self->GetDefn;
7619  my $field = $d->GetFieldIndex(shift // 0);
7620  return $d->_GetFieldDefn($field);
7621 }
7622 
7623 #** @method list GetFieldNames()
7624 # Object method.
7625 # @return a list of the names of the fields in this layer. The
7626 # non-geometry field names are first in the list and then the geometry
7627 # fields.
7628 #*
7629 sub GetFieldNames {
7630  my $self = shift;
7631  my $d = $self->GetDefn;
7632  my @ret;
7633  for (my $i = 0; $i < $d->GetFieldCount; $i++) {
7634  push @ret, $d->GetFieldDefn($i)->Name();
7635  }
7636  for (my $i = 0; $i < $d->GetGeomFieldCount; $i++) {
7637  push @ret, $d->GetGeomFieldDefn($i)->Name();
7638  }
7639  return @ret;
7640 }
7641 
7642 #** @method scalar GetGeomFieldDefn($name)
7643 # Object method.
7644 # Get the definition of a spatial field.
7645 # @param name the name of the spatial field.
7646 # @return a Geo::OGR::GeomFieldDefn object.
7647 #*
7648 sub GetGeomFieldDefn {
7649  my $self = shift;
7650  my $d = $self->GetDefn;
7651  my $field = $d->GetGeomFieldIndex(shift // 0);
7652  return $d->_GetGeomFieldDefn($field);
7653 }
7654 
7655 #** @method scalar GetName()
7656 # Object method.
7657 # @return the name of the layer.
7658 #*
7659 sub GetName {
7660 }
7661 
7662 #** @method Geo::OGR::Feature GetNextFeature()
7663 # Object method.
7664 # @return iteratively Geo::OGR::Feature objects from the layer. The
7665 # iteration obeys the spatial and the attribute filter.
7666 #*
7667 sub GetNextFeature {
7668 }
7669 
7670 #** @method hash reference GetSchema()
7671 # Object method.
7672 # @brief Get the schema of this layer.
7673 # @note The schema of a layer cannot be set with this method. If you
7674 # have a Geo::OGR::FeatureDefn object before creating the layer, use
7675 # its schema in the Geo::OGR::CreateLayer method.
7676 # @return the schema of this layer, as in Geo::OGR::FeatureDefn::Schema.
7677 #*
7678 sub GetSchema {
7679  my $self = shift;
7680  carp "Schema of a layer should not be set directly." if @_;
7681  if (@_ and @_ % 2 == 0) {
7682  my %schema = @_;
7683  if ($schema{Fields}) {
7684  for my $field (@{$schema{Fields}}) {
7685  $self->CreateField($field);
7686  }
7687  }
7688  }
7689  return $self->GetDefn->Schema;
7690 }
7691 
7692 #** @method Geo::OGR::Geometry GetSpatialFilter()
7693 # Object method.
7694 # @return a new Geo::OGR::Geometry object
7695 #*
7696 sub GetSpatialFilter {
7697 }
7698 
7699 #** @method GetStyleTable()
7700 #*
7701 sub GetStyleTable {
7702 }
7703 
7704 #** @method Identity(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7705 # Object method.
7706 # The result layer contains features whose geometries represent areas
7707 # that are in the input layer. The features in the result layer have
7708 # attributes from both input and method layers. The schema of the
7709 # result layer can be set by the user or, if it is empty, is
7710 # initialized to contain all fields in input and method layers.
7711 # @param method method layer.
7712 # @param result result layer.
7713 # @param options a reference to an options hash.
7714 # @param callback [optional] a reference to a subroutine, which will
7715 # be called with parameters (number progress, string msg, callback_data)
7716 # @param callback_data [optional]
7717 #*
7718 sub Identity {
7719 }
7720 
7721 #** @method InsertFeature($feature)
7722 # Object method.
7723 # Creates a new feature which has the schema of the layer and
7724 # initializes it with data from the argument. Then inserts the feature
7725 # into the layer (using CreateFeature). Uses Geo::OGR::Feature::Row or
7726 # Geo::OGR::Feature::Tuple.
7727 # @param feature a Geo::OGR::Feature object or reference to feature
7728 # data in a hash (as in Geo::OGR::Feature::Row) or in an array (as in
7729 # Geo::OGR::Feature::Tuple)
7730 # @return the new feature.
7731 #*
7732 sub InsertFeature {
7733  my $self = shift;
7734  my $feature = shift;
7735  error("Usage: \$feature->InsertFeature(reference to a hash or array).") unless ref($feature);
7736  my $new = Geo::OGR::Feature->new(Schema => $self, Values => $feature);
7737  $self->CreateFeature($new);
7738  return unless defined wantarray;
7739  keep($new, $self);
7740 }
7741 
7742 #** @method Intersection(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7743 # Object method.
7744 # The result layer contains features whose geometries represent areas
7745 # that are common between features in the input layer and in the
7746 # method layer. The schema of the result layer can be set before
7747 # calling this method, or is initialized to contain all fields from
7748 # this and method layer.
7749 # @param method method layer.
7750 # @param result result layer.
7751 # @param options a reference to an options hash.
7752 # @param callback [optional] a reference to a subroutine, which will
7753 # be called with parameters (number progress, string msg, callback_data)
7754 # @param callback_data [optional]
7755 #*
7756 sub Intersection {
7757 }
7758 
7759 #** @method ReorderField()
7760 #*
7761 sub ReorderField {
7762 }
7763 
7764 #** @method ReorderFields()
7765 #*
7766 sub ReorderFields {
7767 }
7768 
7769 #** @method ResetReading()
7770 # Object method.
7771 # Initialize the layer object for iterative reading.
7772 #*
7773 sub ResetReading {
7774 }
7775 
7776 #** @method RollbackTransaction()
7777 # Object method.
7778 #*
7779 sub RollbackTransaction {
7780 }
7781 
7782 #** @method hash reference Row(%row)
7783 # Object method.
7784 # Get and/or set the data of a feature that has the supplied feature
7785 # id (the next feature obtained with GetNextFeature is used if feature
7786 # id is not given). Calls Geo::OGR::Feature::Row.
7787 # @param row [optional] feature data
7788 # @return a reference to feature data in a hash
7789 #*
7790 sub Row {
7791  my $self = shift;
7792  my $update = @_ > 0;
7793  my %row = @_;
7794  my $feature = defined $row{FID} ? $self->GetFeature($row{FID}) : $self->GetNextFeature;
7795  return unless $feature;
7796  my $ret;
7797  if (defined wantarray) {
7798  $ret = $feature->Row(@_);
7799  } else {
7800  $feature->Row(@_);
7801  }
7802  $self->SetFeature($feature) if $update;
7803  return unless defined wantarray;
7804  return $ret;
7805 }
7806 
7807 #** @method SetAttributeFilter($filter_string)
7808 # Object method.
7809 # Set or clear the attribute filter.
7810 # @param filter_string a SQL WHERE clause or undef to clear the
7811 # filter.
7812 #*
7813 sub SetAttributeFilter {
7814 }
7815 
7816 #** @method SetFeature($feature)
7817 # Object method.
7818 # @note The feature should have the same schema as the layer.
7819 #
7820 # Replaces a feature in the layer based on the given feature's
7821 # id. Requires RandomWrite capability.
7822 # @param feature a Geo::OGR::Feature object
7823 #*
7824 sub SetFeature {
7825 }
7826 
7827 #** @method SetIgnoredFields(@fields)
7828 # Object method.
7829 # @param fields a list of field names
7830 #*
7831 sub SetIgnoredFields {
7832 }
7833 
7834 #** @method SetNextByIndex($new_index)
7835 # Object method.
7836 # @param new_index the index to which set the read cursor in the
7837 # current iteration
7838 #*
7839 sub SetNextByIndex {
7840 }
7841 
7842 #** @method SetSpatialFilter($filter)
7843 # Object method.
7844 # @param filter [optional] a Geo::OGR::Geometry object. If not given,
7845 # removes the filter if there is one.
7846 #*
7847 sub SetSpatialFilter {
7848 }
7849 
7850 #** @method SetSpatialFilterRect($minx, $miny, $maxx, $maxy)
7851 # Object method.
7852 # @param minx
7853 # @param miny
7854 # @param maxx
7855 # @param maxy
7856 #*
7857 sub SetSpatialFilterRect {
7858 }
7859 
7860 #** @method SetStyleTable()
7861 #*
7862 sub SetStyleTable {
7863 }
7864 
7865 #** @method Geo::OGR::Geometry SpatialFilter(@filter)
7866 # Object method.
7867 # @param filter [optional] a Geo::OGR::Geometry object or a string. An
7868 # undefined value removes the filter if there is one.
7869 # @return a new Geo::OGR::Geometry object
7870 # @param filter [optional] a rectangle ($minx, $miny, $maxx, $maxy).
7871 # @return a new Geo::OGR::Geometry object
7872 #*
7873 sub SpatialFilter {
7874  my $self = shift;
7875  $self->SetSpatialFilter($_[0]) if @_ == 1;
7876  $self->SetSpatialFilterRect(@_) if @_ == 4;
7877  return unless defined wantarray;
7878  $self->GetSpatialFilter;
7879 }
7880 
7881 #** @method Geo::OSR::SpatialReference SpatialReference($name, Geo::OSR::SpatialReference sr)
7882 # Object method.
7883 # @note A.k.a GetSpatialRef.
7884 # Get or set the projection of a spatial field of this layer. Gets or
7885 # sets the projection of the first field if no field name is given.
7886 # @param name [optional] a name of a spatial field in this layer.
7887 # @param sr [optional] a Geo::OSR::SpatialReference object,
7888 # which replaces the existing projection.
7889 # @return a Geo::OSR::SpatialReference object, which represents the
7890 # projection in the given spatial field.
7891 #*
7892 sub SpatialReference {
7893  my $self = shift;
7894  my $d = $self->GetDefn;
7895  my $field = @_ == 2 ? $d->GetGeomFieldIndex(shift // 0) : 0;
7896  my $sr = shift;
7897  my $d2 = $d->_GetGeomFieldDefn($field);
7898  $d2->SpatialReference($sr) if defined $sr;
7899  return $d2->SpatialReference() if defined wantarray;
7900 }
7901 
7902 #** @method StartTransaction()
7903 # Object method.
7904 #*
7905 sub StartTransaction {
7906 }
7907 
7908 #** @method SymDifference(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7909 # Object method.
7910 # The result layer contains features whose geometries represent areas
7911 # that are in either in the input layer or in the method layer but not
7912 # in both. The features in the result layer have attributes from both
7913 # input and method layers. For features which represent areas that are
7914 # only in the input or in the method layer the respective attributes
7915 # have undefined values. The schema of the result layer can be set by
7916 # the user or, if it is empty, is initialized to contain all fields in
7917 # the input and method layers.
7918 # @param method method layer.
7919 # @param result result layer.
7920 # @param options a reference to an options hash.
7921 # @param callback [optional] a reference to a subroutine, which will
7922 # be called with parameters (number progress, string msg, callback_data)
7923 # @param callback_data [optional]
7924 #*
7925 sub SymDifference {
7926 }
7927 
7928 #** @method SyncToDisk()
7929 # Object method.
7930 #*
7931 sub SyncToDisk {
7932 }
7933 
7934 #** @method scalar TestCapability($cap)
7935 # Object method.
7936 # @param cap A capability string.
7937 # @return a boolean value indicating whether the layer has the
7938 # specified capability.
7939 #*
7940 sub TestCapability {
7941  my($self, $cap) = @_;
7942  return _TestCapability($self, $CAPABILITIES{$cap});
7943 }
7944 
7945 #** @method list Tuple(@tuple)
7946 # Object method.
7947 # Get and/set the data of a feature that has the supplied feature id
7948 # (the next feature obtained with GetNextFeature is used if feature id
7949 # is not given). The expected data in the tuple is: ([feature id,]
7950 # non-spatial fields, spatial fields). Calls Geo::OGR::Feature::Tuple.
7951 # @param tuple [optional] feature data
7952 # @note The schema of the tuple needs to be the same as that of the
7953 # layer.
7954 # @return a reference to feature data in an array
7955 #*
7956 sub Tuple {
7957  my $self = shift;
7958  my $FID = shift;
7959  my $feature = defined $FID ? $self->GetFeature($FID) : $self->GetNextFeature;
7960  return unless $feature;
7961  my $set = @_ > 0;
7962  unshift @_, $feature->GetFID if $set;
7963  my @ret;
7964  if (defined wantarray) {
7965  @ret = $feature->Tuple(@_);
7966  } else {
7967  $feature->Tuple(@_);
7968  }
7969  $self->SetFeature($feature) if $set;
7970  return unless defined wantarray;
7971  return @ret;
7972 }
7973 
7974 #** @method Union(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7975 # Object method.
7976 # The result layer contains features whose geometries represent areas
7977 # that are in either in the input layer or in the method layer. The
7978 # schema of the result layer can be set before calling this method, or
7979 # is initialized to contain all fields from this and method layer.
7980 # @param method method layer.
7981 # @param result result layer.
7982 # @param options a reference to an options hash.
7983 # @param callback [optional] a reference to a subroutine, which will
7984 # be called with parameters (number progress, string msg, callback_data)
7985 # @param callback_data [optional]
7986 #*
7987 sub Union {
7988 }
7989 
7990 #** @method Update(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, coderef callback, $callback_data)
7991 # Object method.
7992 # The result layer contains features whose geometries represent areas
7993 # that are either in the input layer or in the method layer. The
7994 # features in the result layer have areas of the features of the
7995 # method layer or those ares of the features of the input layer that
7996 # are not covered by the method layer. The features of the result
7997 # layer get their attributes from the input layer. The schema of the
7998 # result layer can be set by the user or, if it is empty, is
7999 # initialized to contain all fields in the input layer.
8000 # @param method method layer.
8001 # @param result result layer.
8002 # @param options a reference to an options hash.
8003 # @param callback [optional] a reference to a subroutine, which will
8004 # be called with parameters (number progress, string msg, callback_data)
8005 # @param callback_data [optional]
8006 #*
8007 sub Update {
8008 }
8009 
8010 #** @class Geo::OGR::StyleTable
8011 #*
8012 package Geo::OGR::StyleTable;
8013 
8014 use base qw(Geo::OGR)
8015 
8016 #** @method AddStyle()
8017 #*
8018 sub AddStyle {
8019 }
8020 
8021 #** @method Find()
8022 #*
8023 sub Find {
8024 }
8025 
8026 #** @method GetLastStyleName()
8027 #*
8028 sub GetLastStyleName {
8029 }
8030 
8031 #** @method GetNextStyle()
8032 #*
8033 sub GetNextStyle {
8034 }
8035 
8036 #** @method LoadStyleTable()
8037 #*
8038 sub LoadStyleTable {
8039 }
8040 
8041 #** @method ResetStyleStringReading()
8042 #*
8043 sub ResetStyleStringReading {
8044 }
8045 
8046 #** @method SaveStyleTable()
8047 #*
8048 sub SaveStyleTable {
8049 }
8050 
8051 #** @method new()
8052 #*
8053 sub new {
8054  my $pkg = shift;
8055  my $self = Geo::OGRc::new_StyleTable(@_);
8056  bless $self, $pkg if defined($self);
8057 }
8058 
8059 #** @class Geo::OSR
8060 # @brief Base class for projection related classes.
8061 # @details
8062 #*
8063 package Geo::OSR;
8064 
8065 #** @method list AngularUnits()
8066 # Package subroutine.
8067 # @return list of known angular units.
8068 #*
8069 sub AngularUnits {
8070  return keys %ANGULAR_UNITS;
8071 }
8072 
8073 #** @method CreateCoordinateTransformation()
8074 #*
8075 sub CreateCoordinateTransformation {
8076 }
8077 
8078 #** @method list Datums()
8079 # Package subroutine.
8080 # @return list of known datums.
8081 #*
8082 sub Datums {
8083  return keys %DATUMS;
8084 }
8085 
8086 #** @method GetPROJSearchPaths()
8087 #*
8088 sub GetPROJSearchPaths {
8089 }
8090 
8091 #** @method GetPROJVersionMajor()
8092 #*
8093 sub GetPROJVersionMajor {
8094 }
8095 
8096 #** @method GetPROJVersionMicro()
8097 #*
8098 sub GetPROJVersionMicro {
8099 }
8100 
8101 #** @method GetPROJVersionMinor()
8102 #*
8103 sub GetPROJVersionMinor {
8104 }
8105 
8106 #** @method scalar GetUserInputAsWKT($name)
8107 # Package subroutine.
8108 # @param name the user input
8109 # @return a WKT string.
8110 #*
8111 sub GetUserInputAsWKT {
8112 }
8113 
8114 #** @method scalar GetWellKnownGeogCSAsWKT($name)
8115 # Package subroutine.
8116 # @brief Get well known geographic coordinate system as WKT
8117 # @param name a well known name
8118 # @return a WKT string.
8119 #*
8120 sub GetWellKnownGeogCSAsWKT {
8121 }
8122 
8123 #** @method list LinearUnits()
8124 # Package subroutine.
8125 # @return list of known linear units.
8126 #*
8127 sub LinearUnits {
8128  return keys %LINEAR_UNITS;
8129 }
8130 
8131 #** @method OAMS_AUTHORITY_COMPLIANT()
8132 #*
8133 sub OAMS_AUTHORITY_COMPLIANT {
8134 }
8135 
8136 #** @method OAMS_CUSTOM()
8137 #*
8138 sub OAMS_CUSTOM {
8139 }
8140 
8141 #** @method OAMS_TRADITIONAL_GIS_ORDER()
8142 #*
8143 sub OAMS_TRADITIONAL_GIS_ORDER {
8144 }
8145 
8146 #** @method OAO_Down()
8147 #*
8148 sub OAO_Down {
8149 }
8150 
8151 #** @method OAO_East()
8152 #*
8153 sub OAO_East {
8154 }
8155 
8156 #** @method OAO_North()
8157 #*
8158 sub OAO_North {
8160 
8161 #** @method OAO_Other()
8162 #*
8163 sub OAO_Other {
8164 }
8165 
8166 #** @method OAO_South()
8167 #*
8168 sub OAO_South {
8169 }
8170 
8171 #** @method OAO_Up()
8172 #*
8173 sub OAO_Up {
8174 }
8175 
8176 #** @method OAO_West()
8177 #*
8178 sub OAO_West {
8179 }
8180 
8181 #** @method OSRAreaOfUse_east_lon_degree_get()
8182 #*
8183 sub OSRAreaOfUse_east_lon_degree_get {
8184 }
8185 
8186 #** @method OSRAreaOfUse_name_get()
8187 #*
8188 sub OSRAreaOfUse_name_get {
8189 }
8190 
8191 #** @method OSRAreaOfUse_north_lat_degree_get()
8192 #*
8193 sub OSRAreaOfUse_north_lat_degree_get {
8194 }
8195 
8196 #** @method OSRAreaOfUse_south_lat_degree_get()
8197 #*
8198 sub OSRAreaOfUse_south_lat_degree_get {
8199 }
8200 
8201 #** @method OSRAreaOfUse_west_lon_degree_get()
8202 #*
8203 sub OSRAreaOfUse_west_lon_degree_get {
8204 }
8205 
8206 #** @method list Parameters()
8207 # Package subroutine.
8208 # @return list of known projection parameters.
8209 #*
8210 sub Parameters {
8211  return keys %PARAMETERS;
8212 }
8213 
8214 #** @method list Projections()
8215 # Package subroutine.
8216 # @return list of known projections.
8217 #*
8218 sub Projections {
8219  return keys %PROJECTIONS;
8220 }
8221 
8222 #** @method SRS_PM_GREENWICH()
8223 #*
8224 sub SRS_PM_GREENWICH {
8225 }
8226 
8227 #** @method SRS_WGS84_INVFLATTENING()
8228 #*
8229 sub SRS_WGS84_INVFLATTENING {
8230 }
8231 
8232 #** @method SRS_WGS84_SEMIMAJOR()
8233 #*
8234 sub SRS_WGS84_SEMIMAJOR {
8235 }
8236 
8237 #** @method SRS_WKT_WGS84_LAT_LONG()
8238 #*
8239 sub SRS_WKT_WGS84_LAT_LONG {
8240 }
8241 
8242 #** @method SetPROJSearchPath()
8243 #*
8244 sub SetPROJSearchPath {
8245 }
8246 
8247 #** @method SetPROJSearchPaths()
8248 #*
8249 sub SetPROJSearchPaths {
8250 }
8251 
8252 #** @class Geo::OSR::AreaOfUse
8253 #*
8254 package Geo::OSR::AreaOfUse;
8255 
8256 use base qw(Geo::OSR)
8257 
8258 #** @method new()
8259 #*
8260 sub new {
8261  my $pkg = shift;
8262  my $self = Geo::OSRc::new_AreaOfUse(@_);
8263  bless $self, $pkg if defined($self);
8264 }
8265 
8266 #** @class Geo::OSR::CoordinateTransformation
8267 # @brief An object for transforming from one projection to another.
8268 # @details
8269 #*
8270 package Geo::OSR::CoordinateTransformation;
8271 
8272 use base qw(Geo::OSR)
8273 
8274 #** @method array reference TransformPoint($x, $y, $z)
8275 # Object method.
8276 # @param x
8277 # @param y
8278 # @param z [optional]
8279 # @return arrayref = [$x, $y, $z]
8280 #*
8281 sub TransformPoint {
8282 }
8283 
8284 #** @method TransformPoints(arrayref points)
8285 # Object method.
8286 # @param points [in/out] a reference to a list of points (line string
8287 # or ring) that is modified in-place. A list of points is: ([x, y, z],
8288 # [x, y, z], ...), where z is optional. Supports also lists of line
8289 # strings and polygons.
8290 #*
8291 sub TransformPoints {
8292  my($self, $points) = @_;
8293  _TransformPoints($self, $points), return unless ref($points->[0]->[0]);
8294  for my $p (@$points) {
8295  TransformPoints($self, $p);
8296  }
8297 }
8298 1;
8299 # This file was automatically generated by SWIG (http://www.swig.org).
8300 # Version 4.0.1
8301 #
8302 # Do not make changes to this file unless you know what you are doing--modify
8303 # the SWIG interface file instead.
8304 }
8305 
8306 #** @method Geo::OSR::CoordinateTransformation new($src, $dst)
8307 # Class method.
8308 # @param src a Geo::OSR::SpatialReference object
8309 # @param dst a Geo::OSR::SpatialReference object
8310 # @return a new Geo::OSR::CoordinateTransformation object
8311 #*
8312 sub new {
8313  my $pkg = shift;
8314  my $self = Geo::OSRc::new_CoordinateTransformation(@_);
8315  bless $self, $pkg if defined($self);
8316 }
8317 
8318 #** @class Geo::OSR::CoordinateTransformationOptions
8319 #*
8320 package Geo::OSR::CoordinateTransformationOptions;
8321 
8322 use base qw(Geo::OSR)
8323 
8324 #** @method SetAreaOfInterest()
8325 #*
8326 sub SetAreaOfInterest {
8327 }
8328 
8329 #** @method SetOperation()
8330 #*
8331 sub SetOperation {
8332 }
8333 
8334 #** @method new()
8335 #*
8336 sub new {
8337  my $pkg = shift;
8338  my $self = Geo::OSRc::new_CoordinateTransformationOptions(@_);
8339  bless $self, $pkg if defined($self);
8340 }
8341 
8342 #** @class Geo::OSR::SpatialReference
8343 # @brief A spatial reference system.
8344 # @details <a href="http://www.gdal.org/classOGRSpatialReference.html">Documentation
8345 # of the underlying C++ class at www.gdal.org</a>
8346 #*
8347 package Geo::OSR::SpatialReference;
8348 
8349 use base qw(Geo::OSR)
8350 
8351 #** @method AddGuessedTOWGS84()
8352 #*
8353 sub AddGuessedTOWGS84 {
8354 }
8355 
8356 #** @method As()
8357 #*
8358 sub As {
8359 }
8360 
8361 #** @method AutoIdentifyEPSG()
8362 # Object method.
8363 # Set EPSG authority info if possible.
8364 #*
8365 sub AutoIdentifyEPSG {
8366 }
8367 
8368 #** @method Geo::OSR::SpatialReference Clone()
8369 # Object method.
8370 # Make a duplicate of this SpatialReference object.
8371 # @return a new Geo::OSR::SpatialReference object
8372 #*
8373 sub Clone {
8374 }
8375 
8376 #** @method Geo::OSR::SpatialReference CloneGeogCS()
8377 # Object method.
8378 # Make a duplicate of the GEOGCS node of this SpatialReference object.
8379 # @return a new Geo::OSR::SpatialReference object
8380 #*
8381 sub CloneGeogCS {
8382 }
8383 
8384 #** @method ConvertToOtherProjection()
8385 #*
8386 sub ConvertToOtherProjection {
8387 }
8388 
8389 #** @method CopyGeogCSFrom($rhs)
8390 # Object method.
8391 # @param rhs Geo::OSR::SpatialReference
8392 #*
8393 sub CopyGeogCSFrom {
8394 }
8395 
8396 #** @method DemoteTo2D()
8397 #*
8398 sub DemoteTo2D {
8399 }
8400 
8401 #** @method EPSGTreatsAsLatLong()
8402 # Object method.
8403 # Returns TRUE if EPSG feels this geographic coordinate system should be treated as having lat/long coordinate ordering.
8404 #*
8405 sub EPSGTreatsAsLatLong {
8406 }
8407 
8408 #** @method EPSGTreatsAsNorthingEasting()
8409 #*
8410 sub EPSGTreatsAsNorthingEasting {
8411 }
8412 
8413 #** @method Export($format)
8414 # Object method.
8415 # Export the spatial reference to a selected format.
8416 # @note a.k.a. As
8417 #
8418 # @param format One of the following. The return value is explained
8419 # after the format. Other arguments are explained in parenthesis.
8420 # - WKT (Text): Well Known Text string
8421 # - PrettyWKT: Well Known Text string nicely formatted (simplify)
8422 # - Proj4: PROJ.4 string
8423 # - PCI: a list: ($proj_string, $units, [$parms1, ...])
8424 # - USGS: a list: ($code, $zone, [$parms1, ...], $datum)
8425 # - GML (XML): GML based string (dialect)
8426 # - MapInfoCS (MICoordSys): MapInfo style co-ordinate system definition
8427 #
8428 # @note The named parameter syntax also works and is needed is those
8429 # cases when other arguments need or may be given. The format should
8430 # be given using key as, 'to' or 'format'.
8431 #
8432 # @note ExportTo* and AsText methods also exist but are not documented here.
8433 #
8434 # @return a scalar or a list depending on the export format
8435 #*
8436 sub Export {
8437  my $self = shift;
8438  my $format;
8439  $format = pop if @_ == 1;
8440  my %params = @_;
8441  $format //= $params{to} //= $params{format} //= $params{as} //= '';
8442  my $simplify = $params{simplify} // 0;
8443  my $dialect = $params{dialect} // '';
8444  my %converters = (
8445  WKT => sub { return ExportToWkt($self) },
8446  Text => sub { return ExportToWkt($self) },
8447  PrettyWKT => sub { return ExportToPrettyWkt($self, $simplify) },
8448  Proj4 => sub { return ExportToProj4($self) },
8449  PCI => sub { return ExportToPCI($self) },
8450  USGS => sub { return ExportToUSGS($self) },
8451  GML => sub { return ExportToXML($self, $dialect) },
8452  XML => sub { return ExportToXML($self, $dialect) },
8453  MICoordSys => sub { return ExportToMICoordSys() },
8454  MapInfoCS => sub { return ExportToMICoordSys() },
8455  );
8456  error(1, $format, \%converters) unless $converters{$format};
8457  return $converters{$format}->();
8458 }
8459 
8460 #** @method ExportToPROJJSON()
8461 #*
8462 sub ExportToPROJJSON {
8463 }
8464 
8465 #** @method scalar GetAngularUnits()
8466 # Object method.
8467 # @return a number
8468 #*
8469 sub GetAngularUnits {
8470 }
8471 
8472 #** @method GetAngularUnitsName()
8473 #*
8474 sub GetAngularUnitsName {
8475 }
8476 
8477 #** @method GetAreaOfUse()
8478 #*
8479 sub GetAreaOfUse {
8480 }
8481 
8482 #** @method scalar GetAttrValue($name, $child = 0)
8483 # Object method.
8484 # @param name
8485 # @param child
8486 # @return string
8487 #*
8488 sub GetAttrValue {
8489 }
8490 
8491 #** @method scalar GetAuthorityCode($target_key)
8492 # Object method.
8493 # @param target_key
8494 # @return string
8495 #*
8496 sub GetAuthorityCode {
8497 }
8498 
8499 #** @method scalar GetAuthorityName($target_key)
8500 # Object method.
8501 # @param target_key
8502 # @return string
8503 #*
8504 sub GetAuthorityName {
8505 }
8506 
8507 #** @method GetAxesCount()
8508 #*
8509 sub GetAxesCount {
8510 }
8511 
8512 #** @method GetAxisMappingStrategy()
8513 #*
8514 sub GetAxisMappingStrategy {
8515 }
8516 
8517 #** @method GetAxisName()
8518 #*
8519 sub GetAxisName {
8520 }
8521 
8522 #** @method GetAxisOrientation()
8523 #*
8524 sub GetAxisOrientation {
8525 }
8526 
8527 #** @method GetDataAxisToSRSAxisMapping()
8528 #*
8529 sub GetDataAxisToSRSAxisMapping {
8530 }
8531 
8532 #** @method GetInvFlattening()
8533 # Object method.
8534 #*
8535 sub GetInvFlattening {
8536 }
8537 
8538 #** @method scalar GetLinearUnits()
8539 # Object method.
8540 # @return a number
8541 #*
8542 sub GetLinearUnits {
8543 }
8544 
8545 #** @method scalar GetLinearUnitsName()
8546 # Object method.
8547 # @return string
8548 #*
8549 sub GetLinearUnitsName {
8550 }
8551 
8552 #** @method GetName()
8553 #*
8554 sub GetName {
8555 }
8556 
8557 #** @method scalar GetNormProjParm($name, $default_val = 0.0)
8558 # Object method.
8559 # @param name
8560 # @param default_val
8561 # @return a number
8562 #*
8563 sub GetNormProjParm {
8564 }
8565 
8566 #** @method scalar GetProjParm($name, $default_val = 0.0)
8567 # Object method.
8568 # @param name
8569 # @param default_val
8570 # @return a number
8571 #*
8572 sub GetProjParm {
8573 }
8574 
8575 #** @method GetSemiMajor()
8576 # Object method.
8577 #*
8578 sub GetSemiMajor {
8579 }
8580 
8581 #** @method GetSemiMinor()
8582 # Object method.
8583 #*
8584 sub GetSemiMinor {
8585 }
8586 
8587 #** @method GetTOWGS84()
8588 # Object method.
8589 # @return array = ($p1, $p2, $p3, $p4, $p5, $p6, $p7)
8590 #*
8591 sub GetTOWGS84 {
8592 }
8593 
8594 #** @method GetTargetLinearUnits()
8595 #*
8596 sub GetTargetLinearUnits {
8597 }
8598 
8599 #** @method GetUTMZone()
8600 # Object method.
8601 # Get UTM zone information.
8602 # @return The UTM zone (integer). In scalar context the returned value
8603 # is negative for southern hemisphere zones. In list context returns
8604 # two values ($zone, $north), where $zone is always non-negative and
8605 # $north is true or false.
8606 #*
8607 sub GetUTMZone {
8608  my $self = shift;
8609  my $zone = _GetUTMZone($self);
8610  if (wantarray) {
8611  my $north = 1;
8612  if ($zone < 0) {
8613  $zone *= -1;
8614  $north = 0;
8615  }
8616  return ($zone, $north);
8617  } else {
8618  return $zone;
8619  }
8620 }
8621 
8622 #** @method HasTOWGS84()
8623 #*
8624 sub HasTOWGS84 {
8625 }
8626 
8627 #** @method ImportFromOzi()
8628 #*
8629 sub ImportFromOzi {
8630 }
8631 
8632 #** @method scalar IsCompound()
8633 # Object method.
8634 # @return boolean
8635 #*
8636 sub IsCompound {
8637 }
8638 
8639 #** @method IsDerivedGeographic()
8640 #*
8641 sub IsDerivedGeographic {
8642 }
8643 
8644 #** @method scalar IsGeocentric()
8645 # Object method.
8646 # @return boolean
8647 #*
8648 sub IsGeocentric {
8649 }
8650 
8651 #** @method scalar IsGeographic()
8652 # Object method.
8653 # @return boolean
8654 #*
8655 sub IsGeographic {
8656 }
8657 
8658 #** @method scalar IsLocal()
8659 # Object method.
8660 # @return boolean
8661 #*
8662 sub IsLocal {
8663 }
8664 
8665 #** @method scalar IsProjected()
8666 # Object method.
8667 # @return boolean
8668 #*
8669 sub IsProjected {
8670 }
8671 
8672 #** @method scalar IsSame($rs)
8673 # Object method.
8674 # @param rs a Geo::OSR::SpatialReference object
8675 # @return boolean
8676 #*
8677 sub IsSame {
8678 }
8679 
8680 #** @method scalar IsSameGeogCS($rs)
8681 # Object method.
8682 # @param rs a Geo::OSR::SpatialReference object
8683 # @return boolean
8684 #*
8685 sub IsSameGeogCS {
8686 }
8687 
8688 #** @method scalar IsSameVertCS($rs)
8689 # Object method.
8690 # @param rs a Geo::OSR::SpatialReference object
8691 # @return boolean
8692 #*
8693 sub IsSameVertCS {
8694 }
8695 
8696 #** @method scalar IsVertical()
8697 # Object method.
8698 # @return boolean
8699 #*
8700 sub IsVertical {
8701 }
8702 
8703 #** @method MorphFromESRI()
8704 # Object method.
8705 #*
8706 sub MorphFromESRI {
8707 }
8708 
8709 #** @method MorphToESRI()
8710 # Object method.
8711 #*
8712 sub MorphToESRI {
8713 }
8714 
8715 #** @method PromoteTo3D()
8716 #*
8717 sub PromoteTo3D {
8718 }
8719 
8720 #** @method Set(%params)
8721 # Object method.
8722 # Set a parameter or parameters in the spatial reference object.
8723 # @param params Named parameters. Recognized keys and respective
8724 # values are the following.
8725 # - Authority: authority name (give also TargetKey, Node and Code)
8726 # - TargetKey:
8727 # - Node: partial or complete path to the target node (Node and Value together sets an attribute value)
8728 # - Code: code for value with an authority
8729 # - Value: value to be assigned to a node, a projection parameter or an object
8730 # - AngularUnits: angular units for the geographic coordinate system (give also Value) (one of Geo::OSR::LinearUnits)
8731 # - LinearUnits: linear units for the target node or the object (give also Value and optionally Node) (one of Geo::OSR::LinearUnits)
8732 # - Parameter: projection parameter to set (give also Value and Normalized) (one of Geo::OSR::Parameters)
8733 # - Normalized: set to true to indicate that the Value argument is in "normalized" form
8734 # - Name: a well known name of a geographic coordinate system (e.g. WGS84)
8735 # - GuessFrom: arbitrary text that specifies a projection ("user input")
8736 # - LOCAL_CS: name of a local coordinate system
8737 # - GeocentricCS: name of a geocentric coordinate system
8738 # - VerticalCS: name of a vertical coordinate system (give also Datum and optionally VertDatumType [default is 2005])
8739 # - Datum: a known (OGC or EPSG) name (or(?) one of Geo::OSR::Datums)
8740 # - 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
8741 # - Parameters: a reference to a list containing the coordinate system or projection parameters
8742 # - Zone: zone for setting up UTM or State Plane coordinate systems (State Plane zone in USGS numbering scheme)
8743 # - North: set false for southern hemisphere
8744 # - NAD83: set false if the NAD27 zone definition should be used instead of NAD83
8745 # - UnitName: to override the legal definition for a zone
8746 # - UnitConversionFactor: to override the legal definition for a zone
8747 # - Spheroid: user visible name
8748 # - HorizontalCS: Horizontal coordinate system name
8749 # - Projection: name of a projection, one of Geo::OSR::Projections (give also optionally Parameters and Variant)
8750 #
8751 # @note Numerous Set* methods also exist but are not documented here.
8752 #*
8753 sub Set {
8754  my($self, %params) = @_;
8755  if (exists $params{Authority} and exists $params{TargetKey} and exists $params{Node} and exists $params{Code}) {
8756  SetAuthority($self, $params{TargetKey}, $params{Authority}, $params{Code});
8757  } elsif (exists $params{Node} and exists $params{Value}) {
8758  SetAttrValue($self, $params{Node}, $params{Value});
8759  } elsif (exists $params{AngularUnits} and exists $params{Value}) {
8760  SetAngularUnits($self, $params{AngularUnits}, $params{Value});
8761  } elsif (exists $params{LinearUnits} and exists $params{Node} and exists $params{Value}) {
8762  SetTargetLinearUnits($self, $params{Node}, $params{LinearUnits}, $params{Value});
8763  } elsif (exists $params{LinearUnits} and exists $params{Value}) {
8764  SetLinearUnitsAndUpdateParameters($self, $params{LinearUnits}, $params{Value});
8765  } elsif ($params{Parameter} and exists $params{Value}) {
8766  error(1, $params{Parameter}, \%Geo::OSR::PARAMETERS) unless exists $Geo::OSR::PARAMETERS{$params{Parameter}};
8767  $params{Normalized} ?
8768  SetNormProjParm($self, $params{Parameter}, $params{Value}) :
8769  SetProjParm($self, $params{Parameter}, $params{Value});
8770  } elsif (exists $params{Name}) {
8771  SetWellKnownGeogCS($self, $params{Name});
8772  } elsif (exists $params{GuessFrom}) {
8773  SetFromUserInput($self, $params{GuessFrom});
8774  } elsif (exists $params{LOCAL_CS}) {
8775  SetLocalCS($self, $params{LOCAL_CS});
8776  } elsif (exists $params{GeocentricCS}) {
8777  SetGeocCS($self, $params{GeocentricCS});
8778  } elsif (exists $params{VerticalCS} and $params{Datum}) {
8779  my $type = $params{VertDatumType} || 2005;
8780  SetVertCS($self, $params{VerticalCS}, $params{Datum}, $type);
8781  } elsif (exists $params{CoordinateSystem}) {
8782  my @parameters = ();
8783  @parameters = @{$params{Parameters}} if ref($params{Parameters});
8784  if ($params{CoordinateSystem} eq 'State Plane' and exists $params{Zone}) {
8785  my $NAD83 = exists $params{NAD83} ? $params{NAD83} : 1;
8786  my $name = exists $params{UnitName} ? $params{UnitName} : undef;
8787  my $c = exists $params{UnitConversionFactor} ? $params{UnitConversionFactor} : 0.0;
8788  SetStatePlane($self, $params{Zone}, $NAD83, $name, $c);
8789  } elsif ($params{CoordinateSystem} eq 'UTM' and exists $params{Zone} and exists $params{North}) {
8790  my $north = exists $params{North} ? $params{North} : 1;
8791  SetUTM($self, $params{Zone}, $north);
8792  } elsif ($params{CoordinateSystem} eq 'WGS') {
8793  SetTOWGS84($self, @parameters);
8794  } elsif ($params{CoordinateSystem} and $params{Datum} and $params{Spheroid}) {
8795  SetGeogCS($self, $params{CoordinateSystem}, $params{Datum}, $params{Spheroid}, @parameters);
8796  } elsif ($params{CoordinateSystem} and $params{HorizontalCS} and $params{VerticalCS}) {
8797  SetCompoundCS($self, $params{CoordinateSystem}, $params{HorizontalCS}, $params{VerticalCS});
8798  } else {
8799  SetProjCS($self, $params{CoordinateSystem});
8800  }
8801  } elsif (exists $params{Projection}) {
8802  error(1, $params{Projection}, \%Geo::OSR::PROJECTIONS) unless exists $Geo::OSR::PROJECTIONS{$params{Projection}};
8803  my @parameters = ();
8804  @parameters = @{$params{Parameters}} if ref($params{Parameters});
8805  if ($params{Projection} eq 'Albers_Conic_Equal_Area') {
8806  SetACEA($self, @parameters);
8807  } elsif ($params{Projection} eq 'Azimuthal_Equidistant') {
8808  SetAE($self, @parameters);
8809  } elsif ($params{Projection} eq 'Bonne') {
8810  SetBonne($self, @parameters);
8811  } elsif ($params{Projection} eq 'Cylindrical_Equal_Area') {
8812  SetCEA($self, @parameters);
8813  } elsif ($params{Projection} eq 'Cassini_Soldner') {
8814  SetCS($self, @parameters);
8815  } elsif ($params{Projection} eq 'Equidistant_Conic') {
8816  SetEC($self, @parameters);
8817  # Eckert_I, Eckert_II, Eckert_III, Eckert_V ?
8818  } elsif ($params{Projection} eq 'Eckert_IV') {
8819  SetEckertIV($self, @parameters);
8820  } elsif ($params{Projection} eq 'Eckert_VI') {
8821  SetEckertVI($self, @parameters);
8822  } elsif ($params{Projection} eq 'Equirectangular') {
8823  @parameters == 4 ?
8824  SetEquirectangular($self, @parameters) :
8825  SetEquirectangular2($self, @parameters);
8826  } elsif ($params{Projection} eq 'Gauss_Schreiber_Transverse_Mercator') {
8827  SetGaussSchreiberTMercator($self, @parameters);
8828  } elsif ($params{Projection} eq 'Gall_Stereographic') {
8829  SetGS($self, @parameters);
8830  } elsif ($params{Projection} eq 'Goode_Homolosine') {
8831  SetGH($self, @parameters);
8832  } elsif ($params{Projection} eq 'Interrupted_Goode_Homolosine') {
8833  SetIGH($self);
8834  } elsif ($params{Projection} eq 'Geostationary_Satellite') {
8835  SetGEOS($self, @parameters);
8836  } elsif ($params{Projection} eq 'Gnomonic') {
8837  SetGnomonic($self, @parameters);
8838  } elsif ($params{Projection} eq 'Hotine_Oblique_Mercator') {
8839  # Hotine_Oblique_Mercator_Azimuth_Center ?
8840  SetHOM($self, @parameters);
8841  } elsif ($params{Projection} eq 'Hotine_Oblique_Mercator_Two_Point_Natural_Origin') {
8842  SetHOM2PNO($self, @parameters);
8843  } elsif ($params{Projection} eq 'Krovak') {
8844  SetKrovak($self, @parameters);
8845  } elsif ($params{Projection} eq 'Lambert_Azimuthal_Equal_Area') {
8846  SetLAEA($self, @parameters);
8847  } elsif ($params{Projection} eq 'Lambert_Conformal_Conic_2SP') {
8848  SetLCC($self, @parameters);
8849  } elsif ($params{Projection} eq 'Lambert_Conformal_Conic_1SP') {
8850  SetLCC1SP($self, @parameters);
8851  } elsif ($params{Projection} eq 'Lambert_Conformal_Conic_2SP_Belgium') {
8852  SetLCCB($self, @parameters);
8853  } elsif ($params{Projection} eq 'miller_cylindrical') {
8854  SetMC($self, @parameters);
8855  } elsif ($params{Projection} =~ /^Mercator/) {
8856  # Mercator_1SP, Mercator_2SP, Mercator_Auxiliary_Sphere ?
8857  # variant is in Variant (or Name)
8858  SetMercator($self, @parameters);
8859  } elsif ($params{Projection} eq 'Mollweide') {
8860  SetMollweide($self, @parameters);
8861  } elsif ($params{Projection} eq 'New_Zealand_Map_Grid') {
8862  SetNZMG($self, @parameters);
8863  } elsif ($params{Projection} eq 'Oblique_Stereographic') {
8864  SetOS($self, @parameters);
8865  } elsif ($params{Projection} eq 'Orthographic') {
8866  SetOrthographic($self, @parameters);
8867  } elsif ($params{Projection} eq 'Polyconic') {
8868  SetPolyconic($self, @parameters);
8869  } elsif ($params{Projection} eq 'Polar_Stereographic') {
8870  SetPS($self, @parameters);
8871  } elsif ($params{Projection} eq 'Robinson') {
8872  SetRobinson($self, @parameters);
8873  } elsif ($params{Projection} eq 'Sinusoidal') {
8874  SetSinusoidal($self, @parameters);
8875  } elsif ($params{Projection} eq 'Stereographic') {
8876  SetStereographic($self, @parameters);
8877  } elsif ($params{Projection} eq 'Swiss_Oblique_Cylindrical') {
8878  SetSOC($self, @parameters);
8879  } elsif ($params{Projection} eq 'Transverse_Mercator_South_Orientated') {
8880  SetTMSO($self, @parameters);
8881  } elsif ($params{Projection} =~ /^Transverse_Mercator/) {
8882  my($variant) = $params{Projection} =~ /^Transverse_Mercator_(\w+)/;
8883  $variant //= $params{Variant} //= $params{Name};
8884  $variant ?
8885  SetTMVariant($self, $variant, @parameters) :
8886  SetTM($self, @parameters);
8887  } elsif ($params{Projection} eq 'Tunisia_Mining_Grid') {
8888  SetTMG($self, @parameters);
8889  } elsif ($params{Projection} eq 'VanDerGrinten') {
8890  SetVDG($self, @parameters);
8891  } else {
8892  # Aitoff, Craster_Parabolic, International_Map_of_the_World_Polyconic, Laborde_Oblique_Mercator
8893  # Loximuthal, Miller_Cylindrical, Quadrilateralized_Spherical_Cube, Quartic_Authalic, Two_Point_Equidistant
8894  # Wagner_I, Wagner_II, Wagner_III, Wagner_IV, Wagner_V, Wagner_VI, Wagner_VII
8895  # Winkel_I, Winkel_II, Winkel_Tripel
8896  # ?
8897  SetProjection($self, $params{Projection});
8898  }
8899  } else {
8900  error("Not enough information to create a spatial reference object.");
8901  }
8902 }
8903 
8904 #** @method SetAxisMappingStrategy()
8905 #*
8906 sub SetAxisMappingStrategy {
8908 
8909 #** @method SetDataAxisToSRSAxisMapping()
8910 #*
8911 sub SetDataAxisToSRSAxisMapping {
8912 }
8913 
8914 #** @method SetMercator2SP()
8915 #*
8916 sub SetMercator2SP {
8917 }
8918 
8919 #** @method SetVerticalPerspective()
8920 #*
8921 sub SetVerticalPerspective {
8922 }
8923 
8924 #** @method Validate()
8925 # Object method.
8926 #*
8927 sub Validate {
8928 }
8929 
8930 #** @method Geo::OSR::SpatialReference new(%params)
8931 # Class method.
8932 # Create a new spatial reference object using a named parameter. This
8933 # constructor recognizes the following key words (alternative in
8934 # parenthesis): WKT (Text), Proj4, ESRI, EPSG, EPSGA, PCI, USGS, GML
8935 # (XML), URL, ERMapper (ERM), MapInfoCS (MICoordSys). The value
8936 # depends on the key.
8937 # - WKT: Well Known Text string
8938 # - Proj4: PROJ.4 string
8939 # - ESRI: reference to a list of strings (contents of ESRI .prj file)
8940 # - EPSG: EPSG code number
8941 # - EPSGA: EPSG code number (the resulting CS will have EPSG preferred axis ordering)
8942 # - PCI: listref: [PCI_projection_string, Grid_units_code, [17 cs parameters]]
8943 # - USGS: listref: [Projection_system_code, Zone, [15 cs parameters], Datum_code, Format_flag]
8944 # - GML: GML string
8945 # - URL: URL for downloading the spatial reference from
8946 # - ERMapper: listref: [Projection, Datum, Units]
8947 # - MapInfoCS: MapInfo style co-ordinate system definition
8948 #
8949 # For more information, consult the import methods in <a href="http://www.gdal.org/classOGRSpatialReference.html">OGR documentation</a>.
8950 #
8951 # @note ImportFrom* methods also exist but are not documented here.
8952 #
8953 # Usage:
8954 # \code
8955 # $sr = Geo::OSR::SpatialReference->new( key => value );
8956 # \endcode
8957 # @return a new Geo::OSR::SpatialReference object
8958 #*
8959 sub new {
8960  my $pkg = shift;
8961  my %param = @_;
8962  my $self = Geo::OSRc::new_SpatialReference();
8963  if (exists $param{WKT}) {
8964  ImportFromWkt($self, $param{WKT});
8965  } elsif (exists $param{Text}) {
8966  ImportFromWkt($self, $param{Text});
8967  } elsif (exists $param{Proj4}) {
8968  ImportFromProj4($self, $param{Proj4});
8969  } elsif (exists $param{ESRI}) {
8970  ImportFromESRI($self, @{$param{ESRI}});
8971  } elsif (exists $param{EPSG}) {
8972  ImportFromEPSG($self, $param{EPSG});
8973  } elsif (exists $param{EPSGA}) {
8974  ImportFromEPSGA($self, $param{EPSGA});
8975  } elsif (exists $param{PCI}) {
8976  ImportFromPCI($self, @{$param{PCI}});
8977  } elsif (exists $param{USGS}) {
8978  ImportFromUSGS($self, @{$param{USGS}});
8979  } elsif (exists $param{XML}) {
8980  ImportFromXML($self, $param{XML});
8981  } elsif (exists $param{GML}) {
8982  ImportFromGML($self, $param{GML});
8983  } elsif (exists $param{URL}) {
8984  ImportFromUrl($self, $param{URL});
8985  } elsif (exists $param{ERMapper}) {
8986  ImportFromERM($self, @{$param{ERMapper}});
8987  } elsif (exists $param{ERM}) {
8988  ImportFromERM($self, @{$param{ERM}});
8989  } elsif (exists $param{MICoordSys}) {
8990  ImportFromMICoordSys($self, $param{MICoordSys});
8991  } elsif (exists $param{MapInfoCS}) {
8992  ImportFromMICoordSys($self, $param{MapInfoCS});
8993  } elsif (exists $param{WGS}) {
8994  eval {
8995  SetWellKnownGeogCS($self, 'WGS'.$param{WGS});
8996  };
8997  confess last_error() if $@;
8998  } else {
8999  error("Unrecognized/missing parameters: @_.");
9000  }
9001  bless $self, $pkg if defined $self;
9002 }
9003 
public Geo::GDAL::Extent new(array params)
public method IsEmpty()
A definition of a non-spatial attribute.
Definition: all.pm:12141
The schema of a feature or a layer.
Definition: all.pm:11731
public Geo::OGR::Geometry new(hash params)
public Geo::GDAL::Dataset OpenEx(hash params)
public Geo::GDAL::ColorTable new(scalar GDALPaletteInterp='RGB')
A set of associated raster bands or vector layer source.
Definition: all.pm:4052
public Geo::GDAL::Band Band(scalar index)
public scalar Overlaps(scalar extent)
A driver for a specific dataset format.
Definition: all.pm:5940
An attribute table in a raster band.
Definition: all.pm:8159
public Geo::GDAL::Dataset Create(hash params)
public method new(array params)
public method AddGeometry(scalar other)
public Geo::OGR::FieldDefn new(hash params)
Create a new field definition.
A simple XML parser
Definition: all.pm:9303
public Geo::OSR::SpatialReference new(hash params)
public method VSIFFlushL()
public Geo::GDAL::Driver Driver(scalar Name)
public scalar GeometryType()
public Geo::OGR::GeomFieldDefn new(hash params)
Create a new spatial field definition.
Spatial data.
Definition: all.pm:13099
public list GeometryTypes()
A color table from a raster band or a color table, which can be used for a band. ...
Definition: all.pm:3866
public Geo::OGR::Feature new(hash schema)
Create a new feature.
public Geo::OGR::FeatureDefn new(hash schema)
public list Tuple(array tuple)
public array reference Points(arrayref points)
A raster band.
Definition: all.pm:2080
public method Set3D()
A rectangular area in projection coordinates: xmin, ymin, xmax, ymax.
Definition: all.pm:6685
An object, which holds meta data.
Definition: all.pm:7963
A collection of similar features.
Definition: all.pm:15747
public scalar GetDataTypeSize(scalar DataType)
Definition: all.pm:13
A spatial reference system.
Definition: all.pm:18373
public scalar PackCharacter(scalar DataType)
An array of affine transformation coefficients.
Definition: all.pm:7040
A collection of non-spatial and spatial attributes.
Definition: all.pm:10671
A definition of a spatial attribute.
Definition: all.pm:12724