Пример #1
0
    static inline OutputIterator apply(Geometry const& geometry,
            OutputIterator out, Strategy const& strategy)
    {
        typename Strategy::state_type state;

        strategy.apply(geometry, state);
        strategy.result(state, out, Order == clockwise);
        return out;
    }
Пример #2
0
 static inline typename default_length_result<Segment>::type apply(
         Segment const& segment, Strategy const& strategy)
 {
     typedef typename point_type<Segment>::type point_type;
     point_type p1, p2;
     geometry::detail::assign_point_from_index<0>(segment, p1);
     geometry::detail::assign_point_from_index<1>(segment, p2);
     return strategy.apply(p1, p2);
 }
Пример #3
0
 static inline typename return_type<Strategy>::type apply(Point const& point,
             Segment const& segment, Strategy const& strategy)
 {
     
     typename point_type<Segment>::type p[2];
     geometry::detail::assign_point_from_index<0>(segment, p[0]);
     geometry::detail::assign_point_from_index<1>(segment, p[1]);
     return strategy.apply(point, p[0], p[1]);
 }
Пример #4
0
 static inline void apply(Point const& point,
                          PointTransformer const& transformer,
                          Strategy const& strategy,
                          typename Strategy::state_type& state)
 {
     geofeatures_boost::ignore_unused(strategy);
     strategy.apply(static_cast<Point const&>(transformer.apply(point)),
                    state);
 }
Пример #5
0
    static inline void apply(Point const& point, Segment const& segment,
                    Strategy const& strategy, Result& result)
    {
       
        typename point_type<Segment>::type p[2];
        geometry::detail::assign_point_from_index<0>(segment, p[0]);
        geometry::detail::assign_point_from_index<1>(segment, p[1]);

        strategy.apply(point, p[0], p[1], result);
    }
Пример #6
0
    static inline bool apply(Geometry1 const& source, Geometry2& target,
                Strategy const& strategy)
    {
        typedef typename point_type<Geometry1>::type point_type1;
        typedef typename point_type<Geometry2>::type point_type2;

        point_type1 source_point[2];
        geometry::detail::assign_point_from_index<0>(source, source_point[0]);
        geometry::detail::assign_point_from_index<1>(source, source_point[1]);

        point_type2 target_point[2];
        if (strategy.apply(source_point[0], target_point[0])
            && strategy.apply(source_point[1], target_point[1]))
        {
            geometry::detail::assign_point_to_index<0>(target_point[0], target);
            geometry::detail::assign_point_to_index<1>(target_point[1], target);
            return true;
        }
        return false;
    }
 static inline typename strategy::distance::services::return_type
     <
         Strategy,
         typename point_type<Box1>::type,
         typename point_type<Box2>::type
     >::type
 apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
 {
     boost::ignore_unused(strategy);
     return strategy.apply(box1, box2);
 }
Пример #8
0
        static void apply(ApplyMethod)
        {
            // 1: inspect and define both arguments of apply
            typedef typename parameter_type_of
                <
                    ApplyMethod, 0
                >::type ptype1;

            typedef typename parameter_type_of
                <
                    ApplyMethod, 1
                >::type ptype2;

            // 2) must define meta-function return_type
            typedef typename strategy::distance::services::return_type
                <
                    Strategy, ptype1, ptype2
                >::type rtype;

            // 3) must define meta-function "comparable_type"
            typedef typename strategy::distance::services::comparable_type
                <
                    Strategy
                >::type ctype;

            // 4) must define meta-function "tag"
            typedef typename strategy::distance::services::tag
                <
                    Strategy
                >::type tag;

            // 5) must implement apply with arguments
            Strategy* str = 0;
            ptype1 *p1 = 0;
            ptype2 *p2 = 0;
            rtype r = str->apply(*p1, *p2);

            // 6) must define (meta)struct "get_comparable" with apply
            ctype c = strategy::distance::services::get_comparable
                <
                    Strategy
                >::apply(*str);

            // 7) must define (meta)struct "result_from_distance" with apply
            r = strategy::distance::services::result_from_distance
                <
                    Strategy,
                    ptype1, ptype2
                >::apply(*str, 1.0);

            boost::ignore_unused_variable_warning(str);
            boost::ignore_unused_variable_warning(c);
            boost::ignore_unused_variable_warning(r);
        }
