Esempio n. 1
0
        bool doTest(const char* const* inputWKT, const char* const* expectWKT)
        {
          using std::cout;
          using std::endl;

          std::vector<Geom*> inputGeoms, expectGeoms;

          readWKT(inputWKT, inputGeoms);
          readWKT(expectWKT, expectGeoms);

          Polygonizer polygonizer;
          polygonizer.add(&inputGeoms);

          std::auto_ptr< std::vector<Poly*> > retGeoms;
          retGeoms.reset( polygonizer.getPolygons() );

          delAll(inputGeoms);

          bool ok = compare(expectGeoms, *retGeoms);
          if  ( ! ok ) {
            cout << "OBTAINED(" << retGeoms->size() << "): ";
            printAll(cout, *retGeoms);
            cout << endl;

            ensure( "not all expected geometries in the obtained set", 0 );
          }

          delAll(expectGeoms);
          delAll(*retGeoms);

          return ok;
        }
Esempio n. 2
0
// Start reading here
void do_all()
{
	vector<Geometry *> *geoms = new vector<Geometry *>;
	vector<Geometry *> *newgeoms;
	
	// Define a precision model using 0,0 as the reference origin
	// and 2.0 as coordinates scale.
	PrecisionModel *pm = new PrecisionModel(2.0, 0, 0);

	// Initialize global factory with defined PrecisionModel
	// and a SRID of -1 (undefined).
	global_factory = new GeometryFactory(pm, -1);

	// We do not need PrecisionMode object anymore, it has
	// been copied to global_factory private storage
	delete pm;

////////////////////////////////////////////////////////////////////////
// GEOMETRY CREATION
////////////////////////////////////////////////////////////////////////

	// Read function bodies to see the magic behind them
	geoms->push_back(create_point(150, 350));
	geoms->push_back(create_square_linearring(0,0,100));
	geoms->push_back(create_ushaped_linestring(60,60,100));
	geoms->push_back(create_square_linearring(0,0,100));
	geoms->push_back(create_square_polygon(0,200,300));
	geoms->push_back(create_square_polygon(0,250,300));
	geoms->push_back(create_simple_collection(geoms));

#if GEOMETRIC_SHAPES
	// These ones use a GeometricShapeFactory
	geoms->push_back(create_circle(0, 0, 10));
	geoms->push_back(create_ellipse(0, 0, 8, 12));
	geoms->push_back(create_rectangle(-5, -5, 10, 10)); // a square
	geoms->push_back(create_rectangle(-5, -5, 10, 20)); // a rectangle
	// The upper-right quarter of a vertical ellipse
	geoms->push_back(create_arc(0, 0, 10, 20, 0, M_PI/2));
	geoms->push_back(create_sinestar(10, 10, 100, 5, 2).release()); // a sine star
#endif

	// Print all geoms.
	cout<<"--------HERE ARE THE BASE GEOMS ----------"<<endl;
	wkt_print_geoms(geoms);


#if UNARY_OPERATIONS

////////////////////////////////////////////////////////////////////////
// UNARY OPERATIONS
////////////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////
	// CENTROID
	/////////////////////////////////////////////
	
	// Find centroid of each base geometry
	newgeoms = new vector<Geometry *>;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g = (*geoms)[i];
		newgeoms->push_back( g->getCentroid() );
	}

	// Print all convex hulls
	cout<<endl<<"------- AND HERE ARE THEIR CENTROIDS -----"<<endl;
	wkt_print_geoms(newgeoms);

	// Delete the centroids
	for (unsigned int i=0; i<newgeoms->size(); i++) {
		delete (*newgeoms)[i];
	}
	delete newgeoms;
	
	/////////////////////////////////////////////
	// BUFFER
	/////////////////////////////////////////////
	
	newgeoms = new vector<Geometry *>;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g = (*geoms)[i];
		try {
			Geometry *g2 = g->buffer(10);
			newgeoms->push_back(g2);
		}
		catch (const GEOSException& exc) {
			cerr <<"GEOS Exception: geometry "<<i<<"->buffer(10): "<<exc.what()<<"\n";
		}
	}

	cout<<endl<<"--------HERE COMES THE BUFFERED GEOMS ----------"<<endl;
	wkt_print_geoms(newgeoms);

	for (unsigned int i=0; i<newgeoms->size(); i++) {
		delete (*newgeoms)[i];
	}
	delete newgeoms;
	
	/////////////////////////////////////////////
	// CONVEX HULL
	/////////////////////////////////////////////
	
	// Make convex hulls of geometries
	newgeoms = new vector<Geometry *>;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g = (*geoms)[i];
		newgeoms->push_back( g->convexHull() );
	}

	// Print all convex hulls
	cout<<endl<<"--------HERE COMES THE HULLS----------"<<endl;
	wkt_print_geoms(newgeoms);

	// Delete the hulls
	for (unsigned int i=0; i<newgeoms->size(); i++) {
		delete (*newgeoms)[i];
	}
	delete newgeoms;

#endif // UNARY_OPERATIONS

#if RELATIONAL_OPERATORS

////////////////////////////////////////////////////////////////////////
// RELATIONAL OPERATORS
////////////////////////////////////////////////////////////////////////

