[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