File Coverage

blib/lib/Geo/GoogleEarth/Pluggable/Plugin/GreatCircle.pm
Criterion Covered Total %
statement 18 38 47.3
branch 0 2 0.0
condition 0 2 0.0
subroutine 6 7 85.7
pod 1 1 100.0
total 25 50 50.0


line stmt bran cond sub pod time code
1             package Geo::GoogleEarth::Pluggable::Plugin::GreatCircle;
2 1     1   31889 use warnings;
  1         2  
  1         32  
3 1     1   6 use strict;
  1         1  
  1         34  
4 1     1   875 use GPS::Point;
  1         2848  
  1         34  
5 1     1   960 use Geo::Forward;
  1         8556  
  1         35  
6 1     1   815 use Geo::Inverse; #fail at complie time if you don't have it
  1         1001  
  1         165  
7              
8             our $VERSION='0.01';
9              
10             =head1 NAME
11              
12             Geo::GoogleEarth::Pluggable::Plugin::GreatCircle - Great Circle plugin for Geo::GoogleEarth::Pluggable
13              
14             =head1 SYNOPSIS
15              
16             use Geo::GoogleEarth::Pluggable;
17             my $document=Geo::GoogleEarth::Pluggable->new;
18             my $arc=$document->GreatCircleArcSegment(%data);
19              
20             =head1 DESCRIPTION
21              
22             Calculates the Great Circle Arc between two points and creates points in between so that Google Earth can display it as "straight" lines and it still looks like a Great Circle Arc.
23              
24             =head1 USAGE
25              
26             =head1 METHODS
27              
28             =head2 GreatCircleArcSegment
29              
30             Returns a LineString object.
31              
32             my $list=$folder->GreatCircleArcSegment(
33             startPoint=>{lat=>39,lon=>-77},
34             endPoint=>{lat=>40,lon=>-76});
35             my @list=$folder->GreatCircleArcSegment(
36             name=>"My Great Circle", #name passed through to LineString
37             startPoint=>{lat=>39,lon=>-77},
38             endPoint=>{lat=>40,lon=>-76},
39             span=>5000);
40              
41             startPoint and endPoint can be any valid scalar structure supported by GPS::Point->newMulti() constructor
42              
43             =cut
44              
45             sub GreatCircleArcSegment {
46 0     0 1   my $self=shift; #$self isa Geo::GoogleEarth::Pluggable::Folder object
47 0           my %data=@_;
48 0   0       my $span=delete($data{"span"})||10000; #meters
49              
50 0           my $pt=[]; #list of GPS::Point objects
51 0           $pt->[0] = GPS::Point->newMulti(delete($data{"startPoint"}));
52 0           my $end = GPS::Point->newMulti(delete($data{"endPoint"}));
53              
54 0           my ($faz, $baz, $dist)=$pt->[0]->distance($end); #requires Geo::Inverse
55 0           $pt->[0]->heading($faz);
56 0           $end->heading($baz-180);
57              
58 0           my $n=int($dist/$span);
59 0 0         $n=2 if $n < 2;
60 0           $span=$dist/$n;
61              
62 1     1   7 use Geo::Forward;
  1         3  
  1         152  
63 0           my $gf=Geo::Forward->new;
64 0           foreach my $i (1 .. $n-1) {
65 0           my ($lat,$lon,$baz) = $gf->forward($pt->[$i-1]->latlon,$faz,$span);
66 0           $pt->[$i]=GPS::Point->new(lat=>$lat, lon=>$lon);
67 0           $faz=$baz+180;
68             }
69              
70 0           $pt->[$n]=$end;
71 0           $data{"coordinates"}=$pt;
72 0           return $self->LineString(%data);
73             }
74              
75             =head1 BUGS
76              
77             Log on RT and send to geo-perl email list
78              
79             =head1 SUPPORT
80              
81             =head1 AUTHOR
82              
83             Michael R. Davis
84             CPAN ID: MRDVT
85             STOP, LLC
86             domain=>michaelrdavis,tld=>com,account=>perl
87             http://www.stopllc.com/
88              
89             =head1 COPYRIGHT
90              
91             This program is free software licensed under the...
92              
93             The BSD License
94              
95             The full text of the license can be found in the
96             LICENSE file included with this module.
97              
98             =head1 SEE ALSO
99              
100             =cut
101              
102             1;