/********************************************************************** * * GEOS - Geometry Engine Open Source * http://geos.osgeo.org * * Copyright (C) 2011 Sandro Santilli * * This is free software; you can redistribute and/or modify it under * the terms of the GNU Lesser General Public Licence as published * by the Free Software Foundation. * See the COPYING file for more information. * ********************************************************************** * * Last port: perf/operation/predicate/RectangleIntersectsPerfTest.java r378 (JTS-1.12) * **********************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace geos::geom; using namespace geos::io; class RectangleIntersectsPerfTest { public: RectangleIntersectsPerfTest() : pm(), fact(GeometryFactory::create(&pm, 0)) {} void test(uint32_t nPts) { double size = 100; Coordinate origin(0, 0); Geometry::Ptr sinePoly( createSineStar(origin, size, nPts)->getBoundary() ); /* * Make the geometry "crinkly" by rounding off the points. * This defeats the MonotoneChain optimization in the full relate * algorithm, and provides a more realistic test. */ using geos::precision::SimpleGeometryPrecisionReducer; PrecisionModel p_pm(size / 10); SimpleGeometryPrecisionReducer reducer(&p_pm); Geometry::Ptr sinePolyCrinkly(reducer.reduce(sinePoly.get())); sinePoly.reset(); Geometry& target = *sinePolyCrinkly; testRectangles(target, 30, 5); } private: static const int MAX_ITER = 10; static const int NUM_AOI_PTS = 2000; static const int NUM_LINES = 5000; static const int NUM_LINE_PTS = 1000; PrecisionModel pm; GeometryFactory::Ptr fact; void testRectangles(const Geometry& target, int nRect, double rectSize) { std::vector rects; createRectangles(*target.getEnvelopeInternal(), nRect, rectSize, rects); test(rects, target); for (const Geometry* g: rects) { delete g; } } void test(std::vector& rect, const Geometry& g) { geos::util::Profile sw(""); sw.start(); for(std::size_t i = 0; i < MAX_ITER; i++) { for(std::size_t j = 0; j < rect.size(); j++) { rect[j]->intersects(&g); } } sw.stop(); std::cout << g.getNumPoints() << " points: " << sw.getTot() << " usecs" << std::endl; } // Push newly created geoms to rectLit void createRectangles(const Envelope& env, int nRect, double, std::vector& rectList) { int nSide = 1 + (int)std::sqrt((double) nRect); double dx = env.getWidth() / nSide; double dy = env.getHeight() / nSide; for(int i = 0; i < nSide; i++) { for(int j = 0; j < nSide; j++) { double baseX = env.getMinX() + i * dx; double baseY = env.getMinY() + j * dy; Envelope envRect( baseX, baseX + dx, baseY, baseY + dy); Geometry* rect = fact->toGeometry(&envRect).release(); rectList.push_back(rect); } } } Polygon::Ptr createSineStar(const Coordinate& origin, double size, uint32_t nPts) { using geos::geom::util::SineStarFactory; SineStarFactory gsf(fact.get()); gsf.setCentre(origin); gsf.setSize(size); gsf.setNumPoints(nPts); gsf.setArmLengthRatio(2); gsf.setNumArms(20); Polygon::Ptr poly = gsf.createSineStar(); return poly; } }; int main() { RectangleIntersectsPerfTest tester; tester.test(500); tester.test(100000); }