Пример #9
0
 static inline void apply(Range const& range, OutputIterator out,
                          Distance const& max_distance, Strategy const& strategy)
 {
     if (pdalboost::size(range) <= 2 || max_distance < 0)
     {
         std::copy(pdalboost::begin(range), pdalboost::end(range), out);
     }
     else
     {
         strategy.apply(range, out, max_distance);
     }
 }
Пример #10
0
    static inline OutputIterator apply(UniqueSubRange1 const& range_p,
                UniqueSubRange2 const& range_q,
                TurnInfo const& ,
                Strategy const& strategy,
                RobustPolicy const& robust_policy,
                OutputIterator out)
    {
        typedef typename TurnInfo::point_type turn_point_type;

        typedef policies::relate::segments_intersection_points
            <
                segment_intersection_points
                    <
                        turn_point_type,
                        typename geometry::segment_ratio_type
                            <
                                turn_point_type, RobustPolicy
                            >::type
                    >
            > policy_type;

        typedef model::referring_segment<Point1 const> segment_type1;
        typedef model::referring_segment<Point2 const> segment_type2;
        Point1 const& pi = range_p.at(0);
        Point1 const& pj = range_p.at(1);
        Point2 const& qi = range_q.at(0);
        Point2 const& qj = range_q.at(1);
        segment_type1 p1(pi, pj);
        segment_type2 q1(qi, qj);

        typedef typename geometry::robust_point_type
            <
                Point1, RobustPolicy
            >::type robust_point_type;

        robust_point_type pi_rob, pj_rob, qi_rob, qj_rob;
        geometry::recalculate(pi_rob, pi, robust_policy);
        geometry::recalculate(pj_rob, pj, robust_policy);
        geometry::recalculate(qi_rob, qi, robust_policy);
        geometry::recalculate(qj_rob, qj, robust_policy);
        typename policy_type::return_type result
            = strategy.apply(p1, q1, policy_type(), robust_policy,
                             pi_rob, pj_rob, qi_rob, qj_rob);

        for (std::size_t i = 0; i < result.count; i++)
        {
            TurnInfo tp;
            geometry::convert(result.intersections[i], tp.point);
            *out++ = tp;
        }

        return out;
    }
Пример #11
0
        static void apply(ApplyMethod)
        {
            // 1) inspect and define both arguments of apply
            typedef typename parameter_type_of
                <
                    ApplyMethod, 0
                >::type ptype;

            typedef typename parameter_type_of
                <
                    ApplyMethod, 1
                >::type sptype;

            namespace services = strategy::distance::services;
            // 2) must define meta-function "tag"
            typedef typename services::tag<Strategy>::type tag;

            BOOST_MPL_ASSERT_MSG
                ((boost::is_same
                      <
                          tag, strategy_tag_distance_point_segment
                      >::value),
                 INCORRECT_STRATEGY_TAG,
                 (types<tag>));

            // 3) must define meta-function "return_type"
            typedef typename services::return_type
                <
                    Strategy, ptype, sptype
                >::type rtype;

            // 4) must define meta-function "comparable_type"
            typedef typename services::comparable_type<Strategy>::type ctype;

            // 5) must implement apply with arguments
            Strategy *str = 0;
            ptype *p = 0;
            sptype *sp1 = 0;
            sptype *sp2 = 0;

            rtype r = str->apply(*p, *sp1, *sp2);

            // 6) must define (meta-)struct "get_comparable" with apply
            ctype cstrategy = services::get_comparable<Strategy>::apply(*str);

            // 7) must define (meta-)struct "result_from_distance" with apply
            r = services::result_from_distance
                <
                    Strategy, ptype, sptype
                >::apply(*str, rtype(1.0));

            boost::ignore_unused(str, r, cstrategy);
        }
    static inline
    typename distance_result
        <
            typename point_type<Range1>::type,
            typename point_type<Range2>::type,
            Strategy
        >::type
    apply(Range1 const& r1, Range2 const& r2, Strategy const& strategy)
    {

        typedef typename distance_result
            <
                typename point_type<Range1>::type,
                typename point_type<Range2>::type,
                Strategy
            >::type result_type;

        typedef typename boost::range_size<Range1>::type size_type;

        boost::geometry::detail::throw_on_empty_input(r1);
        boost::geometry::detail::throw_on_empty_input(r2);

        size_type const n = boost::size(r1);
        result_type dis_max = 0;

#ifdef BOOST_GEOMETRY_ENABLE_SIMILARITY_RTREE
        namespace bgi = boost::geometry::index;
        typedef typename point_type<Range1>::type point_t;
        typedef bgi::rtree<point_t, bgi::linear<4> > rtree_type;
        rtree_type rtree(boost::begin(r2), boost::end(r2));
        point_t res;
#endif

        for (size_type i = 0 ; i < n ; i++)
        {
#ifdef BOOST_GEOMETRY_ENABLE_SIMILARITY_RTREE
            size_type found = rtree.query(bgi::nearest(range::at(r1, i), 1), &res);
            result_type dis_min = strategy.apply(range::at(r1,i), res);
#else
            result_type dis_min = point_range::apply(range::at(r1, i), r2, strategy);
#endif
            if (dis_min > dis_max )
            {
                dis_max = dis_min;
            }
        }
        return dis_max;
    }
