Thread: Circles with circle() vs ST_Buffer() Equality equalities

Circles with circle() vs ST_Buffer() Equality equalities

From
PALAYRET Jacques
Date:
Hello,

With PostgreSQL 10.11, I was trying to compare a circle made with the function circle() to the « same » or similar one made thanks to the function ST_Buffer().
-> The circle of type circle : circle('POINT(1 2)'::geometry::point, 0.5::double precision) :
SELECT  ST_AsText(polygon(32, circle('POINT(1 2)'::geometry::point, 0.5::double precision))::geometry) AS circle_cast_as_polygon ;
                                                          circle_cast_as_polygon
-------------------------------------------------------------------------------------------
 POLYGON((0.5 2,0.509607359798385 2.09754516100806,0.538060233744357 2.19134171618254,0.584265193848727 2.2777851165098,0.646446609406726 2.35355339059327,0.722214883490199 2.41573480615127,0.808658283817455 2.46193976625564,0.902454838991936 2.49039264020162,1 2.5,1.09754516100806 2.49039264020162,1.19134171618254 2.46193976625564,1.27778511650982.41573480615127,1.35355339059327 2.35355339059327,1.41573480615127 2.2777851165098,1.46193976625564 2.19134171618254,1.49039264020162 2.09754516100806,1.5 2,1.490392640201621.90245483899194,1.46193976625564 1.80865828381746,1.41573480615127 1.7222148834902,1.35355339059327 1.64644660940673,1.2777851165098 1.58426519384873,1.19134171618255 1.53806023374436,1.09754516100806 1.50960735979838,1 1.5,0.902454838991936 1.50960735979838,0.808658283817455 1.53806023374436,0.722214883490199 1.58426519384873,0.646446609406726 1.64644660940673,0.584265193848727 1.7222148834902,0.538060233744357 1.80865828381745,0.509607359798385 1.90245483899194,0.5 2))

-> The circle of polygon sub-type : ST_Buffer('POINT(1 2)'::geometry, 0.5::double precision) :
SELECT  ST_AsText(ST_Buffer('POINT(1 2)'::geometry, 0.5::double precision)) AS circle_as_polygon_via_ST_Buffer  ;
                                                          circle_as_polygon_via_st_buffer
-------------------------------------------------------------------------------------------
 POLYGON((1.5 2,1.49039264020162 1.90245483899194,1.46193976625564 1.80865828381746,1.41573480615127 1.7222148834902,1.35355339059327 1.64644660940673,1.2777851165098 1.58426519384873,1.19134171618255 1.53806023374436,1.09754516100806 1.50960735979838,1 1.5,0.902454838991937 1.50960735979838,0.808658283817456 1.53806023374436,0.7222148834902 1.58426519384873,0.646446609406727 1.64644660940673,0.584265193848728 1.7222148834902,0.538060233744357 1.80865828381745,0.509607359798385 1.90245483899193,0.5 2,0.509607359798384 2.09754516100806,0.538060233744356 2.19134171618254,0.584265193848726 2.2777851165098,0.646446609406725 2.35355339059327,0.722214883490197 2.41573480615127,0.808658283817453 2.46193976625564,0.902454838991934 2.49039264020161,0.999999999999998 2.5,1.09754516100806 2.49039264020162,1.19134171618254 2.46193976625564,1.2777851165098 2.41573480615127,1.35355339059327 2.35355339059327,1.41573480615127 2.2777851165098,1.46193976625564 2.19134171618255,1.49039264020161 2.09754516100807,1.5 2))

Comparison :
SELECT ST_OrderingEquals(ST_Buffer('POINT(1 2)'::geometry, 0.5::double precision) , polygon(32, circle('POINT(1 2)'::geometry::point, 0.5::double precision))::geometry) ;
 st_orderingequals
-------------------
 f
-> OK, with an ordering polygon equality

=> But, I was surprised by the result of the following 2 SQL queries, in particular by the second one :

SELECT ST_Equals(ST_Buffer('POINT(1 2)'::geometry, 0.5::double precision) , polygon(32, circle('POINT(1 2)'::geometry::point, 0.5::double precision))::geometry) ;
 st_equals
-----------
 f                    <= weird for me !
SELECT ST_Buffer('POINT(1 2)'::geometry, 0.5::double precision) = polygon(32, circle('POINT(1 2)'::geometry::point, 0.5::double precision))::geometry AS BounderingEquals ;
 bounderingequals
------------------
 f                    <= weird for me !

Details (OK) :
SELECT box(polygon(32, circle('POINT(1 2)'::geometry::point, 0.5::double precision))::geometry) AS box_from_circle_through_polygon ;
 box_from_circle_through_polygon
---------------------------------
 (1.5,2.5),(0.5,1.5)
SELECT  box( ST_Buffer('POINT(1 2)'::geometry, 0.5::double precision)) AS box_from_ST_Buffer_polygon ;
 box_from_st_buffer_polygon
----------------------------
 (1.5,2.5),(0.5,1.5)
