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.

The new() constructor may be called with a hash list to set the value of the ellipsoid to be used, the value of the units to be used for angles and distances, and whether or not the output range of longitudes and bearing angles should be symmetric around zero or always greater than zero. The initial default constructor is equivalent to the following:

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', DIS => 'FEE', Lon => 1, ell => 'NAD27', bEA => 0 ) is valid.

Set the angle 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. The units of angle apply to both input and output latitude, longitude, and bearing values.

Set the distance unit used by the Geo::Ellipsoid object. The unit of distance may also be set in the constructor of the object. The recognized values are 'meter', 'kilometer', 'mile', 'nm' (nautical mile), or 'foot'. The default is 'meter'. The value is not case sensitive and may be abbreviated to 3 letters.

$geo->set_distance_unit('kilometer');

For any other unit of distance not recogized by this method, pass a numerical argument representing the length of the distance unit in meters. For example, to use units of furlongs, call

Sets the ellipsoid parameters to the specified ( major semiaxis and reciprocal flattening. A zero value for the reciprocal flattening will result in a sphere for the ellipsoid, and a warning message will be issued.

If called with no argument or a true argument, sets the range of output values for longitude to be in the range [-pi,+pi) radians. If called with a false or undefined argument, sets the output angle range to be [0,2*pi) radians.

If called with no argument or a true argument, sets the range of output values for bearing to be in the range [-pi,+pi) radians. If called with a false or undefined argument, sets the output angle range to be [0,2*pi) radians.

Returns a list consisting of the distance unit 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.

Returns the (x,y) displacement in distance units 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.

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 ellipsoid. The methods will not return valid results in these cases.

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