Exemplo n.º 1
0
 static inline bool check_element(char m)
 {
     if ( BOOST_GEOMETRY_CONDITION(V >= '0' && V <= '9') )
     {
         return m == 'F' || ( m < V && m >= '0' && m <= '9' );
     }
     else if ( BOOST_GEOMETRY_CONDITION(V == 'T') )
     {
         return m == 'F';
     }
     return false;
 }
Exemplo n.º 2
0
inline void clean_closing_dups_and_spikes(Range& range,
                RobustPolicy const& robust_policy)
{
    std::size_t const minsize
        = core_detail::closure::minimum_ring_size
            <
                geometry::closure<Range>::value
            >::value;

    if (boost::size(range) <= minsize)
    {
        return;
    }

    typedef typename boost::range_iterator<Range>::type iterator_type;
    static bool const closed = geometry::closure<Range>::value == geometry::closed;

// TODO: the following algorithm could be rewritten to first look for spikes
// and then erase some number of points from the beginning of the Range

    bool found = false;
    do
    {
        found = false;
        iterator_type first = boost::begin(range);
        iterator_type second = first + 1;
        iterator_type ultimate = boost::end(range) - 1;
        if (BOOST_GEOMETRY_CONDITION(closed))
        {
            ultimate--;
        }

        // Check if closing point is a spike (this is so if the second point is
        // considered as a spike w.r.t. the last segment)
        if (point_is_spike_or_equal(*second, *ultimate, *first, robust_policy))
        {
            range::erase(range, first);
            if (BOOST_GEOMETRY_CONDITION(closed))
            {
                // Remove closing last point
                range::resize(range, boost::size(range) - 1);
                // Add new closing point
                range::push_back(range, range::front(range));
            }
            found = true;
        }
    } while(found && boost::size(range) > minsize);
}
void test_point_multilinestring()
{
    typedef bg::model::linestring<P> ls;
    typedef bg::model::multi_linestring<ls> mls;

    test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0, 2 0, 2 2),(0 0, 0 2))", "0FFFFF102");
    test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0, 2 0, 2 2),(0 0, 0 2, 2 2))", "0FFFFF1F2");
    test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0, 2 0, 2 2),(0 0, 0 2, 2 2),(0 0, 1 1))", "F0FFFF102");

    test_geometry<P, mls>("POINT(0 0)", "MULTILINESTRING((0 0,5 0),(0 0,0 5,5 0),(0 0,-5 0),(0 0,0 -5,-5 0))", "0FFFFF1F2");
    test_geometry<P, mls>("POINT(5 0)", "MULTILINESTRING((0 0,5 0),(0 0,0 5,5 0),(0 0,-5 0),(0 0,0 -5,-5 0))", "0FFFFF1F2");
    test_geometry<P, mls>("POINT(1 0)", "MULTILINESTRING((0 0,5 0),(0 0,0 5,5 0),(0 0,-5 0),(0 0,0 -5,-5 0))", "0FFFFF1F2");

    // assertion failure in relate->boundary_checker->std::equal_range with msvc
    if (BOOST_GEOMETRY_CONDITION(is_nan_case_supported<mls>::value))
    {
        // on the boundary
        std::string wkt0 = "POINT(3.1e+307 1)";
        P g0;
        bg::read_wkt(wkt0, g0);

        // disjoint
        std::string wkt1 = "POINT(1.1e+308 1.2e+308)";
        P g1;
        bg::read_wkt(wkt1, g1);

        mls g2;
        std::string wkt2;
        nan_case(g2, wkt2);

        check_geometry(g0, g2, wkt0, wkt2, "*********");
        check_geometry(g1, g2, wkt1, wkt2, "*********");
    }
}
Exemplo n.º 4
0
inline bool points_equal_or_close(Point1 const& point1,
        Point2 const& point2,
        RobustPolicy const& robust_policy)
{
    if (detail::equals::equals_point_point(point1, point2))
    {
        return true;
    }

    if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled))
    {
        return false;
    }

    // Try using specified robust policy
    typedef typename geometry::robust_point_type
    <
        Point1,
        RobustPolicy
    >::type robust_point_type;

    robust_point_type point1_rob, point2_rob;
    geometry::recalculate(point1_rob, point1, robust_policy);
    geometry::recalculate(point2_rob, point2, robust_policy);

    return detail::equals::equals_point_point(point1_rob, point2_rob);
}
Exemplo n.º 5
0
    static inline void apply(std::string const& case_id,
                             std::string const& wkt1,
                             std::string const& wkt2,
                             double expected_distance,
                             double expected_comparable_distance,
                             Strategy const& strategy)
    {
        typedef test_distance_of_geometries<Geometry1, Geometry2> tester;

        bool const is_comparable = boost::is_same
            <
                Strategy,
                typename services::comparable_type<Strategy>::type
            >::value;

        if (BOOST_GEOMETRY_CONDITION(is_comparable))
        {
            tester::apply(case_id, wkt1, wkt2,
                          expected_comparable_distance,
                          expected_comparable_distance,
                          strategy);
        }
        else
        {
            tester::apply(case_id, wkt1, wkt2,
                          expected_distance,
                          expected_comparable_distance,
                          strategy);
        }
    }
inline bool point_is_collinear(Point1 const& last_point,
            Point2 const& segment_a,
            Point3 const& segment_b,
            SideStrategy const& strategy,
            RobustPolicy const& robust_policy)
{
    int const side = strategy.apply(segment_a, segment_b, last_point);
    if (side == 0)
    {
        return true;
    }

    // This part (or whole method, because it is then trivial)
    // will be removed after rescaling
    if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled))
    {
        return false;
    }

    // Redo, using specified robust policy
    typedef typename geometry::robust_point_type
    <
        Point1,
        RobustPolicy
    >::type robust_point_type;

    robust_point_type last_point_rob, segment_a_rob, segment_b_rob;
    geometry::recalculate(last_point_rob, last_point, robust_policy);
    geometry::recalculate(segment_a_rob, segment_a, robust_policy);
    geometry::recalculate(segment_b_rob, segment_b, robust_policy);

    int const side_rob = strategy.apply(segment_a_rob, segment_b_rob, last_point_rob);
    return side_rob == 0;
}
 inline bool apply(Section const& sec1, Section const& sec2)
 {
     if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box)
             && ! sec1.duplicate
             && ! sec2.duplicate)
     {
         detail::get_turns::get_turns_in_sections
                 <
                     Geometry, Geometry,
                     false, false,
                     Section, Section,
                     TurnPolicy
                 >::apply(
                         0, m_geometry, sec1,
                         0, m_geometry, sec2,
                         false,
                         m_rescale_policy,
                         m_turns, m_interrupt_policy);
     }
     if (BOOST_GEOMETRY_CONDITION(m_interrupt_policy.has_intersections))
     {
         // TODO: we should give partition an interrupt policy.
         // Now we throw, and catch below, to stop the partition loop.
         throw self_ip_exception();
     }
     return true;
 }
Exemplo n.º 8
0
void test_ordered_ring(std::string const& wkt_point,
        std::string const& wkt_geometry, bool expected, bool on_border)
{
    typedef bg::model::ring<Point, Clockwise, Closed> ring_type;
    ring_type ring;
    Point point;

    bg::read_wkt(wkt_geometry, ring);
    if ( BOOST_GEOMETRY_CONDITION(! Clockwise) )
    {
        std::reverse(boost::begin(ring), boost::end(ring));
    }

    bg::read_wkt(wkt_point, point);

    bool detected = bg::within(point, ring);

    BOOST_CHECK_MESSAGE(detected == expected,
        "within: " << wkt_point
        << " in " << wkt_geometry
        << " -> Expected: " << expected
        << " detected: " << detected
        << " clockwise: " << int(Clockwise)
        << " closed: " << int(Closed)
        );

    // other strategy (note that this one cannot detect OnBorder
    // (without modifications)

    bg::strategy::within::franklin<Point> franklin;
    detected = bg::within(point, ring, franklin);
    if (! on_border)
    {
        BOOST_CHECK_MESSAGE(detected == expected,
            "within: " << wkt_point
            << " in " << wkt_geometry
            << " -> Expected: " << expected
            << " detected: " << detected
            << " clockwise: " << int(Clockwise)
            << " closed: " << int(Closed)
            );
    }


    bg::strategy::within::crossings_multiply<Point> cm;
    detected = bg::within(point, ring, cm);
    if (! on_border)
    {
        BOOST_CHECK_MESSAGE(detected == expected,
            "within: " << wkt_point
            << " in " << wkt_geometry
            << " -> Expected: " << expected
            << " detected: " << detected
            << " clockwise: " << int(Clockwise)
            << " closed: " << int(Closed)
            );
    }
}
Exemplo n.º 9
0
    static inline return_type
    apply(Segment1 const& segment1, Segment2 const& segment2,
          Strategy const& strategy)
    {
        if (geometry::intersects(segment1, segment2))
        {
            return 0;
        }

        typename point_type<Segment1>::type p[2];
        detail::assign_point_from_index<0>(segment1, p[0]);
        detail::assign_point_from_index<1>(segment1, p[1]);

        typename point_type<Segment2>::type q[2];
        detail::assign_point_from_index<0>(segment2, q[0]);
        detail::assign_point_from_index<1>(segment2, q[1]);

        comparable_strategy cstrategy =
            strategy::distance::services::get_comparable
                <
                    Strategy
                >::apply(strategy);

        comparable_return_type d[4];
        d[0] = cstrategy.apply(q[0], p[0], p[1]);
        d[1] = cstrategy.apply(q[1], p[0], p[1]);
        d[2] = cstrategy.apply(p[0], q[0], q[1]);
        d[3] = cstrategy.apply(p[1], q[0], q[1]);

        std::size_t imin = std::distance(boost::addressof(d[0]),
                                         std::min_element(d, d + 4));

        if (BOOST_GEOMETRY_CONDITION(is_comparable<Strategy>::value))
        {
            return d[imin];
        }

        switch (imin)
        {
        case 0:
            return strategy.apply(q[0], p[0], p[1]);
        case 1:
            return strategy.apply(q[1], p[0], p[1]);
        case 2:
            return strategy.apply(p[0], q[0], q[1]);
        default:
            return strategy.apply(p[1], q[0], q[1]);
        }
    }
    static inline void apply(Point const& point, Geometry const& geometry, Result & result)
    {
        int pig = detail::within::point_in_geometry(point, geometry);

        if ( pig > 0 ) // within
        {
            relate::set<interior, interior, '0', Transpose>(result);
        }
        else if ( pig == 0 )
        {
            relate::set<interior, boundary, '0', Transpose>(result);
        }
        else // pig < 0 - not within
        {
            relate::set<interior, exterior, '0', Transpose>(result);
        }

        relate::set<exterior, exterior, result_dimension<Point>::value, Transpose>(result);

        if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
            return;

        // the point is on the boundary
        if ( pig == 0 )
        {
            // NOTE: even for MLs, if there is at least one boundary point,
            // somewhere there must be another one

            // check if there are other boundaries outside
            typedef detail::relate::topology_check<Geometry> tc_t;
            //tc_t tc(geometry, point);
            //if ( tc.has_interior )
                relate::set<exterior, interior, tc_t::interior, Transpose>(result);
            //if ( tc.has_boundary )
                relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
        }
        else
        {
            // check if there is a boundary in Geometry
            typedef detail::relate::topology_check<Geometry> tc_t;
            tc_t tc(geometry);
            if ( tc.has_interior )
                relate::set<exterior, interior, tc_t::interior, Transpose>(result);
            if ( tc.has_boundary )
                relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
        }
    }
Exemplo n.º 11
0
    static inline void analyse_each_turn(Result & res,
                                         Analyser & analyser,
                                         TurnIt first, TurnIt last)
    {
        if ( first == last )
            return;

        for ( TurnIt it = first ; it != last ; ++it )
        {
            analyser.apply(res, it);

            if ( BOOST_GEOMETRY_CONDITION(res.interrupt) )
                return;
        }

        analyser.apply(res);
    }
Exemplo n.º 12
0
    static inline bool apply(MultiPoint const& multipoint,
                             VisitPolicy& visitor)
    {
        boost::ignore_unused(multipoint, visitor);

        if (BOOST_GEOMETRY_CONDITION(
                AllowEmptyMultiGeometries || !boost::empty(multipoint)))
        {
            // we allow empty multi-geometries, so an empty multipoint
            // is considered valid
            return visitor.template apply<no_failure>();
        }
        else
        {
            // we do not allow an empty multipoint
            return visitor.template apply<failure_few_points>();
        }
    }
Exemplo n.º 13
0
int test_main(int, char* [])
{
    test_all<bg::model::d2::point_xy<double> >();

#if ! defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
    test_all<bg::model::d2::point_xy<float> >();

#if defined(HAVE_TTMATH)
    std::cout << "Testing TTMATH" << std::endl;
    test_all<bg::model::d2::point_xy<ttmath_big> >();
#endif

#endif

    // Commented, because exception is now disabled:
    // test_exception<bg::model::d2::point_xy<double> >();

    test_pointer_version();
#if ! defined(BOOST_GEOMETRY_RESCALE_TO_ROBUST)
    test_rational<bg::model::d2::point_xy<boost::rational<int> > >();
#endif

    test_boxes_nd<double>();

#ifdef BOOST_GEOMETRY_TEST_INCLUDE_FAILING_TESTS
    // ticket #10868 still fails for 32-bit integers
    test_ticket_10868<int32_t>("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))");

#if !defined(BOOST_NO_INT64) || defined(BOOST_HAS_INT64_T) || defined(BOOST_HAS_MS_INT64)
    test_ticket_10868<int64_t>("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))");
#endif

    if (BOOST_GEOMETRY_CONDITION(sizeof(long) * CHAR_BIT >= 64))
    {
        test_ticket_10868<long>("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))");
    }

#if defined(BOOST_HAS_LONG_LONG)
    test_ticket_10868<boost::long_long_type>("MULTIPOLYGON(((33520458 6878575,33480192 14931538,31446819 18947953,30772384 19615678,30101303 19612322,30114725 16928001,33520458 6878575)))");
#endif
#endif

    return 0;
}
    static inline bool apply(Point& point, Box const& box)
    {
        if (BOOST_GEOMETRY_CONDITION(Midpoint))
        {
            Point p1, p2;
            detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, p1);
            detail::assign::assign_box_2d_corner<max_corner, min_corner>(box, p2);
            midpoint_helper
                <
                    Point,
                    0, dimension<Point>::value
                >::apply(point, p1, p2);
        }
        else
        {
            detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, point);
        }

        return true;
    }