SELECT box(polygon(32, circle('POINT(1 2)'::geometry::point, 0.5::double precision))::geometry) =  box( ST_Buffer('POINT(1 2)'::geometry, 0.5::double precision)) AS BounderingBoxEquals ;
 bounderingboxequals
---------------------
 t

=> Have you any explanations on the result (=false) of  st_equals (NOT ordering)  and  bounderingequals ?

Thanks in advance.
Regards
----- Météo-France -----
PALAYRET JACQUES
DCSC/MBD
jacques.palayret@meteo.fr
Fixe : +33 561078319

Re: Circles with circle() vs ST_Buffer() Equality equalities

From
PALAYRET Jacques
Date:
Hello,

Sorry, forget my questions.
I checked the differences between the 2 polygons too quickly.
Actually, I checked only some points and some attributes :

SELECT ST_Area(geometry), ST_Perimeter(geometry), ST_NPoints(ST_ExteriorRing(geometry))
FROM (
SELECT polygon(32, circle('POINT(1 2)'::geometry::point, 0.5::double precision))::geometry
UNION
SELECT ST_Buffer('POINT(1 2)'::geometry, 0.5::double precision)
) t(geometry)
;
      st_area      |   st_perimeter   | st_npoints
-------------------+------------------+------------
 0.780361288064513 | 3.13654849054594 |         33
 0.780361288064513 | 3.13654849054594 |         33
----------> exactly the same results with the 2 polygons
...

----------> But, NOT all the points are identical :

SELECT ST_AsText((g1).geom) FROM (
SELECT st_dumppoints(ST_ExteriorRing(geometry))
FROM (
SELECT polygon(32, circle('POINT(1 2)'::geometry::point, 0.5::double precision))::geometry
) t1(geometry)
)t11(g1)
EXCEPT
SELECT ST_AsText((g2).geom) FROM (
SELECT st_dumppoints(ST_ExteriorRing(geometry))
FROM (
SELECT ST_Buffer('POINT(1 2)'::geometry, 0.5::double precision)
) t2(geometry)
)t22(g2)
ORDER BY 1 ;
                 st_astext
-------------------------------------------
 POINT(0.509607359798385 1.90245483899194)
 POINT(0.509607359798385 2.09754516100806)
 POINT(0.538060233744357 2.19134171618254)
 POINT(0.584265193848727 1.7222148834902)
 POINT(0.584265193848727 2.2777851165098)
 POINT(0.646446609406726 1.64644660940673)
 POINT(0.646446609406726 2.35355339059327)
 POINT(0.722214883490199 1.58426519384873)
 POINT(0.722214883490199 2.41573480615127)
 POINT(0.808658283817455 1.53806023374436)
 POINT(0.808658283817455 2.46193976625564)
 POINT(0.902454838991936 1.50960735979838)
 POINT(0.902454838991936 2.49039264020162)
 POINT(1 2.5)
 POINT(1.46193976625564 2.19134171618254)
 POINT(1.49039264020162 2.09754516100806)
(16 lignes)

SELECT ST_AsText((g1).geom) FROM (
SELECT st_dumppoints(ST_ExteriorRing(geometry))
FROM (
SELECT ST_Buffer('POINT(1 2)'::geometry, 0.5::double precision)
) t1(geometry)
)t11(g1)
EXCEPT
SELECT ST_AsText((g2).geom) FROM (
SELECT st_dumppoints(ST_ExteriorRing(geometry))
FROM (
SELECT polygon(32, circle('POINT(1 2)'::geometry::point, 0.5::double precision))::geometry
) t2(geometry)
)t22(g2)
ORDER BY 1 ;
                 st_astext
-------------------------------------------
 POINT(0.509607359798384 2.09754516100806)
 POINT(0.509607359798385 1.90245483899193)
 POINT(0.538060233744356 2.19134171618254)
 POINT(0.584265193848726 2.2777851165098)
 POINT(0.584265193848728 1.7222148834902)
 POINT(0.646446609406725 2.35355339059327)
 POINT(0.646446609406727 1.64644660940673)
 POINT(0.722214883490197 2.41573480615127)
 POINT(0.7222148834902 1.58426519384873)
 POINT(0.808658283817453 2.46193976625564)
 POINT(0.808658283817456 1.53806023374436)
 POINT(0.902454838991934 2.49039264020161)
 POINT(0.902454838991937 1.50960735979838)
 POINT(0.999999999999998 2.5)
 POINT(1.46193976625564 2.19134171618255)
 POINT(1.49039264020161 2.09754516100807)
(16 lignes)

=> It is a bit weird, but it seems there are slight differences on some points.
For example :
POINT(1 2.5)   for   polygon(32, circle('POINT(1 2)'::geometry::point, 0.5::double precision))::geometry
and
POINT(0.999999999999998 2.5)   for   ST_Buffer('POINT(1 2)'::geometry, 0.5::double precision)

I guess it comes from rounding because the start point is not the same for the 2 polygons.


----- Météo-France -----
PALAYRET JACQUES
DCSC/MBD
jacques.palayret@meteo.fr
Fixe : +33 561078319