12

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.
5
  • EPSG:4326 is lat long
    – nmtoken
    Commented Jul 10, 2020 at 15:18
  • Hi @nmtoken, can you post a link or links to official EPSG:7030 documentation? The only thing that I see at Spatialreference is this citation as Autority... And explain why you say that 4326 "is not" the standard Geography-datatype reference. (again there 7030 is an authority code) Commented Jul 10, 2020 at 15:35
  • For official should look at the EPSG Geodetic Parameter Registry GML representation for EPSG:7030 is: epsg-registry.org/…
    – nmtoken
    Commented Jul 10, 2020 at 16:27
  • @nmtoken, seems you wrong. It is confuse, but seems that WGS84 is urn:ogc:def:crs:EPSG::4326, a CRS (coordinate reference system). In this link we can see its composition: urn:ogc:def:ellipsoid:EPSG::7030 (an ellipsoid model definition) and urn:ogc:def:datum:EPSG::6326, the current datum of WGS84. Commented Jul 10, 2020 at 20:52
  • 1
    Epsg 4326 is the CRS, I was commenting on the code for the ellipsoid. See WGS84 tag description
    – nmtoken
    Commented Jul 11, 2020 at 5:48

1 Answer 1

24

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.
5
  • Hi, thanks for the good explanations (!). Can you add some comments about ambiguous assertions on the guide? Example 1. about ambiguous functions like float ST_Area(geography geog, boolean use_spheroid=true), that say that you can use 2 parameters only with Geography, but we can use with Geometry(4326), and the behaviour will be the same as Geography, doing supposed same calculus. Example 2. about "Geography vs Geometry" distinct internal libraries, and when PostGIS is mixing calls to both in the same Geometry-parameter function. Commented Jul 10, 2020 at 13:29
  • @PeterKrauss see the update - hope it helps clarifying your comment?
    – geozelot
    Commented Jul 10, 2020 at 14:57
  • 1
    The WGS 84 ellipsoid is not EPSG:4326 the ellipsoid is EPSG:7030
    – nmtoken
    Commented Jul 10, 2020 at 15:17
  • @mmtoken thx., corrected.
    – geozelot
    Commented Jul 10, 2020 at 15:20
  • 1
    To avoid terminological confusion: the named "WGS84" is a CRS (coordinate reference system), so synonyms and human-readable abbreviation for urn:ogc:def:crs:EPSG::4326. Any formal standard CRS is composed by ellipsoid parametrized model reference + datum reference. The WGS84's ellipsoid is EPSG:7030 and the WGS84's datum is EPSG::6326. Commented Jul 11, 2020 at 13:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.