inline bool point_in_range(Strategy& strategy, State& state,
        Point const& point, Iterator begin, Iterator end)
{
    boost::ignore_unused(strategy);

    Iterator it = begin;
    for (Iterator previous = it++; it != end; ++previous, ++it)
    {
        if (! strategy.apply(point, *previous, *it, state))
        {
            // We're probably on the boundary
            return false;
        }
    }
    return true;
}
Пример #14
0
        static void apply()
        {
            Strategy *str = 0;
            state_type *st = 0;

            // 4) must implement a static method apply,
            // getting two segment-points
            spoint_type const* sp = 0;
            str->apply(*sp, *sp, *st);

            // 5) must implement a static method result
            //  getting the centroid
            point_type *c = 0;
            bool r = str->result(*st, *c);

            boost::ignore_unused_variable_warning(str);
            boost::ignore_unused_variable_warning(r);
        }
Пример #15
0
    static inline void apply(Ring const& ring,
            Strategy const& strategy, typename Strategy::state_type& state)
    {
        typedef typename closeable_view<Ring const, Closure>::type view_type;

        typedef typename boost::range_iterator<view_type const>::type iterator_type;

        view_type view(ring);
        iterator_type it = boost::begin(view);
        iterator_type end = boost::end(view);

        for (iterator_type previous = it++;
            it != end;
            ++previous, ++it)
        {
            strategy.apply(*previous, *it, state);
        }
    }
Пример #16
0
void time_compare_s(int const n)
{
    boost::timer t;
    P p1, p2;
    bg::assign_values(p1, 1, 1);
    bg::assign_values(p2, 2, 2);
    Strategy strategy;
    typename bg::strategy::distance::services::return_type<Strategy, P, P>::type s = 0;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            bg::set<0>(p2, bg::get<0>(p2) + 0.001);
            s += strategy.apply(p1, p2);
        }
    }
    std::cout << "s: " << s << " t: " << t.elapsed() << std::endl;
}
Пример #17
0
    static inline typename Strategy::return_type
    apply(Ring const& ring, Strategy const& strategy)
    {
        BOOST_CONCEPT_ASSERT( (geometry::concept::AreaStrategy<Strategy>) );
        assert_dimension<Ring, 2>();

        // Ignore warning (because using static method sometimes) on strategy
        boost::ignore_unused_variable_warning(strategy);

        // An open ring has at least three points,
        // A closed ring has at least four points,
        // if not, there is no (zero) area
        if (int(boost::size(ring))
                < core_detail::closure::minimum_ring_size<Closure>::value)
        {
            return typename Strategy::return_type();
        }

        typedef typename reversible_view<Ring const, Direction>::type rview_type;
        typedef typename closeable_view
            <
                rview_type const, Closure
            >::type view_type;
        typedef typename boost::range_iterator<view_type const>::type iterator_type;

        rview_type rview(ring);
        view_type view(rview);
        typename Strategy::state_type state;
        iterator_type it = boost::begin(view);
        iterator_type end = boost::end(view);

        for (iterator_type previous = it++;
            it != end;
            ++previous, ++it)
        {
            strategy.apply(*previous, *it, state);
        }

        return strategy.result(state);
    }
