[postgis-tickets] [PostGIS] #5392: Aggregate ST_Union fails to join some "circles" when radius is too large - lwgeom_unaryunion_prec: GEOS Error: TopologyException
PostGIS
trac at osgeo.org
Tue Jun 6 14:38:25 PDT 2023
#5392: Aggregate ST_Union fails to join some "circles" when radius is too large -
lwgeom_unaryunion_prec: GEOS Error: TopologyException
----------------------+---------------------------
Reporter: rotten | Owner: pramsey
Type: defect | Status: closed
Priority: medium | Milestone: PostGIS 3.3.4
Component: postgis | Version: 3.3.x
Resolution: invalid | Keywords:
----------------------+---------------------------
Comment (by robe):
@rotten,
ST_Buffer for geometry is generally fine it's the transforms that
ST_Buffer(geography..) is doing that converts your valid geometry to an
invalid one. There are so many operations that can result in converting a
valid geometry to an invalid one that we don't bother checking. The
exercise is left up to the user.
The issue is with ST_Buffer(geography ...). As noted
https://postgis.net/docs/ST_Buffer.html it does a transform (at least 2)
under the hood to guess at an appropriate spatial ref for your data and
then convert what it came up with to the 4326 you started with. If your
radius is big enough it goes beyond what one can pretend is flat.
Note how the below is invalid
{{{
select
ST_Isvalid( ST_Buffer(
ST_Point(-177.2519031::float8, -18.5973127::float8,
4326)::geography,
290086::integer
)::geometry)
}}}
If you look under the hood of ST_Buffer(geography... is doing)
You will see the hack that pramsey is referring to:
it's determining that this hidden srid 999101 is the best meter based
spatial ref sys for the point you presented
{{{
SELECT _ST_BestSRID(ST_Point(-177.2519031::float8, -18.5973127::float8,
4326));
}}}
-- now take that and buffer it by 290,086 meters
-- still valid right yeh
{{{
SELECT ST_IsValid(ST_Buffer(ST_Transform(ST_Point(-177.2519031::float8,
-18.5973127::float8, 4326), 999101),290086)) ;
}}}
Now try to transform it back to 4326, it's invalid
{{{
SELECT ST_IsValid(ST_Buffer(ST_Transform(ST_Point(-177.2519031::float8,
-18.5973127::float8, 4326), 999101),290086)) ;
}}}
I know it's sad, at a certain point our pretend that the world is flat
goes hay wire when we try to convert it to another flat representation and
the bounds of our flatness stretch beyond what the flat world we picked is
suitable and so the transformation function does its best for and every
flat world eventually reduces to a wraparound
--
Ticket URL: <https://trac.osgeo.org/postgis/ticket/5392#comment:8>
PostGIS <http://trac.osgeo.org/postgis/>
The PostGIS Trac is used for bug, enhancement & task tracking, a user and developer wiki, and a view into the subversion code repository of PostGIS project.
More information about the postgis-tickets
mailing list