void test_multi_linestring_multi_linestring()
{
    typedef bg::model::linestring<P> ls;
    typedef bg::model::multi_linestring<ls> mls;

    test_geometry<mls, mls>("MULTILINESTRING((0 0,0 0,18 0,18 0,19 0,19 0,19 0,30 0,30 0))",
                            "MULTILINESTRING((0 10,5 0,20 0,20 0,30 0))",
                            "1F1F00102");
    test_geometry<mls, mls>("MULTILINESTRING((0 0,0 0,18 0,18 0,19 0,19 0,19 0,30 0,30 0))",
                            //"MULTILINESTRING((0 10,5 0,20 0,20 0,30 0),(1 10,1 10,1 0,1 0,1 -10),(2 0,2 0),(3 0,3 0,3 0),(0 0,0 0,0 10,0 10),(30 0,30 0,31 0,31 0))",
                            "MULTILINESTRING((0 10,5 0,20 0,20 0,30 0),(1 10,1 10,1 0,1 0,1 -10),(0 0,0 0,0 10,0 10),(30 0,30 0,31 0,31 0))",
                            "1F100F102");
    test_geometry<mls, mls>("MULTILINESTRING((0 0,0 0,18 0,18 0,19 0,19 0,19 0,30 0,30 0))",
                            "MULTILINESTRING((0 10,5 0,20 0,20 0,30 0),(0 0,0 0,0 10,0 10))",
                            "1F1F0F1F2");

    // point-like
    test_geometry<mls, mls>("MULTILINESTRING((0 0, 0 0),(1 1, 1 1))",
                            "MULTILINESTRING((0 0, 0 0))",
                            "0F0FFFFF2");
    test_geometry<mls, mls>("MULTILINESTRING((0 0, 0 0),(1 1, 1 1))",
                            "MULTILINESTRING((0 0, 0 0),(1 1, 1 1))",
                            "0FFFFFFF2");
    test_geometry<mls, mls>("MULTILINESTRING((0 0, 0 0),(1 1, 1 1))",
                            "MULTILINESTRING((2 2, 2 2),(3 3, 3 3))",
                            "FF0FFF0F2");

    test_geometry<mls, mls>("MULTILINESTRING((0 5,10 5,10 10,5 10),(5 10,5 0,5 2),(5 2,5 5,0 5))",
                            "MULTILINESTRING((5 5,0 5),(5 5,5 0),(10 10,10 5,5 5,5 10,10 10))",
                            "10FFFFFF2");

    if ( BOOST_GEOMETRY_CONDITION((
            boost::is_same<typename bg::coordinate_type<P>::type, double>::value )) )
    {
        // assertion failure in 1.57
        test_geometry<mls, mls>("MULTILINESTRING((-0.59322033898305082 -8.0508474576271194,-2.882352941176471 -7.7647058823529411,-2.8823529411764706 -7.7647058823529411,-3.7361111111111112 -6.5694444444444446,-3.4404145077720205 -5.766839378238342,-4.1864406779661012 -3.6779661016949152,-7.5252525252525251 -5.5858585858585865,-7.5862068965517242 -5.1896551724137936,-4.47887323943662 -2.859154929577465,-4.5789473684210531 -2.5789473684210527,-3 -1,-2.9310344827586206 -0.86206896551724144,-3.1764705882352944 -0.70588235294117663,-4.7401960784313726 -2.1274509803921577,-5.3255813953488369 -0.48837209302325502,-4.7872340425531918 0.31914893617021284,-5.8571428571428577 1.0000000000000007,-5.3255813953488369 -0.48837209302325502,-5.9473684210526319 -1.4210526315789465,-8 2,-7.7333333333333334 2.1939393939393939,-8.8294573643410867 2.891472868217055,-8.8556701030927822 3.061855670103093,-7.5999999999999996 3.6000000000000001,-7.7999999999999998 3.7999999999999998,-7.75 3.7916666666666665,-7.5471698113207548 3.6226415094339623,-7.3200000000000003 3.7200000000000002,-3.473684210526315 3.0789473684210527,-3.2549019607843133 3.2156862745098036,-2.9999999999999982 3.1428571428571423,-3.1733333333333325 3.2666666666666666,-2.9180327868852456 3.4262295081967209,-2.8723404255319145 3.1063829787234041,-2.1111111111111112 2.8888888888888888,-2.1428571428571428 2.8571428571428572,-1.8433734939759043 2.8072289156626509,-1.8396226415094346 2.8113207547169816,-1.6486486486486487 2.756756756756757,-1.76510067114094 2.8926174496644301,-0.53846153846153855 4.2307692307692308,1.8148148148148147 5.4074074074074074,1.588235294117647 2.2352941176470589,1.819672131147541 2.1967213114754101,2 4,2 2.1666666666666665,2.3538461538461544 2.1076923076923078,2 1.6875000000000004,2 -2,1.2173913043478262 -3.8260869565217392,1.7375886524822697 1.3758865248226959,1.5073170731707317 1.1024390243902444,1.1428571428571428 -4,-0.59322033898305082 -8.0508474576271194),(1.666666666666667 1.5999999999999988,1.5675675675675675 1.8378378378378377,1.4374999999999991 1.8750000000000002,1.0487804878048776 2.3414634146341466,0.46666666666666712 2.6060606060606055,0.086956521739131043 2.2608695652173911,1.4374999999999991 1.8750000000000002,1.666666666666667 1.5999999999999988))",
                                "MULTILINESTRING((-2.333333333333333 -8.6666666666666661,-4.3253012048192767 -8.168674698795181,-4.1194968553459113 -7.6100628930817606,-2.8823529411764706 -7.7647058823529411,-2.882352941176471 -7.7647058823529411,-2.263157894736842 -8.6315789473684212,-2.333333333333333 -8.6666666666666661))",
                                "*********");
    }
}
Exemplo n.º 16
0
inline Box values_box(FwdIter first, FwdIter last, Translator const& tr)
{
    typedef typename std::iterator_traits<FwdIter>::value_type element_type;
    BOOST_MPL_ASSERT_MSG((is_leaf_element<element_type>::value),
                         SHOULD_BE_CALLED_ONLY_FOR_LEAF_ELEMENTS,
                         (element_type));

    Box result = elements_box<Box>(first, last, tr);

#ifdef BOOST_GEOMETRY_INDEX_EXPERIMENTAL_ENLARGE_BY_EPSILON
    if (BOOST_GEOMETRY_CONDITION((
        ! is_bounding_geometry
            <
                typename indexable_type<Translator>::type
            >::value)))
    {
        geometry::detail::expand_by_epsilon(result);
    }
#endif

    return result;
}
Exemplo n.º 17
0
void test_linestring_linestring()
{
    typedef bgm::linestring<P> ls;

    test_geometry<ls, ls>("ls2d_1", "LINESTRING(1 1, 3 3)", "LINESTRING(3 3, 1 1)", true);
    test_geometry<ls, ls>("ls2d_2", "LINESTRING(1 1, 3 3, 2 5)", "LINESTRING(1 1, 2 2, 3 3, 2 5)", true);
    test_geometry<ls, ls>("ls2d_3", "LINESTRING(1 0, 3 3, 2 5)", "LINESTRING(1 1, 2 2, 3 3, 2 5)", false);
    test_geometry<ls, ls>("ls2d_4", "LINESTRING(1 0, 3 3, 2 5)", "LINESTRING(1 1, 3 3, 2 5)", false);
    test_geometry<ls, ls>("ls2d_5", "LINESTRING(0 5,5 5,10 5,10 0,5 0,5 5,5 10,10 10,15 10,15 5,10 5,10 10,10 15)",
                                    "LINESTRING(0 5,15 5,15 10,5 10,5 0,10 0,10 15)", true);
    test_geometry<ls, ls>("ls2d_6", "LINESTRING(0 5,5 5,10 5,10 10,5 10,5 5,5 0)", "LINESTRING(0 5,5 5,5 10,10 10,10 5,5 5,5 0)", true);
    test_geometry<ls, ls>("ls2d_7", "LINESTRING(0 5,10 5,10 10,5 10,5 0)", "LINESTRING(0 5,5 5,5 10,10 10,10 5,5 5,5 0)", true);
    test_geometry<ls, ls>("ls2d_8", "LINESTRING(0 0,5 0,5 0,6 0)", "LINESTRING(0 0,6 0)", true);

    test_geometry<ls, ls>("ls2d_seg", "LINESTRING(1 1,2 2)", "LINESTRING(1 1,2 2)", true);
    test_geometry<ls, ls>("ls2d_rev", "LINESTRING(1 1,2 2)", "LINESTRING(2 2,1 1)", true);

    test_geometry<ls, ls>("ls2d_spike", "LINESTRING(0 0,5 0,3 0,6 0)", "LINESTRING(0 0,6 0)", true);

    test_geometry<ls, ls>("ls2d_ring1", "LINESTRING(0 0,5 0,5 5,0 5,0 0)", "LINESTRING(5 5,0 5,0 0,5 0,5 5)", true);
    test_geometry<ls, ls>("ls2d_ring2", "LINESTRING(0 0,5 0,5 5,0 5,0 0)", "LINESTRING(5 5,5 0,0 0,0 5,5 5)", true);
    test_geometry<ls, ls>("ls2d_overl_ring1", "LINESTRING(0 0,5 0,5 5,0 5,0 0)", "LINESTRING(5 5,0 5,0 0,5 0,5 5,0 5)", true);
    test_geometry<ls, ls>("ls2d_overl_ring2", "LINESTRING(0 0,5 0,5 5,0 5,0 0)", "LINESTRING(5 5,5 0,0 0,0 5,5 5,5 0)", true);

    // https://svn.boost.org/trac/boost/ticket/10904
    if ( BOOST_GEOMETRY_CONDITION(
            boost::is_floating_point<typename bg::coordinate_type<ls>::type>::value ) )
    {
        test_geometry<ls, ls>("ls2d_small1",
                              "LINESTRING(5.6956521739130430148634331999347 -0.60869565217391330413931882503675,5.5 -0.50000000000000066613381477509392)",
                              "LINESTRING(5.5 -0.50000000000000066613381477509392,5.5 -0.5)",
                              false);

        test_geometry<ls, ls>("ls2d_small2",
                              "LINESTRING(-3.2333333333333333925452279800083 5.5999999999999978683717927196994,-3.2333333333333333925452279800083 5.5999999999999996447286321199499)",
                              "LINESTRING(-3.2333333333333325043668082798831 5.5999999999999996447286321199499,-3.2333333333333333925452279800083 5.5999999999999996447286321199499)",
                              false);
    }
}
void test_multipoint_multipoint()
{
    typedef bg::model::multi_point<P> mpt;

    test_geometry<mpt, mpt>("MULTIPOINT(0 0)", "MULTIPOINT(0 0)", "0FFFFFFF2");
    test_geometry<mpt, mpt>("MULTIPOINT(1 0)", "MULTIPOINT(0 0)", "FF0FFF0F2");
    test_geometry<mpt, mpt>("MULTIPOINT(0 0)", "MULTIPOINT(0 0, 1 0)", "0FFFFF0F2");
    test_geometry<mpt, mpt>("MULTIPOINT(0 0, 1 0)", "MULTIPOINT(0 0)", "0F0FFFFF2");
    test_geometry<mpt, mpt>("MULTIPOINT(0 0, 1 1)", "MULTIPOINT(0 0, 1 0)", "0F0FFF0F2");

    //typedef bg::model::d2::point_xy<float> ptf;
    //typedef bg::model::multi_point<ptf> mptf;
    //test_geometry<mptf, mpt>("MULTIPOINT(0 0)", "MULTIPOINT(0 0)", "0FFFFFFF2");

    // assertion failure in relate->boundary_checker->std::equal_range with msvc
    if (BOOST_GEOMETRY_CONDITION(is_nan_case_supported<mpt>::value))
    {
        mpt g;
        std::string wkt;
        nan_case(g, wkt);

        check_geometry(g, g, wkt, wkt, "*********");
    }
}
inline bool point_is_spike_or_equal(Point1 const& last_point,
            Point2 const& segment_a,
            Point3 const& segment_b,
            SideStrategy const& strategy,
            RobustPolicy const& robust_policy)
{
    if (point_is_spike_or_equal(last_point, segment_a, segment_b, strategy))
    {
        return true;
    }

    if (BOOST_GEOMETRY_CONDITION(! RobustPolicy::enabled))
    {
        return false;
    }

    // Try using specified robust policy
    typedef typename geometry::robust_point_type
    <
        Point1,
        RobustPolicy
    >::type robust_point_type;

    robust_point_type last_point_rob, segment_a_rob, segment_b_rob;
    geometry::recalculate(last_point_rob, last_point, robust_policy);
    geometry::recalculate(segment_a_rob, segment_a, robust_policy);
    geometry::recalculate(segment_b_rob, segment_b, robust_policy);

    return point_is_spike_or_equal
        (
            last_point_rob,
            segment_a_rob,
            segment_b_rob,
            strategy
        );
}
Exemplo n.º 20
0
void test_all()
{
    typedef bg::model::box<P> box;
    typedef bg::model::polygon<P> polygon;
    typedef bg::model::ring<P> ring;

    typedef typename bg::coordinate_type<P>::type ct;

    test_one<polygon, polygon, polygon>("simplex_normal",
        simplex_normal[0], simplex_normal[1],
        3, 12, 2.52636706856656,
        3, 12, 3.52636706856656);

    test_one<polygon, polygon, polygon>("simplex_with_empty",
        simplex_normal[0], polygon_empty,
        1, 4, 8.0,
        0, 0, 0.0);

    test_one<polygon, polygon, polygon>(
            "star_ring", example_star, example_ring,
            5, 22, 1.1901714,
            5, 27, 1.6701714);

    test_one<polygon, polygon, polygon>("two_bends",
        two_bends[0], two_bends[1],
        1, 5, 8.0,
        1, 5, 8.0);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<polygon, polygon, polygon>("star_comb_15",
        star_comb_15[0], star_comb_15[1],
        30, 160, 227.658275102812,
        30, 198, 480.485775259312);
#endif

    test_one<polygon, polygon, polygon>("new_hole",
        new_hole[0], new_hole[1],
        1, 9, 7.0,
        1, 13, 14.0);


    test_one<polygon, polygon, polygon>("crossed",
        crossed[0], crossed[1],
        1, 18, 19.5,
        1, 7, 2.5);

    test_one<polygon, polygon, polygon>("disjoint",
        disjoint[0], disjoint[1],
        1, 5, 1.0,
        1, 5, 1.0);

    // The too small one might be discarded (depending on point-type / compiler)
    // We check area only
    test_one<polygon, polygon, polygon>("distance_zero",
        distance_zero[0], distance_zero[1],
        -1, -1, 8.7048386,
        -1, -1, 0.0098387,
        tolerance(0.001));

    test_one<polygon, polygon, polygon>("equal_holes_disjoint",
        equal_holes_disjoint[0], equal_holes_disjoint[1],
        1, 5, 9.0,
        1, 5, 9.0);

    test_one<polygon, polygon, polygon>("only_hole_intersections1",
        only_hole_intersections[0], only_hole_intersections[1],
        2, 10,  1.9090909,
        4, 16, 10.9090909);

    test_one<polygon, polygon, polygon>("only_hole_intersection2",
        only_hole_intersections[0], only_hole_intersections[2],
        3, 20, 30.9090909,
        4, 16, 10.9090909);

    test_one<polygon, polygon, polygon>("first_within_second",
        first_within_second[1], first_within_second[0],
        1, 10, 24,
        0, 0, 0);

    test_one<polygon, polygon, polygon>("fitting",
        fitting[0], fitting[1],
        1, 9, 21.0,
        1, 4, 4.0,
        1, 5, 25.0);

    test_one<polygon, polygon, polygon>("identical",
        identical[0], identical[1],
        0, 0, 0.0,
        0, 0, 0.0);

    test_one<polygon, polygon, polygon>("intersect_exterior_and_interiors_winded",
        intersect_exterior_and_interiors_winded[0], intersect_exterior_and_interiors_winded[1],
        4, 20, 11.533333,
        5, 26, 29.783333);

    test_one<polygon, polygon, polygon>("intersect_holes_intersect_and_disjoint",
        intersect_holes_intersect_and_disjoint[0], intersect_holes_intersect_and_disjoint[1],
        2, 16, 15.75,
        3, 17, 6.75);

    test_one<polygon, polygon, polygon>("intersect_holes_intersect_and_touch",
        intersect_holes_intersect_and_touch[0], intersect_holes_intersect_and_touch[1],
        3, 21, 16.25,
        3, 17, 6.25);

    test_one<polygon, polygon, polygon>("intersect_holes_new_ring",
        intersect_holes_new_ring[0], intersect_holes_new_ring[1],
        3, 15, 9.8961,
        4, 25, 121.8961,
        tolerance(0.01));

    test_one<polygon, polygon, polygon>("first_within_hole_of_second",
        first_within_hole_of_second[0], first_within_hole_of_second[1],
        1, 5, 1,
        1, 10, 16);

    test_one<polygon, polygon, polygon>("intersect_holes_disjoint",
        intersect_holes_disjoint[0], intersect_holes_disjoint[1],
        2, 14, 16.0,
        2, 10, 6.0);

    test_one<polygon, polygon, polygon>("intersect_holes_intersect",
        intersect_holes_intersect[0], intersect_holes_intersect[1],
        2, 16, 15.75,
        2, 12, 5.75);

    test_one<polygon, polygon, polygon>(
            "case4", case_4[0], case_4[1],
            6, 28, 2.77878787878788,
            4, 22, 4.77878787878788);

    test_one<polygon, polygon, polygon>(
            "case5", case_5[0], case_5[1],
            8, 36, 2.43452380952381,
            7, 33, 3.18452380952381);

#ifdef BOOST_GEOMETRY_TEST_INCLUDE_FAILING_TESTS
    // Fails, a-b is partly generated, b-a does not have any output
    // It failed already in 1.59
    test_one<polygon, polygon, polygon>("case_58_iet",
        case_58[0], case_58[2],
        3, 12, 0.6666666667,
        1, -1, 11.1666666667);
#endif

    test_one<polygon, polygon, polygon>("case_80",
        case_80[0], case_80[1],
        1, 9, 44.5,
        1, 10, 84.5);

#ifdef BOOST_GEOMETRY_TEST_INCLUDE_FAILING_TESTS
    // Fails, holes are not subtracted
    test_one<polygon, polygon, polygon>("case_81",
        case_81[0], case_81[1],
        1, 8, 80.5,
        1, 8, 83.0,
        1, 12, 80.5 + 83.0);
#endif

    test_one<polygon, polygon, polygon>("winded",
        winded[0], winded[1],
        3, 37, 61,
        1, 15, 13);

    test_one<polygon, polygon, polygon>("within_holes_disjoint",
        within_holes_disjoint[0], within_holes_disjoint[1],
        2, 15, 25,
        1, 5, 1);

    test_one<polygon, polygon, polygon>("side_side",
        side_side[0], side_side[1],
        1, 5, 1,
        1, 5, 1,
        1, 7, 2);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<polygon, polygon, polygon>("buffer_mp1",
        buffer_mp1[0], buffer_mp1[1],
        1, 61, 10.2717,
        1, 61, 10.2717);

    if ( BOOST_GEOMETRY_CONDITION((boost::is_same<ct, double>::value)) )
    {
        test_one<polygon, polygon, polygon>("buffer_mp2",
            buffer_mp2[0], buffer_mp2[1],
            1, 91, 12.09857,
            1, 155, 24.19714);
    }
#endif

    /*** TODO: self-tangencies for difference
    test_one<polygon, polygon, polygon>("wrapped_a",
        wrapped[0], wrapped[1],
        3, 1, 61,
        1, 0, 13);

    test_one<polygon, polygon, polygon>("wrapped_b",
        wrapped[0], wrapped[2],
        3, 1, 61,
        1, 0, 13);
    ***/

    // Isovist - the # output polygons differ per compiler/pointtype, (very) small
    // rings might be discarded. We check area only
    test_one<polygon, polygon, polygon>("isovist",
        isovist1[0], isovist1[1],
        -1, -1, 0.279132,
        -1, -1, 224.8892,
#if defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
        tolerance(0.1));
#else
        tolerance(0.001));
