Beispiel #1
0
        static inline bool apply(Polygon const& polygon,
                                 TurnIterator first,
                                 TurnIterator beyond)
        {
            typedef typename std::iterator_traits
                <
                    TurnIterator
                >::value_type turn_type;
            typedef complement_graph<typename turn_type::point_type> graph;

            graph g(geometry::num_interior_rings(polygon) + 1);
            for (TurnIterator tit = first; tit != beyond; ++tit)
            {
                typename graph::vertex_handle v1 = g.add_vertex
                    ( tit->operations[0].seg_id.ring_index + 1 );
                typename graph::vertex_handle v2 = g.add_vertex
                    ( tit->operations[1].seg_id.ring_index + 1 );
                typename graph::vertex_handle vip = g.add_vertex(tit->point);

                g.add_edge(v1, vip);
                g.add_edge(v2, vip);
            }

            debug_print_complement_graph(std::cout, g);

            return !g.has_cycles();
        }
Beispiel #2
0
    static inline bool apply(Polygon const& polygon)
    {
        typedef typename point_type<Polygon>::type point_type;
        typedef typename ring_type<Polygon>::type ring_type;

        typedef debug_validity_phase<Polygon> debug_phase;

        // check validity of exterior ring
        debug_phase::apply(1);

        if ( !detail::is_valid::is_valid_ring
                 <
                     ring_type,
                     AllowDuplicates,
                     false // do not check self intersections
                 >::apply(exterior_ring(polygon)) )
        {
            return false;
        }

        // check validity of interior rings
        debug_phase::apply(2);

        if ( !are_valid_interior_rings(geometry::interior_rings(polygon)) )
        {
            return false;
        }


        // compute turns and check if all are acceptable
        debug_phase::apply(3);

        typedef typename geometry::rescale_policy_type
            <
                point_type
            >::type rescale_policy_type;

        typedef detail::overlay::turn_info
            <
                point_type,
                typename geometry::segment_ratio_type
                    <
                        point_type,
                        rescale_policy_type
                    >::type
            > turn_info;

        typedef detail::overlay::get_turn_info
            <
                detail::overlay::assign_null_policy
            > turn_policy;

        rescale_policy_type robust_policy
            = geometry::get_rescale_policy<rescale_policy_type>(polygon);

        detail::overlay::stateless_predicate_based_interrupt_policy
            <
                is_acceptable_turn
            > interrupt_policy;

        std::deque<turn_info> turns;
        geometry::self_turns<turn_policy>(polygon,
                                          robust_policy,
                                          turns,
                                          interrupt_policy);

        if ( interrupt_policy.has_intersections )
        {
            return false;
        }

        debug_print_turns(turns.begin(), turns.end());

        // put the ring id's that are associated with turns in a
        // container with fast lookup (std::set)
        std::set<int> rings_with_turns;
        for (typename std::deque<turn_info>::const_iterator tit = turns.begin();
             tit != turns.end(); ++tit)
        {
            rings_with_turns.insert(tit->operations[0].seg_id.ring_index);
            rings_with_turns.insert(tit->operations[0].other_id.ring_index);
        }


        // check if all interior rings are inside the exterior ring
        debug_phase::apply(4);

        if ( !are_holes_inside(geometry::interior_rings(polygon),
                               geometry::exterior_ring(polygon),
                               rings_with_turns) )
        {
            return false;
        }


        // check whether the interior of the polygon is a connected set
        debug_phase::apply(5);

        typedef graph_vertex<typename turn_info::point_type> graph_vertex;
        typedef complement_graph<graph_vertex> graph;

        graph g(geometry::num_interior_rings(polygon) + 1);
        for (typename std::deque<turn_info>::const_iterator tit = turns.begin();
             tit != turns.end(); ++tit)
        {
            typename graph::vertex_handle v1
                = g.add_vertex(tit->operations[0].seg_id.ring_index);
            typename graph::vertex_handle v2
                = g.add_vertex(tit->operations[0].other_id.ring_index);
            typename graph::vertex_handle vip = g.add_vertex(tit->point);

            g.add_edge(v1, vip);
            g.add_edge(v2, vip);
        }

        debug_print_complement_graph(std::cout, g);

        return !g.has_cycles();
    }