Geo::GDAL  2.0
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 #
4 # Geo::GDAL wraps many GDAL utility functions and acts as a root class
5 # for all GDAL raster classes. A "raster" is a dataset, whose core is
6 # a rectagular grid or grids of pixels, called a "band" in GDAL. Each
7 # pixel contains a numeric value of a specific data type
8 #*
9 package Geo::GDAL;
10 
11 use base qw()
12 
13 #** @method list AccessTypes()
14 # Class method.
15 # @return a list of GDAL data set open modes. These are currently:
16 # ReadOnly, and Update.
17 #*
18 sub AccessTypes {
19  return @ACCESS_TYPES;
20 }
21 
22 #** @method Geo::GDAL::Dataset AutoCreateWarpedVRT(Geo::GDAL::Dataset src, Geo::OSR::SpatialReference src_srs=undef, Geo::OSR::SpatialReference dst_srs=undef, $ResampleAlg='NearestNeighbour', $maxerror=0.0)
23 # Class method.
24 # @param src
25 # @param src_srs source projection.
26 # @param dst_srs destination projection.
27 # @param ResampleAlg one of Geo::GDAL::ResamplingTypes().
28 # @param maxerror
29 # @return a new Geo::GDAL::Dataset object
30 #
31 # <a href="http://www.gdal.org/gdalwarper_8h.html">Documentation for GDAL warper</a>
32 #*
33 sub AutoCreateWarpedVRT {
34  my @p = @_;
35  for my $i (1..2) {
36  if (defined $p[$i] and ref($p[$i])) {
37  $p[$i] = $p[$i]->ExportToWkt;
38  }
39  }
40  if (defined $p[3]) {
41  confess "Unknown data type: '$p[3]'." unless exists $Geo::GDAL::RESAMPLING_STRING2INT{$p[3]};
42  $p[3] = $Geo::GDAL::RESAMPLING_STRING2INT{$p[3]};
43  }
44  return _AutoCreateWarpedVRT(@p);
45 }
46 
47 #** @method CPLBinaryToHex()
48 #*
49 sub CPLBinaryToHex {
50 }
51 
52 #** @method CPLHexToBinary()
53 #*
54 sub CPLHexToBinary {
55 }
56 
57 #** @method list Child($node, $i)
58 # Class method.
59 # @param node
60 # @param i 0 .. number of children - 1
61 # @return
62 #*
63 sub Child {
64  my($node, $child) = @_;
65  return $node->[2+$child];
66 }
67 
68 #** @method list Children($node)
69 # Class method.
70 # @param node
71 # @return
72 #*
73 sub Children {
74  my $node = shift;
75  return @$node[2..$#$node];
76 }
77 
78 #** @method ComputeMedianCutPCT(Geo::GDAL::Band red, Geo::GDAL::Band green, Geo::GDAL::Band blue, $num_colors, $colors, subref progress, $progress_data)
79 # Class method.
80 # Compute an "optimal" color table for a three band image.
81 # @param red a Geo::GDAL::Band object
82 # @param green a Geo::GDAL::Band object
83 # @param blue a Geo::GDAL::Band object
84 # @param num_colors the desired number of colors
85 # @param colors an empty Geo::GDAL::ColorTable object
86 # @param progress [optional] a reference to a subroutine, which will
87 # be called with parameters (number progress, string msg, progress_data)
88 # @param progress_data [optional]
89 #
90 # <a href="http://www.gdal.org/gdal__alg_8h.html">Documentation for GDAL algorithms</a>
91 #*
92 sub ComputeMedianCutPCT {
93  my @p = @_;
94  $p[6] = 1 if $p[5] and not defined $p[6];
95  _ComputeMedianCutPCT(@p);
96 }
97 
98 #** @method ComputeProximity(Geo::GDAL::Band src, Geo::GDAL::Band proximity, hashref options, subref progress, $progress_data)
99 # Class method.
100 # @param src The raster from which the proximities are computed from.
101 # @param proximity The raster to which the proximities are computed to.
102 # @param options Options. Supported key, value pairs are
103 # - VALUES => n[,n]* A list of target pixel values to measure the
104 # distance from. If this option is not provided proximity will be
105 # computed from non-zero pixel values. Currently pixel values are
106 # internally processed as integers.
107 # - DISTUNITS => PIXEL|GEO Indicates whether distances will be
108 # computed in pixel units or in georeferenced units. The default is
109 # pixel units. This also determines the interpretation of MAXDIST.
110 # - MAXDIST => n The maximum distance to search. Proximity distances
111 # greater than this value will not be computed. Instead output pixels
112 # will be set to a nodata value.
113 # - NODATA => n The NODATA value to use on the output band for pixels
114 # that are beyond MAXDIST. If not provided, the hProximityBand will
115 # be queried for a nodata value. If one is not found, 65535 will be
116 # used.
117 # - FIXED_BUF_VAL => n If this option is set, all pixels within the
118 # MAXDIST threadhold are set to this fixed value instead of to a
119 # proximity distance.
120 # @param progress [optional] a reference to a subroutine, which will
121 # be called with parameters (number progress, string msg, progress_data)
122 # @param progress_data [optional]
123 #
124 # <a href="http://www.gdal.org/gdal__alg_8h.html">Documentation for GDAL algorithms</a>
125 #*
126 sub ComputeProximity {
127  my @p = @_;
128  $p[4] = 1 if $p[3] and not defined $p[4];
129  _ComputeProximity(@p);
130 }
131 
132 #** @method scalar DataTypeIsComplex($DataType)
133 # Class method.
134 # @param DataType A GDAL pixel data type (one of those listed by Geo::GDAL::DataTypes).
135 # @return true if the data type is a complex number.
136 #*
137 sub DataTypeIsComplex {
138  my $t = shift;
139  my $t2 = $t;
140  $t2 = $TYPE_STRING2INT{$t} if exists $TYPE_STRING2INT{$t};
141  confess "Unknown data type: '$t'." unless exists $TYPE_INT2STRING{$t2};
142  return _DataTypeIsComplex($t2);
143 }
144 
145 #** @method list DataTypeValueRange($DataType)
146 # Class method.
147 # @param DataType Data type (one of those listed by Geo::GDAL::DataTypes).
148 # @note Some returned values are inaccurate.
149 #
150 # @return the minimum, maximum range of the data type.
151 #*
152 sub DataTypeValueRange {
153  my $t = shift;
154  confess "Unknown data type: '$t'." unless exists $TYPE_STRING2INT{$t};
155  # these values are from gdalrasterband.cpp
156  return (0,255) if $t =~ /Byte/;
157  return (0,65535) if $t =~/UInt16/;
158  return (-32768,32767) if $t =~/Int16/;
159  return (0,4294967295) if $t =~/UInt32/;
160  return (-2147483648,2147483647) if $t =~/Int32/;
161  return (-4294967295.0,4294967295.0) if $t =~/Float32/;
162  return (-4294967295.0,4294967295.0) if $t =~/Float64/;
163 }
164 
165 #** @method list DataTypes()
166 # Class method.
167 # @return a list of GDAL pixel data types. These are currently:
168 # Byte, CFloat32, CFloat64, CInt16, CInt32, Float32, Float64, Int16, Int32, UInt16, UInt32, and Unknown.
169 #*
170 sub DataTypes {
171  return @DATA_TYPES;
172 }
173 
174 #** @method Debug()
175 #*
176 sub Debug {
177 }
178 
179 #** @method scalar DecToDMS($angle, $axis, $precision=2)
180 # Class method.
181 # Convert decimal degrees to degrees, minutes, and seconds string
182 # @param angle A number
183 # @param axis A string specifying latitude or longitude ('Long').
184 # @param precision
185 # @return a string nndnn'nn.nn'"L where n is a number and L is either
186 # N or E
187 #*
188 sub DecToDMS {
189 }
190 
191 #** @method scalar DecToPackedDMS($dec)
192 # Class method.
193 # @param dec Decimal degrees
194 # @return packed DMS, i.e., a number DDDMMMSSS.SS
195 #*
196 sub DecToPackedDMS {
197 }
198 
199 #** @method DitherRGB2PCT($red, $green, $blue, $target, $colors, subref progress, $progress_data)
200 # Class method.
201 # Dither a three band image into one band using a color table.
202 # @param red a Geo::GDAL::Band object
203 # @param green a Geo::GDAL::Band object
204 # @param blue a Geo::GDAL::Band object
205 # @param target a Geo::GDAL::Band object
206 # @param colors a Geo::GDAL::ColorTable object
207 # @param progress [optional] a reference to a subroutine, which will
208 # be called with parameters (number progress, string msg, progress_data)
209 # @param progress_data [optional]
210 #
211 # <a href="http://www.gdal.org/gdal__alg_8h.html">Documentation for GDAL algorithms</a>
212 #*
213 sub DitherRGB2PCT {
214  my @p = @_;
215  $p[6] = 1 if $p[5] and not defined $p[6];
216  _DitherRGB2PCT(@p);
217 }
218 
219 #** @method EscapeString()
220 #*
221 sub EscapeString {
222 }
223 
224 #** @method scalar FindFile($class, $basename)
225 # Class method.
226 # Search for GDAL support files.
227 #
228 # An example:
229 # \code
230 # use Geo::GDAL;
231 # $a = Geo::GDAL::FindFile('gdal', 'pcs.csv');
232 # print STDERR "$a\n";
233 # \endcode
234 # Prints (for example):
235 # \code
236 # c:\msys\1.0\local\share\gdal\pcs.csv
237 # \endcode
238 #
239 # @param class The class of files to search for. For example 'gdal'.
240 # @param basename The basename of the file to search for. For example
241 # 'pcs.csv'.
242 # @return the path to the searched file or undef.
243 #*
244 sub FindFile {
245 }
246 
247 #** @method FinderClean()
248 # Class method.
249 # Clear the set of support file search paths.
250 #*
251 sub FinderClean {
252 }
253 
254 #** @method GOA2GetAccessToken()
255 #*
256 sub GOA2GetAccessToken {
257 }
258 
259 #** @method GOA2GetAuthorizationURL()
260 #*
261 sub GOA2GetAuthorizationURL {
262 }
263 
264 #** @method GOA2GetRefreshToken()
265 #*
266 sub GOA2GetRefreshToken {
267 }
268 
269 #** @method scalar GetCacheMax()
270 # Class method.
271 # @return maximum amount of memory (as bytes) for caching within GDAL.
272 #*
273 sub GetCacheMax {
274 }
275 
276 #** @method scalar GetCacheUsed()
277 # Class method.
278 # @return the amount of memory currently used for caching within GDAL.
279 #*
280 sub GetCacheUsed {
281 }
282 
283 #** @method scalar GetConfigOption($key, $default)
284 # Class method.
285 # @param key A GDAL config option.
286 # @param default A default value for the option.
287 # @return the value of the GDAL config option or the value of the
288 # default parameter.
289 #*
290 sub GetConfigOption {
291 }
292 
293 #** @method scalar GetDataTypeSize($DataType)
294 # Class method.
295 # @param DataType A GDAL pixel data type (one of those listed by Geo::GDAL::DataTypes).
296 # @return the size as the number of bits.
297 #*
298 sub GetDataTypeSize {
299  my $t = shift;
300  my $t2 = $t;
301  $t2 = $TYPE_STRING2INT{$t} if exists $TYPE_STRING2INT{$t};
302  confess "Unknown data type: '$t'." unless exists $TYPE_INT2STRING{$t2};
303  return _GetDataTypeSize($t2);
304 }
305 
306 #** @method Geo::GDAL::Driver GetDriver($name)
307 # Class method.
308 # Create a driver object for the internal GDAL driver.
309 # @param name the (short) name of the driver.
310 # @return a Geo::GDAL::Driver object, which represents the internal driver.
311 #*
312 sub GetDriver {
313  my($name) = @_;
314  $name = 0 unless defined $name;
315  my $driver;
316  $driver = _GetDriver($name) if $name =~ /^\d+$/; # is the name an index to driver list?
317  $driver = GetDriverByName("$name") unless $driver;
318  if ($driver) {
319  my $md = $driver->GetMetadata;
320  confess "Driver exists but does not have raster capabilities."
321  unless $md->{DCAP_RASTER} and $md->{DCAP_RASTER} eq 'YES';
322  return $driver;
323  }
324  confess "Driver not found: '$name'. Maybe support for it was not built in?";
325 }
326 
327 #** @method list GetDriverNames()
328 # Class method.
329 # @return a list of the named of all (available and registered) GDAL
330 # raster drivers.
331 #*
332 sub GetDriverNames {
333  my @names;
334  for my $i (0..GetDriverCount()-1) {
335  my $driver = _GetDriver($i);
336  my $md = $driver->GetMetadata;
337  next unless $md->{DCAP_RASTER} and $md->{DCAP_RASTER} eq 'YES';
338  push @names, _GetDriver($i)->Name;
339  }
340  return @names;
341 }
342 
343 #** @method GetJPEG2000StructureAsString()
344 #*
345 sub GetJPEG2000StructureAsString {
346 }
347 
348 #** @method Geo::GDAL::Driver IdentifyDriver($path, $siblings)
349 # Class method.
350 # @param path a dataset path.
351 # @param siblings [optional] A list of names of files in the directory
352 # specified by the path.
353 # @return a Geo::GDAL::Driver object, which represents an internal driver.
354 #*
355 sub IdentifyDriver {
356 }
357 
358 #** @method list NodeData($node)
359 # Class method.
360 # @param node
361 # @return ($NodeType, $value)
362 #*
363 sub NodeData {
364  my $node = shift;
365  return (Geo::GDAL::NodeType($node->[0]), $node->[1]);
366 }
367 
368 #** @method scalar NodeType($type)
369 # Class method.
370 # Convert between integer and string expressions of CPLXMLNodeTypes
371 # @param type (as integer)
372 # @return type (as string)
373 #*
374 sub NodeType {
375  my $type = shift;
376  return $NODE_TYPE_INT2STRING{$type} if $type =~ /^\d/;
377  return $NODE_TYPE_STRING2INT{$type};
378 }
379 
380 #** @method list NodeTypes()
381 # Class method.
382 # @return a list of GDAL XML parser node types. These are currently:
383 # Attribute, Comment, Element, Literal, and Text.
384 #*
385 sub NodeTypes {
386  return @NODE_TYPES;
387 }
388 
389 #** @method Geo::GDAL::Dataset Open($name, $access = 'ReadOnly')
390 # Class method.
391 # An example
392 # \code
393 # use Geo::GDAL;
394 # $ds = Geo::GDAL::Open('existing.tiff', 'Update');
395 # \endcode
396 # @param name
397 # @param access Access type (one of those listed by Geo::GDAL::AccessTypes).
398 # @return a new Geo::GDAL::Dataset object.
399 #*
400 sub Open {
401  my @p = @_;
402  if (defined $p[1]) {
403  confess "Unknown access type: '$p[1]'." unless exists $Geo::GDAL::ACCESS_STRING2INT{$p[1]};
404  $p[1] = $Geo::GDAL::ACCESS_STRING2INT{$p[1]};
405  }
406  return _Open(@p);
407 }
408 
409 #** @method Geo::GDAL::Dataset OpenEx($name, $open_flags = 0, array reference allowed_drivers = undef, array reference open_options = undef, array reference sibling_files = undef);
410 # Class method.
411 # @return a new Geo::GDAL::Dataset object.
412 #*
413 sub OpenEx {
414 }
415 
416 #** @method Geo::GDAL::Dataset OpenShared($name, $access = 'ReadOnly')
417 # Class method.
418 # @param name
419 # @param access Access type (one of those listed by Geo::GDAL::AccessTypes).
420 # @return a new Geo::GDAL::Dataset object.
421 #*
422 sub OpenShared {
423  my @p = @_;
424  if (defined $p[1]) {
425  confess "Unknown access type: '$p[1]'." unless exists $Geo::GDAL::ACCESS_STRING2INT{$p[1]};
426  $p[1] = $Geo::GDAL::ACCESS_STRING2INT{$p[1]};
427  }
428  return _OpenShared(@p);
429 }
430 
431 #** @method scalar PackCharacter($DataType)
432 # Class method.
433 # Get the character that is needed for Perl's pack and unpack when
434 # they are used with Geo::GDAL::Band::ReadRaster and
435 # Geo::GDAL::Band::WriteRaster. Note that Geo::GDAL::Band::ReadTile
436 # and Geo::GDAL::Band::WriteTile have simpler interfaces that do not
437 # require pack and unpack.
438 # @param DataType A GDAL pixel data type (typically from $band->{DataType}).
439 # @return a character which can be used in Perl's pack and unpack.
440 #*
441 sub PackCharacter {
442  my $t = shift;
443  $t = $TYPE_INT2STRING{$t} if exists $TYPE_INT2STRING{$t};
444  confess "Unknown data type: '$t'." unless exists $TYPE_STRING2INT{$t};
445  my $is_big_endian = unpack("h*", pack("s", 1)) =~ /01/; # from Programming Perl
446  return 'C' if $t =~ /^Byte$/;
447  return ($is_big_endian ? 'n': 'v') if $t =~ /^UInt16$/;
448  return 's' if $t =~ /^Int16$/;
449  return ($is_big_endian ? 'N' : 'V') if $t =~ /^UInt32$/;
450  return 'l' if $t =~ /^Int32$/;
451  return 'f' if $t =~ /^Float32$/;
452  return 'd' if $t =~ /^Float64$/;
453 }
454 
455 #** @method scalar PackedDMSToDec($packed)
456 # Class method.
457 # @param packed DMS as a number DDDMMMSSS.SS
458 # @return decimal degrees
459 #*
460 sub PackedDMSToDec {
461 }
462 
463 #** @method array reference ParseXMLString($XML)
464 # Class method.
465 # Parses a given XML into an array of arrays and returns a reference
466 # to that. An array in the structure is: (CPLXMLNodeType, value,
467 # child, child, ...). CPLXMLNodeType is an integer.
468 # @param XML
469 # @return an XMLTree.
470 #
471 # Example:
472 # \code
473 # open FILE, "data.xml" or die "Couldn't open file: $!";
474 # my $xml = join("", <FILE>);
475 # close FILE;
476 # my $tree = Geo::GDAL::ParseXMLString($xml);
477 # traverse($tree);
478 # print Geo::GDAL::SerializeXMLTree($tree),"\n";
479 #
480 # sub traverse {
481 # . my $node = shift;
482 # . my $type = shift @$node;
483 # . my $data = shift @$node;
484 # . $type = Geo::GDAL::NodeType($type);
485 # . print "$type, $data\n";
486 # . for my $child (@$node) {
487 # . traverse($child);
488 # . }
489 # }
490 # \endcode
491 #*
492 sub ParseXMLString {
493 }
494 
495 #** @method Polygonize(Geo::GDAL::Band src, Geo::GDAL::Band mask, Geo::OGR::Layer out, $PixValField, hashref options, subref progress, $progress_data)
496 # Class method.
497 # @param src
498 # @param mask All pixels in the mask band with a value other than zero
499 # will be considered suitable for collection as polygons. Must be
500 # undef if not used.
501 # @param out
502 # @param PixValField The index (or name) of the field in output layer
503 # into which the pixel value of the polygon should be written.
504 # @param options Not used.
505 # @param progress [optional] a reference to a subroutine, which will
506 # be called with parameters (number progress, string msg, progress_data)
507 # @param progress_data [optional]
508 #
509 # <a href="http://www.gdal.org/gdal__alg_8h.html">Documentation for GDAL algorithms</a>
510 #*
511 sub Polygonize {
512  my @params = @_;
513  $params[6] = 1 if $params[5] and not defined $params[6];
514  $params[3] = $params[2]->GetLayerDefn->GetFieldIndex($params[3]) unless $params[3] =~ /^\d/;
515  _Polygonize(@params);
516 }
517 
518 #** @method PopFinderLocation()
519 # Class method.
520 # Remove the latest addition from the set of support file search
521 # paths.
522 #*
523 sub PopFinderLocation {
524 }
525 
526 #** @method PushFinderLocation($path)
527 # Class method.
528 # Add a path to the set of paths from where GDAL support files are
529 # sought.
530 #*
531 sub PushFinderLocation {
532 }
533 
534 #** @method list RIOResamplingTypes()
535 # Class method.
536 # @return a list of GDAL raster IO resampling methods.
537 #*
538 sub RIOResamplingTypes {
539  return @RIO_RESAMPLING_TYPES;
540 }
541 
542 #** @method RasterizeLayer(Geo::GDAL::Dataset ds, arrayref bands, Geo::OGR::Layer layer, $transformer, $arg, arrayref burn_values, hashref options, subref progress, $progress_data)
543 # Class method.
544 # @param ds
545 # @param bands A reference to a list of bands to be updated.
546 # @param layer
547 # @param transformer Not supported, must be undef.
548 # @param arg Transformer argument, must be undef.
549 # @param burn_values Values to be used for burning the geometries. One for each layer.
550 # @param options Not used.
551 # @param progress [optional] a reference to a subroutine, which will
552 # be called with parameters (number progress, string msg, progress_data)
553 # @param progress_data [optional]
554 #
555 # <a href="http://www.gdal.org/gdal__alg_8h.html">Documentation for GDAL algorithms</a>
556 #*
557 sub RasterizeLayer {
558  my @p = @_;
559  $p[8] = 1 if $p[7] and not defined $p[8];
560  _RasterizeLayer(@p);
561 }
562 
563 #** @method ReprojectImage($src_ds, $dst_ds, $src_wkt=undef, $dst_wkt=undef, $ResampleAlg='NearestNeighbour', $WarpMemoryLimit=0, $maxerror=0.0, subref progress, $progress_data)
564 # Class method.
565 # @param src_ds Source dataset.
566 # @param dst_ds Destination dataset.
567 # @param src_wkt Source projection as a WKT.
568 # @param dst_wkt Destination projection as a WKT.
569 # @param ResampleAlg One of NearestNeighbour Bilinear Cubic or CubicSpline.
570 # @param WarpMemoryLimit The amount of memory allowed for caching. Default is 0, i.e., no limit.
571 # @param maxerror Maximum error measured in input pixels that is
572 # allowed in approximating the transformation. Default is 0.0, i.e.,
573 # exact calculations.
574 # @param progress [optional] a reference to a subroutine, which will
575 # be called with parameters (number progress, string msg, progress_data).
576 # Reprojection is terminated if the progress function returns 0.
577 # @param progress_data [optional]
578 #
579 # <a href="http://www.gdal.org/gdalwarper_8h.html">Documentation for GDAL warper</a>
580 #*
581 sub ReprojectImage {
582  my @p = @_;
583  $p[8] = 1 if $p[7] and not defined $p[8];
584  if (defined $p[4]) {
585  confess "Unknown data type: '$p[4]'." unless exists $Geo::GDAL::RESAMPLING_STRING2INT{$p[4]};
586  $p[4] = $Geo::GDAL::RESAMPLING_STRING2INT{$p[4]};
587  }
588  return _ReprojectImage(@p);
589 }
590 
591 #** @method list ResamplingTypes()
592 # Class method.
593 # @return a list of GDAL resampling methods.
594 #*
595 sub ResamplingTypes {
596  return @RESAMPLING_TYPES;
597 }
598 
599 #** @method scalar SerializeXMLTree(arrayref XMLTree)
600 # Class method.
601 # @param XMLTree
602 # @return XML
603 #*
604 sub SerializeXMLTree {
605 }
606 
607 #** @method SetCacheMax($Bytes)
608 # Class method.
609 # @param Bytes New maximum amount of memory for caching within GDAL.
610 #
611 #*
612 sub SetCacheMax {
613 }
614 
615 #** @method SetConfigOption($key, $value)
616 # Class method.
617 # @param key A GDAL config option. Possible values include
618 # 'GDAL_FORCE_CACHING', 'USE_RRD', GDAL_DATA', 'GDAL_SKIP',
619 # 'GDAL_DRIVER_PATH', 'GDAL_IGNORE_AXIS_ORIENTATION',
620 # 'GMLJP2OVERRIDE', 'GDAL_DISABLE_READDIR_ON_OPEN',
621 # 'GDAL_PAM_ENABLED', 'GDAL_PAM_MODE', 'GDAL_PAM_PROXY_DIR',
622 # 'GDAL_MAX_DATASET_POOL_SIZE', 'GDAL_FORCE_CACHING', 'GDAL_CACHEMAX',
623 # 'GDAL_SWATH_SIZE', 'PROJSO', 'CENTER_LONG',
624 # 'OGR_DEBUG_ORGANIZE_POLYGONS', 'OGR_ORGANIZE_POLYGONS',
625 # and 'GDAL_JP2K_ALT_OFFSETVECTOR_ORDER'.
626 # Consult the GDAL main documentation for the semantics of config options.
627 # @param value A value for the option, typically 'YES', 'NO',
628 # undef, a path, or a filename.
629 #*
630 sub SetConfigOption {
631 }
632 
633 #** @method SieveFilter(Geo::GDAL::Band src, Geo::GDAL::Band mask, Geo::GDAL::Band dst, $threshold, $connectedness, hashref options, subref progress, $progress_data)
634 # Class method.
635 # Removes small raster polygons.
636 # @param src
637 # @param mask
638 # @param dst
639 # @param threshold An integer.
640 # @param connectedness 4 or 8
641 # @param options Not used.
642 # @param progress [optional] a reference to a subroutine, which will
643 # be called with parameters (number progress, string msg, progress_data)
644 # @param progress_data [optional]
645 #
646 # <a href="http://www.gdal.org/gdal__alg_8h.html">Documentation for GDAL algorithms</a>
647 #*
648 sub SieveFilter {
649  my @p = @_;
650  $p[7] = 1 if $p[6] and not defined $p[7];
651  _SieveFilter(@p);
652 }
653 
654 #** @method scalar VersionInfo($request = 'VERSION_NUM')
655 # Class method.
656 # @param request A string specifying the request. Currently either
657 # "VERSION_NUM", "RELEASE_DATE", "RELEASE_NAME", or
658 # "--version". Default is "VERSION_NUM".
659 # @return Requested information.
660 #*
661 sub VersionInfo {
662 }
663 
664 #** @class Geo::GDAL::AsyncReader
665 # @brief Enable asynchronous requests.
666 # @todo Test and document.
667 #
668 # This class is not yet documented nor tested in the GDAL Perl wrappers
669 #*
670 package Geo::GDAL::AsyncReader;
671 
672 use base qw(Geo::GDAL)
673 
674 #** @method GetNextUpdatedRegion()
675 #*
676 sub GetNextUpdatedRegion {
677 }
678 
679 #** @method LockBuffer()
680 #*
681 sub LockBuffer {
682 }
683 
684 #** @method UnlockBuffer()
685 #*
686 sub UnlockBuffer {
687 }
688 
689 #** @class Geo::GDAL::Band
690 # @brief A raster band.
691 #*
692 package Geo::GDAL::Band;
693 
695 
696 #** @attr $XSize
697 # Object attribute.
698 # scalar (access as $band->{XSize})
699 #*
700 
701 #** @attr $YSize
702 # Object attribute.
703 # scalar (access as $band->{YSize})
704 #*
705 
706 #** @method Geo::GDAL::RasterAttributeTable AttributeTable($AttributeTable)
707 # @param AttributeTable [optional] A Geo::GDAL::RasterAttributeTable object.
708 # @return a new Geo::GDAL::RasterAttributeTable object, whose data is
709 # contained within the band.
710 #*
711 sub AttributeTable {
712  my $self = shift;
713  SetDefaultRAT($self, $_[0]) if @_ and defined $_[0];
714  return unless defined wantarray;
715  my $r = GetDefaultRAT($self);
716  $Geo::GDAL::RasterAttributeTable::BANDS{$r} = $self if $r;
717  return $r;
718 }
719 
720 #** @method list CategoryNames(@names)
721 # @param names [optional]
722 # @return
723 #*
724 sub CategoryNames {
725  my $self = shift;
726  SetRasterCategoryNames($self, \@_) if @_;
727  return unless defined wantarray;
728  my $n = GetRasterCategoryNames($self);
729  return @$n;
730 }
731 
732 #** @method scalar Checksum($xoff = 0, $yoff = 0, $xsize = undef, $ysize = undef)
733 # Computes a checksum from the raster or a part of it.
734 # @param xoff
735 # @param yoff
736 # @param xsize
737 # @param ysize
738 # @return the checksum.
739 #*
740 sub Checksum {
741 }
742 
743 #** @method scalar ColorInterpretation($color_interpretation)
744 # @note a.k.a. GetRasterColorInterpretation and GetColorInterpretation
745 # (get only and returns an integer), SetRasterColorInterpretation and
746 # SetColorInterpretation (set only and requires an integer)
747 # @param color_interpretation [optional] new color interpretation, one
748 # of Geo::GDAL::Band::ColorInterpretations.
749 # @return color interpretation, one of Geo::GDAL::Band::ColorInterpretations.
750 #*
751 sub ColorInterpretation {
752  my($self, $ci) = @_;
753  if (defined $ci) {
754  my $ci2 = $ci;
755  $ci2 = $COLOR_INTERPRETATION_STRING2INT{$ci} if exists $COLOR_INTERPRETATION_STRING2INT{$ci};
756  confess "Unknown color interpretation: '$ci'." unless exists $COLOR_INTERPRETATION_INT2STRING{$ci2};
757  SetRasterColorInterpretation($self, $ci2);
758  return $ci;
759  } else {
760  return $COLOR_INTERPRETATION_INT2STRING{GetRasterColorInterpretation($self)};
761  }
762 }
763 
764 #** @method ColorInterpretations()
765 #*
766 sub ColorInterpretations {
767  return @COLOR_INTERPRETATIONS;
768 }
769 
770 #** @method Geo::GDAL::ColorTable ColorTable($ColorTable)
771 # Get or set the color table of this band.
772 # @param ColorTable [optional] a Geo::GDAL::ColorTable object
773 # @return a new Geo::GDAL::ColorTable object in a non-void context.
774 #*
775 sub ColorTable {
776  my $self = shift;
777  SetRasterColorTable($self, $_[0]) if @_ and defined $_[0];
778  return unless defined wantarray;
779  GetRasterColorTable($self);
780 }
781 
782 #** @method ComputeBandStats($samplestep = 1)
783 # @param samplestep the row increment in computing the statistics.
784 # @note Returns uncorrected sample standard deviation.
785 #
786 # See also Geo::GDAL::Band::ComputeStatistics.
787 # @return a list (mean, stddev).
788 #*
789 sub ComputeBandStats {
790 }
791 
792 #** @method ComputeRasterMinMax($approx_ok = 0)
793 # @return arrayref MinMax = [min, max]
794 #*
795 sub ComputeRasterMinMax {
796 }
797 
798 #** @method list ComputeStatistics($approx_ok, $progress = undef, $progress_data = undef)
799 # @param approx_ok Whether it is allowed to compute the statistics
800 # based on overviews or similar.
801 # @note Returns uncorrected sample standard deviation.
802 #
803 # See also Geo::GDAL::Band::ComputeBandStats.
804 # @return a list ($min, $max, $mean, $stddev).
805 #*
806 sub ComputeStatistics {
807 }
808 
809 #** @method Geo::OGR::Layer Contours($DataSource, hashref LayerConstructor, $ContourInterval, $ContourBase, arrayref FixedLevels, $NoDataValue, $IDField, $ElevField, subref Progress, $ProgressData)
810 # Generate contours for this raster band. This method can also be used with named parameters.
811 # @note This method is a wrapper for ContourGenerate.
812 #
813 # An example:
814 # \code
815 # use Geo::GDAL;
816 # $dem = Geo::GDAL::Open('dem.gtiff');
817 # $contours = $dem->Band->Contours(ContourInterval => 10, ElevField => 'z');
818 # $n = $contours->GetFeatureCount;
819 # \endcode
820 #
821 # @param DataSource a Geo::OGR::DataSource object, default is a Memory data source
822 # @param LayerConstructor data for Geo::OGR::DataSource::CreateLayer, default is {Name => 'contours'}
823 # @param ContourInterval default is 100
824 # @param ContourBase default is 0
825 # @param FixedLevels a reference to a list of fixed contour levels, default is []
826 # @param NoDataValue default is undef
827 # @param IDField default is '', i.e., no field (the field is created if this is given)
828 # @param ElevField default is '', i.e., no field (the field is created if this is given)
829 # @param progress [optional] a reference to a subroutine, which will
830 # be called with parameters (number progress, string msg, progress_data)
831 # @param progress_data [optional]
832 # @return
833 #*
834 sub Contours {
835  my $self = shift;
836  my %defaults = (DataSource => undef,
837  LayerConstructor => {Name => 'contours'},
838  ContourInterval => 100,
839  ContourBase => 0,
840  FixedLevels => [],
841  NoDataValue => undef,
842  IDField => -1,
843  ElevField => -1,
844  Progress => undef,
845  ProgressData => undef);
846  my %params;
847  if (!defined($_[0]) or (blessed($_[0]) and $_[0]->isa('Geo::OGR::DataSource'))) {
848  ($params{DataSource}, $params{LayerConstructor},
849  $params{ContourInterval}, $params{ContourBase},
850  $params{FixedLevels}, $params{NoDataValue},
851  $params{IDField}, $params{ElevField},
852  $params{Progress}, $params{ProgressData}) = @_;
853  } else {
854  %params = @_;
855  if (exists $params{progress}) {
856  $params{Progress} = $params{progress};
857  delete $params{progress};
858  }
859  if (exists $params{progress_data}) {
860  $params{ProgressData} = $params{progress_data};
861  delete $params{progress_data};
862  }
863  }
864  for (keys %params) {
865  carp "unknown parameter $_ in Geo::GDAL::Band::Contours" unless exists $defaults{$_};
866  }
867  for (keys %defaults) {
868  $params{$_} = $defaults{$_} unless defined $params{$_};
869  }
870  $params{DataSource} = Geo::OGR::GetDriver('Memory')->CreateDataSource('ds')
871  unless defined $params{DataSource};
872  $params{LayerConstructor}->{Schema} = {} unless $params{LayerConstructor}->{Schema};
873  $params{LayerConstructor}->{Schema}{Fields} = [] unless $params{LayerConstructor}->{Schema}{Fields};
874  my %fields;
875  unless ($params{IDField} =~ /^[+-]?\d+$/ or $fields{$params{IDField}}) {
876  push @{$params{LayerConstructor}->{Schema}{Fields}}, {Name => $params{IDField}, Type => 'Integer'};
877  }
878  unless ($params{ElevField} =~ /^[+-]?\d+$/ or $fields{$params{ElevField}}) {
879  my $type = $self->DataType() =~ /Float/ ? 'Real' : 'Integer';
880  push @{$params{LayerConstructor}->{Schema}{Fields}}, {Name => $params{ElevField}, Type => $type};
881  }
882  my $layer = $params{DataSource}->CreateLayer($params{LayerConstructor});
883  my $schema = $layer->GetLayerDefn;
884  for ('IDField', 'ElevField') {
885  $params{$_} = $schema->GetFieldIndex($params{$_}) unless $params{$_} =~ /^[+-]?\d+$/;
886  }
887  $params{ProgressData} = 1 if $params{Progress} and not defined $params{ProgressData};
888  ContourGenerate($self, $params{ContourInterval}, $params{ContourBase}, $params{FixedLevels},
889  $params{NoDataValue}, $layer, $params{IDField}, $params{ElevField},
890  $params{Progress}, $params{ProgressData});
891  return $layer;
892 }
893 
894 #** @method CreateMaskBand(@flags)
895 # @note May invalidate any previous mask band obtained with Geo::GDAL::Band::GetMaskBand.
896 #
897 # @param flags one or more mask flags. The flags are Geo::GDAL::Band::MaskFlags.
898 #*
899 sub CreateMaskBand {
900  my $self = shift;
901  my $f = 0;
902  if (@_ and $_[0] =~ /^\d$/) {
903  $f = shift;
904  } else {
905  for my $flag (@_) {
906  carp "Unknown mask flag: '$flag'." unless $MASK_FLAGS{$flag};
907  $f |= $MASK_FLAGS{$flag};
908  }
909  }
910  $self->_CreateMaskBand($f);
911 }
912 # GetMaskBand should be redefined and the result should be put into
913 # %Geo::GDAL::Dataset::BANDS
914 # GetOverview should be redefined and the result should be put into
915 # %Geo::GDAL::Dataset::BANDS
916 }
917 
918 #** @method scalar DataType()
919 # @return the data type of this band (as string, one of Geo::GDAL::DataTypes).
920 #*
921 sub DataType {
922  my $self = shift;
923  return $Geo::GDAL::TYPE_INT2STRING{$self->{DataType}};
924 }
925 
926 #** @method Domains()
927 #*
928 sub Domains {
929  return @DOMAINS;
930 }
931 
932 #** @method Fill($real_part, $imag_part = 0.0)
933 # Fill the band with a constant value.
934 # @param real_part Real component of fill value.
935 # @param imag_part Imaginary component of fill value.
936 #
937 #*
938 sub Fill {
939 }
940 
941 #** @method FillNodata($mask, $max_search_dist, $smoothing_iterations, $options, subref progress, $progress_data)
942 # Interpolate values for pixels in this raster. The pixels to fill
943 # should be marked in the mask band with zero.
944 # @note This is a wrapper for Geo::GDAL::FillNodata.
945 #
946 # @param mask [optional] a mask band indicating pixels to be interpolated (zero valued) (default is to get it with Geo::GDAL::Band::GetMaskBand).
947 # @param max_search_dist [optional] the maximum number of pixels to
948 # search in all directions to find values to interpolate from (default is 10).
949 # @param smoothing_iterations [optional] the number of 3x3 smoothing filter passes to run (0 or more) (default is 0).
950 # @param options [optional] A reference to a hash. No options have been defined so far for this algorithm (default is {}).
951 # @param progress [optional] a reference to a subroutine, which will
952 # be called with parameters (number progress, string msg, progress_data) (default is undef).
953 # @param progress_data [optional] (default is undef).
954 #
955 # <a href="http://www.gdal.org/gdal__alg_8h.html">Documentation for GDAL algorithms</a>
956 #*
957 sub FillNodata {
958  my $self = shift;
959  my $mask = shift;
960  $mask = $self->GetMaskBand unless $mask;
961  my @p = @_;
962  $p[0] = 10 unless defined $p[0];
963  $p[1] = 0 unless defined $p[1];
964  $p[2] = undef unless defined $p[2];
965  $p[3] = undef unless defined $p[3];
966  $p[4] = undef unless defined $p[1];
967  Geo::GDAL::FillNodata($self, $mask, @p);
968 }
969 
970 #** @method FlushCache()
971 # Write cached data to disk. There is usually no need to call this
972 # method.
973 #*
974 sub FlushCache {
975 }
976 
977 #** @method scalar GetBandNumber()
978 # @note a.k.a. GetBand
979 # @return the number of this band.
980 #*
981 sub GetBandNumber {
982 }
983 
984 #** @method list GetBlockSize()
985 # @return the size of a preferred i/o raster blocks as a list (width,
986 # height).
987 #*
988 sub GetBlockSize {
989 }
990 
991 #** @method Geo::GDAL::ColorTable GetColorTable()
992 # @note a.k.a. GetRasterColorTable, see also ColorTable
993 # @return a color table object.
994 #*
995 sub GetColorTable {
996 }
997 
998 #** @method GetDataset()
999 #*
1000 sub GetDataset {
1001 }
1002 
1003 #** @method list GetDefaultHistogram($force = 1, subref progress = undef, $progress_data = undef)
1004 # @param force true to force the computation
1005 # @param progress [optional] a reference to a subroutine, which will
1006 # be called with parameters (number progress, string msg, progress_data)
1007 # @param progress_data [optional]
1008 # @return a list: ($min, $max, arrayref histogram).
1009 #*
1010 sub GetDefaultHistogram {
1011 }
1012 
1013 #** @method list GetHistogram(%parameters)
1014 # Compute histogram from the raster.
1015 # @param parameters Named parameters:
1016 # - \a Min the lower bound, default is -0.5
1017 # - \a Max the upper bound, default is 255.5
1018 # - \a Buckets the number of buckets in the histogram, default is 256
1019 # - \a IncludeOutOfRange whether to use the first and last values in the returned list
1020 # for out of range values, default is false;
1021 # the bucket size is (Max-Min) / Buckets if this is false and
1022 # (Max-Min) / (Buckets-2) if this is true
1023 # - \a ApproxOK if histogram can be computed from overviews, default is false
1024 # - \a Progress an optional progress function, the default is undef
1025 # - \a ProgressData data for the progress function, the default is undef
1026 # @return a list which contains the count of values in each bucket
1027 #*
1028 sub GetHistogram {
1029  my $self = shift;
1030  my %defaults = (Min => -0.5,
1031  Max => 255.5,
1032  Buckets => 256,
1033  IncludeOutOfRange => 0,
1034  ApproxOK => 0,
1035  Progress => undef,
1036  ProgressData => undef);
1037  my %params = @_;
1038  for (keys %params) {
1039  carp "unknown parameter $_ in Geo::GDAL::Band::GetHistogram" unless exists $defaults{$_};
1040  }
1041  for (keys %defaults) {
1042  $params{$_} = $defaults{$_} unless defined $params{$_};
1043  }
1044  $params{ProgressData} = 1 if $params{Progress} and not defined $params{ProgressData};
1045  _GetHistogram($self, $params{Min}, $params{Max}, $params{Buckets},
1046  $params{IncludeOutOfRange}, $params{ApproxOK},
1047  $params{Progress}, $params{ProgressData});
1048 }
1049 
1050 #** @method Geo::GDAL::Band GetMaskBand()
1051 # @return the mask band associated with this
1052 # band.
1053 #*
1054 sub GetMaskBand {
1055 }
1056 
1057 #** @method list GetMaskFlags()
1058 # @return th mask flags of the mask band associated with this
1059 # band. The flags are Geo::GDAL::Band::MaskFlags.
1060 #*
1061 sub GetMaskFlags {
1062  my $self = shift;
1063  my $f = $self->_GetMaskFlags;
1064  my @f;
1065  for my $flag (keys %MASK_FLAGS) {
1066  push @f, $flag if $f & $MASK_FLAGS{$flag};
1067  }
1068  return wantarray ? @f : $f;
1069 }
1070 
1071 #** @method scalar GetMaximum()
1072 # @note Call Geo::GDAL::Band::ComputeStatistics before calling
1073 # GetMaximum to make sure the value is computed.
1074 #
1075 # @return statistical minimum of the band or undef if statistics are
1076 # not kept or computed in scalar context. In list context returns the
1077 # maximum value or a (kind of) maximum value supported by the data
1078 # type and a boolean value, which indicates which is the case (true is
1079 # first, false is second).
1080 #*
1081 sub GetMaximum {
1082 }
1083 
1084 #** @method scalar GetMinimum()
1085 # @note Call Geo::GDAL::Band::ComputeStatistics before calling
1086 # GetMinimum to make sure the value is computed.
1087 #
1088 # @return statistical minimum of the band or undef if statistics are
1089 # not kept or computed in scalar context. In list context returns the
1090 # minimum value or a (kind of) minimum value supported by the data
1091 # type and a boolean value, which indicates which is the case (true is
1092 # first, false is second).
1093 #*
1094 sub GetMinimum {
1095 }
1096 
1097 #** @method Geo::GDAL::Band GetOverview($index)
1098 # @param index 0..GetOverviewCount-1
1099 # @return a Geo::GDAL::Band object, which represents the internal
1100 # overview band, or undef. if the index is out of bounds.
1101 #*
1102 sub GetOverview {
1103 }
1104 
1105 #** @method scalar GetOverviewCount()
1106 # @return the number of overviews available of the band.
1107 #*
1108 sub GetOverviewCount {
1109 }
1110 
1111 #** @method list GetStatistics($approx_ok, $force)
1112 # @param approx_ok Whether it is allowed to compute the statistics
1113 # based on overviews or similar.
1114 # @param force Whether to force scanning of the whole raster.
1115 # @note Uses Geo::GDAL::Band::ComputeStatistics internally.
1116 #
1117 # @return a list ($min, $max, $mean, $stddev).
1118 #*
1119 sub GetStatistics {
1120 }
1121 
1122 #** @method HasArbitraryOverviews()
1123 # @return true or false.
1124 #*
1125 sub HasArbitraryOverviews {
1126 }
1127 
1128 #** @method list MaskFlags()
1129 # Class method.
1130 # @return the list of mask flags. These are
1131 # - \a AllValid: There are no invalid pixels, all mask values will be 255.
1132 # When used this will normally be the only flag set.
1133 # - \a PerDataset: The mask band is shared between all bands on the dataset.
1134 # - \a Alpha: The mask band is actually an alpha band and may have values
1135 # other than 0 and 255.
1136 # - \a NoData: Indicates the mask is actually being generated from nodata values.
1137 # (mutually exclusive of Alpha).
1138 #*
1139 sub MaskFlags {
1140  my @f = sort {$MASK_FLAGS{$a} <=> $MASK_FLAGS{$b}} keys %MASK_FLAGS;
1141  return @f;
1142 }
1143 
1144 #** @method scalar NoDataValue($NoDataValue)
1145 # @note a.k.a. GetNoDataValue (get only), SetNoDataValue (set only)
1146 # @param NoDataValue [optional]
1147 # Get or set the "no data" value.
1148 # @note $band->NoDataValue(undef) sets the "no data" value to the Posix
1149 # floating point maximum.
1150 # @return the "no data" value in scalar context. In list context
1151 # returns the no data value or an out of range value and a boolean
1152 # value, which indicates which is the case (true is first, false is
1153 # second).
1154 #*
1155 sub NoDataValue {
1156  my $self = shift;
1157  if (@_ > 0) {
1158  if (defined $_[0]) {
1159  SetNoDataValue($self, $_[0]);
1160  } else {
1161  SetNoDataValue($self, POSIX::FLT_MAX); # hopefully an "out of range" value
1162  }
1163  }
1164  GetNoDataValue($self);
1165 }
1166 
1167 #** @method scalar PackCharacter()
1168 # @return the character to use in Perl pack and unpack for the DataType of this band.
1169 #*
1170 sub PackCharacter {
1171  my $self = shift;
1172  return Geo::GDAL::PackCharacter($self->DataType);
1173 }
1174 
1175 #** @method scalar ReadRaster(%params)
1176 # Read data from the band.
1177 #
1178 # @param params named parameters. These are
1179 # - \a XOff x offset (pixel coordinates) (default is 0)
1180 # - \a YOff y offset (pixel coordinates) (default is 0)
1181 # - \a XSize width of the area to read (default is the width of the band)
1182 # - \a YSize height of the area to read (default is the height of the band)
1183 # - \a BufXSize (default is undef, i.e., the same as XSize)
1184 # - \a BufYSize (default is undef, i.e., the same as YSize)
1185 # - \a BufType data type of the buffer (default is the data type of the band)
1186 # - \a BufPixelSpace (default is 0)
1187 # - \a BufLineSpace (default is 0)
1188 # - \a ResampleAlg one of Geo::GDAL::RIOResamplingTypes (default is 'NearestNeighbour'),
1189 # - \a Progress reference to a progress function (default is undef)
1190 # - \a ProgressData (default is undef)
1191 #
1192 # If the parameters are given as a list the order is as above.
1193 # <a href="http://www.gdal.org/classGDALDataset.html">Entry in GDAL docs (method RasterIO)</a>
1194 # @return a buffer, open the buffer with \a unpack function of Perl. See Geo::GDAL::Band::PackCharacter.
1195 #*
1196 sub ReadRaster {
1197  my $self = shift;
1198  my ($width, $height) = $self->Size;
1199  my ($type) = $self->DataType;
1200  my %d = (
1201  XOFF => 0,
1202  YOFF => 0,
1203  XSIZE => $width,
1204  YSIZE => $height,
1205  BUFXSIZE => undef,
1206  BUFYSIZE => undef,
1207  BUFTYPE => $type,
1208  BUFPIXELSPACE => 0,
1209  BUFLINESPACE => 0,
1210  RESAMPLEALG => 'NearestNeighbour',
1211  PROGRESS => undef,
1212  PROGRESSDATA => undef
1213  );
1214  my %p;
1215  my $t;
1216  if (defined $_[0]) {
1217  $t = uc($_[0]);
1218  $t =~ s/_//g;
1219  }
1220  if (@_ == 0) {
1221  } elsif (ref($_[0]) eq 'HASH') {
1222  %p = %{$_[0]};
1223  } elsif (@_ % 2 == 0 and (defined $t and exists $d{$t})) {
1224  %p = @_;
1225  } else {
1226  ($p{xoff},$p{yoff},$p{xsize},$p{ysize},$p{buf_xsize},$p{buf_ysize},$p{buf_type},$p{buf_pixel_space},$p{buf_line_space},$p{resample_alg},$p{progress},$p{progress_data}) = @_;
1227  }
1228  for (keys %p) {
1229  my $u = uc($_);
1230  $u =~ s/_//g;
1231  carp "Unknown named parameter '$_'." unless exists $d{$u};
1232  $p{$u} = $p{$_};
1233  }
1234  for (keys %d) {
1235  $p{$_} = $d{$_} unless defined $p{$_};
1236  }
1237  confess "Unknown resampling algorithm: '$p{RESAMPLEALG}'."
1238  unless exists $Geo::GDAL::RIO_RESAMPLING_STRING2INT{$p{RESAMPLEALG}};
1239  $p{RESAMPLEALG} = $Geo::GDAL::RIO_RESAMPLING_STRING2INT{$p{RESAMPLEALG}};
1240  unless ($Geo::GDAL::TYPE_INT2STRING{$p{BUFTYPE}}) {
1241  confess "Unknown data type: '$p{BUFTYPE}'."
1242  unless exists $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
1243  $p{BUFTYPE} = $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
1244  }
1245  $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});
1246 }
1247 
1248 #** @method array reference ReadTile($xoff = 0, $yoff = 0, $xsize = <width>, $ysize = <height>)
1249 #
1250 # Usage example (print the data from a band):
1251 # \code
1252 # print "@$_\n" for ( @{ $band->ReadTile() } );
1253 # \endcode
1254 # Another usage example (process the data of a large dataset that has one band):
1255 # \code
1256 # my($W,$H) = $dataset->Band(1)->Size();
1257 # my($xoff,$yoff,$w,$h) = (0,0,200,200);
1258 # while (1) {
1259 # . if ($xoff >= $W) {
1260 # . $xoff = 0;
1261 # . $yoff += $h;
1262 # . last if $yoff >= $H;
1263 # . }
1264 # . my $data = $dataset->Band(1)->ReadTile($xoff,$yoff,min($W-$xoff,$w),min($H-$yoff,$h));
1265 # . # add your data processing code here
1266 # . $dataset->Band(1)->WriteTile($data,$xoff,$yoff);
1267 # . $xoff += $w;
1268 # }
1269 #
1270 # sub min {
1271 # . return $_[0] < $_[1] ? $_[0] : $_[1];
1272 # }
1273 # \endcode
1274 # @param xoff
1275 # @param yoff
1276 # @param xsize
1277 # @param ysize
1278 # @return a two-dimensional Perl array, organizes as data->[y][x], y =
1279 # 0..height-1, x = 0..width-1.
1280 #*
1281 sub ReadTile {
1282  my($self, $xoff, $yoff, $xsize, $ysize) = @_;
1283  $xoff = 0 unless defined $xoff;
1284  $yoff = 0 unless defined $yoff;
1285  $xsize = $self->{XSize} - $xoff unless defined $xsize;
1286  $ysize = $self->{YSize} - $yoff unless defined $ysize;
1287  my $buf = $self->ReadRaster($xoff, $yoff, $xsize, $ysize);
1288  my $pc = Geo::GDAL::PackCharacter($self->{DataType});
1289  my $w = $xsize * Geo::GDAL::GetDataTypeSize($self->{DataType})/8;
1290  my $offset = 0;
1291  my @data;
1292  for (0..$ysize-1) {
1293  my $sub = substr($buf, $offset, $w);
1294  my @d = unpack($pc."[$xsize]", $sub);
1295  push @data, \@d;
1296  $offset += $w;
1297  }
1298  return \@data;
1299 }
1300 
1301 #** @method RegenerateOverview(Geo::GDAL::Band overview, $resampling, subref progress, $progress_data)
1302 # @param overview a Geo::GDAL::Band object for the overview.
1303 # @param resampling [optional] the resampling method (one of Geo::GDAL::RIOResamplingTypes) (default is Average).
1304 # @param progress [optional] a reference to a subroutine, which will
1305 # be called with parameters (number progress, string msg, progress_data)
1306 # @param progress_data [optional]
1307 #*
1308 sub RegenerateOverview {
1309  my $self = shift;
1310  #Geo::GDAL::Band overview, scalar resampling, subref callback, scalar callback_data
1311  my @p = @_;
1312  Geo::GDAL::RegenerateOverview($self, @p);
1313 }
1314 
1315 #** @method RegenerateOverviews(arrayref overviews, $resampling, subref progress, $progress_data)
1316 # @todo This is not yet available
1317 #
1318 # @param overviews a list of Geo::GDAL::Band objects for the overviews.
1319 # @param resampling [optional] the resampling method (one of Geo::GDAL::RIOResamplingTypes) (default is Average).
1320 # @param progress [optional] a reference to a subroutine, which will
1321 # be called with parameters (number progress, string msg, progress_data)
1322 # @param progress_data [optional]
1323 #*
1324 sub RegenerateOverviews {
1325  my $self = shift;
1326  #arrayref overviews, scalar resampling, subref callback, scalar callback_data
1327  my @p = @_;
1328  Geo::GDAL::RegenerateOverviews($self, @p);
1329 }
1330 
1331 #** @method ScaleAndOffset($scale, $offset)
1332 # Scale and offset are used to transform raw pixel values into the
1333 # units returned by GetUnits(). The conversion function is:
1334 # \code
1335 # Units value = (raw value * scale) + offset
1336 # \endcode
1337 # @return a list ($scale, $offset), the values are undefined if they
1338 # are not set.
1339 # @since version 1.9 of the bindings.
1340 #*
1341 sub ScaleAndOffset {
1342  my $self = shift;
1343  SetScale($self, $_[0]) if @_ > 0 and defined $_[0];
1344  SetOffset($self, $_[1]) if @_ > 1 and defined $_[1];
1345  return unless defined wantarray;
1346  my $scale = GetScale($self);
1347  my $offset = GetOffset($self);
1348  return ($scale, $offset);
1349 }
1350 
1351 #** @method SetColorTable($ColorTable)
1352 # @note a.k.a. SetRasterColorTable, see also ColorTable
1353 # @param ColorTable A color table object.
1354 #
1355 #*
1356 sub SetColorTable {
1357 }
1358 
1359 #** @method list SetDefaultHistogram($min, $max, $histogram)
1360 # @param min
1361 # @param max
1362 # @param histogram reference to an array containing the histogram
1363 #
1364 #*
1365 sub SetDefaultHistogram {
1366 }
1367 
1368 #** @method SetStatistics($min, $max, $mean, $stddev)
1369 # Save the statistics of the band if possible (the format can save
1370 # arbitrary metadata).
1371 # @param min
1372 # @param max
1373 # @param mean
1374 # @param stddev
1375 #*
1376 sub SetStatistics {
1377 }
1378 
1379 #** @method list Size()
1380 # @return the size of the band as a list (width, height).
1381 #*
1382 sub Size {
1383  my $self = shift;
1384  return ($self->{XSize}, $self->{YSize});
1385 }
1386 
1387 #** @method Unit($type)
1388 # @param type [optional] the unit (a string).
1389 # @note $band->Unit(undef) sets the unit value to an empty string.
1390 # @return the unit (a string).
1391 # @since version 1.9 of the bindings.
1392 #*
1393 sub Unit {
1394  my $self = shift;
1395  if (@_ > 0) {
1396  my $unit = shift;
1397  $unit = '' unless defined $unit;
1398  SetUnitType($self, $unit);
1399  }
1400  return unless defined wantarray;
1401  GetUnitType($self);
1403 
1404 #** @method WriteRaster(%params)
1405 # Write data into the band.
1406 #
1407 # @param params named parameters. These are
1408 # - \a XOff x offset (pixel coordinates) (default is 0)
1409 # - \a YOff y offset (pixel coordinates) (default is 0)
1410 # - \a XSize width of the area to write (default is the width of the band)
1411 # - \a YSize height of the area to write (default is the height of the band)
1412 # - \a Buf a buffer containing the data. Create the buffer with \a pack function of Perl. See Geo::GDAL::Band::PackCharacter.
1413 # - \a BufXSize (default is undef, i.e., the same as XSize)
1414 # - \a BufYSize (default is undef, i.e., the same as YSize)
1415 # - \a BufType data type of the buffer (default is the data type of the band)
1416 # - \a BufPixelSpace (default is 0)
1417 # - \a BufLineSpace (default is 0)
1418 #
1419 # If the parameters are given as a list the order is as above.
1420 # <a href="http://www.gdal.org/classGDALDataset.html">Entry in GDAL docs (method RasterIO)</a>
1421 #*
1422 sub WriteRaster {
1423  my $self = shift;
1424  my ($width, $height) = $self->Size;
1425  my ($type) = $self->DataType;
1426  my %d = (
1427  XOFF => 0,
1428  YOFF => 0,
1429  XSIZE => $width,
1430  YSIZE => $height,
1431  BUF => undef,
1432  BUFXSIZE => undef,
1433  BUFYSIZE => undef,
1434  BUFTYPE => $type,
1435  BUFPIXELSPACE => 0,
1436  BUFLINESPACE => 0
1437  );
1438  my %p;
1439  my $t;
1440  if (defined $_[0]) {
1441  $t = uc($_[0]);
1442  $t =~ s/_//g;
1443  }
1444  if (@_ == 0) {
1445  } elsif (ref($_[0]) eq 'HASH') {
1446  %p = %{$_[0]};
1447  } elsif (@_ % 2 == 0 and (defined $t and exists $d{$t})) {
1448  %p = @_;
1449  } else {
1450  ($p{xoff},$p{yoff},$p{xsize},$p{ysize},$p{buf},$p{buf_xsize},$p{buf_ysize},$p{buf_type},$p{buf_pixel_space},$p{buf_line_space}) = @_;
1451  }
1452  for (keys %p) {
1453  my $u = uc($_);
1454  $u =~ s/_//g;
1455  carp "Unknown named parameter '$_'." unless exists $d{$u};
1456  $p{$u} = $p{$_};
1457  }
1458  for (keys %d) {
1459  $p{$_} = $d{$_} unless defined $p{$_};
1460  }
1461  unless ($Geo::GDAL::TYPE_INT2STRING{$p{BUFTYPE}}) {
1462  confess "Unknown data type: '$p{BUFTYPE}'."
1463  unless exists $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
1464  $p{BUFTYPE} = $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
1465  }
1466  $self->_WriteRaster($p{XOFF},$p{YOFF},$p{XSIZE},$p{YSIZE},$p{BUF},$p{BUFXSIZE},$p{BUFYSIZE},$p{BUFTYPE},$p{BUFPIXELSPACE},$p{BUFLINESPACE});
1467 }
1468 
1469 #** @method WriteTile($data, $xoff = 0, $yoff = 0)
1470 # @param data A two-dimensional Perl array, organizes as data->[y][x], y =
1471 # 0..height-1, x = 0..width-1.
1472 # @param xoff
1473 # @param yoff
1474 #
1475 #*
1476 sub WriteTile {
1477  my($self, $data, $xoff, $yoff) = @_;
1478  $xoff = 0 unless defined $xoff;
1479  $yoff = 0 unless defined $yoff;
1480  my $xsize = @{$data->[0]};
1481  $xsize = $self->{XSize} - $xoff if $xsize > $self->{XSize} - $xoff;
1482  my $ysize = @{$data};
1483  $ysize = $self->{YSize} - $yoff if $ysize > $self->{YSize} - $yoff;
1484  my $pc = Geo::GDAL::PackCharacter($self->{DataType});
1485  for my $i (0..$ysize-1) {
1486  my $scanline = pack($pc."[$xsize]", @{$data->[$i]});
1487  $self->WriteRaster( $xoff, $yoff+$i, $xsize, 1, $scanline );
1488  }
1489 }
1490 
1491 #** @class Geo::GDAL::ColorTable
1492 # @brief A color table in a raster band.
1493 #*
1494 package Geo::GDAL::ColorTable;
1495 
1496 use base qw(Geo::GDAL)
1497 
1498 #** @method Geo::GDAL::ColorTable Clone()
1499 # @return a new Geo::GDAL::ColorTable object
1500 #*
1501 sub Clone {
1502 }
1503 
1504 #** @method list ColorEntries(@color_entries)
1505 # Get or set the table of color entries.
1506 # @deprecated use Geo::GDAL::ColorTable::ColorTable
1507 #
1508 # @param color_entries [optional]
1509 # @return a table of color entries (a list of lists) in a non void context
1510 #*
1511 sub ColorEntries {
1512 }
1513 
1514 #** @method list ColorEntry($i, @color)
1515 # Get or set a color entry.
1516 # @param i
1517 # @param color [optional]
1518 # @return a color entry
1519 #*
1520 sub ColorEntry {
1521  my $self = shift;
1522  my $index = shift;
1523  SetColorEntry($self, $index, @_) if @_ > 0;
1524  GetColorEntry($self, $index) if defined wantarray;
1525 }
1526 
1527 #** @method list ColorTable(@colortable)
1528 # Get or set the table of color entries.
1529 # @param colortable [optional]
1530 # @return a table of color entries (a list of lists) in a non void context
1531 #*
1532 sub ColorTable {
1533  my $self = shift;
1534  my @table;
1535  if (@_) {
1536  my $index = 0;
1537  for my $color (@_) {
1538  push @table, [ColorEntry($self, $index, @$color)];
1539  $index++;
1540  }
1541  } else {
1542  for (my $index = 0; $index < GetCount($self); $index++) {
1543  push @table, [ColorEntry($self, $index)];
1544  }
1545  }
1546  return @table;
1547 }
1548 
1549 #** @method CreateColorRamp($start_index, arrayref start_color, $end_index, arrayref end_color)
1550 # @param start_index
1551 # @param start_color
1552 # @param end_index
1553 # @param end_color
1554 #
1555 #*
1556 sub CreateColorRamp {
1557 }
1558 
1559 #** @method list GetColorEntry($i)
1560 # @param i
1561 # @return array ColorEntry = ($c1, $c2, $c3, $c4)
1562 #*
1563 sub GetColorEntry {
1564 }
1565 
1566 #** @method list GetColorEntryAsRGB($i)
1567 # @param i
1568 # @return array ColorEntry = ($r, $g, $b, $alpha)
1569 #*
1570 sub GetColorEntryAsRGB {
1571 }
1572 
1573 #** @method scalar GetCount()
1574 # @return scalar (count of color entries as int)
1575 #*
1576 sub GetCount {
1577 }
1578 
1579 #** @method scalar GetPaletteInterpretation()
1580 # @return paletter interpretation (string)
1581 #*
1582 sub GetPaletteInterpretation {
1583  my $self = shift;
1584  return $PALETTE_INTERPRETATION_INT2STRING{GetPaletteInterpretation($self)};
1585 }
1586 
1587 #** @method SetColorEntry($index, @ColorEntry)
1588 # @param index
1589 # @param ColorEntry a list or a reference to an array
1590 #
1591 #*
1592 sub SetColorEntry {
1593  my $self = shift;
1594  my $index = shift;
1595  my $color;
1596  if (ref($_[0]) eq 'ARRAY') {
1597  $color = shift;
1598  } else {
1599  $color = [@_];
1600  }
1601  eval {
1602  $self->_SetColorEntry($index, $color);
1603  };
1604  confess $@ if $@;
1605 }
1606 
1607 #** @method Geo::GDAL::ColorTable new($GDALPaletteInterp = 'RGB')
1608 # Class method.
1609 #
1610 # Usage:
1611 # \code
1612 # $ct = Geo::GDAL::ColorTable->new(...arguments...);
1613 # \endcode
1614 # @return a new Geo::GDAL::ColorTable object
1615 #*
1616 sub new {
1617  my($pkg, $pi) = @_;
1618  $pi = $PALETTE_INTERPRETATION_STRING2INT{$pi} if defined $pi and exists $PALETTE_INTERPRETATION_STRING2INT{$pi};
1619  my $self = Geo::GDALc::new_ColorTable($pi);
1620  bless $self, $pkg if defined($self);
1621 }
1622 
1623 #** @class Geo::GDAL::Dataset
1624 # @brief A set of associated raster bands.
1625 #*
1626 package Geo::GDAL::Dataset;
1627 
1628 use base qw(Geo::GDAL::MajorObject Geo::GDAL)
1629 
1630 #** @attr $RasterCount
1631 # scalar (access as $dataset->{RasterCount})
1632 #*
1633 
1634 #** @attr $RasterXSize
1635 # scalar (access as $dataset->{RasterXSize})
1636 #*
1637 
1638 #** @attr $RasterYSize
1639 # scalar (access as $dataset->{RasterYSize})
1640 #*
1641 
1642 #** @method AddBand($datatype = 'Byte', hashref options = 0)
1643 # Add a new band to the dataset. The driver must support the action.
1644 # @param datatype GDAL pixel data type (one of those listed by Geo::GDAL::DataTypes).
1645 # @param options reference to a hash of format specific key=>value options.
1646 #*
1647 sub AddBand {
1648  my @p = @_;
1649  if (defined $p[1]) {
1650  confess "Unknown data type: '$p[1]'." unless exists $Geo::GDAL::TYPE_STRING2INT{$p[1]};
1651  $p[1] = $Geo::GDAL::TYPE_STRING2INT{$p[1]};
1652  }
1653  return _AddBand(@p);
1654 }
1655 
1656 #** @method Geo::GDAL::Band Band($index)
1657 # Create a band object for the band within the dataset.
1658 # @note a.k.a. GetRasterBand
1659 # @param index 1...RasterCount
1660 # @return a new Geo::GDAL::Band object
1661 #*
1662 sub Band {
1663 }
1664 
1665 #** @method list Bands()
1666 # @return a list of new Geo::GDAL::Band objects
1667 #*
1668 sub Bands {
1669  my $self = shift;
1670  my @bands;
1671  for my $i (1..$self->{RasterCount}) {
1672  push @bands, GetRasterBand($self, $i);
1673  }
1674  return @bands;
1675 }
1676 
1677 #** @method BuildOverviews($resampling, arrayref overviews, subref progress, $progress_data)
1678 # @param resampling the resampling method, one of Geo::GDAL::RIOResamplingTypes.
1679 # @param overviews The list of overview decimation factors to
1680 # build. For example [2,4,8].
1681 # @param progress [optional] a reference to a subroutine, which will
1682 # be called with parameters (number progress, string msg, progress_data)
1683 # @param progress_data [optional]
1684 #*
1685 sub BuildOverviews {
1686  my $self = shift;
1687  my @p = @_;
1688  $p[0] = uc($p[0]) if $p[0];
1689  eval {
1690  $self->_BuildOverviews(@p);
1691  };
1692  confess $@ if $@;
1693 }
1694 
1695 #** @method CommitTransaction()
1696 #*
1697 sub CommitTransaction {
1698 }
1699 
1700 #** @method Domains()
1701 #*
1702 sub Domains {
1703  return @DOMAINS;
1704 }
1705 
1706 #** @method list GCPs(@GCPs, Geo::OSR::SpatialReference sr)
1707 # Get or set the GCPs and their projection.
1708 # @param GCPs [optional] a list of Geo::GDAL::GCP objects
1709 # @param sr [optional] the projection of the GCPs.
1710 # @return a list of Geo::GDAL::GCP objects followed by a Geo::OSR::SpatialReference object.
1711 #*
1712 sub GCPs {
1713  my $self = shift;
1714  if (@_ > 0) {
1715  my $proj = pop @_;
1716  $proj = $proj->Export('WKT') if $proj and ref($proj);
1717  SetGCPs($self, \@_, $proj);
1718  }
1719  return unless defined wantarray;
1720  my $proj = Geo::OSR::SpatialReference->new(GetGCPProjection($self));
1721  my $GCPs = GetGCPs($self);
1722  return (@$GCPs, $proj);
1723 }
1724 
1725 #** @method Geo::GDAL::GeoTransform GeoTransform(Geo::GDAL::GeoTransform $geo_transform)
1726 # Transformation from pixel coordinates (column,row) to projection
1727 # coordinates (x,y)
1728 # \code
1729 # x = geo_transform[0] + column*geo_transform[1] + row*geo_transform[2]
1730 # y = geo_transform[3] + column*geo_transform[4] + row*geo_transform[5]
1731 # \endcode
1732 # @param geo_transform [optional]
1733 # @return the geo transform in a non-void context.
1734 #*
1735 sub GeoTransform {
1736  my $self = shift;
1737  eval {
1738  if (@_ == 1) {
1739  SetGeoTransform($self, $_[0]);
1740  } elsif (@_ > 1) {
1741  SetGeoTransform($self, \@_);
1742  }
1743  };
1744  confess $@ if $@;
1745  return unless defined wantarray;
1746  my $t = GetGeoTransform($self);
1747  if (wantarray) {
1748  return @$t;
1749  } else {
1750  return Geo::GDAL::GeoTransform->new($t);
1751  }
1752 }
1753 
1754 #** @method Geo::GDAL::Driver GetDriver()
1755 # @return a new Geo::GDAL::Driver object
1756 #*
1757 sub GetDriver {
1758 }
1759 
1760 #** @method list GetFileList()
1761 # @return list of files GDAL believes to be part of this dataset.
1762 #*
1763 sub GetFileList {
1764 }
1765 
1766 #** @method scalar GetGCPProjection()
1767 # @return projection string.
1768 #*
1769 sub GetGCPProjection {
1770 }
1771 
1772 #** @method Geo::GDAL::Dataset Open($name, $access='ReadOnly')
1773 # Class method.
1774 # An example:
1775 # \code
1776 # use Geo::GDAL;
1777 # $ds = Geo::GDAL::Dataset::Open('/data/dem.tiff', 'Update');
1778 # \endcode
1779 # @param name
1780 # @param access Access type (one of those listed by Geo::GDAL::AccessTypes).
1781 # @return a new Geo::GDAL::Dataset object.
1782 #*
1783 sub Open {
1784  return Geo::GDAL::Open(@_);
1785 }
1786 
1787 #** @method Geo::GDAL::Dataset OpenShared($name, $access='ReadOnly')
1788 # Class method.
1789 # @param name
1790 # @param access Access type (one of those listed by Geo::GDAL::AccessTypes).
1791 # @return a new Geo::GDAL::Dataset object.
1792 #*
1793 sub OpenShared {
1794  return Geo::GDAL::OpenShared(@_);
1795 }
1796 
1797 #** @method scalar ReadRaster(%params)
1798 # Read data from the dataset.
1799 #
1800 # @param params named parameters. These are
1801 # - \a XOff x offset (pixel coordinates) (default is 0)
1802 # - \a YOff y offset (pixel coordinates) (default is 0)
1803 # - \a XSize width of the area to read (default is the width of the dataset)
1804 # - \a YSize height of the area to read (default is the height of the dataset)
1805 # - \a BufXSize (default is undef, i.e., the same as XSize)
1806 # - \a BufYSize (default is undef, i.e., the same as YSize)
1807 # - \a BufType data type of the buffer (default is the data type of the first band)
1808 # - \a BandList a reference to an array of band indeces (default is [1])
1809 # - \a BufPixelSpace (default is 0)
1810 # - \a BufLineSpace (default is 0)
1811 # - \a BufBandSpace (default is 0)
1812 # - \a ResampleAlg one of Geo::GDAL::RIOResamplingTypes (default is 'NearestNeighbour'),
1813 # - \a Progress reference to a progress function (default is undef)
1814 # - \a ProgressData (default is undef)
1815 #
1816 # If the parameters are given as a list the order is as above.
1817 # <a href="http://www.gdal.org/classGDALDataset.html">Entry in GDAL docs (method RasterIO)</a>
1818 # @return a buffer, open the buffer with \a unpack function of Perl. See Geo::GDAL::Band::PackCharacter.
1819 #*
1820 sub ReadRaster {
1821  my $self = shift;
1822  my ($width, $height) = $self->Size;
1823  my ($type) = $self->Band->DataType;
1824  my %d = (
1825  XOFF => 0,
1826  YOFF => 0,
1827  XSIZE => $width,
1828  YSIZE => $height,
1829  BUFXSIZE => undef,
1830  BUFYSIZE => undef,
1831  BUFTYPE => $type,
1832  BANDLIST => [1],
1833  BUFPIXELSPACE => 0,
1834  BUFLINESPACE => 0,
1835  BUFBANDSPACE => 0,
1836  RESAMPLEALG => 'NearestNeighbour',
1837  PROGRESS => undef,
1838  PROGRESSDATA => undef
1839  );
1840  my %p;
1841  my $t;
1842  if (defined $_[0]) {
1843  $t = uc($_[0]);
1844  $t =~ s/_//g;
1845  }
1846  if (@_ == 0) {
1847  } elsif (ref($_[0]) eq 'HASH') {
1848  %p = %{$_[0]};
1849  } elsif (@_ % 2 == 0 and (defined $t and exists $d{$t})) {
1850  %p = @_;
1851  } else {
1852  ($p{xoff},$p{yoff},$p{xsize},$p{ysize},$p{buf_xsize},$p{buf_ysize},$p{buf_type},$p{band_list},$p{buf_pixel_space},$p{buf_line_space},$p{buf_band_space},$p{resample_alg},$p{progress},$p{progress_data}) = @_;
1853  }
1854  for (keys %p) {
1855  my $u = uc($_);
1856  $u =~ s/_//g;
1857  carp "Unknown named parameter '$_'." unless exists $d{$u};
1858  $p{$u} = $p{$_};
1859  }
1860  for (keys %d) {
1861  $p{$_} = $d{$_} unless defined $p{$_};
1862  }
1863  confess "Unknown resampling algorithm: '$p{RESAMPLEALG}'."
1864  unless exists $Geo::GDAL::RIO_RESAMPLING_STRING2INT{$p{RESAMPLEALG}};
1865  $p{RESAMPLEALG} = $Geo::GDAL::RIO_RESAMPLING_STRING2INT{$p{RESAMPLEALG}};
1866  unless ($Geo::GDAL::TYPE_INT2STRING{$p{BUFTYPE}}) {
1867  confess "Unknown data type: '$p{BUFTYPE}'."
1868  unless exists $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
1869  $p{BUFTYPE} = $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
1870  }
1871  $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});
1872 }
1873 
1874 #** @method RollbackTransaction()
1875 #*
1876 sub RollbackTransaction {
1877 }
1878 
1879 #** @method list Size()
1880 # @return (width, height)
1881 #*
1882 sub Size {
1883  my $self = shift;
1884  return ($self->{RasterXSize}, $self->{RasterYSize});
1885 }
1886 
1887 #** @method Geo::OSR::SpatialReference SpatialReference(Geo::OSR::SpatialReference sr)
1888 # Get or set the projection of this dataset.
1889 # @param sr [optional] a Geo::OSR::SpatialReference object,
1890 # which replaces the existing projection definition of this dataset.
1891 # @return a Geo::OSR::SpatialReference object, which represents the
1892 # projection of this dataset.
1893 # @note Methods GetProjection, SetProjection, and Projection return WKT strings.
1894 #*
1895 sub SpatialReference {
1896  my($self, $sr) = @_;
1897  SetProjection($self, $sr->As('WKT')) if defined $sr;
1898  return Geo::OSR::SpatialReference->new(GetProjection($self)) if defined wantarray;
1899 }
1900 
1901 #** @method StartTransaction()
1902 #*
1903 sub StartTransaction {
1904 }
1905 
1906 #** @method WriteRaster(%params)
1907 # Write data into the dataset.
1908 #
1909 # @param params named parameters. These are
1910 # - \a XOff x offset (pixel coordinates) (default is 0)
1911 # - \a YOff y offset (pixel coordinates) (default is 0)
1912 # - \a XSize width of the area to write (default is the width of the dataset)
1913 # - \a YSize height of the area to write (default is the height of the dataset)
1914 # - \a Buf a buffer containing the data. Create the buffer with \a pack function of Perl. See Geo::GDAL::Band::PackCharacter.
1915 # - \a BufXSize (default is undef, i.e., the same as XSize)
1916 # - \a BufYSize (default is undef, i.e., the same as YSize)
1917 # - \a BufType data type of the buffer (default is the data type of the first band)
1918 # - \a BandList a reference to an array of band indeces (default is [1])
1919 # - \a BufPixelSpace (default is 0)
1920 # - \a BufLineSpace (default is 0)
1921 # - \a BufBandSpace (default is 0)
1922 #
1923 # If the parameters are given as a list the order is as above.
1924 # <a href="http://www.gdal.org/classGDALDataset.html">Entry in GDAL docs (method RasterIO)</a>
1925 #*
1926 sub WriteRaster {
1927  my $self = shift;
1928  my ($width, $height) = $self->Size;
1929  my ($type) = $self->Band->DataType;
1930  my %d = (
1931  XOFF => 0,
1932  YOFF => 0,
1933  XSIZE => $width,
1934  YSIZE => $height,
1935  BUF => undef,
1936  BUFXSIZE => undef,
1937  BUFYSIZE => undef,
1938  BUFTYPE => $type,
1939  BANDLIST => [1],
1940  BUFPIXELSPACE => 0,
1941  BUFLINESPACE => 0,
1942  BUFBANDSPACE => 0
1943  );
1944  my %p;
1945  my $t;
1946  if (defined $_[0]) {
1947  $t = uc($_[0]);
1948  $t =~ s/_//g;
1949  }
1950  if (@_ == 0) {
1951  } elsif (ref($_[0]) eq 'HASH') {
1952  %p = %{$_[0]};
1953  } elsif (@_ % 2 == 0 and (defined $t and exists $d{$t})) {
1954  %p = @_;
1955  } else {
1956  ($p{xoff},$p{yoff},$p{xsize},$p{ysize},$p{buf},$p{buf_xsize},$p{buf_ysize},$p{buf_type},$p{band_list},$p{buf_pixel_space},$p{buf_line_space},$p{buf_band_space}) = @_;
1957  }
1958  for (keys %p) {
1959  my $u = uc($_);
1960  $u =~ s/_//g;
1961  carp "Unknown named parameter '$_'." unless exists $d{$u};
1962  $p{$u} = $p{$_};
1963  }
1964  for (keys %d) {
1965  $p{$_} = $d{$_} unless defined $p{$_};
1966  }
1967  unless ($Geo::GDAL::TYPE_INT2STRING{$p{BUFTYPE}}) {
1968  confess "Unknown data type: '$p{BUFTYPE}'."
1969  unless exists $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
1970  $p{BUFTYPE} = $Geo::GDAL::TYPE_STRING2INT{$p{BUFTYPE}};
1971  }
1972  $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});
1973 }
1974 
1975 #** @class Geo::GDAL::Driver
1976 # @brief A raster format driver.
1977 #*
1978 package Geo::GDAL::Driver;
1979 
1980 use base qw(Geo::GDAL::MajorObject Geo::GDAL)
1981 
1982 #** @attr $HelpTopic
1983 # $driver->{HelpTopic}
1984 #*
1985 
1986 #** @attr $LongName
1987 # $driver->{LongName}
1988 #*
1989 
1990 #** @attr $ShortName
1991 # $driver->{ShortName}
1992 #*
1993 
1994 #** @method list Capabilities()
1995 # @return A list of capabilities. When executed as a class method
1996 # returns a list of all potential capabilities a driver may have. When
1997 # executed as an object method returns a list of all capabilities the
1998 # driver has.
1999 #
2000 # Currently capabilities are:
2001 # CREATE, CREATECOPY, DEFAULT_FIELDS, NOTNULL_FIELDS, NOTNULL_GEOMFIELDS, OPEN, RASTER, VECTOR, and VIRTUALIO.
2002 #
2003 # Examples.
2004 # \code
2005 # @all_capabilities = Geo::GDAL::Driver::Capabilities;
2006 # @capabilities_of_the_geotiff_driver = Geo::GDAL::Driver('GTiff')->Capabilities;
2007 # \endcode
2008 #*
2009 sub Capabilities {
2010  my $self = shift;
2011  return @CAPABILITIES unless $self;
2012  my $h = $self->GetMetadata;
2013  my @cap;
2014  for my $cap (@CAPABILITIES) {
2015  my $test = $h->{'DCAP_'.uc($cap)};
2016  push @cap, $cap if defined($test) and $test eq 'YES';
2017  }
2018  return @cap;
2019 }
2020 
2021 #** @method Geo::GDAL::Dataset Copy($name, $src, $strict = 1, hashref options = undef)
2022 # Copy the files of a dataset.
2023 # @param NewName String.
2024 # @param OldName String.
2025 # Create a new Geo::GDAL::Dataset as a copy of an existing dataset.
2026 # @note a.k.a. CreateCopy
2027 # @param name
2028 # @param src A Geo::GDAL::Dataset object.
2029 # @param strict
2030 # @param options An anonymous hash of driver specific parameters.
2031 # @return a new Geo::GDAL::Dataset object.
2032 #*
2033 sub Copy {
2034 }
2035 
2036 #** @method CopyFiles()
2037 #*
2038 sub CopyFiles {
2039 }
2040 
2041 #** @method Geo::GDAL::Dataset Create(%params)
2042 # Create a GDAL dataset using this driver.
2043 # @note a.k.a. CreateDataset
2044 #
2045 # @note As a list the parameters are: Name, Width, Height, NumberOfBands, PixelDataType, Options
2046 #
2047 # Create a new Geo::GDAL::Dataset
2048 # @param params named parameters:
2049 # - \a Name the name of the dataset (default is 'unnamed').
2050 # - \a Width the width of the dataset (default is 256).
2051 # - \a Height the height of the dataset (default is 256).
2052 # - \a Bands number of bands in the dataset (default is 1).
2053 # - \a Type the data type of the pixels the dataset (default is 'Byte'). One of Geo::OGR::Driver::CreationDataTypes.
2054 # - \a Options creation options as a reference to a hash (default is {}).
2055 #
2056 # @return a new Geo::GDAL::Dataset object.
2057 #*
2058 sub Create {
2059  my $self = shift;
2060  my %defaults = ( Name => 'unnamed',
2061  Width => 256,
2062  Height => 256,
2063  Bands => 1,
2064  Type => 'Byte',
2065  Options => {} );
2066  my %params;
2067  if (@_ == 0) {
2068  } elsif (ref($_[0]) eq 'HASH') {
2069  %params = %{$_[0]};
2070  } elsif (exists $defaults{$_[0]} and @_ % 2 == 0) {
2071  %params = @_;
2072  } else {
2073  ($params{Name}, $params{Width}, $params{Height}, $params{Bands}, $params{Type}, $params{Options}) = @_;
2074  }
2075  for my $k (keys %params) {
2076  carp "Create: unrecognized named parameter '$k'." unless exists $defaults{$k};
2077  }
2078  for my $k (keys %defaults) {
2079  $params{$k} = $defaults{$k} unless defined $params{$k};
2080  }
2081  my $type;
2082  confess "Unknown data type: '$params{Type}'." unless exists $Geo::GDAL::TYPE_STRING2INT{$params{Type}};
2083  $type = $Geo::GDAL::TYPE_STRING2INT{$params{Type}};
2084  return $self->_Create($params{Name}, $params{Width}, $params{Height}, $params{Bands}, $type, $params{Options});
2085 }
2086 
2087 #** @method list CreationDataTypes()
2088 # @return a list of data types that can be used for new datasets.
2089 #*
2090 sub CreationDataTypes {
2091  my $self = shift;
2092  my $h = $self->GetMetadata;
2093  return split /\s+/, $h->{DMD_CREATIONDATATYPES} if $h->{DMD_CREATIONDATATYPES};
2094 }
2095 
2096 #** @method list CreationOptionList()
2097 # @return a list of options, each option is a hashref, the keys are
2098 # name, type and description or Value. Value is a listref.
2099 #*
2100 sub CreationOptionList {
2101  my $self = shift;
2102  my @options;
2103  my $h = $self->GetMetadata->{DMD_CREATIONOPTIONLIST};
2104  if ($h) {
2105  $h = Geo::GDAL::ParseXMLString($h);
2106  my($type, $value) = Geo::GDAL::NodeData($h);
2107  if ($value eq 'CreationOptionList') {
2108  for my $o (Geo::GDAL::Children($h)) {
2109  my %option;
2110  for my $a (Geo::GDAL::Children($o)) {
2111  my(undef, $key) = Geo::GDAL::NodeData($a);
2112  my(undef, $value) = Geo::GDAL::NodeData(Geo::GDAL::Child($a, 0));
2113  if ($key eq 'Value') {
2114  push @{$option{$key}}, $value;
2115  } else {
2116  $option{$key} = $value;
2117  }
2118  }
2119  push @options, \%option;
2120  }
2121  }
2122  }
2123  return @options;
2124 }
2125 
2126 #** @method Delete($name)
2127 # @param name
2128 #*
2129 sub Delete {
2130 }
2131 
2132 #** @method Domains()
2133 #*
2134 sub Domains {
2135  return @DOMAINS;
2136 }
2137 
2138 #** @method scalar Extension()
2139 # @return a suggested extension or extensions (e.g., ext1/ext2) for
2140 # datasets.
2141 #*
2142 sub Extension {
2143  my $self = shift;
2144  my $h = $self->GetMetadata;
2145  return $h->{DMD_EXTENSION};
2146 }
2147 
2148 #** @method scalar MIMEType()
2149 # @return a suggested MIME type for datasets.
2150 #*
2151 sub MIMEType {
2152  my $self = shift;
2153  my $h = $self->GetMetadata;
2154  return $h->{DMD_MIMETYPE};
2155 }
2156 
2157 #** @method scalar Name()
2158 # @return The short name of the driver.
2159 #*
2160 sub Name {
2161  my $self = shift;
2162  return $self->{ShortName};
2163 }
2164 
2165 #** @method Rename($NewName, $OldName)
2166 # Rename (move) a GDAL dataset.
2167 # @param NewName String.
2168 # @param OldName String.
2169 #*
2170 sub Rename {
2171 }
2172 
2173 #** @method scalar TestCapability($cap)
2174 # Test whether the driver has the specified capability.
2175 # @param cap A capability string (one of those returned by Capabilities).
2176 # @return a boolean value.
2177 #*
2178 sub TestCapability {
2179  my($self, $cap) = @_;
2180  my $h = $self->GetMetadata->{'DCAP_'.uc($cap)};
2181  return (defined($h) and $h eq 'YES') ? 1 : undef;
2182 }
2183 
2184 #** @class Geo::GDAL::GCP
2185 # @brief A ground control point for georeferencing images.
2186 #*
2187 package Geo::GDAL::GCP;
2188 
2189 use base qw(Geo::GDAL)
2190 
2191 #** @attr $Column
2192 # pixel x coordinate (access as $gcp->{Column})
2193 # @note Pixel is deprecated.
2194 #
2195 #*
2196 
2197 #** @attr $Id
2198 # unique identifier (string) (access as $gcp->{Id})
2199 #*
2200 
2201 #** @attr $Info
2202 # informational message (access as $gcp->{Info})
2203 #*
2204 
2205 #** @attr $Row
2206 # pixel y coordinate (access as $gcp->{Row})
2207 # @note Line is deprecated.
2208 #
2209 #*
2210 
2211 #** @attr $X
2212 # projection coordinate (access as $gcp->{X})
2213 #*
2214 
2215 #** @attr $Y
2216 # projection coordinate (access as $gcp->{Y})
2217 #*
2218 
2219 #** @attr $Z
2220 # projection coordinate (access as $gcp->{Z})
2221 #*
2222 
2223 #** @method scalar new($x = 0.0, $y = 0.0, $z = 0.0, $column = 0.0, $row = 0.0, $info = "", $id = "")
2224 # Class method.
2225 # @param x projection coordinate
2226 # @param y projection coordinate
2227 # @param z projection coordinate
2228 # @param column pixel x coordinate
2229 # @param row pixel y coordinate
2230 # @param info informational message
2231 # @param id unique identifier (string)
2232 # @return a new Geo::GDAL::GCP object
2233 #*
2234 sub new {
2235  my $pkg = shift;
2236  my $self = Geo::GDALc::new_GCP(@_);
2237  bless $self, $pkg if defined($self);
2238 }
2239 
2240 #** @class Geo::GDAL::GeoTransform
2241 # @brief An array of affine transformation coefficients.
2242 #
2243 # The geo transformation has the form
2244 # \code
2245 # x = a + column * b + row * c
2246 # y = d + column * e + row * f
2247 # \endcode
2248 # where<br/>
2249 # (column,row) is the location in pixel coordinates<br/>
2250 # (x,y) is the location in projection coordinates<br/>
2251 # or vice versa.
2252 # A Geo::GDAL::GeoTransform object is a reference to an anonymous array.
2253 #*
2254 package Geo::GDAL::GeoTransform;
2255 
2256 use base qw()
2257 
2258 #** @method Apply(array reference x, array reference y)
2259 # @return a list (x, y), where x and y are references to arrays of
2260 # transformed coordinates.
2261 #*
2262 sub Apply {
2263  my ($self, $columns, $rows) = @_;
2264  my (@x, @y);
2265  for my $i (0..$#$columns) {
2266  ($x[$i], $y[$i]) =
2267  Geo::GDAL::ApplyGeoTransform($self, $columns->[$i], $rows->[$i]);
2268  }
2269  return (\@x, \@y);
2270 }
2271 
2272 #** @method FromGCPs(@GCPs, $ApproxOK)
2273 # Compute transformation coefficients from a list of Geo::GDAL::GCP
2274 # objects
2275 # @param GCPs A list of Geo::GDAL::GCP objects.
2276 # @param ApproxOK [optional] Minimize the error in the coefficient (integer, default is true).
2277 # @return a new Geo::GDAL::GeoTransform object.
2278 #*
2279 sub FromGCPs {
2280  my @GCPs;
2281  my $ApproxOK = 1;
2282  if (ref($_[0]) eq 'ARRAY') {
2283  @GCPs = @{$_[0]};
2284  $ApproxOK = $_[1] if defined $_[1];
2285  } else {
2286  @GCPs = @_;
2287  $ApproxOK = pop @GCPs if !ref($GCPs[$#GCPs]);
2288  }
2289  my $self = Geo::GDAL::GCPsToGeoTransform(\@GCPs, $ApproxOK);
2290  bless $self, 'Geo::GDAL::GetTransform';
2291  return $self;
2292 }
2293 
2294 #** @method Inv()
2295 # @return a new Geo::GDAL::GeoTransform object, which is the inverse
2296 # of this one (in void context changes this object).
2297 #*
2298 sub Inv {
2299  my $self = shift;
2300  my @inv = Geo::GDAL::InvGeoTransform($self);
2301  unless (defined wantarray) {
2302  @$self = @inv;
2303  } else {
2304  return new(@inv);
2305  }
2306 }
2307 1;
2308 # This file was automatically generated by SWIG (http://www.swig.org).
2309 # Version 3.0.5
2310 #
2311 # Do not make changes to this file unless you know what you are doing--modify
2312 # the SWIG interface file instead.
2313 }
2314 
2315 #** @method new(@coeffs)
2316 # Class method.
2317 # @return a new Geo::GDAL::GeoTransform object.
2318 #*
2319 sub new {
2320  my $class = shift;
2321  my $self;
2322  if (@_ == 0) {
2323  $self = [0,1,0,0,0,1];
2324  } elsif (@_ == 1) {
2325  $self = $_[0];
2326  } else {
2327  my @a = @_;
2328  $self = \@a;
2329  }
2330  bless $self, $class;
2331  return $self;
2332 }
2333 
2334 #** @class Geo::GDAL::MajorObject
2335 # @brief An object, which holds meta data.
2336 #*
2337 package Geo::GDAL::MajorObject;
2338 
2339 use base qw(Geo::GDAL)
2340 
2341 #** @method scalar Description($description)
2342 # @param description [optional]
2343 # @return the description in a non-void context.
2344 #*
2345 sub Description {
2346  my($self, $desc) = @_;
2347  SetDescription($self, $desc) if defined $desc;
2348  GetDescription($self) if defined wantarray;
2349 }
2350 
2351 #** @method Domains()
2352 # Class method.
2353 # @return the class specific DOMAINS list
2354 #*
2355 sub Domains {
2356  return @DOMAINS;
2357 }
2358 
2359 #** @method scalar GetDescription()
2360 # @return
2361 #*
2362 sub GetDescription {
2363 }
2364 
2365 #** @method hash reference GetMetadata($domain = "")
2366 # @note see Metadata
2367 # @param domain
2368 # @return
2369 #*
2370 sub GetMetadata {
2371 }
2372 
2373 #** @method GetMetadataDomainList()
2374 #*
2375 sub GetMetadataDomainList {
2376 }
2377 
2378 #** @method hash reference Metadata(hashref metadata = undef, $domain = '')
2379 # @param metadata
2380 # @param domain
2381 # @return the metadata in a non-void context.
2382 #*
2383 sub Metadata {
2384  my $self = shift;
2385  my $metadata;
2386  $metadata = shift if ref $_[0];
2387  my $domain = shift;
2388  $domain = '' unless defined $domain;
2389  SetMetadata($self, $metadata, $domain) if defined $metadata;
2390  GetMetadata($self, $domain) if defined wantarray;
2391 }
2392 
2393 #** @method SetDescription($NewDesc)
2394 # @param NewDesc
2395 #
2396 #*
2397 sub SetDescription {
2398 }
2399 
2400 #** @method SetMetadata(hashref metadata, $domain = "")
2401 # @note see Metadata
2402 # @param metadata
2403 # @param domain
2404 #
2405 #*
2406 sub SetMetadata {
2407 }
2408 
2409 #** @class Geo::GDAL::RasterAttributeTable
2410 # @brief An attribute table in a raster band.
2411 #*
2412 package Geo::GDAL::RasterAttributeTable;
2413 
2414 use base qw(Geo::GDAL)
2415 
2416 #** @method ChangesAreWrittenToFile()
2417 #*
2418 sub ChangesAreWrittenToFile {
2419 }
2420 
2421 #** @method Geo::GDAL::RasterAttributeTable Clone()
2422 # @return a new Geo::GDAL::RasterAttributeTable object
2423 #*
2424 sub Clone {
2425 }
2426 
2427 #** @method hash Columns(%columns)
2428 # A get/set method for the columns of the RAT
2429 # @param columns optional, a the keys are column names and the values are anonymous
2430 # hashes with keys Type and Usage
2431 # @return a hash similar to the optional input parameter
2432 #*
2433 sub Columns {
2434  my $self = shift;
2435  my %columns;
2436  if (@_) { # create columns
2437  %columns = @_;
2438  for my $name (keys %columns) {
2439  $self->CreateColumn($name, $columns{$name}{Type}, $columns{$name}{Usage});
2440  }
2441  }
2442  %columns = ();
2443  for my $c (0..$self->GetColumnCount-1) {
2444  my $name = $self->GetNameOfCol($c);
2445  $columns{$name}{Type} = $self->GetTypeOfCol($c);
2446  $columns{$name}{Usage} = $self->GetUsageOfCol($c);
2447  }
2448  return %columns;
2449 }
2450 
2451 #** @method CreateColumn($name, $type, $usage)
2452 # @param name
2453 # @param type one of FieldTypes
2454 # @param usage one of FieldUsages
2455 #*
2456 sub CreateColumn {
2457  my($self, $name, $type, $usage) = @_;
2458  confess "Unknown RAT column type: '$type'." unless exists $FIELD_TYPE_STRING2INT{$type};
2459  confess "Unknown RAT column usage: '$usage'." unless exists $FIELD_USAGE_STRING2INT{$usage};
2460  for my $color (qw/Red Green Blue Alpha/) {
2461  carp "RAT column type will be 'Integer' for usage '$color'." if $usage eq $color and $type ne 'Integer';
2462  }
2463  $type = $FIELD_TYPE_STRING2INT{$type};
2464  $usage = $FIELD_USAGE_STRING2INT{$usage};
2465  _CreateColumn($self, $name, $type, $usage);
2466 }
2467 
2468 #** @method DumpReadable()
2469 #*
2470 sub DumpReadable {
2471 }
2472 
2473 #** @method list FieldTypes()
2474 # Class method.
2475 # @return
2476 #*
2477 sub FieldTypes {
2478  return @FIELD_TYPES;
2479 }
2480 
2481 #** @method list FieldUsages()
2482 # Class method.
2483 # @return
2484 #*
2485 sub FieldUsages {
2486  return @FIELD_USAGES;
2487 }
2488 
2489 #** @method scalar GetColOfUsage($usage)
2490 # @param usage
2491 # @return
2492 #*
2493 sub GetColOfUsage {
2494  my($self, $usage) = @_;
2495  _GetColOfUsage($self, $FIELD_USAGE_STRING2INT{$usage});
2496 }
2497 
2498 #** @method scalar GetColumnCount()
2499 # @return
2500 #*
2501 sub GetColumnCount {
2502 }
2503 
2504 #** @method scalar GetNameOfCol($column)
2505 # @param column
2506 # @return
2507 #*
2508 sub GetNameOfCol {
2509 }
2510 
2511 #** @method scalar GetRowCount()
2512 #*
2513 sub GetRowCount {
2514 }
2515 
2516 #** @method scalar GetRowOfValue($value)
2517 # @param value a pixel value
2518 # @return row index or -1
2519 #*
2520 sub GetRowOfValue {
2521 }
2522 
2523 #** @method scalar GetTypeOfCol($column)
2524 # @param column
2525 # @return
2526 #*
2527 sub GetTypeOfCol {
2528  my($self, $col) = @_;
2529  $FIELD_TYPE_INT2STRING{_GetTypeOfCol($self, $col)};
2530 }
2531 
2532 #** @method scalar GetUsageOfCol($column)
2533 # @param column
2534 # @return
2535 #*
2536 sub GetUsageOfCol {
2537  my($self, $col) = @_;
2538  $FIELD_USAGE_INT2STRING{_GetUsageOfCol($self, $col)};
2539 }
2540 
2541 #** @method scalar GetValueAsDouble($row, $column)
2542 # @param row
2543 # @param column
2544 # @return
2545 #*
2546 sub GetValueAsDouble {
2547 }
2548 
2549 #** @method scalar GetValueAsInt($row, $column)
2550 # @param row
2551 # @param column
2552 # @return
2553 #*
2554 sub GetValueAsInt {
2555 }
2556 
2557 #** @method scalar GetValueAsString($row, $column)
2558 # @param row
2559 # @param column
2560 # @return
2561 #*
2562 sub GetValueAsString {
2563 }
2564 
2565 #** @method LinearBinning($Row0MinIn, $BinSizeIn)
2566 # @param Row0MinIn [optional] the lower bound (pixel value) of the first category.
2567 # @param BinSizeIn [optional] the width of each category (in pixel value units).
2568 # @return ($Row0MinIn, $BinSizeIn) or an empty list if LinearBinning is not set.
2569 #*
2570 sub LinearBinning {
2571  my $self = shift;
2572  SetLinearBinning($self, @_) if @_ > 0;
2573  return unless defined wantarray;
2574  my @a = GetLinearBinning($self);
2575  return $a[0] ? ($a[1], $a[2]) : ();
2576 }
2577 
2578 #** @method SetRowCount($count)
2579 # @param count
2580 #
2581 #*
2582 sub SetRowCount {
2583 }
2584 
2585 #** @method SetValueAsDouble($row, $column, $value)
2586 # @param row
2587 # @param column
2588 # @param value
2589 #
2590 #*
2591 sub SetValueAsDouble {
2592 }
2593 
2594 #** @method SetValueAsInt($row, $column, $value)
2595 # @param row
2596 # @param column
2597 # @param value
2598 #
2599 #*
2600 sub SetValueAsInt {
2601 }
2602 
2603 #** @method SetValueAsString($row, $column, $value)
2604 # @param row
2605 # @param column
2606 # @param value
2607 #
2608 #*
2609 sub SetValueAsString {
2610 }
2611 
2612 #** @method scalar Value($row, $column, $value)
2613 # @param row
2614 # @param column
2615 # @param value [optional]
2616 # @return
2617 #*
2618 sub Value {
2619  my($self, $row, $column) = @_;
2620  SetValueAsString($self, $row, $column, $_[3]) if defined $_[3];
2621  return unless defined wantarray;
2622  GetValueAsString($self, $row, $column);
2623 }
2624 
2625 #** @method Geo::GDAL::RasterAttributeTable new()
2626 # Class method.
2627 # @return a new Geo::GDAL::RasterAttributeTable object
2628 #*
2629 sub new {
2630  my $pkg = shift;
2631  my $self = Geo::GDALc::new_RasterAttributeTable(@_);
2632  bless $self, $pkg if defined($self);
2633 }
2634 
2635 #** @class Geo::GDAL::Transformer
2636 # @brief
2637 #
2638 # This class is not yet documented for the GDAL Perl bindings.
2639 # @todo Test and document.
2640 #*
2641 package Geo::GDAL::Transformer;
2642 
2643 use base qw(Geo::GDAL)
2644 
2645 #** @method TransformGeolocations()
2646 #*
2647 sub TransformGeolocations {
2648 }
2649 
2650 #** @method TransformPoint()
2651 #*
2652 sub TransformPoint {
2653 }
2654 
2655 #** @method new()
2656 #*
2657 sub new {
2658  my $pkg = shift;
2659  my $self = Geo::GDALc::new_Transformer(@_);
2660  bless $self, $pkg if defined($self);
2661 }
2662 
2663 #** @class Geo::GDAL::VSIF
2664 # @brief A GDAL virtual file system.
2665 #*
2666 package Geo::GDAL::VSIF;
2667 
2668 use base qw()
2669 
2670 #** @method Close()
2671 #*
2672 sub Close {
2673  my ($self, $data) = @_;
2674  eval {
2675  Geo::GDAL::VSIFCloseL($self);
2676  };
2677  if ($@) {
2678  confess "Cannot close file: $@.";
2679  }
2680 }
2681 
2682 #** @method MkDir()
2683 #*
2684 sub MkDir {
2685  my ($path) = @_;
2686  my $mode = 0; # unused in CPL
2687  eval {
2688  Geo::GDAL::Mkdir($path, $mode);
2689  };
2690  if ($@) {
2691  confess "Cannot make directory \"$path\": $@.";
2692  }
2693 }
2694 
2695 #** @method Geo::GDAL::VSIF Open($filename, $mode)
2696 # Class method.
2697 # @param filename Name of the file to open. For example "/vsimem/x".
2698 # @param mode Access mode. 'r', 'r+', 'w', etc.
2699 # @return A file handle on success.
2700 #*
2701 sub Open {
2702  my ($path, $mode) = @_;
2703  my $self = Geo::GDAL::VSIFOpenL($path, $mode);
2704  bless $self, 'Geo::GDAL::VSIF';
2705 }
2706 
2707 #** @method scalar Read($count)
2708 # @param count The number of bytes to read from the file.
2709 # @return A byte string.
2710 #*
2711 sub Read {
2712  my ($self, $count) = @_;
2713  Geo::GDAL::VSIFReadL($count, $self);
2714 }
2715 
2716 #** @method list ReadDir($dir)
2717 # Class method.
2718 # @return Contents of a directory in an anonymous array or as a list.
2719 #*
2720 sub ReadDir {
2721  my ($path) = @_;
2722  Geo::GDAL::ReadDir($path);
2723 }
2724 
2725 #** @method scalar ReadDirRecursive($dir)
2726 # Class method.
2727 # @return Contents of a directory tree in an anonymous array.
2728 #*
2729 sub ReadDirRecursive {
2730  my ($path) = @_;
2731  Geo::GDAL::ReadDirRecursive($path);
2732 }
2733 
2734 #** @method Rename($old, $new)
2735 # Class method.
2736 # Rename a file.
2737 # @note The name of this method is VSIRename in GDAL.
2738 #
2739 #*
2740 sub Rename {
2741  my ($old, $new) = @_;
2742  eval {
2743  Geo::GDAL::Rename($old, $new);
2744  };
2745  if ($@) {
2746  confess "Cannot rename file \"$old\": $@.";
2747  }
2748 }
2749 
2750 #** @method RmDir()
2751 #*
2752 sub RmDir {
2753  my ($dirname, $recursive) = @_;
2754  eval {
2755  if (!$recursive) {
2756  Geo::GDAL::Rmdir($dirname);
2757  } else {
2758  for my $f (ReadDir($dirname)) {
2759  next if $f eq '..' or $f eq '.';
2760  my @s = Stat($dirname.'/'.$f);
2761  if ($s[0] eq 'f') {
2762  Unlink($dirname.'/'.$f);
2763  } elsif ($s[0] eq 'd') {
2764  Rmdir($dirname.'/'.$f, 1);
2765  Rmdir($dirname.'/'.$f);
2766  }
2767  }
2768  RmDir($dirname);
2769  }
2770  };
2771  if ($@) {
2772  my $r = $recursive ? ' recursively' : '';
2773  confess "Cannot remove directory \"$dirname\"$r: $@.";
2774  }
2775 }
2776 
2777 #** @method Rmdir($path)
2778 # Class method.
2779 # Remove a directory.
2780 # @note The name of this method is VSIRmdir in GDAL.
2781 #
2782 #*
2783 sub Rmdir {
2785 
2786 #** @method Seek($offset, $whence)
2787 #*
2788 sub Seek {
2789  my ($self, $offset, $whence) = @_;
2790  Geo::GDAL::VSIFSeekL($self, $offset, $whence);
2791 }
2792 
2793 #** @method list Stat($filename)
2794 # Class method.
2795 # @return ($filemode, $filesize). filemode is f for a plain file, d
2796 # for a directory, l for a symbolic link, p for a named pipe (FIFO), S
2797 # for a socket, b for a block special file, and c for a character
2798 # special file.
2799 #*
2800 sub Stat {
2801  my ($path) = @_;
2802  eval {
2803  Geo::GDAL::Stat($path);
2804  };
2805  if ($@) {
2806  confess "Cannot stat file \"$path\": $@.";
2807  }
2808 }
2809 
2810 #** @method scalar Tell()
2811 #*
2812 sub Tell {
2813  my ($self) = @_;
2814  Geo::GDAL::VSIFTellL($self);
2815 }
2816 
2817 #** @method Truncate($new_size)
2818 #*
2819 sub Truncate {
2820  my ($self, $new_size) = @_;
2821  eval {
2822  Geo::GDAL::VSIFTruncateL($self, $new_size);
2823  };
2824  if ($@) {
2825  confess "Cannot truncate file: $@.";
2826  }
2827 }
2828 
2829 #** @method Unlink($filename)
2830 # Class method.
2831 # @param filename The file to delete.
2832 # @return 0 on success and -1 on an error.
2833 #*
2834 sub Unlink {
2835  my ($filename) = @_;
2836  eval {
2837  Geo::GDAL::Unlink($filename);
2838  };
2839  if ($@) {
2840  confess "Cannot unlink file \"$filename\": $@.";
2841  }
2842 }
2843 
2844 #** @method Write($scalar)
2845 # @param scalar The byte string to write to the file.
2846 # @return Number of bytes written into the file.
2847 #*
2848 sub Write {
2849  my ($self, $data) = @_;
2850  Geo::GDAL::VSIFWriteL($data, $self);
2851 }
2852 
2853 #** @class Geo::OGR
2854 # @brief OGR utility functions.
2855 #
2856 # A wrapper for many OGR utility functions and a root class for all
2857 # OGR classes.
2858 #*
2859 package Geo::OGR;
2860 
2861 use base qw()
2862 
2863 #** @method list ByteOrders()
2864 # Class method.
2865 # @return a list of byte order types, XDR and NDR. XDR denotes
2866 # big-endian and NDR denotes little-endian.
2867 #*
2868 sub ByteOrders {
2869 }
2870 
2871 #** @method scalar GeometryTypeModify($type, $modifier)
2872 # @param type a geometry type (one of Geo::OGR::GeometryTypes).
2873 # @param modifier one of 'flatten', 'set_Z', 'make_collection', 'make_curve', or 'make_linear'.
2874 # @return modified geometry type.
2875 #*
2876 sub GeometryTypeModify {
2877  my($type, $modifier) = @_;
2878  confess "Unknown geometry type: '$type'." unless exists $Geo::OGR::Geometry::TYPE_STRING2INT{$type};
2879  $type = $Geo::OGR::Geometry::TYPE_STRING2INT{$type};
2880  return $Geo::OGR::Geometry::TYPE_INT2STRING{GT_Flatten($type)} if $modifier =~ /flat/i;
2881  return $Geo::OGR::Geometry::TYPE_INT2STRING{GT_SetZ($type)} if $modifier =~ /z/i;
2882  return $Geo::OGR::Geometry::TYPE_INT2STRING{GT_GetCollection($type)} if $modifier =~ /collection/i;
2883  return $Geo::OGR::Geometry::TYPE_INT2STRING{GT_GetCurve($type)} if $modifier =~ /curve/i;
2884  return $Geo::OGR::Geometry::TYPE_INT2STRING{GT_GetLinear($type)} if $modifier =~ /linear/i;
2885  confess "Unknown geometry type modifier: '$modifier'.";
2886 }
2887 
2888 #** @method scalar GeometryTypeTest($type, $test, $type2)
2889 # @param type a geometry type (one of Geo::OGR::GeometryTypes).
2890 # @param test one of 'has_z', 'is_subclass_of', 'is_curve', 'is_surface', or 'is_non_linear'.
2891 # @param type2 a geometry type (one of Geo::OGR::GeometryTypes). Required for 'is_subclass_of' test.
2892 # @return result of the test.
2893 #*
2894 sub GeometryTypeTest {
2895  my($type, $test, $type2) = @_;
2896  confess "Unknown geometry type: '$type'." unless exists $Geo::OGR::Geometry::TYPE_STRING2INT{$type};
2897  $type = $Geo::OGR::Geometry::TYPE_STRING2INT{$type};
2898  if (defined $type2) {
2899  confess "Unknown geometry type: '$type2'." unless exists $Geo::OGR::Geometry::TYPE_STRING2INT{$type2};
2900  $type2 = $Geo::OGR::Geometry::TYPE_STRING2INT{$type2};
2901  } else {
2902  confess "Usage: GeometryTypeTest(type1, 'is_subclass_of', type2)." if $test =~ /subclass/i;
2903  }
2904  return GT_HasZ($type) if $test =~ /z/i;
2905  return GT_IsSubClassOf($type, $type2) if $test =~ /subclass/i;
2906  return GT_IsCurve($type) if $test =~ /curve/i;
2907  return GT_IsSurface($type) if $test =~ /surface/i;
2908  return GT_IsNonLinear($type) if $test =~ /linear/i;
2909  confess "Unknown geometry type test: '$test'.";
2910 }
2911 
2912 #** @method list GeometryTypes()
2913 # Class method.
2914 # @return a list of all geometry types, currently:
2915 # CircularString, CircularStringZ, CompoundCurve, CompoundCurveZ, CurvePolygon, CurvePolygonZ, GeometryCollection, GeometryCollection25D, LineString, LineString25D, LinearRing, MultiCurve, MultiCurveZ, MultiLineString, MultiLineString25D, MultiPoint, MultiPoint25D, MultiPolygon, MultiPolygon25D, MultiSurface, MultiSurfaceZ, None, Point, Point25D, Polygon, Polygon25D, and Unknown.
2916 #*
2917 sub GeometryTypes {
2918 }
2919 
2920 #** @method Geo::OGR::Driver GetDriver($name)
2921 # @param name a driver name. One of Geo::OGR::GetDriverNames.
2922 # @return a Geo::OGR::Driver object that represents the internal driver.
2923 #*
2924 sub GetDriver {
2925  my($name) = @_;
2926  $name = 0 unless defined $name;
2927  my $driver;
2928  $driver = _GetDriver($name) if $name =~ /^\d+$/; # is the name an index to driver list?
2929  $driver = GetDriverByName("$name") unless $driver;
2930  return $driver if $driver;
2931  confess "Driver not found: '$name'. Maybe support for it was not built in?";
2932 }
2933 
2934 #** @method list GetDriverNames()
2935 # @return a list of the names of available Geo::OGR::Drivers.
2936 #*
2937 sub GetDriverNames {
2938  my @names;
2939  for my $i (0..GetDriverCount()-1) {
2940  push @names, _GetDriver($i)->Name;
2941  }
2942  return @names;
2943 }
2944 
2945 #** @method GetNonLinearGeometriesEnabledFlag()
2946 #*
2947 sub GetNonLinearGeometriesEnabledFlag {
2948 }
2949 
2950 #** @method Geo::OGR::DataSource GetOpenDS($number)
2951 # @param number The number of the requested data source.
2952 # @return a new Geo::OGR::DataSource object.
2953 #*
2954 sub GetOpenDS {
2955 }
2956 
2957 #** @method scalar GetOpenDSCount()
2958 # @return the number of all open data sources.
2959 #*
2960 sub GetOpenDSCount {
2961 }
2962 
2963 #** @method OLMD_FID64()
2964 #*
2965 sub OLMD_FID64 {
2966 }
2967 
2968 #** @method Geo::OGR::DataSource Open($name, $update = 0)
2969 # @param name The data source string (directory, filename, etc.).
2970 # @param update Whether to open the data source in update mode.
2971 # @return a new Geo::OGR::DataSource object.
2972 #*
2973 sub Open {
2974 }
2975 
2976 #** @method Geo::OGR::DataSource OpenShared($name, $update = 0)
2977 # @param name The data source string (directory, filename, etc.).
2978 # @param update Whether to open the data source in update mode.
2979 # @return a new Geo::OGR::DataSource object.
2980 #*
2981 sub OpenShared {
2982 }
2983 
2984 #** @method SetGenerate_DB2_V72_BYTE_ORDER($Generate_DB2_V72_BYTE_ORDER)
2985 # Needed only on IBM DB2.
2986 #*
2987 sub SetGenerate_DB2_V72_BYTE_ORDER {
2988 }
2989 
2990 #** @method SetNonLinearGeometriesEnabledFlag()
2991 #*
2992 sub SetNonLinearGeometriesEnabledFlag {
2993 }
2994 
2995 #** @class Geo::OGR::DataSource
2996 # @brief A source and/or storage of vector data layers.
2997 #
2998 # A data source object may, depending on its capabilities, create,
2999 # open (as such or using GDAL SQL), copy, and delete layers.
3000 #*
3001 package Geo::OGR::DataSource;
3002 
3003 use base qw(Geo::GDAL::MajorObject Geo::OGR)
3004 
3005 #** @method list Capabilities()
3006 # Both a class and an object method.
3007 # @return a list of capabilities. The object method returns a list of
3008 # all capabilities the data source has. The class method returns a
3009 # list of all potential capabilities a data source may have. These are
3010 # currently:
3011 # CreateGeomFieldAfterCreateLayer, CreateLayer, CurveGeometries, DeleteLayer, EmulatedTransactions, and Transactions.
3012 #*
3013 sub Capabilities {
3014  return @CAPABILITIES if @_ == 0;
3015  my $self = shift;
3016  my @cap;
3017  for my $cap (@CAPABILITIES) {
3018  push @cap, $cap if _TestCapability($self, $CAPABILITIES{$cap});
3019  }
3020  return @cap;
3021 }
3022 
3023 #** @method CommitTransaction()
3024 #*
3025 sub CommitTransaction {
3026 }
3027 
3028 #** @method Geo::OGR::Layer CopyLayer($layer, $name, hashref options = undef)
3029 # @param layer A Geo::OGR::Layer object to be copied.
3030 # @param name A name for the new layer.
3031 # @param options A ref to a hash of format specific options.
3032 # @return a new Geo::OGR::Layer object.
3033 #*
3034 sub CopyLayer {
3035 }
3036 
3037 #** @method Geo::OGR::Layer CreateLayer(%params)
3038 # @brief Create a new layer into this data source.
3039 #
3040 # @param %params A list of named parameters:
3041 # - \a Name (scalar) name for the new layer.
3042 # - \a Fields (array reference) a list of field definitions as in
3043 # Geo::OGR::Layer::CreateField.
3044 # - \a ApproxOK (boolean value, default is true) a flag, which is forwarded to Geo::OGR::Layer::CreateField.
3045 # - \a Options (hash reference) driver specific hash of layer creation options.
3046 # - \a Schema (hash reference, deprecated) may contain keys Name, Fields, GeomFields, GeometryType.
3047 # - \a SRS (scalar, deprecated) the spatial reference for the default geometry field.
3048 # - \a GeometryType (scalar) the type of the default geometry field (if only one geometry field).
3049 #
3050 # @note If Fields or Schema|Fields is not given, a default geometry
3051 # field (Name => '', GeometryType => 'Unknown') is created. The type
3052 # can be also set with the named parameter.
3053 #
3054 # Example:
3055 # \code
3056 # my $roads = Geo::OGR::Driver('Memory')->Create('road')->
3057 # . CreateLayer(
3058 # . Fields => [ { Name => 'class',
3059 # . Type => 'Integer' },
3060 # . { Name => 'geom',
3061 # . Type => 'LineString25D' } ] );
3062 # \endcode
3063 # @return a new Geo::OGR::Layer object.
3064 #*
3065 sub CreateLayer {
3066  my $self = shift;
3067  my %defaults = ( Name => 'unnamed',
3068  SRS => undef,
3069  Options => {},
3070  GeometryType => 'Unknown',
3071  Schema => undef,
3072  Fields => undef,
3073  ApproxOK => 1);
3074  my %params;
3075  if (@_ == 0) {
3076  } elsif (ref($_[0]) eq 'HASH') {
3077  %params = %{$_[0]};
3078  } elsif (@_ % 2 == 0 and (defined $_[0] and exists $defaults{$_[0]})) {
3079  %params = @_;
3080  } else {
3081  ($params{Name}, $params{SRS}, $params{GeometryType}, $params{Options}, $params{Schema}) = @_;
3082  }
3083  for (keys %params) {
3084  carp "CreateLayer: unknown named parameter '$_'." unless exists $defaults{$_};
3085  }
3086  if (exists $params{Schema}) {
3087  my $s = $params{Schema};
3088  $params{GeometryType} = $s->{GeometryType} if exists $s->{GeometryType};
3089  $params{Fields} = $s->{Fields} if exists $s->{Fields};
3090  $params{Name} = $s->{Name} if exists $s->{Name};
3091  }
3092  $defaults{GeometryType} = 'None' if $params{Fields};
3093  for (keys %defaults) {
3094  $params{$_} = $defaults{$_} unless defined $params{$_};
3095  }
3096  confess "Unknown geometry type: '$params{GeometryType}'."
3097  unless exists $Geo::OGR::Geometry::TYPE_STRING2INT{$params{GeometryType}};
3098  my $gt = $Geo::OGR::Geometry::TYPE_STRING2INT{$params{GeometryType}};
3099  my $layer = _CreateLayer($self, $params{Name}, $params{SRS}, $gt, $params{Options});
3100  $LAYERS{tied(%$layer)} = $self;
3101  my $f = $params{Fields};
3102  if ($f) {
3103  confess "Named parameter 'Fields' must be a reference to an array." unless ref($f) eq 'ARRAY';
3104  for my $field (@$f) {
3105  $layer->CreateField($field);
3106  }
3107  }
3108  return $layer;
3109 }
3110 
3111 #** @method DeleteLayer($name)
3112 # Deletes a layer from the data source. Note that if there is a layer
3113 # object for the deleted layer, it becomes unusable.
3114 # @param name name of the layer to delete.
3115 #*
3116 sub DeleteLayer {
3117  my ($self, $name) = @_;
3118  my $index;
3119  for my $i (0..$self->GetLayerCount-1) {
3120  my $layer = GetLayerByIndex($self, $i);
3121  $index = $i, last if $layer->GetName eq $name;
3122  }
3123  confess "No such layer: '$name'." unless defined $index;
3124  _DeleteLayer($self, $index);
3125 }
3126 
3127 #** @method Geo::OGR::Layer ExecuteSQL($statement, $geom = undef, $dialect = "")
3128 # @param statement A SQL statement.
3129 # @param geom A Geo::OGR::Geometry object.
3130 # @param dialect
3131 # @return a new Geo::OGR::Layer object. The data source object will
3132 # exist as long as the layer object exists.
3133 #*
3134 sub ExecuteSQL {
3135  my $self = shift;
3136  my $layer = $self->_ExecuteSQL(@_);
3137  $LAYERS{tied(%$layer)} = $self;
3138  $RESULT_SET{tied(%$layer)} = 1;
3139  return $layer;
3140 }
3141 
3142 #** @method FlushCache()
3143 #*
3144 sub FlushCache {
3145 }
3146 
3147 #** @method Geo::OGR::Driver GetDriver()
3148 # @return a Geo::OGR::Driver object for this data source.
3149 #*
3150 sub GetDriver {
3151 }
3152 
3153 #** @method Geo::OGR::Layer GetLayer($name)
3154 # @param name the name of the requested layer. If not given, then
3155 # returns the first layer in the data source.
3156 # @return a new Geo::OGR::Layer object that represents the layer
3157 # in the data source.
3158 #*
3159 sub GetLayer {
3160  my($self, $name) = @_;
3161  my $layer = defined $name ? GetLayerByName($self, "$name") : GetLayerByIndex($self, 0);
3162  $name = '' unless defined $name;
3163  confess "No such layer: '$name'." unless $layer;
3164  $LAYERS{tied(%$layer)} = $self;
3165  return $layer;
3166 }
3167 
3168 #** @method list GetLayerNames()
3169 # @note Delivers the functionality of undocumented method GetLayerCount.
3170 # @return a list of the names of the layers this data source provides.
3171 #*
3172 sub GetLayerNames {
3173  my $self = shift;
3174  my @names;
3175  for my $i (0..$self->GetLayerCount-1) {
3176  my $layer = GetLayerByIndex($self, $i);
3177  push @names, $layer->GetName;
3178  }
3179  return @names;
3180 }
3181 
3182 #** @method scalar GetName()
3183 # @return the name of this data source.
3184 #*
3185 sub GetName {
3186 }
3187 
3188 #** @method GetStyleTable()
3189 #*
3190 sub GetStyleTable {
3191 }
3192 
3193 #** @method Geo::OGR::DataSource Open($name, $update = 0)
3194 # Class method.
3195 # An example:
3196 # \code
3197 # use Geo::GDAL;
3198 # $ds = Geo::OGR::DataSource::Open('/data/roads.shp');
3199 # \endcode
3200 # @param name The data source name (directory, filename, etc.).
3201 # @param update Whether to open the data source in update mode.
3202 # @return a new Geo::OGR::DataSource object.
3203 #*
3204 sub Open {
3205  return Geo::OGR::Open(@_);
3206 }
3207 
3208 #** @method Geo::OGR::DataSource OpenShared($name, $update = 0)
3209 # Class method.
3210 # @param name The data source name (directory, filename, etc.).
3211 # @param update Whether to open the data source in update mode.
3212 # @return a new Geo::OGR::DataSource object.
3213 #*
3214 sub OpenShared {
3215  return Geo::OGR::OpenShared(@_);
3216 }
3217 
3218 #** @method ReleaseResultSet($layer)
3219 # @param layer A layer the has been created with ExecuteSQL.
3220 # @note There is no need to call this method. The result set layer is
3221 # released in the destructor of the layer that was created with SQL.
3222 #*
3223 sub ReleaseResultSet {
3224  # a no-op, _ReleaseResultSet is called from Layer::DESTROY
3225 }
3226 
3227 #** @method RollbackTransaction()
3228 #*
3229 sub RollbackTransaction {
3230 }
3231 
3232 #** @method SetStyleTable()
3233 #*
3234 sub SetStyleTable {
3235 }
3236 
3237 #** @method StartTransaction()
3238 #*
3239 sub StartTransaction {
3240 }
3241 
3242 #** @method scalar TestCapability($cap)
3243 # @param cap A capability string.
3244 # @return a boolean value indicating whether the data source has the
3245 # specified capability.
3246 #*
3247 sub TestCapability {
3248  my($self, $cap) = @_;
3249  confess "No such capability defined for class DataSource: '$cap'." unless defined $CAPABILITIES{$cap};
3250  return _TestCapability($self, $CAPABILITIES{$cap});
3251 }
3252 
3253 #** @method new()
3254 #*
3255 sub new {
3256  my $pkg = shift;
3257  return Geo::OGR::Open(@_);
3258 }
3259 
3260 #** @class Geo::OGR::Driver
3261 # @brief A vector format driver.
3262 #
3263 # A driver may, depending on its capabilities, create, open, copy, and
3264 # delete data sources.
3265 #*
3266 package Geo::OGR::Driver;
3267 
3268 use base qw(Geo::GDAL::MajorObject Geo::OGR)
3269 
3270 #** @method list Capabilities()
3271 # Both a class and an object method.
3272 # @return a list of capabilities. The object method returns a list of
3273 # the capabilities the driver has. The class method returns a list of
3274 # all potential capabilities a driver may have. These are currently:
3275 # CreateDataSource, and DeleteDataSource.
3276 #
3277 # Examples:
3278 # \code
3279 # @all_capabilities = Geo::OGR::Driver::Capabilities;
3280 # @capabilities_of_a_driver = Geo::OGR::Driver('KML')->Capabilities;
3281 # \endcode
3282 #*
3283 sub Capabilities {
3284  return @CAPABILITIES if @_ == 0;
3285  my $self = shift;
3286  my @cap;
3287  for my $cap (@CAPABILITIES) {
3288  push @cap, $cap if _TestCapability($self, $CAPABILITIES{$cap});
3289  }
3290  return @cap;
3291 }
3292 
3293 #** @method Geo::OGR::DataSource Copy(Geo::OGR::DataSource source, $name, arrayref options = undef)
3294 # Copy an OGR data source object.
3295 # @note a.k.a. CopyDataSource
3296 # @param source the Geo::OGR::DataSource object to be copied.
3297 # @param name the name for the new data source.
3298 # @param options driver specific options.
3299 # @return a new Geo::OGR::DataSource object.
3300 #*
3301 sub Copy {
3302 }
3303 
3304 #** @method Geo::OGR::DataSource Create($name, hashref options = undef )
3305 # Create an OGR data source object.
3306 # @note a.k.a. CreateDataSource
3307 # @param name The data source name.
3308 # @param options Driver specific options.
3309 #
3310 # Usage:
3311 # \code
3312 # $ds = Geo::OGR::Driver('driver name')->Create('data source name', {});
3313 # \endcode
3314 # @return a new Geo::OGR::DataSource object.
3315 #*
3316 sub Create {
3317 }
3318 
3319 #** @method Delete($name)
3320 # Delete an OGR data source.
3321 # @note a.k.a. DeleteDataSource
3322 # @param name The name of data source.
3323 #*
3324 sub Delete {
3325 }
3326 
3327 #** @method scalar Name()
3328 # @note a.k.a. GetName
3329 # @return the name of the driver.
3330 #*
3331 sub Name {
3332 }
3333 
3334 #** @method Geo::OGR::DataSource Open($name, $update = 0)
3335 # Open an OGR data source object. Alternative name: OpenDataSource.
3336 # @note a.k.a. GetDataSource
3337 # @param name the name of data source.
3338 # @param update whether to open the data source in update mode.
3339 # @return a new Geo::OGR::DataSource object
3340 #*
3341 sub Open {
3342 }
3343 
3344 #** @method scalar TestCapability($cap)
3345 # @param cap A capability string.
3346 # @return boolean value.
3347 #*
3348 sub TestCapability {
3349  my($self, $cap) = @_;
3350  confess "No such capability defined for class Driver: '$cap'." unless defined $CAPABILITIES{$cap};
3351  return _TestCapability($self, $CAPABILITIES{$cap});
3352 }
3353 
3354 #** @class Geo::OGR::Feature
3355 # @brief A collection of non-spatial and spatial attributes.
3356 #
3357 # A feature is a collection of non-spatial and spatial attributes and
3358 # an id, which is a special attribute, and data records according to
3359 # this data model. Attributes are called fields and some fields are
3360 # spatial, i.e., their value is a geometry. Fields have at least a
3361 # name and a type. Features may exist within a layer or
3362 # separetely. The data model of a feature is a definition object.
3363 #*
3364 package Geo::OGR::Feature;
3365 
3366 use base qw(Geo::OGR)
3367 
3368 #** @method Geo::OGR::Feature Clone()
3369 # @return a new Geo::OGR::Feature object
3370 #*
3371 sub Clone {
3372 }
3373 
3374 #** @method DumpReadable()
3375 # Write the contents of this feature to stdout.
3376 #*
3377 sub DumpReadable {
3378 }
3379 
3380 #** @method scalar Equal($feature)
3381 # @param feature a Geo::OGR::Feature object for comparison
3382 # @return boolean
3383 #*
3384 sub Equal {
3385 }
3386 
3387 #** @method scalar FID($id)
3388 # @brief Get or set the id of this feature.
3389 # @param id [optional] the id to set for this feature.
3390 # @return integer the id of this feature.
3391 #*
3392 sub FID {
3393  my $self = shift;
3394  $self->SetFID($_[0]) if @_;
3395  return unless defined wantarray;
3396  $self->GetFID;
3397 }
3398 
3399 #** @method Field($name, @Value)
3400 # @brief Get or set the field.
3401 # @param name the name of the field.
3402 # @param Value a scalar or list depending on the field type.
3403 # @return the value of the field, which may be a scalar or a list,
3404 # depending on the field type.
3405 #*
3406 sub Field {
3407  my $self = shift;
3408  my $field = shift;
3409  $self->SetField($field, @_) if @_;
3410  $self->GetField($field);
3411 }
3412 
3413 #** @method FillUnsetWithDefault()
3414 #*
3415 sub FillUnsetWithDefault {
3416 }
3417 
3418 #** @method scalar Geometry($name, $geometry)
3419 # @brief Get or set the value of a geometry field.
3420 # @note This method delivers the functionality of undocumented methods
3421 # SetGeometry($geometry), SetGeometryDirectly, SetGeomField,
3422 # SetGeomFieldDirectly, GetGeometry, GetGeometryRef.
3423 #
3424 # Set or get the geometry in the feature. When setting, does a check
3425 # against the schema (GeometryType) of the feature. The ownership of
3426 # the geometry is given (if the parameter is an object) or kept to the
3427 # feature and thus the geometry will keep the feature alive as long as
3428 # the geometry is alive.
3429 # @param name [optional] the name of the spatial field,
3430 # whose geometry is to be set. If not given, sets or gets the geometry
3431 # of the first spatial field.
3432 # @param geometry [optional] a Geo::OGR::Geometry object or a hash
3433 # array from which such can be created (using
3434 # Geo::OGR::Geometry::new)
3435 # @return in a non-void context the geometry in the feature
3436 # as a Geo::OGR::Geometry object.
3437 #*
3438 sub Geometry {
3439  my $self = shift;
3440  my $field = (ref($_[0]) eq '' or (@_ > 2 and @_ % 2 == 1)) ? shift : undef;
3441  $field = $self->_GetGeomFieldIndex($field);
3442  if (@_) {
3443  my $type = $self->GetDefn->GetGeomFieldDefn($field)->Type;
3444  my $geometry;
3445  if (@_ == 1) {
3446  $geometry = $_[0];
3447  } elsif (@_ and @_ % 2 == 0) {
3448  %$geometry = @_;
3449  }
3450  if (blessed($geometry) and $geometry->isa('Geo::OGR::Geometry')) {
3451  confess "The type of the inserted geometry ('".$geometry->GeometryType."') is not the field type ('$type')."
3452  if $type ne 'Unknown' and $type ne $geometry->GeometryType;
3453  eval {
3454  $self->SetGeomFieldDirectly($field, $geometry);
3455  };
3456  confess "$@" if $@;
3457  $GEOMETRIES{tied(%{$geometry})} = $self;
3458  } elsif (ref($geometry) eq 'HASH') {
3459  $geometry->{GeometryType} = $type unless exists $geometry->{GeometryType};
3460  eval {
3461  $geometry = Geo::OGR::Geometry->new($geometry);
3462  };
3463  confess "The type of the inserted geometry ('".$geometry->GeometryType."') is not the field type ('$type')."
3464  if $type ne 'Unknown' and $type ne $geometry->GeometryType;
3465  eval {
3466  $self->SetGeomFieldDirectly($field, $geometry);
3467  };
3468  confess "$@" if $@;
3469  } else {
3470  confess "'@_' does not define a geometry.";
3471  }
3472  }
3473  return unless defined wantarray;
3474  my $geometry = $self->GetGeomFieldRef($field);
3475  return unless $geometry;
3476  $GEOMETRIES{tied(%{$geometry})} = $self;
3477  return $geometry;
3478 }
3479 
3480 #** @method Geo::OGR::FeatureDefn GetDefn()
3481 # @note A.k.a GetDefnRef.
3482 # @return a Geo::OGR::FeatureDefn object, which represents the definition of this feature.
3483 #*
3484 sub GetDefn {
3485  my $self = shift;
3486  my $defn = $self->GetDefnRef;
3487  $DEFNS{$defn} = $self;
3488  return $defn;
3489 }
3490 
3491 #** @method scalar GetFID()
3492 # @return the feature id (an integer).
3493 #*
3494 sub GetFID {
3495 }
3496 
3497 #** @method list GetField($name)
3498 # @note A number of GetFieldAs* methods exist but they are not
3499 # documented. Syntax $feature->{field} can be used to access the
3500 # field (v1.9.0)
3501 # @param name the name of the field
3502 # @return the value of the field, which may be a scalar or a list,
3503 # depending on the field type.
3504 #*
3505 sub GetField {
3506  my($self, $field) = @_;
3507  $field = $self->_GetFieldIndex($field);
3508  return unless IsFieldSet($self, $field);
3509  my $type = GetFieldType($self, $field);
3510  if ($type == $Geo::OGR::OFTInteger) {
3511  return GetFieldAsInteger($self, $field);
3512  }
3513  if ($type == $Geo::OGR::OFTInteger64) {
3514  return GetFieldAsInteger64($self, $field);
3515  }
3516  if ($type == $Geo::OGR::OFTReal) {
3517  return GetFieldAsDouble($self, $field);
3518  }
3519  if ($type == $Geo::OGR::OFTString) {
3520  return GetFieldAsString($self, $field);
3521  }
3522  if ($type == $Geo::OGR::OFTIntegerList) {
3523  my $ret = GetFieldAsIntegerList($self, $field);
3524  return wantarray ? @$ret : $ret;
3525  }
3526  if ($type == $Geo::OGR::OFTInteger64List) {
3527  my $ret = GetFieldAsInteger64List($self, $field);
3528  return wantarray ? @$ret : $ret;
3529  }
3530  if ($type == $Geo::OGR::OFTRealList) {
3531  my $ret = GetFieldAsDoubleList($self, $field);
3532  return wantarray ? @$ret : $ret;
3533  }
3534  if ($type == $Geo::OGR::OFTStringList) {
3535  my $ret = GetFieldAsStringList($self, $field);
3536  return wantarray ? @$ret : $ret;
3537  }
3538  if ($type == $Geo::OGR::OFTBinary) {
3539  return GetFieldAsString($self, $field);
3540  }
3541  if ($type == $Geo::OGR::OFTDate) {
3542  my @ret = GetFieldAsDateTime($self, $field);
3543  # year, month, day, hour, minute, second, timezone
3544  return wantarray ? @ret[0..2] : [@ret[0..2]];
3545  }
3546  if ($type == $Geo::OGR::OFTTime) {
3547  my @ret = GetFieldAsDateTime($self, $field);
3548  return wantarray ? @ret[3..6] : [@ret[3..6]];
3549  }
3550  if ($type == $Geo::OGR::OFTDateTime) {
3551  return GetFieldAsDateTime($self, $field);
3552  }
3553  confess "Perl bindings do not support field type '$Geo::OGR::FieldDefn::TYPE_INT2STRING{$type}'.";
3554 }
3555 
3556 #** @method GetFieldAsBinary()
3557 #*
3558 sub GetFieldAsBinary {
3559 }
3560 
3561 #** @method GetFieldAsInteger64()
3562 #*
3563 sub GetFieldAsInteger64 {
3564 }
3565 
3566 #** @method Geo::OGR::FieldDefn GetFieldDefn($name)
3567 # @note A.k.a GetFieldDefnRef
3568 # @param name the name of the field.
3569 # @return a new Geo::OGR::FieldDefn object that represents the field
3570 # in question.
3571 #*
3572 sub GetFieldDefn {
3573 }
3574 
3575 #** @method list GetFieldNames()
3576 # Get the names of the fields in this feature.
3577 #*
3578 sub GetFieldNames {
3579 }
3580 
3581 #** @method hash reference GetSchema()
3582 # @brief Get the schema of this feature.
3583 # @return the schema of this layer, as in Geo::OGR::FeatureDefn::Schema.
3584 #*
3585 sub GetSchema {
3586  my $self = shift;
3587  confess "Schema of a feature cannot be set directly." if @_;
3588  return $self->GetDefnRef->Schema;
3589 }
3590 
3591 #** @method scalar GetStyleString()
3592 # @return a string
3593 #*
3594 sub GetStyleString {
3595 }
3596 
3597 #** @method scalar IsFieldSet($field)
3598 # @param field the name (or index) of the field
3599 # @return boolean
3600 #*
3601 sub IsFieldSet {
3602 }
3603 
3604 #** @method hash reference Row(%row)
3605 # @note This method discards the data the destination feature (or
3606 # layer) does not support. Changes in data due to differences between
3607 # field types may also occur.
3608 #
3609 # Get and/or set the data of the feature. The key of the (key,value)
3610 # pairs of the row is the field name. Special field names FID and
3611 # Geometry are used for feature id and geometry respectively. The
3612 # geometry is set and get using the Geo::OGR::Feature::Geometry
3613 # method. Field values are set using the Geo::OGR::Feature::SetField
3614 # method.
3615 # @param row [optional] feature data in a hash.
3616 # @return a reference to feature data in a hash. Spatial fields are
3617 # returned as Geo::OGR::Geometry objects.
3618 #*
3619 sub Row {
3620  my $self = shift;
3621  my $nf = $self->GetFieldCount;
3622  my $ngf = $self->GetGeomFieldCount;
3623  if (@_) { # update
3624  my %row;
3625  if (@_ == 1 and ref($_[0]) eq 'HASH') {
3626  %row = %{$_[0]};
3627  } elsif (@_ and @_ % 2 == 0) {
3628  %row = @_;
3629  } else {
3630  confess 'Usage: $feature->Row(%FeatureData).';
3631  }
3632  $self->SetFID($row{FID}) if defined $row{FID};
3633  #$self->Geometry($schema, $row{Geometry}) if $row{Geometry};
3634  for my $name (keys %row) {
3635  next if $name eq 'FID';
3636  if ($name eq 'Geometry') {
3637  $self->SetGeometry(0, $row{$name});
3638  next;
3639  }
3640  my $f = 0;
3641  for my $i (0..$nf-1) {
3642  if ($self->GetFieldDefnRef($i)->Name eq $name) {
3643  $self->SetField($i, $row{$name});
3644  $f = 1;
3645  last;
3646  }
3647  }
3648  next if $f;
3649  for my $i (0..$ngf-1) {
3650  if ($self->GetGeomFieldDefnRef($i)->Name eq $name) {
3651  $self->SetGeometry($i, $row{$name});
3652  $f = 1;
3653  last;
3654  }
3655  }
3656  next if $f;
3657  carp "Feature->Row: Unknown field: '$name'.";
3658  }
3659  }
3660  return unless defined wantarray;
3661  my %row = ();
3662  for my $i (0..$nf-1) {
3663  my $name = $self->GetFieldDefnRef($i)->Name;
3664  $row{$name} = $self->GetField($i);
3665  }
3666  for my $i (0..$ngf-1) {
3667  my $name = $self->GetGeomFieldDefnRef($i)->Name;
3668  $name = 'Geometry' if $name eq '';
3669  $row{$name} = $self->GetGeometry($i);
3670  }
3671  $row{FID} = $self->GetFID;
3672  #$row{Geometry} = $self->Geometry;
3673  return \%row;
3674 }
3675 
3676 #** @method SetFID($id)
3677 # @param id the feature id.
3678 #*
3679 sub SetFID {
3680 }
3681 
3682 #** @method SetField($name, @Value)
3683 # @note Syntax $feature->{field} can be used to access the
3684 # field (v1.9.0)
3685 # @param name the name of the field.
3686 # @param Value a string, integer, double, a list (year, month,
3687 # day), a list (hour, minute, second, tzflag), a list (year, month,
3688 # day, hour, minute, second, tzflag), or a list of integers, doubles,
3689 # or strings.
3690 # @note If value is not given or is undefined this method unsets the field.
3691 #*
3692 sub SetField {
3693  my $self = shift;
3694  my $field = shift;
3695  $field = $self->_GetFieldIndex($field);
3696  if (@_ == 0 or !defined($_[0])) {
3697  _UnsetField($self, $field);
3698  return;
3699  }
3700  my $list = ref($_[0]) ? $_[0] : [@_];
3701  my $type = GetFieldType($self, $field);
3702  if ($type == $Geo::OGR::OFTInteger or
3703  $type == $Geo::OGR::OFTInteger64 or
3704  $type == $Geo::OGR::OFTReal or
3705  $type == $Geo::OGR::OFTString or
3706  $type == $Geo::OGR::OFTBinary)
3707  {
3708  _SetField($self, $field, $_[0]);
3709  }
3710  elsif ($type == $Geo::OGR::OFTIntegerList) {
3711  SetFieldIntegerList($self, $field, $list);
3712  }
3713  elsif ($type == $Geo::OGR::OFTInteger64List) {
3714  SetFieldInteger64List($self, $field, $list);
3715  }
3716  elsif ($type == $Geo::OGR::OFTRealList) {
3717  SetFieldDoubleList($self, $field, $list);
3718  }
3719  elsif ($type == $Geo::OGR::OFTStringList) {
3720  SetFieldStringList($self, $field, $list);
3721  }
3722  elsif ($type == $Geo::OGR::OFTDate) {
3723  # year, month, day, hour, minute, second, timezone
3724  for my $i (0..6) {
3725  $list->[$i] = 0 unless defined $list->[$i];
3726  }
3727  _SetField($self, $field, @$list[0..6]);
3728  }
3729  elsif ($type == $Geo::OGR::OFTTime) {
3730  $list->[3] = 0 unless defined $list->[3];
3731  _SetField($self, $field, 0, 0, 0, @$list[0..3]);
3732  }
3733  elsif ($type == $Geo::OGR::OFTDateTime) {
3734  $list->[6] = 0 unless defined $list->[6];
3735  _SetField($self, $field, @$list[0..6]);
3736  }
3737  else {
3738  confess "Perl bindings do not support field type '$Geo::OGR::FieldDefn::TYPE_INT2STRING{$type}'.";
3739  }
3740 }
3741 
3742 #** @method SetFieldBinaryFromHexString()
3743 #*
3744 sub SetFieldBinaryFromHexString {
3745 }
3746 
3747 #** @method SetFieldInteger64()
3748 #*
3749 sub SetFieldInteger64 {
3750 }
3751 
3752 #** @method SetFrom($other, $forgiving = 1, hashref map)
3753 # @param other a Geo::OGR::Feature object
3754 # @param forgiving [optional] set to false if the operation should not
3755 # continue if output fields do not match some of the source fields
3756 # @param map [optional] a mapping from output field indexes to source
3757 # fields, include into the hash all field indexes of this feature
3758 # which should be set
3759 #*
3760 sub SetFrom {
3761  my($self, $other) = @_;
3762  _SetFrom($self, $other), return if @_ <= 2;
3763  my $forgiving = $_[2];
3764  _SetFrom($self, $other, $forgiving), return if @_ <= 3;
3765  my $map = $_[3];
3766  my @list;
3767  for my $i (1..GetFieldCount($self)) {
3768  push @list, ($map->{$i} || -1);
3769  }
3770  SetFromWithMap($self, $other, 1, \@list);
3771 }
3772 
3773 #** @method SetStyleString($string)
3774 # @param string
3775 #*
3776 sub SetStyleString {
3777 }
3778 
3779 #** @method list Tuple(@tuple)
3780 # @note This method discards the data the destination feature (or
3781 # layer) does not support. Changes in data due to differences between
3782 # field types may also occur.
3783 #
3784 # @note The schema of the tuple needs to be the same as that of the
3785 # feature.
3786 #
3787 # Get and/set the data of the feature. The expected data in the tuple
3788 # is ([feature_id,] non-spatial fields, spatial fields). The fields in
3789 # the order they are in the schema. Field values are set using the
3790 # Geo::OGR::Feature::Field method. Geometries are set and get using
3791 # the Geo::OGR::Feature::Geometry method.
3792 # @param tuple [optional] feature data in an array
3793 # @return feature data in an array
3794 #*
3795 sub Tuple {
3796  my $self = shift;
3797  my $nf = $self->GetFieldCount;
3798  my $ngf = $self->GetGeomFieldCount;
3799  if (@_) {
3800  my $FID;
3801  $FID = shift if @_ == $nf + $ngf + 1;
3802  $self->SetFID($FID) if defined $FID;
3803  my $values = \@_;
3804  if (@$values != $nf + $ngf) {
3805  my $n = $nf + $ngf;
3806  confess "Too many or too few attribute values for a feature (need $n).";
3807  }
3808  my $index = 0; # index to non-geometry and geometry fields
3809  for my $i (0..$nf-1) {
3810  $self->SetField($i, $values->[$i]);
3811  }
3812  for my $i (0..$ngf-1) {
3813  $self->SetGeometry($i, $values->[$nf+$i]);
3814  }
3815  }
3816  return unless defined wantarray;
3817  my @ret = ($self->GetFID);
3818  for my $i (0..$nf-1) {
3819  my $v = $self->GetField($i);
3820  push @ret, $v;
3821  }
3822  for my $i (0..$ngf-1) {
3823  my $v = $self->GetGeometry($i);
3824  push @ret, $v;
3825  }
3826  return @ret;
3827 }
3828 
3829 #** @method UnsetField($field)
3830 # @note Field value can be unset by calling SetField without
3831 # parameters or with an undefined argument.
3832 # @param field the name (or index) of the field
3833 #*
3834 sub UnsetField {
3835  my($self, $field) = @_;
3836  $field = $self->_GetFieldIndex($field);
3837  _UnsetField($self, $field);
3838 }
3839 
3840 #** @method scalar Validate(list flags)
3841 # @param flags one of more of null, geom_type, width,
3842 # allow_null_when_default, or all.
3843 # @exception croaks with an error message if the feature is not valid.
3844 # @return integer denoting the validity of the feature object.
3845 #*
3846 sub Validate {
3847  my $self = shift;
3848  my $flags = 0;
3849  for my $flag (@_) {
3850  my $f = eval '$Geo::OGR::'.uc($flag);
3851  $flags |= $f;
3852  }
3853  _Validate($self, $flags);
3854 }
3855 
3856 #** @method Geo::OGR::Feature new(%schema)
3857 # Class method.
3858 # @param schema as in Schema
3859 # @return a new Geo::OGR::Feature object
3860 #*
3861 sub new {
3862  my $pkg = shift;
3863  my $self = Geo::OGRc::new_Feature(@_);
3864  bless $self, $pkg if defined($self);
3865 }
3866 
3867 #** @class Geo::OGR::FeatureDefn
3868 # @brief A definition of the attributes of a feature class or a layer.
3869 #
3870 # A definition object is a collection of field definition objects. A
3871 # read-only definition object is obtained from a layer or a feature.
3872 #*
3873 package Geo::OGR::FeatureDefn;
3874 
3875 use base qw(Geo::OGR)
3876 
3877 #** @method AddField(%params)
3878 # @param params named parameters to create a new Geo::OGR::FieldDefn
3879 # or Geo::OGR::GeomFieldDefn object.
3880 #*
3881 sub AddField {
3882  my $self = shift;
3883  confess "Read-only definition." if $Geo::OGR::Feature::DEFNS{$self} or $Geo::OGR::Layer::DEFNS{$self};
3884  my %params;
3885  if (@_ == 0) {
3886  } elsif (ref($_[0]) eq 'HASH') {
3887  %params = %{$_[0]};
3888  } elsif (@_ % 2 == 0) {
3889  %params = @_;
3890  }
3891  $params{Type} = '' unless defined $params{Type};
3892  if (exists $Geo::OGR::FieldDefn::TYPE_STRING2INT{$params{Type}}) {
3893  my $fd = Geo::OGR::FieldDefn->new(%params);
3894  $self->AddFieldDefn($fd);
3895  } else {
3896  my $fd = Geo::OGR::GeomFieldDefn->new(%params);
3897  $self->AddGeomFieldDefn($fd);
3898  }
3899 }
3900 
3901 #** @method DeleteField($name)
3902 # @note Currently only geometry fields can be deleted.
3903 # @param index the index of the geometry field to be deleted.
3904 #*
3905 sub DeleteField {
3906  my ($self, $name) = @_;
3907  confess "Read-only definition." if $Geo::OGR::Feature::DEFNS{$self} or $Geo::OGR::Layer::DEFNS{$self};
3908  for my $i (0..$self->GetFieldCount-1) {
3909  confess "Non-geometry fields cannot be deleted." if $self->GetFieldDefn($i)->Name eq $name;
3910  }
3911  for my $i (0..$self->GetGeomFieldCount-1) {
3912  $self->DeleteGeomFieldDefn($i) if $self->GetGeomFieldDefn($i)->Name eq $name;
3913  }
3914  confess "No such field: '$name'.";
3915 }
3916 
3917 #** @method object GetFieldDefn($name)
3918 # @param name the name of the field.
3919 # @return either a Geo::OGR::FieldDefn or Geo::OGR::GeomFieldDefn
3920 # object that represents the field in question.
3921 #*
3922 sub GetFieldDefn {
3923  my ($self, $name) = @_;
3924  for my $i (0..$self->GetFieldCount-1) {
3925  my $fd = $self->GetFieldDefn($i);
3926  return $fd if $fd->Name eq $name;
3927  }
3928  for my $i (0..$self->GetGeomFieldCount-1) {
3929  my $fd = $self->GetGeomFieldDefn($i);
3930  return $fd if $fd->Name eq $name;
3931  }
3932  confess "No such field: '$name'.";
3933 }
3934 
3935 #** @method list GetFieldNames()
3936 # The names of the fields in this layer or feature definition.
3937 # @return the list of field names.
3938 #*
3939 sub GetFieldNames {
3940  my $self = shift;
3941  my @names = ();
3942  for my $i (0..$self->GetFieldCount-1) {
3943  push @names, $self->GetFieldDefn($i)->Name;
3944  }
3945  for my $i (0..$self->GetGeomFieldCount-1) {
3946  push @names, $self->GetGeomFieldDefn($i)->Name;
3947  }
3948  return @names;
3949 }
3950 
3951 #** @method scalar GetName()
3952 # @return the name of this layer or feature definition.
3953 #*
3954 sub GetName {
3955 }
3956 
3957 #** @method hash reference GetSchema()
3958 # @brief Get the schema of this feature or layer definition.
3959 #
3960 # The schema is a hash whose keywords are Name, StyleIgnored and
3961 # Fields. Fields is an anonymous array of first non-spatial and then
3962 # spatial field schemas as in Geo::OGR::FieldDefn::Schema and
3963 # Geo::OGR::GeomFieldDefn::Schema.
3964 # @return the schema of this feature or layer definition.
3965 #*
3966 sub GetSchema {
3967  my $self = shift;
3968  carp "Schema of a feature definition should not be set directly." if @_;
3969  if (@_ and @_ % 2 == 0) {
3970  my %schema = @_;
3971  if ($schema{Fields}) {
3972  for my $field (@{$schema{Fields}}) {
3973  $self->AddField($field);
3974  }
3975  }
3976  }
3977  my %schema;
3978  $schema{Name} = $self->Name();
3979  $schema{StyleIgnored} = $self->StyleIgnored();
3980  $schema{Fields} = [];
3981  for my $i (0..$self->GetFieldCount-1) {
3982  my $s = $self->GetFieldDefn($i)->Schema;
3983  push @{$schema{Fields}}, $s;
3984  }
3985  for my $i (0..$self->GetGeomFieldCount-1) {
3986  my $s = $self->GetGeomFieldDefn($i)->Schema;
3987  push @{$schema{Fields}}, $s;
3988  }
3989  return wantarray ? %schema : \%schema;
3990 }
3991 
3992 #** @method IsSame(Geo::OGR::FeatureDefn defn)
3993 # @return true if this definition is similar to the other definition,
3994 # false otherwise.
3995 #*
3996 sub IsSame {
3997 }
3998 
3999 #** @method scalar IsStyleIgnored()
4000 # Get the ignore status of style information when fetching features.
4001 # @return the ignore status of style information
4002 # @since 1.9.0
4003 #*
4004 sub IsStyleIgnored {
4005 }
4006 
4007 #** @method SetStyleIgnored($IgnoreState)
4008 # Set the ignore status of style information when fetching features.
4009 # @since 1.9.0
4010 #*
4011 sub SetStyleIgnored {
4012 }
4013 
4014 #** @method Geo::OGR::FeatureDefn new(%schema)
4015 # Class method.
4016 # Creates a new layer or feature definition. The new definition is
4017 # either initialized to the given schema or it will contain no
4018 # non-spatial fields and one spatial field, whose Name is '' and
4019 # GeometryType is 'Unknown' or the value of the named parameter
4020 # GeometryType.
4021 # @param schema [optional] The schema for the new feature definition,
4022 # as in Geo::OGR::FeatureDefn::Schema.
4023 # @return a Geo::OGR::FeatureDefn object
4024 #
4025 # Example usage:
4026 # \code
4027 # $fd = Geo::OGR::FeatureDefn->new(
4028 # Name => "name",
4029 # Fields => [{ Name => 'field1', Type => 'String' },
4030 # { Name => 'geom', GeometryType => 'Point' }] );
4031 # \endcode
4032 #*
4033 sub new {
4034  my $pkg = shift;
4035  my %schema;
4036  if (@_ == 1 and ref($_[0]) eq 'HASH') {
4037  %schema = %{$_[0]};
4038  } elsif (@_ and @_ % 2 == 0) {
4039  %schema = @_;
4040  }
4041  my $fields = $schema{Fields};
4042  confess "The Fields argument is not a reference to an array." if $fields and ref($fields) ne 'ARRAY';
4043  $schema{Name} = '' unless exists $schema{Name};
4044  my $self = Geo::OGRc::new_FeatureDefn($schema{Name});
4045  bless $self, $pkg;
4046  my $gt = $schema{GeometryType};
4047  if ($fields) {
4048  $self->DeleteGeomFieldDefn(0); # either default behavior or argument specified
4049  } else {
4050  $self->GeometryType($schema{GeometryType}) if exists $schema{GeometryType};
4051  }
4052  $self->StyleIgnored($schema{StyleIgnored}) if exists $schema{StyleIgnored};
4053  for my $fd (@{$fields}) {
4054  my $d = $fd;
4055  if (ref($fd) eq 'HASH') {
4056  if ($fd->{GeometryType} or exists $Geo::OGR::Geometry::TYPE_STRING2INT{$fd->{Type}}) {
4057  $d = Geo::OGR::GeomFieldDefn->new(%$fd);
4058  } else {
4059  $d = Geo::OGR::FieldDefn->new(%$fd);
4060  }
4061  }
4062  if (blessed($d) and $d->isa('Geo::OGR::FieldDefn')) {
4063  AddFieldDefn($self, $d);
4064  } elsif (blessed($d) and $d->isa('Geo::OGR::GeomFieldDefn')) {
4065  AddGeomFieldDefn($self, $d);
4066  } else {
4067  confess "Item in field list does not define a field.";
4068  }
4069  }
4070  return $self;
4071 }
4072 
4073 #** @class Geo::OGR::FieldDefn
4074 # @brief A definition of a non-spatial attribute.
4075 #*
4076 package Geo::OGR::FieldDefn;
4077 
4078 use base qw(Geo::OGR)
4079 
4080 #** @method scalar Default($value)
4081 # Get or set the default value for this field.
4082 # @note a.k.a. GetDefault and SetDefault
4083 # @param value [optional]
4084 # @return the default value of this field in non-void context.
4085 #*
4086 sub Default {
4087  my $self = shift;
4088  SetDefault($self, $_[0]) if @_;
4089  GetDefault($self) if defined wantarray;
4090 }
4091 
4092 #** @method GetSchema()
4093 #*
4094 sub GetSchema {
4095 }
4097 #** @method scalar Ignored($ignore)
4098 # Get and/or set the ignore status (whether this field should be
4099 # omitted when fetching features) of this field.
4100 # @note a.k.a. IsIgnored, SetIgnored
4101 # @param ignore [optional]
4102 # @return the ignore status of this field in non-void context.
4103 # @since 1.9.0
4104 #*
4105 sub Ignored {
4106  my $self = shift;
4107  SetIgnored($self, $_[0]) if @_;
4108  IsIgnored($self) if defined wantarray;
4109 }
4110 
4111 #** @method IsDefaultDriverSpecific()
4112 #*
4113 sub IsDefaultDriverSpecific {
4115 
4116 #** @method scalar Justify($justify)
4117 # Get and/or set the justification of this field.
4118 # @note a.k.a. GetJustify, SetJustify
4119 # @param justify [optional] One of field justify types (Geo::OGR::FieldDefn::JustifyValues).
4120 # @return the justify value of this field in non-void context.
4121 #*
4122 sub Justify {
4123  my($self, $justify) = @_;
4124  if (defined $justify) {
4125  confess "Unknown justify value: '$justify'." unless exists $JUSTIFY_STRING2INT{$justify};
4126  $justify = $JUSTIFY_STRING2INT{$justify} if exists $JUSTIFY_STRING2INT{$justify};
4127  SetJustify($self, $justify);
4128  }
4129  return $JUSTIFY_INT2STRING{GetJustify($self)} if defined wantarray;
4131 
4132 #** @method list JustifyValues()
4133 # Class method.
4134 # Justify values supported by GDAL. Current list is
4135 # Left, Right, and Undefined.
4136 #*
4137 sub JustifyValues {
4138  return @JUSTIFY_VALUES;
4139 }
4140 
4141 #** @method scalar Name($name)
4142 # Get and/or set the name of the field.
4143 # @note a.k.a. GetName, GetNameRef, SetName
4144 # @param name [optional]
4145 # @return the name in non-void context
4146 #*
4147 sub Name {
4148  my $self = shift;
4149  SetName($self, $_[0]) if @_;
4150  GetName($self) if defined wantarray;
4151 }
4152 
4153 #** @method scalar Nullable($nullable)
4154 # Get or set the nullable constraint for this field.
4155 # @note a.k.a. IsNullable and SetNullable
4156 # @param nullable [optional]
4157 # @return the nullable value of this field in non-void context.
4158 #*
4159 sub Nullable {
4160  my $self = shift;
4161  SetNullable($self, $_[0]) if @_;
4162  IsNullable($self) if defined wantarray;
4163 }
4164 
4165 #** @method scalar Precision($precision)
4166 # Get and/or set the precision of this field.
4167 # @note a.k.a. GetPrecision, SetPrecision
4168 # @param precision [optional]
4169 # @return the precision of this field in non-void context.
4170 #*
4171 sub Precision {
4172  my $self = shift;
4173  SetPrecision($self, $_[0]) if @_;
4174  GetPrecision($self) if defined wantarray;
4175 }
4176 
4177 #** @method hash reference Schema(%params)
4178 # Get the schema or set parts of the schema
4179 # @param params [optional] as those in Geo::OGR::FieldDefn::new.
4180 # @return a reference to a hash whose keys are as those in Geo::OGR::FieldDefn::new.
4181 #*
4182 sub Schema {
4183  my $self = shift;
4184  if (@_) {
4185  my %args = @_;
4186  for my $key (keys %SCHEMA_KEYS) {
4187  eval '$self->'.$key.'($args{'.$key.'}) if exists $args{'.$key.'}';
4188  croak $@ if $@;
4189  }
4190  }
4191  return unless defined wantarray;
4192  my %schema = ();
4193  for my $key (keys %SCHEMA_KEYS) {
4194  $schema{$key} = eval '$self->'.$key;
4195  }
4196  return wantarray ? %schema : \%schema;
4197 }
4198 
4199 #** @method SetSchema()
4200 #*
4201 sub SetSchema {
4202 }
4203 
4204 #** @method scalar SubType($SubType)
4205 # @note a.k.a. GetSubType, SetSubType
4206 # @param SubType [optional] One of field sub types (Geo::OGR::FieldDefn::SubTypes).
4207 # @return the sub type of this field in non-void context.
4208 #*
4209 sub SubType {
4210  my($self, $sub_type) = @_;
4211  if (defined $sub_type) {
4212  confess "Unknown field sub type: '$sub_type'." unless exists $SUB_TYPE_STRING2INT{$sub_type};
4213  $sub_type = $SUB_TYPE_STRING2INT{$sub_type};
4214  SetSubType($self, $sub_type);
4215  }
4216  return $SUB_TYPE_INT2STRING{GetSubType($self)} if defined wantarray;
4217 }
4218 
4219 #** @method SubTypes()
4220 #*
4221 sub SubTypes {
4222  return @SUB_TYPES;
4223 }
4224 
4225 #** @method scalar Type($type)
4226 # @note a.k.a. GetFieldTypeName, GetTypeName, GetType, SetType
4227 # @param type [optional] One of field types (Geo::OGR::FieldDefn::Types).
4228 # @return one of field types in non-void context.
4229 #*
4230 sub Type {
4231  my($self, $type) = @_;
4232  if (defined $type) {
4233  confess "Unknown field type: '$type'." unless exists $TYPE_STRING2INT{$type};
4234  $type = $TYPE_STRING2INT{$type};
4235  SetType($self, $type);
4236  }
4237  return $TYPE_INT2STRING{GetType($self)} if defined wantarray;
4238 }
4239 
4240 #** @method list Types()
4241 # Class method.
4242 # Field types supported by GDAL. Current list is
4243 # Binary, Date, DateTime, Integer, Integer64, Integer64List, IntegerList, Real, RealList, String, StringList, Time, WideString, and WideStringList.
4244 #*
4245 sub Types {
4246  return @TYPES;
4247 }
4248 
4249 #** @method scalar Width($width)
4250 # Get and/or set the field width.
4251 # @note a.k.a. GetWidth, SetWidth
4252 # @param width [optional]
4253 # @return the width of this field in non-void context.
4254 #*
4255 sub Width {
4256  my $self = shift;
4257  SetWidth($self, $_[0]) if @_;
4258  GetWidth($self) if defined wantarray;
4259 }
4260 
4261 #** @method Geo::OGR::FieldDefn new(%params)
4262 # Class method.
4263 # @brief Create a new field definition.
4264 #
4265 # This method supports both an argument list and named arguments.
4266 #
4267 # @param name Field name (please do not try to name the field as Name or Type etc.).
4268 # @param type One of supported field types
4269 # (see Geo::OGR::FieldDefn::Types). Optional. Default is String.
4270 #
4271 # or
4272 #
4273 # @param params one or more of:
4274 # - \a Name Field name (default is 'unnamed').
4275 # - \a Type Field type, one of Geo::OGR::FieldDefn::Types (default is 'String').
4276 # - \a SubType Field sub type, one of Geo::OGR::FieldDefn::SubTypes.
4277 # - \a Justify Justify value, one of Geo::OGR::FieldDefn::JustifyValues
4278 # - \a Width
4279 # - \a Precision
4280 # - \a Nullable (default is true)
4281 # - \a Default
4282 # - \a Ignored (default is false)
4283 # @return a new Geo::OGR::FieldDefn object
4284 #*
4285 sub new {
4286  my $pkg = shift;
4287  my ($name, $type) = ('unnamed', 'String');
4288  my %args;
4289  if (@_ == 0) {
4290  } elsif (@_ == 1) {
4291  $name = shift;
4292  } elsif (@_ == 2 and not $Geo::OGR::FieldDefn::SCHEMA_KEYS{$_[0]}) {
4293  $name = shift;
4294  $type = shift;
4295  } else {
4296  my %named = @_;
4297  for my $key (keys %named) {
4298  if ($Geo::OGR::FieldDefn::SCHEMA_KEYS{$key}) {
4299  $args{$key} = $named{$key};
4300  } else {
4301  carp "Unrecognized argument: '$key'.";
4302  }
4303  }
4304  $name = $args{Name} if exists $args{Name};
4305  delete $args{Name};
4306  $type = $args{Type} if exists $args{Type};
4307  delete $args{Type};
4308  }
4309  confess "Unknown field type: '$type'." unless exists $Geo::OGR::FieldDefn::TYPE_STRING2INT{$type};
4310  $type = $Geo::OGR::FieldDefn::TYPE_STRING2INT{$type};
4311  my $self = Geo::OGRc::new_FieldDefn($name, $type);
4312  if (defined($self)) {
4313  bless $self, $pkg;
4314  $self->Schema(%args);
4315  }
4316  return $self;
4317 }
4318 
4319 #** @class Geo::OGR::GeomFieldDefn
4320 # @brief A definition of a spatial attribute.
4321 #*
4322 package Geo::OGR::GeomFieldDefn;
4323 
4324 use base qw(Geo::OGR)
4325 
4326 #** @method GetSchema()
4327 #*
4328 sub GetSchema {
4329 }
4330 
4331 #** @method scalar Ignored($ignore)
4332 # @note a.k.a. IsIgnored, SetIgnored
4333 # @return the ignore status of the field.
4334 #*
4335 sub Ignored {
4336  my $self = shift;
4337  SetIgnored($self, $_[0]) if @_;
4338  IsIgnored($self) if defined wantarray;
4339 }
4340 
4341 #** @method scalar Name($name)
4342 # @note a.k.a. GetName, GetNameRef, SetName
4343 # @return the name of the field.
4344 #*
4345 sub Name {
4346  my $self = shift;
4347  SetName($self, $_[0]) if @_;
4348  GetName($self) if defined wantarray;
4349 }
4350 
4351 #** @method scalar Nullable($nullable)
4352 # @note a.k.a. IsNullable, SetNullable
4353 # @return the nullable status of the field.
4354 #*
4355 sub Nullable {
4356  my $self = shift;
4357  SetNullable($self, $_[0]) if @_;
4358  IsNullable($self) if defined wantarray;
4359 }
4360 
4361 #** @method hash reference Schema(%params)
4362 # Get the schema or set parts of the schema.
4363 # @param params [optional] as those in Geo::OGR::GeomFieldDefn::new.
4364 # @return a reference to a hash whose keys are as those in Geo::OGR::GeomFieldDefn::new.
4365 #*
4366 sub Schema {
4367  my $self = shift;
4368  if (@_) {
4369  my %args = @_;
4370  for my $key (keys %SCHEMA_KEYS) {
4371  eval '$self->'.$key.'($args{'.$key.'}) if exists $args{'.$key.'}';
4372  croak $@ if $@;
4373  }
4374  }
4375  return unless defined wantarray;
4376  my %schema = ();
4377  for my $key (keys %SCHEMA_KEYS) {
4378  $schema{$key} = eval '$self->'.$key;
4379  }
4380  return wantarray ? %schema : \%schema;
4381 }
4382 
4383 #** @method SetSchema()
4384 #*
4385 sub SetSchema {
4386 }
4387 
4388 #** @method scalar SpatialReference($sr)
4389 # @note a.k.a. GetSpatialRef, SetSpatialRef
4390 # @return the spatial reference of the field as a Geo::OSR::SpatialReference object.
4391 #*
4392 sub SpatialReference {
4393  my $self = shift;
4394  SetSpatialRef($self, $_[0]) if @_;
4395  GetSpatialRef($self) if defined wantarray;
4396 }
4397 
4398 #** @method Type()
4399 # @return the type of this geometry field. One of Geo::OGR::GeomFieldDefn::Types
4400 #*
4401 sub Type {
4402  my($self, $type) = @_;
4403  if (defined $type) {
4404  confess "Unknown geometry type: '$type'." unless exists $Geo::OGR::Geometry::TYPE_STRING2INT{$type};
4405  $type = $Geo::OGR::Geometry::TYPE_STRING2INT{$type};
4406  SetType($self, $type);
4407  }
4408  $Geo::OGR::Geometry::TYPE_INT2STRING{GetType($self)} if defined wantarray;
4409 }
4410 
4411 #** @method Types()
4412 # Class method.
4413 # @return a list of all geometry types, currently:
4414 # CircularString, CircularStringZ, CompoundCurve, CompoundCurveZ, CurvePolygon, CurvePolygonZ, GeometryCollection, GeometryCollection25D, LineString, LineString25D, LinearRing, MultiCurve, MultiCurveZ, MultiLineString, MultiLineString25D, MultiPoint, MultiPoint25D, MultiPolygon, MultiPolygon25D, MultiSurface, MultiSurfaceZ, None, Point, Point25D, Polygon, Polygon25D, and Unknown.
4415 #*
4416 sub Types {
4417  return @Geo::OGR::Geometry::GEOMETRY_TYPES;
4418 }
4419 
4420 #** @method Geo::OGR::GeomFieldDefn new(%params)
4421 # Class method.
4422 # @brief Create a new spatial field definition.
4423 #
4424 # @param params one or more of:
4425 # - \a Name name for the field (default is 'geom').
4426 # - \a GeometryType type for the field type, one of Geo::OGR::GeomFieldDefn::Types (default is 'Unknown').
4427 # - \a SpatialReference a Geo::OSR::SpatialReference object.
4428 # - \a Nullable (default is true)
4429 # - \a Ignored (default is false)
4430 # @return a new Geo::OGR::GeomFieldDefn object
4431 #*
4432 sub new {
4433  my $pkg = shift;
4434  my ($name, $type) = ('geom', 'Unknown');
4435  my %args;
4436  if (@_ == 0) {
4437  } elsif (@_ == 1) {
4438  $name = shift;
4439  } elsif (@_ == 2 and not $Geo::OGR::GeomFieldDefn::SCHEMA_KEYS{$_[0]}) {
4440  $name = shift;
4441  $type = shift;
4442  } else {
4443  my %named = @_;
4444  for my $key (keys %named) {
4445  if ($Geo::OGR::GeomFieldDefn::SCHEMA_KEYS{$key}) {
4446  $args{$key} = $named{$key};
4447  } else {
4448  carp "Unrecognized argument: '$key'.";
4449  }
4450  }
4451  $name = $args{Name} if exists $args{Name};
4452  delete $args{Name};
4453  $type = $args{Type} if $args{Type};
4454  delete $args{Type};
4455  $type = $args{GeometryType} if $args{GeometryType};
4456  delete $args{GeometryType};
4457  }
4458  confess "Unknown geometry type: '$type'." unless exists $Geo::OGR::Geometry::TYPE_STRING2INT{$type};
4459  $type = $Geo::OGR::Geometry::TYPE_STRING2INT{$type};
4460  my $self = Geo::OGRc::new_GeomFieldDefn($name, $type);
4461  if (defined($self)) {
4462  bless $self, $pkg;
4463  $self->Schema(%args);
4464  }
4465  return $self;
4466 }
4467 
4468 #** @class Geo::OGR::Geometry
4469 # @brief Spatial data.
4470 #
4471 # A geometry is spatial data (coordinate values, and a reference to a
4472 # spatial reference system) organized into one of the geometry
4473 # types. Geometries can be created from several type of data including
4474 # a Perl data structure. There are several methods, which modify,
4475 # compare, test, or compute values from geometries.
4476 # @note Most spatial analysis methods require <a
4477 # href="http://geos.osgeo.org/doxygen/">GEOS</a> to work rigorously.
4478 #*
4479 package Geo::OGR::Geometry;
4480 
4481 use base qw(Geo::OGR)
4482 
4483 #** @method AddGeometry($other)
4484 # Add a copy of another geometry to a geometry collection
4485 # @param other a Geo::OGR::Geometry object
4486 #*
4487 sub AddGeometry {
4488 }
4489 
4490 #** @method AddGeometryDirectly($other)
4491 # @param other a Geo::OGR::Geometry object
4492 #*
4493 sub AddGeometryDirectly {
4494 }
4495 
4496 #** @method AddPoint($x, $y, $z)
4497 # Set the data of a point or add a point to a line string. Consider
4498 # using Geo::OGR::Geometry::Points. Note that the coordinate
4499 # dimension is automatically upgraded to 25D (3) if z is given.
4500 # @param x
4501 # @param y
4502 # @param z [optional]
4503 # Calls internally the 2D or 3D version depending on the number of parameters.
4504 #*
4505 sub AddPoint {
4506  @_ == 4 ? AddPoint_3D(@_) : AddPoint_2D(@_);
4507 }
4508 
4509 #** @method AddPoint_2D($x, $y)
4510 # Set the data of a point or add a point to a line string. Consider
4511 # using Geo::OGR::Geometry::Points.
4512 # @param x
4513 # @param y
4514 #*
4515 sub AddPoint_2D {
4516 }
4517 
4518 #** @method AddPoint_3D($x, $y, $z)
4519 # Set the data of a point or add a point to a line string. Note that
4520 # the coordinate dimension is automatically upgraded to 25D (3). Consider
4521 # using Geo::OGR::Geometry::Points.
4522 # @param x
4523 # @param y
4524 # @param z
4525 #*
4526 sub AddPoint_3D {
4527 }
4528 
4529 #** @method Geo::OGR::Geometry ApproximateArcAngles(%params)
4530 # Class method.
4531 # Create a line string, which approximates an arc.
4532 # @note All angles are in degrees.
4533 #
4534 # @param %params named parameters, these are:
4535 # - \a Center center point (default is [0, 0, 0])
4536 # - \a PrimaryRadius default is 1,
4537 # - \a SecondaryAxis default is 1,
4538 # - \a Rotation default is 0,
4539 # - \a StartAngle default is 0,
4540 # - \a EndAngle default is 360,
4541 # - \a MaxAngleStepSizeDegrees default is 4
4542 # @return a new Geo::OGR::Geometry object.
4543 #*
4544 sub ApproximateArcAngles {
4545  my %p = @_;
4546  my %default = ( Center => [0,0,0],
4547  PrimaryRadius => 1,
4548  SecondaryAxis => 1,
4549  Rotation => 0,
4550  StartAngle => 0,
4551  EndAngle => 360,
4552  MaxAngleStepSizeDegrees => 4
4553  );
4554  for my $p (keys %p) {
4555  if (exists $default{$p}) {
4556  $p{$p} = $default{$p} unless defined $p{$p};
4557  } else {
4558  carp "Unknown named parameter: '$p'.";
4559  }
4560  }
4561  for my $p (keys %default) {
4562  $p{$p} = $default{$p} unless exists $p{$p};
4563  }
4564  confess "Usage: Center => [x,y,z]." unless ref($p{Center}) eq 'ARRAY';
4565  for my $i (0..2) {
4566  $p{Center}->[$i] = 0 unless defined $p{Center}->[$i];
4567  }
4568  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});
4569 }
4570 
4571 #** @method scalar Area()
4572 # @note a.k.a. GetArea
4573 # @return the area of the polygon or multipolygon
4574 #*
4575 sub Area {
4576 }
4577 
4578 #** @method scalar As(%params)
4579 # Export the geometry into a known format.
4580 # @param params named parameters, either: Text (a.k.a WKT), WKB
4581 # (a.k.a. Binary) (ByteOrder can also be defined, default is 'XDR'),
4582 # ISO WKT and WKB, HEXWKB, HEXEWKB (srid can also be given), GML,
4583 # GeoJSON, Binary.
4584 # @note Uses As\<format\>/ExportTo\<format\> methods.
4585 # @return the geometry in a given format.
4586 #*
4587 sub As {
4588  my $self = shift;
4589  my %param;
4590  if (@_ == 1 and ref($_[0]) eq 'HASH') {
4591  %param = %{$_[0]};
4592  } elsif (@_ % 2 == 0) {
4593  %param = @_;
4594  } else {
4595  ($param{Format}, $param{x}) = @_;
4596  }
4597  $param{ByteOrder} = 'XDR' unless $param{ByteOrder};
4598  my $f = $param{Format};
4599  my $x = $param{x};
4600  $x = $param{ByteOrder} unless defined $x;
4601  if ($f =~ /text/i) {
4602  return $self->AsText;
4603  } elsif ($f =~ /wkt/i) {
4604  if ($f =~ /iso/i) {
4605  return $self->ExportToIsoWkt;
4606  } else {
4607  return $self->AsText;
4608  }
4609  } elsif ($f =~ /binary/i) {
4610  return $self->AsBinary($x);
4611  } elsif ($f =~ /wkb/i) {
4612  if ($f =~ /iso/i) {
4613  return $self->ExportToIsoWkb;
4614  } elsif ($f =~ /hexe/i) {
4615  $param{srid} = 'XDR' unless $param{srid};
4616  $x = $param{srid} unless defined $x;
4617  return $self->AsHEXEWKB($x);
4618  } elsif ($f =~ /hex/i) {
4619  return $self->AsHEXWKB;
4620  } else {
4621  return $self->AsBinary($x);
4622  }
4623  } elsif ($f =~ /gml/i) {
4624  return $self->AsGML;
4625  } elsif ($f =~ /kml/i) {
4626  return $self->AsKML;
4627  } elsif ($f =~ /json/i) {
4628  return $self->AsJSON;
4629  } else {
4630  confess "Unsupported format: $f.";
4631  }
4632 }
4633 
4634 #** @method AssignSpatialReference($srs)
4635 # @param srs a Geo::OSR::SpatialReference object
4636 #*
4637 sub AssignSpatialReference {
4638 }
4639 
4640 #** @method Geo::OGR::Geometry Boundary()
4641 # @note a.k.a. GetBoundary
4642 # @return the boundary of this geometry as a geometry
4643 # @since 1.8.0
4644 #*
4645 sub Boundary {
4646 }
4647 
4648 #** @method Geo::OGR::Geometry Buffer($distance, $quadsecs = 30)
4649 # @param distance
4650 # @param quadsecs
4651 # @return a new Geo::OGR::Geometry object
4652 #*
4653 sub Buffer {
4654 }
4655 
4656 #** @method Geo::OGR::Geometry BuildPolygonFromEdges($BestEffort = 0, $AutoClose = 0, $Tolerance = 0)
4657 # Attempt to create a polygon from a collection of lines or from a multilinestring.
4658 # @param BestEffort For future
4659 # @param AutoClose Assure the first and last points of rings are same.
4660 # @param Tolerance Snap distance.
4661 # @exception Several possibilities, some are reported, some are general errors.
4662 # @return a new Geo::OGR::Geometry object (Polygon)
4663 #*
4664 sub BuildPolygonFromEdges {
4665 }
4666 
4667 #** @method list ByteOrders()
4668 # Class method.
4669 # Same as Geo::OGR::ByteOrders
4670 #*
4671 sub ByteOrders {
4672  return @BYTE_ORDER_TYPES;
4673 }
4674 
4675 #** @method Geo::OGR::Geometry Centroid()
4676 # @return a new Geo::OGR::Geometry object
4677 # @since 1.8.0
4678 #*
4679 sub Centroid {
4680 }
4681 
4682 #** @method Geo::OGR::Geometry Clone()
4683 # @return a new Geo::OGR::Geometry object
4684 #*
4685 sub Clone {
4686 }
4687 
4688 #** @method CloseRings()
4689 #*
4690 sub CloseRings {
4691 }
4692 
4693 #** @method Geo::OGR::Geometry Collect(@geometries)
4694 # Create a geometrycollection from this and possibly other geometries.
4695 # @param geometries [optional] More geometries to add to the collection.
4696 # @return a new Geo::OGR::Geometry object of type geometrycollection.
4697 #*
4698 sub Collect {
4699 }
4700 
4701 #** @method scalar Contains($other)
4702 # @param other a Geo::OGR::Geometry object
4703 # @return true if this geometry contains the other geometry, false otherwise
4704 #*
4705 sub Contains {
4706 }
4707 
4708 #** @method Geo::OGR::Geometry ConvexHull()
4709 # @return a new Geo::OGR::Geometry object
4710 #*
4711 sub ConvexHull {
4712 }
4713 
4714 #** @method scalar CoordinateDimension($dimension)
4715 # @param dimension [optional]
4716 # @return 2 or 3
4717 #*
4718 sub CoordinateDimension {
4719  my $self = shift;
4720  SetCoordinateDimension($self, $_[0]) if @_;
4721  GetCoordinateDimension($self) if defined wantarray;
4722 }
4723 
4724 #** @method scalar Crosses($other)
4725 # @param other a Geo::OGR::Geometry object
4726 # @return true if this geometry crosses the other geometry, false otherwise
4727 #*
4728 sub Crosses {
4729 }
4730 
4731 #** @method Geo::OGR::Geometry Difference($other)
4732 # @param other a Geo::OGR::Geometry object
4733 # @return a new Geo::OGR::Geometry object
4734 #*
4735 sub Difference {
4736 }
4737 
4738 #** @method scalar Disjoint($other)
4739 # @param other a Geo::OGR::Geometry object
4740 # @return true if this geometry is disjoint from the other geometry, false otherwise
4741 #*
4742 sub Disjoint {
4743 }
4744 
4745 #** @method list Dissolve()
4746 # Dissolve a geometrycollection into separate geometries.
4747 # @return a list of new Geo::OGR::Geometry objects cloned from the collection.
4748 #*
4749 sub Dissolve {
4750  my $self = shift;
4751  my @c;
4752  my $n = $self->GetGeometryCount;
4753  if ($n > 0) {
4754  for my $i (0..$n-1) {
4755  push @c, $self->GetGeometryRef($i)->Clone;
4756  }
4757  } else {
4758  push @c, $self;
4759  }
4760  return @c;
4761 }
4762 
4763 #** @method scalar Distance($other)
4764 # @param other a Geo::OGR::Geometry object
4765 # @return the distance to the other geometry
4766 #*
4767 sub Distance {
4768 }
4769 
4770 #** @method Empty()
4771 # Clear geometry data, i.e., remove all points, or, for a point, set
4772 # the coordinate dimension as zero.
4773 #*
4774 sub Empty {
4775 }
4776 
4777 #** @method scalar Equals($other)
4778 # @note a.k.a. Equal (deprecated)
4779 # @param other a Geo::OGR::Geometry object
4780 # @return true if this geometry is equivalent to the other geometry, false otherwise
4781 #*
4782 sub Equals {
4783 }
4784 
4785 #** @method FlattenTo2D()
4786 #*
4787 sub FlattenTo2D {
4788 }
4789 
4790 #** @method Geo::OGR::Geometry ForceTo($type, ref options)
4791 # Attempt to make a geometry of type 'type' out of this geometry.
4792 # @param type target geometry type. One of Geo::OGR::GeometryTypes.
4793 # @param options not used currently.
4794 # @return a new Geo::OGR::Geometry object.
4795 #*
4796 sub ForceTo {
4797  my $self = shift;
4798  my $type = shift;
4799  confess "Unknown geometry type: '$type'." unless exists $TYPE_STRING2INT{$type};
4800  $type = $TYPE_STRING2INT{$type};
4801  eval {
4802  $self = Geo::OGR::ForceTo($self, $type, @_);
4803  };
4804  confess $@ if $@;
4805  return $self;
4806 }
4807 
4808 #** @method Geo::OGR::Geometry ForceToCollection(@geometries)
4809 # Create a geometrycollection from the geometry.
4810 # @param geometries [optional] More geometries to add to the collection.
4811 # @return a new Geo::OGR::Geometry object of type geometrycollection.
4812 #*
4813 sub ForceToCollection {
4814  my $self = Geo::OGR::Geometry->new(GeometryType => 'GeometryCollection');
4815  for my $g (@_) {
4816  $self->AddGeometry($g);
4817  }
4818  return $self;
4819 }
4820 
4821 #** @method Geo::OGR::Geometry ForceToLineString()
4822 # Attempt to create a line string from this geometry.
4823 # @return a new Geo::OGR::Geometry object.
4824 #*
4825 sub ForceToLineString {
4826  my $self = shift;
4827  $self = Geo::OGR::ForceToLineString($self);
4828  return $self;
4829 }
4830 
4831 #** @method Geo::OGR::Geometry ForceToMultiLineString(@linestrings)
4832 # Attempt to create a multilinestring from the geometry, which must be a linestring.
4833 # @param linestrings [optional] More linestrings to add to the collection.
4834 # @return a new Geo::OGR::Geometry object of type multilinestring.
4835 #*
4836 sub ForceToMultiLineString {
4837  my $self = shift;
4838  $self = Geo::OGR::ForceToMultiLineString($self);
4839  for my $g (@_) {
4840  $self->AddGeometry($g);
4841  }
4842  return $self;
4843 }
4844 
4845 #** @method Geo::OGR::Geometry ForceToMultiPoint(@points)
4846 # Attempt to create a multipoint from the geometry, which must be a point.
4847 # @param points [optional] More points to add to the collection.
4848 # @return a new Geo::OGR::Geometry object of type multipoint.
4849 #*
4850 sub ForceToMultiPoint {
4851  my $self = shift;
4852  $self = Geo::OGR::ForceToMultiPoint($self);
4853  for my $g (@_) {
4854  $self->AddGeometry($g);
4855  }
4856  return $self;
4857 }
4858 
4859 #** @method Geo::OGR::Geometry ForceToMultiPolygon(@polygons)
4860 # Attempt to create a multipolygon from the geometry, which must be a polygon.
4861 # @param polygons [optional] More polygons to add to the collection.
4862 # @return a new Geo::OGR::Geometry object of type multipolygon.
4863 #*
4864 sub ForceToMultiPolygon {
4865  my $self = shift;
4866  $self = Geo::OGR::ForceToMultiPolygon($self);
4867  for my $g (@_) {
4868  $self->AddGeometry($g);
4869  }
4870  return $self;
4871 }
4872 
4873 #** @method Geo::OGR::Geometry ForceToPolygon()
4874 # Attempt to create a polygon from this geometry.
4875 # @exception None reported. If this method fails, just a copy is returned.
4876 # @return a new Geo::OGR::Geometry object.
4877 #*
4878 sub ForceToPolygon {
4879 }
4880 
4881 #** @method scalar GeometryType()
4882 # @return the geometry type of this geometry (one of Geo::OGR::GeometryTypes).
4883 #*
4884 sub GeometryType {
4885  my $self = shift;
4886  return $TYPE_INT2STRING{$self->GetGeometryType};
4887 }
4888 
4889 #** @method list GeometryTypes()
4890 # Class method.
4891 # Same as Geo::OGR::GeometryTypes
4892 #*
4893 sub GeometryTypes {
4894  return @GEOMETRY_TYPES;
4895 }
4896 
4897 #** @method scalar GetCoordinateDimension()
4898 # @return an integer
4899 #*
4900 sub GetCoordinateDimension {
4901 }
4902 
4903 #** @method GetCurveGeometry()
4904 #*
4905 sub GetCurveGeometry {
4906 }
4907 
4908 #** @method scalar GetDimension()
4909 # @return 0, 1, or 2
4910 #*
4911 sub GetDimension {
4912 }
4913 
4914 #** @method list GetEnvelope()
4915 # @note In scalar context returns a reference to an anonymous array
4916 # containing the envelope.
4917 # @note The order of values is different from those returned by
4918 # Geo::OGR::Layer::GetExtent.
4919 # @return the envelope ($minx, $maxx, $miny, $maxy)
4920 #*
4921 sub GetEnvelope {
4922 }
4923 
4924 #** @method list GetEnvelope3D()
4925 # @note In scalar context returns a reference to an anonymous array
4926 # containing the envelope.
4927 # @return the 3-D envelope ($minx, $maxx, $miny, $maxy, $minz, $maxz)
4928 # @since 1.9.0
4929 #*
4930 sub GetEnvelope3D {
4931 }
4932 
4933 #** @method scalar GetGeometryCount()
4934 # @return an integer
4935 #*
4936 sub GetGeometryCount {
4937 }
4938 
4939 #** @method scalar GetGeometryName()
4940 # @deprecated use Geo::OGR::Geometry::GeometryType.
4941 #
4942 # @return a string
4943 #*
4944 sub GetGeometryName {
4945 }
4946 
4947 #** @method scalar GetGeometryRef($index)
4948 # @param index index to the geometry, which is a part of this geometry
4949 # @return a new Geo::OGR::Geometry object whose data is a part of the
4950 # parent geometry
4951 #*
4952 sub GetGeometryRef {
4953 }
4954 
4955 #** @method scalar GetGeometryType()
4956 # @deprecated use Geo::OGR::Geometry::GeometryType, which returns the
4957 # type as a string.
4958 #
4959 # @return type as an integer
4960 #*
4961 sub GetGeometryType {
4962 }
4963 
4964 #** @method GetLinearGeometry()
4965 #*
4966 sub GetLinearGeometry {
4967 }
4968 
4969 #** @method list GetPoint($index = 0)
4970 # @param index
4971 # @return (x,y) or a list with more coordinates
4972 #*
4973 sub GetPoint {
4974  my($self, $i) = @_;
4975  $i = 0 unless defined $i;
4976  my $point = ($self->GetGeometryType & 0x80000000) == 0 ? GetPoint_2D($self, $i) : GetPoint_3D($self, $i);
4977  return @$point;
4978 }
4979 
4980 #** @method scalar GetPointCount()
4981 # @return an integer
4982 #*
4983 sub GetPointCount {
4984 }
4985 
4986 #** @method scalar GetPoint_2D($index = 0)
4987 # @param index
4988 # @return (x,y) or a list with more coordinates
4989 #*
4990 sub GetPoint_2D {
4991 }
4992 
4993 #** @method scalar GetPoint_3D($index = 0)
4994 # @param index
4995 # @return (x,y) or a list with more coordinates
4996 #*
4997 sub GetPoint_3D {
4998 }
4999 
5000 #** @method Geo::OSR::SpatialReference GetSpatialReference()
5001 # @return a new Geo::OSR::SpatialReference object
5002 #*
5003 sub GetSpatialReference {
5004 }
5005 
5006 #** @method scalar GetX($index = 0)
5007 # @param index
5008 # @return a number
5009 #*
5010 sub GetX {
5011 }
5012 
5013 #** @method scalar GetY($index = 0)
5014 # @param index
5015 # @return a number
5016 #*
5017 sub GetY {
5018 }
5019 
5020 #** @method scalar GetZ($index = 0)
5021 # @param index
5022 # @return a number
5023 #*
5024 sub GetZ {
5025 }
5026 
5027 #** @method HasCurveGeometry()
5028 #*
5029 sub HasCurveGeometry {
5030 }
5031 
5032 #** @method Geo::OGR::Geometry Intersection($other)
5033 # @param other a Geo::OGR::Geometry object
5034 # @return a new Geo::OGR::Geometry object
5035 #*
5036 sub Intersection {
5038 
5039 #** @method scalar Intersects($other)
5040 # @note a.k.a. Intersect (deprecated)
5041 # @param other a Geo::OGR::Geometry object
5042 # @return true if this geometry intersects with the other geometry, false otherwise
5043 #*
5044 sub Intersects {
5045 }
5046 
5047 #** @method scalar IsEmpty()
5048 # Test whether the geometry is empty (has no points, or, for a point,
5049 # has coordinate dimension of zero).
5050 # @return boolean
5051 #*
5052 sub IsEmpty {
5053 }
5054 
5055 #** @method scalar IsRing()
5056 # Test if the geometry is a ring. Requires GEOS in GDAL.
5057 # @return boolean
5058 #*
5059 sub IsRing {
5060 }
5061 
5062 #** @method scalar IsSimple()
5063 # Test the simplicity of the geometry (OGC sense). Requires GEOS in GDAL.
5064 # @return boolean
5065 #*
5066 sub IsSimple {
5067 }
5068 
5069 #** @method scalar IsValid()
5070 # Test the validity of the geometry (OGC sense). Requires GEOS in GDAL.
5071 # @return boolean
5072 #*
5073 sub IsValid {
5074 }
5075 
5076 #** @method scalar Length()
5077 # @return the length of the linestring
5078 #*
5079 sub Length {
5080 }
5081 
5082 #** @method Move($dx, $dy, $dz)
5083 # Move every point of the object as defined by the parameters.
5084 # @param dx
5085 # @param dy
5086 # @param dz [optional]
5087 #*
5088 sub Move {
5089 }
5090 
5091 #** @method scalar Overlaps($other)
5092 # @param other a Geo::OGR::Geometry object
5093 # @return true if this geometry overlaps the other geometry, false otherwise
5094 #*
5095 sub Overlaps {
5096 }
5097 
5098 #** @method list Point($index, $x, $y, $z)
5099 # Get or set the point
5100 # @param index The index of the point. Optional (ignored if given) for
5101 # Point and Point25D geometries.
5102 # @param x [optional]
5103 # @param y [optional]
5104 # @param z [optional]
5105 # @return
5106 #*
5107 sub Point {
5108  my $self = shift;
5109  my $i;
5110  if (@_) {
5111  my $t = $self->GetGeometryType;
5112  if ($t == $Geo::OGR::wkbPoint) {
5113  shift if @_ > 2;
5114  $i = 0;
5115  } elsif ($t == $Geo::OGR::wkbPoint25D) {
5116  shift if @_ > 3;
5117  $i = 0;
5118  } else {
5119  my $i = shift;
5120  }
5121  SetPoint($self, $i, @_);
5122  }
5123  return GetPoint($self, $i) if defined wantarray;
5124 }
5125 
5126 #** @method PointOnSurface()
5127 #*
5128 sub PointOnSurface {
5129 }
5130 
5131 #** @method array reference Points(arrayref points)
5132 # Get or set the points of the geometry. The points (vertices) are
5133 # stored in obvious lists of lists. When setting, the geometry is
5134 # first emptied. The method uses internally either AddPoint_2D or
5135 # AddPoint_3D depending on the coordinate dimension of the input data.
5136 #
5137 # @note The same structure may represent different geometries
5138 # depending on the actual geometry type of the object.
5139 #
5140 # @param points [optional] A reference to an array. A point is a reference to an
5141 # array of numbers, a linestring or a ring is a reference to an array of points,
5142 # a polygon is a reference to an array of rings, etc.
5143 #
5144 # @return A reference to an array.
5145 #*
5146 sub Points {
5147  my $self = shift;
5148  my $t = $self->GetGeometryType;
5149  my $flat = not Geo::OGR::GT_HasZ($t);
5150  $t = Geo::OGR::GT_Flatten($t);
5151  $t = $TYPE_INT2STRING{$t};
5152  my $points = shift;
5153  if ($points) {
5154  Empty($self);
5155  if ($t eq 'Unknown' or $t eq 'None' or $t eq 'GeometryCollection') {
5156  confess "Can't set points of a geometry of type '$t'.";
5157  } elsif ($t eq 'Point') {
5158  # support both "Point" as a list of one point and one point
5159  if (ref($points->[0])) {
5160  $flat ?
5161  AddPoint_2D($self, @{$points->[0]}[0..1]) :
5162  AddPoint_3D($self, @{$points->[0]}[0..2]);
5163  } else {
5164  $flat ?
5165  AddPoint_2D($self, @$points[0..1]) :
5166  AddPoint_3D($self, @$points[0..2]);
5167  }
5168  } elsif ($t eq 'LineString' or $t eq 'LinearRing') {
5169  if ($flat) {
5170  for my $p (@$points) {
5171  AddPoint_2D($self, @$p[0..1]);
5172  }
5173  } else{
5174  for my $p (@$points) {
5175  AddPoint_3D($self, @$p[0..2]);
5176  }
5177  }
5178  } elsif ($t eq 'Polygon') {
5179  for my $r (@$points) {
5180  my $ring = Geo::OGR::Geometry->new('LinearRing');
5181  $ring->SetCoordinateDimension(3) unless $flat;
5182  $ring->Points($r);
5183  $self->AddGeometryDirectly($ring);
5184  }
5185  } elsif ($t eq 'MultiPoint') {
5186  for my $p (@$points) {
5187  my $point = Geo::OGR::Geometry->new($flat ? 'Point' : 'Point25D');
5188  $point->Points($p);
5189  $self->AddGeometryDirectly($point);
5190  }
5191  } elsif ($t eq 'MultiLineString') {
5192  for my $l (@$points) {
5193  my $linestring = Geo::OGR::Geometry->new($flat ? 'LineString' : 'LineString25D');
5194  $linestring->Points($l);
5195  $self->AddGeometryDirectly($linestring);
5196  }
5197  } elsif ($t eq 'MultiPolygon') {
5198  for my $p (@$points) {
5199  my $polygon = Geo::OGR::Geometry->new($flat ? 'Polygon' : 'Polygon25D');
5200  $polygon->Points($p);
5201  $self->AddGeometryDirectly($polygon);
5202  }
5203  }
5204  }
5205  return unless defined wantarray;
5206  $self->_GetPoints($flat);
5207 }
5208 
5209 #** @method Segmentize($MaxLength)
5210 # Modify the geometry such it has no segment longer than the given length.
5211 # @param MaxLength the given length
5212 #*
5213 sub Segmentize {
5214 }
5215 
5216 #** @method SetCoordinateDimension($dimension)
5217 # @param dimension
5218 #*
5219 sub SetCoordinateDimension {
5220 }
5221 
5222 #** @method SetPoint($index, $x, $y, $z)
5223 # Set the data of a point or a line string. Note that the coordinate
5224 # dimension is automatically upgraded to 25D (3) if z is given.
5225 # @param index
5226 # @param x
5227 # @param y
5228 # @param z [optional]
5229 #*
5230 sub SetPoint {
5231  @_ == 5 ? SetPoint_3D(@_) : SetPoint_2D(@_);
5232 }
5233 
5234 #** @method SetPoint_2D($index, $x, $y)
5235 # @param index
5236 # @param x
5237 # @param y
5238 #*
5239 sub SetPoint_2D {
5240 }
5241 
5242 #** @method SetPoint_3D($index, $x, $y, $z)
5243 # Set the data of a point or a line string. Note that the coordinate
5244 # dimension is automatically upgraded to 25D (3).
5245 # @param index
5246 # @param x
5247 # @param y
5248 # @param z
5249 #*
5250 sub SetPoint_3D {
5251 }
5252 
5253 #** @method Geo::OGR::Geometry Simplify($Tolerance)
5254 # Simplify the geometry.
5255 # @param Tolerance the length tolerance for the simplification
5256 # @since 1.8.0
5257 # @return a new Geo::OSR::Geometry object
5258 #*
5259 sub Simplify {
5260 }
5261 
5262 #** @method SimplifyPreserveTopology()
5263 #*
5264 sub SimplifyPreserveTopology {
5265 }
5266 
5267 #** @method Geo::OGR::Geometry SymDifference($other)
5268 # Compute symmetric difference.
5269 # @note a.k.a. SymmetricDifference
5270 # @param other a Geo::OGR::Geometry object
5271 # @return a new Geo::OGR::Geometry object
5272 # @since 1.8.0
5273 #*
5274 sub SymDifference {
5275 }
5276 
5277 #** @method scalar Touches($other)
5278 # @param other a Geo::OGR::Geometry object
5279 # @return true if this geometry touches the other geometry, false otherwise
5280 #*
5281 sub Touches {
5282 }
5283 
5284 #** @method Transform($trans)
5285 # @param trans a Geo::OSR::CoordinateTransformation object
5286 #*
5287 sub Transform {
5288 }
5289 
5290 #** @method TransformTo($srs)
5291 # @param srs a Geo::OSR::SpatialReference object
5292 #*
5293 sub TransformTo {
5294 }
5295 
5296 #** @method Geo::OGR::Geometry Union($other)
5297 # @param other a Geo::OGR::Geometry object
5298 # @return a new Geo::OGR::Geometry object
5299 #*
5300 sub Union {
5301 }
5302 
5303 #** @method Geo::OGR::Geometry UnionCascaded()
5304 # @return a new Geo::OGR::Geometry object
5305 # @since 1.8.0
5306 #*
5307 sub UnionCascaded {
5308 }
5309 
5310 #** @method Value()
5311 #*
5312 sub Value {
5313 }
5314 
5315 #** @method scalar Within($other)
5316 # @param other a Geo::OGR::Geometry object
5317 # @return true if this geometry is within the other geometry, false otherwise
5318 #*
5319 sub Within {
5320 }
5321 
5322 #** @method scalar WkbSize()
5323 # @return an integer
5324 #*
5325 sub WkbSize {
5326 }
5327 
5328 #** @method Geo::OGR::Geometry new(%params)
5329 # Class method.
5330 # @param %params A named parameter, one of: WKT, WKB, HEXWKB,
5331 # HEXEWKB, GML, GeoJSON, arc, or GeometryType and optionally Points.
5332 # - \a GeometryType one the supported geometry types, see Geo::OGR::GeometryTypes.
5333 # - \a WKT a well known text string, which defines a geometry.
5334 # - \a WKB a well known binary string, which defines a geometry.
5335 # - \a HEXWKB WKB in hexadecimal.
5336 # - \a HEXEWKB PostGIS extended WKB.
5337 # - \a GML geometry written in Geographic Markup Language.
5338 # - \a GeoJSON geometry written in GeoJSON (JavaScript Object Notation for Geographic data).
5339 # - \a arc a reference to a list of values defining an arc: [CenterX,
5340 # CenterY, CenterZ, PrimaryRadius, SecondaryRadius, Rotation,
5341 # StartAngle, EndAngle, MaxAngleStepSizeDegrees] (see also Geo::OGR::Geometry::ApproximateArcAngles)
5342 # - \a Points An anonymous array as in method
5343 # Geo::OGR::Geometry::Points; Note: requires also GeometryType
5344 # parameter
5345 #
5346 # @note uses CreateGeometryFrom* functions from Geo::OGR
5347 #
5348 # @return a new Geo::OGR::Geometry object.
5349 # Usage:
5350 # \code
5351 # $g = Geo::OGR::Geometry->new(...arguments...);
5352 # \endcode
5353 #*
5354 sub new {
5355  my $pkg = shift;
5356  my ($type, $wkt, $wkb, $gml, $json, $srs, $points, $arc);
5357  my %param;
5358  if (@_ == 1 and ref($_[0]) eq 'HASH') {
5359  %param = %{$_[0]};
5360  } elsif (@_ % 2 == 0) {
5361  %param = @_;
5362  } else {
5363  ($param{GeometryType}) = @_;
5364  }
5365  $type = ($param{type} or $param{Type} or $param{GeometryType});
5366  $srs = ($param{srs} or $param{SRS});
5367  $wkt = ($param{wkt} or $param{WKT});
5368  $wkb = ($param{wkb} or $param{WKB});
5369  my $hex = ($param{hexewkb} or $param{HEXEWKB}); # PostGIS HEX EWKB
5370  my $srid;
5371  if ($hex) {
5372  # get and remove SRID
5373  $srid = substr($hex, 10, 8);
5374  substr($hex, 10, 8) = '';
5375  } else {
5376  $hex = ($param{hexwkb} or $param{HEXWKB});
5377  }
5378  if ($hex) {
5379  $wkb = '';
5380  for (my $i = 0; $i < length($hex); $i+=2) {
5381  $wkb .= chr(hex(substr($hex,$i,2)));
5382  }
5383  }
5384  $gml = ($param{gml} or $param{GML});
5385  $json = ($param{geojson} or $param{GeoJSON});
5386  $points = $param{Points};
5387  $arc = ($param{arc} or $param{Arc});
5388  my $self;
5389  if (defined $wkt) {
5390  $self = Geo::OGRc::CreateGeometryFromWkt($wkt, $srs);
5391  } elsif (defined $wkb) {
5392  $self = Geo::OGRc::CreateGeometryFromWkb($wkb, $srs);
5393  } elsif (defined $gml) {
5394  $self = Geo::OGRc::CreateGeometryFromGML($gml);
5395  } elsif (defined $json) {
5396  $self = Geo::OGRc::CreateGeometryFromJson($json);
5397  } elsif (defined $type) {
5398  confess "Unknown geometry type: '$type'." unless exists $Geo::OGR::Geometry::TYPE_STRING2INT{$type};
5399  $type = $Geo::OGR::Geometry::TYPE_STRING2INT{$type};
5400  $self = Geo::OGRc::new_Geometry($type); # flattens the type
5401  SetCoordinateDimension($self, 3) if Geo::OGR::GT_HasZ($type);
5402  } elsif (defined $arc) {
5403  $self = Geo::OGRc::ApproximateArcAngles(@$arc);
5404  } else {
5405  confess "Missing a parameter when creating a Geo::OGR::Geometry object.";
5406  }
5407  bless $self, $pkg if defined $self;
5408  $self->Points($points) if $points;
5409  return $self;
5410 }
5411 
5412 #** @class Geo::OGR::Layer
5413 # @brief A collection of similar features.
5414 #
5415 # A layer object is typically obtained with a data source object. A
5416 # layer has a data model (a schema), which is maintained in a
5417 # definition object, and a set of features, which contain data
5418 # according to the data model. The schema is typically set when the
5419 # layer is created or opened, but it may be altered somewhat with
5420 # methods Geo::OGR::Layer::CreateField,
5421 # Geo::OGR::Layer::AlterFieldDefn, and
5422 # Geo::OGR::Layer::DeleteField. Features and/or their data can be
5423 # read, inserted and deleted. Reading can be filtered. Layers can be
5424 # compared to each other with methods Clip, Erase, Identity,
5425 # Intersection, SymDifference, Union, and Update.
5426 #*
5427 package Geo::OGR::Layer;
5428 
5429 use base qw(Geo::GDAL::MajorObject Geo::OGR)
5430 
5431 #** @method AlterFieldDefn($name, %params)
5432 # @param field the name of the field to be altered.
5433 # @param params as in Geo::OGR::FieldDefn::new. Width and
5434 # Precision should be both or neither.
5435 # @note Only non-spatial fields can be altered.
5436 # @note Also the deprecated form AlterFieldDefn($field,
5437 # Geo::OGR::FieldDefn $Defn, $Flags) works.
5438 #*
5439 sub AlterFieldDefn {
5440  my $self = shift;
5441  my $field = shift;
5442  my $index;
5443  eval {
5444  $index = $self->GetFieldIndex($field);
5445  };
5446  confess "Only non-spatial fields can be altered.\n$@" if $@;
5447  if (blessed($_[0]) and $_[0]->isa('Geo::OGR::FieldDefn')) {
5448  _AlterFieldDefn($self, $index, @_);
5449  } elsif (@_ % 2 == 0) {
5450  my %params = @_;
5451  my $definition = Geo::OGR::FieldDefn->new(%params);
5452  my $flags = 0;
5453  $flags |= 1 if exists $params{Name};
5454  $flags |= 2 if exists $params{Type};
5455  $flags |= 4 if exists $params{Width} or exists $params{Precision};
5456  $flags |= 8 if exists $params{Nullable};
5457  $flags |= 16 if exists $params{Default};
5458  _AlterFieldDefn($self, $index, $definition, $flags);
5459  } else {
5460  croak "Usage: AlterFieldDefn(\$Name, \%NamedParameters)";
5461  }
5462 }
5463 
5464 #** @method list Capabilities()
5465 # Both a class and an object method.
5466 # @return a list of capabilities. The object method returns a list of
5467 # the capabilities the layer has. The class method returns a list of
5468 # all potential capabilities a layer may have. These are currently:
5469 # AlterFieldDefn, CreateField, CreateGeomField, CurveGeometries, DeleteFeature, DeleteField, FastFeatureCount, FastGetExtent, FastSetNextByIndex, FastSpatialFilter, IgnoreFields, RandomRead, RandomWrite, ReorderFields, SequentialWrite, StringsAsUTF8, and Transactions.
5470 #
5471 # Examples:
5472 # \code
5473 # @cap = Geo::OGR::Layer::Capabilities(); # the class method
5474 # @cap = $layer->Capabilities(); # the object method
5475 # \endcode
5476 #*
5477 sub Capabilities {
5478  return @CAPABILITIES if @_ == 0;
5479  my $self = shift;
5480  my @cap;
5481  for my $cap (@CAPABILITIES) {
5482  push @cap, $cap if _TestCapability($self, $CAPABILITIES{$cap});
5483  }
5484  return @cap;
5485 }
5486 
5487 #** @method Clip(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, subref callback, $callback_data)
5488 # Clip off areas that are not covered by the method layer. The schema
5489 # of the result layer can be set before calling this method, or is
5490 # initialized to to contain all fields from
5491 # this and method layer.
5492 # @param method method layer.
5493 # @param result result layer.
5494 # @param options a reference to an options hash.
5495 # @param callback [optional] a reference to a subroutine, which will
5496 # be called with parameters (number progress, string msg, callback_data)
5497 # @param callback_data [optional]
5498 #*
5499 sub Clip {
5500 }
5501 
5502 #** @method CommitTransaction()
5503 #*
5504 sub CommitTransaction {
5505 }
5506 
5507 #** @method CreateFeature($feature)
5508 # @deprecated use Geo::OGR::Layer::InsertFeature which accepts Perl
5509 # data and checks for geometry type and attribute data
5510 #
5511 # @note The feature should have the same schema as the layer.
5512 #
5513 # Inserts a feature into the layer. The given feature's id may change.
5514 # @param feature a Geo::OGR::Feature object
5515 #*
5516 sub CreateFeature {
5517 }
5518 
5519 #** @method CreateField(%params)
5520 # Create a field.
5521 # @param params as in Geo::OGR::FieldDefn::new or
5522 # Geo::OGR::GeomFieldDefn::new, plus ApproxOK (whose default is true).
5523 #*
5524 sub CreateField {
5525  my $self = shift;
5526  my %defaults = ( ApproxOK => 1,
5527  Type => '' );
5528  my %params;
5529  if (@_ == 0) {
5530  } elsif (ref($_[0]) eq 'HASH') {
5531  %params = %{$_[0]};
5532  } elsif (@_ % 2 == 0) {
5533  %params = @_;
5534  } else {
5535  ($params{Defn}) = @_;
5536  }
5537  for (keys %defaults) {
5538  $params{$_} = $defaults{$_} unless defined $params{$_};
5539  }
5540  if (blessed($params{Defn}) and $params{Defn}->isa('Geo::OGR::FieldDefn')) {
5541  $self->_CreateField($params{Defn}, $params{ApproxOK});
5542  } elsif (blessed($_[0]) and $params{Defn}->isa('Geo::OGR::GeomFieldDefn')) {
5543  $self->CreateGeomField($params{Defn}, $params{ApproxOK});
5544  } else {
5545  my $a = $params{ApproxOK};
5546  delete $params{ApproxOK};
5547  if (exists $params{GeometryType}) {
5548  $params{Type} = $params{GeometryType};
5549  delete $params{GeometryType};
5550  }
5551  if (exists $Geo::OGR::FieldDefn::TYPE_STRING2INT{$params{Type}}) {
5552  my $fd = Geo::OGR::FieldDefn->new(%params);
5553  _CreateField($self, $fd, $a);
5554  } else {
5555  my $fd = Geo::OGR::GeomFieldDefn->new(%params);
5556  CreateGeomField($self, $fd, $a);
5557  }
5558  }
5559 }
5560 
5561 #** @method DataSource()
5562 #*
5563 sub DataSource {
5564 }
5565 
5566 #** @method DeleteFeature($fid)
5567 # @param fid feature id
5568 #*
5569 sub DeleteFeature {
5570 }
5571 
5572 #** @method DeleteField($field)
5573 # Delete an existing field from a layer.
5574 # @param field name (or index) of the field which is deleted
5575 # @note Only non-spatial fields can be deleted.
5576 #*
5577 sub DeleteField {
5578  my($self, $fn) = @_;
5579  my $d = $self->GetDefn;
5580  my $index = $d->GetFieldIndex($fn);
5581  $index = $fn if $index < 0;
5582  eval {
5583  _DeleteField($self, $index);
5584  };
5585  confess "Field not found: '$fn'. Only non-spatial fields can be deleted." if $@;
5586 }
5587 
5588 #** @method Erase(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, subref callback, $callback_data)
5589 # The result layer contains features whose geometries represent areas
5590 # that are in the input layer but not in the method layer. The
5591 # features in the result layer have attributes from the input
5592 # layer. The schema of the result layer can be set by the user or, if
5593 # it is empty, is initialized to contain all fields in the input
5594 # layer.
5595 # @param method method layer.
5596 # @param result result layer.
5597 # @param options a reference to an options hash.
5598 # @param callback [optional] a reference to a subroutine, which will
5599 # be called with parameters (number progress, string msg, callback_data)
5600 # @param callback_data [optional]
5601 #*
5602 sub Erase {
5603 }
5604 
5605 #** @method ForFeatures($code, $in_place)
5606 # @note experimental, the syntax may change
5607 #
5608 # Call code for all features. This is a simple wrapper for
5609 # ResetReading and while(GetNextFeature).
5610 #
5611 # Example usage:
5612 # \code
5613 # $layer->ForFeatures(sub {my $f = shift; $self->DeleteFeature($f->FID)}); # empties the layer
5614 # \endcode
5615 #
5616 # @param code a reference to a subroutine, which is called with each
5617 # feature as an argument
5618 # @param in_place if set to true, the feature is stored back to the
5619 # layer
5620 #*
5621 sub ForFeatures {
5622  my $self = shift;
5623  my $code = shift;
5624  my $in_place = shift;
5625  $self->ResetReading;
5626  while (my $f = $self->GetNextFeature) {
5627  $code->($f);
5628  $self->SetFeature($f) if $in_place;
5629  };
5630 }
5631 
5632 #** @method ForGeometries($code, $in_place)
5633 # @note experimental, the syntax may change
5634 #
5635 # Call code for all geometries. This is a simple wrapper for
5636 # ResetReading and while(GetNextFeature).
5637 #
5638 # Example usage:
5639 # \code
5640 # my $area = 0;
5641 # $layer->ForGeometries(sub {my $g = shift; $area += $g->Area}); # computes the total area
5642 # \endcode
5643 #
5644 # @param code a reference to a subroutine, which is called with each
5645 # geometry as an argument
5646 # @param in_place if set to true, the geometry is stored back to the
5647 # layer
5648 #*
5649 sub ForGeometries {
5650  my $self = shift;
5651  my $code = shift;
5652  my $in_place = shift;
5653  $self->ResetReading;
5654  while (my $f = $self->GetNextFeature) {
5655  my $g = $f->Geometry();
5656  $code->($g);
5657  if ($in_place) {
5658  $f->Geometry($g);
5659  $self->SetFeature($f);
5660  }
5661  }
5662 }
5663 
5664 #** @method GeometryType()
5665 #*
5666 sub GeometryType {
5667  my $self = shift;
5668  my $d = $self->GetDefn;
5669  my $fd = $d->GetGeomFieldDefn(0);
5670  return $fd->Type if $fd;
5671 }
5672 
5673 #** @method Geo::OGR::DataSource GetDataSource()
5674 # @return the data source object to which this layer object belongs to.
5675 #*
5676 sub GetDataSource {
5677  my $self = shift;
5678  return $Geo::OGR::DataSource::LAYERS{$self};
5679 }
5680 
5681 #** @method Geo::OGR::FeatureDefn GetDefn()
5682 # A.k.a GetLayerDefn.
5683 # @return a Geo::OGR::FeatureDefn object.
5684 #*
5685 sub GetDefn {
5686  my $self = shift;
5687  my $defn = $self->GetLayerDefn;
5688  $DEFNS{$defn} = $self;
5689  return $defn;
5690 }
5691 
5692 #** @method list GetExtent($force = 1)
5693 # @param force compute the extent even if it is expensive
5694 # @note In scalar context returns a reference to an anonymous array
5695 # containing the extent.
5696 # @note The order of values is different from those returned by
5697 # Geo::OGR::Geometry::GetEnvelope.
5698 # @return the extent ($minx, $miny, $maxx, $maxy)
5699 # @param force
5700 # @return the extent = ($minx, $miny, $maxx, $maxy) as a listref
5701 #*
5702 sub GetExtent {
5703 }
5704 
5705 #** @method scalar GetFIDColumn()
5706 # @return the name of the underlying database column being used as the
5707 # FID column, or "" if not supported.
5708 #*
5709 sub GetFIDColumn {
5710 }
5711 
5712 #** @method Geo::OGR::Feature GetFeature($fid)
5713 # @param fid feature id
5714 # @return a new Geo::OGR::Feature object that represents the feature in the layer.
5715 #*
5716 sub GetFeature {
5717 }
5718 
5719 #** @method scalar GetFeatureCount($force = 1)
5720 # @param force
5721 # @return integer
5722 #*
5723 sub GetFeatureCount {
5724 }
5725 
5726 #** @method scalar GetFeaturesRead()
5727 # @return integer
5728 #*
5729 sub GetFeaturesRead {
5730 }
5731 
5732 #** @method hash GetFieldDefn($name)
5733 # Get the definition of a field.
5734 # @param name the name of the field.
5735 # @return the field definition object, either Geo::OGR::FieldDefn or
5736 # Geo::OGR::GeomFieldDefn.
5737 #*
5738 sub GetFieldDefn {
5739  my ($self, $name) = @_;
5740  my $d = $self->GetDefn;
5741  for (my $i = 0; $i < $d->GetFieldCount; $i++) {
5742  my $fd = $d->GetFieldDefn($i);
5743  return $fd if $fd->Name eq $name;
5744  }
5745  for (my $i = 0; $i < $d->GetGeomFieldCount; $i++) {
5746  my $fd = $d->GetGeomFieldDefn($i);
5747  return $fd if $fd->Name eq $name;
5748  }
5749  confess "No such field: '$name'.";
5750 }
5751 
5752 #** @method list GetFieldNames()
5753 # @return a list of the names of the fields in this layer. The
5754 # non-geometry field names are first in the list and then the geometry
5755 # fields.
5756 #*
5757 sub GetFieldNames {
5758  my $self = shift;
5759  my $d = $self->GetDefn;
5760  my @ret;
5761  for (my $i = 0; $i < $d->GetFieldCount; $i++) {
5762  push @ret, $d->GetFieldDefn($i)->Name();
5763  }
5764  for (my $i = 0; $i < $d->GetGeomFieldCount; $i++) {
5765  push @ret, $d->GetGeomFieldDefn($i)->Name();
5766  }
5767  return @ret;
5768 }
5769 
5770 #** @method scalar GetName()
5771 # @return the name of the layer.
5772 #*
5773 sub GetName {
5774 }
5775 
5776 #** @method Geo::OGR::Feature GetNextFeature()
5777 # @return iteratively Geo::OGR::Feature objects from the layer. The
5778 # iteration obeys the spatial and the attribute filter.
5779 #*
5780 sub GetNextFeature {
5781 }
5782 
5783 #** @method hash reference GetSchema()
5784 # @brief Get the schema of this layer.
5785 # @note The schema of a layer cannot be set with this method. If you
5786 # have a Geo::OGR::FeatureDefn object before creating the layer, use
5787 # its schema in the Geo::OGR::CreateLayer method.
5788 # @return the schema of this layer, as in Geo::OGR::FeatureDefn::Schema.
5789 #*
5790 sub GetSchema {
5791  my $self = shift;
5792  carp "Schema of a layer should not be set directly." if @_;
5793  if (@_ and @_ % 2 == 0) {
5794  my %schema = @_;
5795  if ($schema{Fields}) {
5796  for my $field (@{$schema{Fields}}) {
5797  $self->CreateField($field);
5798  }
5799  }
5800  }
5801  return $self->GetDefn->Schema;
5802 }
5803 
5804 #** @method Geo::OGR::Geometry GetSpatialFilter()
5805 # @return a new Geo::OGR::Geometry object
5806 #*
5807 sub GetSpatialFilter {
5808 }
5809 
5810 #** @method GetStyleTable()
5811 #*
5812 sub GetStyleTable {
5813 }
5814 
5815 #** @method Identity(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, subref callback, $callback_data)
5816 # The result layer contains features whose geometries represent areas
5817 # that are in the input layer. The features in the result layer have
5818 # attributes from both input and method layers. The schema of the
5819 # result layer can be set by the user or, if it is empty, is
5820 # initialized to contain all fields in input and method layers.
5821 # @param method method layer.
5822 # @param result result layer.
5823 # @param options a reference to an options hash.
5824 # @param callback [optional] a reference to a subroutine, which will
5825 # be called with parameters (number progress, string msg, callback_data)
5826 # @param callback_data [optional]
5827 #*
5828 sub Identity {
5829 }
5830 
5831 #** @method InsertFeature($feature)
5832 # Creates a new feature which has the schema of the layer and
5833 # initializes it with data from the argument. Then inserts the feature
5834 # into the layer (using CreateFeature). Uses Geo::OGR::Feature::Row or
5835 # Geo::OGR::Feature::Tuple.
5836 # @param feature a Geo::OGR::Feature object or reference to feature
5837 # data in a hash (as in Geo::OGR::Feature::Row) or in an array (as in
5838 # Geo::OGR::Feature::Tuple)
5839 #*
5840 sub InsertFeature {
5841  my $self = shift;
5842  my $feature = shift;
5843  confess "Usage: \$feature->InsertFeature(reference to a hash or array)." unless ref($feature);
5844  my $new = Geo::OGR::Feature->new($self->GetDefn);
5845  if (ref($feature) eq 'HASH') {
5846  $new->Row(%$feature);
5847  } elsif (ref($feature) eq 'ARRAY') {
5848  $new->Tuple(@$feature);
5849  } elsif (blessed($feature) and $feature->isa('Geo::OGR::Feature')) {
5850  $new->Row($feature->Row);
5851  }
5852  $self->CreateFeature($new);
5853 }
5854 
5855 #** @method Intersection(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, subref callback, $callback_data)
5856 # The result layer contains features whose geometries represent areas
5857 # that are common between features in the input layer and in the
5858 # method layer. The schema of the result layer can be set before
5859 # calling this method, or is initialized to contain all fields from
5860 # this and method layer.
5861 # @param method method layer.
5862 # @param result result layer.
5863 # @param options a reference to an options hash.
5864 # @param callback [optional] a reference to a subroutine, which will
5865 # be called with parameters (number progress, string msg, callback_data)
5866 # @param callback_data [optional]
5867 #*
5868 sub Intersection {
5869 }
5870 
5871 #** @method ReorderField()
5872 #*
5873 sub ReorderField {
5874 }
5875 
5876 #** @method ReorderFields()
5877 #*
5878 sub ReorderFields {
5879 }
5880 
5881 #** @method ResetReading()
5882 # Initialize the layer object for iterative reading.
5883 #*
5884 sub ResetReading {
5885 }
5886 
5887 #** @method RollbackTransaction()
5888 #*
5889 sub RollbackTransaction {
5890 }
5891 
5892 #** @method hash reference Row(%row)
5893 # Get and/or set the data of a feature that has the supplied feature
5894 # id (the next feature obtained with GetNextFeature is used if feature
5895 # id is not given). Calls Geo::OGR::Feature::Row.
5896 # @param row [optional] feature data
5897 # @return a reference to feature data in a hash
5898 #*
5899 sub Row {
5900  my $self = shift;
5901  my $update = @_ > 0;
5902  my %row = @_;
5903  my $feature = defined $row{FID} ? $self->GetFeature($row{FID}) : $self->GetNextFeature;
5904  return unless $feature;
5905  my $ret;
5906  if (defined wantarray) {
5907  $ret = $feature->Row(@_);
5908  } else {
5909  $feature->Row(@_);
5910  }
5911  $self->SetFeature($feature) if $update;
5912  return unless defined wantarray;
5913  return $ret;
5914 }
5915 
5916 #** @method SetAttributeFilter($filter_string)
5917 # Set or clear the attribute filter.
5918 # @param filter_string a SQL WHERE clause or undef to clear the
5919 # filter.
5920 #*
5921 sub SetAttributeFilter {
5922 }
5923 
5924 #** @method SetFeature($feature)
5925 # @note The feature should have the same schema as the layer.
5926 #
5927 # Replaces a feature in the layer based on the given feature's
5928 # id. Requires RandomWrite capability.
5929 # @param feature a Geo::OGR::Feature object
5930 #*
5931 sub SetFeature {
5932 }
5933 
5934 #** @method SetIgnoredFields(@fields)
5935 # @param fields a list of field names
5936 #*
5937 sub SetIgnoredFields {
5938 }
5939 
5940 #** @method SetNextByIndex($new_index)
5941 # @param new_index the index to which set the read cursor in the
5942 # current iteration
5943 #*
5944 sub SetNextByIndex {
5945 }
5946 
5947 #** @method SetSpatialFilter($filter)
5948 # @param filter [optional] a Geo::OGR::Geometry object. If not given,
5949 # removes the filter if there is one.
5950 #*
5951 sub SetSpatialFilter {
5952 }
5953 
5954 #** @method SetSpatialFilterRect($minx, $miny, $maxx, $maxy)
5955 # @param minx
5956 # @param miny
5957 # @param maxx
5958 # @param maxy
5959 #*
5960 sub SetSpatialFilterRect {
5961 }
5962 
5963 #** @method SetStyleTable()
5964 #*
5965 sub SetStyleTable {
5966 }
5967 
5968 #** @method Geo::OGR::Geometry SpatialFilter(@filter)
5969 # @param filter [optional] a Geo::OGR::Geometry object or a string. An
5970 # undefined value removes the filter if there is one.
5971 # @return a new Geo::OGR::Geometry object
5972 # @param filter [optional] a rectangle ($minx, $miny, $maxx, $maxy).
5973 # @return a new Geo::OGR::Geometry object
5974 #*
5975 sub SpatialFilter {
5976  my $self = shift;
5977  $self->SetSpatialFilter($_[0]) if @_ == 1;
5978  $self->SetSpatialFilterRect(@_) if @_ == 4;
5979  return unless defined wantarray;
5980  $self->GetSpatialFilter;
5981 }
5982 
5983 #** @method Geo::OSR::SpatialReference SpatialReference($name, Geo::OSR::SpatialReference sr)
5984 # @note A.k.a GetSpatialRef.
5985 # Get or set the projection of a spatial field of this layer. Gets or
5986 # sets the projection of the first field if no field name is given.
5987 # @param name [optional] a name of a spatial field in this layer.
5988 # @param sr [optional] a Geo::OSR::SpatialReference object,
5989 # which replaces the existing projection.
5990 # @return a Geo::OSR::SpatialReference object, which represents the
5991 # projection in the given spatial field.
5992 #*
5993 sub SpatialReference {
5994  my($self, $field, $sr) = @_;
5995  my $d = $self->GetDefn;
5996  my $i;
5997  if (not defined $field or (blessed($field) and $field->isa('Geo::OSR::SpatialReference'))) {
5998  $i = 0;
5999  } else {
6000  $i = $d->GetGeomFieldIndex($field);
6001  }
6002  my $d2 = $d->GetGeomFieldDefn($i);
6003  $d2->SpatialReference($sr) if defined $sr;
6004  return $d2->SpatialReference() if defined wantarray;
6005 }
6006 
6007 #** @method StartTransaction()
6008 #*
6009 sub StartTransaction {
6010 }
6011 
6012 #** @method SymDifference(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, subref callback, $callback_data)
6013 # The result layer contains features whose geometries represent areas
6014 # that are in either in the input layer or in the method layer but not
6015 # in both. The features in the result layer have attributes from both
6016 # input and method layers. For features which represent areas that are
6017 # only in the input or in the method layer the respective attributes
6018 # have undefined values. The schema of the result layer can be set by
6019 # the user or, if it is empty, is initialized to contain all fields in
6020 # the input and method layers.
6021 # @param method method layer.
6022 # @param result result layer.
6023 # @param options a reference to an options hash.
6024 # @param callback [optional] a reference to a subroutine, which will
6025 # be called with parameters (number progress, string msg, callback_data)
6026 # @param callback_data [optional]
6027 #*
6028 sub SymDifference {
6029 }
6030 
6031 #** @method SyncToDisk()
6032 #*
6033 sub SyncToDisk {
6034 }
6035 
6036 #** @method scalar TestCapability($cap)
6037 # @param cap A capability string.
6038 # @return a boolean value indicating whether the layer has the
6039 # specified capability.
6040 #*
6041 sub TestCapability {
6042  my($self, $cap) = @_;
6043  return _TestCapability($self, $CAPABILITIES{$cap});
6044 }
6045 
6046 #** @method list Tuple(@tuple)
6047 # Get and/set the data of a feature that has the supplied feature id
6048 # (the next feature obtained with GetNextFeature is used if feature id
6049 # is not given). The expected data in the tuple is: ([feature id,]
6050 # non-spatial fields, spatial fields). Calls Geo::OGR::Feature::Tuple.
6051 # @param tuple [optional] feature data
6052 # @note The schema of the tuple needs to be the same as that of the
6053 # layer.
6054 # @return a reference to feature data in an array
6055 #*
6056 sub Tuple {
6057  my $self = shift;
6058  my $FID = shift;
6059  my $feature = defined $FID ? $self->GetFeature($FID) : $self->GetNextFeature;
6060  return unless $feature;
6061  my $set = @_ > 0;
6062  unshift @_, $feature->GetFID if $set;
6063  my @ret;
6064  if (defined wantarray) {
6065  @ret = $feature->Tuple(@_);
6066  } else {
6067  $feature->Tuple(@_);
6068  }
6069  $self->SetFeature($feature) if $set;
6070  return unless defined wantarray;
6071  return @ret;
6072 }
6073 
6074 #** @method Union(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, subref callback, $callback_data)
6075 # The result layer contains features whose geometries represent areas
6076 # that are in either in the input layer or in the method layer. The
6077 # schema of the result layer can be set before calling this method, or
6078 # is initialized to contain all fields from this and method layer.
6079 # @param method method layer.
6080 # @param result result layer.
6081 # @param options a reference to an options hash.
6082 # @param callback [optional] a reference to a subroutine, which will
6083 # be called with parameters (number progress, string msg, callback_data)
6084 # @param callback_data [optional]
6085 #*
6086 sub Union {
6087 }
6088 
6089 #** @method Update(Geo::OGR::Layer method, Geo::OGR::Layer result, hashref options, subref callback, $callback_data)
6090 # The result layer contains features whose geometries represent areas
6091 # that are either in the input layer or in the method layer. The
6092 # features in the result layer have areas of the features of the
6093 # method layer or those ares of the features of the input layer that
6094 # are not covered by the method layer. The features of the result
6095 # layer get their attributes from the input layer. The schema of the
6096 # result layer can be set by the user or, if it is empty, is
6097 # initialized to contain all fields in the input layer.
6098 # @param method method layer.
6099 # @param result result layer.
6100 # @param options a reference to an options hash.
6101 # @param callback [optional] a reference to a subroutine, which will
6102 # be called with parameters (number progress, string msg, callback_data)
6103 # @param callback_data [optional]
6104 #*
6105 sub Update {
6106 }
6107 
6108 #** @class Geo::OGR::StyleTable
6109 #*
6110 package Geo::OGR::StyleTable;
6111 
6112 use base qw(Geo::OGR)
6113 
6114 #** @method AddStyle()
6115 #*
6116 sub AddStyle {
6117 }
6118 
6119 #** @method Find()
6120 #*
6121 sub Find {
6122 }
6123 
6124 #** @method GetLastStyleName()
6125 #*
6126 sub GetLastStyleName {
6127 }
6128 
6129 #** @method GetNextStyle()
6130 #*
6131 sub GetNextStyle {
6132 }
6133 
6134 #** @method LoadStyleTable()
6135 #*
6136 sub LoadStyleTable {
6137 }
6138 
6139 #** @method ResetStyleStringReading()
6140 #*
6141 sub ResetStyleStringReading {
6142 }
6143 
6144 #** @method SaveStyleTable()
6145 #*
6146 sub SaveStyleTable {
6147 }
6148 
6149 #** @method new()
6150 #*
6151 sub new {
6152  my $pkg = shift;
6153  my $self = Geo::OGRc::new_StyleTable(@_);
6154  bless $self, $pkg if defined($self);
6155 }
6156 
6157 #** @class Geo::OSR
6158 # @brief Base class for projection related classes.
6159 #*
6160 package Geo::OSR;
6161 
6162 use base qw()
6163 
6164 #** @method list AngularUnits()
6165 # Class method.
6166 # @return list of known angular units.
6167 #*
6168 sub AngularUnits {
6169  return keys %ANGULAR_UNITS;
6170 }
6171 
6172 #** @method CreateCoordinateTransformation()
6173 #*
6174 sub CreateCoordinateTransformation {
6175 }
6176 
6177 #** @method list Datums()
6178 # Class method.
6179 # @return list of known datums.
6180 #*
6181 sub Datums {
6182  return keys %DATUMS;
6183 }
6184 
6185 #** @method list GetProjectionMethodParamInfo($projection, $parameter)
6186 # Class method.
6187 # @param projection one of Geo::OSR::Projections
6188 # @param parameter one of Geo::OSR::Parameters
6189 # @return ($user_friendly_name, $type, $default_value)
6190 #*
6191 sub GetProjectionMethodParamInfo {
6192 }
6193 
6194 #** @method list GetProjectionMethodParameterList($projection)
6195 # Class method.
6196 # @param projection one of Geo::OSR::Projections
6197 # @return (arrayref parameters, $projection_name)
6198 #*
6199 sub GetProjectionMethodParameterList {
6200 }
6201 
6202 #** @method array reference GetProjectionMethods()
6203 # Class method.
6204 # @deprecated Use Geo::OSR::Projections.
6205 #
6206 # @return reference to an array of possible projection methods
6207 #*
6208 sub GetProjectionMethods {
6209 }
6210 
6211 #** @method scalar GetUserInputAsWKT($name)
6212 # Class method.
6213 # @param name the user input
6214 # @return a WKT string
6215 #*
6216 sub GetUserInputAsWKT {
6217 }
6218 
6219 #** @method scalar GetWellKnownGeogCSAsWKT($name)
6220 # Class method.
6221 # @brief Get well known geographic coordinate system as WKT
6222 # @param name a well known name
6223 # @return a WKT string
6224 #*
6225 sub GetWellKnownGeogCSAsWKT {
6226 }
6227 
6228 #** @method list LinearUnits()
6229 # Class method.
6230 # @return list of known linear units.
6231 #*
6232 sub LinearUnits {
6233  return keys %LINEAR_UNITS;
6234 }
6235 
6236 #** @method list Parameters()
6237 # Class method.
6238 # @return list of known projection parameters.
6239 #*
6240 sub Parameters {
6241  return keys %PARAMETERS;
6242 }
6243 
6244 #** @method list Projections()
6245 # Class method.
6246 # @return list of known projections.
6247 #*
6248 sub Projections {
6249  return keys %PROJECTIONS;
6250 }
6251 
6252 #** @method SRS_PM_GREENWICH()
6253 #*
6254 sub SRS_PM_GREENWICH {
6255 }
6256 
6257 #** @method SRS_WGS84_INVFLATTENING()
6258 #*
6259 sub SRS_WGS84_INVFLATTENING {
6260 }
6261 
6262 #** @method SRS_WGS84_SEMIMAJOR()
6263 #*
6264 sub SRS_WGS84_SEMIMAJOR {
6265 }
6266 
6267 #** @method SRS_WKT_WGS84()
6268 #*
6269 sub SRS_WKT_WGS84 {
6270 }
6271 
6272 #** @class Geo::OSR::CoordinateTransformation
6273 # @brief An object for transforming from one projection to another.
6274 #*
6275 package Geo::OSR::CoordinateTransformation;
6276 
6277 use base qw(Geo::OSR)
6278 
6279 #** @method array reference TransformPoint($x, $y, $z)
6280 # @param x
6281 # @param y
6282 # @param z [optional]
6283 # @return arrayref = [$x, $y, $z]
6284 #*
6285 sub TransformPoint {
6286 }
6287 
6288 #** @method TransformPoints(arrayref points)
6289 # @param points [in/out] a reference to a list of points (line string
6290 # or ring) that is modified in-place. A list of points is: ([x, y, z],
6291 # [x, y, z], ...), where z is optional. Supports also lists of line
6292 # strings and polygons.
6293 #*
6294 sub TransformPoints {
6295  my($self, $points) = @_;
6296  _TransformPoints($self, $points), return unless ref($points->[0]->[0]);
6297  for my $p (@$points) {
6298  TransformPoints($self, $p);
6299  }
6300 }
6301 1;
6302 # This file was automatically generated by SWIG (http://www.swig.org).
6303 # Version 3.0.5
6304 #
6305 # Do not make changes to this file unless you know what you are doing--modify
6306 # the SWIG interface file instead.
6307 }
6308 
6309 #** @method Geo::OSR::CoordinateTransformation new($src, $dst)
6310 # Class method.
6311 # @param src a Geo::OSR::SpatialReference object
6312 # @param dst a Geo::OSR::SpatialReference object
6313 # @return a new Geo::OSR::CoordinateTransformation object
6314 #*
6315 sub new {
6316  my $pkg = shift;
6317  my $self = Geo::OSRc::new_CoordinateTransformation(@_);
6318  bless $self, $pkg if defined($self);
6319 }
6320 
6321 #** @class Geo::OSR::SpatialReference
6322 # @brief A spatial reference system.
6323 #
6324 # <a href="http://www.gdal.org/ogr/classOGRSpatialReference.html">Documentation
6325 # of the underlying C++ class at www.gdal.org</a>
6326 #*
6327 package Geo::OSR::SpatialReference;
6328 
6329 use base qw(Geo::OSR)
6330 
6331 #** @method As()
6332 #*
6333 sub As {
6334 }
6335 
6336 #** @method AutoIdentifyEPSG()
6337 # Set EPSG authority info if possible.
6338 #*
6339 sub AutoIdentifyEPSG {
6340 }
6341 
6342 #** @method Geo::OSR::SpatialReference Clone()
6343 # Make a duplicate of this SpatialReference object.
6344 # @return a new Geo::OSR::SpatialReference object
6345 #*
6346 sub Clone {
6347 }
6348 
6349 #** @method Geo::OSR::SpatialReference CloneGeogCS()
6350 # Make a duplicate of the GEOGCS node of this SpatialReference object.
6351 # @return a new Geo::OSR::SpatialReference object
6352 #*
6353 sub CloneGeogCS {
6354 }
6355 
6356 #** @method CopyGeogCSFrom($rhs)
6357 # @param rhs Geo::OSR::SpatialReference
6358 #*
6359 sub CopyGeogCSFrom {
6360 }
6361 
6362 #** @method EPSGTreatsAsLatLong()
6363 # Returns TRUE if EPSG feels this geographic coordinate system should be treated as having lat/long coordinate ordering.
6364 #*
6365 sub EPSGTreatsAsLatLong {
6366 }
6367 
6368 #** @method EPSGTreatsAsNorthingEasting()
6369 #*
6370 sub EPSGTreatsAsNorthingEasting {
6371 }
6372 
6373 #** @method Export($format)
6374 # Export the spatial reference to a selected format.
6375 # @note a.k.a. As
6376 #
6377 # @param format One of the following. The return value is explained
6378 # after the format. Other arguments are explained in parenthesis.
6379 # - WKT (Text): Well Known Text string
6380 # - PrettyWKT: Well Known Text string nicely formatted (simplify)
6381 # - Proj4: PROJ.4 string
6382 # - PCI: a list: ($proj_string, $units, [$parms1, ...])
6383 # - USGS: a list: ($code, $zone, [$parms1, ...], $datum)
6384 # - GML (XML): GML based string (dialect)
6385 # - MapInfoCS (MICoordSys): MapInfo style co-ordinate system definition
6386 #
6387 # @note The named parameter syntax also works and is needed is those
6388 # cases when other arguments need or may be given. The format should
6389 # be given using key as, 'to' or 'format'.
6390 #
6391 # @note ExportTo* and AsText methods also exist but are not documented here.
6392 #
6393 # @return a scalar or a list depending on the export format
6394 #*
6395 sub Export {
6396  my $self = shift;
6397  my $format;
6398  $format = pop if @_ == 1;
6399  my %params = @_;
6400  $format = $params{to} unless $format;
6401  $format = $params{format} unless $format;
6402  $format = $params{as} unless $format;
6403  if ($format eq 'WKT' or $format eq 'Text') {
6404  return ExportToWkt($self);
6405  } elsif ($format eq 'PrettyWKT') {
6406  my $simplify = exists $params{simplify} ? $params{simplify} : 0;
6407  return ExportToPrettyWkt($self, $simplify);
6408  } elsif ($format eq 'Proj4') {
6409  return ExportToProj4($self);
6410  } elsif ($format eq 'PCI') {
6411  return ExportToPCI($self);
6412  } elsif ($format eq 'USGS') {
6413  return ExportToUSGS($self);
6414  } elsif ($format eq 'GML' or $format eq 'XML') {
6415  my $dialect = exists $params{dialect} ? $params{dialect} : '';
6416  return ExportToXML($self, $dialect);
6417  } elsif ($format eq 'MICoordSys' or $format eq 'MapInfoCS') {
6418  return ExportToMICoordSys();
6419  } else {
6420  confess "Unrecognized export format.";
6421  }
6422 }
6423 
6424 #** @method Fixup()
6425 #*
6426 sub Fixup {
6427 }
6428 
6429 #** @method FixupOrdering()
6430 #*
6431 sub FixupOrdering {
6432 }
6433 
6434 #** @method scalar GetAngularUnits()
6435 # @return a number
6436 #*
6437 sub GetAngularUnits {
6438 }
6439 
6440 #** @method scalar GetAttrValue($name, $child = 0)
6441 # @param name
6442 # @param child
6443 # @return string
6444 #*
6445 sub GetAttrValue {
6446 }
6447 
6448 #** @method scalar GetAuthorityCode($target_key)
6449 # @param target_key
6450 # @return string
6451 #*
6452 sub GetAuthorityCode {
6453 }
6454 
6455 #** @method scalar GetAuthorityName($target_key)
6456 # @param target_key
6457 # @return string
6458 #*
6459 sub GetAuthorityName {
6460 }
6461 
6462 #** @method GetInvFlattening()
6463 #*
6464 sub GetInvFlattening {
6465 }
6466 
6467 #** @method scalar GetLinearUnits()
6468 # @return a number
6469 #*
6470 sub GetLinearUnits {
6471 }
6472 
6473 #** @method scalar GetLinearUnitsName()
6474 # @return string
6475 #*
6476 sub GetLinearUnitsName {
6477 }
6478 
6479 #** @method scalar GetNormProjParm($name, $default_val = 0.0)
6480 # @param name
6481 # @param default_val
6482 # @return a number
6483 #*
6484 sub GetNormProjParm {
6485 }
6486 
6487 #** @method scalar GetProjParm($name, $default_val = 0.0)
6488 # @param name
6489 # @param default_val
6490 # @return a number
6491 #*
6492 sub GetProjParm {
6493 }
6494 
6495 #** @method GetSemiMajor()
6496 #*
6497 sub GetSemiMajor {
6498 }
6499 
6500 #** @method GetSemiMinor()
6501 #*
6502 sub GetSemiMinor {
6503 }
6504 
6505 #** @method GetTOWGS84()
6506 # @return array = ($p1, $p2, $p3, $p4, $p5, $p6, $p7)
6507 #*
6508 sub GetTOWGS84 {
6509 }
6510 
6511 #** @method GetUTMZone()
6512 # Get UTM zone information.
6513 # @return The UTM zone (integer). In scalar context the returned value
6514 # is negative for southern hemisphere zones. In list context returns
6515 # two values ($zone, $north), where $zone is always non-negative and
6516 # $north is true or false.
6517 #*
6518 sub GetUTMZone {
6519  my $self = shift;
6520  my $zone = _GetUTMZone($self);
6521  if (wantarray) {
6522  my $north = 1;
6523  if ($zone < 0) {
6524  $zone *= -1;
6525  $north = 0;
6526  }
6527  return ($zone, $north);
6528  } else {
6529  return $zone;
6530  }
6531 }
6532 
6533 #** @method ImportFromOzi()
6534 #*
6535 sub ImportFromOzi {
6536 }
6537 
6538 #** @method scalar IsCompound()
6539 # @return boolean
6540 #*
6541 sub IsCompound {
6543 
6544 #** @method scalar IsGeocentric()
6545 # @return boolean
6546 #*
6547 sub IsGeocentric {
6548 }
6549 
6550 #** @method scalar IsGeographic()
6551 # @return boolean
6552 #*
6553 sub IsGeographic {
6554 }
6555 
6556 #** @method scalar IsLocal()
6557 # @return boolean
6558 #*
6559 sub IsLocal {
6560 }
6561 
6562 #** @method scalar IsProjected()
6563 # @return boolean
6564 #*
6565 sub IsProjected {
6566 }
6567 
6568 #** @method scalar IsSame($rs)
6569 # @param rs a Geo::OSR::SpatialReference object
6570 # @return boolean
6571 #*
6572 sub IsSame {
6573 }
6574 
6575 #** @method scalar IsSameGeogCS($rs)
6576 # @param rs a Geo::OSR::SpatialReference object
6577 # @return boolean
6578 #*
6579 sub IsSameGeogCS {
6580 }
6581 
6582 #** @method scalar IsSameVertCS($rs)
6583 # @param rs a Geo::OSR::SpatialReference object
6584 # @return boolean
6585 #*
6586 sub IsSameVertCS {
6587 }
6588 
6589 #** @method scalar IsVertical()
6590 # @return boolean
6591 #*
6592 sub IsVertical {
6593 }
6594 
6595 #** @method MorphFromESRI()
6596 #*
6597 sub MorphFromESRI {
6598 }
6599 
6600 #** @method MorphToESRI()
6601 #*
6602 sub MorphToESRI {
6603 }
6604 
6605 #** @method Set(%params)
6606 # Set a parameter or parameters in the spatial reference object.
6607 # @param params Named parameters. Recognized keys and respective
6608 # values are the following.
6609 # - Authority: authority name (give also TargetKey, Node and Code)
6610 # - TargetKey:
6611 # - Node: partial or complete path to the target node (Node and Value together sets an attribute value)
6612 # - Code: code for value with an authority
6613 # - Value: value to be assigned to a node, a projection parameter or an object
6614 # - AngularUnits: angular units for the geographic coordinate system (give also Value) (one of Geo::OSR::LinearUnits)
6615 # - LinearUnits: linear units for the target node or the object (give also Value and optionally Node) (one of Geo::OSR::LinearUnits)
6616 # - Parameter: projection parameter to set (give also Value and Normalized) (one of Geo::OSR::Parameters)
6617 # - Normalized: set to true to indicate that the Value argument is in "normalized" form
6618 # - Name: a well known name of a geographic coordinate system (e.g. WGS84)
6619 # - GuessFrom: arbitrary text that specifies a projection ("user input")
6620 # - LOCAL_CS: name of a local coordinate system
6621 # - GeocentricCS: name of a geocentric coordinate system
6622 # - VerticalCS: name of a vertical coordinate system (give also Datum and optionally VertDatumType [default is 2005])
6623 # - Datum: a known (OGC or EPSG) name (or(?) one of Geo::OSR::Datums)
6624 # - 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
6625 # - Parameters: a reference to a list containing the coordinate system or projection parameters
6626 # - Zone: zone for setting up UTM or State Plane coordinate systems (State Plane zone in USGS numbering scheme)
6627 # - North: set false for southern hemisphere
6628 # - NAD83: set false if the NAD27 zone definition should be used instead of NAD83
6629 # - UnitName: to override the legal definition for a zone
6630 # - UnitConversionFactor: to override the legal definition for a zone
6631 # - Spheroid: user visible name
6632 # - HorizontalCS: Horizontal coordinate system name
6633 # - Projection: name of a projection, one of Geo::OSR::Projections (give also optionally Parameters and Variant)
6634 #
6635 # @note Numerous Set* methods also exist but are not documented here.
6636 #*
6637 sub Set {
6638  my($self, %params) = @_;
6639  if (exists $params{Authority} and exists $params{TargetKey} and exists $params{Node} and exists $params{Code}) {
6640  SetAuthority($self, $params{TargetKey}, $params{Authority}, $params{Code});
6641  } elsif (exists $params{Node} and exists $params{Value}) {
6642  SetAttrValue($self, $params{Node}, $params{Value});
6643  } elsif (exists $params{AngularUnits} and exists $params{Value}) {
6644  SetAngularUnits($self, $params{AngularUnits}, $params{Value});
6645  } elsif (exists $params{LinearUnits} and exists $params{Node} and exists $params{Value}) {
6646  SetTargetLinearUnits($self, $params{Node}, $params{LinearUnits}, $params{Value});
6647  } elsif (exists $params{LinearUnits} and exists $params{Value}) {
6648  SetLinearUnitsAndUpdateParameters($self, $params{LinearUnits}, $params{Value});
6649  } elsif ($params{Parameter} and exists $params{Value}) {
6650  croak "Unknown projection parameter '$params{Parameter}'." unless exists $Geo::OSR::PARAMETERS{$params{Parameter}};
6651  $params{Normalized} ?
6652  SetNormProjParm($self, $params{Parameter}, $params{Value}) :
6653  SetProjParm($self, $params{Parameter}, $params{Value});
6654  } elsif ($params{Name}) {
6655  SetWellKnownGeogCS($self, $params{Name});
6656  } elsif ($params{GuessFrom}) {
6657  SetFromUserInput($self, $params{GuessFrom});
6658  } elsif ($params{LOCAL_CS}) {
6659  SetLocalCS($self, $params{LOCAL_CS});
6660  } elsif ($params{GeocentricCS}) {
6661  SetGeocCS($self, $params{GeocentricCS});
6662  } elsif ($params{VerticalCS} and $params{Datum}) {
6663  my $type = $params{VertDatumType} || 2005;
6664  SetVertCS($self, $params{VerticalCS}, $params{Datum}, $type);
6665  } elsif ($params{CoordinateSystem}) {
6666  my @parameters = ();
6667  @parameters = @{$params{Parameters}} if ref($params{Parameters});
6668  if ($params{CoordinateSystem} eq 'State Plane' and exists $params{Zone}) {
6669  my $NAD83 = exists $params{NAD83} ? $params{NAD83} : 1;
6670  my $name = exists $params{UnitName} ? $params{UnitName} : undef;
6671  my $c = exists $params{UnitConversionFactor} ? $params{UnitConversionFactor} : 0.0;
6672  SetStatePlane($self, $params{Zone}, $NAD83, $name, $c);
6673  } elsif ($params{CoordinateSystem} eq 'UTM' and exists $params{Zone} and exists $params{North}) {
6674  my $north = exists $params{North} ? $params{North} : 1;
6675  SetUTM($self, $params{Zone}, $north);
6676  } elsif ($params{CoordinateSystem} eq 'WGS') {
6677  SetTOWGS84($self, @parameters);
6678  } elsif ($params{CoordinateSystem} and $params{Datum} and $params{Spheroid}) {
6679  SetGeogCS($self, $params{CoordinateSystem}, $params{Datum}, $params{Spheroid}, @parameters);
6680  } elsif ($params{CoordinateSystem} and $params{HorizontalCS} and $params{VerticalCS}) {
6681  SetCompoundCS($self, $params{CoordinateSystem}, $params{HorizontalCS}, $params{VerticalCS});
6682  } else {
6683  SetProjCS($self, $params{CoordinateSystem});
6684  }
6685  } elsif ($params{Projection}) {
6686  confess "Unknown projection." unless exists $Geo::OSR::PROJECTIONS{$params{Projection}};
6687  my @parameters = ();
6688  @parameters = @{$params{Parameters}} if ref($params{Parameters});
6689  if ($params{Projection} eq 'Albers_Conic_Equal_Area') {
6690  SetACEA($self, @parameters);
6691  } elsif ($params{Projection} eq 'Azimuthal_Equidistant') {
6692  SetAE($self, @parameters);
6693  } elsif ($params{Projection} eq 'Bonne') {
6694  SetBonne($self, @parameters);
6695  } elsif ($params{Projection} eq 'Cylindrical_Equal_Area') {
6696  SetCEA($self, @parameters);
6697  } elsif ($params{Projection} eq 'Cassini_Soldner') {
6698  SetCS($self, @parameters);
6699  } elsif ($params{Projection} eq 'Equidistant_Conic') {
6700  SetEC($self, @parameters);
6701  # Eckert_I, Eckert_II, Eckert_III, Eckert_V ?
6702  } elsif ($params{Projection} eq 'Eckert_IV') {
6703  SetEckertIV($self, @parameters);
6704  } elsif ($params{Projection} eq 'Eckert_VI') {
6705  SetEckertVI($self, @parameters);
6706  } elsif ($params{Projection} eq 'Equirectangular') {
6707  @parameters == 4 ?
6708  SetEquirectangular($self, @parameters) :
6709  SetEquirectangular2($self, @parameters);
6710  } elsif ($params{Projection} eq 'Gauss_Schreiber_Transverse_Mercator') {
6711  SetGaussSchreiberTMercator($self, @parameters);
6712  } elsif ($params{Projection} eq 'Gall_Stereographic') {
6713  SetGS($self, @parameters);
6714  } elsif ($params{Projection} eq 'Goode_Homolosine') {
6715  SetGH($self, @parameters);
6716  } elsif ($params{Projection} eq 'Interrupted_Goode_Homolosine') {
6717  SetIGH($self);
6718  } elsif ($params{Projection} eq 'Geostationary_Satellite') {
6719  SetGEOS($self, @parameters);
6720  } elsif ($params{Projection} eq 'Gnomonic') {
6721  SetGnomonic($self, @parameters);
6722  } elsif ($params{Projection} eq 'Hotine_Oblique_Mercator') {
6723  # Hotine_Oblique_Mercator_Azimuth_Center ?
6724  SetHOM($self, @parameters);
6725  } elsif ($params{Projection} eq 'Hotine_Oblique_Mercator_Two_Point_Natural_Origin') {
6726  SetHOM2PNO($self, @parameters);
6727  } elsif ($params{Projection} eq 'Krovak') {
6728  SetKrovak($self, @parameters);
6729  } elsif ($params{Projection} eq 'Lambert_Azimuthal_Equal_Area') {
6730  SetLAEA($self, @parameters);
6731  } elsif ($params{Projection} eq 'Lambert_Conformal_Conic_2SP') {
6732  SetLCC($self, @parameters);
6733  } elsif ($params{Projection} eq 'Lambert_Conformal_Conic_1SP') {
6734  SetLCC1SP($self, @parameters);
6735  } elsif ($params{Projection} eq 'Lambert_Conformal_Conic_2SP_Belgium') {
6736  SetLCCB($self, @parameters);
6737  } elsif ($params{Projection} eq 'miller_cylindrical') {
6738  SetMC($self, @parameters);
6739  } elsif ($params{Projection} =~ /^Mercator/) {
6740  # Mercator_1SP, Mercator_2SP, Mercator_Auxiliary_Sphere ?
6741  # variant is in Variant (or Name)
6742  SetMercator($self, @parameters);
6743  } elsif ($params{Projection} eq 'Mollweide') {
6744  SetMollweide($self, @parameters);
6745  } elsif ($params{Projection} eq 'New_Zealand_Map_Grid') {
6746  SetNZMG($self, @parameters);
6747  } elsif ($params{Projection} eq 'Oblique_Stereographic') {
6748  SetOS($self, @parameters);
6749  } elsif ($params{Projection} eq 'Orthographic') {
6750  SetOrthographic($self, @parameters);
6751  } elsif ($params{Projection} eq 'Polyconic') {
6752  SetPolyconic($self, @parameters);
6753  } elsif ($params{Projection} eq 'Polar_Stereographic') {
6754  SetPS($self, @parameters);
6755  } elsif ($params{Projection} eq 'Robinson') {
6756  SetRobinson($self, @parameters);
6757  } elsif ($params{Projection} eq 'Sinusoidal') {
6758  SetSinusoidal($self, @parameters);
6759  } elsif ($params{Projection} eq 'Stereographic') {
6760  SetStereographic($self, @parameters);
6761  } elsif ($params{Projection} eq 'Swiss_Oblique_Cylindrical') {
6762  SetSOC($self, @parameters);
6763  } elsif ($params{Projection} eq 'Transverse_Mercator_South_Orientated') {
6764  SetTMSO($self, @parameters);
6765  } elsif ($params{Projection} =~ /^Transverse_Mercator/) {
6766  my($variant) = $params{Projection} =~ /^Transverse_Mercator_(\w+)/;
6767  $variant = $params{Variant} unless $variant;
6768  $variant = $params{Name} unless $variant;
6769  $variant ?
6770  SetTMVariant($self, $variant, @parameters) :
6771  SetTM($self, @parameters);
6772  } elsif ($params{Projection} eq 'Tunisia_Mining_Grid') {
6773  SetTMG($self, @parameters);
6774  } elsif ($params{Projection} eq 'VanDerGrinten') {
6775  SetVDG($self, @parameters);
6776  } else {
6777  # Aitoff, Craster_Parabolic, International_Map_of_the_World_Polyconic, Laborde_Oblique_Mercator
6778  # Loximuthal, Miller_Cylindrical, Quadrilateralized_Spherical_Cube, Quartic_Authalic, Two_Point_Equidistant
6779  # Wagner_I, Wagner_II, Wagner_III, Wagner_IV, Wagner_V, Wagner_VI, Wagner_VII
6780  # Winkel_I, Winkel_II, Winkel_Tripel
6781  # ?
6782  SetProjection($self, $params{Projection});
6783  }
6784  } else {
6785  confess "Not enough information for a spatial reference object.";
6786  }
6787 }
6788 
6789 #** @method StripCTParms()
6790 #*
6791 sub StripCTParms {
6792 }
6793 
6794 #** @method Validate()
6795 #*
6796 sub Validate {
6797 }
6798 
6799 #** @method Geo::OSR::SpatialReference new(%params)
6800 # Class method.
6801 # Create a new spatial reference object using a named parameter. This
6802 # constructor recognizes the following key words (alternative in
6803 # parenthesis): WKT (Text), Proj4, ESRI, EPSG, EPSGA, PCI, USGS, GML
6804 # (XML), URL, ERMapper (ERM), MapInfoCS (MICoordSys). The value
6805 # depends on the key.
6806 # - WKT: Well Known Text string
6807 # - Proj4: PROJ.4 string
6808 # - ESRI: reference to a list of strings (contents of ESRI .prj file)
6809 # - EPSG: EPSG code number
6810 # - EPSGA: EPSG code number (the resulting CS will have EPSG preferred axis ordering)
6811 # - PCI: listref: [PCI_projection_string, Grid_units_code, [17 cs parameters]]
6812 # - USGS: listref: [Projection_system_code, Zone, [15 cs parameters], Datum_code, Format_flag]
6813 # - GML: GML string
6814 # - URL: URL for downloading the spatial reference from
6815 # - ERMapper: listref: [Projection, Datum, Units]
6816 # - MapInfoCS: MapInfo style co-ordinate system definition
6817 #
6818 # For more information, consult the import methods in <a href="http://www.gdal.org/ogr/classOGRSpatialReference.html">OGR documentation</a>.
6819 #
6820 # @note ImportFrom* methods also exist but are not documented here.
6821 #
6822 # Usage:
6823 # \code
6824 # $sr = Geo::OSR::SpatialReference->new( key => value );
6825 # \endcode
6826 # @return a new Geo::OSR::SpatialReference object
6827 #*
6828 sub new {
6829  my $pkg = shift;
6830  my %param = @_;
6831  my $self = Geo::OSRc::new_SpatialReference();
6832  if ($param{WKT}) {
6833  ImportFromWkt($self, $param{WKT});
6834  } elsif ($param{Text}) {
6835  ImportFromWkt($self, $param{Text});
6836  } elsif ($param{Proj4}) {
6837  ImportFromProj4($self, $param{Proj4});
6838  } elsif ($param{ESRI}) {
6839  ImportFromESRI($self, @{$param{ESRI}});
6840  } elsif ($param{EPSG}) {
6841  ImportFromEPSG($self, $param{EPSG});
6842  } elsif ($param{EPSGA}) {
6843  ImportFromEPSGA($self, $param{EPSGA});
6844  } elsif ($param{PCI}) {
6845  ImportFromPCI($self, @{$param{PCI}});
6846  } elsif ($param{USGS}) {
6847  ImportFromUSGS($self, @{$param{USGS}});
6848  } elsif ($param{XML}) {
6849  ImportFromXML($self, $param{XML});
6850  } elsif ($param{GML}) {
6851  ImportFromGML($self, $param{GML});
6852  } elsif ($param{URL}) {
6853  ImportFromUrl($self, $param{URL});
6854  } elsif ($param{ERMapper}) {
6855  ImportFromERM($self, @{$param{ERMapper}});
6856  } elsif ($param{ERM}) {
6857  ImportFromERM($self, @{$param{ERM}});
6858  } elsif ($param{MICoordSys}) {
6859  ImportFromMICoordSys($self, $param{MICoordSys});
6860  } elsif ($param{MapInfoCS}) {
6861  ImportFromMICoordSys($self, $param{MapInfoCS});
6862  } elsif ($param{WGS}) {
6863  eval {
6864  SetWellKnownGeogCS($self, 'WGS'.$param{WGS});
6865  };
6866  confess "$@" if $@;
6867  } else {
6868  confess "Unrecognized/missing parameters: @_.";
6869  }
6870  bless $self, $pkg if defined $self;
6871 }
6872 
public hash reference Row(hash row)
public list NodeData(scalar node)
public list Children(scalar node)
A definition of a non-spatial attribute.
Definition: all.pm:7754
public method new(array coeffs)
public Geo::OGR::Geometry new(hash params)
public array reference ParseXMLString(scalar XML)
public Geo::GDAL::Dataset OpenShared(scalar name, scalar access= 'ReadOnly')
public Geo::OGR::Driver GetDriver(scalar name)
public scalar NodeType(scalar type)
public method AddGeometry(scalar other)
public Geo::OGR::FieldDefn new(hash params)
Create a new field definition.
public Geo::OSR::SpatialReference new(hash params)
public scalar GeometryType()
public Geo::OGR::DataSource OpenShared(scalar name, scalar update=0)
public method SetCoordinateDimension(scalar dimension)
public Geo::OGR::DataSource Open(scalar name, scalar update=0)
public Geo::OGR::GeomFieldDefn new(hash params)
Create a new spatial field definition.
Spatial data.
Definition: all.pm:8514
public Geo::GDAL::Dataset Open(scalar name, scalar access= 'ReadOnly')
public list Child(scalar node, scalar i)
public Geo::OGR::Feature new(hash schema)
GDAL utility functions and a root class for raster classes.
Definition: all.pm:14
OGR utility functions.
Definition: all.pm:5495
public array reference Points(arrayref points)
An object, which holds meta data.
Definition: all.pm:4311
public scalar GetDataTypeSize(scalar DataType)
Base class for projection related classes.
Definition: all.pm:12076
A spatial reference system.
Definition: all.pm:12476
public scalar PackCharacter(scalar DataType)
public scalar Name(scalar name)
An array of affine transformation coefficients.
Definition: all.pm:4180
A collection of non-spatial and spatial attributes.
Definition: all.pm:6542
A definition of a spatial attribute.
Definition: all.pm:8224