#endif
    // SQL Server gives:    0.279121891701124 and 224.889211358929
    // PostGIS gives:       0.279121991127244 and 224.889205853156
    // No robustness gives: 0.279121991127106 and 224.825363749290

#ifdef BOOST_GEOMETRY_TEST_INCLUDE_FAILING_TESTS
    test_one<polygon, polygon, polygon>("geos_1",
        geos_1[0], geos_1[1],
        21, -1, 0.31640625,
         9, -1, 0.01953125);

    // Excluded this test in the normal suite, it is OK like this for many clang/gcc/msvc
    // versions, but NOT OK for many other clang/gcc/msvc versions on other platforms
    // It might depend on partition (order)
    //        10, -1, 0.02148439); // change in partition might give these results

    // SQL Server gives: 0.28937764436705 and 0.000786406897532288 with 44/35 rings
    // PostGIS gives:    0.30859375       and 0.033203125 with 35/35 rings
#endif

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<polygon, polygon, polygon>("geos_2",
        geos_2[0], geos_2[1],
        1, -1, 138.6923828,
        1, -1, 211.859375,
        tolerance(0.01)); // MSVC 14 expects 138.69214 and 211.85913

    test_one<polygon, polygon, polygon>("geos_3",
        geos_3[0], geos_3[1],
        1, -1, 16211128.5,
        1, -1, 13180420.0,
        1, -1, 16211128.5 + 13180420.0);
#endif

    test_one<polygon, polygon, polygon>("geos_4",
        geos_4[0], geos_4[1],
        1, -1, 971.9163115,
        1, -1, 1332.4163115);

    test_one<polygon, polygon, polygon>("ggl_list_20110306_javier",
        ggl_list_20110306_javier[0], ggl_list_20110306_javier[1],
        1, -1, 71495.3331,
        2, -1, 8960.49049,
        2, -1, 71495.3331 + 8960.49049);

    test_one<polygon, polygon, polygon>("ggl_list_20110307_javier",
        ggl_list_20110307_javier[0], ggl_list_20110307_javier[1],
        1, if_typed<ct, float>(14, 13), 16815.6,
        1, 4, 3200.4,
        tolerance(0.01));

    if ( BOOST_GEOMETRY_CONDITION((! boost::is_same<ct, float>::value)) )
    {
        test_one<polygon, polygon, polygon>("ggl_list_20110716_enrico",
            ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1],
            3, -1, 35723.8506317139,
            1, -1, 58456.4964294434,
            1, -1, 35723.8506317139 + 58456.4964294434);
    }

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<polygon, polygon, polygon>("ggl_list_20110820_christophe",
        ggl_list_20110820_christophe[0], ggl_list_20110820_christophe[1],
        1, -1, 2.8570121719168924,
        1, -1, 64.498061986388564);
#endif

    test_one<polygon, polygon, polygon>("ggl_list_20120717_volker",
        ggl_list_20120717_volker[0], ggl_list_20120717_volker[1],
        1, 11, 3370866.2295081965,
        1, 5, 384.2295081964694,
        tolerance(0.01));

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    // 2011-07-02 / 2014-06-19
    // Interesting FP-precision case.
    // sql server gives: 6.62295817619452E-05
    // PostGIS gives: 0.0 (no output)
    // Boost.Geometry gave results depending on FP-type, and compiler, and operating system.
    // Since rescaling to integer results are equal w.r.t. compiler/FP type,
    // however, some long spikes are still generated in the resulting difference
    test_one<polygon, polygon, polygon>("ggl_list_20110627_phillip",
        ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1],
        if_typed_tt<ct>(1, 1), -1,
        if_typed_tt<ct>(0.0000000000001105367, 0.000125137888971949),
        1, -1, 3577.40960816756,
        tolerance(0.01)
        );
#endif

    // Ticket 8310, one should be completely subtracted from the other.
    test_one<polygon, polygon, polygon>("ticket_8310a",
        ticket_8310a[0], ticket_8310a[1],
        1, 10, 10.11562724,
        0, 0, 0);
    test_one<polygon, polygon, polygon>("ticket_8310b",
        ticket_8310b[0], ticket_8310b[1],
        1, 10, 10.12655608,
        0, 0, 0);
    test_one<polygon, polygon, polygon>("ticket_8310c",
        ticket_8310c[0], ticket_8310c[1],
        1, 10, 10.03103292,
        0, 0, 0);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<polygon, polygon, polygon>("ticket_9081_15",
            ticket_9081_15[0], ticket_9081_15[1],
            2, 10, 0.0334529710902111,
            1, 4, 5.3469555172380723e-010);
#endif

    test_one<polygon, polygon, polygon>("ticket_9081_314",
            ticket_9081_314[0], ticket_9081_314[1],
            2, 12, 0.0451236449624935,
            0, 0, 0);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<polygon, polygon, polygon>("ticket_9563",
            ticket_9563[0], ticket_9563[1],
            0, 0, 0,
            6, 24, 20.096189);

    test_one<polygon, polygon, polygon>("ticket_10108_a",
            ticket_10108_a[0], ticket_10108_a[1],
            1, 4,  0.0145037,
            1, 4,  0.029019232);
    test_one<polygon, polygon, polygon>("ticket_10108_b",
            ticket_10108_b[0], ticket_10108_b[1],
            1, 5, 1081.68697,
            1, 5, 1342.65795);
#endif

    // From assemble-test, with a u/u case
    test_one<polygon, polygon, polygon>("assemble_0210",
            "POLYGON((0 0,0 10,10 10,10 0,0 0),(8.5 1,9.5 1,9.5 2,8.5 2,8.5 1))",
            "POLYGON((2 0.5,0.5 2,0.5 8,2 9.5,6 9.5,8.5 8,8.5 2,7 0.5,2 0.5),(2 2,7 2,7 8,2 8,2 2))",
            2, 23, 62.25,
            0, 0, 0.0);

    // Other combi's
    {
        test_one<polygon, polygon, ring>(
                "star_ring_ring", example_star, example_ring,
                5, 22, 1.1901714, 5, 27, 1.6701714);

        test_one<polygon, ring, polygon>(
                "ring_star_ring", example_ring, example_star,
                5, 27, 1.6701714, 5, 22, 1.1901714);

        static std::string const clip = "POLYGON((2.5 0.5,5.5 2.5))";

        test_one<polygon, box, ring>("star_box",
            clip, example_star,
            4, 20, 2.833333, 4, 16, 0.833333);

        test_one<polygon, ring, box>("box_star",
            example_star, clip,
            4, 16, 0.833333, 4, 20, 2.833333);
    }

    // Counter clockwise
    {
        typedef bg::model::polygon<P, false> polygon_ccw;
        test_one<polygon, polygon_ccw, polygon_ccw>(
                "star_ring_ccw", example_star, example_ring,
                5, 22, 1.1901714, 5, 27, 1.6701714);
        test_one<polygon, polygon, polygon_ccw>(
                "star_ring_ccw1", example_star, example_ring,
                5, 22, 1.1901714, 5, 27, 1.6701714);
        test_one<polygon, polygon_ccw, polygon>(
                "star_ring_ccw2", example_star, example_ring,
                5, 22, 1.1901714, 5, 27, 1.6701714);
    }

    // Multi/box (should be moved to multi)
    {
        typedef bg::model::multi_polygon<polygon> mp;

        static std::string const clip = "POLYGON((2 2,4 4))";

        test_one<polygon, box, mp>("simplex_multi_box_mp",
            clip, case_multi_simplex[0],
            2, -1, 0.53333333333, 3, -1, 8.53333333333);
        test_one<polygon, mp, box>("simplex_multi_mp_box",
            case_multi_simplex[0], clip,
            3, -1, 8.53333333333, 2, -1, 0.53333333333);

    }

    /***
    Experimental (cut), does not work:
    test_one<polygon, polygon, polygon>(
            "polygon_pseudo_line",
            "POLYGON((0 0,0 4,4 4,4 0,0 0))",
            "POLYGON((2 -2,2 -1,2 6,2 -2))",
            5, 22, 1.1901714,
            5, 27, 1.6701714);
    ***/

#ifdef BOOST_GEOMETRY_TEST_INCLUDE_FAILING_TESTS
    test_one<polygon, polygon, polygon>("ticket_11725_2",
        ticket_11725_2[0], ticket_11725_2[1],
        2, -1, 7.5, 0, -1, 0.0);
    test_one<polygon, polygon, polygon>("mysql_21977775",
        mysql_21977775[0], mysql_21977775[1],
        2, -1, 160.856568913, 2, -1, 92.3565689126);
#endif

    test_one<polygon, polygon, polygon>("mysql_21965285",
        mysql_21965285[0], mysql_21965285[1],
        1, -1, 92.0,
        1, -1, 14.0,
        1, -1, 92.0 + 14.0);
}
Exemplo n.º 21
0
    static inline result_type apply(T1 const& lon1,
                                    T1 const& lat1,
                                    T2 const& lon2,
                                    T2 const& lat2,
                                    Spheroid const& spheroid)
    {
        result_type result;

        // coordinates in radians

        if ( math::equals(lon1, lon2) && math::equals(lat1, lat2) )
        {
            return result;
        }

        CT const c0 = CT(0);
        CT const c1 = CT(1);
        CT const pi = math::pi<CT>();
        CT const f = formula::flattening<CT>(spheroid);

        CT const dlon = lon2 - lon1;
        CT const sin_dlon = sin(dlon);
        CT const cos_dlon = cos(dlon);
        CT const sin_lat1 = sin(lat1);
        CT const cos_lat1 = cos(lat1);
        CT const sin_lat2 = sin(lat2);
        CT const cos_lat2 = cos(lat2);

        // H,G,T = infinity if cos_d = 1 or cos_d = -1
        // lat1 == +-90 && lat2 == +-90
        // lat1 == lat2 && lon1 == lon2
        CT cos_d = sin_lat1*sin_lat2 + cos_lat1*cos_lat2*cos_dlon;
        // on some platforms cos_d may be outside valid range
        if (cos_d < -c1)
            cos_d = -c1;
        else if (cos_d > c1)
            cos_d = c1;

        CT const d = acos(cos_d); // [0, pi]
        CT const sin_d = sin(d);  // [-1, 1]

        if ( BOOST_GEOMETRY_CONDITION(EnableDistance) )
        {
            CT const K = math::sqr(sin_lat1-sin_lat2);
            CT const L = math::sqr(sin_lat1+sin_lat2);
            CT const three_sin_d = CT(3) * sin_d;

            CT const one_minus_cos_d = c1 - cos_d;
            CT const one_plus_cos_d = c1 + cos_d;
            // cos_d = 1 or cos_d = -1 means that the points are antipodal

            CT const H = math::equals(one_minus_cos_d, c0) ?
                            c0 :
                            (d + three_sin_d) / one_minus_cos_d;
            CT const G = math::equals(one_plus_cos_d, c0) ?
                            c0 :
                            (d - three_sin_d) / one_plus_cos_d;

            CT const dd = -(f/CT(4))*(H*K+G*L);

            CT const a = get_radius<0>(spheroid);

            result.distance = a * (d + dd);
        }

        if ( BOOST_GEOMETRY_CONDITION(CalcAzimuths) )
        {
            // sin_d = 0 <=> antipodal points
            if (math::equals(sin_d, c0))
            {
                // T = inf
                // dA = inf
                // azimuth = -inf
                result.azimuth = lat1 <= lat2 ? c0 : pi;
            }
            else
            {
                CT const c2 = CT(2);

                CT A = c0;
                CT U = c0;
                if (math::equals(cos_lat2, c0))
                {
                    if (sin_lat2 < c0)
                    {
                        A = pi;
                    }
                }
                else
                {
                    CT const tan_lat2 = sin_lat2/cos_lat2;
                    CT const M = cos_lat1*tan_lat2-sin_lat1*cos_dlon;
                    A = atan2(sin_dlon, M);
                    CT const sin_2A = sin(c2*A);
                    U = (f/ c2)*math::sqr(cos_lat1)*sin_2A;
                }

                CT B = c0;
                CT V = c0;
                if (math::equals(cos_lat1, c0))
                {
                    if (sin_lat1 < c0)
                    {
                        B = pi;
                    }
                }
                else
                {
                    CT const tan_lat1 = sin_lat1/cos_lat1;
                    CT const N = cos_lat2*tan_lat1-sin_lat2*cos_dlon;
                    B = atan2(sin_dlon, N);
                    CT const sin_2B = sin(c2*B);
                    V = (f/ c2)*math::sqr(cos_lat2)*sin_2B;
                }

                CT const T = d / sin_d;

                // even with sin_d == 0 checked above if the second point
                // is somewhere in the antipodal area T may still be great
                // therefore dA and dB may be great and the resulting azimuths
                // may be some more or less arbitrary angles

                if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth))
                {
                    CT const dA = V*T - U;
                    result.azimuth = A - dA;
                    normalize_azimuth(result.azimuth, A, dA);
                }

                if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth))
                {
                    CT const dB = -U*T + V;
                    result.reverse_azimuth = pi - B - dB;
                    if (result.reverse_azimuth > pi)
                    {
                        result.reverse_azimuth -= 2 * pi;
                    }
                    normalize_azimuth(result.reverse_azimuth, B, dB);
                }
            }
        }

        if (BOOST_GEOMETRY_CONDITION(CalcQuantities))
        {
            typedef differential_quantities<CT, EnableReducedLength, EnableGeodesicScale, 1> quantities;
            quantities::apply(dlon, sin_lat1, cos_lat1, sin_lat2, cos_lat2,
                              result.azimuth, result.reverse_azimuth,
                              get_radius<2>(spheroid), f,
                              result.reduced_length, result.geodesic_scale);
        }

        return result;
    }