inline bool point_in_section(Strategy& strategy, State& state,
        Point const& point, CoordinateType const& point_y,
        Iterator begin, Iterator end,
        int direction)
{
    if (direction == 0)
    {
        // Not a monotonic section, or no change in Y-direction
        return point_in_range(strategy, state, point, begin, end);
    }

    // We're in a monotonic section in y-direction
    Iterator it = begin;

    for (Iterator previous = it++; it != end; ++previous, ++it)
    {
        // Depending on sections.direction we can quit for this section
        CoordinateType const previous_y = geometry::get<1>(*previous);

        if (direction == 1 && point_y < previous_y)
        {
            // Section goes upwards, y increases, point is is below section
            return true;
        }
        else if (direction == -1 && point_y > previous_y)
        {
            // Section goes downwards, y decreases, point is above section
            return true;
        }

        if (! strategy.apply(point, *previous, *it, state))
        {
            // We're probably on the boundary
            return false;
        }
    }
    return true;
}
Пример #19
0
void test_2d(std::string const& wkt_p,
             std::string const& wkt_sp1,
             std::string const& wkt_sp2,
             T expected_distance,
             T expected_comparable_distance,
             Strategy strategy,
             ComparableStrategy comparable_strategy)
{
    P1 p;
    P2 sp1, sp2;
    bg::read_wkt(wkt_p, p);
    bg::read_wkt(wkt_sp1, sp1);
    bg::read_wkt(wkt_sp2, sp2);

    BOOST_CONCEPT_ASSERT
        (
            (bg::concept::PointSegmentDistanceStrategy<Strategy, P1, P2>)
        );
    BOOST_CONCEPT_ASSERT
        (
            (bg::concept::PointSegmentDistanceStrategy<ComparableStrategy, P1, P2>)
        );

    {
        typedef typename bg::strategy::distance::services::return_type<Strategy, P1, P2>::type return_type;
        return_type d = strategy.apply(p, sp1, sp2);
        test_check_close(d, expected_distance, 0.001);
    }

    // Test combination with the comparable strategy
    {
        typedef typename bg::strategy::distance::services::return_type<ComparableStrategy, P1, P2>::type return_type;
        return_type d = comparable_strategy.apply(p, sp1, sp2);
        test_check_close(d, expected_comparable_distance, 0.01);
    }

}
Пример #20
0
void time_compare_s(int const n)
{
    typedef bg::model::box<P> box_type;

    boost::timer t;
    P p;
    box_type b;
    bg::assign_values(b, 0, 0, 1, 1);
    bg::assign_values(p, 2, 2);
    Strategy strategy;
    typename bg::strategy::distance::services::return_type
        <
            Strategy, P, box_type
        >::type s = 0;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            bg::set<0>(p, bg::get<0>(p) + 0.001);
            s += strategy.apply(p, b);
        }
    }
    std::cout << "s: " << s << " t: " << t.elapsed() << std::endl;
}
Пример #21
0
 static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
 {
     assert_dimension_equal<Box1, Box2>();
     ::boost::ignore_unused_variable_warning(strategy);
     return strategy.apply(box1, box2);
 }
Пример #22
0
 static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
 {
     ::boost::ignore_unused_variable_warning(strategy);
     return strategy.apply(point, box);
 }
