Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

invalid geometries - ST_MakeValid() vs GeosMakeValid()

84 views
Skip to first unread message

Antonio Valanzano

unread,
Jan 22, 2025, 11:21:51 AMJan 22
to SpatiaLite Users
I have a table with polygons and one of this is invalid.

The return string of ST_IsValidReason is:  Ring Self-intersection[143.661926 49.31221] ...

When I try to repair this geometry with

UPDATE russia_poligoni
SET geometry = ST_MakeValid(geometry)
WHERE id_poligoon = 25;

I receive this message:
SQL error: russia_poligoni.geometry violates Geometry constraint [geom-type or SRID not allowed]

if I use

UPDATE russia_poligoni
SET geometry = GeosMakeValid(geometry)
WHERE id_poligono = 25;

everything is fine.

The correction made by GeosMakeValid(geometry) consists of adding an interior ring.

Looking at the documentation "SQL functions reference list" for version 5.1.0
I notice that
ST_MakeValid() is based on RTTOPO
GeosMakeValid() is based on GEOS 3100
and there is this note:
" Note: this function is similar to ST_MakeValid() but is based on a completely different algorithm, so results could be very different.".

Is it possibile that ST_MakeValid is unable to repair a such common situation ?

Does someone  know which are the situations that ST_MakeValid is capable of repairing?

Antonio




Antonio Valanzano

unread,
Jan 23, 2025, 9:51:27 AMJan 23
to SpatiaLite Users
I have built a simplified version of the invalid polygon of my previous post.

SELECT ST_PolygonFromText('POLYGON ((0 0, 0 10, 10 10, 10 0, 5 0, 3 3, 5 6, 7 3, 5 0, 0 0))')

fig_01.JPG
Then I have verified if this polygon is valid or not

SELECT
ST_IsValid(
ST_PolygonFromText('POLYGON ((0 0, 0 10, 10 10, 10 0, 5 0, 3 3, 5 6, 7 3, 5 0, 0 0))')
);
---1 row
0    ==> geometrica non valida

Then I have tried to repair this polygon

SELECT
GeosMakeValid(
ST_PolygonFromText('POLYGON ((0 0, 0 10, 10 10, 10 0, 5 0, 3 3, 5 6, 7 3, 5 0, 0 0))')
);
--1 row
BLOB sz=148 GEOMETRY

-- BLOB explore
SRID: 0
Geometry type: POLYGON

#1 POLYGON:
  1)    exterior ring: 6 vertices

fig_02.JPG
As it  can be seen from the image the "repaired" polygon is not "correct" ( the hole in the bottom part is missing)

Then I have tried to repair the polygon using ST_MakeValid()

SELECT
ST_MakeValid(
ST_PolygonFromText('POLYGON ((0 0, 0 10, 10 10, 10 0, 5 0, 3 3, 5 6, 7 3, 5 0, 0 0))')
);
--1 row
BLOB sz=241 GEOMETRY

-- BLOB explore
SRID: 0
Geometry type: MULTIPOLYGON

#1 POLYGON:
  1)    exterior ring: 6 vertices
  1.1)  interior ring: 5 vertices

fig_03.JPG

This time the repaired polygon is correct, the function ST_MakeValid has created an interior ring.

The results of this simulation are in contrast with those of my previous post where ST_MakeValid wasn't capable of repairing the polygon and
GeosMakeValid() was able to correctly repair the invalid geometry.

I am therefore a little confused about different results in similar situations.

Has someone experienced such strange behaviour of the two functions ?

Antonio

Pieter Roggemans

unread,
Jan 24, 2025, 11:41:12 AMJan 24
to SpatiaLite Users
Making invalid polygons valid is a more interesting topic than you would think at first sight...

In essense: there are many different choices to be made when creating an algorithm to repair a geometry... and there is no (single) correct solution.

Some reading if you are interested:
  • The newest (unreleased) version of Shapely also has two methods to choose from: "linework", probably similar to ST_MakeValid and "structure", probably equal to GeosMakeValid as shapely is also just calling GEOS under the hood: shapely.make_valid
  • A blog post by a developer of JTS (the java "mother" library of GEOS), about the "structure" algorithm
  • Another blog post, about the same "structure" algorithm when it arrived in PostGIS: postgis-3.2-st_makevalid
  • Finally the github issue with all details about the "structure" algorithm: https://github.com/locationtech/jts/issues/652
Pieter

Op donderdag 23 januari 2025 om 15:51:27 UTC+1 schreef Antonio Valanzano:

Antonio Valanzano

unread,
Jan 24, 2025, 3:55:27 PMJan 24
to spatiali...@googlegroups.com
Thanks for the detailed information.
I will read the suggested material.

Antonio

--
You received this message because you are subscribed to a topic in the Google Groups "SpatiaLite Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/spatialite-users/ESPKoPTQ6CY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to spatialite-use...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/spatialite-users/9a20ef99-4f9c-4786-aebf-fbcd66be585dn%40googlegroups.com.

a.fu...@lqt.it

unread,
Jan 24, 2025, 5:15:57 PMJan 24
to spatiali...@googlegroups.com
On Wed, 22 Jan 2025 08:21:51 -0800 (PST), Antonio Valanzano wrote:
> I have a table with polygons and one of this is invalid.
>
> When I try to repair this geometry
>
> I receive this message:
> SQL error: russia_poligoni.geometry violates Geometry constraint
> [geom-type or SRID not allowed]
>

Hi Antonio,

Peter has already given a complete and very detailed answer:
1. repairing an invalid polygon is not a strictly deterministic
science, it's rather a subtle art largely based on empirical
criteria.
2. there are several algorithms, none perfect but all useful
and interesting in their own way.
3. it's not a problem that admits a single exact and precise
solution; each algorithm gives a different answer, it's up
to you to choose the one you think is best (or least bad)
on a case-by-case basis.

That said: if SpatiaLite reports an error when you try to update
the geometry by replacing the invalid one with the repaired one,
the most likely thing is that the "repair" algorithm you are
using has changed the class of the geometry.

A concrete example:

SELECT GeometryType(
GeomFromText(
'POLYGON((0 0, 1 0, 0 1, 1 1, 0 0))'
)):
---------------------------------
POLYGON

SELECT GeometryType(
ST_MakeValid(
GeomFromText(
'POLYGON((0 0, 1 0, 0 1, 1 1, 0 0))'
)));
---------------------------------
MULTIPOLYGON


In these cases it's still possible to recover the repaired
geometry, it just requires a little more work.

In any case you must always first check what kind of
geometry was created by the "repair" algorithm to then
decide the best approach on a case-by-case basis.

Repairing invalid polygons is not a silver bullet to
be fired blindly, it's rather a kind of surgical
operation that requires extreme attention to all
details, always keeping in mind that each case is
different from all the others and that there are
never fixed rules.

bye Sandro

Antonio Valanzano

unread,
Jan 25, 2025, 12:26:52 AMJan 25
to spatiali...@googlegroups.com
Sandro, 
thanks for adding some more specific information about the change of geometry type eventually produced by ST_MakeValid.

However it could be useful to add  in the function reference list also the type of algorithm used respectively by ST_MakeValid ("linework") and GeosMakeVald ("structure") so users can be more aware of the results and also find literature material useful for making the right choice between the two based on the specific situation.

It is just a suggestion.

Antonio

--
You received this message because you are subscribed to a topic in the Google Groups "SpatiaLite Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/spatialite-users/ESPKoPTQ6CY/unsubscribe.
To unsubscribe from this group and all its topics, send an email to spatialite-use...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages