Opened 15 years ago

Last modified 4 years ago

#472 new enhancement

Missing ST_IsValid for Geography Types

Reported by: rfcmedia Owned by: pramsey
Priority: medium Milestone: PostGIS Fund Me
Component: postgis Version: master
Keywords: Cc:

Description

There is no ST_IsValid for geography types.

I do not think casting a geography as a geometry and then running it through ST_IsValid will yield correct results either.

Consider a polygon (-170 0, 170 0, 178 5, 178 -5, -170 0) in degrees on a spherical surface. This is not a valid polygon as there is clearly an intersection between two lines at (178, 0) but this would be considered a valid polygon if it were cast as a geometry.

Change History (7)

comment:1 by pramsey, 15 years ago

Milestone: PostGIS 1.5.2PostGIS 2.0.0

comment:2 by mwtoews, 13 years ago

It would also be valuable to have a regression table to evaluate what is valid or invalid, similar to: http://trac.osgeo.org/postgis/browser/trunk/regress/isvalid_test

comment:3 by strk, 13 years ago

Milestone: PostGIS 2.0.0PostGIS Future
Version: 1.5.Xtrunk

This one doesn't sounds likely to happen for 2.0, correct me if I'm wrong.

comment:4 by robe, 7 years ago

Milestone: PostGIS FuturePostGIS Fund Me

Milestone renamed

comment:5 by mschott, 4 years ago

edit: The code given below is of course specialised for multipolygons and I just figured it does not work for empty geometries (throws rather cryptic error).

This is how I handle geography validity atm. Being aware that this may be resource intensive and that it may still fail e.g. if the object was projected in an st_intersect (where the best_srid is created for both objects together, afaik) with the respective documentation this might actually help some users. Be aware though that casting between geog and geom may introduce errors at a later stage. E.g. st_difference on two valid geoms casted to geog may produce invalid geogs when the resulting geom is casted back.

CREATE OR REPLACE FUNCTION {checkValidGeogFunc}(geography) RETURNS boolean
    AS 'SELECT
            st_isvalid(
                ST_transform(
                    $1::geometry,
                    _ST_bestsrid($1)
                )
            );'
    LANGUAGE SQL
    IMMUTABLE
    RETURNS NULL ON NULL INPUT;

CREATE OR REPLACE FUNCTION {validateGeogFunc}(geography) RETURNS geography
    AS 'SELECT
            ST_transform(
                st_multi(
                    st_collectionextract(
                        st_makevalid(
                            ST_transform(
                                $1::geometry,
                                _ST_bestsrid($1)
                            )
                        ),
                        3
                    )
                ),
                4326
            )::geography;'
    LANGUAGE SQL
    IMMUTABLE
    RETURNS NULL ON NULL INPUT;
Last edited 4 years ago by mschott (previous) (diff)

comment:6 by komzpa, 4 years ago

Best way would be to get your idea of validity tolerance threshold, ST_Segmentize on that and check validity. I.e, select ST_IsValid(ST_Segmentize(geog::geography, 1000)::geometry) will get you an guarantee that there is no issue that's huger than 1000m in geography.

comment:7 by mschott, 4 years ago

That's a great idea!

But I needed to ensure e.g. st_intersection will never fail as it actually does the transformation (afaik).

Note: See TracTickets for help on using tickets.