1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2011 Sandro Santilli <strk@kbt.io>
*
* 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 <geos/geom/PrecisionModel.h>
#include <geos/geom/GeometryFactory.h>
#include <geos/util/GeometricShapeFactory.h>
#include <geos/precision/SimpleGeometryPrecisionReducer.h>
#include <geos/geom/util/SineStarFactory.h>
#include <geos/geom/Geometry.h>
#include <geos/geom/Polygon.h>
#include <geos/geom/Point.h>
#include <geos/profiler.h>
#include <iostream>
#include <vector>
#include <cmath>
#include <sstream>
#include <memory>
using namespace geos::geom;
using namespace geos::io;
class InteriorPointAreaPerfTest {
public:
InteriorPointAreaPerfTest()
:
pm(),
fact(GeometryFactory::create(&pm, 0))
{
showHeader();
}
void
test(uint32_t nPts)
{
Coordinate origin(ORG_X, ORG_Y);
std::unique_ptr<geos::geom::Polygon> sinePoly =
createSineStar(origin, SIZE, nPts);
/*
* 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;
double scale = nPts / SIZE;
PrecisionModel p_pm(scale);
SimpleGeometryPrecisionReducer reducer(&p_pm);
std::unique_ptr<Geometry> sinePolyCrinkly(reducer.reduce(sinePoly.get()));
sinePoly.reset();
//std::cout << sinePolyCrinkly->toText() << std::endl;
test(*sinePolyCrinkly);
}
const double ORG_X = 100.0;
const double ORG_Y = 100.0;
const double SIZE = 100.0;
const int N_ARMS = 20;
const double ARM_RATIO = 0.3;
const int N_ITER = 100;
private:
PrecisionModel pm;
GeometryFactory::Ptr fact;
void
showHeader() {
std::cout << "Interior Point Area perf test" << std::endl;
std::cout << "# Iterations: " << N_ITER << std::endl;
std::cout << "SineStar: origin: ("
<< ORG_X << ", " << ORG_Y
<< ") size: " << SIZE
<< " # arms: " << N_ARMS
<< " arm ratio: " << ARM_RATIO
<< std::endl;
}
void
test(geos::geom::Geometry& poly)
{
geos::util::Profile sw("");
sw.start();
for(int i = 0; i < N_ITER; i++) {
std::unique_ptr<geos::geom::Point> pt( poly.getInteriorPoint() );
}
sw.stop();
std::cout << poly.getNumPoints() << " points: " << sw.getTotFormatted() << std::endl;
}
std::unique_ptr<geos::geom::Polygon>
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( ARM_RATIO );
gsf.setNumArms( N_ARMS );
std::unique_ptr<geos::geom::Polygon> poly = gsf.createSineStar();
return poly;
}
};
int
main()
{
InteriorPointAreaPerfTest tester;
tester.test(100);
tester.test(1000);
tester.test(10000);
tester.test(100000);
tester.test(1000000);
}
|