diff options
author | Vladimir Byko-Ianko <v.bykoianko@corp.mail.ru> | 2015-04-21 10:43:55 +0300 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 02:47:17 +0300 |
commit | 30737b7bfeb67db966794028345abbe335e7cc79 (patch) | |
tree | e257a0db4d62ea41d453cb50259f89fcdcf22bcd /routing/routing_tests/turns_generator_test.cpp | |
parent | 861adb654c22419f2c96dad9e70f9f6f46aff725 (diff) |
Fix after colleagues comments
Diffstat (limited to 'routing/routing_tests/turns_generator_test.cpp')
-rw-r--r-- | routing/routing_tests/turns_generator_test.cpp | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/routing/routing_tests/turns_generator_test.cpp b/routing/routing_tests/turns_generator_test.cpp new file mode 100644 index 0000000000..b78fb94335 --- /dev/null +++ b/routing/routing_tests/turns_generator_test.cpp @@ -0,0 +1,272 @@ +#include "testing/testing.hpp" + +#include "routing/route.hpp" +#include "routing/turns.hpp" +#include "routing/turns_generator.hpp" + +#include "indexer/mercator.hpp" + +#include "geometry/point2d.hpp" + +#include "std/cmath.hpp" +#include "std/string.hpp" +#include "std/vector.hpp" + +using namespace routing; + +namespace +{ +UNIT_TEST(TestSplitLanes) +{ + vector<string> result; + routing::turns::SplitLanes("through|through|through|through;right", '|', result); + vector<string> expected1 = {"through", "through", "through", "through;right"}; + TEST_EQUAL(result, expected1, ()); + + routing::turns::SplitLanes("adsjkddfasui8747&sxdsdlad8\"\'", '|', result); + TEST_EQUAL(result.size(), 1, ()); + TEST_EQUAL(result[0], "adsjkddfasui8747&sxdsdlad8\"\'", ()); + + routing::turns::SplitLanes("|||||||", '|', result); + vector<string> expected2 = {"", "", "", "", "", "", ""}; + TEST_EQUAL(result, expected2, ()); +} + +UNIT_TEST(TestParseSingleLane) +{ + routing::turns::TSingleLane result; + TEST(routing::turns::ParseSingleLane("through;right", ';', result), ()); + vector<routing::turns::LaneWay> expected1 = {routing::turns::LaneWay::Through, routing::turns::LaneWay::Right}; + TEST_EQUAL(result, expected1, ()); + + TEST(!routing::turns::ParseSingleLane("through;Right", ';', result), ()); + + TEST(!routing::turns::ParseSingleLane("through ;right", ';', result), ()); + TEST_EQUAL(result.size(), 0, ()); + + TEST(!routing::turns::ParseSingleLane("SD32kk*887;;", ';', result), ()); + TEST_EQUAL(result.size(), 0, ()); + + TEST(!routing::turns::ParseSingleLane("Что-то на кириллице", ';', result), ()); + TEST_EQUAL(result.size(), 0, ()); + + TEST(!routing::turns::ParseSingleLane("משהו בעברית", ';', result), ()); + TEST_EQUAL(result.size(), 0, ()); + + TEST(routing::turns::ParseSingleLane("left;through", ';', result), ()); + vector<routing::turns::LaneWay> expected2 = {routing::turns::LaneWay::Left, routing::turns::LaneWay::Through}; + TEST_EQUAL(result, expected2, ()); + + TEST(routing::turns::ParseSingleLane("left", ';', result), ()); + TEST_EQUAL(result.size(), 1, ()); + TEST_EQUAL(result[0], routing::turns::LaneWay::Left, ()); +} + +UNIT_TEST(TestParseLanes) +{ + vector<routing::turns::TSingleLane> result; + TEST(routing::turns::ParseLanes("through|through|through|through;right", result), ()); + TEST_EQUAL(result.size(), 4, ()); + TEST_EQUAL(result[0].size(), 1, ()); + TEST_EQUAL(result[3].size(), 2, ()); + TEST_EQUAL(result[0][0], routing::turns::LaneWay::Through, ()); + TEST_EQUAL(result[3][0], routing::turns::LaneWay::Through, ()); + TEST_EQUAL(result[3][1], routing::turns::LaneWay::Right, ()); + + TEST(routing::turns::ParseLanes("left|left;through|through|through", result), ()); + TEST_EQUAL(result.size(), 4, ()); + TEST_EQUAL(result[0].size(), 1, ()); + TEST_EQUAL(result[1].size(), 2, ()); + TEST_EQUAL(result[3].size(), 1, ()); + TEST_EQUAL(result[0][0], routing::turns::LaneWay::Left, ()); + TEST_EQUAL(result[1][0], routing::turns::LaneWay::Left, ()); + TEST_EQUAL(result[1][1], routing::turns::LaneWay::Through, ()); + TEST_EQUAL(result[3][0], routing::turns::LaneWay::Through, ()); + + TEST(routing::turns::ParseLanes("left|through|through", result), ()); + TEST_EQUAL(result.size(), 3, ()); + TEST_EQUAL(result[0].size(), 1, ()); + TEST_EQUAL(result[1].size(), 1, ()); + TEST_EQUAL(result[2].size(), 1, ()); + TEST_EQUAL(result[0][0], routing::turns::LaneWay::Left, ()); + TEST_EQUAL(result[1][0], routing::turns::LaneWay::Through, ()); + TEST_EQUAL(result[2][0], routing::turns::LaneWay::Through, ()); + + TEST(routing::turns::ParseLanes("left|le ft| through|through | right", result), ()); + TEST_EQUAL(result.size(), 5, ()); + TEST_EQUAL(result[0].size(), 1, ()); + TEST_EQUAL(result[4].size(), 1, ()); + TEST_EQUAL(result[0][0], routing::turns::LaneWay::Left, ()); + TEST_EQUAL(result[1][0], routing::turns::LaneWay::Left, ()); + TEST_EQUAL(result[2][0], routing::turns::LaneWay::Through, ()); + TEST_EQUAL(result[3][0], routing::turns::LaneWay::Through, ()); + TEST_EQUAL(result[4][0], routing::turns::LaneWay::Right, ()); + + TEST(routing::turns::ParseLanes("left|Left|through|througH|right", result), ()); + TEST_EQUAL(result.size(), 5, ()); + TEST_EQUAL(result[0].size(), 1, ()); + TEST_EQUAL(result[4].size(), 1, ()); + TEST_EQUAL(result[0][0], routing::turns::LaneWay::Left, ()); + TEST_EQUAL(result[4][0], routing::turns::LaneWay::Right, ()); + + TEST(routing::turns::ParseLanes("left|Left|through|througH|through;right;sharp_rIght", result), ()); + TEST_EQUAL(result.size(), 5, ()); + TEST_EQUAL(result[0].size(), 1, ()); + TEST_EQUAL(result[4].size(), 3, ()); + TEST_EQUAL(result[0][0], routing::turns::LaneWay::Left, ()); + TEST_EQUAL(result[4][0], routing::turns::LaneWay::Through, ()); + TEST_EQUAL(result[4][1], routing::turns::LaneWay::Right, ()); + TEST_EQUAL(result[4][2], routing::turns::LaneWay::SharpRight, ()); + + TEST(!routing::turns::ParseLanes("left|Leftt|through|througH|right", result), ()); + TEST_EQUAL(result.size(), 0, ()); + + TEST(!routing::turns::ParseLanes("Что-то на кириллице", result), ()); + TEST_EQUAL(result.size(), 0, ()); + + TEST(!routing::turns::ParseLanes("משהו בעברית", result), ()); + TEST_EQUAL(result.size(), 0, ()); + + TEST(routing::turns::ParseLanes("left |Left|through|througH|right", result), ()); + TEST_EQUAL(result.size(), 5, ()); + TEST_EQUAL(result[0][0], routing::turns::LaneWay::Left, ()); + TEST_EQUAL(result[1][0], routing::turns::LaneWay::Left, ()); +} + +UNIT_TEST(TestFixupTurns) +{ + double const kHalfSquareSideMeters = 10.; + m2::PointD const kSquareCenterLonLat = {0., 0.}; + m2::RectD const kSquareNearZero = MercatorBounds::MetresToXY(kSquareCenterLonLat.x, + kSquareCenterLonLat.y, kHalfSquareSideMeters); + // Removing a turn in case staying on a roundabout. + vector<m2::PointD> const pointsMerc1 = { + { kSquareNearZero.minX(), kSquareNearZero.minY()}, + { kSquareNearZero.minX(), kSquareNearZero.maxY() }, + { kSquareNearZero.maxX(), kSquareNearZero.maxY() }, + { kSquareNearZero.maxX(), kSquareNearZero.minY() } + }; + // The constructor TurnItem(uint32_t idx, turns::TurnDirection t, uint32_t exitNum = 0) + // is used for initialization of vector<TurnItem> below. + Route::TurnsT turnsDir1 = { + { 0, turns::EnterRoundAbout }, + { 1, turns::StayOnRoundAbout }, + { 2, turns::LeaveRoundAbout }, + { 3, turns::ReachedYourDestination } + }; + + turns::FixupTurns(pointsMerc1, turnsDir1); + Route::TurnsT expectedTurnDir1 = { + { 0, turns::EnterRoundAbout, 2 }, + { 2, turns::LeaveRoundAbout }, + { 3, turns::ReachedYourDestination } + }; + TEST_EQUAL(turnsDir1, expectedTurnDir1, ()); + + // Merging turns which are close to each other. + vector<m2::PointD> const pointsMerc2 = { + { kSquareNearZero.minX(), kSquareNearZero.minY()}, + { kSquareCenterLonLat.x, kSquareCenterLonLat.y }, + { kSquareNearZero.maxX(), kSquareNearZero.maxY() }}; + Route::TurnsT turnsDir2 = { + { 0, turns::GoStraight }, + { 1, turns::TurnLeft }, + { 2, turns::ReachedYourDestination } + }; + + turns::FixupTurns(pointsMerc2, turnsDir2); + Route::TurnsT expectedTurnDir2 = { + { 1, turns::TurnLeft }, + { 2, turns::ReachedYourDestination } + }; + TEST_EQUAL(turnsDir2, expectedTurnDir2, ()); + + // No turn is removed. + vector<m2::PointD> const pointsMerc3 = { + { kSquareNearZero.minX(), kSquareNearZero.minY()}, + { kSquareNearZero.minX(), kSquareNearZero.maxY() }, + { kSquareNearZero.maxX(), kSquareNearZero.maxY() }}; + Route::TurnsT turnsDir3 = { + { 1, turns::TurnRight }, + { 2, turns::ReachedYourDestination } + }; + + turns::FixupTurns(pointsMerc3, turnsDir3); + Route::TurnsT expectedTurnDir3 = { + { 1, turns::TurnRight }, + { 2, turns::ReachedYourDestination } + }; + TEST_EQUAL(turnsDir3, expectedTurnDir3, ()); +} + +UNIT_TEST(TestCalculateTurnGeometry) +{ + double constexpr kHalfSquareSideMeters = 10.; + double constexpr kSquareSideMeters = 2 * kHalfSquareSideMeters; + double const kErrorMeters = 1.; + m2::PointD const kSquareCenterLonLat = {0., 0.}; + m2::RectD const kSquareNearZero = MercatorBounds::MetresToXY(kSquareCenterLonLat.x, + kSquareCenterLonLat.y, kHalfSquareSideMeters); + + // Empty vectors + vector<m2::PointD> const points1; + Route::TurnsT const turnsDir1; + turns::TurnsGeomT turnsGeom1; + turns::CalculateTurnGeometry(points1, turnsDir1, turnsGeom1); + TEST(turnsGeom1.empty(), ()); + + // A turn is in the middle of a very short route. + vector<m2::PointD> const points2 = { + { kSquareNearZero.minX(), kSquareNearZero.minY() }, + { kSquareNearZero.maxX(), kSquareNearZero.maxY() }, + { kSquareNearZero.minX(), kSquareNearZero.maxY() } + }; + Route::TurnsT const turnsDir2 = { + { 1, turns::TurnLeft }, + { 2, turns::ReachedYourDestination } + }; + turns::TurnsGeomT turnsGeom2; + + turns::CalculateTurnGeometry(points2, turnsDir2, turnsGeom2); + TEST_EQUAL(turnsGeom2.size(), 1, ()); + TEST_EQUAL(turnsGeom2[0].m_indexInRoute, 1, ()); + TEST_EQUAL(turnsGeom2[0].m_turnIndex, 1, ()); + TEST_EQUAL(turnsGeom2[0].m_points.size(), 3, ()); + TEST_LESS(fabs(MercatorBounds::DistanceOnEarth(turnsGeom2[0].m_points[1], + turnsGeom2[0].m_points[2]) - kSquareSideMeters), + kErrorMeters, ()); + + // Two turns. One is in the very beginnig of a short route and another one is at the end. + // The first turn is located at point 0 and the second one at the point 3. + // 1----->2 + // ^ | + // | 4 | + // | \ v + // 0 3 + vector<m2::PointD> const points3 = { + { kSquareNearZero.minX(), kSquareNearZero.minY() }, + { kSquareNearZero.minX(), kSquareNearZero.maxY() }, + { kSquareNearZero.maxX(), kSquareNearZero.maxY() }, + { kSquareNearZero.maxX(), kSquareNearZero.minY() }, + { kSquareCenterLonLat.x, kSquareCenterLonLat.y } + }; + Route::TurnsT const turnsDir3 = { + { 0, turns::GoStraight }, + { 3, turns::TurnSharpRight }, + { 4, turns::ReachedYourDestination } + }; + turns::TurnsGeomT turnsGeom3; + + turns::CalculateTurnGeometry(points3, turnsDir3, turnsGeom3); + TEST_EQUAL(turnsGeom3.size(), 1, ()); + TEST_EQUAL(turnsGeom3[0].m_indexInRoute, 3, ()); + TEST_EQUAL(turnsGeom3[0].m_turnIndex, 3, ()); + TEST_EQUAL(turnsGeom3[0].m_points.size(), 5, ()); + TEST_LESS(fabs(MercatorBounds::DistanceOnEarth(turnsGeom3[0].m_points[1], + turnsGeom3[0].m_points[2]) - kSquareSideMeters), + kErrorMeters, ()); + TEST_LESS(fabs(MercatorBounds::DistanceOnEarth(turnsGeom3[0].m_points[2], + turnsGeom3[0].m_points[3]) - kSquareSideMeters), + kErrorMeters, ()); +} +} |