File Coverage

blib/lib/Geo/GDAL/FFI/Layer.pm
Criterion Covered Total %
statement 54 100 54.0
branch 7 30 23.3
condition 3 12 25.0
subroutine 13 22 59.0
pod 8 13 61.5
total 85 177 48.0


line stmt bran cond sub pod time code
1             package Geo::GDAL::FFI::Layer;
2 5     5   70 use v5.10;
  5         22  
3 5     5   28 use strict;
  5         11  
  5         122  
4 5     5   27 use warnings;
  5         11  
  5         115  
5 5     5   25 use Carp;
  5         9  
  5         331  
6 5     5   49 use base 'Geo::GDAL::FFI::Object';
  5         20  
  5         4316  
7              
8             our $VERSION = 0.0700;
9              
10             sub DESTROY {
11 5     5   15 my $self = shift;
12 5         105 Geo::GDAL::FFI::OGR_L_SyncToDisk($$self);
13             #say STDERR "delete parent $parent{$$self}";
14 5         18 Geo::GDAL::FFI::_deregister_parent_ref ($$self);
15             #say STDERR "destroy $self";
16             }
17              
18             sub GetParentDataset {
19 0     0 0 0 my ($self) = @_;
20 0         0 return Geo::GDAL::FFI::_get_parent_ref ($$self);
21             }
22              
23             sub GetDefn {
24 4     4 1 28 my $self = shift;
25 4         42 my $d = Geo::GDAL::FFI::OGR_L_GetLayerDefn($$self);
26 4         42 return bless \$d, 'Geo::GDAL::FFI::FeatureDefn';
27             }
28              
29             sub CreateField {
30 2     2 0 16 my $self = shift;
31 2         5 my $def = shift;
32 2 100 33     20 unless (ref $def) {
33             # name => type calling syntax
34 1         3 my $name = $def;
35 1         1 my $type = shift;
36 1         12 $def = Geo::GDAL::FFI::FieldDefn->new({Name => $name, Type => $type})
37             } elsif (ref $def eq 'HASH') {
38             $def = Geo::GDAL::FFI::FieldDefn->new($def)
39             }
40 2   50     14 my $approx_ok = shift // 1;
41 2         27 my $e = Geo::GDAL::FFI::OGR_L_CreateField($$self, $$def, $approx_ok);
42 2 50       11 return unless $e;
43 0         0 confess Geo::GDAL::FFI::error_msg({OGRError => $e});
44             }
45              
46             sub CreateGeomField {
47 1     1 0 5 my $self = shift;
48 1         3 my $def = shift;
49 1 50 0     3 unless (ref $def) {
50             # name => type calling syntax
51 1         2 my $name = $def;
52 1         3 my $type = shift;
53 1         9 $def = Geo::GDAL::FFI::GeomFieldDefn->new({Name => $name, Type => $type});
54             } elsif (ref $def eq 'HASH') {
55             $def = Geo::GDAL::FFI::GeomFieldDefn->new($def)
56             }
57 1   50     7 my $approx_ok = shift // 1;
58 1         15 my $e = Geo::GDAL::FFI::OGR_L_CreateGeomField($$self, $$def, $approx_ok);
59 1 50       8 return unless $e;
60 0         0 confess Geo::GDAL::FFI::error_msg({OGRError => $e});
61             }
62              
63             sub GetSpatialRef {
64 0     0 0 0 my ($self) = @_;
65 0         0 my $sr = Geo::GDAL::FFI::OGR_L_GetSpatialRef($$self);
66 0 0       0 return unless $sr;
67 0         0 return bless \$sr, 'Geo::GDAL::FFI::SpatialReference';
68             }
69              
70             sub ResetReading {
71 0     0 1 0 my $self = shift;
72 0         0 Geo::GDAL::FFI::OGR_L_ResetReading($$self);
73             }
74              
75             sub GetNextFeature {
76 0     0 1 0 my $self = shift;
77 0         0 my $f = Geo::GDAL::FFI::OGR_L_GetNextFeature($$self);
78 0 0       0 return unless $f;
79 0         0 return bless \$f, 'Geo::GDAL::FFI::Feature';
80             }
81              
82             sub GetFeature {
83 1     1 1 327 my ($self, $fid) = @_;
84 1         10 my $f = Geo::GDAL::FFI::OGR_L_GetFeature($$self, $fid);
85 1 50       5 confess unless $f;
86 1         6 return bless \$f, 'Geo::GDAL::FFI::Feature';
87             }
88              
89             sub SetFeature {
90 0     0 1 0 my ($self, $f) = @_;
91 0         0 Geo::GDAL::FFI::OGR_L_SetFeature($$self, $$f);
92             }
93              
94             sub CreateFeature {
95 3     3 1 15 my ($self, $f) = @_;
96 3         179 my $e = Geo::GDAL::FFI::OGR_L_CreateFeature($$self, $$f);
97 3 50       17 return $f unless $e;
98             }
99              
100             sub DeleteFeature {
101 0     0 1 0 my ($self, $fid) = @_;
102 0         0 my $e = Geo::GDAL::FFI::OGR_L_DeleteFeature($$self, $fid);
103 0 0       0 return unless $e;
104 0         0 confess Geo::GDAL::FFI::error_msg({OGRError => $e});
105             }
106              
107             __PACKAGE__->_make_overlay_methods();
108              
109             sub _make_overlay_methods {
110 5     5   14 my ($pkg) = @_;
111 5         16 my @methods = (qw /
112             Intersection Union SymDifference
113             Identity Update Clip Erase
114             /);
115            
116 5     5   37 no strict 'refs';
  5         11  
  5         2186  
117 5         13 foreach my $method_name (@methods) {
118 35         169 *{$pkg . '::' . $method_name} =
119             sub {
120 0     0   0 my ($self, $method, $args) = @_;
121 0 0       0 confess "Method layer missing." unless $method;
122 0   0     0 $args //= {};
123 0         0 my $result = $args->{Result};
124 0 0       0 unless ($result) {
125 0         0 my $schema = {
126             GeometryType => 'Unknown'
127             };
128 0         0 $result = Geo::GDAL::FFI::GetDriver('Memory')->Create->CreateLayer($schema);
129             }
130 0         0 my $o = 0;
131 0         0 for my $key (keys %{$args->{Options}}) {
  0         0  
132 0         0 $o = Geo::GDAL::FFI::CSLAddString($o, "$key=$args->{Options}{$key}");
133             }
134 0         0 my $p = 0;
135 0 0       0 $p = FFI::Platypus->new->closure($args->{Progress}) if $args->{Progress};
136 0         0 my $e = &{'Geo::GDAL::FFI::OGR_L_'.$method_name} ($$self, $$method, $$result, $o, $p, $args->{ProgressData});
  0         0  
137 0         0 Geo::GDAL::FFI::CSLDestroy($o);
138 0 0       0 return $result unless $e;
139 0         0 confess Geo::GDAL::FFI::error_msg({OGRError => $e});
140 35         168 };
141             }
142              
143 5         16 return;
144             }
145              
146             sub GetExtent {
147 0     0 1   my ($self, $force) = @_;
148 0           my $extent = [0,0,0,0];
149 0 0         $force = $force ? \1 : \0; # ensure $force is a ref
150 0           my $e = Geo::GDAL::FFI::OGR_L_GetExtent ($$self, $extent, $force);
151 0 0         return $extent unless $e;
152 0           confess Geo::GDAL::FFI::error_msg({OGRError => $e});
153             }
154              
155             sub GetName {
156 0     0 0   my ($self) = @_;
157 0           return $self->GetDefn->GetName;
158             }
159              
160             1;
161              
162             =pod
163              
164             =encoding UTF-8
165              
166             =head1 NAME
167              
168             Geo::GDAL::FFI::Layer - A collection of vector features in GDAL
169              
170             =head1 SYNOPSIS
171              
172             =head1 DESCRIPTION
173              
174             A set of (vector) features having a same schema (the same Defn
175             object). Obtain a layer object by the CreateLayer or GetLayer method
176             of a vector dataset object.
177              
178             =head1 METHODS
179              
180             =head2 GetDefn
181              
182             my $defn = $layer->GetDefn;
183              
184             Returns the FeatureDefn object for this layer.
185              
186             =head2 ResetReading
187              
188             $layer->ResetReading;
189              
190             =head2 GetNextFeature
191              
192             my $feature = $layer->GetNextFeature;
193              
194             =head2 GetFeature
195              
196             my $feature = $layer->GetFeature($fid);
197              
198             =head2 SetFeature
199              
200             $layer->SetFeature($feature);
201              
202             =head2 CreateFeature
203              
204             $layer->CreateFeature($feature);
205              
206             =head2 DeleteFeature
207              
208             $layer->DeleteFeature($fid);
209            
210             =head2 GetExtent
211             $layer->GetExtent();
212             $layer->GetExtent(1);
213              
214             Returns an array ref with [minx, miny, maxx, maxy].
215             Argument is a boolean to force calculation even
216             if it is expensive.
217              
218             =head2 Intersection, Union, SymDifference, Identity, Update, Clip, Erase
219              
220             $result = $layer->($method, $args);
221              
222             Runs the algorithm between layer and method layer. Named
223             arguments are the following.
224              
225             =over 4
226              
227             =item C
228              
229             Optional, allows the user to define the result layer.
230              
231             =item C
232              
233             Optional, allows the user to define the options (see GDAL docs).
234              
235             =item C
236              
237             Optional, the progress indicator callback.
238              
239             =item C
240              
241             Optional, data for the progress callback.
242              
243             =back
244              
245             =head1 LICENSE
246              
247             This software is released under the Artistic License. See
248             L.
249              
250             =head1 AUTHOR
251              
252             Ari Jolma - Ari.Jolma at gmail.com
253              
254             =head1 SEE ALSO
255              
256             L
257              
258             L, L, L
259              
260             =cut
261              
262             __END__;