From 70fbc97e589604a9f34b86274cefd2da8cdc570a Mon Sep 17 00:00:00 2001 From: zmiao Date: Tue, 28 Apr 2020 20:03:46 +0300 Subject: [test] Distance expression: Update unit tests --- test/fixtures/geometry_data/multi_point_3.geojson | 75 ++++++++ .../fixtures/geometry_data/multi_polygon_1.geojson | 132 ++++++++++++++ .../fixtures/geometry_data/multi_polygon_2.geojson | 81 +++++++++ test/style/property_expression.test.cpp | 189 +++++++++++++++++---- 4 files changed, 444 insertions(+), 33 deletions(-) create mode 100644 test/fixtures/geometry_data/multi_point_3.geojson create mode 100644 test/fixtures/geometry_data/multi_polygon_1.geojson create mode 100644 test/fixtures/geometry_data/multi_polygon_2.geojson (limited to 'test') diff --git a/test/fixtures/geometry_data/multi_point_3.geojson b/test/fixtures/geometry_data/multi_point_3.geojson new file mode 100644 index 0000000000..3d486cbbf4 --- /dev/null +++ b/test/fixtures/geometry_data/multi_point_3.geojson @@ -0,0 +1,75 @@ +{ + "type": "Feature", + "properties": { + "marker-color": "#e0d96a" + }, + "geometry": { + "type": "MultiPoint", + "coordinates": [ + [ + 24.941325187683105, + 60.169503396855 + ], + [ + 24.943127632141113, + 60.16984495711831 + ], + [ + 24.94493007659912, + 60.17101904344053 + ], + [ + 24.947762489318848, + 60.16753935642882 + ], + [ + 24.9479341506958, + 60.16907644153227 + ], + [ + 24.946002960205078, + 60.16901239775532 + ], + [ + 24.944028854370117, + 60.16824386269413 + ], + [ + 24.9459171295166, + 60.16756070532545 + ], + [ + 24.940338134765625, + 60.168286559558055 + ], + [ + 24.94248390197754, + 60.1678168910033 + ], + [ + 24.944286346435547, + 60.16696293097573 + ], + [ + 24.946260452270508, + 60.16619434797435 + ], + [ + 24.941411018371582, + 60.16619434797435 + ], + [ + 24.943749904632565, + 60.16782756536319 + ], + [ + 24.942612648010254, + 60.16908711548297 + ], + [ + 24.944608211517334, + 60.16952474447549 + ] + ] + } +} \ No newline at end of file diff --git a/test/fixtures/geometry_data/multi_polygon_1.geojson b/test/fixtures/geometry_data/multi_polygon_1.geojson new file mode 100644 index 0000000000..0a804ce38d --- /dev/null +++ b/test/fixtures/geometry_data/multi_polygon_1.geojson @@ -0,0 +1,132 @@ +{ + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": { + "stroke": "#e0d96a", + "stroke-width": 2, + "stroke-opacity": 1, + "fill": "#c6ec00", + "fill-opacity": 0.5 + }, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 24.93870735168457, + 60.16429416283512 + ], + [ + 24.936389923095703, + 60.16205223008669 + ], + [ + 24.940123558044434, + 60.16250062887229 + ], + [ + 24.943857192993164, + 60.16333335324268 + ], + [ + 24.943127632141113, + 60.16465712803696 + ], + [ + 24.94123935699463, + 60.16595949958244 + ], + [ + 24.936561584472656, + 60.16561789892518 + ], + [ + 24.93450164794922, + 60.16435821580911 + ], + [ + 24.935274124145508, + 60.163568220403924 + ], + [ + 24.93870735168457, + 60.16429416283512 + ] + ] + ], + [ + [ + [ + 24.95166778564453, + 60.174306261926034 + ], + [ + 24.949607849121094, + 60.172918839697616 + ], + [ + 24.952783584594727, + 60.17144597351834 + ], + [ + 24.95595932006836, + 60.17217174191747 + ], + [ + 24.956517219543457, + 60.1742635728851 + ], + [ + 24.954586029052734, + 60.175736312737385 + ], + [ + 24.950637817382812, + 60.175245406790246 + ], + [ + 24.9514102935791, + 60.174348950911465 + ], + [ + 24.95166778564453, + 60.174306261926034 + ] + ] + ], + [ + [ + [ + 24.930424690246582, + 60.17413550542946 + ], + [ + 24.92875099182129, + 60.171830205844614 + ], + [ + 24.936904907226562, + 60.1703145966823 + ], + [ + 24.937891960144043, + 60.172150396016946 + ], + [ + 24.937891960144043, + 60.173922058560485 + ], + [ + 24.930424690246582, + 60.17413550542946 + ] + ] + ] + ] + } + } + ] +} \ No newline at end of file diff --git a/test/fixtures/geometry_data/multi_polygon_2.geojson b/test/fixtures/geometry_data/multi_polygon_2.geojson new file mode 100644 index 0000000000..ea7723754d --- /dev/null +++ b/test/fixtures/geometry_data/multi_polygon_2.geojson @@ -0,0 +1,81 @@ +{ + "type": "Feature", + "properties": {}, + "geometry": { + "type": "MultiPolygon", + "coordinates": [ + [ + [ + [ + 24.94171142578125, + 60.16777419352904 + ], + [ + 24.948577880859375, + 60.16777419352904 + ], + [ + 24.948577880859375, + 60.170122472217564 + ], + [ + 24.94171142578125, + 60.170122472217564 + ], + [ + 24.94171142578125, + 60.16777419352904 + ] + ] + ], + [ + [ + [ + 24.951581954956055, + 60.169503396855 + ], + [ + 24.955186843872067, + 60.169503396855 + ], + [ + 24.955186843872067, + 60.17052806699205 + ], + [ + 24.951581954956055, + 60.17052806699205 + ], + [ + 24.951581954956055, + 60.169503396855 + ] + ] + ], + [ + [ + [ + 24.944243431091305, + 60.16301307713581 + ], + [ + 24.94716167449951, + 60.16301307713581 + ], + [ + 24.94716167449951, + 60.16412335429406 + ], + [ + 24.944243431091305, + 60.16412335429406 + ], + [ + 24.944243431091305, + 60.16301307713581 + ] + ] + ] + ] + } +} \ No newline at end of file diff --git a/test/style/property_expression.test.cpp b/test/style/property_expression.test.cpp index 924b0f91f6..aecbec18e3 100644 --- a/test/style/property_expression.test.cpp +++ b/test/style/property_expression.test.cpp @@ -468,11 +468,12 @@ TEST(PropertyExpression, WithinExpressionAntiMeridian) { TEST(PropertyExpression, DistanceExpression) { static const double invalidResult = std::numeric_limits::quiet_NaN(); static const CanonicalTileID canonicalTileID(15, 18653, 9484); + // Parsing error with invalid geojson source { // geoJSON source must be Point or LineString. const std::string invalidGeoSource = R"({ - "type": "Polygon", + "type": "Unknown", "coordinates": [[[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]] })"; std::stringstream ss; @@ -481,48 +482,18 @@ TEST(PropertyExpression, DistanceExpression) { ASSERT_FALSE(expression); } - // Parsing error with invalid unit + // Parsing error with extra arguments { const std::string invalidGeoSource = R"({ "type": "Point", "coordinates": [0, 0], })"; std::stringstream ss; - ss << std::string(R"(["distance", )") << invalidGeoSource << std::string(R"(, "InvalidUnits"])"); + ss << std::string(R"(["distance", )") << invalidGeoSource << std::string(R"(, "ExtraArgument"])"); auto expression = createExpression(ss.str().c_str()); ASSERT_FALSE(expression); } - // Evaluation test with non-supported geometry type - { - const std::string pointGeoSource = R"({ - "type": "Point", - "coordinates": - [ - 24.938492774963375, - 60.16980226227959 - ] - })"; - std::stringstream ss; - ss << std::string(R"(["distance", )") << pointGeoSource << std::string(R"( ])"); - auto expression = createExpression(ss.str().c_str()); - ASSERT_TRUE(expression); - PropertyExpression propExpr(std::move(expression)); - - Polygon testRing{{{24.937505722045895, 60.16815846879986}, - {24.940595626831055, 60.16815846879986}, - {24.940595626831055, 60.169268572114106}, - {24.937505722045895, 60.169268572114106}, - {24.937505722045895, 60.16815846879986}}}; - auto geoPoly = convertGeometry(testRing, canonicalTileID); - StubGeometryTileFeature polyFeature(FeatureType::Polygon, geoPoly); - - // return evaluation error - auto evaluatedResult = - propExpr.evaluate(EvaluationContext(&polyFeature).withCanonicalTileID(&canonicalTileID), invalidResult); - EXPECT_TRUE(std::isnan(evaluatedResult)); - } - // Evaluation test with Point to Point distance by using different units { const std::string pointGeoSource = R"({ @@ -752,4 +723,156 @@ TEST(PropertyExpression, DistanceExpression) { EvaluationContext(&multiLineFeature).withCanonicalTileID(&canonicalTileID), invalidResult); EXPECT_NEAR(384.109, evaluatedResult, 0.01); } + + // Evaluation test with MultiPoint to MultiPolygon distance + { + const auto multiPolygon = mbgl::util::read_file("test/fixtures/geometry_data/multi_polygon_1.geojson"); + std::stringstream ss; + ss << std::string(R"(["distance", )") << multiPolygon << std::string(R"( ])"); + auto expression = createExpression(ss.str().c_str()); + ASSERT_TRUE(expression); + PropertyExpression propExpr(std::move(expression)); + + const auto multiPointFeature1 = getFeature("multi_point_3.geojson", FeatureType::Point, canonicalTileID); + auto evaluatedResult = propExpr.evaluate( + EvaluationContext(&multiPointFeature1).withCanonicalTileID(&canonicalTileID), invalidResult); + EXPECT_NEAR(27.917, evaluatedResult, 0.01); + + const auto multiPointFeature2 = getFeature("multi_point_2.geojson", FeatureType::Point, canonicalTileID); + evaluatedResult = propExpr.evaluate( + EvaluationContext(&multiPointFeature2).withCanonicalTileID(&canonicalTileID), invalidResult); + EXPECT_NEAR(0.0, evaluatedResult, 0.01); + } + + // Evaluation test with MultiLine to MultiPolygon distance + { + const auto multiPolygon = mbgl::util::read_file("test/fixtures/geometry_data/multi_polygon_1.geojson"); + std::stringstream ss; + ss << std::string(R"(["distance", )") << multiPolygon << std::string(R"( ])"); + auto expression = createExpression(ss.str().c_str()); + ASSERT_TRUE(expression); + PropertyExpression propExpr(std::move(expression)); + + const auto multiLineFeature1 = + getFeature("multi_line_string_1.geojson", FeatureType::LineString, canonicalTileID); + auto evaluatedResult = propExpr.evaluate( + EvaluationContext(&multiLineFeature1).withCanonicalTileID(&canonicalTileID), invalidResult); + EXPECT_NEAR(193.450, evaluatedResult, 0.01); + + const auto multiLineFeature2 = + getFeature("multi_line_string_2.geojson", FeatureType::LineString, canonicalTileID); + evaluatedResult = propExpr.evaluate(EvaluationContext(&multiLineFeature2).withCanonicalTileID(&canonicalTileID), + invalidResult); + EXPECT_NEAR(0.0, evaluatedResult, 0.01); + } + + // Evaluation test with Polygon to MultiPolygon distance + { + const auto multiPolygon = mbgl::util::read_file("test/fixtures/geometry_data/multi_polygon_1.geojson"); + std::stringstream ss; + ss << std::string(R"(["distance", )") << multiPolygon << std::string(R"( ])"); + auto expression = createExpression(ss.str().c_str()); + ASSERT_TRUE(expression); + PropertyExpression propExpr(std::move(expression)); + + Polygon polygon{{{24.94171142578125, 60.16777419352904}, + {24.948577880859375, 60.16777419352904}, + {24.948577880859375, 60.170122472217564}, + {24.94171142578125, 60.170122472217564}, + {24.94171142578125, 60.16777419352904}}}; + auto geoPolygon = convertGeometry(polygon, canonicalTileID); + StubGeometryTileFeature polygonFeature(FeatureType::Polygon, geoPolygon); + + auto evaluatedResult = + propExpr.evaluate(EvaluationContext(&polygonFeature).withCanonicalTileID(&canonicalTileID), invalidResult); + EXPECT_NEAR(203.876, evaluatedResult, 0.01); + } + + // Evaluation test with MultiPolygon to MultiPolygon distance + { + const auto multiPolygon = mbgl::util::read_file("test/fixtures/geometry_data/multi_polygon_1.geojson"); + std::stringstream ss; + ss << std::string(R"(["distance", )") << multiPolygon << std::string(R"( ])"); + auto expression = createExpression(ss.str().c_str()); + ASSERT_TRUE(expression); + PropertyExpression propExpr(std::move(expression)); + + const auto multiPolygonFeature = getFeature("multi_polygon_2.geojson", FeatureType::Polygon, canonicalTileID); + auto evaluatedResult = propExpr.evaluate( + EvaluationContext(&multiPolygonFeature).withCanonicalTileID(&canonicalTileID), invalidResult); + EXPECT_NEAR(41.632, evaluatedResult, 0.01); + } + + // Evaluation test with LineString/Polygon to Polygon distance with special cases + { + const std::string multiPolygon = R"({ + "type": "Polygon", + "coordinates": [[[24.937891960144043, 60.16730451765011], + [24.94892120361328, 60.16730451765011], + [24.94892120361328, 60.17010112498546], + [24.937891960144043, 60.17010112498546], + [24.937891960144043, 60.16730451765011]]]})"; + std::stringstream ss; + ss << std::string(R"(["distance", )") << multiPolygon << std::string(R"( ])"); + auto expression = createExpression(ss.str().c_str()); + ASSERT_TRUE(expression); + PropertyExpression propExpr(std::move(expression)); + + // polygon1 is fully inside polygon + Polygon polygon1{{{24.941797256469727, 60.16850004304534}, + {24.94235515594482, 60.16850004304534}, + {24.94235515594482, 60.169439353910285}, + {24.941797256469727, 60.169439353910285}, + {24.941797256469727, 60.16850004304534}}}; + auto geoPolygon1 = convertGeometry(polygon1, canonicalTileID); + StubGeometryTileFeature polygonFeature1(FeatureType::Polygon, geoPolygon1); + + auto evaluatedResult = + propExpr.evaluate(EvaluationContext(&polygonFeature1).withCanonicalTileID(&canonicalTileID), invalidResult); + EXPECT_NEAR(0.0, evaluatedResult, 0.01); + + // polygon2's line is intersecting polygon, but no point is inside polygon + Polygon polygon2{{{24.943385124206543, 60.166066249059554}, + {24.94596004486084, 60.166066249059554}, + {24.94596004486084, 60.1714246271462}, + {24.943385124206543, 60.1714246271462}, + {24.943385124206543, 60.166066249059554}}}; + auto geoPolygon2 = convertGeometry(polygon2, canonicalTileID); + StubGeometryTileFeature polygonFeature2(FeatureType::Polygon, geoPolygon2); + + evaluatedResult = + propExpr.evaluate(EvaluationContext(&polygonFeature2).withCanonicalTileID(&canonicalTileID), invalidResult); + EXPECT_NEAR(0.0, evaluatedResult, 0.01); + + // one of polygon3's point is inside polygon + Polygon polygon3{{{24.94797706604004, 60.1694607015724}, + {24.952354431152344, 60.1694607015724}, + {24.952354431152344, 60.17082692309542}, + {24.94797706604004, 60.17082692309542}, + {24.94797706604004, 60.1694607015724}}}; + auto geoPolygon3 = convertGeometry(polygon3, canonicalTileID); + StubGeometryTileFeature polygonFeature3(FeatureType::Polygon, geoPolygon3); + + evaluatedResult = + propExpr.evaluate(EvaluationContext(&polygonFeature3).withCanonicalTileID(&canonicalTileID), invalidResult); + EXPECT_NEAR(0.0, evaluatedResult, 0.01); + + // lineString1 is within polygon + LineString lineString1{{24.947097301483154, 60.16921520262075}, {24.947311878204346, 60.1680197032483}}; + auto geoLineString1 = convertGeometry(lineString1, canonicalTileID); + StubGeometryTileFeature lineFeature1(FeatureType::LineString, geoLineString1); + + evaluatedResult = + propExpr.evaluate(EvaluationContext(&lineFeature1).withCanonicalTileID(&canonicalTileID), invalidResult); + EXPECT_NEAR(0.0, evaluatedResult, 0.01); + + // lineString2 is intersecting the polygon but its points are outside the polygon + LineString lineString2{{24.93999481201172, 60.17116846959888}, {24.940037727355957, 60.16542574699484}}; + auto geoLineString2 = convertGeometry(lineString2, canonicalTileID); + StubGeometryTileFeature lineFeature2(FeatureType::LineString, geoLineString2); + + evaluatedResult = + propExpr.evaluate(EvaluationContext(&lineFeature2).withCanonicalTileID(&canonicalTileID), invalidResult); + EXPECT_NEAR(0.0, evaluatedResult, 0.01); + } } -- cgit v1.2.1