Skip to content

Commit 63cd826

Browse files
committed
Move trig to the bottom
1 parent 6770d7f commit 63cd826

File tree

1 file changed

+55
-55
lines changed

1 file changed

+55
-55
lines changed

lib/VWF/Utils.pm

Lines changed: 55 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package VWF::Utils;
22

33
# VWF is licensed under GPL2.0 for personal use only
4-
# njh@bandsman.co.uk
4+
# njh@nigelhorne.com
55

66
=head1 NAME
77
@@ -90,58 +90,6 @@ sub create_memory_cache {
9090
return _create_cache('memory_cache', $args);
9191
}
9292

93-
=head2 distance
94-
95-
Calculate the great circle distance between two points on Earth using the Haversine formula.
96-
More accurate than the original implementation, especially for short distances.
97-
98-
Parameters:
99-
- lat1, lon1: Latitude and longitude of first point (decimal degrees)
100-
- lat2, lon2: Latitude and longitude of second point (decimal degrees)
101-
- unit: 'K' for kilometers, 'N' for nautical miles, 'M' or undef for statute miles
102-
103-
Returns: Distance in specified units
104-
105-
Throws: Error on invalid input parameters
106-
107-
=cut
108-
109-
sub distance($lat1, $lon1, $lat2, $lon2, $unit = 'M') {
110-
# Input validation
111-
for my $coord_ref ([\$lat1, 'lat1'], [\$lon1, 'lon1'], [\$lat2, 'lat2'], [\$lon2, 'lon2']) {
112-
my ($coord, $name) = @$coord_ref;
113-
croak "$name must be defined" unless defined $$coord;
114-
croak "$name must be numeric" unless looks_like_number($$coord);
115-
}
116-
117-
# Range validation
118-
croak "Latitude must be between -90 and 90 degrees"
119-
if abs($lat1) > 90 || abs($lat2) > 90;
120-
croak "Longitude must be between -180 and 180 degrees"
121-
if abs($lon1) > 180 || abs($lon2) > 180;
122-
123-
# Handle identical points
124-
return 0 if $lat1 == $lat2 && $lon1 == $lon2;
125-
126-
# Validate unit
127-
$unit = uc($unit || 'M');
128-
croak "Unknown unit '$unit'. Use 'K', 'N', or 'M'"
129-
unless $unit =~ /^[KNM]$/;
130-
131-
# Use optimized calculation with appropriate radius
132-
my $radius = $unit eq 'K' ? EARTH_RADIUS_KM :
133-
$unit eq 'N' ? EARTH_RADIUS_NM :
134-
EARTH_RADIUS_MILES;
135-
136-
# Haversine formula
137-
my $dlat = deg2rad($lat2 - $lat1);
138-
my $dlon = deg2rad($lon2 - $lon1);
139-
my $a = sin($dlat/2)**2 + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dlon/2)**2;
140-
my $c = 2 * asin(sqrt($a));
141-
142-
return $radius * $c;
143-
}
144-
14593
# Private helper functions
14694

14795
sub _create_cache($cache_type, $args) {
@@ -383,13 +331,65 @@ sub _parse_server_config($config, $logger) {
383331
return @servers;
384332
}
385333

334+
=head2 distance
335+
336+
Calculate the great circle distance between two points on Earth using the Haversine formula.
337+
More accurate than the original implementation, especially for short distances.
338+
339+
Parameters:
340+
- lat1, lon1: Latitude and longitude of first point (decimal degrees)
341+
- lat2, lon2: Latitude and longitude of second point (decimal degrees)
342+
- unit: 'K' for kilometers, 'N' for nautical miles, 'M' or undef for statute miles
343+
344+
Returns: Distance in specified units
345+
346+
Throws: Error on invalid input parameters
347+
348+
=cut
349+
350+
sub distance($lat1, $lon1, $lat2, $lon2, $unit = 'M') {
351+
# Input validation
352+
for my $coord_ref ([\$lat1, 'lat1'], [\$lon1, 'lon1'], [\$lat2, 'lat2'], [\$lon2, 'lon2']) {
353+
my ($coord, $name) = @$coord_ref;
354+
croak "$name must be defined" unless defined $$coord;
355+
croak "$name must be numeric" unless looks_like_number($$coord);
356+
}
357+
358+
# Range validation
359+
croak "Latitude must be between -90 and 90 degrees"
360+
if abs($lat1) > 90 || abs($lat2) > 90;
361+
croak "Longitude must be between -180 and 180 degrees"
362+
if abs($lon1) > 180 || abs($lon2) > 180;
363+
364+
# Handle identical points
365+
return 0 if $lat1 == $lat2 && $lon1 == $lon2;
366+
367+
# Validate unit
368+
$unit = uc($unit || 'M');
369+
croak "Unknown unit '$unit'. Use 'K', 'N', or 'M'"
370+
unless $unit =~ /^[KNM]$/;
371+
372+
# Use optimized calculation with appropriate radius
373+
my $radius = $unit eq 'K' ? EARTH_RADIUS_KM :
374+
$unit eq 'N' ? EARTH_RADIUS_NM :
375+
EARTH_RADIUS_MILES;
376+
377+
# Haversine formula
378+
my $dlat = deg2rad($lat2 - $lat1);
379+
my $dlon = deg2rad($lon2 - $lon1);
380+
my $a = sin($dlat/2)**2 + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dlon/2)**2;
381+
my $c = 2 * asin(sqrt($a));
382+
383+
return $radius * $c;
384+
}
385+
386386
1;
387387

388388
__END__
389389
390390
=head1 AUTHOR
391391
392-
Nigel Horne, C<< <njh at bandsman.co.uk> >>
392+
Nigel Horne, C<< <njh at nigelhorne.com> >>
393393
394394
=head1 BUGS
395395
@@ -410,4 +410,4 @@ Commercial users must apply in writing for a licence.
410410
411411
L<CHI>, L<Math::Trig>, L<DBI>
412412
413-
=cut
413+
=cut

0 commit comments

Comments
 (0)