The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Geo::Ellipsoid - Calculate positions, distances, and bearings on the surface of an ellipsoid.

VERSION

Version 0.901, released October, 2005.

SYNOPSIS

  use Geo::Ellipsoid;
  $geo = Geo::Ellipsoid->new(ellipsoid=>'NAD27', units=>'degrees');
  @origin = ( 37.619002, -122.374843 );    # SFO
  @dest = ( 33.942536, -118.408074 );      # LAX
  ( $range, $bearing ) = $geo->to( @origin, @dest );
  ($lat,$lon) = $geo->at( @origin, 45.0, 2000 );
  ( $x, $y ) = $geo->displacement( @origin, $lat, $lon );
  @pos = $geo->location( $lat, $lon, $x, $y );

DESCRIPTION

Geo::Ellipsoid performs geometrical calculations on the surface of an ellipsoid. An ellipsoid is a three-dimension object formed from the rotation of an ellipse about one of its axes. The approximate shape of the earth is an ellipsoid, so Geo::Ellipsoid can accurately calculate distance and bearing between two widely-separated locations on the earth's surface.

The shape of an ellipsoid is defined by the lengths of its semi-major and semi-minor axes. The shape may also be specifed by the flattening ratio f as:

    f = ( semi-major - semi-minor ) / semi-major
    

which, since f is a small number, is normally given as the reciprocal of the flattening 1/f.

The shape of the earth has been surveyed and estimated differently at different times over the years. The two most common sets of values used to describe the size and shape of the earth in the United States are 'NAD27', dating from 1927, and 'WGS84', from 1984. United States Geological Survey topographical maps, for example, use one or the other of these values, and commonly-available Global Positioning System (GPS) units can be set to use one or the other. See "DEFINED ELLIPSOIDS" below for the ellipsoid survey values that may be selected for use by Geo::Ellipsoid.

CONSTRUCTOR

new

The new() constructor may be called with a hash list to set the value of the ellipsoid to be used and the value of the units to be used for angles. The default constructor is equivalent to the following:

    my $geo = Geo::Ellipsoid->new( 
      ellipsoid => 'WGS84', 
      units => 'radians' 
    );
    

The constructor arguments may be of any case and, with the exception of the ellipsoid value, abbreviated to their first three characters. Thus, ( UNI => 'DEG', ell => 'NAD27' ) is valid.

METHODS

set_units

Set the units used by the Geo::Ellipsoid object. The units may also be set in the constructor of the object. The allowable values are 'degrees' or 'radians'. The default is 'radians'. The units value is not case sensitive and may be abbreviated to 3 letters. An invalid value will be accepted as 'radians'.

    $geo->set_units('degrees');

set_ellipsoid

Set the ellipsoid to be used by the Geo::Ellipsoid object. See "DEFINED ELLIPSOIDS" below for the allowable values. The value may also be set by the constructor. The default value is 'WGS84'.

    $geo->set_ellipsoid('NAD27');

set_custom_ellipsoid

Sets the ellipsoid parameters to the specified ( major semiaxis and reciprocal flattening.

    $geo->set_custom_ellipsoid( 'sphere', 6378137, 0 );
    

scales

Returns a list consisting of the meters per angle of latitude and longitude (degrees or radians) at the specified latitude. These values may be used for fast approximations of distance calculations in the vicinity of some location.

    ( $lat_scale, $lon_scale ) = $geo->scales($lat0);
    $x = $lon_scale * ($lon - $lon0); 
    $y = $lat_scale * ($lat - $lat0); 

range

Returns the range in meters between two specified locations given as latitude, longitude pairs.

    my $dist = $geo->range( $lat1, $lon1, $lat2, $lon2 );
    my $dist = $geo->range( @origin, @destination );

bearing

Returns the bearing in degrees or radians from the first location to the second. Zero bearing is true north.

    my $bearing = $geo->bearing( $lat1, $lon1, $lat2, $lon2 );

at

Returns the list (latitude,longitude) in degrees or radians that is a specified range and bearing from a given location.

    my( $lat2, $lon2 ) = $geo->at( $lat1, $lon1, $range, $bearing );

to

In list context, returns (range, bearing) between two specified locations. In scalar context, returns just the range.

    my( $dist, $theta ) = $geo->to( $lat1, $lon1, $lat2, $lon2 );
    my $dist = $geo->to( $lat1, $lon1, $lat2, $lon2 );

displacement

Returns the (x,y) displacement in meters between the two specified locations.

    my( $x, $y ) = $geo->displacement( $lat1, $lon1, $lat2, $lon2 );
    

NOTE: The x and y displacements are only approximations and only valid between two locations that are fairly near to each other. Beyond 10 kilometers or more, the concept of X and Y on a curved surface loses its meaning.

location

Returns the list (latitude,longitude) of a location at a given (x,y) displacement from a given location.

        my @loc = $geo->location( $lat, $lon, $x, $y );

DEFINED ELLIPSOIDS

The following ellipsoids are defined in Geo::Ellipsoid, with the semi-major axis in meters and the reciprocal flattening as shown. The default ellipsoid is WGS84.

    Ellipsoid        Semi-Major Axis (m.)     1/Flattening
    ---------        -------------------     ---------------
    WGS84                6378137.0           298.25722210088
    NAD27                6378206.4           294.9786982138
    AIRY                 6377563.396         299.3249646
    AIRY-MODIFIED        6377340.189         299.3249646
    AUSTRALIAN           6378160.0           298.25
    BESSEL-1841          6377397.155         299.1528128
    CLARKE-1880          6378249.145         293.465
    EVEREST-1830         6377276.345         290.8017
    EVEREST-MODIFIED     6377304.063         290.8017
    FISHER-1960          6378166.0           298.3
    FISHER-1968          6378150.0           298.3
    HOUGH-1956           6378270.0           297.0
    HAYFORD              6378388.0           297.0
    KRASSOVSKY-1938      6378245.0           298.3
    NWL-9D               6378145.0           298.25
    SOUTHAMERICAN-1969   6378160.0           298.25
    SOVIET-1985          6378136.0           298.257
    WGS72                6378135.0           298.26
    GRS80                6378137.0           298.25722210088

LIMITATIONS

The methods should not be used on points which are too near the poles (above or below 89 degrees), and should not be used on points which are antipodal, i.e., exactly on opposite sides of the geoid. The methods will not return valid results in these cases.

ACKNOWLEDGEMENTS

The conversion algorithms used here are Perl translations of Fortran routines written by LCDR L. Pfeifer NGS Rockville MD that implement T. Vincenty's Modified Rainsford's method with Helmert's elliptical terms as published in "Direct and Inverse Solutions of Ellipsoid on the Ellipsoid with Application of Nested Equations", T. Vincenty, Survey Review, April 1975.

The Fortran source code files inverse.for and forward.for may be obtained from

    ftp://ftp.ngs.noaa.gov/pub/pcsoft/for_inv.3d/source/

AUTHOR

Jim Gibson, <Jim@Gibson.org>

BUGS

This version cannot handle points that are too near to the poles, for some of the methods, or points which are anti-podal, that is on opposite sides of the earth. In this case, the iterative algorithms will not converge, a warning message will be emitted, and undefined values will be returned.

Please report any bugs or feature requests to bug-geo-ellipsoid@rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Geo-Ellipsoid. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

COPYRIGHT & LICENSE

Copyright 2005 Jim Gibson, all rights reserved.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 119:

You forgot a '=back' before '=head1'