2011-11-08 5 views
11

Así que quiero unirme a todos los polígonos interrelacionados en un multi_polígono. ¿Cómo hacer tal cosa?Boost :: Geometry: cómo unir polígonos intersecantes en un multi_polygon?

, teniendo tal imagen (de una multi_polygon verde), que queremos optimizar (podemos ver líneas de puntos amarillos - resultado de la simplificación que, aparentemente, se realizó en cada polígono de multi_polygon no en multi_polygon en general):

enter image description here

y aquí es el código compilables para generar dicha imagen:

#include <iostream> 
#include <fstream> 
#include <boost/assign.hpp> 

#include <boost/algorithm/string.hpp> 
#include <boost/geometry/geometry.hpp> 
#include <boost/geometry/geometries/geometries.hpp> 
#include <boost/geometry/multi/geometries/multi_polygon.hpp> 

#include <boost/geometry/extensions/io/svg/svg_mapper.hpp> 

template <typename Geometry1, typename Geometry2> 
void create_svg(std::string const& filename, Geometry1 const& a, Geometry2 const& b) 
{ 
    typedef typename boost::geometry::point_type<Geometry1>::type point_type; 
    std::ofstream svg(filename.c_str()); 

    boost::geometry::svg_mapper<point_type> mapper(svg, 400, 400); 
    mapper.add(a); 
    mapper.add(b); 

    mapper.map(a, "fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2"); 
    mapper.map(b, "opacity:0.8;fill:none;stroke:rgb(255,128,0);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round"); 
} 


boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > make_point(int x, int y) 
{ 
    boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > return_item; 
    boost::geometry::model::d2::point_xy<double> p1(x, y); 
    boost::geometry::model::d2::point_xy<double> p2(x-1, y); 
    boost::geometry::model::d2::point_xy<double> p3(x-1, y-1); 
    boost::geometry::model::d2::point_xy<double> p4(x, y-1); 

    boost::geometry::append( return_item, p1); 
    boost::geometry::append( return_item, p2); 
    boost::geometry::append( return_item, p3); 
    boost::geometry::append( return_item, p4); 

    return return_item; 

} 

int main() 
{ 
    // create a container for joined points structure 
    boost::geometry::model::multi_polygon< boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > > output, simpl; 

    // join points one by one (because one day we would have many=)) 
    output.push_back(make_point(1,1)); 
    boost::geometry::correct(output); 

    output.push_back(make_point(2,1)); 
    boost::geometry::correct(output); 

    output.push_back(make_point(3,1)); 
    boost::geometry::correct(output); 

    output.push_back(make_point(4,1)); 
    boost::geometry::correct(output); 

    output.push_back(make_point(5,1)); 
    boost::geometry::correct(output); 

    output.push_back(make_point(2,2)); 
    boost::geometry::correct(output); 

    output.push_back(make_point(3,2)); 
    boost::geometry::correct(output); 

    output.push_back(make_point(5,2)); 
    boost::geometry::correct(output); 

    output.push_back(make_point(5,5)); 
    boost::geometry::correct(output); 


    // simplify joined structure 
    boost::geometry::simplify(output, simpl, 0.5); 

    // create an svg image 
    create_svg("make_envelope.svg", output, simpl); 
} 

requiere al menos impulso 1.47.0 y 3 archivos desde boost/geometry/extensions/io/svg/

lo que necesito es simple: ¿cómo agrupar polígonos interrelacionados? En este caso vamos a conseguir 2 polígonos en nuestra multy_poligon como se muestra aquí - rojo y verde:

enter image description here

Actualización:

Así que encontré esta información en dissolve y código de ejemplo creado que utiliza anillos de cels la creación:

#include <iostream> 
#include <fstream> 
#include <boost/assign.hpp> 

//Boost 
#include <boost/algorithm/string.hpp> 
#include <boost/geometry/geometry.hpp> 
#include <boost/geometry/geometries/geometries.hpp> 
#include <boost/geometry/multi/geometries/multi_polygon.hpp> 
#include <boost/geometry/geometries/adapted/boost_tuple.hpp> 

BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian) 

#include <boost/foreach.hpp> 

//Boost Geometry extensions (from trunk) 
#include <boost/geometry/extensions/io/svg/svg_mapper.hpp> 

template <typename Geometry1, typename Geometry2> 
void create_svg(std::string const& filename, Geometry1 const& a, Geometry2 const& b) 
{ 
    typedef typename boost::geometry::point_type<Geometry1>::type point_type; 
    std::ofstream svg(filename.c_str()); 

    boost::geometry::svg_mapper<point_type> mapper(svg, 400, 400); 
    mapper.add(a); 
    mapper.add(b); 

    mapper.map(a, "fill-rule:nonzero;fill-opacity:0.5;fill:rgb(153,204,0);stroke:rgb(153,204,0);stroke-width:2;"); 
    mapper.map(b, "opacity:0.8;fill:none;stroke:rgb(255,128,0);stroke-width:4;stroke-dasharray:1,7;stroke-linecap:round"); 
} 

void make_point(int x, int y, boost::geometry::model::ring<boost::geometry::model::d2::point_xy<double> > & ring) 
{ 
    using namespace boost::assign; 

    ring += 
     boost::geometry::model::d2::point_xy<double>(x-1, y-1), 
     boost::geometry::model::d2::point_xy<double>(x, y-1), 
     boost::geometry::model::d2::point_xy<double>(x, y), 
     boost::geometry::model::d2::point_xy<double>(x-1, y), 
     boost::geometry::model::d2::point_xy<double>(x-1, y-1); 

} 

int main() 
{ 
    using namespace boost::assign; 
    boost::geometry::model::ring<boost::geometry::model::d2::point_xy<double> > ring0, ring1,ring; 

    boost::geometry::model::multi_polygon< boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<double> > > outputw; 

    make_point(1, 1, ring) ; 
    make_point(2, 1, ring) ; 
    make_point(3, 1, ring) ; 
    make_point(4, 1, ring) ; 
    make_point(5, 1, ring) ; 
    make_point(2, 2, ring) ; 
    make_point(3, 2, ring) ; 
    make_point(5, 2, ring) ; 

    boost::geometry::model::ring<boost::geometry::model::d2::point_xy<double> > output; 
    boost::geometry::simplify(ring, output, 1); 

    // create an svg image 
    create_svg("make_envelope.svg", ring, output); 
} 

devuelve como imagen del anillo:

enter image description here

Si pudiéramos usar dissolve para convertirlo en poligon eso realmente resolvería algunos de mis problemas. Pero parece que actualmente no podemos debido a este problema de errores del compilador descrito here

+0

Creo que podría estar buscando para la Conectividad de extracción: http://www.boost.org/doc/libs/1_47_0/libs/ polygon/doc/gtl_connectivity_extraction.htm –

Respuesta

9

¿Qué pasa con el uso de Qt. Si usa un QPolygonF puede llamar a unir, que hace exactamente lo que necesita. Después del unísono, puedes extraer los puntos y volver a colocarlos en tu contenedor de impulso.

Si QT no es una opción echar un vistazo a los algoritmos propuestos aquí http://www.wykobi.com