void test_linestring_multi_linestring()
{
    typedef bg::model::linestring<P> ls;
    typedef bg::model::multi_linestring<ls> mls;

    // LS disjoint
    test_geometry<ls, mls>("LINESTRING(0 0,10 0)", "MULTILINESTRING((1 0,2 0),(1 1,2 1))", "101FF0102");
    // linear ring disjoint
    test_geometry<ls, mls>("LINESTRING(0 0,10 0)", "MULTILINESTRING((1 0,2 0),(1 1,2 1,2 2,1 1))", "101FF01F2");
    // 2xLS forming non-simple linear ring disjoint
    test_geometry<ls, mls>("LINESTRING(0 0,10 0)", "MULTILINESTRING((1 0,2 0),(1 1,2 1,2 2),(1 1,2 2))", "101FF01F2");

    test_geometry<ls, mls>("LINESTRING(0 0,10 0)",
                           "MULTILINESTRING((1 0,9 0),(9 0,2 0))",
                           "101FF0FF2");

    // rings
    test_geometry<ls, mls>("LINESTRING(0 0,5 0,5 5,0 5,0 0)",
                           "MULTILINESTRING((5 5,0 5,0 0),(0 0,5 0,5 5))",
                           "1FFFFFFF2");
    test_geometry<ls, mls>("LINESTRING(0 0,5 0,5 5,0 5,0 0)",
                           "MULTILINESTRING((5 5,5 0,0 0),(0 0,0 5,5 5))",
                           "1FFFFFFF2");
    // overlapping rings
    test_geometry<ls, mls>("LINESTRING(0 0,5 0,5 5,0 5,0 0)",
                           "MULTILINESTRING((5 5,0 5,0 0),(0 0,5 0,5 5,0 5))",
                           "10FFFFFF2");
    test_geometry<ls, mls>("LINESTRING(0 0,5 0,5 5,0 5,0 0)",
                           "MULTILINESTRING((5 5,5 0,0 0),(0 0,0 5,5 5,5 0))",
                           "10FFFFFF2");

    // INVALID LINESTRINGS
    // 1-point LS (a Point) disjoint
    //test_geometry<ls, mls>("LINESTRING(0 0,10 0)", "MULTILINESTRING((1 0,2 0),(1 1))", "101FF00F2");
    //test_geometry<ls, mls>("LINESTRING(0 0,10 0)", "MULTILINESTRING((1 0,2 0),(1 1,1 1))", "101FF00F2");
    //test_geometry<ls, mls>("LINESTRING(0 0,10 0)", "MULTILINESTRING((1 0,2 0),(1 1,1 1,1 1))", "101FF00F2");
    // 1-point LS (a Point) NOT disjoint
    //test_geometry<ls, mls>("LINESTRING(0 0,10 0)", "MULTILINESTRING((1 0,9 0),(2 0))", "101FF0FF2");
    //test_geometry<ls, mls>("LINESTRING(0 0,10 0)", "MULTILINESTRING((1 0,9 0),(2 0,2 0))", "101FF0FF2");
    //test_geometry<ls, mls>("LINESTRING(0 0,10 0)", "MULTILINESTRING((1 0,9 0),(2 0,2 0,2 0))", "101FF0FF2");

    // point-like
    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      // |--------------|
                           "MULTILINESTRING((0 0, 1 0),(2 0, 2 0))",    // |------|  *
                           "101F00FF2");
    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      // |--------------|
                           "MULTILINESTRING((0 0, 1 0),(1 0, 1 0))",    // |------*
                           "101F00FF2");
    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      // |--------------|
                           "MULTILINESTRING((5 0, 1 0),(1 0, 1 0))",    //        *-------|
                           "101F00FF2");
    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      // |--------------|
                           "MULTILINESTRING((0 0, 1 0),(5 0, 5 0))",    // |------|       *
                           "10100FFF2");
    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      // |--------------|
                           "MULTILINESTRING((0 0, 1 0),(0 0, 0 0))",    // *------|
                           "101000FF2");
    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      // |--------------|
                           "MULTILINESTRING((4 0, 5 0),(5 0, 5 0))",    //         |------*
                           "101000FF2");
    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      // |--------------|
                           "MULTILINESTRING((1 0, 2 0),(0 0, 0 0))",    // *  |------|
                           "1010F0FF2");

    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      //   |--------------|
                           "MULTILINESTRING((2 0, 2 0),(2 0, 2 2))",    //            *
                           "001FF0102");                                //            |

    // for consistency
    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      // |--------------|
                           "MULTILINESTRING((0 0, 5 0),(0 0, 2 0))",    // |--------------|
                           "10F00FFF2");                                // |------|

    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      // |--------------|
                           "MULTILINESTRING((0 0, 5 0),(3 0, 5 0))",    // |--------------|
                           "10F00FFF2");                                //         |------|

    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      // |--------------|
                           "MULTILINESTRING((0 0, 5 0),(0 0, 6 0))",    // |--------------|
                           "1FF00F102");                                // |----------------|

    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      //   |--------------|
                           "MULTILINESTRING((0 0, 5 0),(-1 0, 5 0))",   //   |--------------|
                           "1FF00F102");                                // |----------------|

    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      //   |--------------|
                           "MULTILINESTRING((0 0, 5 0),(-1 0, 6 0))",   //   |--------------|
                           "1FF00F102");                                // |------------------|

    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      //   |--------------|
                           "MULTILINESTRING((0 0, 5 0),(-1 0, 2 0))",   //   |--------------|
                           "10F00F102");                                // |-------|

    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      //   |--------------|
                           "MULTILINESTRING((0 0, 5 0),(2 0, 6 0))",    //   |--------------|
                           "10F00F102");                                //            |-------|

    test_geometry<ls, mls>("LINESTRING(0 0, 5 0)",                      //   |--------------|
                           "MULTILINESTRING((0 0, 5 0),(2 0, 2 2))",    //   |--------------|
                           "10FF0F102");                                //            |
                                                                        //            |

    if ( BOOST_GEOMETRY_CONDITION(boost::is_floating_point<typename bg::coordinate_type<ls>::type>::value) )
    {
        // related to https://svn.boost.org/trac/boost/ticket/10904
        test_geometry<ls, mls>("LINESTRING(-2305843009213693956 4611686018427387906, -33 -92, 78 83)",
                               "MULTILINESTRING((20 100, 31 -97, -46 57, -20 -4),(-71 -4))",
                               "*********"); // TODO: be more specific with the result
    }

    // 22.01.2015
    // inspired by L/A and A/A
    test_geometry<ls, mls>("LINESTRING(1 1,2 2)", "MULTILINESTRING((0 0,1 1),(1 1,3 3))", "1FF0FF102");

    // 25.01.2015
    test_geometry<ls, mls>("LINESTRING(1 1, 5 5, 4 4)",
                           "MULTILINESTRING((2 5, 7 5, 8 3, 6 3, 4 0),(0 0,10 10))",
                           "1FF0FF102");
    test_geometry<ls, mls>("LINESTRING(4 1, 4 5, 4 4)",
                           "MULTILINESTRING((2 5, 7 5, 8 3, 6 3, 4 0),(4 0, 4 8, 0 4))",
                           "1FF0FF102");
    test_geometry<ls, mls>("LINESTRING(1 1,5 5,4 4)",
                           "MULTILINESTRING((5 0,5 5,5 10),(0 0,10 10))",
                           "1FF0FF102");
    test_geometry<ls, mls>("LINESTRING(1 1,5 5,1 0)",
                           "MULTILINESTRING((5 0,5 5,5 10),(0 0,5 5,1 0))",
                           "1FF00F102");
    test_geometry<ls, mls>("LINESTRING(5 5,4 4)",
                           "MULTILINESTRING((5 0,5 5,5 10),(0 0,10 10))",
                           "1FF0FF102");
    test_geometry<ls, mls>("LINESTRING(6 6,5 5,4 4)",
                           "MULTILINESTRING((5 0,5 5,5 10),(0 0,10 10))",
                           "1FF0FF102");
    test_geometry<ls, mls>("LINESTRING(5 5,4 4)",
                           "MULTILINESTRING((5 0,5 5,5 10))",
                           "FF10F0102");
}
Exemplo n.º 23
0
void test_all()
{
    typedef bg::model::polygon<P, Clockwise> polygon_type;
    typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;

    bg::strategy::buffer::join_miter join_miter;
    bg::strategy::buffer::join_round join_round(100);
    bg::strategy::buffer::join_round join_round_rough(12);
    bg::strategy::buffer::end_flat end_flat;

    bg::strategy::buffer::join_round join_round32(32);
    bg::strategy::buffer::end_round end_round32(32);

    test_one<multi_polygon_type, polygon_type>("triangles424", triangles, join_miter, end_flat, 417.910, 4.24);
    test_one<multi_polygon_type, polygon_type>("triangles425", triangles, join_miter, end_flat, 418.918, 4.25);
    test_one<multi_polygon_type, polygon_type>("triangles426", triangles, join_miter, end_flat, 419.927, 4.26);
    test_one<multi_polygon_type, polygon_type>("zonethru_10", zonethru, join_miter, end_flat, 96.0000, 1.0);

    test_one<multi_polygon_type, polygon_type>("multi_simplex_05", simplex, join_round, end_flat, 23.7030, 0.5);
    test_one<multi_polygon_type, polygon_type>("multi_simplex_05", simplex, join_miter, end_flat, 24.5965, 0.5);
    test_one<multi_polygon_type, polygon_type>("multi_simplex_10", simplex, join_round, end_flat, 34.2532, 1.0);
    test_one<multi_polygon_type, polygon_type>("multi_simplex_10", simplex, join_miter, end_flat, 38.1379, 1.0);
    test_one<multi_polygon_type, polygon_type>("multi_simplex_20", simplex, join_round, end_flat, 59.9159, 2.0);
    test_one<multi_polygon_type, polygon_type>("multi_simplex_20", simplex, join_miter, end_flat, 77.7060, 2.0);
    test_one<multi_polygon_type, polygon_type>("multi_simplex_50", simplex, join_round, end_flat, 174.46, 5.0);
    test_one<multi_polygon_type, polygon_type>("multi_simplex_50", simplex, join_miter, end_flat, 298.797, 5.0);

    test_one<multi_polygon_type, polygon_type>("multi_simplex_01", simplex, join_round, end_flat, 9.7514, -0.1);
    test_one<multi_polygon_type, polygon_type>("multi_simplex_05", simplex, join_round, end_flat, 3.2019, -0.5);
    test_one<multi_polygon_type, polygon_type>("multi_simplex_10", simplex, join_round, end_flat, 0.2012, -1.0);
    test_one<multi_polygon_type, polygon_type>("multi_simplex_12", simplex, join_round, end_flat, 0.0, -1.2);

    test_one<multi_polygon_type, polygon_type>("zonethru_05", zonethru, join_round, end_flat, 67.4627, 0.5);
    test_one<multi_polygon_type, polygon_type>("zonethru_05", zonethru, join_miter, end_flat, 68.0000, 0.5);
    test_one<multi_polygon_type, polygon_type>("zonethru_10", zonethru, join_round, end_flat, 93.8508, 1.0);
    test_one<multi_polygon_type, polygon_type>("zonethru_10", zonethru, join_miter, end_flat, 96.0000, 1.0);
    test_one<multi_polygon_type, polygon_type>("zonethru_15", zonethru, join_round, end_flat, 114.584, 1.5);
    test_one<multi_polygon_type, polygon_type>("zonethru_15", zonethru, join_miter, end_flat, 117.000, 1.5);

    test_one<multi_polygon_type, polygon_type>("wrapped_05", wrapped, join_round, end_flat, 104.570, 0.5);
    test_one<multi_polygon_type, polygon_type>("wrapped_05", wrapped, join_miter, end_flat, 105.000, 0.5);
    test_one<multi_polygon_type, polygon_type>("wrapped_10", wrapped, join_round, end_flat, 142.281, 1.0);
    test_one<multi_polygon_type, polygon_type>("wrapped_10", wrapped, join_miter, end_flat, 144.000, 1.0);
    test_one<multi_polygon_type, polygon_type>("wrapped_15", wrapped, join_round, end_flat, 167.066, 1.5);
    test_one<multi_polygon_type, polygon_type>("wrapped_15", wrapped, join_miter, end_flat, 169.000, 1.5);

    test_one<multi_polygon_type, polygon_type>("wrapped_05", wrapped, join_round, end_flat, 33.215, -0.5);
    test_one<multi_polygon_type, polygon_type>("wrapped_05", wrapped, join_miter, end_flat, 33.000, -0.5);
    test_one<multi_polygon_type, polygon_type>("wrapped_15", wrapped, join_round, end_flat, 0.0, -1.5);
    test_one<multi_polygon_type, polygon_type>("wrapped_15", wrapped, join_miter, end_flat, 0.0, -1.5);
    test_one<multi_polygon_type, polygon_type>("wrapped_25", wrapped, join_round, end_flat, 0.0, -2.5);
    test_one<multi_polygon_type, polygon_type>("wrapped_25", wrapped, join_miter, end_flat, 0.0, -2.5);
    test_one<multi_polygon_type, polygon_type>("wrapped_50", wrapped, join_round, end_flat, 0.0, -5.0);
    test_one<multi_polygon_type, polygon_type>("wrapped_50", wrapped, join_miter, end_flat, 0.0, -5.0);

    test_one<multi_polygon_type, polygon_type>("nested_05", nested, join_round, end_flat, 191.570, 0.5);
    test_one<multi_polygon_type, polygon_type>("nested_05", nested, join_round, end_flat, 64.430, -0.5);
    test_one<multi_polygon_type, polygon_type>("nested_10", nested, join_round, end_flat, 254.279, 1.0);
    test_one<multi_polygon_type, polygon_type>("nested_10", nested, join_round, end_flat, 1.721, -1.0);
    test_one<multi_polygon_type, polygon_type>("nested_25", nested, join_round, end_flat, 355.622, 2.5);
    test_one<multi_polygon_type, polygon_type>("nested_25", nested, join_round, end_flat, 0, -2.5);
    // 3.0 is exactly touching (for the deflate case)
    test_one<multi_polygon_type, polygon_type>("nested_30", nested, join_round, end_flat, 392.256, 3.0);
    test_one<multi_polygon_type, polygon_type>("nested_30", nested, join_round, end_flat, 0, -3.0);
    test_one<multi_polygon_type, polygon_type>("nested_29", nested, join_round, end_flat, 384.803, 2.9);
    test_one<multi_polygon_type, polygon_type>("nested_29", nested, join_round, end_flat, 0, -2.9);
    test_one<multi_polygon_type, polygon_type>("nested_31", nested, join_round, end_flat, 399.771, 3.1);
    test_one<multi_polygon_type, polygon_type>("nested_31", nested, join_round, end_flat, 0, -3.1);

    test_one<multi_polygon_type, polygon_type>("degenerate0", degenerate0, join_round, end_flat, 0.0, 1.0);
    test_one<multi_polygon_type, polygon_type>("degenerate1", degenerate1, join_round, end_flat, 5.708, 1.0);
    test_one<multi_polygon_type, polygon_type>("degenerate2", degenerate2, join_round, end_flat, 133.0166, 0.75);

    test_one<multi_polygon_type, polygon_type>("rt_a", rt_a, join_round, end_flat, 34.5381, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_a", rt_a, join_miter, end_flat, 36, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_b", rt_b, join_round, end_flat, 31.4186, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_b", rt_b, join_miter, end_flat, 34, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_c", rt_c, join_round, end_flat, 14.7093, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_c", rt_c, join_miter, end_flat, 16, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_d", rt_d, join_round, end_flat, 18.8726, 0.3);
    test_one<multi_polygon_type, polygon_type>("rt_e", rt_e, join_round, end_flat, 14.1866, 0.3);

    test_one<multi_polygon_type, polygon_type>("rt_g1", rt_g1, join_round, end_flat, 24.719, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_g3", rt_g3, join_miter, end_flat, 16.5711, 1.0);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<multi_polygon_type, polygon_type>("rt_d", rt_d, join_miter, end_flat, 19.8823, 0.3);
    test_one<multi_polygon_type, polygon_type>("rt_e", rt_e, join_miter, end_flat, 15.1198, 0.3);
    test_one<multi_polygon_type, polygon_type>("rt_f", rt_f, join_miter, end_flat, 4.60853, 0.3);
    test_one<multi_polygon_type, polygon_type>("rt_g1", rt_g1, join_miter, end_flat, 30.3137, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_g2", rt_g2, join_miter, end_flat, 18.5711, 1.0);
#endif

    test_one<multi_polygon_type, polygon_type>("rt_h", rt_h, join_round, end_flat, 47.6012, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_h", rt_h, join_miter, end_flat, 61.7058, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_i", rt_i, join_round, end_flat, 10.7528, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_i", rt_i, join_miter, end_flat, 13.6569, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_j", rt_j, join_round, end_flat, 28.7309, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_j", rt_j, join_miter, end_flat, 35.1421, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_k", rt_k, join_round, end_flat, 42.0092, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_k", rt_k, join_miter, end_flat, 48.0563, 1.0);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<multi_polygon_type, polygon_type>("rt_l", rt_l, join_miter, end_flat, 19.3995, 1.0);
#endif

    test_one<multi_polygon_type, polygon_type>("rt_m1", rt_m1, join_round, end_flat, 14.1074, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_m1", rt_m1, join_miter, end_flat, 19.4853, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_m2", rt_m2, join_miter, end_flat, 21.4853, 1.0);

    test_one<multi_polygon_type, polygon_type>("rt_n", rt_n,  join_miter, end_flat, 18.4853, 1.0);

    test_one<multi_polygon_type, polygon_type>("rt_o1", rt_o1, join_round, end_flat, 17.536, 1.0);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<multi_polygon_type, polygon_type>("rt_o1", rt_o1, join_miter, end_flat, 20.9142, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_o2", rt_o2, join_miter, end_flat, 25.7426, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_o3", rt_o3, join_miter, end_flat, 28.8247, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_o4", rt_o4, join_miter, end_flat, 34.6532, 1.0);
#endif

    test_one<multi_polygon_type, polygon_type>("rt_p1", rt_p1, join_miter, end_flat, 24.8211, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p2", rt_p2, join_miter, end_flat, 21.4853, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p3", rt_p3, join_miter, end_flat, 22.3995, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p4", rt_p4, join_miter, end_flat, 33.0563, 1.0);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<multi_polygon_type, polygon_type>("rt_p5", rt_p5, join_miter, end_flat, 17, 1.0);
#endif

    test_one<multi_polygon_type, polygon_type>("rt_p6", rt_p6, join_miter, end_flat, 18.4853, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p7", rt_p7, join_miter, end_flat, 26.2279, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p8", rt_p8, join_miter, end_flat, 29.0563, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p9", rt_p9, join_miter, end_flat, 26.1421, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p10", rt_p10, join_miter, end_flat, 23.3995, 1.0);

    test_one<multi_polygon_type, polygon_type>("rt_p11", rt_p11, join_miter, end_flat, 28.7426, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p12", rt_p12, join_miter, end_flat, 22.5711, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p13", rt_p13, join_miter, end_flat, 19.9142, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p14", rt_p14, join_miter, end_flat, 20.8284, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p15", rt_p15, join_miter, end_flat, 23.6569, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p16", rt_p16, join_miter, end_flat, 23.4853, 1.0);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<multi_polygon_type, polygon_type>("rt_p17", rt_p17, join_miter, end_flat, 25.3137, 1.0);
#endif

    test_one<multi_polygon_type, polygon_type>("rt_p18", rt_p18, join_miter, end_flat, 23.3137, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p19", rt_p19, join_miter, end_flat, 25.5637, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_p20", rt_p20, join_miter, end_flat, 25.4853, 1.0);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<multi_polygon_type, polygon_type>("rt_p21", rt_p21, join_miter, end_flat, 17.1716, 1.0);
#endif

    test_one<multi_polygon_type, polygon_type>("rt_p22", rt_p22, join_miter, end_flat, 26.5711, 1.0);

    test_one<multi_polygon_type, polygon_type>("rt_q1", rt_q1, join_miter, end_flat, 27, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_q2", rt_q2, join_miter, end_flat, 26.4853, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_q2", rt_q2, join_miter, end_flat, 0.9697, -0.25);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<multi_polygon_type, polygon_type>("rt_r", rt_r, join_miter, end_flat, 21.0761, 1.0);
#endif

    test_one<multi_polygon_type, polygon_type>("rt_s1", rt_s1, join_miter, end_flat, 20.4853, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_s2", rt_s2, join_miter, end_flat, 24.6495, 1.0);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<multi_polygon_type, polygon_type>("rt_t1", rt_t, join_miter, end_flat, 15.6569, 1.0);
#endif

    test_one<multi_polygon_type, polygon_type>("rt_t2", rt_t, join_miter, end_flat, 0.1679, -0.25);

    test_one<multi_polygon_type, polygon_type>("rt_u1", rt_u1, join_round, end_flat, 33.2032, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_u2", rt_u2, join_round, end_flat, 138.8001, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_u3", rt_u3, join_round, end_flat, 133.4526, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_u4", rt_u4, join_round, end_flat, 126.9268, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_u5", rt_u5, join_round, end_flat, 78.4906, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_u6", rt_u6, join_round, end_flat, 115.4461, 1.0);

    test_one<multi_polygon_type, polygon_type>("rt_u7", rt_u7, join_miter, end_flat, 42.6421, 1.0);
    if (BOOST_GEOMETRY_CONDITION(Clockwise))
    {
        // This configuration is not yet stable. By the changed sorting of turns, they now fail
        // (the change was irrelevant to this, so they succeeded earlier by luck).
        // TODO: get_occupation/left_turns in combination with a u/u turn
        test_one<multi_polygon_type, polygon_type>("rt_u7", rt_u7, join_round, end_flat, 35.6233, 1.0);
        test_one<multi_polygon_type, polygon_type>("rt_u7_rough", rt_u7, join_round_rough, end_flat, 35.1675, 1.0);
    }

    test_one<multi_polygon_type, polygon_type>("rt_u8", rt_u8, join_miter, end_flat, 70.9142, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_u9", rt_u9, join_miter, end_flat, 59.3063, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_u10", rt_u10, join_miter, end_flat, 144.0858, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_u10_50", rt_u10, join_miter, end_flat, 0.2145, -0.50);
    test_one<multi_polygon_type, polygon_type>("rt_u10_25", rt_u10, join_miter, end_flat, 9.6682, -0.25);

    test_one<multi_polygon_type, polygon_type>("rt_u11", rt_u11, join_miter, end_flat, 131.3995, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_u11_50", rt_u11, join_miter, end_flat, 0.04289, -0.50);
    test_one<multi_polygon_type, polygon_type>("rt_u11_25", rt_u11, join_miter, end_flat, 10.1449, -0.25);

#if defined(BOOST_GEOMETRY_BUFFER_USE_SIDE_OF_INTERSECTION)
    test_one<multi_polygon_type, polygon_type>("rt_u12", rt_u12, join_miter, end_flat, 142.1348, 1.0);
    test_one<multi_polygon_type, polygon_type>("rt_u13", rt_u13, join_miter, end_flat, 115.4853, 1.0);
#endif

    test_one<multi_polygon_type, polygon_type>("neighbouring_small",
        neighbouring,
        join_round32, end_round32, 128, -1);
    test_one<multi_polygon_type, polygon_type>("neighbouring_with_holes_small",
        neighbouring_with_holes,
        join_round32, end_round32, 97.757, -1);
    test_one<multi_polygon_type, polygon_type>("neighbouring_large",
        neighbouring,
        join_round32, end_round32, 0, -10);
    test_one<multi_polygon_type, polygon_type>("neighbouring_with_holes_large",
        neighbouring_with_holes,
        join_round32, end_round32, 0, -10);

    test_one<multi_polygon_type, polygon_type>("mysql_report_2015_07_05_1",
        mysql_report_2015_07_05_1,
        join_round32, end_round32, 6.04454566324708726e+23, 5526,
        same_distance, false, 1e+020);
    test_one<multi_polygon_type, polygon_type>("mysql_report_2015_07_05_2",
        mysql_report_2015_07_05_2,
        join_round32, end_round32, 0, 948189399);
}
Exemplo n.º 24
0
void test_areal()
{
    typedef typename bg::coordinate_type<Polygon>::type ct;
    bool const ccw = bg::point_order<Polygon>::value == bg::counterclockwise;
    bool const open = bg::closure<Polygon>::value == bg::open;

    test_one<Polygon, Polygon, Polygon>("simplex_with_empty_1",
        simplex_normal[0], polygon_empty,
        0, 0, 0.0);
    test_one<Polygon, Polygon, Polygon>("simplex_with_empty_2",
        polygon_empty, simplex_normal[0],
        0, 0, 0.0);

    test_one<Polygon, Polygon, Polygon>("simplex_normal",
        simplex_normal[0], simplex_normal[1],
        1, 7, 5.47363293);
    test_one<Polygon, Polygon, Polygon>("star_ring", example_star, example_ring,
        1, 18, 2.80983);

    test_one<Polygon, Polygon, Polygon>("star_poly", example_star, example_polygon,
        1, 0, // CLN: 23 points, other types: 22 point (one is merged)
        2.5020508);
    test_one<Polygon, Polygon, Polygon>("first_within_second1",
        first_within_second[0], first_within_second[1],
        1, 5, 1.0);

    test_one<Polygon, Polygon, Polygon>("first_within_second2",
        first_within_second[1], first_within_second[0],
        1, 5, 1.0);

    test_one<Polygon, Polygon, Polygon>("first_within_hole_of_second",
            first_within_hole_of_second[0], first_within_hole_of_second[1],
            0, 0, 0.0);

    // Two forming new hole
    test_one<Polygon, Polygon, Polygon>("new_hole",
        new_hole[0], new_hole[1],
        2, 10, 2.0);

    // Two identical
    test_one<Polygon, Polygon, Polygon>("identical",
        identical[0], identical[1],
        1, 5, 1.0);

    test_one<Polygon, Polygon, Polygon>("intersect_exterior_and_interiors_winded",
        intersect_exterior_and_interiors_winded[0], intersect_exterior_and_interiors_winded[1],
        1, 14, 25.2166667);

    test_one<Polygon, Polygon, Polygon>("intersect_holes_disjoint",
        intersect_holes_disjoint[0], intersect_holes_disjoint[1],
        1, 15, 18.0);

    test_one<Polygon, Polygon, Polygon>("intersect_holes_intersect",
        intersect_holes_intersect[0], intersect_holes_intersect[1],
        1, 14, 18.25);

    test_one<Polygon, Polygon, Polygon>("intersect_holes_intersect_and_disjoint",
        intersect_holes_intersect_and_disjoint[0], intersect_holes_intersect_and_disjoint[1],
        1, 19, 17.25);

    test_one<Polygon, Polygon, Polygon>("intersect_holes_intersect_and_touch",
        intersect_holes_intersect_and_touch[0], intersect_holes_intersect_and_touch[1],
        1, 23, 17.25);

    test_one<Polygon, Polygon, Polygon>("intersect_holes_new_ring",
        intersect_holes_new_ring[0], intersect_holes_new_ring[1],
        2, 23, 122.1039);

    test_one<Polygon, Polygon, Polygon>("winded",
        winded[0], winded[1],
        1, 22, 40.0);

    test_one<Polygon, Polygon, Polygon>("within_holes_disjoint",
        within_holes_disjoint[0], within_holes_disjoint[1],
        1, 15, 23.0);

    test_one<Polygon, Polygon, Polygon>("side_side",
        side_side[0], side_side[1],
        0, 0, 0.0);

    test_one<Polygon, Polygon, Polygon>("two_bends",
        two_bends[0], two_bends[1],
        1, 7, 24.0);

    test_one<Polygon, Polygon, Polygon>("star_comb_15",
        star_comb_15[0], star_comb_15[1],
        28, 150, 189.952883);

    test_one<Polygon, Polygon, Polygon>("simplex_normal",
        simplex_normal[0], simplex_normal[1],
        1, 7, 5.47363293);

    test_one<Polygon, Polygon, Polygon>("distance_zero",
        distance_zero[0], distance_zero[1],
        1, 0 /* f: 4, other: 5 */, 0.29516139, 0.01);

    test_one<Polygon, Polygon, Polygon>("equal_holes_disjoint",
        equal_holes_disjoint[0], equal_holes_disjoint[1],
        1, 20, 81 - 2 * 3 * 3 - 3 * 7);

    test_one<Polygon, Polygon, Polygon>("only_hole_intersections1",
        only_hole_intersections[0], only_hole_intersections[1],
        1, 21, 178.090909);
    test_one<Polygon, Polygon, Polygon>("only_hole_intersection2",
        only_hole_intersections[0], only_hole_intersections[2],
        1, 21, 149.090909);

    test_one<Polygon, Polygon, Polygon>("fitting",
        fitting[0], fitting[1],
        0, 0, 0);

    test_one<Polygon, Polygon, Polygon>("crossed",
        crossed[0], crossed[1],
        3, 0, 1.5);

    test_one<Polygon, Polygon, Polygon>("pie_2_3_23_0",
        pie_2_3_23_0[0], pie_2_3_23_0[1],
        1, 4, 163292.679042133, 0.1);

    test_one<Polygon, Polygon, Polygon>("isovist",
        isovist1[0], isovist1[1],
        1, 19, 88.19203,
        if_typed_tt<ct>(0.01, 0.1));

    // SQL Server gives: 88.1920416352664
    // PostGIS gives:    88.19203677911

    test_one<Polygon, Polygon, Polygon>("geos_1",
        geos_1[0], geos_1[1],
            1, -1, 3461.0214843, 0.005); // MSVC 14 reports 3461.025390625

    // Expectations:
    // In most cases: 0 (no intersection)
    // In some cases: 1.430511474609375e-05 (clang/gcc on Xubuntu using b2)
    // In some cases: 5.6022983000000002e-05 (powerpc64le-gcc-6-0)
    test_one<Polygon, Polygon, Polygon>("geos_2",
        geos_2[0], geos_2[1],
            0, 0, 6.0e-5, -1.0); // -1 denotes: compare with <=

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<Polygon, Polygon, Polygon>("geos_3",
        geos_3[0], geos_3[1],
            0, 0, 0.0);
#endif
    test_one<Polygon, Polygon, Polygon>("geos_4",
        geos_4[0], geos_4[1],
            1, -1, 0.08368849);


    if ( BOOST_GEOMETRY_CONDITION(! ccw && open) )
    {
        // Pointcount for ttmath/double (both 5) or float (4)
        // double returns 5 (since method append_no_dups_or_spikes)
        // but not for ccw/open. Those cases has to be adapted once, anyway,
        // because for open always one point too much is generated...
        test_one<Polygon, Polygon, Polygon>("ggl_list_20110306_javier",
            ggl_list_20110306_javier[0], ggl_list_20110306_javier[1],
            1, if_typed<ct, float>(4, 5),
            0.6649875,
            if_typed<ct, float>(1.0, 0.01));
    }

    // SQL Server reports: 0.400390625
    // PostGIS reports 0.4
    // BG did report 0.4 but is changed to 0.397
    // when selecting other IP closer at endpoint or if segment B is smaller than A
    test_one<Polygon, Polygon, Polygon>("ggl_list_20110307_javier",
        ggl_list_20110307_javier[0], ggl_list_20110307_javier[1],
        1, 4,
        #if defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
            0.40
        #else
            0.397162651, 0.01
        #endif
            );

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<Polygon, Polygon, Polygon>("ggl_list_20110627_phillip",
        ggl_list_20110627_phillip[0], ggl_list_20110627_phillip[1],
        1, if_typed_tt<ct>(6, 5), 11151.6618);
#endif

    test_one<Polygon, Polygon, Polygon>("ggl_list_20110716_enrico",
        ggl_list_20110716_enrico[0], ggl_list_20110716_enrico[1],
        3, 16, 35723.8506317139);

    test_one<Polygon, Polygon, Polygon>("ggl_list_20131119_james",
        ggl_list_20131119_james[0], ggl_list_20131119_james[1],
        1, 4, 6.6125873045, 0.1);

    test_one<Polygon, Polygon, Polygon>("ggl_list_20140223_shalabuda",
        ggl_list_20140223_shalabuda[0], ggl_list_20140223_shalabuda[1],
        1, 4, 3.77106, 0.001);

#if 0
    // TODO: fix this testcase, it should give 0 but instead it gives one of the input polygons
    // Mailed to the Boost.Geometry list on 2014/03/21 by [email protected]
    test_one<Polygon, Polygon, Polygon>("ggl_list_20140321_7415963",
        ggl_list_20140321_7415963[0], ggl_list_20140321_7415963[1],
        0, 0, 0, 0.1);
#endif

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<Polygon, Polygon, Polygon>("buffer_rt_f", buffer_rt_f[0], buffer_rt_f[1],
                1, 4,  0.00029437899183903937, 0.01);
#endif

    test_one<Polygon, Polygon, Polygon>("buffer_rt_g", buffer_rt_g[0], buffer_rt_g[1],
                1, 0, 2.914213562373);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<Polygon, Polygon, Polygon>("ticket_8254", ticket_8254[0], ticket_8254[1],
                1, 4, 3.635930e-08, 0.01);
#endif

    test_one<Polygon, Polygon, Polygon>("ticket_6958", ticket_6958[0], ticket_6958[1],
                1, 4, 4.34355e-05, 0.01);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<Polygon, Polygon, Polygon>("ticket_8652", ticket_8652[0], ticket_8652[1],
                1, 4, 0.0003);
#endif

    test_one<Polygon, Polygon, Polygon>("ticket_8310a", ticket_8310a[0], ticket_8310a[1],
                1, 5, 0.3843747);
    test_one<Polygon, Polygon, Polygon>("ticket_8310b", ticket_8310b[0], ticket_8310b[1],
                1, 5, 0.3734379);
    test_one<Polygon, Polygon, Polygon>("ticket_8310c", ticket_8310c[0], ticket_8310c[1],
                1, 5, 0.4689541);

    test_one<Polygon, Polygon, Polygon>("ticket_9081_15",
                ticket_9081_15[0], ticket_9081_15[1],
                1, 4, 0.0068895780745301394);

    test_one<Polygon, Polygon, Polygon>("ticket_10108_a",
                ticket_10108_a[0], ticket_10108_a[1],
                0, 0, 0.0);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    // msvc  5.6023011e-5
    // mingw 5.6022954e-5
    test_one<Polygon, Polygon, Polygon>("ticket_10108_b",
                ticket_10108_b[0], ticket_10108_b[1],
                0, 0, 5.6022983e-5);
#endif

    test_one<Polygon, Polygon, Polygon>("ticket_10747_a",
                ticket_10747_a[0], ticket_10747_a[1],
                1, 4, 70368744177664);
    test_one<Polygon, Polygon, Polygon>("ticket_10747_b",
                ticket_10747_b[0], ticket_10747_b[1],
                1, 4, 7036874417766400);
    test_one<Polygon, Polygon, Polygon>("ticket_10747_c",
                ticket_10747_c[0], ticket_10747_c[1],
                1, 4, 17592186044416);
    test_one<Polygon, Polygon, Polygon>("ticket_10747_d",
                ticket_10747_d[0], ticket_10747_d[1],
                1, 4, 703687777321);
    test_one<Polygon, Polygon, Polygon>("ticket_10747_e",
                ticket_10747_e[0], ticket_10747_e[1],
                1, 4, 7.0368748575710959e-15);

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<Polygon, Polygon, Polygon>("ticket_9563", ticket_9563[0], ticket_9563[1],
                1, 8, 129.90381);
#endif

#if ! defined(BOOST_GEOMETRY_NO_ROBUSTNESS)
    test_one<Polygon, Polygon, Polygon>("buffer_mp1", buffer_mp1[0], buffer_mp1[1],
                1, 31, 2.271707796);
#endif

    test_one<Polygon, Polygon, Polygon>("buffer_mp2", buffer_mp2[0], buffer_mp2[1],
                1, 29, 0.457126);

    test_one<Polygon, Polygon, Polygon>("case_58_iet",
        case_58[0], case_58[2],
        2, -1, 1.0 / 3.0);

    test_one<Polygon, Polygon, Polygon>("case_80",
        case_80[0], case_80[1],
        0, -1, 0.0);

    test_one<Polygon, Polygon, Polygon>("case_81",
        case_81[0], case_81[1],
        0, -1, 0.0);

    test_one<Polygon, Polygon, Polygon>("mysql_21964049",
        mysql_21964049[0], mysql_21964049[1],
        0, -1, 0.0);

    test_one<Polygon, Polygon, Polygon>("mysql_21964465",
        mysql_21964465[0], mysql_21964465[1],
        0, -1, 0.0);

#ifdef BOOST_GEOMETRY_TEST_INCLUDE_FAILING_TESTS
    test_one<Polygon, Polygon, Polygon>("mysql_21965285_b_inv",
        mysql_21965285_b_inv[0],
        mysql_21965285_b_inv[1],
        2, -1, 183.71376870369406);
#endif

    return;

    test_one<Polygon, Polygon, Polygon>(
        "polygon_pseudo_line",
        "Polygon((0 0,0 4,4 4,4 0,0 0))",
        "Polygon((2 -2,2 -1,2 6,2 -2))",
        5, 22, 1.1901714);
}
Exemplo n.º 25
0
    static inline result_type apply(T1 const& lon1,
                                    T1 const& lat1,
                                    T2 const& lon2,
                                    T2 const& lat2,
                                    Spheroid const& spheroid)
    {
        result_type result;

        if (math::equals(lat1, lat2) && math::equals(lon1, lon2))
        {
            return result;
        }

        CT const c1 = 1;
        CT const c2 = 2;
        CT const c3 = 3;
        CT const c4 = 4;
        CT const c16 = 16;
        CT const c_e_12 = CT(1e-12);

        CT const pi = geometry::math::pi<CT>();
        CT const two_pi = c2 * pi;

        // lambda: difference in longitude on an auxiliary sphere
        CT L = lon2 - lon1;
        CT lambda = L;

        if (L < -pi) L += two_pi;
        if (L > pi) L -= two_pi;

        CT const radius_a = CT(get_radius<0>(spheroid));
        CT const radius_b = CT(get_radius<2>(spheroid));
        CT const flattening = geometry::detail::flattening<CT>(spheroid);

        // U: reduced latitude, defined by tan U = (1-f) tan phi
        CT const one_min_f = c1 - flattening;
        CT const tan_U1 = one_min_f * tan(lat1); // above (1)
        CT const tan_U2 = one_min_f * tan(lat2); // above (1)

        // calculate sin U and cos U using trigonometric identities
        CT const temp_den_U1 = math::sqrt(c1 + math::sqr(tan_U1));
        CT const temp_den_U2 = math::sqrt(c1 + math::sqr(tan_U2));
        // cos = 1 / sqrt(1 + tan^2)
        CT const cos_U1 = c1 / temp_den_U1;
        CT const cos_U2 = c1 / temp_den_U2;
        // sin = tan / sqrt(1 + tan^2)
        CT const sin_U1 = tan_U1 / temp_den_U1;
        CT const sin_U2 = tan_U2 / temp_den_U2;

        // calculate sin U and cos U directly
        //CT const U1 = atan(tan_U1);
        //CT const U2 = atan(tan_U2);
        //cos_U1 = cos(U1);
        //cos_U2 = cos(U2);
        //sin_U1 = tan_U1 * cos_U1; // sin(U1);
        //sin_U2 = tan_U2 * cos_U2; // sin(U2);

        CT previous_lambda;
        CT sin_lambda;
        CT cos_lambda;
        CT sin_sigma;
        CT sin_alpha;
        CT cos2_alpha;
        CT cos2_sigma_m;
        CT sigma;

        int counter = 0; // robustness

        do
        {
            previous_lambda = lambda; // (13)
            sin_lambda = sin(lambda);
            cos_lambda = cos(lambda);
            sin_sigma = math::sqrt(math::sqr(cos_U2 * sin_lambda) + math::sqr(cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda)); // (14)
            CT cos_sigma = sin_U1 * sin_U2 + cos_U1 * cos_U2 * cos_lambda; // (15)
            sin_alpha = cos_U1 * cos_U2 * sin_lambda / sin_sigma; // (17)
            cos2_alpha = c1 - math::sqr(sin_alpha);
            cos2_sigma_m = math::equals(cos2_alpha, 0) ? 0 : cos_sigma - c2 * sin_U1 * sin_U2 / cos2_alpha; // (18)

            CT C = flattening/c16 * cos2_alpha * (c4 + flattening * (c4 - c3 * cos2_alpha)); // (10)
            sigma = atan2(sin_sigma, cos_sigma); // (16)
            lambda = L + (c1 - C) * flattening * sin_alpha *
                (sigma + C * sin_sigma * ( cos2_sigma_m + C * cos_sigma * (-c1 + c2 * math::sqr(cos2_sigma_m)))); // (11)

            ++counter; // robustness

        } while ( geometry::math::abs(previous_lambda - lambda) > c_e_12
               && geometry::math::abs(lambda) < pi
               && counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness
    
        if ( BOOST_GEOMETRY_CONDITION(EnableDistance) )
        {
            // Oops getting hard here
            // (again, problem is that ttmath cannot divide by doubles, which is OK)
            CT const c1 = 1;
            CT const c2 = 2;
            CT const c3 = 3;
            CT const c4 = 4;
            CT const c6 = 6;
            CT const c47 = 47;
            CT const c74 = 74;
            CT const c128 = 128;
            CT const c256 = 256;
            CT const c175 = 175;
            CT const c320 = 320;
            CT const c768 = 768;
            CT const c1024 = 1024;
            CT const c4096 = 4096;
            CT const c16384 = 16384;

            //CT sqr_u = cos2_alpha * (math::sqr(radius_a) - math::sqr(radius_b)) / math::sqr(radius_b); // above (1)
            CT sqr_u = cos2_alpha * ( math::sqr(radius_a / radius_b) - c1 ); // above (1)

            CT A = c1 + sqr_u/c16384 * (c4096 + sqr_u * (-c768 + sqr_u * (c320 - c175 * sqr_u))); // (3)
            CT B = sqr_u/c1024 * (c256 + sqr_u * ( -c128 + sqr_u * (c74 - c47 * sqr_u))); // (4)
            CT delta_sigma = B * sin_sigma * ( cos2_sigma_m + (B/c4) * (cos(sigma)* (-c1 + c2 * cos2_sigma_m)
                - (B/c6) * cos2_sigma_m * (-c3 + c4 * math::sqr(sin_sigma)) * (-c3 + c4 * cos2_sigma_m))); // (6)

            result.distance = radius_b * A * (sigma - delta_sigma); // (19)
        }
    
        if ( BOOST_GEOMETRY_CONDITION(CalcAzimuths) )
        {
            if (BOOST_GEOMETRY_CONDITION(CalcFwdAzimuth))
            {
                result.azimuth = atan2(cos_U2 * sin_lambda, cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda); // (20)
            }

            if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth))
            {
                result.reverse_azimuth = atan2(cos_U1 * sin_lambda, -sin_U1 * cos_U2 + cos_U1 * sin_U2 * cos_lambda); // (21)
            }
        }

        if (BOOST_GEOMETRY_CONDITION(CalcQuantities))
        {
            typedef differential_quantities<CT, EnableReducedLength, EnableGeodesicScale, 2> quantities;
            quantities::apply(lon1, lat1, lon2, lat2,
                              result.azimuth, result.reverse_azimuth,
                              radius_b, flattening,
                              result.reduced_length, result.geodesic_scale);
        }

        return result;
    }
Exemplo n.º 26
0
void test_multi_linestring_polygon()
{
    typedef bg::model::linestring<P> ls;
    typedef bg::model::multi_linestring<ls> mls;
    typedef bg::model::polygon<P> poly;
    typedef typename bg::coordinate_type<P>::type coord_t;

    test_geometry<mls, poly>("MULTILINESTRING((11 11, 20 20),(5 7, 4 1))",
                             "POLYGON((0 0,0 10,10 10,10 0,0 0),(2 2,4 2,4 4,2 4,2 2))",
                             "1F10F0212");
    test_geometry<mls, poly>("MULTILINESTRING((10 0, 18 12),(2 2,2 1))",
                             "POLYGON((5 0,0 -5,-5 0,0 5,5 0))",
                             "1F10F0212");

    if ( BOOST_GEOMETRY_CONDITION((
            boost::is_same<coord_t, double>::value )) )
    {
        // assertion failure in 1.57
        test_geometry<mls, poly>("MULTILINESTRING((-0.59322033898305082 -8.0508474576271194,-2.882352941176471 -7.7647058823529411,-2.8823529411764706 -7.7647058823529411,-3.7361111111111112 -6.5694444444444446,-3.4404145077720205 -5.766839378238342,-4.1864406779661012 -3.6779661016949152,-7.5252525252525251 -5.5858585858585865,-7.5862068965517242 -5.1896551724137936,-4.47887323943662 -2.859154929577465,-4.5789473684210531 -2.5789473684210527,-3 -1,-2.9310344827586206 -0.86206896551724144,-3.1764705882352944 -0.70588235294117663,-4.7401960784313726 -2.1274509803921577,-5.3255813953488369 -0.48837209302325502,-4.7872340425531918 0.31914893617021284,-5.8571428571428577 1.0000000000000007,-5.3255813953488369 -0.48837209302325502,-5.9473684210526319 -1.4210526315789465,-8 2,-7.7333333333333334 2.1939393939393939,-8.8294573643410867 2.891472868217055,-8.8556701030927822 3.061855670103093,-7.5999999999999996 3.6000000000000001,-7.7999999999999998 3.7999999999999998,-7.75 3.7916666666666665,-7.5471698113207548 3.6226415094339623,-7.3200000000000003 3.7200000000000002,-3.473684210526315 3.0789473684210527,-3.2549019607843133 3.2156862745098036,-2.9999999999999982 3.1428571428571423,-3.1733333333333325 3.2666666666666666,-2.9180327868852456 3.4262295081967209,-2.8723404255319145 3.1063829787234041,-2.1111111111111112 2.8888888888888888,-2.1428571428571428 2.8571428571428572,-1.8433734939759043 2.8072289156626509,-1.8396226415094346 2.8113207547169816,-1.6486486486486487 2.756756756756757,-1.76510067114094 2.8926174496644301,-0.53846153846153855 4.2307692307692308,1.8148148148148147 5.4074074074074074,1.588235294117647 2.2352941176470589,1.819672131147541 2.1967213114754101,2 4,2 2.1666666666666665,2.3538461538461544 2.1076923076923078,2 1.6875000000000004,2 -2,1.2173913043478262 -3.8260869565217392,1.7375886524822697 1.3758865248226959,1.5073170731707317 1.1024390243902444,1.1428571428571428 -4,-0.59322033898305082 -8.0508474576271194),(1.666666666666667 1.5999999999999988,1.5675675675675675 1.8378378378378377,1.4374999999999991 1.8750000000000002,1.0487804878048776 2.3414634146341466,0.46666666666666712 2.6060606060606055,0.086956521739131043 2.2608695652173911,1.4374999999999991 1.8750000000000002,1.666666666666667 1.5999999999999988))",
                                 "POLYGON((-2.333333333333333 -8.6666666666666661,-4.3253012048192767 -8.168674698795181,-4.1194968553459113 -7.6100628930817606,-2.8823529411764706 -7.7647058823529411,-2.882352941176471 -7.7647058823529411,-2.263157894736842 -8.6315789473684212,-2.333333333333333 -8.6666666666666661))",
                                 "*********");
        test_geometry<mls, poly>("MULTILINESTRING((-2.333333333333333 -8.6666666666666661,-4.3253012048192767 -8.168674698795181,-4.1194968553459113 -7.6100628930817606,-2.8823529411764706 -7.7647058823529411,-2.882352941176471 -7.7647058823529411,-2.263157894736842 -8.6315789473684212,-2.333333333333333 -8.6666666666666661))",
                                 "POLYGON((-0.59322033898305082 -8.0508474576271194,-2.882352941176471 -7.7647058823529411,-2.8823529411764706 -7.7647058823529411,-3.7361111111111112 -6.5694444444444446,-3.4404145077720205 -5.766839378238342,-4.1864406779661012 -3.6779661016949152,-7.5252525252525251 -5.5858585858585865,-7.5862068965517242 -5.1896551724137936,-4.47887323943662 -2.859154929577465,-4.5789473684210531 -2.5789473684210527,-3 -1,-2.9310344827586206 -0.86206896551724144,-3.1764705882352944 -0.70588235294117663,-4.7401960784313726 -2.1274509803921577,-5.3255813953488369 -0.48837209302325502,-4.7872340425531918 0.31914893617021284,-5.8571428571428577 1.0000000000000007,-5.3255813953488369 -0.48837209302325502,-5.9473684210526319 -1.4210526315789465,-8 2,-7.7333333333333334 2.1939393939393939,-8.8294573643410867 2.891472868217055,-8.8556701030927822 3.061855670103093,-7.5999999999999996 3.6000000000000001,-7.7999999999999998 3.7999999999999998,-7.75 3.7916666666666665,-7.5471698113207548 3.6226415094339623,-7.3200000000000003 3.7200000000000002,-3.473684210526315 3.0789473684210527,-3.2549019607843133 3.2156862745098036,-2.9999999999999982 3.1428571428571423,-3.1733333333333325 3.2666666666666666,-2.9180327868852456 3.4262295081967209,-2.8723404255319145 3.1063829787234041,-2.1111111111111112 2.8888888888888888,-2.1428571428571428 2.8571428571428572,-1.8433734939759043 2.8072289156626509,-1.8396226415094346 2.8113207547169816,-1.6486486486486487 2.756756756756757,-1.76510067114094 2.8926174496644301,-0.53846153846153855 4.2307692307692308,1.8148148148148147 5.4074074074074074,1.588235294117647 2.2352941176470589,1.819672131147541 2.1967213114754101,2 4,2 2.1666666666666665,2.3538461538461544 2.1076923076923078,2 1.6875000000000004,2 -2,1.2173913043478262 -3.8260869565217392,1.7375886524822697 1.3758865248226959,1.5073170731707317 1.1024390243902444,1.1428571428571428 -4,-0.59322033898305082 -8.0508474576271194),(1.666666666666667 1.5999999999999988,1.5675675675675675 1.8378378378378377,1.4374999999999991 1.8750000000000002,1.0487804878048776 2.3414634146341466,0.46666666666666712 2.6060606060606055,0.086956521739131043 2.2608695652173911,1.4374999999999991 1.8750000000000002,1.666666666666667 1.5999999999999988))",
                                 "*********");
    }

    // 21.01.2015
    test_geometry<mls, poly>("MULTILINESTRING((6 6,15 15),(0 0, 7 7))",
                             "POLYGON((5 5,5 15,15 15,15 5,5 5))",
                             "101000212");
    test_geometry<mls, poly>("MULTILINESTRING((15 15,6 6),(0 0, 7 7))",
                             "POLYGON((5 5,5 15,15 15,15 5,5 5))",
                             "101000212");
    // extended
    test_geometry<mls, poly>("MULTILINESTRING((15 15,6 6),(4 14,6 16))",
                             "POLYGON((5 5,5 15,15 15,15 5,5 5))",
                             "101000212");

    // 23.01.2015
    test_geometry<mls, poly>("MULTILINESTRING((4 10, 3 10, 10 6),(5 0, 7 5, 9 10))",
                             "POLYGON((0 0,0 10,10 10,10 0,5 5,0 0))",
                             "111F00212");

    // 23.01.2015
    test_geometry<mls, poly>("MULTILINESTRING((3 10, 1 5, 1 10, 3 4, 7 8, 6 10, 10 2))",
                             "POLYGON((0 0,0 10,10 10,10 0,0 0))",
                             "10FF0F212");

    // mysql bug
    // assertion failure in relate->boundary_checker->std::equal_range with msvc
    if (BOOST_GEOMETRY_CONDITION(is_nan_case_supported<mls>::value))
    {
        mls g1;
        std::string wkt1;
        nan_case(g1, wkt1);

        std::string wkt2 = "POLYGON((1.1e+308 1.2e+308,-1 -9,1 1e+12,1.1e+308 7.8e+307,1.1e+308 1.2e+308),(3 2,1 1,8e+307 1e+308,3 2),(258 2049,1 -3,1 1,-6 9,258 2049))";
        poly g2;
        bg::read_wkt(wkt2, g2);

        check_geometry(g1, g2, wkt1, wkt2, "*********");
    }
}
void test_linestring_linestring()
{
    typedef bg::model::linestring<P> ls;

    test_geometry<ls, ls>("LINESTRING(0 0, 2 2, 3 2)", "LINESTRING(0 0, 2 2, 3 2)", "1FFF0FFF2");
    test_geometry<ls, ls>("LINESTRING(0 0,3 2)", "LINESTRING(0 0, 2 2, 3 2)", "FF1F0F1F2");
    test_geometry<ls, ls>("LINESTRING(1 0,2 2,2 3)", "LINESTRING(0 0, 2 2, 3 2)", "0F1FF0102");

    test_geometry<ls, ls>("LINESTRING(0 0,5 0)", "LINESTRING(0 0,1 1,2 0,2 -1)", "0F1F00102");
    
    test_geometry<ls, ls>("LINESTRING(0 0, 1 1, 2 2, 3 2)", "LINESTRING(0 0, 2 2, 3 2)", "1FFF0FFF2");
    test_geometry<ls, ls>("LINESTRING(3 2, 2 2, 1 1, 0 0)", "LINESTRING(0 0, 2 2, 3 2)", "1FFF0FFF2");
    test_geometry<ls, ls>("LINESTRING(0 0, 1 1, 2 2, 3 2)", "LINESTRING(3 2, 2 2, 0 0)", "1FFF0FFF2");
    test_geometry<ls, ls>("LINESTRING(3 2, 2 2, 1 1, 0 0)", "LINESTRING(3 2, 2 2, 0 0)", "1FFF0FFF2");

    test_geometry<ls, ls>("LINESTRING(3 1, 2 2, 1 1, 0 0)", "LINESTRING(0 0, 2 2, 3 2)", "1F1F00102");
    test_geometry<ls, ls>("LINESTRING(3 3, 2 2, 1 1, 0 0)", "LINESTRING(0 0, 2 2, 3 2)", "1F1F00102");

    test_geometry<ls, ls>("LINESTRING(0 0, 1 1, 2 2, 2 3)", "LINESTRING(0 0, 2 2, 2 3)", "1FFF0FFF2");
    test_geometry<ls, ls>("LINESTRING(2 3, 2 2, 1 1, 0 0)", "LINESTRING(0 0, 2 2, 2 3)", "1FFF0FFF2");
    test_geometry<ls, ls>("LINESTRING(0 0, 1 1, 2 2, 2 3)", "LINESTRING(2 3, 2 2, 0 0)", "1FFF0FFF2");
    test_geometry<ls, ls>("LINESTRING(2 3, 2 2, 1 1, 0 0)", "LINESTRING(2 3, 2 2, 0 0)", "1FFF0FFF2");

    test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 3 2)", "LINESTRING(0 0, 2 2, 4 2)", "1FF0FF102");

    test_geometry<ls, ls>("LINESTRING(3 2, 2 2, 1 1)", "LINESTRING(0 0, 2 2, 4 2)", "1FF0FF102");
    test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 3 2)", "LINESTRING(4 2, 2 2, 0 0)", "1FF0FF102");
    test_geometry<ls, ls>("LINESTRING(3 2, 2 2, 1 1)", "LINESTRING(4 2, 2 2, 0 0)", "1FF0FF102");

//    test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 2 2)", "LINESTRING(0 0, 2 2, 4 2)", true);

//    test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 3 3)", "LINESTRING(0 0, 2 2, 4 2)", false);
//    test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 3 2, 3 3)", "LINESTRING(0 0, 2 2, 4 2)", false);
//    test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 3 1)", "LINESTRING(0 0, 2 2, 4 2)", false);
//    test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 3 2, 3 1)", "LINESTRING(0 0, 2 2, 4 2)", false);

//    test_geometry<ls, ls>("LINESTRING(0 1, 1 1, 2 2, 3 2)", "LINESTRING(0 0, 2 2, 4 2)", false);
//    test_geometry<ls, ls>("LINESTRING(0 1, 0 0, 2 2, 3 2)", "LINESTRING(0 0, 2 2, 4 2)", false);
//    test_geometry<ls, ls>("LINESTRING(1 0, 1 1, 2 2, 3 2)", "LINESTRING(0 0, 2 2, 4 2)", false);
//    test_geometry<ls, ls>("LINESTRING(1 0, 0 0, 2 2, 3 2)", "LINESTRING(0 0, 2 2, 4 2)", false);

//    test_geometry<ls, ls>("LINESTRING(0 0)", "LINESTRING(0 0)", false);
//    test_geometry<ls, ls>("LINESTRING(1 1)", "LINESTRING(0 0, 2 2)", true);
//    test_geometry<ls, ls>("LINESTRING(0 0)", "LINESTRING(0 0, 2 2)", false);
//    test_geometry<ls, ls>("LINESTRING(0 0, 1 1)", "LINESTRING(0 0)", false);

//    test_geometry<ls, ls>("LINESTRING(0 0,5 0,3 0,6 0)", "LINESTRING(0 0,6 0)", true);
//    test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,1 1)", "LINESTRING(0 0,3 3,6 3)", true);

    // SPIKES!
    test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,1 1,5 3)", "LINESTRING(0 0,3 3,6 3)", "1F100F102");
    test_geometry<ls, ls>("LINESTRING(5 3,1 1,3 3,2 2,0 0)", "LINESTRING(0 0,3 3,6 3)", "1F100F102");
    test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,1 1,5 3)", "LINESTRING(6 3,3 3,0 0)", "1F100F102");
    test_geometry<ls, ls>("LINESTRING(5 3,1 1,3 3,2 2,0 0)", "LINESTRING(6 3,3 3,0 0)", "1F100F102");

    test_geometry<ls, ls>("LINESTRING(6 3,3 3,0 0)", "LINESTRING(0 0,2 2,3 3,1 1,5 3)", "101F001F2");

    test_geometry<ls, ls>("LINESTRING(0 0,10 0)", "LINESTRING(1 0,9 0,2 0)", "101FF0FF2");
    test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,1 1)", "LINESTRING(0 0,3 3,6 3)", "1FF00F102");
    // TODO: REWRITE MATRICES
    // BEGIN
    /*test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,1 1)", "LINESTRING(0 0,4 4,6 3)", "1FF00F102");

    test_geometry<ls, ls>("LINESTRING(0 0,2 0,1 0)", "LINESTRING(0 1,0 0,2 0)", "1FF00F102");
    test_geometry<ls, ls>("LINESTRING(2 0,0 0,1 0)", "LINESTRING(0 1,0 0,2 0)", "1FF00F102");

    test_geometry<ls, ls>("LINESTRING(0 0,3 3,1 1)", "LINESTRING(3 0,3 3,3 1)", "0F1FF0102");
    test_geometry<ls, ls>("LINESTRING(0 0,3 3,1 1)", "LINESTRING(2 0,2 3,2 1)", "0F1FF0102");
    test_geometry<ls, ls>("LINESTRING(0 0,3 3,1 1)", "LINESTRING(2 0,2 2,2 1)", "0F1FF0102");
 
     test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,4 4)", "LINESTRING(0 0,1 1,4 4)", "1FFF0FFF2");*/
    // END

    test_geometry<ls, ls>("LINESTRING(0 0,2 2,3 3,4 4)", "LINESTRING(0 0,1 1,4 4)", "1FFF0FFF2");

    // loop i/i i/i u/u u/u
    test_geometry<ls, ls>("LINESTRING(0 0,10 0)",
                          "LINESTRING(1 1,1 0,6 0,6 1,4 1,4 0,9 0,9 1)", "1F1FF0102");

    // self-intersecting and self-touching equal
    test_geometry<ls, ls>("LINESTRING(0 5,5 5,10 5,10 10,5 10,5 5,5 0)",
                          "LINESTRING(0 5,5 5,5 10,10 10,10 5,5 5,5 0)", "1FFF0FFF2");
    // self-intersecting loop and self-touching equal
    test_geometry<ls, ls>("LINESTRING(0 5,5 5,10 5,10 10,5 10,5 5,10 5,10 10,5 10,5 5,5 0)",
                          "LINESTRING(0 5,5 5,5 10,10 10,10 5,5 5,5 0)", "1FFF0FFF2");

    test_geometry<ls, ls>("LINESTRING(0 0,1 1)", "LINESTRING(0 1,1 0)", "0F1FF0102");
    test_geometry<ls, ls>("LINESTRING(0 0,1 1)", "LINESTRING(1 1,2 0)", "FF1F00102");
    test_geometry<ls, ls>("LINESTRING(0 0,1 1)", "LINESTRING(2 0,1 1)", "FF1F00102");

    test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 1,3 5,4 0)", "LINESTRING(1 0,2 1,3 5)", "101FF0FF2");
    test_geometry<ls, ls>("LINESTRING(0 0,1 0,2 1,3 5,4 0)", "LINESTRING(3 5,2 1,1 0)", "101FF0FF2");
    test_geometry<ls, ls>("LINESTRING(1 0,2 1,3 5)", "LINESTRING(4 0,3 5,2 1,1 0,0 0)", "1FF0FF102");
    test_geometry<ls, ls>("LINESTRING(3 5,2 1,1 0)", "LINESTRING(4 0,3 5,2 1,1 0,0 0)", "1FF0FF102");
    
    test_geometry<ls, ls>("LINESTRING(0 0,10 0)", "LINESTRING(-1 -1,1 0,10 0,20 -1)", "1F10F0102");
    test_geometry<ls, ls>("LINESTRING(0 0,10 0)", "LINESTRING(20 -1,10 0,1 0,-1 -1)", "1F10F0102");

    test_geometry<ls, ls>("LINESTRING(-1 1,0 0,1 0,5 0,5 5,10 5,15 0,31 0)",
                          "LINESTRING(-1 -1,0 0,1 0,2 0,3 1,4 0,30 0)",
                          "101FF0102");
    test_geometry<ls, ls>("LINESTRING(-1 1,0 0,1 0,5 0,5 5,10 5,15 0,31 0)",
                          "LINESTRING(30 0,4 0,3 1,2 0,1 0,0 0,-1 -1)",
                          "101FF0102");
    test_geometry<ls, ls>("LINESTRING(31 0,15 0,10 5,5 5,5 0,1 0,0 0,-1 1)",
                          "LINESTRING(-1 -1,0 0,1 0,2 0,3 1,4 0,30 0)",
                          "101FF0102");
    test_geometry<ls, ls>("LINESTRING(31 0,15 0,10 5,5 5,5 0,1 0,0 0,-1 1)",
                          "LINESTRING(30 0,4 0,3 1,2 0,1 0,0 0,-1 -1)",
                          "101FF0102");

    // self-IP
    test_geometry<ls, ls>("LINESTRING(1 0,9 0)",
                          "LINESTRING(0 0,10 0,10 10,5 0,0 10)",
                          "1FF0FF102");
    test_geometry<ls, ls>("LINESTRING(1 0,5 0,9 0)",
                          "LINESTRING(0 0,10 0,10 10,5 0,0 10)",
                          "1FF0FF102");
    test_geometry<ls, ls>("LINESTRING(1 0,9 0)",
                          "LINESTRING(0 0,10 0,10 10,5 10,5 -1)",
                          "1FF0FF102");
    test_geometry<ls, ls>("LINESTRING(1 0,9 0)",
                          "LINESTRING(0 0,10 0,5 0,5 5)",
                          "1FF0FF102");
    test_geometry<ls, ls>("LINESTRING(1 0,7 0)", "LINESTRING(0 0,10 0,10 10,4 -1)",
                          "1FF0FF102");
    test_geometry<ls, ls>("LINESTRING(1 0,5 0,7 0)", "LINESTRING(0 0,10 0,10 10,4 -1)",
                          "1FF0FF102");
    test_geometry<ls, ls>("LINESTRING(1 0,7 0,8 1)", "LINESTRING(0 0,10 0,10 10,4 -1)",
                          "1F10F0102");
    test_geometry<ls, ls>("LINESTRING(1 0,5 0,7 0,8 1)", "LINESTRING(0 0,10 0,10 10,4 -1)",
                          "1F10F0102");

    // self-IP going out and in on the same point
    test_geometry<ls, ls>("LINESTRING(2 0,5 0,5 5,6 5,5 0,8 0)", "LINESTRING(1 0,9 0)",
                          "1F10FF102");

    // duplicated points
    test_geometry<ls, ls>("LINESTRING(1 1, 2 2, 2 2)", "LINESTRING(0 0, 2 2, 4 2)", "1FF0FF102");
    test_geometry<ls, ls>("LINESTRING(1 1, 1 1, 2 2)", "LINESTRING(0 0, 2 2, 4 2)", "1FF0FF102");

    // linear ring
    test_geometry<ls, ls>("LINESTRING(0 0,10 0)", "LINESTRING(5 0,9 0,5 5,1 0,5 0)", "1F1FF01F2");
    test_geometry<ls, ls>("LINESTRING(0 0,5 0,10 0)", "LINESTRING(5 0,9 0,5 5,1 0,5 0)", "1F1FF01F2");
    test_geometry<ls, ls>("LINESTRING(0 0,5 0,10 0)", "LINESTRING(5 0,10 0,5 5,1 0,5 0)", "1F10F01F2");

    test_geometry<ls, ls>("LINESTRING(0 0,5 0)", "LINESTRING(5 0,10 0,5 5,0 0,5 0)", "1FF0FF1F2");
    test_geometry<ls, ls>("LINESTRING(0 0,5 0)", "LINESTRING(5 0,10 0,5 5,5 0)", "FF10F01F2");

    test_geometry<ls, ls>("LINESTRING(1 0,1 6)", "LINESTRING(0 0,5 0,5 5,0 5)", "0F10F0102");

    // point-size Linestring
    test_geometry<ls, ls>("LINESTRING(1 0,1 0)", "LINESTRING(0 0,5 0)", "0FFFFF102");
    test_geometry<ls, ls>("LINESTRING(1 0,1 0)", "LINESTRING(1 0,5 0)", "F0FFFF102");
    test_geometry<ls, ls>("LINESTRING(1 0,1 0)", "LINESTRING(0 0,1 0)", "F0FFFF102");
    test_geometry<ls, ls>("LINESTRING(1 0,1 0)", "LINESTRING(1 0,1 0)", "0FFFFFFF2");
    test_geometry<ls, ls>("LINESTRING(1 0,1 0)", "LINESTRING(0 0,0 0)", "FF0FFF0F2");

    //to_svg<ls, ls>("LINESTRING(0 0,5 0)", "LINESTRING(5 0,10 0,5 5,5 0)", "test_relate_00.svg");

    // INVALID LINESTRINGS
    // 1-point LS (a Point) NOT disjoint
    //test_geometry<ls, ls>("LINESTRING(1 0)", "LINESTRING(0 0,5 0)", "0FFFFF102");
    //test_geometry<ls, ls>("LINESTRING(0 0,5 0)", "LINESTRING(1 0)", "0F1FF0FF2");
    //test_geometry<ls, ls>("LINESTRING(0 0,5 0)", "LINESTRING(1 0,1 0,1 0)", "0F1FF0FF2");
    // Point/Point
    //test_geometry<ls, ls>("LINESTRING(0 0)", "LINESTRING(0 0)", "0FFFFFFF2");

    if ( BOOST_GEOMETRY_CONDITION(
            boost::is_floating_point<typename bg::coordinate_type<ls>::type>::value ) )
    {
        // https://svn.boost.org/trac/boost/ticket/10904
        // very small segments
        test_geometry<ls, ls>("LINESTRING(5.6956521739130430148634331999347 -0.60869565217391330413931882503675,5.5 -0.50000000000000066613381477509392)",
                              "LINESTRING(5.5 -0.50000000000000066613381477509392,5.5 -0.5)",
                              "FF1F00102");
        test_geometry<ls, ls>("LINESTRING(-3.2333333333333333925452279800083 5.5999999999999978683717927196994,-3.2333333333333333925452279800083 5.5999999999999996447286321199499)",
                              "LINESTRING(-3.2333333333333325043668082798831 5.5999999999999996447286321199499,-3.2333333333333333925452279800083 5.5999999999999996447286321199499)",
                              "FF1F00102", "F0FFFF102"); // on some platforms the first Linestring may be detected as degenerated to Point

        // detected as collinear
        test_geometry<ls, ls>("LINESTRING(1 -10, 3.069359e+307 3.069359e+307)",
                              "LINESTRING(1 6, 1 0)",
                              "*********"); // TODO: be more specific with the result
    }

    // OTHER MASKS
    {
        namespace bgdr = bg::detail::relate;
        ls ls1, ls2, ls3, ls4;
        bg::read_wkt("LINESTRING(0 0,2 0)", ls1);
        bg::read_wkt("LINESTRING(2 0,4 0)", ls2);
        bg::read_wkt("LINESTRING(1 0,1 1)", ls3);
        bg::read_wkt("LINESTRING(1 0,4 0)", ls4);
        BOOST_CHECK(bgdr::relate(ls1, ls2, bgdr::mask9("FT*******")
                                        || bgdr::mask9("F**T*****")
                                        || bgdr::mask9("F***T****")));
        BOOST_CHECK(bgdr::relate(ls1, ls3, bgdr::mask9("FT*******")
                                        || bgdr::mask9("F**T*****")
                                        || bgdr::mask9("F***T****")));
        BOOST_CHECK(bgdr::relate(ls3, ls1, bgdr::mask9("FT*******")
                                        || bgdr::mask9("F**T*****")
                                        || bgdr::mask9("F***T****")));
        BOOST_CHECK(bgdr::relate(ls2, ls4, bgdr::mask9("T*F**F***"))); // within
    }

    // spike - boundary and interior on the same point
    test_geometry<ls, ls>("LINESTRING(3 7, 8 8, 2 6)", "LINESTRING(5 7, 10 7, 0 7)", "0010F0102");

    // 22.01.2015
    test_geometry<ls, ls>("LINESTRING(5 5,10 10)", "LINESTRING(6 6,3 3)", "1010F0102");
    test_geometry<ls, ls>("LINESTRING(5 5,2 8)", "LINESTRING(4 6,7 3)", "1010F0102");
}
Exemplo n.º 28
0
    static inline result_type apply(T const& lo1,
                                    T const& la1,
                                    Dist const& distance,
                                    Azi const& azimuth12,
                                    Spheroid const& spheroid)
    {
        result_type result;

        CT const lon1 = lo1;
        CT const lat1 = la1;

        if ( math::equals(distance, Dist(0)) || distance < Dist(0) )
        {
            result.lon2 = lon1;
            result.lat2 = lat1;
            return result;
        }

        CT const radius_a = CT(get_radius<0>(spheroid));
        CT const radius_b = CT(get_radius<2>(spheroid));
        CT const flattening = formula::flattening<CT>(spheroid);

        CT const sin_azimuth12 = sin(azimuth12);
        CT const cos_azimuth12 = cos(azimuth12);

        // U: reduced latitude, defined by tan U = (1-f) tan phi
        CT const one_min_f = CT(1) - flattening;
        CT const tan_U1 = one_min_f * tan(lat1);
        CT const sigma1 = atan2(tan_U1, cos_azimuth12); // (1)

        // may be calculated from tan using 1 sqrt()
        CT const U1 = atan(tan_U1);
        CT const sin_U1 = sin(U1);
        CT const cos_U1 = cos(U1);

        CT const sin_alpha = cos_U1 * sin_azimuth12; // (2)
        CT const sin_alpha_sqr = math::sqr(sin_alpha);
        CT const cos_alpha_sqr = CT(1) - sin_alpha_sqr;

        CT const b_sqr = radius_b * radius_b;
        CT const u_sqr = cos_alpha_sqr * (radius_a * radius_a - b_sqr) / b_sqr;
        CT const A = CT(1) + (u_sqr/CT(16384)) * (CT(4096) + u_sqr*(CT(-768) + u_sqr*(CT(320) - u_sqr*CT(175)))); // (3)
        CT const B = (u_sqr/CT(1024))*(CT(256) + u_sqr*(CT(-128) + u_sqr*(CT(74) - u_sqr*CT(47)))); // (4)

        CT s_div_bA = distance / (radius_b * A);
        CT sigma = s_div_bA; // (7)

        CT previous_sigma;
        CT sin_sigma;
        CT cos_sigma;
        CT cos_2sigma_m;
        CT cos_2sigma_m_sqr;

        int counter = 0; // robustness

        do
        {
            previous_sigma = sigma;

            CT const two_sigma_m = CT(2) * sigma1 + sigma; // (5)

            sin_sigma = sin(sigma);
            cos_sigma = cos(sigma);
            CT const sin_sigma_sqr = math::sqr(sin_sigma);
            cos_2sigma_m = cos(two_sigma_m);
            cos_2sigma_m_sqr = math::sqr(cos_2sigma_m);

            CT const delta_sigma = B * sin_sigma * (cos_2sigma_m
                                        + (B/CT(4)) * ( cos_sigma * (CT(-1) + CT(2)*cos_2sigma_m_sqr)
                                            - (B/CT(6) * cos_2sigma_m * (CT(-3)+CT(4)*sin_sigma_sqr) * (CT(-3)+CT(4)*cos_2sigma_m_sqr)) )); // (6)

            sigma = s_div_bA + delta_sigma; // (7)

            ++counter; // robustness

        } while ( geometry::math::abs(previous_sigma - sigma) > CT(1e-12)
               //&& geometry::math::abs(sigma) < pi
               && counter < BOOST_GEOMETRY_DETAIL_VINCENTY_MAX_STEPS ); // robustness

        if (BOOST_GEOMETRY_CONDITION(CalcCoordinates))
        {
            result.lat2
                = atan2( sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_azimuth12,
                         one_min_f * math::sqrt(sin_alpha_sqr + math::sqr(sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_azimuth12))); // (8)

            CT const lambda = atan2( sin_sigma * sin_azimuth12,
                                     cos_U1 * cos_sigma - sin_U1 * sin_sigma * cos_azimuth12); // (9)
            CT const C = (flattening/CT(16)) * cos_alpha_sqr * ( CT(4) + flattening * ( CT(4) - CT(3) * cos_alpha_sqr ) ); // (10)
            CT const L = lambda - (CT(1) - C) * flattening * sin_alpha
                            * ( sigma + C * sin_sigma * ( cos_2sigma_m + C * cos_sigma * ( CT(-1) + CT(2) * cos_2sigma_m_sqr ) ) ); // (11)

            result.lon2 = lon1 + L;
        }

        if (BOOST_GEOMETRY_CONDITION(CalcRevAzimuth))
        {
            result.reverse_azimuth
                = atan2(sin_alpha, -sin_U1 * sin_sigma + cos_U1 * cos_sigma * cos_azimuth12); // (12)
        }

        if (BOOST_GEOMETRY_CONDITION(CalcQuantities))
        {
            typedef differential_quantities<CT, EnableReducedLength, EnableGeodesicScale, 2> quantities;
            quantities::apply(lon1, lat1, result.lon2, result.lat2,
                              azimuth12, result.reverse_azimuth,
                              radius_b, flattening,
                              result.reduced_length, result.geodesic_scale);
        }

        return result;
    }
Exemplo n.º 29
0
void test_2d()
{
    test_centroid<bg::model::linestring<P> >("LINESTRING(1 1, 2 2, 3 3)", 2.0, 2.0);
    test_centroid<bg::model::linestring<P> >("LINESTRING(0 0,0 4, 4 4)", 1.0, 3.0);
    test_centroid<bg::model::linestring<P> >("LINESTRING(0 0,3 3,0 6,3 9,0 12)", 1.5, 6.0);

    test_centroid<bg::model::linestring<P> >("LINESTRING(1 1,10 1,1 0,10 0,4 -2,1 1)",
                                             5.41385255923004, 0.13507358481085);

    // degenerated linestring (length = 0)
    test_centroid<bg::model::linestring<P> >("LINESTRING(1 1, 1 1)", 1.0, 1.0);
    test_centroid<bg::model::linestring<P> >("LINESTRING(1 1)", 1.0, 1.0);

    {
        bg::model::linestring<P> ls;
        // LINESTRING(1 -1,1e308 -1e308,0.0001 0.000)
        bg::append(ls, P(1, -1));
        typedef typename bg::coordinate_type<P>::type coord_type;
        //double m = 1.0e308;
        coord_type m = (std::numeric_limits<coord_type>::max)();
        bg::append(ls, P(coord_type(m), coord_type(-m)));
        bg::append(ls, P(coord_type(0.0001), coord_type(0.000)));
        if (BOOST_GEOMETRY_CONDITION((boost::is_same<typename bg::coordinate_type<P>::type, double>::value)))
        {
            // for doubles the INF is detected and the calculation stopped
            // currently for Geometries for which the centroid can't be calculated
            // the first Point is returned
            test_centroid<bg::model::linestring<P> >(ls, 1.0, -1.0);
        }
        else
        {
            // for floats internally the double is used to store intermediate results
            // this type is capable to store MAX_FLT and "correctly" calculate the centroid
            // test_centroid<bg::model::linestring<P> >(ls, m/3, -m/3);
            // the result is around (1.7e38 -1.7e38)
        }
    }

    test_centroid<bg::model::segment<P> >("LINESTRING(1 1, 3 3)", 2.0, 2.0);

    test_centroid<bg::model::ring<P> >(
        "POLYGON((2 1.3,2.4 1.7,2.8 1.8,3.4 1.2"
        ",3.7 1.6,3.4 2,4.1 3,5.3 2.6,5.4 1.2,4.9 0.8,2.9 0.7,2 1.3))",
        4.06923363095238, 1.65055803571429);

    test_polygon<bg::model::polygon<P> >();
    test_polygon<all_custom_polygon<P> >();

    // ccw
    test_centroid<bg::model::ring<P, false> >(
        "POLYGON((2 1.3,2.9 0.7,4.9 0.8,5.4 1.2,5.3 2.6,4.1 3,3.4 2"
            ",3.7 1.6,3.4 1.2,2.8 1.8,2.4 1.7,2 1.3))",
        4.06923363095238, 1.65055803571429);

    // open / closed
    test_centroid<bg::model::ring<P, true, true> >(
            "POLYGON((1 1,2 2,3 1,2 0,1 1))", 2.0, 1.0);
    test_centroid<bg::model::ring<P, true, false> >(
            "POLYGON((1 1,2 2,3 1,2 0))", 2.0, 1.0);

    test_centroid<bg::model::box<P> >("POLYGON((1 2,3 4))", 2, 3);
    test_centroid<P>("POINT(3 3)", 3, 3);

    // INT -> FP
    test_centroid
        <
            bg::model::ring<bg::model::d2::point_xy<int> >,
            P, typename bg::coordinate_type<P>::type
        >("POLYGON((1 1, 1 2, 2 2, 2 1, 1 1))", 1.5, 1.5);
    test_centroid
        <
            bg::model::linestring<bg::model::d2::point_xy<int> >,
            P, typename bg::coordinate_type<P>::type
        >("LINESTRING(1 1, 2 2)", 1.5, 1.5);
    test_centroid
        <
            bg::model::box<bg::model::d2::point_xy<int> >,
            P, typename bg::coordinate_type<P>::type
        >("BOX(1 1, 2 2)", 1.5, 1.5);
}
Exemplo n.º 30
0
    static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result)
    {
// TODO: If Areal geometry may have infinite size, change the following line:

        // The result should be FFFFFFFFF
        relate::set<exterior, exterior, result_dimension<Geometry2>::value>(result);// FFFFFFFFd, d in [1,9] or T

        if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
            return;

        // get and analyse turns
        typedef typename turns::get_turns<Geometry1, Geometry2>::turn_info turn_type;
        std::vector<turn_type> turns;

        interrupt_policy_areal_areal<Result> interrupt_policy(geometry1, geometry2, result);

        turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy);
        if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
            return;

        no_turns_aa_pred<Geometry2, Result, false> pred1(geometry2, result);
        for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
        if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
            return;

        no_turns_aa_pred<Geometry1, Result, true> pred2(geometry1, result);
        for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
        if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
            return;
        
        if ( turns.empty() )
            return;

        if ( may_update<interior, interior, '2'>(result)
          || may_update<interior, exterior, '2'>(result)
          || may_update<boundary, interior, '1'>(result)
          || may_update<boundary, exterior, '1'>(result)
          || may_update<exterior, interior, '2'>(result) )
        {
            // sort turns
            typedef turns::less<0, turns::less_op_areal_areal<0> > less;
            std::sort(turns.begin(), turns.end(), less());

            /*if ( may_update<interior, exterior, '2'>(result)
              || may_update<boundary, exterior, '1'>(result)
              || may_update<boundary, interior, '1'>(result)
              || may_update<exterior, interior, '2'>(result) )*/
            {
                // analyse sorted turns
                turns_analyser<turn_type, 0> analyser;
                analyse_each_turn(result, analyser, turns.begin(), turns.end());

                if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
                    return;
            }

            if ( may_update<interior, interior, '2'>(result)
              || may_update<interior, exterior, '2'>(result)
              || may_update<boundary, interior, '1'>(result)
              || may_update<boundary, exterior, '1'>(result)
              || may_update<exterior, interior, '2'>(result) )
            {
                // analyse rings for which turns were not generated
                // or only i/i or u/u was generated
                uncertain_rings_analyser<0, Result, Geometry1, Geometry2> rings_analyser(result, geometry1, geometry2);
                analyse_uncertain_rings<0>::apply(rings_analyser, turns.begin(), turns.end());

                if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
                    return;
            }
        }

        if ( may_update<interior, interior, '2', true>(result)
          || may_update<interior, exterior, '2', true>(result)
          || may_update<boundary, interior, '1', true>(result)
          || may_update<boundary, exterior, '1', true>(result)
          || may_update<exterior, interior, '2', true>(result) )
        {
            // sort turns
            typedef turns::less<1, turns::less_op_areal_areal<1> > less;
            std::sort(turns.begin(), turns.end(), less());

            /*if ( may_update<interior, exterior, '2', true>(result)
              || may_update<boundary, exterior, '1', true>(result)
              || may_update<boundary, interior, '1', true>(result)
              || may_update<exterior, interior, '2', true>(result) )*/
            {
                // analyse sorted turns
                turns_analyser<turn_type, 1> analyser;
                analyse_each_turn(result, analyser, turns.begin(), turns.end());

                if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
                    return;
            }

            if ( may_update<interior, interior, '2', true>(result)
              || may_update<interior, exterior, '2', true>(result)
              || may_update<boundary, interior, '1', true>(result)
              || may_update<boundary, exterior, '1', true>(result)
              || may_update<exterior, interior, '2', true>(result) )
            {
                // analyse rings for which turns were not generated
                // or only i/i or u/u was generated
                uncertain_rings_analyser<1, Result, Geometry2, Geometry1> rings_analyser(result, geometry2, geometry1);
                analyse_uncertain_rings<1>::apply(rings_analyser, turns.begin(), turns.end());

                //if ( result.interrupt )
                //    return;
            }
        }
    }