cout<<"-------------------------------------------------------------------------------"<<endl;
cout<<"RELATIONAL OPERATORS"<<endl;
cout<<"-------------------------------------------------------------------------------"<<endl;

	/////////////////////////////////////////////
	// DISJOINT
	/////////////////////////////////////////////

	cout<<endl;
	cout<<"   DISJOINT   ";
	for (unsigned int i=0; i<geoms->size(); i++) {
		cout<<"\t["<<i<<"]";
	}
	cout<<endl;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g1 = (*geoms)[i];
		cout<<"      ["<<i<<"]\t";
		for (unsigned int j=0; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				if ( g1->disjoint(g2) ) cout<<" 1\t";
				else cout<<" 0\t";
			}
			// Geometry Collection is not a valid argument
			catch (const IllegalArgumentException& exc) {
				cout<<" X\t";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
		cout<<endl;
	}
	
	/////////////////////////////////////////////
	// TOUCHES
	/////////////////////////////////////////////

	cout<<endl;
	cout<<"    TOUCHES   ";
	for (unsigned int i=0; i<geoms->size(); i++) {
		cout<<"\t["<<i<<"]";
	}
	cout<<endl;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g1 = (*geoms)[i];
		cout<<"      ["<<i<<"]\t";
		for (unsigned int j=0; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				if ( g1->touches(g2) ) cout<<" 1\t";
				else cout<<" 0\t";
			}
			// Geometry Collection is not a valid argument
			catch (const IllegalArgumentException& exc) {
				cout<<" X\t";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
		cout<<endl;
	}

	/////////////////////////////////////////////
	// INTERSECTS
	/////////////////////////////////////////////

	cout<<endl;
	cout<<" INTERSECTS   ";
	for (unsigned int i=0; i<geoms->size(); i++) {
		cout<<"\t["<<i<<"]";
	}
	cout<<endl;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g1 = (*geoms)[i];
		cout<<"      ["<<i<<"]\t";
		for (unsigned int j=0; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				if ( g1->intersects(g2) ) cout<<" 1\t";
				else cout<<" 0\t";
			}
			// Geometry Collection is not a valid argument
			catch (const IllegalArgumentException& exc) {
				cout<<" X\t";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
		cout<<endl;
	}

	/////////////////////////////////////////////
	// CROSSES
	/////////////////////////////////////////////

	cout<<endl;
	cout<<"    CROSSES   ";
	for (unsigned int i=0; i<geoms->size(); i++) {
		cout<<"\t["<<i<<"]";
	}
	cout<<endl;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g1 = (*geoms)[i];
		cout<<"      ["<<i<<"]\t";
		for (unsigned int j=0; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				if ( g1->crosses(g2) ) cout<<" 1\t";
				else cout<<" 0\t";
			}
			// Geometry Collection is not a valid argument
			catch (const IllegalArgumentException& exc) {
				cout<<" X\t";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
		cout<<endl;
	}

	/////////////////////////////////////////////
	// WITHIN
	/////////////////////////////////////////////

	cout<<endl;
	cout<<"     WITHIN   ";
	for (unsigned int i=0; i<geoms->size(); i++) {
		cout<<"\t["<<i<<"]";
	}
	cout<<endl;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g1 = (*geoms)[i];
		cout<<"      ["<<i<<"]\t";
		for (unsigned int j=0; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				if ( g1->within(g2) ) cout<<" 1\t";
				else cout<<" 0\t";
			}
			// Geometry Collection is not a valid argument
			catch (const IllegalArgumentException& exc) {
				cout<<" X\t";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
		cout<<endl;
	}

	/////////////////////////////////////////////
	// CONTAINS
	/////////////////////////////////////////////

	cout<<endl;
	cout<<"   CONTAINS   ";
	for (unsigned int i=0; i<geoms->size(); i++) {
		cout<<"\t["<<i<<"]";
	}
	cout<<endl;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g1 = (*geoms)[i];
		cout<<"      ["<<i<<"]\t";
		for (unsigned int j=0; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				if ( g1->contains(g2) ) cout<<" 1\t";
				else cout<<" 0\t";
			}
			// Geometry Collection is not a valid argument
			catch (const IllegalArgumentException& exc) {
				cout<<" X\t";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
		cout<<endl;
	}

	/////////////////////////////////////////////
	// OVERLAPS
	/////////////////////////////////////////////
	
	cout<<endl;
	cout<<"   OVERLAPS   ";
	for (unsigned int i=0; i<geoms->size(); i++) {
		cout<<"\t["<<i<<"]";
	}
	cout<<endl;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g1 = (*geoms)[i];
		cout<<"      ["<<i<<"]\t";
		for (unsigned int j=0; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				if ( g1->overlaps(g2) ) cout<<" 1\t";
				else cout<<" 0\t";
			}
			// Geometry Collection is not a valid argument
			catch (const IllegalArgumentException& exc) {
				cout<<" X\t";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
		cout<<endl;
	}

	/////////////////////////////////////////////
	// RELATE
	/////////////////////////////////////////////

	cout<<endl;
	cout<<"     RELATE   ";
	for (unsigned int i=0; i<geoms->size(); i++) {
		cout<<"\t["<<i<<"]";
	}
	cout<<endl;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g1 = (*geoms)[i];
		cout<<"      ["<<i<<"]\t";
		for (unsigned int j=0; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			IntersectionMatrix *im=NULL;
			try {
				// second argument is intersectionPattern
				string pattern = "212101212";
				if ( g1->relate(g2, pattern) ) cout<<" 1\t";
				else cout<<" 0\t";
				
				// get the intersectionMatrix itself
				im=g1->relate(g2);
				delete im; // delete afterwards
			}
			// Geometry Collection is not a valid argument
			catch (const IllegalArgumentException& exc) {
				cout<<" X\t";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
		cout<<endl;
	}

	/////////////////////////////////////////////
	// EQUALS
	/////////////////////////////////////////////

	cout<<endl;
	cout<<"     EQUALS   ";
	for (unsigned int i=0; i<geoms->size(); i++) {
		cout<<"\t["<<i<<"]";
	}
	cout<<endl;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g1 = (*geoms)[i];
		cout<<"      ["<<i<<"]\t";
		for (unsigned int j=0; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				if ( g1->equals(g2) ) cout<<" 1\t";
				else cout<<" 0\t";
			}
			// Geometry Collection is not a valid argument
			catch (const IllegalArgumentException& exc) {
				cout<<" X\t";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
		cout<<endl;
	}

	/////////////////////////////////////////////
	// EQUALS_EXACT
	/////////////////////////////////////////////

	cout<<endl;
	cout<<"EQUALS_EXACT  ";
	for (unsigned int i=0; i<geoms->size(); i++) {
		cout<<"\t["<<i<<"]";
	}
	cout<<endl;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g1 = (*geoms)[i];
		cout<<"      ["<<i<<"]\t";
		for (unsigned int j=0; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				// second argument is a tolerance
				if ( g1->equalsExact(g2, 0.5) ) cout<<" 1\t";
				else cout<<" 0\t";
			}
			// Geometry Collection is not a valid argument
			catch (const IllegalArgumentException& exc) {
				cout<<" X\t";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
		cout<<endl;
	}

	/////////////////////////////////////////////
	// IS_WITHIN_DISTANCE
	/////////////////////////////////////////////

	cout<<endl;
	cout<<"IS_WITHIN_DIST";
	for (unsigned int i=0; i<geoms->size(); i++) {
		cout<<"\t["<<i<<"]";
	}
	cout<<endl;
	for (unsigned int i=0; i<geoms->size(); i++) {
		Geometry *g1 = (*geoms)[i];
		cout<<"      ["<<i<<"]\t";
		for (unsigned int j=0; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				// second argument is the distance
				if ( g1->isWithinDistance(g2,2) ) cout<<" 1\t";
				else cout<<" 0\t";
			}
			// Geometry Collection is not a valid argument
			catch (const IllegalArgumentException& exc) {
				cout<<" X\t";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
		cout<<endl;
	}

#endif // RELATIONAL_OPERATORS

#if COMBINATIONS

////////////////////////////////////////////////////////////////////////
// COMBINATIONS
////////////////////////////////////////////////////////////////////////

cout<<endl;
cout<<"-------------------------------------------------------------------------------"<<endl;
cout<<"COMBINATIONS"<<endl;
cout<<"-------------------------------------------------------------------------------"<<endl;

	/////////////////////////////////////////////
	// UNION
	/////////////////////////////////////////////

	// Make unions of all geoms
	newgeoms = new vector<Geometry *>;
	for (unsigned int i=0; i<geoms->size()-1; i++) {
		Geometry *g1 = (*geoms)[i];
		for (unsigned int j=i+1; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				Geometry *g3 = g1->Union(g2);
				newgeoms->push_back(g3);
			}
			// It's illegal to union a collection ...
			catch (const IllegalArgumentException& ill) {
				//cerr <<ill.toString()<<"\n";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
	}

	// Print all unions
	cout<<endl<<"----- AND HERE ARE SOME UNION COMBINATIONS ------"<<endl;
	wkt_print_geoms(newgeoms);

	// Delete the resulting geoms
	for (unsigned int i=0; i<newgeoms->size(); i++) {
		delete (*newgeoms)[i];
	}
	delete newgeoms;
	

	/////////////////////////////////////////////
	// INTERSECTION
	/////////////////////////////////////////////
	
	// Compute intersection of adhiacent geometries
	newgeoms = new vector<Geometry *>;
	for (unsigned int i=0; i<geoms->size()-1; i++) {
		Geometry *g1 = (*geoms)[i];
		for (unsigned int j=i+1; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				Geometry *g3 = g1->intersection(g2);
				newgeoms->push_back(g3);
			}
			// Collection are illegal as intersection argument
			catch (const IllegalArgumentException& ill) {
				//cerr <<ill.toString()<<"\n";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
	}

	cout<<endl<<"----- HERE ARE SOME INTERSECTIONS COMBINATIONS ------"<<endl;
	wkt_print_geoms(newgeoms);

	// Delete the resulting geoms
	for (unsigned int i=0; i<newgeoms->size(); i++) {
		delete (*newgeoms)[i];
	}
	delete newgeoms;

	/////////////////////////////////////////////
	// DIFFERENCE
	/////////////////////////////////////////////
	
	// Compute difference of adhiacent geometries
	newgeoms = new vector<Geometry *>;
	for (unsigned int i=0; i<geoms->size()-1; i++) {
		Geometry *g1 = (*geoms)[i];
		for (unsigned int j=i+1; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				Geometry *g3 = g1->difference(g2);
				newgeoms->push_back(g3);
			}
			// Collection are illegal as difference argument
			catch (const IllegalArgumentException& ill) {
				//cerr <<ill.toString()<<"\n";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
	}

	cout<<endl<<"----- HERE ARE SOME DIFFERENCE COMBINATIONS ------"<<endl;
	wkt_print_geoms(newgeoms);

	// Delete the resulting geoms
	for (unsigned int i=0; i<newgeoms->size(); i++) {
		delete (*newgeoms)[i];
	}
	delete newgeoms;
	
	/////////////////////////////////////////////
	// SYMMETRIC DIFFERENCE
	/////////////////////////////////////////////
	
	// Compute symmetric difference of adhiacent geometries
	newgeoms = new vector<Geometry *>;
	for (unsigned int i=0; i<geoms->size()-1; i++) {
		Geometry *g1 = (*geoms)[i];
		for (unsigned int j=i+1; j<geoms->size(); j++) {
			Geometry *g2 = (*geoms)[j];
			try {
				Geometry *g3 = g1->symDifference(g2);
				newgeoms->push_back(g3);
			}
			// Collection are illegal as symdifference argument
			catch (const IllegalArgumentException& ill) {
				//cerr <<ill.toString()<<"\n";
			}
			catch (const std::exception& exc) {
				cerr<<exc.what()<<endl;
			}
		}
	}

	cout<<endl<<"----- HERE ARE SYMMETRIC DIFFERENCES ------"<<endl;
	wkt_print_geoms(newgeoms);

	// Delete the resulting geoms
	for (unsigned int i=0; i<newgeoms->size(); i++) {
		delete (*newgeoms)[i];
	}
	delete newgeoms;

#endif // COMBINATIONS

#if LINEMERGE
	
	/////////////////////////////////////////////
	// LINEMERGE
	/////////////////////////////////////////////
	LineMerger lm;
	lm.add(geoms);
	vector<LineString *> *mls = lm.getMergedLineStrings();
	newgeoms = new vector<Geometry *>;
	for (unsigned int i=0; i<mls->size(); i++)
		newgeoms->push_back((*mls)[i]);
	delete mls;

	cout<<endl<<"----- HERE IS THE LINEMERGE OUTPUT ------"<<endl;
	wkt_print_geoms(newgeoms);
	
	// Delete the resulting geoms
	for (unsigned int i=0; i<newgeoms->size(); i++) {
		delete (*newgeoms)[i];
	}
	delete newgeoms;

#endif // LINEMERGE

#if POLYGONIZE

	/////////////////////////////////////////////
	// POLYGONIZE
	/////////////////////////////////////////////
	Polygonizer plgnzr;
	plgnzr.add(geoms);
	vector<Polygon *> *polys = plgnzr.getPolygons();
	newgeoms = new vector<Geometry *>;
	for (unsigned int i=0; i<polys->size(); i++)
		newgeoms->push_back((*polys)[i]);
	delete polys;

	cout<<endl<<"----- HERE IS POLYGONIZE OUTPUT ------"<<endl;
	wkt_print_geoms(newgeoms);
	
	// Delete the resulting geoms
	for (unsigned int i=0; i<newgeoms->size(); i++) {
		delete (*newgeoms)[i];
	}
	delete newgeoms;

#endif // POLYGONIZE

	/////////////////////////////////////////////
	// CLEANUP
	/////////////////////////////////////////////

	// Delete base geometries 
	for (unsigned int i=0; i<geoms->size(); i++) {
		delete (*geoms)[i];
	}
	delete geoms;

	delete global_factory;
}
Esempio n. 3
0
void
XMLTester::parseTest(const TiXmlNode* node)
{
    using namespace operation::overlay;

    typedef std::auto_ptr< geom::Geometry > GeomAutoPtr;

    int success=0; // no success by default
    std::string opName;
    std::string opArg1;
    std::string opArg2;
    std::string opArg3;
    std::string opArg4;
    std::string opRes;

    ++testCount;

    const TiXmlNode* opnode = node->FirstChild("op");
    if ( ! opnode ) throw(runtime_error("case has no op"));

    //dump_to_stdout(opnode);

    const TiXmlElement* opel = opnode->ToElement();

    const char* tmp = opel->Attribute("name");
    if ( tmp ) opName = tmp;

    tmp = opel->Attribute("arg1");
    if ( tmp ) opArg1 = tmp;

    tmp = opel->Attribute("arg2");
    if ( tmp ) opArg2 = tmp;

    tmp = opel->Attribute("arg3");
    if ( tmp ) opArg3 = tmp;

    tmp = opel->Attribute("arg4");
    if ( tmp ) opArg4 = tmp;

    const TiXmlNode* resnode = opnode->FirstChild();
    if ( ! resnode )
    {
        std::stringstream tmp;
        tmp << "op of test " << testCount
            << " of case " << caseCount
            << " has no expected result child";
        throw(runtime_error(tmp.str()));
    }
    opRes = resnode->Value();

    // trim blanks
    opRes=trimBlanks(opRes);
    opName=trimBlanks(opName);
    tolower(opName);

    std::string opSig="";

    if ( opArg1 != "" ) opSig=opArg1;
    if ( opArg2 != "" ) {
        if ( opSig != "" ) opSig += ", ";
        opSig += opArg2;
    }
    if ( opArg3 != "" ) {
        if ( opSig != "" ) opSig += ", ";
        opSig += opArg3;
    }
    if ( opArg4 != "" ) {
        if ( opSig != "" ) opSig += ", ";
        opSig += opArg4;
    }

    opSignature = opName + "(" + opSig + ")";

    std::string actual_result="NONE";

    // expected_result will be modified by specific tests
    // if needed (geometry normalization, for example)
    std::string expected_result=opRes;

    try
    {

        util::Profile profile("op");

        if (opName=="relate")
        {
            std::auto_ptr<geom::IntersectionMatrix> im(gA->relate(gB));
            assert(im.get());

            if (im->matches(opArg3)) actual_result="true";
            else actual_result="false";

            if (actual_result==opRes) success=1;
        }

        else if (opName=="isvalid")
        {
            geom::Geometry *gT=gA;
            if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) {
                gT=gB;
            } 

            if (gT->isValid()) actual_result="true";
            else actual_result="false";

            if (actual_result==opRes) success=1;

        }

        else if (opName=="intersection")
        {

            GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
            gRes->normalize();

#ifndef USE_BINARYOP
            GeomAutoPtr gRealRes(gA->intersection(gB));
#else
            GeomAutoPtr gRealRes = BinaryOp(gA, gB, overlayOp(OverlayOp::opINTERSECTION));
#endif

            gRealRes->normalize();

            if (gRes->compareTo(gRealRes.get())==0) success=1;

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput )
                success &= int(testValid(gRealRes.get(), "result"));
        }

        else if (opName=="union")
        {
            GeomAutoPtr gRes(parseGeometry(opRes, "expected"));

            GeomAutoPtr gRealRes;
            if ( gB ) {
#ifndef USE_BINARYOP
                gRealRes.reset(gA->Union(gB));
#else
                gRealRes = BinaryOp(gA, gB, overlayOp(OverlayOp::opUNION));
#endif
            } else {
                gRealRes = gA->Union();
            }

            if (gRes->equals(gRealRes.get())) success=1;

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput )
                success &= int(testValid(gRealRes.get(), "result"));
        }

        else if (opName=="difference")
        {

            GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
            gRes->normalize();

#ifndef USE_BINARYOP
            GeomAutoPtr gRealRes(gA->difference(gB));
#else
            GeomAutoPtr gRealRes = BinaryOp(gA, gB, overlayOp(OverlayOp::opDIFFERENCE));
#endif
            
            gRealRes->normalize();

            if (gRes->compareTo(gRealRes.get())==0) success=1;

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput )
                success &= int(testValid(gRealRes.get(), "result"));
        }

        else if (opName=="symdifference")
        {
            GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
            gRes->normalize();

#ifndef USE_BINARYOP
            GeomAutoPtr gRealRes(gA->symDifference(gB));
#else
            GeomAutoPtr gRealRes = BinaryOp(gA, gB, overlayOp(OverlayOp::opSYMDIFFERENCE));
#endif

            gRealRes->normalize();

            if (gRes->compareTo(gRealRes.get())==0) success=1;

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput )
                success &= int(testValid(gRealRes.get(), "result"));
        }

        else if (opName=="intersects")
        {
            geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
            geom::Geometry *g2 = opArg2 == "B" ? gB : gA;

            if (g1->intersects(g2)) actual_result="true";
            else actual_result="false";
            
            if (actual_result==opRes) success=1;
        }

        else if (opName=="contains")
        {
            geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
            geom::Geometry *g2 = opArg2 == "B" ? gB : gA;

            if (g1->contains(g2)) actual_result="true";
            else actual_result="false";
            
            if (actual_result==opRes) success=1;
        }

        else if (opName=="within")
        {
            geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
            geom::Geometry *g2 = opArg2 == "B" ? gB : gA;

            if (g1->within(g2)) actual_result="true";
            else actual_result="false";
            
            if (actual_result==opRes) success=1;
        }

        else if (opName=="covers")
        {
            geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
            geom::Geometry *g2 = opArg2 == "B" ? gB : gA;

            if (g1->covers(g2)) actual_result="true";
            else actual_result="false";
            
            if (actual_result==opRes) success=1;
        }

        else if (opName=="coveredby")
        {
            geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
            geom::Geometry *g2 = opArg2 == "B" ? gB : gA;

            if (g1->coveredBy(g2)) actual_result="true";
            else actual_result="false";
            
            if (actual_result==opRes) success=1;
        }

        else if (opName=="getboundary")
        {
            geom::Geometry *gT=gA;
            if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

            GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
            gRes->normalize();

            GeomAutoPtr gRealRes(gT->getBoundary());
            gRealRes->normalize();

            if (gRes->compareTo(gRealRes.get())==0) success=1;

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput )
                success &= int(testValid(gRealRes.get(), "result"));
        }

        else if (opName=="getcentroid")
        {
            geom::Geometry *gT=gA;
            if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

            GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
            gRes->normalize();

            GeomAutoPtr gRealRes(gT->getCentroid());

            if ( gRealRes.get() ) gRealRes->normalize();
            else gRealRes.reset(factory->createPoint());
            gRealRes->normalize();

            if (gRes->compareTo(gRealRes.get())==0) success=1;

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput ) 
                success &= int(testValid(gRealRes.get(), "result"));
        }

        else if (opName=="issimple")
        {
            geom::Geometry *gT=gA;
            if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

            if (gT->isSimple()) actual_result="true";
            else actual_result="false";

            if (actual_result==opRes) success=1;

        }

        else if (opName=="convexhull")
        {
            geom::Geometry *gT=gA;
            if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

            GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
            gRes->normalize();

            GeomAutoPtr gRealRes(gT->convexHull());
            gRealRes->normalize();

            if (gRes->compareTo(gRealRes.get())==0) success=1;

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput ) 
                success &= int(testValid(gRealRes.get(), "result"));
        }

        else if (opName=="buffer")
        {
            using namespace operation::buffer;

            geom::Geometry *gT=gA;
            if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

            GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
            gRes->normalize();

            profile.start();

            GeomAutoPtr gRealRes;
            double dist = std::atof(opArg2.c_str());

            BufferParameters params;
            if ( opArg3 != "" ) {
        params.setQuadrantSegments(std::atoi(opArg3.c_str()));
            }
            

            BufferOp op(gT, params);
            gRealRes.reset(op.getResultGeometry(dist));

            profile.stop();
            gRealRes->normalize();

            // Validate the buffer operation
            success = checkBufferSuccess(*gRes, *gRealRes, dist);

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput )
                success &= int(testValid(gRealRes.get(), "result"));
        }

        else if (opName=="buffersinglesided")
        {
            using namespace operation::buffer;

            geom::Geometry *gT=gA;
            if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

            GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
            gRes->normalize();

            profile.start();

            GeomAutoPtr gRealRes;
            double dist = std::atof(opArg2.c_str());
                
            BufferParameters params ;
            params.setJoinStyle( BufferParameters::JOIN_ROUND ) ;
            if ( opArg3 != "" ) {
        params.setQuadrantSegments( std::atoi(opArg3.c_str()));
            }
            
            bool leftSide = true ;
            if ( opArg4 == "right" )
            {
                leftSide = false ;
            }

            BufferBuilder bufBuilder( params ) ;
            gRealRes.reset( bufBuilder.bufferLineSingleSided(
                                         gT, dist, leftSide ) ) ;

            profile.stop();
            gRealRes->normalize();

            // Validate the single sided buffer operation
            success = checkSingleSidedBufferSuccess(*gRes,
                    *gRealRes, dist);

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput )
                success &= int(testValid(gRealRes.get(), "result"));
        }

        else if (opName=="buffermitredjoin")
        {
            using namespace operation::buffer;

            geom::Geometry *gT=gA;
            if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

            GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
            gRes->normalize();

            profile.start();

            GeomAutoPtr gRealRes;
            double dist = std::atof(opArg2.c_str());

            BufferParameters params;
            params.setJoinStyle(BufferParameters::JOIN_MITRE);

            if ( opArg3 != "" ) {
        params.setQuadrantSegments(std::atoi(opArg3.c_str()));
            }

            BufferOp op(gT, params);
            gRealRes.reset(op.getResultGeometry(dist));

            profile.stop();
            gRealRes->normalize();

            // Validate the buffer operation
            success = checkBufferSuccess(*gRes, *gRealRes, dist);

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput ) 
                success &= int(testValid(gRealRes.get(), "result"));
        }


        else if (opName=="getinteriorpoint")
        {
            geom::Geometry *gT=gA;
            if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

            GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
            gRes->normalize();

            GeomAutoPtr gRealRes(gT->getInteriorPoint());
            if ( gRealRes.get() ) gRealRes->normalize();
            else gRealRes.reset(factory->createPoint());

            if (gRes->compareTo(gRealRes.get())==0) success=1;

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput ) 
                success &= int(testValid(gRealRes.get(), "result"));
        }

        else if (opName=="iswithindistance")
        {
            double dist=std::atof(opArg3.c_str());
            if (gA->isWithinDistance(gB, dist)) {
                actual_result="true";
            } else {
                actual_result="false";
            }

            if (actual_result==opRes) success=1;

        }

        else if (opName=="polygonize")
        {

            GeomAutoPtr gRes(wktreader->read(opRes));
            gRes->normalize();

            Polygonizer plgnzr;
            plgnzr.add(gA);


            std::vector<geos::geom::Polygon *>*polys = plgnzr.getPolygons();
            std::vector<geom::Geometry *>*newgeoms = new std::vector<geom::Geometry *>;
            for (unsigned int i=0; i<polys->size(); i++)
                newgeoms->push_back((*polys)[i]);
            delete polys;

            GeomAutoPtr gRealRes(factory->createGeometryCollection(newgeoms));
            gRealRes->normalize();


            if (gRes->compareTo(gRealRes.get())==0) success=1;

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput )
                success &= int(testValid(gRealRes.get(), "result"));
        }

        else if (opName=="linemerge")
        {
            GeomAutoPtr gRes(wktreader->read(opRes));
            gRes->normalize();

            geom::Geometry *gT=gA;

            if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

            LineMerger merger;
            merger.add(gT);
            std::auto_ptr< std::vector<geom::LineString *> > lines ( merger.getMergedLineStrings() );
            std::vector<geom::Geometry *>*newgeoms = new std::vector<geom::Geometry *>(lines->begin(),
                    lines->end());

            GeomAutoPtr gRealRes(factory->createGeometryCollection(newgeoms));
            gRealRes->normalize();

            if (gRes->compareTo(gRealRes.get())==0) success=1;

            actual_result=printGeom(gRealRes.get());
            expected_result=printGeom(gRes.get());

            if ( testValidOutput ) 
                success &= int(testValid(gRealRes.get(), "result"));
        }

        else if (opName=="areatest")
        {
            char* rest;
            double toleratedDiff = std::strtod(opRes.c_str(), &rest);
            int validOut = 1;

            if ( rest == opRes.c_str() )
            {
                throw std::runtime_error("malformed testcase: missing tolerated area difference in 'areatest' op");
            }

            if ( verbose > 1 )
            {
        std::cerr << "Running intersection for areatest" << std::endl;
            }
#ifndef USE_BINARYOP
            GeomAutoPtr gI(gA->intersection(gB));
#else
            GeomAutoPtr gI = BinaryOp(gA, gB,
                    overlayOp(OverlayOp::opINTERSECTION));
#endif

            if ( testValidOutput )
            {
                validOut &= int(testValid(gI.get(), "areatest intersection"));
            }

            if ( verbose > 1 )
            {
        std::cerr << "Running difference(A,B) for areatest" << std::endl;
            }

#ifndef USE_BINARYOP
            GeomAutoPtr gDab(gA->difference(gB));
#else
            GeomAutoPtr gDab = BinaryOp(gA, gB,
                    overlayOp(OverlayOp::opDIFFERENCE));
#endif

            if ( testValidOutput )
            {
                validOut &= int(testValid(gI.get(), "areatest difference(a,b)"));
            }

            if ( verbose > 1 )
            {
        std::cerr << "Running difference(B,A) for areatest" << std::endl;
            }

#ifndef USE_BINARYOP
            GeomAutoPtr gDba(gB->difference(gA));
#else
            GeomAutoPtr gDba = BinaryOp(gB, gA,
                    overlayOp(OverlayOp::opDIFFERENCE));
#endif

            if ( testValidOutput )
            {
                validOut &= int(testValid(gI.get(), "areatest difference(b,a)"));
            }

            if ( verbose > 1 )
            {
        std::cerr << "Running symdifference for areatest" << std::endl;
            }

#ifndef USE_BINARYOP
            GeomAutoPtr gSD(gA->symDifference(gB));
#else
            GeomAutoPtr gSD = BinaryOp(gA, gB,
                    overlayOp(OverlayOp::opSYMDIFFERENCE));
#endif

            if ( testValidOutput )
            {
                validOut &= int(testValid(gI.get(), "areatest symdifference"));
            }

            if ( verbose > 1 )
            {
        std::cerr << "Running union for areatest" << std::endl;
            }

#ifndef USE_BINARYOP
            GeomAutoPtr gU(gA->Union(gB));
#else
            GeomAutoPtr gU = BinaryOp(gA, gB,
                    overlayOp(OverlayOp::opUNION));
#endif

            double areaA = gA->getArea();
            double areaB = gB->getArea();
            double areaI = gI->getArea(); 
            double areaDab = gDab->getArea();
            double areaDba = gDba->getArea();
            double areaSD = gSD->getArea();
            double areaU = gU->getArea();

            double maxdiff = 0;
            std::string maxdiffop;

            // @ : symdifference
            // - : difference
            // + : union
            // ^ : intersection
        
            // A == ( A ^ B ) + ( A - B )
            double diff = std::fabs ( areaA - areaI - areaDab );
            if ( diff > maxdiff ) {
                maxdiffop = "A == ( A ^ B ) + ( A - B )";
                maxdiff = diff;
            }

            // B == ( A ^ B ) + ( B - A )
            diff = std::fabs ( areaB - areaI - areaDba );
            if ( diff > maxdiff ) {
                maxdiffop = "B == ( A ^ B ) + ( B - A )";
                maxdiff = diff;
            }

            //  ( A @ B ) == ( A - B ) + ( B - A )
            diff = std::fabs ( areaDab + areaDba - areaSD );
            if ( diff > maxdiff ) {
                maxdiffop = "( A @ B ) == ( A - B ) + ( B - A )";
                maxdiff = diff;
            }

            //  ( A u B ) == ( A ^ B ) + ( A @ B )
            diff = std::fabs ( areaI + areaSD - areaU );
            if ( diff > maxdiff ) {
                maxdiffop = "( A u B ) == ( A ^ B ) + ( A @ B )";
                maxdiff = diff;
            }

            if ( maxdiff <= toleratedDiff )
            {
                success = 1 && validOut;
            }

            std::stringstream tmp;
            tmp << maxdiffop << ": " << maxdiff;
            actual_result=tmp.str();
            expected_result=opRes;

        }
        else if (opName=="distance")
        {
            char* rest;
            double distE = std::strtod(opRes.c_str(), &rest);
            if ( rest == opRes.c_str() )
            {
                throw std::runtime_error("malformed testcase: missing expected result in 'distance' op");
            }

            geom::Geometry *g1 = opArg1 == "B" ? gB : gA;
            geom::Geometry *g2 = opArg2 == "B" ? gB : gA;
            double distO = g1->distance(g2);
            std::stringstream ss; ss << distO; 
            actual_result = ss.str();

            // TODO: Use a tolerance ?
            success = ( distO == distE ) ? 1 : 0;
        }

        else
        {
            std::cerr << *curr_file << ":";
            std::cerr << " case" << caseCount << ":";
            std::cerr << " test" << testCount << ": "
                      << opName << "(" << opSig << ")";
            std::cerr << ": skipped (unrecognized)." << std::endl;
            return;
        }

    }
    catch (const std::exception &e)
    {
        std::cerr<<"EXCEPTION on case "<<caseCount
            <<" test "<<testCount<<": "<<e.what()
            <<std::endl;
        actual_result = e.what();
    }
    catch (...)
    {
        std::cerr << "Unknown EXEPTION on case "
                  << caseCount
                  << std::endl;
        actual_result = "Unknown exception thrown";
    }

    if ( success ) ++succeeded;
    else ++failed;

    if ((!success && verbose) || verbose > 1)
    {
        printTest(!!success, expected_result, actual_result);
    }

    if (test_predicates && gB && gA) {
        runPredicates(gA, gB);
    }

}
Esempio n. 4
0
void
XMLTester::parseTest()
{
	using namespace operation::overlay;

	typedef std::auto_ptr< geom::Geometry > GeomAutoPtr;

	int success=0; // no success by default
	std::string opName;
	std::string opArg1;
	std::string opArg2;
	std::string opArg3;
	std::string opRes;
	//string opSig;

	++testCount;

	xml.IntoElem();
	xml.FindChildElem("op");
	opName=xml.GetChildAttrib("name");
	opArg1=xml.GetChildAttrib("arg1");
	opArg2=xml.GetChildAttrib("arg2");
	opArg3=xml.GetChildAttrib("arg3");
	//opSig=xml.GetChildAttrib("arg3");
	opRes=xml.GetChildData();

	// trim blanks
	opRes=trimBlanks(opRes);
	opName=trimBlanks(opName);
	tolower(opName);

	std::string opSig="";

	if ( opArg1 != "" ) opSig=opArg1;
	if ( opArg2 != "" ) {
		if ( opSig != "" ) opSig += ", ";
		opSig += opArg2;
	}
	if ( opArg3 != "" ) {
		if ( opSig != "" ) opSig += ", ";
		opSig += opArg3;
	}

	opSignature = opName + "(" + opSig + ")";

	std::string actual_result="NONE";

	// expected_result will be modified by specific tests
	// if needed (geometry normalization, for example)
	std::string expected_result=opRes;

	try
	{

		util::Profile profile("op");

		if (opName=="relate")
		{
			std::auto_ptr<geom::IntersectionMatrix> im(gA->relate(gB));
			assert(im.get());

			if (im->matches(opArg3)) actual_result="true";
			else actual_result="false";

			if (actual_result==opRes) success=1;
		}

		else if (opName=="isvalid")
		{
			geom::Geometry *gT=gA;
			if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) {
				gT=gB;
			} 

			if (gT->isValid()) actual_result="true";
			else actual_result="false";

			if (actual_result==opRes) success=1;

		}

		else if (opName=="intersection")
		{

			GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
			gRes->normalize();

			//GeomAutoPtr gRealRes(gA->intersection(gB));
			GeomAutoPtr gRealRes = BinaryOp(gA, gB, overlayOp(OverlayOp::opINTERSECTION));
			gRealRes->normalize();

			if (gRes->compareTo(gRealRes.get())==0) success=1;

			if ( testValidOutput ) testValid(gRes.get(), "result");

			actual_result=printGeom(gRealRes.get());
			expected_result=printGeom(gRes.get());

		}

		else if (opName=="union")
		{
			GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
			gRes->normalize();

			//GeomAutoPtr gRealRes(gA->Union(gB));
			GeomAutoPtr gRealRes = BinaryOp(gA, gB, overlayOp(OverlayOp::opUNION));
			gRealRes->normalize();

			if (gRes->compareTo(gRealRes.get())==0) success=1;

			if ( testValidOutput ) testValid(gRes.get(), "result");

			actual_result=printGeom(gRealRes.get());
			expected_result=printGeom(gRes.get());
		}

		else if (opName=="difference")
		{

			GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
			gRes->normalize();

			//GeomAutoPtr gRealRes(gA->difference(gB));
			GeomAutoPtr gRealRes = BinaryOp(gA, gB, overlayOp(OverlayOp::opDIFFERENCE));
			
			gRealRes->normalize();

			if (gRes->compareTo(gRealRes.get())==0) success=1;

			if ( testValidOutput ) testValid(gRes.get(), "result");

			actual_result=printGeom(gRealRes.get());
			expected_result=printGeom(gRes.get());

		}

		else if (opName=="symdifference")
		{
			GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
			gRes->normalize();

			//GeomAutoPtr gRealRes(gA->symDifference(gB));
			GeomAutoPtr gRealRes = BinaryOp(gA, gB, overlayOp(OverlayOp::opSYMDIFFERENCE));
			gRealRes->normalize();

			if (gRes->compareTo(gRealRes.get())==0) success=1;

			if ( testValidOutput ) testValid(gRes.get(), "result");

			actual_result=printGeom(gRealRes.get());
			expected_result=printGeom(gRes.get());

		}

		else if (opName=="intersects")
		{
			if (gA->intersects(gB)) actual_result="true";
			else actual_result="false";
			
			if (actual_result==opRes) success=1;
		}

		else if (opName=="getboundary")
		{
			geom::Geometry *gT=gA;
			if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

			GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
			gRes->normalize();

			GeomAutoPtr gRealRes(gT->getBoundary());
			gRealRes->normalize();

			if (gRes->compareTo(gRealRes.get())==0) success=1;

			if ( testValidOutput ) testValid(gRes.get(), "result");

			actual_result=printGeom(gRealRes.get());
			expected_result=printGeom(gRes.get());

		}

		else if (opName=="getcentroid")
		{
			geom::Geometry *gT=gA;
			if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

			GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
			gRes->normalize();

			GeomAutoPtr gRealRes(gT->getCentroid());

			if ( gRealRes.get() ) gRealRes->normalize();
			else gRealRes.reset(factory->createGeometryCollection());
			gRealRes->normalize();

			if (gRes->compareTo(gRealRes.get())==0) success=1;

			if ( testValidOutput ) testValid(gRes.get(), "result");

			actual_result=printGeom(gRealRes.get());
			expected_result=printGeom(gRes.get());

		}

		else if (opName=="issimple")
		{
			geom::Geometry *gT=gA;
			if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

			if (gT->isSimple()) actual_result="true";
			else actual_result="false";

			if (actual_result==opRes) success=1;

		}

		else if (opName=="convexhull")
		{
			geom::Geometry *gT=gA;
			if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

			GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
			gRes->normalize();

			GeomAutoPtr gRealRes(gT->convexHull());
			gRealRes->normalize();

			if (gRes->compareTo(gRealRes.get())==0) success=1;

			if ( testValidOutput ) testValid(gRes.get(), "result");

			actual_result=printGeom(gRealRes.get());
			expected_result=printGeom(gRes.get());

		}

		else if (opName=="buffer")
		{
			geom::Geometry *gT=gA;
			if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

			GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
			gRes->normalize();

			profile.start();

			GeomAutoPtr gRealRes;
			double dist = atof(opArg3.c_str());

			if ( opArg2 != "" ) {
				gRealRes.reset(gT->buffer(dist, atoi(opArg2.c_str())));
			} else {
				gRealRes.reset(gT->buffer(dist));
			}
			profile.stop();
			gRealRes->normalize();

			// Assume a success and check for obvious failures
			success=1;
			do
			{
				// TODO: Is a buffer always an area ?
				// 	 we might check geometry type..

				if ( gRes->getGeometryTypeId() != gRealRes->getGeometryTypeId() )
				{
					std::cerr << "Expected result is of type "
					        << gRes->getGeometryType()
						<< "; obtained result is of type "
						<< gRealRes->getGeometryType()
						<< std::endl;
					success=0;
					break;
				}

				if ( gRes->isEmpty() && gRealRes->isEmpty() )
				{
					// Success !
					break;
				}

				if ( gRes->getDimension() != 2 )
				{
					std::cerr << "Don't know how to validate "
						<< "result of buffer operation "
						<< "when expected result is not an "
						<< "areal type."
						<< std::endl;
				}
				
				double expectedArea = gRes->getArea();

				/// Allow area difference being at most
				/// 1/1000 of the area of the expected result.
				double areatol = expectedArea / 1e3;

				GeomAutoPtr gDiff = BinaryOp(gRes.get(), gRealRes.get(),
					overlayOp(OverlayOp::opDIFFERENCE));

				double areaDiff = gDiff->getArea();
				if ( areaDiff > areatol )
				{
					std::cerr << "Area of difference between "
						<< "obtained and expected: "
						<< areaDiff << " - Tolerated diff: "
						<< areatol << std::endl;
					success=0;
					break;
				}
				else
				{
					std::cerr << "Area of difference between "
						<< "obtained and expected: "
						<< areaDiff << " - Tolerated diff: "
						<< areatol << " (SUCCESS!)"
						<< std::endl;
				}

			}
			while (0);

			if ( testValidOutput ) testValid(gRes.get(), "result");

			actual_result=printGeom(gRealRes.get());
			expected_result=printGeom(gRes.get());
		}

		else if (opName=="getinteriorpoint")
		{
			geom::Geometry *gT=gA;
			if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

			GeomAutoPtr gRes(parseGeometry(opRes, "expected"));
			gRes->normalize();

			GeomAutoPtr gRealRes(gT->getInteriorPoint());
			if ( gRealRes.get() ) gRealRes->normalize();
			else gRealRes.reset(factory->createGeometryCollection());

			if (gRes->compareTo(gRealRes.get())==0) success=1;

			if ( testValidOutput ) testValid(gRes.get(), "result");

			actual_result=printGeom(gRealRes.get());
			expected_result=printGeom(gRes.get());

		}

		else if (opName=="iswithindistance")
		{
			float dist=atof(opArg3.c_str());
			if (gA->isWithinDistance(gB, dist)) {
				actual_result="true";
			} else {
				actual_result="false";
			}

			if (actual_result==opRes) success=1;

		}

		else if (opName=="polygonize")
		{

			GeomAutoPtr gRes(wktreader->read(opRes));
			gRes->normalize();

			Polygonizer plgnzr;
			plgnzr.add(gA);


            std::vector<geos::geom::Polygon *>*polys = plgnzr.getPolygons();
			std::vector<geom::Geometry *>*newgeoms = new std::vector<geom::Geometry *>;
			for (unsigned int i=0; i<polys->size(); i++)
				newgeoms->push_back((*polys)[i]);
			delete polys;

			GeomAutoPtr gRealRes(factory->createGeometryCollection(newgeoms));
			gRealRes->normalize();


			if (gRes->compareTo(gRealRes.get())==0) success=1;

			if ( testValidOutput ) testValid(gRes.get(), "result");

			actual_result=printGeom(gRealRes.get());
			expected_result=printGeom(gRes.get());

		}

		else if (opName=="linemerge")
		{
			GeomAutoPtr gRes(wktreader->read(opRes));
			gRes->normalize();

			geom::Geometry *gT=gA;

			if ( ( opArg1 == "B" || opArg1 == "b" ) && gB ) gT=gB;

			LineMerger merger;
			merger.add(gT);
			std::auto_ptr< std::vector<geom::LineString *> > lines ( merger.getMergedLineStrings() );
			std::vector<geom::Geometry *>*newgeoms = new std::vector<geom::Geometry *>(lines->begin(),
					lines->end());

			GeomAutoPtr gRealRes(factory->createGeometryCollection(newgeoms));
			gRealRes->normalize();

			if (gRes->compareTo(gRealRes.get())==0) success=1;

			if ( testValidOutput ) testValid(gRes.get(), "result");

			actual_result=printGeom(gRealRes.get());
			expected_result=printGeom(gRes.get());

		}

		else if (opName=="areatest")
		{
			char* rest;
			double toleratedDiff = strtod(opRes.c_str(), &rest);
			if ( rest == opRes.c_str() )
			{
				throw std::runtime_error("malformed testcase: missing tolerated area difference in 'areatest' op");
			}

			if ( verbose > 1 )
			{
		std::cerr << "Running intersection for areatest" << std::endl;
			}
			GeomAutoPtr gI = BinaryOp(gA, gB,
					overlayOp(OverlayOp::opINTERSECTION));

			if ( testValidOutput )
			{
				testValid(gI.get(), "areatest intersection");
			}

			if ( verbose > 1 )
			{
		std::cerr << "Running difference(A,B) for areatest" << std::endl;
			}
			GeomAutoPtr gDab = BinaryOp(gA, gB,
					overlayOp(OverlayOp::opDIFFERENCE));

			if ( verbose > 1 )
			{
		std::cerr << "Running difference(B,A) for areatest" << std::endl;
			}
			GeomAutoPtr gDba = BinaryOp(gB, gA,
					overlayOp(OverlayOp::opDIFFERENCE));

			if ( testValidOutput )
			{
				testValid(gI.get(), "areatest difference");
			}

			if ( verbose > 1 )
			{
		std::cerr << "Running symdifference for areatest" << std::endl;
			}
			GeomAutoPtr gSD = BinaryOp(gA, gB,
					overlayOp(OverlayOp::opSYMDIFFERENCE));

			if ( verbose > 1 )
			{
		std::cerr << "Running union for areatest" << std::endl;
			}
			GeomAutoPtr gU = BinaryOp(gA, gB,
					overlayOp(OverlayOp::opUNION));

			double areaA = gA->getArea();
			double areaB = gB->getArea();
			double areaI = gI->getArea(); 
			double areaDab = gDab->getArea();
			double areaDba = gDba->getArea();
			double areaSD = gSD->getArea();
			double areaU = gU->getArea();

			double maxdiff = 0;
			std::string maxdiffop;

			// @ : symdifference
			// - : difference
			// + : union
			// ^ : intersection
		
			// A == ( A ^ B ) + ( A - B )
			double diff = fabs ( areaA - areaI - areaDab );
			if ( diff > maxdiff ) {
				maxdiffop = "A == ( A ^ B ) + ( A - B )";
				maxdiff = diff;
			}

			// B == ( A ^ B ) + ( B - A )
			diff = fabs ( areaB - areaI - areaDba );
			if ( diff > maxdiff ) {
				maxdiffop = "B == ( A ^ B ) + ( B - A )";
				maxdiff = diff;
			}

			//  ( A @ B ) == ( A - B ) + ( B - A )
			diff = fabs ( areaDab + areaDba - areaSD );
			if ( diff > maxdiff ) {
				maxdiffop = "( A @ B ) == ( A - B ) + ( B - A )";
				maxdiff = diff;
			}

			//  ( A u B ) == ( A ^ B ) + ( A @ B )
			diff = fabs ( areaI + areaSD - areaU );
			if ( diff > maxdiff ) {
				maxdiffop = "( A u B ) == ( A ^ B ) + ( A @ B )";
				maxdiff = diff;
			}

			if ( maxdiff <= toleratedDiff )
			{
				success=1;
			}

			std::stringstream tmp;
			tmp << maxdiffop << ": " << maxdiff;
			actual_result=tmp.str();
			expected_result=opRes;

		}

		else
		{
			std::cerr << *curr_file << ":";
			std::cerr << " case" << caseCount << ":";
			std::cerr << " test" << testCount << ": "
					  << opName << "(" << opSig << ")";
			std::cerr << ": skipped (unrecognized)." << std::endl;
			return;
		}

	}
	catch (const std::exception &e)
	{
		std::cerr<<"EXCEPTION on case "<<caseCount
			<<" test "<<testCount<<": "<<e.what()
			<<std::endl;
		actual_result = e.what();
	}
	catch (...)
	{
		std::cerr<<"EXEPTION"<<std::endl;
		actual_result = "Unknown exception thrown";
	}

	if ( success ) ++succeeded;
	else ++failed;

	if ((!success && verbose) || verbose > 1)
	{
		printTest(success, expected_result, actual_result);
	}

	if (test_predicates && gB && gA) {
		runPredicates(gA, gB);
	}

	xml.OutOfElem();
}