diff --git a/editor/editor_tests/osm_feature_matcher_test.cpp b/editor/editor_tests/osm_feature_matcher_test.cpp index 8299ca4754..c9023027bb 100644 --- a/editor/editor_tests/osm_feature_matcher_test.cpp +++ b/editor/editor_tests/osm_feature_matcher_test.cpp @@ -261,7 +261,6 @@ char const * const osmRawResponseRelation = R"SEP( )SEP"; -} // namespace // Note: Geometry should not contain duplicates. @@ -355,8 +354,6 @@ UNIT_TEST(GetBestOsmRealtion_Test) TEST_EQUAL(bestWay.attribute("id").value(), string("365808"), ()); } -namespace -{ char const * const osmResponseBuildingMiss = R"SEP( @@ -399,7 +396,6 @@ char const * const osmResponseBuildingMiss = R"SEP( )SEP"; -} // namespace UNIT_TEST(HouseBuildingMiss_test) { @@ -415,3 +411,62 @@ UNIT_TEST(HouseBuildingMiss_test) auto const bestWay = osm::GetBestOsmWayOrRelation(osmResponse, geometry); TEST_EQUAL(bestWay.attribute("id").value(), string("345630019"), ()); } + +string const kHouseWithSeveralEntrances = R"xxx(" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +)xxx"; + +UNIT_TEST(HouseWithSeveralEntrances) +{ + pugi::xml_document osmResponse; + TEST(osmResponse.load_buffer(kHouseWithSeveralEntrances.c_str(), + kHouseWithSeveralEntrances.size()), ()); + + vector const geometry = { + {37.569802534355233, 67.575570401367315}, + {37.56998492456961, 67.57561599892091}, + {37.570076119676798, 67.574481424499169}, + {37.570258509891175, 67.574527022052763} + }; + + auto const bestWay = osm::GetBestOsmWayOrRelation(osmResponse, geometry); + TEST_EQUAL(bestWay.attribute("id").value(), string("30680719"), ()); +} +} // namespace diff --git a/editor/osm_feature_matcher.cpp b/editor/osm_feature_matcher.cpp index 786ebda161..094988bc31 100644 --- a/editor/osm_feature_matcher.cpp +++ b/editor/osm_feature_matcher.cpp @@ -89,11 +89,10 @@ vector GetWaysOrRelationsGeometry(pugi::xml_document const & osmResp return GetRelationsGeometry(osmResponse, wayOrRelation); } -/// @returns value form [-0.5, 0.5]. Negative values are used as penalty, -/// positive as score. -/// @param osmResponse - nodes, ways and relations from osm -/// @param wayOrRelation - either way or relation to be compared agains ourGeometry -/// @param outGeometry - geometry of a FeatureType (ourGeometry must be sort-uniqued) +/// @returns value form [-1, 1]. Negative values are used as penalty, positive as score. +/// @param osmResponse - nodes, ways and relations from osm; +/// @param wayOrRelation - either way or relation to be compared agains ourGeometry; +/// @param outGeometry - geometry of a FeatureType (ourGeometry must be sort-uniqued); double ScoreGeometry(pugi::xml_document const & osmResponse, pugi::xml_node const & wayOrRelation, vector ourGeometry) { @@ -128,9 +127,12 @@ double ScoreGeometry(pugi::xml_document const & osmResponse, } } - auto const wayScore = static_cast(matched) / theirGeometry.size() - 0.5; - auto const geomScore = static_cast(matched) / ourGeometry.size() - 0.5; - auto const result = wayScore <= 0 || geomScore <= 0 + auto const wayScore = static_cast(matched) / theirGeometry.size(); + auto const geomScore = static_cast(matched) / ourGeometry.size(); + // Our geometry is less detailed and we expect the pair to be found for more than half of points. + // OSM geometry is more detailed and we expect the pair to be found for at least a quarter of + // the points. + auto const result = wayScore < 0.25 || geomScore <= 0.5 ? -1 : 2 / (1 / wayScore + 1 / geomScore);