## Expand description

`geoconv`

implements support for converting between some basic coordinate
systems. This package contains support for Wgs84
Latitude/Longitude/Elevation (LLE) geodetic coordinates, Earth-centered,
Earth-fixed (XYZ), and local tangent plane (both East/North/Up (ENU)
and Azimuth/Elevation/Range (AER)) systems.

**This is also absolutely not ready to be used for navigational purposes**. Please do not use this library in any situation that may cause harm to life or property.

This package is particularly useful if you know your location on Earth, and want to geolocate an object that you can observe, or if you know your location on Earth, and an object’s location on Earth and want to determine your relative positions.

This also includes Haversine-distance using the circumference of the earth for approximate great-circle distance between two Lat/Lon points, but only on the “Earth’s surface”. In some cases (long distances) this is a way better approach for distance. If both points are line-of-sight, you likely care more about using the local tangent plane to work out the Range to the target in 3-space by converting both lat/lons to Earth-North-Up or an Azimuth/Elevation/Range.

## §Supported Coordinate Systems

I only implemented what I was interested in (Wgs84), but I threw in another system (Wgs72) since it should be pretty straight-forward to support both. I have no reference data, so some additional testing for that coordinate system would be most welcome.

## §Types

Within `geoconv`

, the main types that you’ll be interacting with for location
data are listed below, along with a short description.

Name | Cartesian or Angular | Where is `0` , `0` , `0` ? | Description |
---|---|---|---|

LLE | Angular | Null Island | Latitude, Longitude, and Elevation |

XYZ | Cartesian | Earth’s Core | X, Y, Z (sometimes called ECEF, Earth-centered, Earth-fixed) |

AER | Angular | Some point on the local tangent plane | Azimuth, Elevation and Range |

ENU | Cartesian | Some point on the local tangent plane | East-North-Up |

## §Determining the Azimuth, Elevation and Rage between two points

Using `geoconv`

, we can take some Latitude, Longitude and Elevation (LLE)
and figure out where another LLE point is in reference to our local
tangent plane – for instance, what the bearing (azimuth), elevation (up
and down) and range to the “other” point is from where “we” are.

```
use geoconv::{LLE, Wgs84, Degrees, Meters, AER};
// Alias for a lat/lon/elevation in the Wgs84 coordinate system,
// used by (among many others), GPS -- this is usually what you
// want when you're processing lat/lon information.
type LLEW84 = LLE<Wgs84>;
// "My" point on earth.
let me = LLEW84::new(
Degrees::new(42.352211),
Degrees::new(-71.051315),
Meters::new(0.0),
);
// "Your" point on earth.
let you = LLEW84::new(
Degrees::new(42.320239),
Degrees::new(-70.929482),
Meters::new(100.0),
);
// Compute in what direction I'd need to look to see you.
let look: AER<Degrees> = me.aer_to(&you);
```

## §Determine the coordinates of something you can range

Using `geoconv`

, we can take some observation taken from a point,
and figure out where that point is. Let’s work through
taking a reading in Azimuth, Elevation and Range (AER) and
turning that back into Latitude, Longitude and Elevation (LLE)
given our location.

```
use geoconv::{LLE, Wgs84, Degrees, Meters, AER};
type LLEW84 = LLE<Wgs84>;
// "My" point on earth.
let me = LLEW84::new(
Degrees::new(42.352211),
Degrees::new(-71.051315),
Meters::new(0.0),
);
// I see something straight ahead of me, 45 degrees in elevation (up),
// and 30 meters away.
let observation = AER {
azimuth: Degrees::new(0.0),
elevation: Degrees::new(45.0),
range: Meters::new(30.0),
};
// Assuming I have a perfect reading on where that object is, where
// is that object as a latitude/longitude?
let observed_lle: LLEW84 = observation.to_lle(&me);
```

## §Haversine (Great Circle) distance between two points

In addition to operations on the local tangent plane, sometimes
the two points being measured are far enough away where the range
between two points is *not* the distance you’d travel between them.

For instance, when traving, from San Francisco to Paris, we need to travel along the curve of the earth, rather than directly through the crust of Earth.

To compute distance beyond line of sight between to latitude and longitude points, we can use the Haversine formula to approximate the distance.

Haversine distance **does not** easily take into account elevation,
so the haversine_distance function does not accept a LLE, rather,
a tuple of AngularMeasures, such as Degrees or Radians.

```
use geoconv::{Degrees, haversine_distance, Meters};
// Latitude, then Longitude (in that order) for the tuples
let lat_lon_a = (Degrees::new(22.55), Degrees::new(43.12));
let lat_lob_b = (Degrees::new(13.45), Degrees::new(100.28));
let result: Meters = haversine_distance(lat_lon_a, lat_lob_b);
```

## Modules§

- A Maidenhead Locator is a way of describing a location on earth commonly used by amateur radio operators. These are usually either 4 or 6 bytes long, with increasing precision as the number of bytes increases.

## Structs§

- AER represents an Azimuth, Elevation, and Range measurement.
- Degrees is an angular measure that ranges from 0 to 360 (sometimes negative)
- ENU is East, North, Up in Meters.
- LLE or Latitude, Longitude, Elevation, is a location somewhere around Earth, in refernce to some CoordinateSystem’s ellipsoid.
- Meters represent the SI unit of measure, Meter
- Radians is an angular measure that ranges from 0 to 2π (𝜏).
- Wgs72 (“World Geodetic System 1972”) is a standard published by the United States National Geospatial-Intelligence Agency.
- Wgs84 (“World Geodetic System 1984”) is a standard published and maintained by the United States National Geospatial-Intelligence Agency. This is the CoordinateSystem used by most systems “by default”, including GPS.
- XYZ is the earth-centric XYZ point system.

## Traits§

- CoordinateSystem is a trait to enable converstion between locations (usually Latitude and Longitude, in the form of LLE objects) to absolute points in space and vice versa.