[geos-devel] Envelope of empty Polygon

Mateusz Łoskot mateusz at loskot.net
Tue Apr 4 21:53:31 EDT 2006


Mateusz Łoskot wrote:
> strk at refractions.net wrote:
>>> 
>>> Is this correct behaviour? Is empty polygon assumed to return 
>>> non-empty envelope as above?
>> Doens't seem correct. Envelope does have a NULL representation, 
>> which is minx > maxx miny > maxy See Envelope::isNull()
> 
> 
> Ups! It was my fail. As I see, Envelope::setToNull() seems to be ok, 
> as you said above:
> 
> void Envelope::setToNull() { minx=0; maxx=-1; miny=0; maxy=-1; }

Actually, it seems the getEnvelope() for (some?) empty geometries does
not work correctly.
I investigated it in details and here is what I see.
I have empty polygon.
I call Polygon::getEnvelope().
This function calls Geometry::getEnvelope() which subsequently calls
Geometry::computeEnvelopeInternal().
The Geometry::computeEnvelopeInternal() function allocates new Envelope:

new Envelope(*(shell->getEnvelopeInternal())); // <--- [1]

using Envelope's copy constructor and passes Envelope returned by
Geometry::getEnvelopeInternal() call.
In fact, for polygon LineString::computeEnvelopeInternal() is called
which checks if LineString (LinearRing in fact) is empty:
// LineString.cpp:229
if (isEmpty()) {
   // Should return NULL instead ?
   return new Envelope();
}

and returns new empty Envelope initialized by Envelope::setToNull(), so
Envelope corners have following values:

minx = 0;
maxx = -1;
miny = 0;
maxy = -1;

NOTE: Everything works correctly, so far.

Now, let's move back to the Envelope's copy ctor from called in [1]:

new Envelope(*(shell->getEnvelopeInternal()));

Here, empty envelope is returned by getEnvelopeInternal() and is
immediately passed to copy ctor of Envelope class.
AND HERE TROUBLES BEGIN.

Envelope::Envelope(const Envelope &env)
{
   init(env.minx, env.maxx, env.miny, env.maxy);
}

As you see above, copy ctor calls init() passing 'env' - a null Envelope
returned from getEnvelopeInternal() call.

But the
Envelope::init(double x1, double x2, double y1, double y2)
call reorganizes min/max values of corners to make Envelope properly
oriented. This reorganizations brokes the state of Envelope - null
state. So, null Envelope stops to be null with some magic :-)

Here is the screenshot from debugging session under VC++:
http://mateusz.loskot.net/chwila/geos-empty-polygon-getenvelope-notempty.jpg

You can see the state of input/output envelope just after init()
execution has been left. I hope it presents the problem very well.

Cheers
-- 
Mateusz Łoskot
http://mateusz.loskot.net



More information about the geos-devel mailing list