[GIS] Is the Geometry(4326) an alias for Geography datatype

geography-data-typepostgispostgresqlwgs84

The main reference about Geography datatype seems docs/using_postgis_dbmanagement:

Prior to PostGIS 2.2, the geography type only supported WGS 84 long lat (SRID:4326). For PostGIS 2.2 and above, any long/lat based spatial reference system defined in the spatial_ref_sys table can be used (…)
Regardless which spatial reference system you use, the units returned by the measurement (…) are in meters.

But it is not explicit: when I am "casting to another type" and when PostGIS is using internally the same "Geography calculations", without any casting need?

Other texts, like postgis-intro/geography, and other documents are also confuse: … is a Geometry with no projection a Geography?
The "standard no projection" is Geometry(4326), so, why the need for a Geography data type if PostGIS can detect it by SRID?

Of course, for PostgreSQL is important to change the data type, to do function overloading… But the guide not explains the equivalence schemas in the internal representation.


NOTES

There are some previous answers to earlier questions:

but those questions are not duplicates of this one.

About comments, to avoid terminological confusion: a Geometry with SRID=4326 is not "only lat long". The so-called "WGS84" is a CRS (coordinate reference system), a synonym and human-readable abbreviation for urn:ogc:def:crs:EPSG::4326. Any formal standard CRS is composed by ellipsoid parametrized model reference + parametrized datum reference, so, the formal definition is:

  • the WGS84's ellipsoid is urn:ogc:def:ellipsoid:EPSG::7030;
  • the WGS84's datum is urn:ogc:def:datum:EPSG::6326.

Best Answer

tl;dr: No. But see the update at the end.


GEOMETRY and GEOGRAPHY are different PostgreSQL TYPES; exposed as higher level (SQL), user-defined composite types to the psql environment, but implemented as lower level (C) base types.

These base types are defined on the C level with e.g. their own typemod constraints, TOAST support, data I/O functions, operator classes and casting behaviour. On top of that, both types have their own indexing mechanics.

On the SQL level, both types (optionally) accept a TEXT and a NUMERIC parameter, which translate to geometry type, and spatial reference. Additionally, you can index both with the same command (USING GIST(<geom>)), although internally those indexes differ, and CAST between them almost seamlessly, with some caveats as seen in the example below.

  • In every way, these are different types with fundamentally different mechanics, despite their deliberately similar handling.

Under the hood, the core difference is the mathematical representation and calculation of and with the given coordinates, in two words: planar vs. spheroidal.

The GEOMETRY type is bound by definition to a 2D planar reference, and operates with Cartesian math regardless of the nature of the CRS; distance between two points is a straight line as e.g. per Pythagoras, even if your geometries are defined in a geodetic reference (e.g. EPSG:4326). The GEOMETRY type is meant to work best for projected CRS.

The GEOGRAPHY type is inherently assuming that the given coordinates are geodetic coordinates, thus operating solely on great circle math (spherical) and/or it's more complicated application on spheroidal/ellipsoidal bodies. The GEOGRAPHY type is meant to work with geographic/geodetic RS (Longitudes/Latitudes) only.

  • Neither does PostGIS "the same 'Geography calculations'", nor detects the nature of a given SRS to do so.

The WGS84 ellipsoid (EPSG:7030) is allegedly among the most usable representation of our planet on a global scale, and is widely supported in transformations to and from projections and other ellipsoids. Also, it is and has ever since been the base reference of most of our positioning systems.

It is de facto a global standard for spatial data storage and its interchangeability.

  • In PostGIS, the actual default SRS is no SRS, or 0 (which is bad to have...).

Now, as a small example of what PostGIS does with wrong SRS definitions; you can do this (note that the coordinates should represent degrees...)

SELECT ST_AsText(ST_SetSRID('POINT(1000 1000)'::GEOMETRY, 4326));

returning a valid GEOMETRY

st_astext       |
----------------|
POINT(1000 1000)|

while this

SELECT ST_AsText(ST_SetSRID('POINT(1000 1000)'::GEOGRAPHY, 4326));

returns a valid GEOGRAPHY

st_astext     |
--------------|
POINT(-80 -80)|

along with the note

Coordinate values were coerced into range [-180 -90, 180 90] for GEOGRAPHY

Btw. coercing here means sth. like

  • Lat: -90 + (1000 % 90) = -80
  • Lon: -180 + (1000 % 180) = -80

so it effectively walks around the globe until 1000 degrees are traversed.

Yet the GEOGRAPHY type does not care if you do

SELECT ST_AsText(ST_SetSRID('POINT(1000 1000)'::GEOGRAPHY, 3857));

except for the above note of coordinate range coercion, while it actually should (if it could; we're assigning a SRS on the created type, so it would be the function assigning it that needed to) inform you about the nature of the SRS (and, since we're at it, IMHO also the uselessness of EPSG:3857...).

However, a CAST to GEOGRAPHY will indeed check the SRS and denies the cast for non-geodetic SRS, e.g.

SELECT ST_SetSRID('POINT(0 0)'::GEOMETRY, 3857)::GEOGRAPHY;

will error out with

ERROR: Only lon/lat coordinate systems are supported in geography.
  • In no way does PostGIS any fail-saving for you in these matters, except when using a CAST to GEOGRAPHY.

Update as per comment request:

Because PostGIS defines the cast from GEOMETRY to GEOGRAPHY (and only this way) AS IMPLICIT, PostgreSQL is free to cast any GEOMETRY to GEOGRAPHY whenever it is necessary, or possible, to solve ambuiguity. This affects parameters to functions in the following ways, where PostgreSQL will CAST implicitly:

  • if a distinct signature is unambiguously invoked that accepts only GEOGRAPHY types; an example would be the ST_Area signatures where, when explicitly used with a value for use_spheroid, PG casts a GEOMETRY to GEOGRAPHY

  • an ambiguous signature for both types is used (i.e. a type overloaded function), and only one parameter is passed in as GEOGRAPHY, the other will get cast; an example is ST_DWithin where, when one parameter gets passed as GEOMETRY and the other as GEOGRAPHY, the former will get cast to GEOGRAPHY

One might say, since only the CAST to GEOGRAPHY is IMPLICIT, it has inherent precedence.

In these cases, since the CAST is used, PostGIS will inform you (and deny the execution) if the GEOMETRY in question does not use a geodetic SRS!

  • The secret ingredient to ambiguity is an implicit CAST.
Related Question