We specify locations on the Earth using coordinates, tuples of numbers that
pinpoint a particular place on the map at some level of precision. But just
knowing the coordinates is not enough; you need to know how to interpret them.

A Spatial Reference (SRS) maps a set of coordinates
to a corresponding real location on the earth.

For example, given the coordinates of a location on the earth:

(-121.5,36.8,2000.0)

Those numbers are meaningless unless you know how to use them.
So combine that with some reference information:

Projected - A local coordinate system takes a limited region of the earth and
“projects” it into a 2D cartesion (X,Y) plane. Examples include UTM, US State Plane,
and Mercator.
(Learn more.)

ECEF - A whole earth, cartesian system. ECEF = Earth Centered Earth Fixed; it is
a 3D cartesion system (X,Y,Z) with the origin (0,0,0) at the earth’s center; the X-axis
intersecting lat/long (0,0), the Y-axis intersecting lat/long (0,-90), and the Z-axis
intersecting the north pole. ECEF is the native system in which osgEarth renders its
graphics. (Learn more)

A datum is a reference point (or set of points) against which geospatial
measurements are made. The same location on earth can have different coordinates
depending on which datum is in use. There are two classes of datum:

A horizontal datum measures positions on the earth. Since the earth is not
a perfect sphere or even a perfect ellipsoid, particular datums are usually
designed to approximate the shape of the earth in a particular region.
Common datums include WGS84 and NAD83 in North America, and ETR89
in Europe.

A vertical datum measures elevation. There are several classes of vertical
datum; osgEarth supports geodetic (based on an ellipsoid) and geoid (based
on a sample set of elevation points around the planet).

osgEarth has the following vertical datums built in:

Geodetic - the default; osgEarth uses the Horizontal datum ellipsoid as a reference

EGM84 geoid

EGM96 geoid - commonly called MSL; used in DTED and KML

EGM2008 geoid

By default, SRS’s in osgEarth use a geodetic vertical datum; i.e., altitude is
measured as “height above ellipsoid (HAE)”.

PROJ4 is a map projections toolkit used by osgEarth and hundreds of other
geospatial applications and toolkits. It has a shorthand represtation for
describing an SRS. Here is the same SRS above, this time in PROJ4 format:

+proj=utm+zone=15+ellps=GRS80+units=m+no_defs

PROJ4 has data tables for all the common components (like UTM zones and datums)
so you don’t have to explicitly define everything like you do with WKT.

The EPSG (the now-defunct European Petroleum Survey Group) established a table
of numerical codes for referencing well-known projections. You can browse a list
of there here. osgEarth will accept
EPSG codes; again for the example above:

epsg:26915

If you know the EPSG code it’s a nice shorthand way to express it. OGR/PROJ4,
which osgEarth requires, includes a large table of EPSG codes.

The SpatialReference class represents an SRS. Lots of classes and functions in
osgEarth require an SRS. Here’s how you create on in code:

constSpatialReference*srs=SpatialReference::get("epsg:4326");

That will give you an SRS. The get() function will accept any of the SRS
representations we discussed above: WKT, PROJ4, EPSG, or Aliases.

If you need an SRS with a vertical datum, express that as a second parameter.
osgEarth support egm84, egm96, and egm2008. Use it like this:

srs=SpatialReference::get("epsg:4326","egm96");

It’s sometimes useful to be able to access an SRS’s component types as well. For
example, every projected SRS has a base geographic SRS that it’s based upon.
You can get this by calling:

geoSRS=srs->getGeographicSRS();

If you’re transforming a projected point to latitude/longitude, that’s the output
SRS you will want.

You can also grab a geocentric (ECEF) SRS corresponding to any SRS, like so:

geocentricSRS=srs->getGeocentricSRS();

SpatialReference has lots of functions for doing transformations, etc. Consult
the header file for information on those. But in practice it is usually best to use
classes like GeoPoint instead of using SpatialReference directly.

A GeoPoint is a georeferenced 2D or 3D point. (“Georeferenced” means that the
coordinate values are paired with an SRS - this means all the information necessary
to plot that point on the map is self-contained.) There are other “Geo” classes
including GeoExtent (a bounding box) and GeoCircle (a bounding circle).

Here is how you create a 2D GeoPoint:

GeoPointpoint(srs,x,y);

You can also create a 3D GeoPoint with an altitude:

GeoPointpoint(srs,x,y,z,ALTMODE_ABSOLUTE);

The ALTMODE_ABSOLUTE is the altitude mode, and it required when you specify
a 3D coordinate:

Always check isValid() because not every point in one SRS can be transformed
into another SRS. UTM Zone 15, for example, is only defined for a 6-degree span
of longitude – values too far outside this range might fail!