Обсуждение: Bad behaviour on some geometric operations on degenerate polygons
Hello. I encountered an unexpected behaviour when doing some geometric operations on polygons that consist of only one point (or more generally, when all points in the polygon are identical). Specifically, taking the center point of such a polygon results in an error message. == Code to reproduce == SELECT @@ polygon '((1, 1))'; == Expected result == (1,1) == Actual result == ERROR: cannot convert empty polygon to circle The same problem exists when one tries to convert a polygon to a point using the point() function (presumably because the same code path is invoked). Ironically, the consequence of this is that the only non-empty polygon that can *not* be converted to a point, is one that occupy precisely a single point. Other operations, such as overlap tests, on the other hand seem to work as one would expect, which leads me to conclude that handling of degenerate polygons is meant to function, and that the behaviour of this particular operation is simply a bug. This bug report applies to at least PostgreSQL versions 9.1.9 and 9.3.0. Other versions, I have not tested. Best Regards, Josef Grahn
On Tue, Oct 15, 2013 at 04:03:58PM +0200, Josef Grahn wrote: > Hello. > > > I encountered an unexpected behaviour when doing some geometric operations on > polygons that consist of only one point (or more generally, when all points in > the polygon are identical). > > Specifically, taking the center point of such a polygon results in an error > message. > > == Code to reproduce == > SELECT @@ polygon '((1, 1))'; > > == Expected result == > (1,1) > > == Actual result == > ERROR: cannot convert empty polygon to circle > > The same problem exists when one tries to convert a polygon to a point using > the point() function (presumably because the same code path is invoked). > Ironically, the consequence of this is that the only non-empty polygon that can > *not* be converted to a point, is one that occupy precisely a single point. > > Other operations, such as overlap tests, on the other hand seem to work as one > would expect, which leads me to conclude that handling of degenerate polygons > is meant to function, and that the behaviour of this particular operation is > simply a bug. > > This bug report applies to at least PostgreSQL versions 9.1.9 and 9.3.0. Other > versions, I have not tested. Thank you for the report; I am just getting to study it. I think you are right. What is happening is that the system wants to convert the poly to a circle, then take its center, but we don't support poly-to-circles with radius zero. What I have done is to add special code to allow getting the center of a single-point polygon _without_ converting to a circle. I think this fixes the two cases you mentioned: test=> SELECT @@ polygon '((1, 1))'; ?column? ---------- (1,1) (1 row) test=> SELECT point(polygon '((1, 1))'); point ------- (1,1) (1 row) but still prevents the creation of a zero-radius circle from a poly: test=> SELECT circle(polygon '((1, 1))'); ERROR: cannot convert empty polygon to circle What is odd however, is that we allow _explicit_ creation of zero-radius circles: test=> SELECT circle '<(1,1),0>'; circle ----------- <(1,1),0> (1 row) so why do we prevent the conversion of single-point polygons to circles with zero radius? I don't know. Patch attached. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + Everyone has their own god. +
Вложения
Bruce Momjian <bruce@momjian.us> writes: > What is odd however, is that we allow _explicit_ creation of zero-radius > circles: > test=> SELECT circle '<(1,1),0>'; > circle > ----------- > <(1,1),0> > (1 row) > so why do we prevent the conversion of single-point polygons to circles > with zero radius? I don't know. Maybe we should rethink that. What you've done here seems like a kluge. regards, tom lane
On Sat, Feb 15, 2014 at 12:00:09AM -0500, Tom Lane wrote: > Bruce Momjian <bruce@momjian.us> writes: > > What is odd however, is that we allow _explicit_ creation of zero-radius > > circles: > > > test=> SELECT circle '<(1,1),0>'; > > circle > > ----------- > > <(1,1),0> > > (1 row) > > > so why do we prevent the conversion of single-point polygons to circles > > with zero radius? I don't know. > > Maybe we should rethink that. What you've done here seems like a kluge. Yes, it would be much easier to allow the zero-radius circles. The attached smaller patch allows all the cases to work: test=> SELECT @@ polygon '((1, 1))'; ?column? ---------- (1,1) (1 row) test=> SELECT point(polygon '((1, 1))'); point ------- (1,1) (1 row) test=> SELECT circle(polygon '((1, 1))'); circle ----------- <(1,1),0> (1 row) -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + Everyone has their own god. +
Вложения
On Sat, Feb 15, 2014 at 12:07:20AM -0500, Bruce Momjian wrote: > On Sat, Feb 15, 2014 at 12:00:09AM -0500, Tom Lane wrote: > > Bruce Momjian <bruce@momjian.us> writes: > > > What is odd however, is that we allow _explicit_ creation of zero-radius > > > circles: > > > > > test=> SELECT circle '<(1,1),0>'; > > > circle > > > ----------- > > > <(1,1),0> > > > (1 row) > > > > > so why do we prevent the conversion of single-point polygons to circles > > > with zero radius? I don't know. > > > > Maybe we should rethink that. What you've done here seems like a kluge. > > Yes, it would be much easier to allow the zero-radius circles. The > attached smaller patch allows all the cases to work: Applied. -- Bruce Momjian <bruce@momjian.us> http://momjian.us EnterpriseDB http://enterprisedb.com + Everyone has their own god. +