[distance] [test] Geo box-box distance tests

This commit is contained in:
Vissarion Fysikopoulos 2017-07-25 13:51:37 +03:00
parent 1728b7a706
commit 0c8e12d1bb
4 changed files with 498 additions and 15 deletions

View File

@ -244,7 +244,7 @@ struct get_comparable<cross_track_geo<FormulaPolicy, Spheroid, CalculationType>
>::type comparable_type;
public :
static inline comparable_type
apply(cross_track_geo<FormulaPolicy, Spheroid, CalculationType> const& strategy)
apply(cross_track_geo<FormulaPolicy, Spheroid, CalculationType> const&)
{
return comparable_type();
}

View File

@ -55,13 +55,16 @@ to cross track
*/
template
<
typename Strategy = cross_track_geo<>,
typename FormulaPolicy = strategy::andoyer,
//typename Strategy = cross_track_geo<>,
typename Spheroid = srs::spheroid<double>,
typename CalculationType = void
>
class cross_track_box_box_geo
{
public:
typedef cross_track_geo<FormulaPolicy, Spheroid, CalculationType> Strategy;
template <typename Box1, typename Box2>
struct return_type
: services::return_type<Strategy, typename point_type<Box1>::type, typename point_type<Box2>::type>
@ -105,28 +108,28 @@ struct tag<cross_track_box_box_geo<Strategy, Spheroid, CalculationType> >
};
template <typename Strategy, typename Spheroid, typename CalculationType, typename P, typename Box>
struct return_type<cross_track_box_box_geo<Strategy, Spheroid, CalculationType>, P, Box>
template <typename Strategy, typename Spheroid, typename CalculationType, typename Box1, typename Box2>
struct return_type<cross_track_box_box_geo<Strategy, Spheroid, CalculationType>, Box1, Box2>
: cross_track_box_box_geo
<
Strategy, Spheroid, CalculationType
>::template return_type<P, Box>
>::template return_type<Box1, Box2>
{};
template <typename Strategy, typename Spheroid, typename P, typename Box>
struct return_type<cross_track_box_box_geo<Strategy, Spheroid>, P, Box>
template <typename Strategy, typename Spheroid, typename Box1, typename Box2>
struct return_type<cross_track_box_box_geo<Strategy, Spheroid>, Box1, Box2>
: cross_track_box_box_geo
<
Strategy, Spheroid
>::template return_type<P, Box>
>::template return_type<Box1, Box2>
{};
template <typename Strategy, typename P, typename Box>
struct return_type<cross_track_box_box_geo<Strategy>, P, Box>
template <typename Strategy, typename Box1, typename Box2>
struct return_type<cross_track_box_box_geo<Strategy>, Box1, Box2>
: cross_track_box_box_geo
<
Strategy
>::template return_type<P, Box>
>::template return_type<Box1, Box2>
{};
template <typename Strategy, typename Spheroid, typename CalculationType>
@ -181,7 +184,7 @@ public:
}
};
/*
// define cross_track_box_box<default_point_segment_strategy> as
// default box-box strategy for the geographic coordinate system
template <typename Box1, typename Box2, typename Strategy>
@ -207,6 +210,17 @@ struct default_strategy
>::type
> type;
};
*/
template <typename Box1, typename Box2>
struct default_strategy
<
box_tag, box_tag, Box1, Box2,
geographic_tag, geographic_tag
>
{
typedef cross_track_box_box_geo<> type;
};
} // namespace services

View File

@ -4,9 +4,10 @@
# Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
# Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
#
# This file was modified by Oracle on 2014, 2015.
# Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
# This file was modified by Oracle on 2014-2017.
# Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
#
# Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
# Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
# Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#
@ -18,6 +19,7 @@ test-suite boost-geometry-algorithms-distance
:
[ run distance.cpp : : : : algorithms_distance ]
[ run distance_areal_areal.cpp : : : : algorithms_distance_areal_areal ]
[ run distance_geo_pl_l.cpp : : : : algorithms_distance_geo_box_box ]
[ run distance_geo_pl_l.cpp : : : : algorithms_distance_geo_pl_l ]
[ run distance_geo_pl_l.cpp : : : : algorithms_distance_geo_point_box ]
[ run distance_linear_areal.cpp : : : : algorithms_distance_linear_areal ]
@ -25,8 +27,8 @@ test-suite boost-geometry-algorithms-distance
[ run distance_pointlike_areal.cpp : : : : algorithms_distance_pointlike_areal ]
[ run distance_pointlike_linear.cpp : : : : algorithms_distance_pointlike_linear ]
[ run distance_pointlike_pointlike.cpp : : : : algorithms_distance_pointlike_pointlike ]
[ run distance_se_box_box.cpp : : : : algorithms_distance_se_box_box ]
[ run distance_se_pl_l.cpp : : : : algorithms_distance_se_pl_l ]
[ run distance_se_pl_pl.cpp : : : : algorithms_distance_se_pl_pl ]
[ run distance_se_box_box.cpp : : : : algorithms_distance_se_box_box ]
[ run distance_se_point_box.cpp : : : : algorithms_distance_se_point_box ]
;

