[geos-devel] symDifference, malfunction or misunderstanding?

Frederik Ramm frederik at remote.org
Fri Nov 27 20:18:19 EST 2009


Dear all,

    apologies for using up about 95% of bandwidth on this list recently. 
I hope that my numerous queries, and your answers, will at least help 
others in my situation in the future through Google et al.

I have a problem with symDifference (in geos-3.0.0 as shipped with 
Ubuntu jaunty, but using the 3.2.0rc2 doesn't change things). Perhaps it 
is a misunderstanding on my part.

I have two symmetric linear rings formed like adjoining angular 
brackets, like this:

+------+------+
|      |(a)   |
|   +--+--+   |
|   |     |   |
|   +--+--+   |
|      |(b)   |
+------+------+

They touch in the middle. Here's the WKT:

LINEARRING (1 4, 3 4, 3 3, 2 3, 2 2, 3 2, 3 1, 1 1, 1 4)
LINEARRING (3 4, 5 4, 5 1, 3 1, 3 2, 4 2, 4 3, 3 3, 3 4)

If I compute the intersection between both, using x->intersection(y), 
then I get what one would expect, namely the two segments labelled "a" 
and "b" in the above diagram:

MULTILINESTRING ((3.00 4.00, 3.00 3.00), (3.00 2.00, 3.00 1.00))

When I do a "symDifference" between the two, I would expect to get the 
original shape minus the "a" and "b" segments, something like

+------+------+
|             |
|   +--+--+   |
|   |     |   |
|   +--+--+   |
|             |
+------+------+

Instead, I get a four-part Multilinestring that contains the original 
shape minus the segment "b", but including the segment "a":

MULTILINESTRING ((1.00 4.00, 3.00 4.00), (3.00 3.00, 2.00 3.00, 2.00 
2.00, 3.00 2.00), (3.00 1.00, 1.00 1.00, 1.00 4.00), (3.00 4.00, 5.00 
4.00, 5.00 1.00, 3.00 1.00), (3.00 2.00, 4.00 2.00, 4.00 3.00, 3.00 3.00))

Just to be on the safe side, I then combined both linear rings into a 
multilinestring (using Union), and then computed the difference between 
this union and the intersection - again expecting to get the shape minus 
"a" and "b", and again getting the shape minus "a" but including "b".

Is this a bug in GEOS, or a bug in my approach?

I'm attaching the full C++ test file.

Bye
Frederik

#include <stdio.h>
#include <geos/geom/PrecisionModel.h>
#include <geos/geom/GeometryFactory.h>
#include <geos/geom/Geometry.h>
#include <geos/io/WKTReader.h>

using namespace geos::geom;
using namespace geos;

GeometryFactory *global_factory;

int main(int argc, char **argv)
{
     PrecisionModel *pm = new PrecisionModel(2.0, 0, 0);
     global_factory = new GeometryFactory(pm, -1);
     delete pm;

     io::WKTReader *reader = new io::WKTReader(global_factory);
     Geometry *a = reader->read(
         "LINEARRING (1 4, 3 4, 3 3, 2 3, 2 2, 3 2, 3 1, 1 1, 1 4)"
         );
     Geometry *b = reader->read(
         "LINEARRING (3 4, 5 4, 5 1, 3 1, 3 2, 4 2, 4 3, 3 3, 3 4)"
         );

     Geometry *inter = a->intersection(b);
     Geometry *diff = a->symDifference(b);

     printf("intersection: %s\n", inter->toString().c_str());
     printf("sym difference: %s\n", diff->toString().c_str());
}

-- 
Frederik Ramm  ##  eMail frederik at remote.org  ##  N49°00'09" E008°23'33"


More information about the geos-devel mailing list