コード例 #1
0
ファイル: overlay.hpp プロジェクト: OggYiu/rag-engine
    static inline OutputIterator apply(
                Geometry1 const& geometry1, Geometry2 const& geometry2,
                RobustPolicy const& robust_policy,
                OutputIterator out,
                Strategy const& )
    {
        if ( geometry::num_points(geometry1) == 0
          && geometry::num_points(geometry2) == 0 )
        {
            return out;
        }

        if ( geometry::num_points(geometry1) == 0
          || geometry::num_points(geometry2) == 0 )
        {
            return return_if_one_input_is_empty
                <
                    GeometryOut, Direction, ReverseOut
                >(geometry1, geometry2, out);
        }

        typedef typename geometry::point_type<GeometryOut>::type point_type;
        typedef detail::overlay::traversal_turn_info
        <
            point_type,
            typename geometry::segment_ratio_type<point_type, RobustPolicy>::type
        > turn_info;
        typedef std::deque<turn_info> container_type;

        typedef std::deque
            <
                typename geometry::ring_type<GeometryOut>::type
            > ring_container_type;

        container_type turn_points;

#ifdef BOOST_GEOMETRY_TIME_OVERLAY
        boost::timer timer;
#endif

#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
std::cout << "get turns" << std::endl;
#endif
        detail::get_turns::no_interrupt_policy policy;
        geometry::get_turns
            <
                Reverse1, Reverse2,
                detail::overlay::assign_null_policy
            >(geometry1, geometry2, robust_policy, turn_points, policy);

#ifdef BOOST_GEOMETRY_TIME_OVERLAY
        std::cout << "get_turns: " << timer.elapsed() << std::endl;
#endif

#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
std::cout << "enrich" << std::endl;
#endif
        typename Strategy::side_strategy_type side_strategy;
        geometry::enrich_intersection_points<Reverse1, Reverse2>(turn_points,
                Direction == overlay_union
                    ? geometry::detail::overlay::operation_union
                    : geometry::detail::overlay::operation_intersection,
                    geometry1, geometry2,
                    robust_policy,
                    side_strategy);

#ifdef BOOST_GEOMETRY_TIME_OVERLAY
        std::cout << "enrich_intersection_points: " << timer.elapsed() << std::endl;
#endif


#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
std::cout << "traverse" << std::endl;
#endif
        // Traverse through intersection/turn points and create rings of them.
        // Note that these rings are always in clockwise order, even in CCW polygons,
        // and are marked as "to be reversed" below
        ring_container_type rings;
        traverse<Reverse1, Reverse2, Geometry1, Geometry2>::apply
                (
                    geometry1, geometry2,
                    Direction == overlay_union
                        ? geometry::detail::overlay::operation_union
                        : geometry::detail::overlay::operation_intersection,
                    robust_policy,
                    turn_points, rings
                );

#ifdef BOOST_GEOMETRY_TIME_OVERLAY
        std::cout << "traverse: " << timer.elapsed() << std::endl;
#endif


        std::map<ring_identifier, int> map;
        map_turns(map, turn_points);

#ifdef BOOST_GEOMETRY_TIME_OVERLAY
        std::cout << "map_turns: " << timer.elapsed() << std::endl;
#endif

        typedef ring_properties<typename geometry::point_type<GeometryOut>::type> properties;

        std::map<ring_identifier, properties> selected;
        select_rings<Direction>(geometry1, geometry2, map, selected, ! turn_points.empty());

#ifdef BOOST_GEOMETRY_TIME_OVERLAY
        std::cout << "select_rings: " << timer.elapsed() << std::endl;
#endif


        // Add rings created during traversal
        {
            ring_identifier id(2, 0, -1);
            for (typename boost::range_iterator<ring_container_type>::type
                    it = boost::begin(rings);
                 it != boost::end(rings);
                 ++it)
            {
                selected[id] = properties(*it, true);
                selected[id].reversed = ReverseOut;
                id.multi_index++;
            }
        }

#ifdef BOOST_GEOMETRY_TIME_OVERLAY
        std::cout << "add traversal rings: " << timer.elapsed() << std::endl;
#endif


        assign_parents(geometry1, geometry2, rings, selected);

#ifdef BOOST_GEOMETRY_TIME_OVERLAY
        std::cout << "assign_parents: " << timer.elapsed() << std::endl;
#endif

        return add_rings<GeometryOut>(selected, geometry1, geometry2, rings, out);
    }
コード例 #2
0
    static inline OutputIterator apply(Geometry const& geometry,
                OutputIterator out)
    {
        // Get the self-intersection points, including turns
        typedef detail::overlay::traversal_turn_info
            <
                typename point_type<Geometry>::type
            > turn_info;

        std::vector<turn_info> turns;
        detail::dissolve::no_interrupt_policy policy;
        geometry::self_turns
            <
                detail::overlay::calculate_distance_policy
            >(geometry, turns, policy);

        // The dissolve process is not necessary if there are no turns at all

        if (boost::size(turns) > 0)
        {
            typedef typename ring_type<Geometry>::type ring_type;
            typedef std::vector<ring_type> out_vector;
            out_vector rings;

            // Enrich the turns
            typedef typename strategy::side::services::default_strategy
            <
                typename cs_tag<Geometry>::type
            >::type side_strategy_type;

            enrich_intersection_points<false, false>(turns,
                        detail::overlay::operation_union,
                        geometry, geometry,
                        side_strategy_type());

            typedef detail::overlay::traverse
                <
                    false, false, 
                    Geometry, Geometry,
                    backtrack_for_dissolve<Geometry>
                > traverser;


            // Traverse the polygons twice for union...
            traverser::apply(geometry, geometry,
                            detail::overlay::operation_union,
                            turns, rings);

            clear_visit_info(turns);

            enrich_intersection_points<false, false>(turns,
                        detail::overlay::operation_intersection,
                        geometry, geometry,
                        side_strategy_type());


            // ... and for intersection
            traverser::apply(geometry, geometry,
                            detail::overlay::operation_intersection,
                            turns, rings);

            std::map<ring_identifier, int> map;
            map_turns(map, turns);

            typedef detail::overlay::ring_properties<typename geometry::point_type<Geometry>::type> properties;

            std::map<ring_identifier, properties> selected;

            detail::overlay::select_rings<overlay_union>(geometry, map, selected, true);

            // Add intersected rings
            {
                ring_identifier id(2, 0, -1);
                for (typename boost::range_iterator<std::vector<ring_type> const>::type
                        it = boost::begin(rings);
                        it != boost::end(rings);
                        ++it)
                {
                    selected[id] = properties(*it, true);
                    id.multi_index++;
                }
            }

            detail::overlay::assign_parents(geometry, rings, selected);
            return detail::overlay::add_rings<GeometryOut>(selected, geometry, rings, out);

        }
        else
        {
            GeometryOut g;
            geometry::convert(geometry, g);
            *out++ = g;
            return out;
        }
    }