File Coverage

blib/lib/Location/GeoTool/Direction.pm
Criterion Covered Total %
statement 66 80 82.5
branch 5 16 31.2
condition 3 5 60.0
subroutine 14 16 87.5
pod 3 6 50.0
total 91 123 73.9


line stmt bran cond sub pod time code
1             package Location::GeoTool::Direction;
2              
3             ################################################################
4             #
5             # Geometric Functions
6             # Location::GeoTool::Direction
7             #
8              
9 8     8   202 use 5.008;
  8         25  
  8         305  
10 8     8   41 use strict;
  8         24  
  8         249  
11 8     8   39 use warnings;
  8         17  
  8         313  
12 8     8   40 use vars qw($VERSION);
  8         23  
  8         469  
13             $VERSION = 0.97;
14              
15 8     8   42 use Location::GeoTool;
  8         13  
  8         55  
16 8     8   43 use Carp;
  8         20  
  8         7521  
17              
18             __PACKAGE__->_make_accessors(
19             qw(from_point to_point direction distance)
20             );
21              
22             # Constructor -- set Startpoint
23             sub new
24             {
25 28     28 0 39 my $class = shift;
26 28 50       121 $class = ref($class) if (ref($class));
27 28         38 my $arg = $_[0];
28 28         40 my $self = {};
29              
30 28 50       143 if (UNIVERSAL::isa($arg, 'Location::GeoTool'))
31             {
32 28         84 $self->{'from_point'} = $arg->_clone;
33             }
34             else
35             {
36 0         0 $self->{'from_point'} = Location::GeoTool->create_coord(@_);
37             }
38 28         145 bless $self, $class;
39             }
40              
41             # Set direction/distance and create Endpoint
42             sub set_vector
43             {
44 16     16 0 25 my $self = shift;
45 16         36 my ($dir,$dist) = @_[0..1];
46            
47 16         37 $self->{'direction'} = $dir;
48 16         27 $self->{'distance'} = $dist;
49              
50 16         35 $dir = _regular_dir($dir);
51              
52 16         45 my $fp = $self->from_point;
53 16         91 my ($flat,$flong) = $fp->format_degree->array;
54 16         84 my $fdatum = $fp->out_datum;
55 16         43 my $fformat = $fp->out_format;
56              
57 16         49 my ($tlat,$tlong) = Location::GeoTool::vector2point_degree($flat,$flong,$dir,$dist,$fdatum);
58            
59 16         57 my $to_point = Location::GeoTool->create_coord($tlat,$tlong,$fdatum,'degree');
60 16         37 my $meth = "format_$fformat";
61 16 50       69 $self->{'to_point'} = ($fdatum eq 'degree') ? $to_point : $to_point->$meth;
62              
63 16         86 return $self;
64             }
65              
66             # Set Endpoint and calcurate direction/distance
67             sub set_topoint
68             {
69 12     12 0 20 my $self = shift;
70 12         21 my $arg = $_[0];
71              
72 12 50       59 if (UNIVERSAL::isa($arg, 'Location::GeoTool'))
73             {
74 0         0 $self->{'to_point'} = $arg->_clone;
75             }
76             else
77             {
78 12         42 $self->{'to_point'} = Location::GeoTool->create_coord(@_);
79             }
80              
81 12         33 my $fp = $self->from_point;
82 12         46 my ($flat,$flong) = $fp->format_degree->array;
83 12         74 my $fdatum = $fp->out_datum;
84              
85 12         22 my $meth = "datum_$fdatum";
86 12         52 my ($tlat,$tlong) = $self->{'to_point'}->$meth->format_degree->array;
87              
88 12         93 my ($dir,$dist) = Location::GeoTool::point2vector_degree($flat,$flong,$tlat,$tlong,$fdatum);
89              
90 12         31 $dir = _regular_dir($dir);
91              
92 12         25 $self->{'direction'} = $dir;
93 12         21 $self->{'distance'} = $dist;
94              
95 12         38 return $self;
96             }
97              
98             # Return a new Location::GeoTool::Direction object
99             # rotate around Startpoint and extend distance
100             sub pivot
101             {
102 0     0 1 0 my $self = shift;
103 0 0       0 croak "Please set End-point before call this method!!" unless ($self->to_point);
104 0         0 my ($rot,$pow) = @_;
105              
106 0         0 my $dir = $self->direction + $rot;
107 0         0 my $dist = $self->distance * $pow;
108            
109 0 0       0 if ($dist < 0)
110             {
111 0         0 $dir += 180;
112 0         0 $dist = abs($dist);
113             }
114              
115 0         0 return $self->new($self->from_point)->set_vector(_regular_dir($dir),$dist);
116             }
117              
118             # Return a new Location::GeoTool::Direction object
119             # reverse between Startpoint and Endpoint
120             sub reverse
121             {
122 0     0 1 0 my $self = shift;
123 0 0       0 croak "Please set End-point before call this method!!" unless ($self->to_point);
124              
125 0         0 return $self->new($self->to_point)->set_topoint($self->from_point);
126             }
127              
128             # Return the name of direction
129             sub dir_string
130             {
131 32   50 32 1 5299 return Location::GeoTool::direction_string(_regular_dir($_[0]->direction),$_[1] || 16,$_[2]);
132             }
133              
134             # Normalize direction 0-360
135             sub _regular_dir
136             {
137 60     60   84 my $dir = $_[0];
138 60   66     288 while ($dir < 0 || $dir >= 360)
139             {
140 6 50       34 $dir += $dir < 0 ? 360 : -360;
141             }
142 60         180 return $dir;
143             }
144              
145             sub _make_accessors
146             {
147 8     8   29 my($class, @attr) = @_;
148 8         17 for my $attr (@attr) {
149 8     8   51 no strict 'refs';
  8         13  
  8         745  
150 32     96   91 *{"$class\::$attr"} = sub { shift->{$attr} };
  32         177  
  96         9804  
151             }
152             }
153              
154             1;
155             __END__