File Coverage

blib/lib/Rinchi/CIGIPP/EnvironmentalRegionControl.pm
Criterion Covered Total %
statement 94 143 65.7
branch 26 62 41.9
condition 10 30 33.3
subroutine 21 23 91.3
pod 19 19 100.0
total 170 277 61.3


line stmt bran cond sub pod time code
1             #
2             # Rinchi Common Image Generator Interface for Perl
3             # Class Identifier: f78ad044-200e-11de-bdab-001c25551abc
4             # Author: Brian M. Ames
5             #
6              
7             package Rinchi::CIGIPP::EnvironmentalRegionControl;
8              
9 1     1   26 use 5.006;
  1         4  
  1         43  
10 1     1   8 use strict;
  1         1  
  1         38  
11 1     1   6 use warnings;
  1         1  
  1         29  
12 1     1   4 use Carp;
  1         1  
  1         5367  
13              
14             require Exporter;
15              
16             our @ISA = qw(Exporter);
17              
18             # Items to export into callers namespace by default. Note: do not export
19             # names by default without a very good reason. Use EXPORT_OK instead.
20             # Do not simply export all your public functions/methods/constants.
21              
22             # This allows declaration use Rinchi::CIGI::AtmosphereControl ':all';
23             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
24             # will save memory.
25             our %EXPORT_TAGS = ( 'all' => [ qw(
26            
27             ) ] );
28              
29             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
30              
31             our @EXPORT = qw(
32            
33             );
34              
35             our $VERSION = '0.02';
36              
37             # Preloaded methods go here.
38              
39             =head1 NAME
40              
41             Rinchi::CIGIPP::EnvironmentalRegionControl - Perl extension for the Common
42             Image Generator Interface - Environmental Region Control data packet.
43             data packet.
44             =head1 SYNOPSIS
45              
46             use Rinchi::CIGIPP::EnvironmentalRegionControl;
47             my $env_ctl = Rinchi::CIGIPP::EnvironmentalRegionControl->new();
48              
49             $packet_type = $env_ctl->packet_type();
50             $packet_size = $env_ctl->packet_size();
51             $region_ident = $env_ctl->region_ident(20814);
52             $merge_terrestrial_surface_conditions = $env_ctl->merge_terrestrial_surface_conditions(Rinchi::CIGIPP->Merge);
53             $merge_maritime_surface_conditions = $env_ctl->merge_maritime_surface_conditions(Rinchi::CIGIPP->UseLast);
54             $merge_aerosol_concentrations = $env_ctl->merge_aerosol_concentrations(Rinchi::CIGIPP->Merge);
55             $merge_weather_properties = $env_ctl->merge_weather_properties(Rinchi::CIGIPP->UseLast);
56             $region_state = $env_ctl->region_state(Rinchi::CIGIPP->Active);
57             $latitude = $env_ctl->latitude(59.996);
58             $longitude = $env_ctl->longitude(81.934);
59             $size_x = $env_ctl->size_x(35.271);
60             $size_y = $env_ctl->size_y(24.1);
61             $corner_radius = $env_ctl->corner_radius(47.747);
62             $rotation = $env_ctl->rotation(71.893);
63             $transition_perimeter = $env_ctl->transition_perimeter(3.385);
64              
65             =head1 DESCRIPTION
66              
67             The Environmental Region Control packet is used to define an area over which
68             the atmospheric conditions and maritime and terrestrial surface conditions can
69             be specified. The shape of the region is a rounded rectangle.
70              
71             Up to 256 weather layers may be defined within a region. Weather layers can be
72             created and manipulated with the Weather Control packet. One set of maritime
73             and/or terrestrial surface condition attributes may be defined per region.
74              
75             The Host is responsible for updating the position and shape of each region. The
76             IG does not automatically manipulate regions because of wind activity or any
77             other internal or external forces.
78              
79             The center of the region is defined by the Latitude and Longitude attributes.
80             The origin of the region's local coordinate system is at this point. The Size X
81             and Size Y attributes determine the length of the rounded rectangle along its X
82             and Y axes.
83              
84             The "roundness" of the corners is determined by the Corner Radius attribute.
85             Setting this radius to zero (0) will create a rectangle. Setting the value
86             equal to one-half that of Size X and Size Y when both are equal will create a
87             circle. The corner radius must be less than or equal to one half of the smaller
88             of Size X or Size Y.
89              
90             The Rotation attribute specifies an angle of rotation (clockwise) about the Z
91             axis of the local NED coordinate system.
92              
93             =head2 EXPORT
94              
95             None by default.
96              
97             #==============================================================================
98              
99             =item new $env_ctl = Rinchi::CIGIPP::EnvironmentalRegionControl->new()
100              
101             Constructor for Rinchi::EnvironmentalRegionControl.
102              
103             =cut
104              
105             sub new {
106 1     1 1 208 my $class = shift;
107 1   33     7 $class = ref($class) || $class;
108              
109 1         27 my $self = {
110             '_Buffer' => '',
111             '_ClassIdent' => 'f78ad044-200e-11de-bdab-001c25551abc',
112             '_Pack' => 'CCSCCSddfffffI',
113             '_Swap1' => 'CCvCCvVVVVVVVVVV',
114             '_Swap2' => 'CCnCCnNNNNNNNNNN',
115             'packetType' => 11,
116             'packetSize' => 48,
117             'regionIdent' => 0,
118             '_bitfields1' => 0, # Includes bitfields unused17, mergeTerrestrialSurfaceConditions, mergeMaritimeSurfaceConditions, mergeAerosolConcentrations, mergeWeatherProperties, and regionState.
119             'mergeTerrestrialSurfaceConditions' => 0,
120             'mergeMaritimeSurfaceConditions' => 0,
121             'mergeAerosolConcentrations' => 0,
122             'mergeWeatherProperties' => 0,
123             'regionState' => 0,
124             '_unused18' => 0,
125             '_unused19' => 0,
126             'latitude' => 0,
127             'longitude' => 0,
128             'sizeX' => 0,
129             'sizeY' => 0,
130             'cornerRadius' => 0,
131             'rotation' => 0,
132             'transitionPerimeter' => 0,
133             '_unused20' => 0,
134             };
135              
136 1 50       5 if (@_) {
137 0 0       0 if (ref($_[0]) eq 'ARRAY') {
    0          
138 0         0 $self->{'_Buffer'} = $_[0][0];
139             } elsif (ref($_[0]) eq 'HASH') {
140 0         0 foreach my $attr (keys %{$_[0]}) {
  0         0  
141 0 0       0 $self->{"_$attr"} = $_[0]->{$attr} unless ($attr =~ /^_/);
142             }
143             }
144             }
145              
146 1         4 bless($self,$class);
147 1         3 return $self;
148             }
149              
150             #==============================================================================
151              
152             =item sub packet_type()
153              
154             $value = $env_ctl->packet_type();
155              
156             Data Packet Identifier.
157              
158             This attribute identifies this data packet as the Environmental Region Control
159             packet. The value of this attribute must be 11.
160              
161             =cut
162              
163             sub packet_type() {
164 1     1 1 8 my ($self) = @_;
165              
166 1         8 return $self->{'packetType'};
167             }
168              
169             #==============================================================================
170              
171             =item sub packet_size()
172              
173             $value = $env_ctl->packet_size();
174              
175             Data Packet Size.
176              
177             This attribute indicates the number of bytes in this data packet. The value of
178             this attribute must be 48.
179              
180             =cut
181              
182             sub packet_size() {
183 1     1 1 6 my ($self) = @_;
184              
185 1         3 return $self->{'packetSize'};
186             }
187              
188             #==============================================================================
189              
190             =item sub region_ident([$newValue])
191              
192             $value = $env_ctl->region_ident($newValue);
193              
194             Region ID.
195              
196             This attribute specifies the environmental region to which the data in this
197             packet will be applied.
198              
199             =cut
200              
201             sub region_ident() {
202 1     1 1 5 my ($self,$nv) = @_;
203 1 50       4 if (defined($nv)) {
204 1         3 $self->{'regionIdent'} = $nv;
205             }
206              
207 1         3 return $self->{'regionIdent'};
208             }
209              
210             #==============================================================================
211              
212             =item sub merge_terrestrial_surface_conditions([$newValue])
213              
214             $value = $env_ctl->merge_terrestrial_surface_conditions($newValue);
215              
216             Merge Terrestrial Surface Conditions.
217              
218             This attribute specifies whether the terrestrial surface conditions found
219             within this region should be merged with those of other regions within areas of
220             overlap.
221             If this attribute is set to Use Last (0), the last Terrestrial Surface
222             Conditions Control packet describing a region containing a given point will be
223             used to determine the surface conditions at that point.
224              
225             If this attribute is set to Merge (1), the surface conditions at any given
226             point within the region are averaged with those of any other regions also
227             containing that point.
228              
229             Note: Regional surface conditions always take priority over global surface conditions.
230              
231             UseLast 0
232             Merge 1
233              
234             =cut
235              
236             sub merge_terrestrial_surface_conditions() {
237 1     1 1 4 my ($self,$nv) = @_;
238 1 50       4 if (defined($nv)) {
239 1 50 33     6 if (($nv==0) or ($nv==1)) {
240 1         3 $self->{'mergeTerrestrialSurfaceConditions'} = $nv;
241 1         3 $self->{'_bitfields1'} |= ($nv << 5) &0x20;
242             } else {
243 0         0 carp "merge_terrestrial_surface_conditions must be 0 (UseLast), or 1 (Merge).";
244             }
245             }
246              
247 1         3 return (($self->{'_bitfields1'} & 0x20) >> 5);
248             }
249              
250             #==============================================================================
251              
252             =item sub merge_maritime_surface_conditions([$newValue])
253              
254             $value = $env_ctl->merge_maritime_surface_conditions($newValue);
255              
256             Merge Maritime Surface Conditions.
257              
258             This attribute specifies whether the maritime surface conditions found within
259             this region should be merged with those of other regions within areas of
260             overlap.
261             If this attribute is set to Use Last (0), the last Maritime Surface Conditions
262             Control packet (Section 4.1.13) describing a region containing a given point
263             will be used to determine the surface conditions at that point.
264              
265             If this attribute is set to Merge (1), the surface conditions at any given
266             point within the region are averaged with those of any other regions also
267             containing that point.
268              
269             Note: Regional surface conditions always take priority over global surface conditions.
270              
271             UseLast 0
272             Merge 1
273              
274             =cut
275              
276             sub merge_maritime_surface_conditions() {
277 1     1 1 2 my ($self,$nv) = @_;
278 1 50       4 if (defined($nv)) {
279 1 50 33     11 if (($nv==0) or ($nv==1)) {
280 1         3 $self->{'mergeMaritimeSurfaceConditions'} = $nv;
281 1         2 $self->{'_bitfields1'} |= ($nv << 4) &0x10;
282             } else {
283 0         0 carp "merge_maritime_surface_conditions must be 0 (UseLast), or 1 (Merge).";
284             }
285             }
286              
287 1         4 return (($self->{'_bitfields1'} & 0x10) >> 4);
288             }
289              
290             #==============================================================================
291              
292             =item sub merge_aerosol_concentrations([$newValue])
293              
294             $value = $env_ctl->merge_aerosol_concentrations($newValue);
295              
296             Merge Aerosol Concentrations.
297              
298             This attribute specifies whether the concentrations of aerosols found within
299             this region should be merged with those of other regions within areas of
300             overlap.
301             If this attribute is set to Use Last (0), the last Weather Control packet
302             describing a layer containing a given point will be used to determine the
303             concentration of the specified aerosol at that point.
304              
305             If this attribute is set to Merge (1), the aerosol concentrations within all
306             weather layers containing a given point are combined (see Table 16).
307              
308             Note: Weather layers within the same region will always be combined. Regional
309             weather conditions always take priority over global weather conditions.
310              
311             UseLast 0
312             Merge 1
313              
314             =cut
315              
316             sub merge_aerosol_concentrations() {
317 1     1 1 3 my ($self,$nv) = @_;
318 1 50       4 if (defined($nv)) {
319 1 50 33     5 if (($nv==0) or ($nv==1)) {
320 1         2 $self->{'mergeAerosolConcentrations'} = $nv;
321 1         3 $self->{'_bitfields1'} |= ($nv << 3) &0x08;
322             } else {
323 0         0 carp "merge_aerosol_concentrations must be 0 (UseLast), or 1 (Merge).";
324             }
325             }
326              
327 1         4 return (($self->{'_bitfields1'} & 0x08) >> 3);
328             }
329              
330             #==============================================================================
331              
332             =item sub merge_weather_properties([$newValue])
333              
334             $value = $env_ctl->merge_weather_properties($newValue);
335              
336             Merge Weather Properties
337              
338             This attribute specifies whether atmospheric conditions within this region
339             should be merged with those of other regions within areas of overlap.
340              
341             If this attribute is set to Use Last (0), the last Weather Control packet
342             describing a layer containing a given point will be used to determine the
343             weather conditions at that point.
344              
345             If this attribute is set to Merge (1), the atmospheric properties of all
346             weather layers containing a given point are combined (see Table 16).
347              
348             Note: Weather layers within the same region will always be combined. Regional
349             weather conditions always take priority over global weather conditions.
350              
351             UseLast 0
352             Merge 1
353              
354             =cut
355              
356             sub merge_weather_properties() {
357 1     1 1 2 my ($self,$nv) = @_;
358 1 50       4 if (defined($nv)) {
359 1 50 33     5 if (($nv==0) or ($nv==1)) {
360 1         2 $self->{'mergeWeatherProperties'} = $nv;
361 1         3 $self->{'_bitfields1'} |= ($nv << 2) &0x04;
362             } else {
363 0         0 carp "merge_weather_properties must be 0 (UseLast), or 1 (Merge).";
364             }
365             }
366              
367 1         3 return (($self->{'_bitfields1'} & 0x04) >> 2);
368             }
369              
370             #==============================================================================
371              
372             =item sub region_state([$newValue])
373              
374             $value = $env_ctl->region_state($newValue);
375              
376             Region State.
377              
378             This attribute specifies whether the region should be active or destroyed. This
379             attribute may be set to one of the following values:
380              
381             Inactive – Any weather layers and surface conditions defined within the region
382             are disabled regardless of their individual enable states.
383              
384             Active – Any weather layers and surface conditions defined within the region
385             are enabled according to their individual enable states.
386              
387             Destroyed – The environmental region is permanently deleted, as are all weather
388             layers and surface conditions assigned to the region.
389              
390             Inactive 0
391             Active 1
392             Destroyed 2
393              
394             =cut
395              
396             sub region_state() {
397 1     1 1 3 my ($self,$nv) = @_;
398 1 50       4 if (defined($nv)) {
399 1 50 33     9 if (($nv==0) or ($nv==1) or ($nv==2)) {
      33        
400 1         2 $self->{'regionState'} = $nv;
401 1         3 $self->{'_bitfields1'} |= $nv &0x03;
402             } else {
403 0         0 carp "region_state must be 0 (Inactive), 1 (Active), or 2 (Destroyed).";
404             }
405             }
406              
407 1         3 return ($self->{'_bitfields1'} & 0x03);
408             }
409              
410             #==============================================================================
411              
412             =item sub latitude([$newValue])
413              
414             $value = $env_ctl->latitude($newValue);
415              
416             Latitude.
417              
418             This attribute specifies the geodetic latitude of the center of the rounded rectangle.
419              
420             =cut
421              
422             sub latitude() {
423 1     1 1 5 my ($self,$nv) = @_;
424 1 50       5 if (defined($nv)) {
425 1 50 33     11 if (($nv>=-90) and ($nv<=90.0)) {
426 1         9 $self->{'latitude'} = $nv;
427             } else {
428 0         0 carp "latitude must be from -90.0 to +90.0.";
429             }
430             }
431              
432 1         4 return $self->{'latitude'};
433             }
434              
435             #==============================================================================
436              
437             =item sub longitude([$newValue])
438              
439             $value = $env_ctl->longitude($newValue);
440              
441             Longitude.
442              
443             This attribute specifies the geodetic longitude of the center of the rounded rectangle.
444              
445             =cut
446              
447             sub longitude() {
448 1     1 1 6 my ($self,$nv) = @_;
449 1 50       5 if (defined($nv)) {
450 1 50 33     9 if (($nv>=-180.0) and ($nv<=180.0)) {
451 1         3 $self->{'longitude'} = $nv;
452             } else {
453 0         0 carp "longitude must be from -180.0 to +180.0.";
454             }
455             }
456              
457 1         4 return $self->{'longitude'};
458             }
459              
460             #==============================================================================
461              
462             =item sub size_x([$newValue])
463              
464             $value = $env_ctl->size_x($newValue);
465              
466             Size X.
467              
468             This attribute specifies the length, measured in meters, of the environmental
469             region along its X axis at the geoid surface. This length does not include the
470             width of the transition perimeter.
471              
472             =cut
473              
474             sub size_x() {
475 1     1 1 5 my ($self,$nv) = @_;
476 1 50       4 if (defined($nv)) {
477 1 50       4 if ($nv > 0.0) {
478 1         4 $self->{'sizeX'} = $nv;
479             } else {
480 0         0 carp "size_x must be > 0.0.";
481             }
482             }
483              
484 1         3 return $self->{'sizeX'};
485             }
486              
487             #==============================================================================
488              
489             =item sub size_y([$newValue])
490              
491             $value = $env_ctl->size_y($newValue);
492              
493             Size Y.
494              
495             This attribute specifies the length, measured in meters, of the environmental
496             region along its Y axis at the geoid surface. This length does not include the
497             width of the transition perimeter.
498              
499             =cut
500              
501             sub size_y() {
502 1     1 1 5 my ($self,$nv) = @_;
503 1 50       4 if (defined($nv)) {
504 1 50       5 if ($nv > 0.0) {
505 1         101 $self->{'sizeY'} = $nv;
506             } else {
507 0         0 carp "size_y must be > 0.0.";
508             }
509             }
510              
511 1         4 return $self->{'sizeY'};
512             }
513              
514             #==============================================================================
515              
516             =item sub corner_radius([$newValue])
517              
518             $value = $env_ctl->corner_radius($newValue);
519              
520             Corner Radius.
521              
522             This attribute specifies the radius, measured in meters, of the corner of the
523             rounded rectangle. The smaller the radius, the “tighter” the corner. A value of
524             0.0 produces a rectangle.
525              
526             =cut
527              
528             sub corner_radius() {
529 1     1 1 7 my ($self,$nv) = @_;
530 1 50       4 if (defined($nv)) {
531 1 50       5 if ($nv>=0.0) {
532 1         3 $self->{'cornerRadius'} = $nv;
533             } else {
534 0         0 carp "corner_radius must be > 0.0.";
535             }
536             }
537              
538 1         12 return $self->{'cornerRadius'};
539             }
540              
541             #==============================================================================
542              
543             =item sub rotation([$newValue])
544              
545             $value = $env_ctl->rotation($newValue);
546              
547             Rotation.
548              
549             This attribute specifies the yaw angle, measured in degrees from true north, of
550             the rounded rectangle.
551              
552             =cut
553              
554             sub rotation() {
555 1     1 1 6 my ($self,$nv) = @_;
556 1 50       5 if (defined($nv)) {
557 1 50 33     9 if (($nv>=-180.0) and ($nv<=180.0)) {
558 1         3 $self->{'rotation'} = $nv;
559             } else {
560 0         0 carp "rotation must be from -180.0 to +180.0.";
561             }
562             }
563              
564 1         4 return $self->{'rotation'};
565             }
566              
567             #==============================================================================
568              
569             =item sub transition_perimeter([$newValue])
570              
571             $value = $env_ctl->transition_perimeter($newValue);
572              
573             Transition Perimeter.
574              
575             This attribute specifies the width, measured in meters, of the transition
576             perimeter around the environmental region. This perimeter is a region through
577             which the weather conditions are interpolated between those inside the
578             environmental region and those immediately outside the perimeter.
579              
580             =cut
581              
582             sub transition_perimeter() {
583 1     1 1 4 my ($self,$nv) = @_;
584 1 50       5 if (defined($nv)) {
585 1 50       10 if ($nv>=0.0) {
586 1         3 $self->{'transitionPerimeter'} = $nv;
587             } else {
588 0         0 carp "transition_perimeter must be >= 0.0.";
589             }
590             }
591              
592 1         3 return $self->{'transitionPerimeter'};
593             }
594              
595             #==========================================================================
596              
597             =item sub pack()
598              
599             $value = $env_ctl->pack();
600              
601             Returns the packed data packet.
602              
603             =cut
604              
605             sub pack($) {
606 1     1 1 6 my $self = shift ;
607            
608 1         11 $self->{'_Buffer'} = CORE::pack($self->{'_Pack'},
609             $self->{'packetType'},
610             $self->{'packetSize'},
611             $self->{'regionIdent'},
612             $self->{'_bitfields1'}, # Includes bitfields unused17, mergeTerrestrialSurfaceConditions, mergeMaritimeSurfaceConditions, mergeAerosolConcentrations, mergeWeatherProperties, and regionState.
613             $self->{'_unused18'},
614             $self->{'_unused19'},
615             $self->{'latitude'},
616             $self->{'longitude'},
617             $self->{'sizeX'},
618             $self->{'sizeY'},
619             $self->{'cornerRadius'},
620             $self->{'rotation'},
621             $self->{'transitionPerimeter'},
622             $self->{'_unused20'},
623             );
624              
625 1         4 return $self->{'_Buffer'};
626             }
627              
628             #==========================================================================
629              
630             =item sub unpack()
631              
632             $value = $env_ctl->unpack();
633              
634             Unpacks the packed data packet.
635              
636             =cut
637              
638             sub unpack($) {
639 0     0 1   my $self = shift @_;
640            
641 0 0         if (@_) {
642 0           $self->{'_Buffer'} = shift @_;
643             }
644 0           my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n) = CORE::unpack($self->{'_Pack'},$self->{'_Buffer'});
645 0           $self->{'packetType'} = $a;
646 0           $self->{'packetSize'} = $b;
647 0           $self->{'regionIdent'} = $c;
648 0           $self->{'_bitfields1'} = $d; # Includes bitfields unused17, mergeTerrestrialSurfaceConditions, mergeMaritimeSurfaceConditions, mergeAerosolConcentrations, mergeWeatherProperties, and regionState.
649 0           $self->{'_unused18'} = $e;
650 0           $self->{'_unused19'} = $f;
651 0           $self->{'latitude'} = $g;
652 0           $self->{'longitude'} = $h;
653 0           $self->{'sizeX'} = $i;
654 0           $self->{'sizeY'} = $j;
655 0           $self->{'cornerRadius'} = $k;
656 0           $self->{'rotation'} = $l;
657 0           $self->{'transitionPerimeter'} = $m;
658 0           $self->{'_unused20'} = $n;
659              
660 0           $self->{'mergeTerrestrialSurfaceConditions'} = $self->merge_terrestrial_surface_conditions();
661 0           $self->{'mergeMaritimeSurfaceConditions'} = $self->merge_maritime_surface_conditions();
662 0           $self->{'mergeAerosolConcentrations'} = $self->merge_aerosol_concentrations();
663 0           $self->{'mergeWeatherProperties'} = $self->merge_weather_properties();
664 0           $self->{'regionState'} = $self->region_state();
665              
666 0           return $self->{'_Buffer'};
667             }
668              
669             #==========================================================================
670              
671             =item sub byte_swap()
672              
673             $obj_name->byte_swap();
674              
675             Byte swaps the packed data packet.
676              
677             =cut
678              
679             sub byte_swap($) {
680 0     0 1   my $self = shift @_;
681            
682 0 0         if (@_) {
683 0           $self->{'_Buffer'} = shift @_;
684             } else {
685 0           $self->pack();
686             }
687 0           my ($a,$b,$c,$d,$e,$f,$g,$h,$i,$j,$k,$l,$m,$n,$o,$p) = CORE::unpack($self->{'_Swap1'},$self->{'_Buffer'});
688              
689 0           $self->{'_Buffer'} = CORE::pack($self->{'_Swap2'},$a,$b,$c,$d,$e,$f,$h,$g,$j,$i,$k,$l,$m,$n,$o,$p);
690 0           $self->unpack();
691              
692 0           return $self->{'_Buffer'};
693             }
694              
695             1;
696             __END__