Пример #23
0
OutputIterator clip_range_with_box(Box const& b, Range const& range,
            RobustPolicy const&,
            OutputIterator out, Strategy const& strategy)
{
    if (boost::begin(range) == boost::end(range))
    {
        return out;
    }

    typedef typename point_type<OutputLinestring>::type point_type;

    OutputLinestring line_out;

    typedef typename boost::range_iterator<Range const>::type iterator_type;
    iterator_type vertex = boost::begin(range);
    for(iterator_type previous = vertex++;
            vertex != boost::end(range);
            ++previous, ++vertex)
    {
        point_type p1, p2;
        geometry::convert(*previous, p1);
        geometry::convert(*vertex, p2);

        // Clip the segment. Five situations:
        // 1. Segment is invisible, finish line if any (shouldn't occur)
        // 2. Segment is completely visible. Add (p1)-p2 to line
        // 3. Point 1 is invisible (clipped), point 2 is visible. Start new line from p1-p2...
        // 4. Point 1 is visible, point 2 is invisible (clipped). End the line with ...p2
        // 5. Point 1 and point 2 are both invisible (clipped). Start/finish an independant line p1-p2
        //
        // This results in:
        // a. if p1 is clipped, start new line
        // b. if segment is partly or completely visible, add the segment
        // c. if p2 is clipped, end the line

        bool c1 = false;
        bool c2 = false;
        model::referring_segment<point_type> s(p1, p2);

        if (!strategy.clip_segment(b, s, c1, c2))
        {
            strategy.apply(line_out, out);
        }
        else
        {
            // a. If necessary, finish the line and add a start a new one
            if (c1)
            {
                strategy.apply(line_out, out);
            }

            // b. Add p1 only if it is the first point, then add p2
            if (boost::empty(line_out))
            {
                detail::overlay::append_no_duplicates(line_out, p1, true);
            }
            detail::overlay::append_no_duplicates(line_out, p2);

            // c. If c2 is clipped, finish the line
            if (c2)
            {
                strategy.apply(line_out, out);
            }
        }

    }

    // Add last part
    strategy.apply(line_out, out);
    return out;
}
    static inline bool apply(Segment const& segment,
                             Box const& box,
                             Strategy const& azimuth_strategy)
    {
        assert_dimension_equal<Segment, Box>();

        typedef typename point_type<Segment>::type segment_point_type;
        typedef typename cs_tag<Segment>::type segment_cs_type;

        segment_point_type p0, p1;
        geometry::detail::assign_point_from_index<0>(segment, p0);
        geometry::detail::assign_point_from_index<1>(segment, p1);

        // Simplest cases first

        // Case 1: if box contains one of segment's endpoints then they are not disjoint
        if (! disjoint_point_box(p0, box) || ! disjoint_point_box(p1, box))
        {
            return false;
        }

        // Case 2: disjoint if bounding boxes are disjoint

        typedef typename coordinate_type<segment_point_type>::type CT;

        segment_point_type p0_normalized =
                geometry::detail::return_normalized<segment_point_type>(p0);
        segment_point_type p1_normalized =
                geometry::detail::return_normalized<segment_point_type>(p1);

        CT lon1 = geometry::get_as_radian<0>(p0_normalized);
        CT lat1 = geometry::get_as_radian<1>(p0_normalized);
        CT lon2 = geometry::get_as_radian<0>(p1_normalized);
        CT lat2 = geometry::get_as_radian<1>(p1_normalized);

        if (lon1 > lon2)
        {
            swap(lon1, lat1, lon2, lat2);
        }

        //Compute alp1 outside envelope and pass it to envelope_segment_impl
        //in order for it to be used later in the algorithm
        CT alp1;

        azimuth_strategy.apply(lon1, lat1, lon2, lat2, alp1);

        geometry::model::box<segment_point_type> box_seg;

        geometry::detail::envelope::envelope_segment_impl<segment_cs_type>
                ::template apply<geometry::radian>(lon1, lat1,
                                                   lon2, lat2,
                                                   box_seg,
                                                   azimuth_strategy,
                                                   alp1);
        if (disjoint_box_box(box, box_seg))
        {
            return true;
        }

        // Case 3: test intersection by comparing angles

        CT a_b0, a_b1, a_b2, a_b3;

        CT b_lon_min = geometry::get_as_radian<geometry::min_corner, 0>(box);
        CT b_lat_min = geometry::get_as_radian<geometry::min_corner, 1>(box);
        CT b_lon_max = geometry::get_as_radian<geometry::max_corner, 0>(box);
        CT b_lat_max = geometry::get_as_radian<geometry::max_corner, 1>(box);

        azimuth_strategy.apply(lon1, lat1, b_lon_min, b_lat_min, a_b0);
        azimuth_strategy.apply(lon1, lat1, b_lon_max, b_lat_min, a_b1);
        azimuth_strategy.apply(lon1, lat1, b_lon_min, b_lat_max, a_b2);
        azimuth_strategy.apply(lon1, lat1, b_lon_max, b_lat_max, a_b3);

        bool b0 = alp1 > a_b0;
        bool b1 = alp1 > a_b1;
        bool b2 = alp1 > a_b2;
        bool b3 = alp1 > a_b3;

        // if not all box points on the same side of the segment then
        // there is an intersection
        if (!(b0 && b1 && b2 && b3) && (b0 || b1 || b2 || b3))
        {
            return false;
        }

        // Case 4: The only intersection case not covered above is when all four
        // points of the box are above (below) the segment in northern (southern)
        // hemisphere. Then we have to compute the vertex of the segment

        CT vertex_lat;
        CT lat_sum = lat1 + lat2;

        if ((b0 && b1 && b2 && b3 && lat_sum > CT(0))
                || (!(b0 && b1 && b2 && b3) && lat_sum < CT(0)))
        {
            CT b_lat_below; //latitude of box closest to equator

            if (lat_sum > CT(0))
            {
                vertex_lat = geometry::get_as_radian<geometry::max_corner, 1>(box_seg);
                b_lat_below = b_lat_min;
            } else {
                vertex_lat = geometry::get_as_radian<geometry::min_corner, 1>(box_seg);
                b_lat_below = b_lat_max;
            }

            //optimization TODO: computing the spherical longitude should suffice for
            // the majority of cases
            CT vertex_lon = geometry::formula::vertex_longitude<CT, CS_Tag>
                                    ::apply(lon1, lat1,
                                            lon2, lat2,
                                            vertex_lat,
                                            alp1,
                                            azimuth_strategy);

            // Check if the vertex point is within the band defined by the
            // minimum and maximum longitude of the box; if yes, then return
            // false if the point is above the min latitude of the box; return
            // true in all other cases
            if (vertex_lon >= b_lon_min && vertex_lon <= b_lon_max
                    && std::abs(vertex_lat) > std::abs(b_lat_below))
            {
                return false;
            }
        }

        return true;
    }
Пример #25
0
 static inline void apply(Point const& point,
         Strategy const& strategy, typename Strategy::state_type& state)
 {
     strategy.apply(point, state);
 }
Пример #26
0
 static inline bool apply(Point1 const& p1, Point2& p2,
             Strategy const& strategy)
 {
     return strategy.apply(p1, p2);
 }
Пример #27
0
 static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const& strategy)
 {
     assert_dimension_equal<Box1, Box2>();
     return strategy.apply(box1, box2);
 }
Пример #28
0
 static inline bool apply(Point const& point, Box const& box, Strategy const& strategy)
 {
     return strategy.apply(point, box);
 }
Пример #29
0
 static inline bool apply(Point const& point, NSphere const& nsphere, Strategy const& strategy)
 {
     assert_dimension_equal<Point, NSphere>();
     boost::ignore_unused_variable_warning(strategy);
     return strategy.apply(point, nsphere);
 }
Пример #30
0
 static inline bool apply(NSphere const& nsphere, Box const& box, Strategy const& strategy)
 {
     assert_dimension_equal<NSphere, Box>();
     boost::ignore_unused_variable_warning(strategy);
     return strategy.apply(nsphere, box);
 }