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; }
// 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; }
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); } }
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(); }