There are three PostGIS functions for checking validity. The first one is the ST_IsValid function. It behaves exactly like ST_IsSimple: it accepts a geometry and returns a Boolean indicating whether the input is valid or not.
SELECT * FROM data_import.ne_110m_land WHERE ST_IsValid(geom) = FALSE;
But what's exactly wrong with returned geometries? PostGIS can return the details of a validity check. Those can be returned in two variants: as a human readable summary or a compound type that includes the summary and location in geometry format. The first variant is named ST_IsValidReason:
SELECT ST_IsValidReason(geom) FROM data_import.ne_110m_land WHERE ST_IsValid(geom) = FALSE;
It returns a summary of test results:
st_isvalidreason
------------------------------------------------------------
Ring Self-intersection[-132.710007884431 54.0400093154234]
The second variant is named ST_IsValidDetail, and returns a valid_detail compound type (similar to a geometry dump) containing three fields:
- valid, of a Boolean type, indicating whether the geometry is valid
- reason, of a text type, indicating the reason for its invalidity (if any)
- location, of a geometry type, indicating the location at which the error was encountered
This variant is useful when making validation reports.
For example:
SELECT ST_IsValidDetail(geom) FROM data_import.ne_110m_land WHERE ST_IsValid(geom) = FALSE;
NOTICE: Ring Self-intersection at or near point -132.71000788443121 54.040009315423447
st_isvaliddetail
-------------------------------------------------------------------------
(f,"Ring Self-intersection",010100000018717462B89660C0B8A376061F054B40)
The following is used to explode it into separate columns:
SELECT (ST_IsValidDetail(geom)).location, (ST_IsValidDetail(geom)).reason FROM data_import.ne_110m_land WHERE ST_IsValid(geom) = FALSE;
NOTICE: Ring Self-intersection at or near point -132.71000788443121 54.040009315423447
location | reason
--------------------------------------------+------------------------
010100000018717462B89660C0B8A376061F054B40 | Ring Self-intersection