blob: 5252506c0792055c2ed289a3420cd1452eea72d4 [file] [log] [blame]
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
//
// Copyright (c) 2009-2011 Barend Gehrels, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_TEST_OVERLAY_P_Q_HPP
#define BOOST_GEOMETRY_TEST_OVERLAY_P_Q_HPP
#include <fstream>
#include <iomanip>
//#define BOOST_GEOMETRY_ROBUSTNESS_USE_DIFFERENCE
// For mixing int/float
#if defined(_MSC_VER)
#pragma warning( disable : 4244 )
#pragma warning( disable : 4267 )
#endif
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/multi/multi.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
#include <boost/geometry/domains/gis/io/wkt/wkt.hpp>
#include <boost/geometry/extensions/io/svg/svg_mapper.hpp>
#include <geometry_test_common.hpp>
struct p_q_settings
{
bool svg;
bool also_difference;
bool wkt;
double tolerance;
p_q_settings()
: svg(false)
, also_difference(false)
, wkt(false)
, tolerance(1.0e-6)
{}
};
template <typename OutputType, typename CalculationType, typename G1, typename G2>
static bool test_overlay_p_q(std::string const& caseid,
G1 const& p, G2 const& q,
p_q_settings const& settings)
{
bool result = true;
typedef typename bg::coordinate_type<G1>::type coordinate_type;
typedef typename bg::point_type<G1>::type point_type;
bg::model::multi_polygon<OutputType> out_i, out_u, out_d, out_d2;
CalculationType area_p = bg::area(p);
CalculationType area_q = bg::area(q);
CalculationType area_d1 = 0, area_d2 = 0;
bg::intersection(p, q, out_i);
CalculationType area_i = bg::area(out_i);
bg::union_(p, q, out_u);
CalculationType area_u = bg::area(out_u);
double sum = (area_p + area_q) - area_u - area_i;
bool wrong = std::abs(sum) > settings.tolerance;
if (settings.also_difference)
{
bg::difference(p, q, out_d);
bg::difference(q, p, out_d2);
area_d1 = bg::area(out_d);
area_d2 = bg::area(out_d2);
double sum_d1 = (area_u - area_q) - area_d1;
double sum_d2 = (area_u - area_p) - area_d2;
bool wrong_d1 = std::abs(sum_d1) > settings.tolerance;
bool wrong_d2 = std::abs(sum_d2) > settings.tolerance;
if (wrong_d1 || wrong_d2)
{
wrong = true;
}
}
bool svg = settings.svg;
if (wrong || settings.wkt)
{
if (wrong)
{
result = false;
svg = true;
}
bg::unique(out_i);
bg::unique(out_u);
std::cout
<< "type: " << string_from_type<CalculationType>::name()
<< " id: " << caseid
<< " area i: " << area_i
<< " area u: " << area_u
<< " area p: " << area_p
<< " area q: " << area_q
<< " sum: " << sum;
if (settings.also_difference)
{
std::cout
<< " area d1: " << area_d1
<< " area d2: " << area_d2;
}
std::cout
<< std::endl
<< std::setprecision(9)
<< " p: " << bg::wkt(p) << std::endl
<< " q: " << bg::wkt(q) << std::endl
<< " i: " << bg::wkt(out_i) << std::endl
<< " u: " << bg::wkt(out_u) << std::endl
;
}
if(svg)
{
std::ostringstream filename;
filename << "overlay_" << caseid << "_"
<< string_from_type<coordinate_type>::name()
<< string_from_type<CalculationType>::name()
<< ".svg";
std::ofstream svg(filename.str().c_str());
bg::svg_mapper<point_type> mapper(svg, 500, 500);
mapper.add(p);
mapper.add(q);
// Input shapes in green/blue
mapper.map(p, "fill-opacity:0.5;fill:rgb(153,204,0);"
"stroke:rgb(153,204,0);stroke-width:3");
mapper.map(q, "fill-opacity:0.3;fill:rgb(51,51,153);"
"stroke:rgb(51,51,153);stroke-width:3");
if (settings.also_difference)
{
for (BOOST_AUTO(it, out_d.begin()); it != out_d.end(); ++it)
{
mapper.map(*it,
"opacity:0.8;fill:none;stroke:rgb(255,128,0);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round");
}
for (BOOST_AUTO(it, out_d2.begin()); it != out_d2.end(); ++it)
{
mapper.map(*it,
"opacity:0.8;fill:none;stroke:rgb(255,0,255);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round");
}
}
else
{
for (BOOST_AUTO(it, out_i.begin()); it != out_i.end(); ++it)
{
mapper.map(*it, "fill-opacity:0.1;stroke-opacity:0.4;fill:rgb(255,0,0);"
"stroke:rgb(255,0,0);stroke-width:4");
}
for (BOOST_AUTO(it, out_u.begin()); it != out_u.end(); ++it)
{
mapper.map(*it, "fill-opacity:0.1;stroke-opacity:0.4;fill:rgb(255,0,0);"
"stroke:rgb(255,0,255);stroke-width:4");
}
}
}
return result;
}
#endif // BOOST_GEOMETRY_TEST_OVERLAY_P_Q_HPP