View File

@ -1 +1,468 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test
// Copyright (c) 2017, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#include <iostream>
#ifndef BOOST_TEST_MODULE
#define BOOST_TEST_MODULE test_distance_geographic_box_box
#endif
#include <boost/range.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/test/included/unit_test.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/strategies/strategies.hpp>
#include "test_distance_geo_common.hpp"
typedef bg::cs::geographic<bg::degree> cs_type;
typedef bg::model::point<double, 2, cs_type> point_type;
typedef bg::model::segment<point_type> segment_type;
typedef bg::model::box<point_type> box_type;
namespace services = bg::strategy::distance::services;
typedef bg::default_distance_result<point_type>::type return_type;
typedef bg::srs::spheroid<double> stype;
// Strategies for point-point distance
typedef bg::strategy::distance::andoyer<stype> andoyer_pp;
typedef bg::strategy::distance::thomas<stype> thomas_pp;
typedef bg::strategy::distance::vincenty<stype> vincenty_pp;
// Strategies for point-segment distance
typedef bg::strategy::distance::cross_track_geo<bg::strategy::andoyer, stype, double>
andoyer_ps;
typedef bg::strategy::distance::cross_track_geo<bg::strategy::thomas, stype, double>
thomas_ps;
typedef bg::strategy::distance::cross_track_geo<bg::strategy::vincenty, stype, double>
vincenty_ps;
// Strategies for point-box distance
typedef bg::strategy::distance::cross_track_box_box_geo
<
bg::strategy::andoyer,
bg::srs::spheroid<double>,
double
> andoyer_bb;
typedef bg::strategy::distance::cross_track_box_box_geo
<
bg::strategy::thomas,
bg::srs::spheroid<double>,
double
> thomas_bb;
typedef bg::strategy::distance::cross_track_box_box_geo
<
bg::strategy::vincenty,
bg::srs::spheroid<double>,
double
> vincenty_bb;
//===========================================================================
template <typename Strategy>
inline bg::default_distance_result<point_type>::type
pp_distance(std::string const& wkt1,
std::string const& wkt2,
Strategy const& strategy)
{
point_type p1, p2;
bg::read_wkt(wkt1, p1);
bg::read_wkt(wkt2, p2);
return bg::distance(p1, p2, strategy);
}
template <typename Strategy>
inline bg::default_distance_result<point_type>::type
ps_distance(std::string const& wkt1,
std::string const& wkt2,
Strategy const& strategy)
{
point_type p;
segment_type s;
bg::read_wkt(wkt1, p);
bg::read_wkt(wkt2, s);
return bg::distance(p, s, strategy);
}
//===========================================================================
// Cases for relative location of box2 wrt to box1
//
// | |
// 11 | 7 | 4
// | |
// --10---+---------+---3---
// | |
// 9 | 6 | 2
// | |
// -------+---------+-------
// | |
// 8 | 5 | 1
// | |
//
// case 6 includes all possible intersections
// The picture assumes northern hemisphere location
// southern hemisphere picture is mirrored wrt the equator
template <typename Strategy_pp, typename Strategy_ps, typename Strategy_bb>
void test_distance_box_box(Strategy_pp const& strategy_pp,
Strategy_ps const& strategy_ps,
Strategy_bb const& strategy_bb)
{
#ifdef BOOST_GEOMETRY_TEST_DEBUG
std::cout << std::endl;
std::cout << "box/box distance tests" << std::endl;
#endif
typedef test_distance_of_geometries<box_type, box_type> tester;
std::string const box1 = "BOX(10 10,20 20)";
// case 1
tester::apply("bb1", box1, "BOX(30 0,40 5)",
pp_distance("POINT(20 10)", "POINT(30 5)", strategy_pp),
strategy_bb);
// case 2
tester::apply("bb2-a", box1, "BOX(30 12, 40 17)",
ps_distance("POINT(30 17)", "SEGMENT(20 10,20 20)", strategy_ps),
strategy_bb);
tester::apply("bb2-b", box1, "BOX(30 10, 40 17)",
ps_distance("POINT(30 17)", "SEGMENT(20 10,20 20)", strategy_ps),
strategy_bb);
tester::apply("bb2-c", box1, "BOX(30 8, 40 17)",
ps_distance("POINT(30 17)", "SEGMENT(20 10,20 20)", strategy_ps),
strategy_bb);
// case 3
tester::apply("bb3-a", box1, "BOX(30 15, 40 25)",
ps_distance("POINT(20 20)", "SEGMENT(30 15,30 25)", strategy_ps),
strategy_bb);
tester::apply("bb3-b", box1, "BOX(30 20, 40 40)",
ps_distance("POINT(20 20)", "SEGMENT(30 20,30 40)", strategy_ps),
strategy_bb);
// case 4
tester::apply("bb4", box1, "BOX(30 25, 40 40)",
pp_distance("POINT(20 20)", "POINT(30 25)", strategy_pp),
strategy_bb);
// case 5
tester::apply("bb5", box1, "BOX(12 2, 17 7)",
pp_distance("POINT(17 7)", "POINT(17 10)", strategy_pp),
strategy_bb);
// case 6, boxes intersect thus distance is 0
tester::apply("bb6-a", box1, "BOX(12 2, 17 10)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-b", box1, "BOX(12 2, 17 17)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-c", box1, "BOX(20 2, 30 10)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-d", box1, "BOX(20 11, 30 15)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-e", box1, "BOX(20 20, 30 30)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-f", box1, "BOX(15 20, 17 30)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-g", box1, "BOX(8 20, 10 25)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-h", box1, "BOX(8 15 , 10 17)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-i", box1, "BOX(8 8, 10 10)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-j", box1, "BOX(15 8, 17 10)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
// case 7
tester::apply("bb7", box1, "BOX(12 22, 17 27)",
pp_distance("POINT(17 20)", "POINT(17 22)", strategy_pp),
strategy_bb);
// case 8
tester::apply("bb8", box1, "BOX(4 4, 8 8)",
pp_distance("POINT(8 8)", "POINT(10 10)", strategy_pp),
strategy_bb);
// case 9
tester::apply("bb9-a", box1, "BOX(4 14, 8 18)",
ps_distance("POINT(8 18)", "SEGMENT(10 10, 10 20)", strategy_ps),
strategy_bb);
tester::apply("bb9-b", box1, "BOX(4 10, 8 18)",
ps_distance("POINT(8 18)", "SEGMENT(10 10, 10 20)", strategy_ps),
strategy_bb);
tester::apply("bb9-c", box1, "BOX(4 8, 8 18)",
ps_distance("POINT(8 18)", "SEGMENT(10 10, 10 20)", strategy_ps),
strategy_bb);
// case 10
tester::apply("bb10", box1, "BOX(4 18, 8 22)",
ps_distance("POINT(10 20)", "SEGMENT(8 18, 8 22)", strategy_ps),
strategy_bb);
tester::apply("bb10", box1, "BOX(4 20, 8 22)",
ps_distance("POINT(10 20)", "SEGMENT(8 20, 8 22)", strategy_ps),
strategy_bb);
// case 11
tester::apply("bb11", box1, "BOX(4 22, 8 24)",
pp_distance("POINT(8 22)", "POINT(10 20)", strategy_pp),
strategy_bb);
// far away boxes
tester::apply("bb-far", "BOX(150 15, 170 25)", box1,
ps_distance("POINT(20 20)", "SEGMENT(150 15, 150 25)", strategy_ps),
strategy_bb);
// crosses antimeridian
tester::apply("bb-anti1", "BOX(170 15, -160 25)", box1,
ps_distance("POINT(20 20)", "SEGMENT(170 15, 170 25)", strategy_ps),
strategy_bb);
tester::apply("bb-anti2", "BOX(170 15, -160 25)", "BOX(160 10, -170 20)",
pp_distance("POINT(20 20)", "POINT(20 20)", strategy_pp),
strategy_bb);
tester::apply("bb-anti3", "BOX(170 15, -160 25)", "BOX(160 10, 170 20)",
pp_distance("POINT(20 20)", "POINT(20 20)", strategy_pp),
strategy_bb);
tester::apply("bb-anti4", "BOX(170 10, -160 20)", "BOX(160 30, -170 40)",
pp_distance("POINT(180 20)", "POINT(180 30)", strategy_pp),
strategy_bb);
// South hemisphere
tester::apply("bb-south1", "BOX(10 -20, 20 -10)", "BOX(30 -15, 40 -12)",
ps_distance("POINT(30 -15)", "SEGMENT(20 -10, 20 -20)", strategy_ps),
strategy_bb);
tester::apply("bb-south2", "BOX(10 -20, 20 -10)", "BOX(30 -30, 40 -25)",
pp_distance("POINT(30 -25)", "POINT(20 -20)", strategy_pp),
strategy_bb);
tester::apply("bb-south3", "BOX(10 -20, 20 -10)", "BOX(30 -25, 40 -15)",
ps_distance("POINT(20 -20)", "SEGMENT(30 -15, 30 -25)", strategy_ps),
strategy_bb);
tester::apply("bb-south4", "BOX(10 -20, 20 -10)", "BOX(5 -30, 30 -25)",
pp_distance("POINT(10 -25)", "POINT(10 -20)", strategy_pp),
strategy_bb);
tester::apply("bb-south4", "BOX(10 -20, 20 -10)", "BOX(5 -7, 30 -5)",
pp_distance("POINT(10 -7)", "POINT(10 -10)", strategy_pp),
strategy_bb);
// Crosses equator
tester::apply("bb-eq1", "BOX(30 -15, 40 30)", "BOX(10 -20, 20 25)",
ps_distance("POINT(20 25)", "SEGMENT(30 -15, 30 30)", strategy_ps),
strategy_bb);
tester::apply("bb-eq2", "BOX(30 -15, 40 20)", "BOX(10 -20, 20 25)",
ps_distance("POINT(30 20)", "SEGMENT(20 -20, 20 25)", strategy_ps),
strategy_bb);
tester::apply("bb-eq3", "BOX(30 5, 40 20)", "BOX(10 -20, 20 25)",
ps_distance("POINT(30 20)", "SEGMENT(20 -20, 20 25)", strategy_ps),
strategy_bb);
tester::apply("bb-eq4", "BOX(5 -30, 40 -25)", "BOX(10 -20, 20 25)",
pp_distance("POINT(10 -25)", "POINT(10 -20)", strategy_pp),
strategy_bb);
tester::apply("bb-eq5", "BOX(30 5, 40 20)", "BOX(10 -20, 50 25)",
pp_distance("POINT(30 20)", "POINT(30 20)", strategy_pp),
strategy_bb);
tester::apply("bb-eq6", "BOX(30 5, 40 20)", "BOX(10 -20, 35 25)",
pp_distance("POINT(30 20)", "POINT(30 20)", strategy_pp),
strategy_bb);
// One box in the north and one in the south hemisphere
tester::apply("bb-ns1", "BOX(30 15, 40 20)", "BOX(10 -20, 20 -15)",
pp_distance("POINT(30 15)", "POINT(20 -15)", strategy_pp),
strategy_bb);
tester::apply("bb-ns2", "BOX(30 15, 40 20)", "BOX(25 -20, 50 -15)",
pp_distance("POINT(30 15)", "POINT(30 -15)", strategy_pp),
strategy_bb);
}
template <typename Strategy_pp, typename Strategy_ps, typename Strategy_bb>
void test_distance_box_box_negative(Strategy_pp const& strategy_pp,
Strategy_ps const& strategy_ps,
Strategy_bb const& strategy_bb)
{
typedef test_distance_of_geometries<box_type, box_type> tester;
std::string const box1neg = "BOX(-20 10,-10 20)";
// case 1
tester::apply("bb1", box1neg, "BOX(-40 0,-30 5)",
pp_distance("POINT(-20 10)", "POINT(-30 5)", strategy_pp),
strategy_bb);
// case 2
tester::apply("bb2-a", box1neg, "BOX(-40 12, -30 17)",
ps_distance("POINT(-30 17)", "SEGMENT(-20 10,-20 20)", strategy_ps),
strategy_bb);
tester::apply("bb2-b", box1neg, "BOX(-40 10, -30 17)",
ps_distance("POINT(-30 17)", "SEGMENT(-20 10,-20 20)", strategy_ps),
strategy_bb);
tester::apply("bb2-c", box1neg, "BOX(-40 8, -30 17)",
ps_distance("POINT(-30 17)", "SEGMENT(-20 10,-20 20)", strategy_ps),
strategy_bb);
// case 3
tester::apply("bb3-a", box1neg, "BOX(-40 15, -30 25)",
ps_distance("POINT(-20 20)", "SEGMENT(-30 15,-30 25)", strategy_ps),
strategy_bb);
tester::apply("bb3-b", box1neg, "BOX(-40 20, -30 40)",
ps_distance("POINT(-20 20)", "SEGMENT(-30 20,-30 40)", strategy_ps),
strategy_bb);
// case 4
tester::apply("bb4", box1neg, "BOX(-40 25, -30 40)",
pp_distance("POINT(-20 20)", "POINT(-30 25)", strategy_pp),
strategy_bb);
// case 5
tester::apply("bb5", box1neg, "BOX(-17 2,-12 7)",
pp_distance("POINT(-17 7)", "POINT(-17 10)", strategy_pp),
strategy_bb);
// case 6, boxes intersect thus distance is 0
tester::apply("bb6-a", box1neg, "BOX(-17 2, -12 10)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-b", box1neg, "BOX(-17 2, -12 17)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-c", box1neg, "BOX(-30 2, -20 10)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-d", box1neg, "BOX(-30 11, -20 15)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-e", box1neg, "BOX(-30 20, -20 30)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-f", box1neg, "BOX(-17 20, -15 30)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-g", box1neg, "BOX(-10 20, -8 25)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-h", box1neg, "BOX(-10 15 , -8 17)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-i", box1neg, "BOX(-10 8, -8 10)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
tester::apply("bb6-j", box1neg, "BOX(-17 8, -15 10)",
pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp),
strategy_bb);
// case 7
tester::apply("bb7", box1neg, "BOX(-17 22, -12 27)",
pp_distance("POINT(-17 20)", "POINT(-17 22)", strategy_pp),
strategy_bb);
// case 8
tester::apply("bb8", box1neg, "BOX(-8 4, -4 8)",
pp_distance("POINT(-8 8)", "POINT(-10 10)", strategy_pp),
strategy_bb);
// case 9
tester::apply("bb9-a", box1neg, "BOX(-8 14, -4 18)",
ps_distance("POINT(-8 18)", "SEGMENT(-10 10, -10 20)", strategy_ps),
strategy_bb);
tester::apply("bb9-b", box1neg, "BOX(-8 10, -4 18)",
ps_distance("POINT(-8 18)", "SEGMENT(-10 10, -10 20)", strategy_ps),
strategy_bb);
tester::apply("bb9-c", box1neg, "BOX(-8 8, -4 18)",
ps_distance("POINT(-8 18)", "SEGMENT(-10 10, -10 20)", strategy_ps),
strategy_bb);
// case 10
tester::apply("bb10", box1neg, "BOX(-8 18, -4 22)",
ps_distance("POINT(-10 20)", "SEGMENT(-8 18, -8 22)", strategy_ps),
strategy_bb);
tester::apply("bb10", box1neg, "BOX(-8 20, -4 22)",
ps_distance("POINT(-10 20)", "SEGMENT(-8 20, -8 22)", strategy_ps),
strategy_bb);
// case 11
tester::apply("bb11", box1neg, "BOX(-8 22, -4 24)",
pp_distance("POINT(-8 22)", "POINT(-10 20)", strategy_pp),
strategy_bb);
}
//===========================================================================
BOOST_AUTO_TEST_CASE( test_all_point_segment )
{
test_distance_box_box(vincenty_pp(), vincenty_ps(), vincenty_bb());
test_distance_box_box(thomas_pp(), thomas_ps(), thomas_bb());
test_distance_box_box(andoyer_pp(), andoyer_ps(), andoyer_bb());
}