Repo created
This commit is contained in:
parent
4af19165ec
commit
68073add76
12458 changed files with 12350765 additions and 2 deletions
20
generator/generator_tests_support/CMakeLists.txt
Normal file
20
generator/generator_tests_support/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
project(generator_tests_support)
|
||||
|
||||
set(SRC
|
||||
routing_helpers.cpp
|
||||
routing_helpers.hpp
|
||||
test_feature.cpp
|
||||
test_feature.hpp
|
||||
test_generator.cpp
|
||||
test_generator.hpp
|
||||
test_mwm_builder.cpp
|
||||
test_mwm_builder.hpp
|
||||
test_with_classificator.cpp
|
||||
test_with_classificator.hpp
|
||||
test_with_custom_mwms.cpp
|
||||
test_with_custom_mwms.hpp
|
||||
)
|
||||
|
||||
omim_add_library(${PROJECT_NAME} ${SRC})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} generator)
|
||||
105
generator/generator_tests_support/routing_helpers.cpp
Normal file
105
generator/generator_tests_support/routing_helpers.cpp
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#include "generator/generator_tests_support/routing_helpers.hpp"
|
||||
|
||||
#include "testing/testing.hpp"
|
||||
|
||||
#include "generator/gen_mwm_info.hpp"
|
||||
|
||||
#include "routing/traffic_stash.hpp"
|
||||
|
||||
#include "routing_common/car_model.hpp"
|
||||
|
||||
#include "coding/file_writer.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/geo_object_id.hpp"
|
||||
#include "base/string_utils.hpp"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace generator
|
||||
{
|
||||
void ReEncodeOsmIdsToFeatureIdsMapping(std::string const & mappingContent, std::string const & outputFilePath)
|
||||
{
|
||||
strings::SimpleTokenizer lineIter(mappingContent, "\n\r" /* line delimiters */);
|
||||
|
||||
std::vector<std::pair<base::GeoObjectId, uint32_t>> osmIdsToFeatureIds;
|
||||
for (; lineIter; ++lineIter)
|
||||
{
|
||||
auto const & line = *lineIter;
|
||||
strings::SimpleTokenizer idIter(line, ", \t" /* id delimiters */);
|
||||
uint64_t osmId = 0;
|
||||
TEST(idIter, ());
|
||||
TEST(strings::to_uint(*idIter, osmId), ("Cannot convert to uint64_t:", *idIter));
|
||||
TEST(idIter, ("Wrong feature ids to osm ids mapping."));
|
||||
++idIter;
|
||||
|
||||
uint32_t featureId = 0;
|
||||
TEST(idIter, ());
|
||||
TEST(strings::to_uint(*idIter, featureId), ("Cannot convert to uint:", *idIter));
|
||||
osmIdsToFeatureIds.emplace_back(base::MakeOsmWay(osmId), featureId);
|
||||
++idIter;
|
||||
TEST(!idIter, ());
|
||||
}
|
||||
|
||||
FileWriter osm2ftWriter(outputFilePath);
|
||||
rw::WriteVectorOfPOD(osm2ftWriter, osmIdsToFeatureIds);
|
||||
}
|
||||
} // namespace generator
|
||||
|
||||
namespace routing
|
||||
{
|
||||
void TestGeometryLoader::Load(uint32_t featureId, RoadGeometry & road)
|
||||
{
|
||||
auto const it = m_roads.find(featureId);
|
||||
if (it == m_roads.cend())
|
||||
return;
|
||||
|
||||
road = it->second;
|
||||
}
|
||||
|
||||
void TestGeometryLoader::AddRoad(uint32_t featureId, bool oneWay, float speed, RoadGeometry::Points const & points)
|
||||
{
|
||||
auto const it = m_roads.find(featureId);
|
||||
CHECK(it == m_roads.end(), ("Already contains feature", featureId));
|
||||
m_roads[featureId] = RoadGeometry(oneWay, speed, speed, points);
|
||||
m_roads[featureId].SetPassThroughAllowedForTests(true);
|
||||
}
|
||||
|
||||
void TestGeometryLoader::SetPassThroughAllowed(uint32_t featureId, bool passThroughAllowed)
|
||||
{
|
||||
auto const it = m_roads.find(featureId);
|
||||
CHECK(it != m_roads.end(), ("No feature", featureId));
|
||||
m_roads[featureId].SetPassThroughAllowedForTests(passThroughAllowed);
|
||||
}
|
||||
|
||||
std::shared_ptr<EdgeEstimator> CreateEstimatorForCar(std::shared_ptr<TrafficStash> trafficStash)
|
||||
{
|
||||
auto const carModel = CarModelFactory({}).GetVehicleModel();
|
||||
return EdgeEstimator::Create(VehicleType::Car, *carModel, trafficStash, nullptr /* DataSource */,
|
||||
nullptr /* NumMwmIds */);
|
||||
}
|
||||
|
||||
std::shared_ptr<EdgeEstimator> CreateEstimatorForCar(traffic::TrafficCache const & trafficCache)
|
||||
{
|
||||
auto numMwmIds = std::make_shared<NumMwmIds>();
|
||||
auto stash = std::make_shared<TrafficStash>(trafficCache, numMwmIds);
|
||||
return CreateEstimatorForCar(stash);
|
||||
}
|
||||
|
||||
Joint MakeJoint(std::vector<RoadPoint> const & points)
|
||||
{
|
||||
Joint joint;
|
||||
for (auto const & point : points)
|
||||
joint.AddPoint(point);
|
||||
|
||||
return joint;
|
||||
}
|
||||
|
||||
std::unique_ptr<IndexGraph> BuildIndexGraph(std::unique_ptr<TestGeometryLoader> geometryLoader,
|
||||
std::shared_ptr<EdgeEstimator> estimator, std::vector<Joint> const & joints)
|
||||
{
|
||||
auto graph = std::make_unique<IndexGraph>(std::make_shared<Geometry>(std::move(geometryLoader)), estimator);
|
||||
graph->Import(joints);
|
||||
return graph;
|
||||
}
|
||||
} // namespace routing
|
||||
56
generator/generator_tests_support/routing_helpers.hpp
Normal file
56
generator/generator_tests_support/routing_helpers.hpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#include "routing/edge_estimator.hpp"
|
||||
#include "routing/geometry.hpp"
|
||||
#include "routing/index_graph.hpp"
|
||||
#include "routing/joint.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace generator
|
||||
{
|
||||
/// \brief Generates a binary file by |mappingContent| with mapping from osm ids to feature ids.
|
||||
/// \param mappingContent a string with lines with mapping from osm id to feature id (one to one).
|
||||
/// For example
|
||||
/// 10, 1,
|
||||
/// 20, 2
|
||||
/// 30, 3,
|
||||
/// 40, 4
|
||||
/// \param outputFilePath full path to an output file where the mapping is saved.
|
||||
void ReEncodeOsmIdsToFeatureIdsMapping(std::string const & mappingContent, std::string const & outputFilePath);
|
||||
} // namespace generator
|
||||
|
||||
namespace traffic
|
||||
{
|
||||
class TrafficCache;
|
||||
}
|
||||
|
||||
namespace routing
|
||||
{
|
||||
class TestGeometryLoader : public GeometryLoader
|
||||
{
|
||||
public:
|
||||
// GeometryLoader overrides:
|
||||
void Load(uint32_t featureId, routing::RoadGeometry & road) override;
|
||||
|
||||
void AddRoad(uint32_t featureId, bool oneWay, float speed, routing::RoadGeometry::Points const & points);
|
||||
|
||||
void SetPassThroughAllowed(uint32_t featureId, bool passThroughAllowed);
|
||||
|
||||
private:
|
||||
std::unordered_map<uint32_t, RoadGeometry> m_roads;
|
||||
};
|
||||
|
||||
std::shared_ptr<EdgeEstimator> CreateEstimatorForCar(traffic::TrafficCache const & trafficCache);
|
||||
std::shared_ptr<EdgeEstimator> CreateEstimatorForCar(std::shared_ptr<TrafficStash> trafficStash);
|
||||
|
||||
Joint MakeJoint(std::vector<routing::RoadPoint> const & points);
|
||||
|
||||
std::unique_ptr<IndexGraph> BuildIndexGraph(std::unique_ptr<TestGeometryLoader> geometryLoader,
|
||||
std::shared_ptr<EdgeEstimator> estimator,
|
||||
std::vector<Joint> const & joints);
|
||||
} // namespace routing
|
||||
484
generator/generator_tests_support/test_feature.cpp
Normal file
484
generator/generator_tests_support/test_feature.cpp
Normal file
|
|
@ -0,0 +1,484 @@
|
|||
#include "generator/generator_tests_support/test_feature.hpp"
|
||||
|
||||
#include "generator/feature_builder.hpp"
|
||||
|
||||
#include "editor/osm_editor.hpp"
|
||||
|
||||
#include "indexer/classificator.hpp"
|
||||
#include "indexer/editable_map_object.hpp"
|
||||
#include "indexer/feature.hpp"
|
||||
#include "indexer/feature_decl.hpp"
|
||||
#include "indexer/feature_meta.hpp"
|
||||
#include "indexer/mwm_set.hpp"
|
||||
|
||||
#include "coding/string_utf8_multilang.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/stl_helpers.hpp"
|
||||
#include "base/string_utils.hpp"
|
||||
|
||||
#include <atomic>
|
||||
#include <sstream>
|
||||
|
||||
namespace generator
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
using namespace feature;
|
||||
using std::ostringstream, std::string, std::string_view, std::vector;
|
||||
|
||||
namespace
|
||||
{
|
||||
uint64_t GenUniqueId()
|
||||
{
|
||||
static std::atomic<uint64_t> id;
|
||||
return id.fetch_add(1);
|
||||
}
|
||||
|
||||
vector<m2::PointD> MakePoly(m2::RectD const & rect)
|
||||
{
|
||||
return {rect.LeftBottom(), rect.RightBottom(), rect.RightTop(), rect.LeftTop(), rect.LeftBottom()};
|
||||
}
|
||||
|
||||
StringUtf8Multilang MakeName(string const & name, string const & lang)
|
||||
{
|
||||
StringUtf8Multilang res;
|
||||
res.AddString(lang, name);
|
||||
|
||||
// Names used for search depend on locale. Fill default name because we need to run tests with
|
||||
// different locales. If you do not need default name to be filled use
|
||||
// TestFeature::TestFeature(StringUtf8Multilang const & name).
|
||||
res.AddString("default", name);
|
||||
return res;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// TestFeature -------------------------------------------------------------------------------------
|
||||
TestFeature::TestFeature() : m_id(GenUniqueId()), m_center(0, 0), m_type(Type::Unknown)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
TestFeature::TestFeature(StringUtf8Multilang name)
|
||||
: m_id(GenUniqueId())
|
||||
, m_center(0, 0)
|
||||
, m_type(Type::Unknown)
|
||||
, m_names(std::move(name))
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
TestFeature::TestFeature(m2::PointD const & center, StringUtf8Multilang name)
|
||||
: m_id(GenUniqueId())
|
||||
, m_center(center)
|
||||
, m_type(Type::Point)
|
||||
, m_names(std::move(name))
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
TestFeature::TestFeature(m2::RectD const & boundary, StringUtf8Multilang name)
|
||||
: TestFeature(MakePoly(boundary), std::move(name), Type::Area)
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
TestFeature::TestFeature(vector<m2::PointD> geometry, StringUtf8Multilang name, Type type)
|
||||
: m_id(GenUniqueId())
|
||||
, m_center(0, 0)
|
||||
, m_geometry(std::move(geometry))
|
||||
, m_type(type)
|
||||
, m_names(std::move(name))
|
||||
{
|
||||
ASSERT(!m_geometry.empty(), ());
|
||||
Init();
|
||||
}
|
||||
|
||||
void TestFeature::Init()
|
||||
{
|
||||
m_metadata.Set(Metadata::FMD_TEST_ID, strings::to_string(m_id));
|
||||
}
|
||||
|
||||
bool TestFeature::Matches(FeatureType & feature) const
|
||||
{
|
||||
auto const sv = feature.GetMetadata(feature::Metadata::FMD_TEST_ID);
|
||||
if (sv.empty())
|
||||
return false;
|
||||
|
||||
uint64_t id;
|
||||
CHECK(strings::to_uint(sv, id), (sv));
|
||||
return id == m_id;
|
||||
}
|
||||
|
||||
void TestFeature::Serialize(FeatureBuilder & fb) const
|
||||
{
|
||||
using feature::Metadata;
|
||||
|
||||
// Iterate [1, FMD_COUNT). Absent types don't matter here.
|
||||
size_t i = 1;
|
||||
auto constexpr count = static_cast<size_t>(Metadata::EType::FMD_COUNT);
|
||||
for (; i < count; ++i)
|
||||
{
|
||||
auto const type = static_cast<Metadata::EType>(i);
|
||||
if (m_metadata.Has(type))
|
||||
fb.GetMetadata().Set(type, string(m_metadata.Get(type)));
|
||||
}
|
||||
|
||||
if (!m_geometry.empty())
|
||||
fb.AssignPoints(m_geometry);
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case Type::Point:
|
||||
{
|
||||
fb.SetCenter(m_center);
|
||||
break;
|
||||
}
|
||||
case Type::Line:
|
||||
{
|
||||
fb.SetLinear();
|
||||
break;
|
||||
}
|
||||
case Type::Area:
|
||||
{
|
||||
fb.SetArea();
|
||||
break;
|
||||
}
|
||||
case Type::Unknown: break;
|
||||
}
|
||||
|
||||
m_names.ForEach([&](int8_t langCode, string_view name)
|
||||
{
|
||||
if (!name.empty())
|
||||
fb.SetName(langCode, name);
|
||||
});
|
||||
|
||||
if (!m_postcode.empty())
|
||||
fb.GetParams().SetPostcode(m_postcode);
|
||||
}
|
||||
|
||||
// TestPlace -------------------------------------------------------------------------------------
|
||||
TestPlace::TestPlace(m2::PointD const & center, string const & name, string const & lang, uint32_t type,
|
||||
uint8_t rank /* = 0 */)
|
||||
: TestFeature(center, MakeName(name, lang))
|
||||
, m_type(type)
|
||||
, m_rank(rank)
|
||||
{}
|
||||
|
||||
TestPlace::TestPlace(m2::PointD const & center, StringUtf8Multilang const & name, uint32_t type, uint8_t rank)
|
||||
: TestFeature(center, name)
|
||||
, m_type(type)
|
||||
, m_rank(rank)
|
||||
{}
|
||||
|
||||
TestPlace::TestPlace(std::vector<m2::PointD> const & boundary, std::string const & name, std::string const & lang,
|
||||
uint32_t type, uint8_t rank)
|
||||
: TestFeature(boundary, MakeName(name, lang), Type::Area)
|
||||
, m_type(type)
|
||||
, m_rank(rank)
|
||||
{}
|
||||
|
||||
void TestPlace::Serialize(FeatureBuilder & fb) const
|
||||
{
|
||||
TestFeature::Serialize(fb);
|
||||
fb.AddType(m_type);
|
||||
fb.GetParams().rank = m_rank;
|
||||
}
|
||||
|
||||
string TestPlace::ToDebugString() const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "TestPlace { " << DebugPrint(m_names) << ", " << DebugPrint(m_center) << ", "
|
||||
<< classif().GetReadableObjectName(m_type) << ", " << int(m_rank) << " }";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
void TestPlace::SetType(base::StringIL const & e)
|
||||
{
|
||||
m_type = classif().GetTypeByPath(e);
|
||||
}
|
||||
|
||||
TestCountry::TestCountry(m2::PointD const & center, std::string const & name, std::string const & lang)
|
||||
: TestPlace(center, name, lang, classif().GetTypeByPath({"place", "country"}), 170 /* rank */)
|
||||
{
|
||||
// Default rank for Country with population ~ 1.0E7
|
||||
}
|
||||
|
||||
TestState::TestState(m2::PointD const & center, string const & name, string const & lang)
|
||||
: TestPlace(center, name, lang, classif().GetTypeByPath({"place", "state"}))
|
||||
{}
|
||||
|
||||
TestSea::TestSea(m2::PointD const & center, std::string const & name, std::string const & lang)
|
||||
: TestPlace(center, name, lang, classif().GetTypeByPath({"place", "sea"}))
|
||||
{}
|
||||
|
||||
uint32_t TestCity::GetCityType()
|
||||
{
|
||||
return classif().GetTypeByPath({"place", "city"});
|
||||
}
|
||||
|
||||
TestCity::TestCity(m2::PointD const & center, string const & name, string const & lang, uint8_t rank)
|
||||
: TestPlace(center, name, lang, GetCityType(), rank)
|
||||
{}
|
||||
|
||||
TestCity::TestCity(m2::PointD const & center, StringUtf8Multilang const & name, uint8_t rank)
|
||||
: TestPlace(center, name, GetCityType(), rank)
|
||||
{}
|
||||
|
||||
TestCity::TestCity(vector<m2::PointD> const & boundary, string const & name, string const & lang, uint8_t rank)
|
||||
: TestPlace(boundary, name, lang, GetCityType(), rank)
|
||||
{}
|
||||
|
||||
TestVillage::TestVillage(m2::PointD const & center, string const & name, string const & lang, uint8_t rank)
|
||||
: TestPlace(center, name, lang, classif().GetTypeByPath({"place", "village"}), rank)
|
||||
{}
|
||||
|
||||
TestSuburb::TestSuburb(m2::PointD const & center, string const & name, string const & lang)
|
||||
: TestPlace(center, name, lang, classif().GetTypeByPath({"place", "suburb"}))
|
||||
{}
|
||||
|
||||
// TestStreet --------------------------------------------------------------------------------------
|
||||
TestStreet::TestStreet(vector<m2::PointD> const & points, string const & name, string const & lang)
|
||||
: TestFeature(points, MakeName(name, lang), Type::Line)
|
||||
{
|
||||
SetType({"highway", "living_street"});
|
||||
}
|
||||
|
||||
TestStreet::TestStreet(vector<m2::PointD> const & points, StringUtf8Multilang const & name)
|
||||
: TestFeature(points, name, Type::Line)
|
||||
{
|
||||
SetType({"highway", "living_street"});
|
||||
}
|
||||
|
||||
void TestStreet::SetType(base::StringIL const & e)
|
||||
{
|
||||
m_highwayType = classif().GetTypeByPath(e);
|
||||
}
|
||||
|
||||
void TestStreet::Serialize(FeatureBuilder & fb) const
|
||||
{
|
||||
TestFeature::Serialize(fb);
|
||||
|
||||
fb.SetType(m_highwayType);
|
||||
|
||||
fb.GetParams().ref = m_roadNumber;
|
||||
}
|
||||
|
||||
string TestStreet::ToDebugString() const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "TestStreet [" << DebugPrint(m_names) << ", " << ::DebugPrint(m_geometry) << "]";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// TestSquare --------------------------------------------------------------------------------------
|
||||
TestSquare::TestSquare(m2::RectD const & rect, string const & name, string const & lang)
|
||||
: TestFeature(rect, MakeName(name, lang))
|
||||
{}
|
||||
|
||||
void TestSquare::Serialize(FeatureBuilder & fb) const
|
||||
{
|
||||
TestFeature::Serialize(fb);
|
||||
|
||||
auto const & classificator = classif();
|
||||
fb.SetType(classificator.GetTypeByPath({"place", "square"}));
|
||||
}
|
||||
|
||||
string TestSquare::ToDebugString() const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "TestSquare [" << DebugPrint(m_names) << "]";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// TestPOI -----------------------------------------------------------------------------------------
|
||||
TestPOI::TestPOI(m2::PointD const & center, string const & name, string const & lang)
|
||||
: TestFeature(center, MakeName(name, lang))
|
||||
{
|
||||
SetTypes({{"railway", "station"}});
|
||||
}
|
||||
|
||||
// static
|
||||
std::pair<TestPOI, FeatureID> TestPOI::AddWithEditor(osm::Editor & editor, MwmSet::MwmId const & mwmId,
|
||||
string const & enName, m2::PointD const & pt)
|
||||
{
|
||||
TestPOI poi(pt, enName, "en");
|
||||
|
||||
osm::EditableMapObject emo;
|
||||
editor.CreatePoint(classif().GetTypeByPath({"shop", "bakery"}), pt, mwmId, emo);
|
||||
|
||||
StringUtf8Multilang names;
|
||||
names.AddString(StringUtf8Multilang::GetLangIndex("en"), enName);
|
||||
emo.SetName(names);
|
||||
emo.SetTestId(poi.GetId());
|
||||
|
||||
editor.SaveEditedFeature(emo);
|
||||
return {poi, emo.GetID()};
|
||||
}
|
||||
|
||||
void TestPOI::Serialize(FeatureBuilder & fb) const
|
||||
{
|
||||
TestFeature::Serialize(fb);
|
||||
|
||||
for (uint32_t t : m_types)
|
||||
fb.AddType(t);
|
||||
|
||||
auto & params = fb.GetParams();
|
||||
if (!m_houseNumber.empty())
|
||||
params.AddHouseNumber(m_houseNumber);
|
||||
|
||||
if (!m_streetName.empty())
|
||||
params.SetStreet(m_streetName);
|
||||
}
|
||||
|
||||
string TestPOI::ToDebugString() const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "TestPOI [" << DebugPrint(m_names) << ", " << DebugPrint(m_center);
|
||||
if (!m_houseNumber.empty())
|
||||
os << ", " << m_houseNumber;
|
||||
if (!m_streetName.empty())
|
||||
os << ", " << m_streetName;
|
||||
os << "]";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
TypesHolder TestPOI::GetTypes() const
|
||||
{
|
||||
TypesHolder types;
|
||||
types.Assign(m_types.begin(), m_types.end());
|
||||
return types;
|
||||
}
|
||||
|
||||
void TestPOI::SetTypes(std::initializer_list<base::StringIL> const & types)
|
||||
{
|
||||
m_types.clear();
|
||||
auto const & c = classif();
|
||||
for (auto const & e : types)
|
||||
m_types.push_back(c.GetTypeByPath(e));
|
||||
}
|
||||
|
||||
// TestMultilingualPOI -----------------------------------------------------------------------------
|
||||
TestMultilingualPOI::TestMultilingualPOI(m2::PointD const & center, string const & defaultName,
|
||||
std::map<string, string> const & multilingualNames)
|
||||
: TestPOI(center, defaultName, "default")
|
||||
, m_multilingualNames(multilingualNames)
|
||||
{}
|
||||
|
||||
void TestMultilingualPOI::Serialize(FeatureBuilder & fb) const
|
||||
{
|
||||
TestPOI::Serialize(fb);
|
||||
|
||||
for (auto const & kv : m_multilingualNames)
|
||||
CHECK(fb.AddName(kv.first, kv.second), ("Can't set feature name:", kv.second, "(", kv.first, ")"));
|
||||
}
|
||||
|
||||
string TestMultilingualPOI::ToDebugString() const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "TestPOI [" << DebugPrint(m_names) << ", ";
|
||||
for (auto const & kv : m_multilingualNames)
|
||||
os << "( " << kv.second << ", " << kv.first << "), ";
|
||||
os << DebugPrint(m_center);
|
||||
if (!m_houseNumber.empty())
|
||||
os << ", " << m_houseNumber;
|
||||
if (!m_streetName.empty())
|
||||
os << ", " << m_streetName;
|
||||
os << "]";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// TestBuilding ------------------------------------------------------------------------------------
|
||||
TestBuilding::TestBuilding(m2::PointD const & center, string const & name, string const & houseNumber,
|
||||
string const & lang)
|
||||
: TestFeature(center, MakeName(name, lang))
|
||||
, m_houseNumber(houseNumber)
|
||||
{}
|
||||
|
||||
TestBuilding::TestBuilding(m2::PointD const & center, string const & name, string const & houseNumber,
|
||||
string_view street, string const & lang)
|
||||
: TestFeature(center, MakeName(name, lang))
|
||||
, m_houseNumber(houseNumber)
|
||||
{
|
||||
m_addr.Set(AddressData::Type::Street, street);
|
||||
}
|
||||
|
||||
TestBuilding::TestBuilding(m2::RectD const & boundary, string const & name, string const & houseNumber,
|
||||
string_view street, string const & lang)
|
||||
: TestFeature(boundary, MakeName(name, lang))
|
||||
, m_houseNumber(houseNumber)
|
||||
{
|
||||
m_addr.Set(AddressData::Type::Street, street);
|
||||
}
|
||||
|
||||
void TestBuilding::Serialize(FeatureBuilder & fb) const
|
||||
{
|
||||
TestFeature::Serialize(fb);
|
||||
|
||||
auto & params = fb.GetParams();
|
||||
if (!m_houseNumber.empty())
|
||||
params.AddHouseNumber(m_houseNumber);
|
||||
|
||||
params.SetAddress(AddressData(m_addr));
|
||||
|
||||
if (m_type == 0)
|
||||
fb.AddType(classif().GetTypeByPath({"building"}));
|
||||
else
|
||||
fb.AddType(m_type);
|
||||
}
|
||||
|
||||
string TestBuilding::ToDebugString() const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "TestBuilding [" << DebugPrint(m_names) << ", " << m_houseNumber << ", " << DebugPrint(m_center) << "]";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// TestPark ----------------------------------------------------------------------------------------
|
||||
TestPark::TestPark(vector<m2::PointD> const & boundary, string const & name, string const & lang)
|
||||
: TestFeature(boundary, MakeName(name, lang), Type::Area)
|
||||
{}
|
||||
|
||||
void TestPark::Serialize(FeatureBuilder & fb) const
|
||||
{
|
||||
TestFeature::Serialize(fb);
|
||||
|
||||
auto const & classificator = classif();
|
||||
fb.AddType(classificator.GetTypeByPath({"leisure", "park"}));
|
||||
}
|
||||
|
||||
string TestPark::ToDebugString() const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "TestPark [" << DebugPrint(m_names) << ", "
|
||||
<< "]";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// TestRoad ----------------------------------------------------------------------------------------
|
||||
TestRoad::TestRoad(vector<m2::PointD> const & points, string const & name, string const & lang)
|
||||
: TestFeature(points, MakeName(name, lang), Type::Line)
|
||||
{}
|
||||
|
||||
void TestRoad::Serialize(FeatureBuilder & fb) const
|
||||
{
|
||||
TestFeature::Serialize(fb);
|
||||
|
||||
auto const & classificator = classif();
|
||||
fb.AddType(classificator.GetTypeByPath({"highway", "road"}));
|
||||
}
|
||||
|
||||
string TestRoad::ToDebugString() const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "TestRoad [" << DebugPrint(m_names) << "]";
|
||||
return os.str();
|
||||
}
|
||||
|
||||
// Functions ---------------------------------------------------------------------------------------
|
||||
string DebugPrint(TestFeature const & feature)
|
||||
{
|
||||
return feature.ToDebugString();
|
||||
}
|
||||
} // namespace tests_support
|
||||
} // namespace generator
|
||||
254
generator/generator_tests_support/test_feature.hpp
Normal file
254
generator/generator_tests_support/test_feature.hpp
Normal file
|
|
@ -0,0 +1,254 @@
|
|||
#pragma once
|
||||
|
||||
#include "indexer/feature_data.hpp"
|
||||
#include "indexer/feature_decl.hpp"
|
||||
#include "indexer/feature_meta.hpp"
|
||||
#include "indexer/mwm_set.hpp"
|
||||
|
||||
#include "coding/string_utf8_multilang.hpp"
|
||||
|
||||
#include "geometry/point2d.hpp"
|
||||
#include "geometry/rect2d.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class FeatureType;
|
||||
namespace feature
|
||||
{
|
||||
class FeatureBuilder;
|
||||
}
|
||||
namespace osm
|
||||
{
|
||||
class Editor;
|
||||
}
|
||||
|
||||
namespace generator
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
class TestFeature
|
||||
{
|
||||
public:
|
||||
virtual ~TestFeature() = default;
|
||||
|
||||
bool Matches(FeatureType & feature) const;
|
||||
void SetPostcode(std::string const & postcode) { m_postcode = postcode; }
|
||||
uint64_t GetId() const { return m_id; }
|
||||
|
||||
std::string_view GetName(std::string_view lang) const
|
||||
{
|
||||
std::string_view res;
|
||||
if (m_names.GetString(lang, res))
|
||||
return res;
|
||||
return {};
|
||||
}
|
||||
|
||||
m2::PointD const & GetCenter() const { return m_center; }
|
||||
|
||||
feature::Metadata & GetMetadata() { return m_metadata; }
|
||||
|
||||
virtual void Serialize(feature::FeatureBuilder & fb) const;
|
||||
virtual std::string ToDebugString() const = 0;
|
||||
|
||||
protected:
|
||||
enum class Type
|
||||
{
|
||||
Point,
|
||||
Line,
|
||||
Area,
|
||||
Unknown
|
||||
};
|
||||
|
||||
TestFeature();
|
||||
explicit TestFeature(StringUtf8Multilang name);
|
||||
TestFeature(m2::PointD const & center, StringUtf8Multilang name);
|
||||
TestFeature(m2::RectD const & boundary, StringUtf8Multilang name);
|
||||
TestFeature(std::vector<m2::PointD> geometry, StringUtf8Multilang name, Type type);
|
||||
|
||||
uint64_t const m_id;
|
||||
m2::PointD const m_center;
|
||||
std::vector<m2::PointD> const m_geometry;
|
||||
Type const m_type;
|
||||
StringUtf8Multilang m_names;
|
||||
std::string m_postcode;
|
||||
feature::Metadata m_metadata;
|
||||
|
||||
private:
|
||||
void Init();
|
||||
};
|
||||
|
||||
class TestPlace : public TestFeature
|
||||
{
|
||||
public:
|
||||
TestPlace(m2::PointD const & center, std::string const & name, std::string const & lang, uint32_t type,
|
||||
uint8_t rank = 0);
|
||||
TestPlace(m2::PointD const & center, StringUtf8Multilang const & name, uint32_t type, uint8_t rank);
|
||||
TestPlace(std::vector<m2::PointD> const & boundary, std::string const & name, std::string const & lang, uint32_t type,
|
||||
uint8_t rank);
|
||||
|
||||
// TestFeature overrides:
|
||||
void Serialize(feature::FeatureBuilder & fb) const override;
|
||||
std::string ToDebugString() const override;
|
||||
|
||||
void SetType(base::StringIL const & e);
|
||||
|
||||
protected:
|
||||
uint32_t m_type;
|
||||
uint8_t const m_rank;
|
||||
};
|
||||
|
||||
class TestCountry : public TestPlace
|
||||
{
|
||||
public:
|
||||
TestCountry(m2::PointD const & center, std::string const & name, std::string const & lang);
|
||||
};
|
||||
|
||||
class TestState : public TestPlace
|
||||
{
|
||||
public:
|
||||
TestState(m2::PointD const & center, std::string const & name, std::string const & lang);
|
||||
};
|
||||
|
||||
// A feature that is big enough for World.mwm but is not a locality.
|
||||
class TestSea : public TestPlace
|
||||
{
|
||||
public:
|
||||
TestSea(m2::PointD const & center, std::string const & name, std::string const & lang);
|
||||
};
|
||||
|
||||
class TestCity : public TestPlace
|
||||
{
|
||||
static uint32_t GetCityType();
|
||||
|
||||
public:
|
||||
TestCity(m2::PointD const & center, std::string const & name, std::string const & lang, uint8_t rank);
|
||||
TestCity(m2::PointD const & center, StringUtf8Multilang const & name, uint8_t rank);
|
||||
TestCity(std::vector<m2::PointD> const & boundary, std::string const & name, std::string const & lang, uint8_t rank);
|
||||
};
|
||||
|
||||
class TestVillage : public TestPlace
|
||||
{
|
||||
public:
|
||||
TestVillage(m2::PointD const & center, std::string const & name, std::string const & lang, uint8_t rank);
|
||||
};
|
||||
|
||||
class TestSuburb : public TestPlace
|
||||
{
|
||||
public:
|
||||
TestSuburb(m2::PointD const & center, std::string const & name, std::string const & lang);
|
||||
};
|
||||
|
||||
class TestStreet : public TestFeature
|
||||
{
|
||||
public:
|
||||
TestStreet(std::vector<m2::PointD> const & points, std::string const & name, std::string const & lang);
|
||||
TestStreet(std::vector<m2::PointD> const & points, StringUtf8Multilang const & name);
|
||||
|
||||
void SetType(base::StringIL const & e);
|
||||
void SetRoadNumber(std::string const & roadNumber) { m_roadNumber = roadNumber; }
|
||||
|
||||
// TestFeature overrides:
|
||||
void Serialize(feature::FeatureBuilder & fb) const override;
|
||||
std::string ToDebugString() const override;
|
||||
|
||||
private:
|
||||
uint32_t m_highwayType;
|
||||
std::string m_roadNumber;
|
||||
};
|
||||
|
||||
class TestSquare : public TestFeature
|
||||
{
|
||||
public:
|
||||
TestSquare(m2::RectD const & rect, std::string const & name, std::string const & lang);
|
||||
|
||||
// TestFeature overrides:
|
||||
void Serialize(feature::FeatureBuilder & fb) const override;
|
||||
std::string ToDebugString() const override;
|
||||
};
|
||||
|
||||
class TestPOI : public TestFeature
|
||||
{
|
||||
public:
|
||||
TestPOI(m2::PointD const & center, std::string const & name, std::string const & lang);
|
||||
|
||||
static std::pair<TestPOI, FeatureID> AddWithEditor(osm::Editor & editor, MwmSet::MwmId const & mwmId,
|
||||
std::string const & enName, m2::PointD const & pt);
|
||||
|
||||
// TestFeature overrides:
|
||||
void Serialize(feature::FeatureBuilder & fb) const override;
|
||||
std::string ToDebugString() const override;
|
||||
|
||||
feature::TypesHolder GetTypes() const;
|
||||
void SetHouseNumber(std::string const & houseNumber) { m_houseNumber = houseNumber; }
|
||||
void SetStreetName(std::string_view name) { m_streetName = name; }
|
||||
|
||||
void SetTypes(std::initializer_list<uint32_t> const & types) { m_types.assign(types); }
|
||||
void SetTypes(std::initializer_list<base::StringIL> const & types);
|
||||
|
||||
protected:
|
||||
std::string m_houseNumber;
|
||||
std::string m_streetName;
|
||||
std::vector<uint32_t> m_types;
|
||||
};
|
||||
|
||||
class TestMultilingualPOI : public TestPOI
|
||||
{
|
||||
public:
|
||||
TestMultilingualPOI(m2::PointD const & center, std::string const & defaultName,
|
||||
std::map<std::string, std::string> const & multilingualNames);
|
||||
// TestFeature overrides:
|
||||
void Serialize(feature::FeatureBuilder & fb) const override;
|
||||
std::string ToDebugString() const override;
|
||||
|
||||
private:
|
||||
std::map<std::string, std::string> m_multilingualNames;
|
||||
};
|
||||
|
||||
class TestBuilding : public TestFeature
|
||||
{
|
||||
public:
|
||||
TestBuilding(m2::PointD const & center, std::string const & name, std::string const & houseNumber,
|
||||
std::string const & lang);
|
||||
TestBuilding(m2::PointD const & center, std::string const & name, std::string const & houseNumber,
|
||||
std::string_view street, std::string const & lang);
|
||||
TestBuilding(m2::RectD const & boundary, std::string const & name, std::string const & houseNumber,
|
||||
std::string_view street, std::string const & lang);
|
||||
|
||||
// TestFeature overrides:
|
||||
void Serialize(feature::FeatureBuilder & fb) const override;
|
||||
std::string ToDebugString() const override;
|
||||
|
||||
void SetType(uint32_t type) { m_type = type; }
|
||||
void SetPlace(std::string_view place) { m_addr.Set(feature::AddressData::Type::Place, place); }
|
||||
|
||||
private:
|
||||
std::string m_houseNumber;
|
||||
feature::AddressData m_addr;
|
||||
uint32_t m_type = 0;
|
||||
};
|
||||
|
||||
class TestPark : public TestFeature
|
||||
{
|
||||
public:
|
||||
TestPark(std::vector<m2::PointD> const & boundary, std::string const & name, std::string const & lang);
|
||||
|
||||
// TestFeature overrides:
|
||||
void Serialize(feature::FeatureBuilder & fb) const override;
|
||||
std::string ToDebugString() const override;
|
||||
};
|
||||
|
||||
class TestRoad : public TestFeature
|
||||
{
|
||||
public:
|
||||
TestRoad(std::vector<m2::PointD> const & points, std::string const & name, std::string const & lang);
|
||||
|
||||
// TestFeature overrides:
|
||||
void Serialize(feature::FeatureBuilder & fb) const override;
|
||||
std::string ToDebugString() const override;
|
||||
};
|
||||
|
||||
std::string DebugPrint(TestFeature const & feature);
|
||||
} // namespace tests_support
|
||||
} // namespace generator
|
||||
160
generator/generator_tests_support/test_generator.cpp
Normal file
160
generator/generator_tests_support/test_generator.cpp
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
#include "test_generator.hpp"
|
||||
|
||||
#include "generator/borders.hpp"
|
||||
#include "generator/camera_info_collector.hpp"
|
||||
#include "generator/feature_sorter.hpp"
|
||||
#include "generator/osm_source.hpp"
|
||||
#include "generator/raw_generator.hpp"
|
||||
|
||||
#include "generator/maxspeeds_builder.hpp"
|
||||
#include "generator/restriction_generator.hpp"
|
||||
#include "generator/road_access_generator.hpp"
|
||||
#include "generator/routing_index_generator.hpp"
|
||||
#include "generator/search_index_builder.hpp"
|
||||
|
||||
#include "indexer/classificator_loader.hpp"
|
||||
#include "indexer/features_offsets_table.hpp"
|
||||
#include "indexer/index_builder.hpp"
|
||||
#include "indexer/map_style_reader.hpp"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
namespace generator
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
|
||||
char const * TestRawGenerator::kWikidataFilename = "wiki_urls.csv";
|
||||
|
||||
bool MakeFakeBordersFile(std::string const & intemediatePath, std::string const & filename)
|
||||
{
|
||||
auto const borderPath = base::JoinPath(intemediatePath, BORDERS_DIR);
|
||||
auto & platform = GetPlatform();
|
||||
auto const code = platform.MkDir(borderPath);
|
||||
if (code != Platform::EError::ERR_OK && code != Platform::EError::ERR_FILE_ALREADY_EXISTS)
|
||||
return false;
|
||||
|
||||
std::vector<m2::PointD> points = {{-180.0, -90.0}, {180.0, -90.0}, {180.0, 90.0}, {-180.0, 90.0}, {-180.0, -90.0}};
|
||||
borders::DumpBorderToPolyFile(borderPath, filename, {m2::RegionD{std::move(points)}});
|
||||
return true;
|
||||
}
|
||||
|
||||
TestRawGenerator::TestRawGenerator()
|
||||
{
|
||||
GetStyleReader().SetCurrentStyle(MapStyleMerged);
|
||||
classificator::Load();
|
||||
|
||||
SetupTmpFolder("./raw_generator");
|
||||
}
|
||||
|
||||
TestRawGenerator::~TestRawGenerator()
|
||||
{
|
||||
UNUSED_VALUE(Platform::RmDirRecursively(GetTmpPath()));
|
||||
}
|
||||
|
||||
void TestRawGenerator::SetupTmpFolder(std::string const & tmpPath)
|
||||
{
|
||||
m_genInfo.m_cacheDir = m_genInfo.m_intermediateDir = tmpPath;
|
||||
UNUSED_VALUE(Platform::RmDirRecursively(tmpPath));
|
||||
CHECK(Platform::MkDirChecked(tmpPath), ());
|
||||
}
|
||||
|
||||
void TestRawGenerator::BuildFB(std::string const & osmFilePath, std::string const & mwmName,
|
||||
bool makeWorld /* = false */)
|
||||
{
|
||||
m_genInfo.m_nodeStorageType = feature::GenerateInfo::NodeStorageType::Index;
|
||||
m_genInfo.m_osmFileName = osmFilePath;
|
||||
m_genInfo.m_osmFileType = feature::GenerateInfo::OsmSourceType::XML;
|
||||
|
||||
CHECK(GenerateIntermediateData(m_genInfo), ());
|
||||
|
||||
// CHECK(MakeFakeBordersFile(GetTmpPath(), mwmName), ());
|
||||
|
||||
m_genInfo.m_tmpDir = m_genInfo.m_targetDir = GetTmpPath();
|
||||
m_genInfo.m_fileName = mwmName;
|
||||
m_genInfo.m_idToWikidataFilename = m_genInfo.GetIntermediateFileName(kWikidataFilename);
|
||||
|
||||
m_genInfo.m_citiesBoundariesFilename = GetCitiesBoundariesPath();
|
||||
|
||||
RawGenerator rawGenerator(m_genInfo);
|
||||
rawGenerator.ForceReloadCache();
|
||||
|
||||
if (makeWorld)
|
||||
rawGenerator.GenerateWorld(false /* cutBordersByWater */);
|
||||
rawGenerator.GenerateCountries(true /* isTests */);
|
||||
|
||||
CHECK(rawGenerator.Execute(), ("Error generating", mwmName));
|
||||
}
|
||||
|
||||
void TestRawGenerator::BuildFeatures(std::string const & mwmName)
|
||||
{
|
||||
using namespace feature;
|
||||
auto const type = IsWorld(mwmName) ? DataHeader::MapType::World : DataHeader::MapType::Country;
|
||||
CHECK(GenerateFinalFeatures(m_genInfo, mwmName, type), ());
|
||||
|
||||
std::string const mwmPath = GetMwmPath(mwmName);
|
||||
|
||||
CHECK(BuildOffsetsTable(mwmPath), ());
|
||||
CHECK(indexer::BuildIndexFromDataFile(mwmPath, mwmPath), ());
|
||||
}
|
||||
|
||||
void TestRawGenerator::BuildSearch(std::string const & mwmName)
|
||||
{
|
||||
CHECK(indexer::BuildSearchIndexFromDataFile(mwmName, m_genInfo, true /* forceRebuild */, 1 /* threadsCount */), ());
|
||||
|
||||
if (IsWorld(mwmName))
|
||||
{
|
||||
generator::OsmIdToBoundariesTable table;
|
||||
CHECK(generator::DeserializeBoundariesTable(GetCitiesBoundariesPath(), table), ());
|
||||
CHECK(generator::BuildCitiesBoundaries(GetMwmPath(mwmName), table), ());
|
||||
}
|
||||
}
|
||||
|
||||
void TestRawGenerator::BuildRouting(std::string const & mwmName, std::string const & countryName)
|
||||
{
|
||||
using namespace routing_builder;
|
||||
CountryParentNameGetterFn const parentGetter = [&countryName](std::string const & name)
|
||||
{ return (name != countryName ? countryName : std::string()); };
|
||||
|
||||
std::string const filePath = GetMwmPath(mwmName);
|
||||
std::string const osmToFeatureFilename = filePath + OSM2FEATURE_FILE_EXTENSION;
|
||||
|
||||
routing_builder::BuildRoutingIndex(filePath, countryName, parentGetter);
|
||||
|
||||
auto osm2feature = routing::CreateWay2FeatureMapper(filePath, osmToFeatureFilename);
|
||||
BuildRoadAccessInfo(filePath, m_genInfo.GetIntermediateFileName(ROAD_ACCESS_FILENAME), *osm2feature);
|
||||
BuildCamerasInfo(filePath, m_genInfo.GetIntermediateFileName(CAMERAS_TO_WAYS_FILENAME), osmToFeatureFilename);
|
||||
|
||||
auto routingGraph = CreateIndexGraph(filePath, countryName, parentGetter);
|
||||
CHECK(routingGraph, ());
|
||||
|
||||
BuildRoadRestrictions(*routingGraph, filePath, m_genInfo.GetIntermediateFileName(RESTRICTIONS_FILENAME),
|
||||
osmToFeatureFilename);
|
||||
BuildMaxspeedsSection(routingGraph.get(), filePath, osmToFeatureFilename,
|
||||
m_genInfo.GetIntermediateFileName(MAXSPEEDS_FILENAME));
|
||||
}
|
||||
|
||||
routing::FeatureIdToOsmId TestRawGenerator::LoadFID2OsmID(std::string const & mwmName)
|
||||
{
|
||||
routing::FeatureIdToOsmId ids;
|
||||
routing::ParseWaysFeatureIdToOsmIdMapping(GetMwmPath(mwmName) + OSM2FEATURE_FILE_EXTENSION, ids);
|
||||
return ids;
|
||||
}
|
||||
|
||||
std::string TestRawGenerator::GetMwmPath(std::string const & mwmName) const
|
||||
{
|
||||
return m_genInfo.GetTargetFileName(mwmName, DATA_FILE_EXTENSION);
|
||||
}
|
||||
|
||||
std::string TestRawGenerator::GetCitiesBoundariesPath() const
|
||||
{
|
||||
return m_genInfo.GetTmpFileName(CITIES_BOUNDARIES_FILE_TAG, ".bin");
|
||||
}
|
||||
|
||||
bool TestRawGenerator::IsWorld(std::string const & mwmName) const
|
||||
{
|
||||
return (mwmName == WORLD_FILE_NAME);
|
||||
}
|
||||
|
||||
} // namespace tests_support
|
||||
} // namespace generator
|
||||
64
generator/generator_tests_support/test_generator.hpp
Normal file
64
generator/generator_tests_support/test_generator.hpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#pragma once
|
||||
|
||||
#include "generator/feature_builder.hpp"
|
||||
#include "generator/generate_info.hpp"
|
||||
#include "generator/routing_helpers.hpp"
|
||||
|
||||
#include "indexer/data_source.hpp"
|
||||
|
||||
namespace generator
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
|
||||
bool MakeFakeBordersFile(std::string const & intemediatePath, std::string const & fileName);
|
||||
|
||||
class TestRawGenerator
|
||||
{
|
||||
feature::GenerateInfo m_genInfo;
|
||||
std::string const & GetTmpPath() const { return m_genInfo.m_cacheDir; }
|
||||
|
||||
public:
|
||||
TestRawGenerator();
|
||||
~TestRawGenerator();
|
||||
|
||||
void SetupTmpFolder(std::string const & tmpPath);
|
||||
|
||||
void BuildFB(std::string const & osmFilePath, std::string const & mwmName, bool makeWorld = false);
|
||||
void BuildFeatures(std::string const & mwmName);
|
||||
void BuildSearch(std::string const & mwmName);
|
||||
void BuildRouting(std::string const & mwmName, std::string const & countryName);
|
||||
|
||||
routing::FeatureIdToOsmId LoadFID2OsmID(std::string const & mwmName);
|
||||
|
||||
template <class FnT>
|
||||
void ForEachFB(std::string const & mwmName, FnT && fn)
|
||||
{
|
||||
using namespace feature;
|
||||
ForEachFeatureRawFormat(m_genInfo.GetTmpFileName(mwmName), [&fn](FeatureBuilder const & fb, uint64_t) { fn(fb); });
|
||||
}
|
||||
|
||||
template <class FnT>
|
||||
void ForEachFeature(std::string const & mwmName, FnT && fn)
|
||||
{
|
||||
FrozenDataSource dataSource;
|
||||
auto const res = dataSource.RegisterMap(platform::LocalCountryFile::MakeTemporary(GetMwmPath(mwmName)));
|
||||
CHECK_EQUAL(res.second, MwmSet::RegResult::Success, ());
|
||||
|
||||
FeaturesLoaderGuard guard(dataSource, res.first);
|
||||
uint32_t const count = guard.GetNumFeatures();
|
||||
for (uint32_t id = 0; id < count; ++id)
|
||||
fn(guard.GetFeatureByIndex(id));
|
||||
}
|
||||
|
||||
std::string GetMwmPath(std::string const & mwmName) const;
|
||||
std::string GetCitiesBoundariesPath() const;
|
||||
|
||||
feature::GenerateInfo & GetGenInfo() { return m_genInfo; }
|
||||
bool IsWorld(std::string const & mwmName) const;
|
||||
|
||||
static char const * kWikidataFilename;
|
||||
};
|
||||
|
||||
} // namespace tests_support
|
||||
} // namespace generator
|
||||
190
generator/generator_tests_support/test_mwm_builder.cpp
Normal file
190
generator/generator_tests_support/test_mwm_builder.cpp
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
#include "generator/generator_tests_support/test_mwm_builder.hpp"
|
||||
|
||||
#include "generator/centers_table_builder.hpp"
|
||||
#include "generator/cities_ids_builder.hpp"
|
||||
#include "generator/feature_builder.hpp"
|
||||
#include "generator/feature_generator.hpp"
|
||||
#include "generator/feature_merger.hpp"
|
||||
#include "generator/feature_sorter.hpp"
|
||||
#include "generator/generator_tests_support/test_feature.hpp"
|
||||
#include "generator/search_index_builder.hpp"
|
||||
|
||||
#include "indexer/city_boundary.hpp"
|
||||
#include "indexer/data_header.hpp"
|
||||
#include "indexer/feature_meta.hpp"
|
||||
#include "indexer/features_offsets_table.hpp"
|
||||
#include "indexer/ftypes_matcher.hpp"
|
||||
#include "indexer/index_builder.hpp"
|
||||
#include "indexer/rank_table.hpp"
|
||||
|
||||
#include "storage/country_info_getter.hpp"
|
||||
|
||||
#include "platform/local_country_file.hpp"
|
||||
|
||||
#include "coding/internal/file_data.hpp"
|
||||
|
||||
#include "base/macros.hpp"
|
||||
#include "base/string_utils.hpp"
|
||||
|
||||
#include "defines.hpp"
|
||||
|
||||
namespace generator
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
using namespace feature;
|
||||
using std::string, std::vector;
|
||||
|
||||
namespace
|
||||
{
|
||||
bool WriteRegionDataForTests(string const & path, vector<string> const & languages)
|
||||
{
|
||||
try
|
||||
{
|
||||
FilesContainerW writer(path, FileWriter::OP_WRITE_EXISTING);
|
||||
RegionData regionData;
|
||||
regionData.SetLanguages(languages);
|
||||
auto w = writer.GetWriter(REGION_INFO_FILE_TAG);
|
||||
regionData.Serialize(*w);
|
||||
}
|
||||
catch (Writer::Exception const & e)
|
||||
{
|
||||
LOG(LERROR, ("Error writing file:", e.Msg()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TestMwmBuilder::TestMwmBuilder(platform::LocalCountryFile & file, DataHeader::MapType type, uint32_t version)
|
||||
: m_file(file)
|
||||
, m_type(type)
|
||||
, m_collector(std::make_unique<FeaturesCollector>(m_file.GetPath(MapFileType::Map) + EXTENSION_TMP))
|
||||
, m_version(version)
|
||||
{}
|
||||
|
||||
TestMwmBuilder::~TestMwmBuilder()
|
||||
{
|
||||
if (m_collector)
|
||||
Finish();
|
||||
}
|
||||
|
||||
void TestMwmBuilder::Add(TestFeature const & feature)
|
||||
{
|
||||
FeatureBuilder fb;
|
||||
feature.Serialize(fb);
|
||||
CHECK(Add(fb), (fb));
|
||||
}
|
||||
|
||||
void TestMwmBuilder::AddSafe(TestFeature const & feature)
|
||||
{
|
||||
FeatureBuilder fb;
|
||||
feature.Serialize(fb);
|
||||
(void)Add(fb);
|
||||
}
|
||||
|
||||
bool TestMwmBuilder::Add(FeatureBuilder & fb)
|
||||
{
|
||||
CHECK(m_collector, ("It's not possible to add features after call to Finish()."));
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case DataHeader::MapType::Country:
|
||||
if (!feature::PreprocessForCountryMap(fb))
|
||||
return false;
|
||||
break;
|
||||
case DataHeader::MapType::World:
|
||||
if (!feature::PreprocessForWorldMap(fb))
|
||||
return false;
|
||||
break;
|
||||
case DataHeader::MapType::WorldCoasts: CHECK(false, ("Coasts are not supported in test builder")); break;
|
||||
}
|
||||
|
||||
auto const & isCityTownOrVillage = ftypes::IsCityTownOrVillageChecker::Instance();
|
||||
if (isCityTownOrVillage(fb.GetTypes()) && fb.GetGeomType() == GeomType::Area)
|
||||
{
|
||||
auto const & metadata = fb.GetMetadata();
|
||||
uint64_t testId;
|
||||
CHECK(strings::to_uint(metadata.Get(Metadata::FMD_TEST_ID), testId), ());
|
||||
m_boundariesTable.Append(testId, indexer::CityBoundary(fb.GetOuterGeometry()));
|
||||
|
||||
fb.SetCenter(fb.GetGeometryCenter());
|
||||
}
|
||||
|
||||
if (!fb.RemoveInvalidTypes() || !fb.PreSerializeAndRemoveUselessNamesForIntermediate())
|
||||
{
|
||||
LOG(LWARNING, ("No types."));
|
||||
return false;
|
||||
}
|
||||
|
||||
m_collector->Collect(fb);
|
||||
return true;
|
||||
}
|
||||
|
||||
void TestMwmBuilder::SetPostcodesData(string const & postcodesPath, indexer::PostcodePointsDatasetType postcodesType,
|
||||
std::shared_ptr<storage::CountryInfoGetter> const & countryInfoGetter)
|
||||
{
|
||||
m_postcodesPath = postcodesPath;
|
||||
m_postcodesType = postcodesType;
|
||||
m_postcodesCountryInfoGetter = countryInfoGetter;
|
||||
}
|
||||
|
||||
void TestMwmBuilder::SetMwmLanguages(vector<string> const & languages)
|
||||
{
|
||||
m_languages = languages;
|
||||
}
|
||||
|
||||
void TestMwmBuilder::Finish()
|
||||
{
|
||||
CHECK(m_collector, ("Finish() already was called."));
|
||||
|
||||
string const tmpFilePath = m_collector->GetFilePath();
|
||||
m_collector.reset();
|
||||
|
||||
GenerateInfo info;
|
||||
info.m_targetDir = m_file.GetDirectory();
|
||||
info.m_tmpDir = m_file.GetDirectory();
|
||||
info.m_intermediateDir = m_file.GetDirectory();
|
||||
info.m_versionDate = static_cast<uint32_t>(base::YYMMDDToSecondsSinceEpoch(m_version));
|
||||
CHECK(GenerateFinalFeatures(info, m_file.GetCountryFile().GetName(), m_type), ("Can't sort features."));
|
||||
|
||||
CHECK(base::DeleteFileX(tmpFilePath), ());
|
||||
|
||||
string const path = m_file.GetPath(MapFileType::Map);
|
||||
UNUSED_VALUE(base::DeleteFileX(path + OSM2FEATURE_FILE_EXTENSION));
|
||||
|
||||
CHECK(BuildOffsetsTable(path), ("Can't build feature offsets table."));
|
||||
|
||||
CHECK(indexer::BuildIndexFromDataFile(path, path), ("Can't build geometry index."));
|
||||
|
||||
CHECK(indexer::BuildSearchIndexFromDataFile(m_file.GetCountryName(), info, true /* forceRebuild */,
|
||||
1 /* threadsCount */),
|
||||
("Can't build search index."));
|
||||
|
||||
if (!m_postcodesPath.empty() && m_postcodesCountryInfoGetter)
|
||||
{
|
||||
CHECK(indexer::BuildPostcodePointsWithInfoGetter(m_file.GetDirectory(), m_file.GetCountryName(), m_postcodesType,
|
||||
m_postcodesPath, true /* forceRebuild */,
|
||||
*m_postcodesCountryInfoGetter),
|
||||
("Can't build postcodes section."));
|
||||
}
|
||||
|
||||
UNUSED_VALUE(base::DeleteFileX(path + TEMP_ADDR_EXTENSION));
|
||||
|
||||
if (m_type == DataHeader::MapType::World)
|
||||
{
|
||||
CHECK(generator::BuildCitiesBoundariesForTesting(path, m_boundariesTable), ());
|
||||
CHECK(generator::BuildCitiesIdsForTesting(path), ());
|
||||
}
|
||||
|
||||
CHECK(indexer::BuildCentersTableFromDataFile(path, true /* forceRebuild */), ("Can't build centers table."));
|
||||
|
||||
CHECK(search::SearchRankTableBuilder::CreateIfNotExists(path), ());
|
||||
|
||||
if (!m_languages.empty())
|
||||
CHECK(WriteRegionDataForTests(path, m_languages), ());
|
||||
|
||||
m_file.SyncWithDisk();
|
||||
}
|
||||
} // namespace tests_support
|
||||
} // namespace generator
|
||||
66
generator/generator_tests_support/test_mwm_builder.hpp
Normal file
66
generator/generator_tests_support/test_mwm_builder.hpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#pragma once
|
||||
|
||||
#include "generator/cities_boundaries_builder.hpp"
|
||||
#include "generator/postcode_points_builder.hpp"
|
||||
|
||||
#include "indexer/data_header.hpp"
|
||||
|
||||
#include "base/timer.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace feature
|
||||
{
|
||||
class FeaturesCollector;
|
||||
class FeatureBuilder;
|
||||
} // namespace feature
|
||||
namespace platform
|
||||
{
|
||||
class LocalCountryFile;
|
||||
}
|
||||
namespace storage
|
||||
{
|
||||
class CountryInfoGetter;
|
||||
}
|
||||
namespace generator
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
class TestFeature;
|
||||
|
||||
class TestMwmBuilder
|
||||
{
|
||||
public:
|
||||
TestMwmBuilder(platform::LocalCountryFile & file, feature::DataHeader::MapType type,
|
||||
uint32_t version = base::GenerateYYMMDD(base::SecondsSinceEpoch()));
|
||||
|
||||
~TestMwmBuilder();
|
||||
|
||||
void Add(TestFeature const & feature);
|
||||
void AddSafe(TestFeature const & feature);
|
||||
bool Add(feature::FeatureBuilder & fb);
|
||||
|
||||
void SetPostcodesData(std::string const & postcodesPath, indexer::PostcodePointsDatasetType postcodesType,
|
||||
std::shared_ptr<storage::CountryInfoGetter> const & countryInfoGetter);
|
||||
|
||||
void SetMwmLanguages(std::vector<std::string> const & languages);
|
||||
|
||||
void Finish();
|
||||
|
||||
private:
|
||||
platform::LocalCountryFile & m_file;
|
||||
feature::DataHeader::MapType m_type;
|
||||
std::vector<std::string> m_languages;
|
||||
std::unique_ptr<feature::FeaturesCollector> m_collector;
|
||||
TestIdToBoundariesTable m_boundariesTable;
|
||||
|
||||
std::shared_ptr<storage::CountryInfoGetter> m_postcodesCountryInfoGetter;
|
||||
std::string m_postcodesPath;
|
||||
indexer::PostcodePointsDatasetType m_postcodesType;
|
||||
|
||||
uint32_t m_version = 0;
|
||||
};
|
||||
} // namespace tests_support
|
||||
} // namespace generator
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#include "generator/generator_tests_support/test_with_classificator.hpp"
|
||||
|
||||
#include "indexer/classificator_loader.hpp"
|
||||
#include "indexer/map_style.hpp"
|
||||
#include "indexer/map_style_reader.hpp"
|
||||
|
||||
namespace generator
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
TestWithClassificator::TestWithClassificator()
|
||||
{
|
||||
GetStyleReader().SetCurrentStyle(MapStyleMerged);
|
||||
classificator::Load();
|
||||
}
|
||||
} // namespace tests_support
|
||||
} // namespace generator
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
namespace generator
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
class TestWithClassificator
|
||||
{
|
||||
public:
|
||||
TestWithClassificator();
|
||||
virtual ~TestWithClassificator() = default;
|
||||
};
|
||||
} // namespace tests_support
|
||||
} // namespace generator
|
||||
86
generator/generator_tests_support/test_with_custom_mwms.cpp
Normal file
86
generator/generator_tests_support/test_with_custom_mwms.cpp
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
#include "generator/generator_tests_support/test_with_custom_mwms.hpp"
|
||||
|
||||
#include "storage/country_info_getter.hpp"
|
||||
|
||||
#include "platform/local_country_file_utils.hpp"
|
||||
|
||||
#include "base/stl_helpers.hpp"
|
||||
#include "base/timer.hpp"
|
||||
|
||||
namespace generator
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
using namespace platform;
|
||||
|
||||
TestWithCustomMwms::TestWithCustomMwms()
|
||||
{
|
||||
m_version = base::GenerateYYMMDD(base::SecondsSinceEpoch());
|
||||
}
|
||||
|
||||
TestWithCustomMwms::~TestWithCustomMwms()
|
||||
{
|
||||
m_dataSource.ClearCache();
|
||||
for (auto const & file : m_files)
|
||||
Cleanup(file);
|
||||
}
|
||||
|
||||
// static
|
||||
void TestWithCustomMwms::Cleanup(LocalCountryFile const & file)
|
||||
{
|
||||
CountryIndexes::DeleteFromDisk(file);
|
||||
file.DeleteFromDisk(MapFileType::Map);
|
||||
}
|
||||
|
||||
void TestWithCustomMwms::DeregisterMap(std::string const & name)
|
||||
{
|
||||
auto const file = CountryFile(name);
|
||||
auto it = base::FindIf(m_files, [&file](LocalCountryFile const & f) { return f.GetCountryFile() == file; });
|
||||
|
||||
if (it == m_files.end())
|
||||
return;
|
||||
|
||||
m_dataSource.DeregisterMap(file);
|
||||
Cleanup(*it);
|
||||
m_files.erase(it);
|
||||
}
|
||||
|
||||
template <class FnT>
|
||||
void TestWithCustomMwms::RegisterLocalMapsImpl(FnT && check)
|
||||
{
|
||||
std::vector<LocalCountryFile> localFiles;
|
||||
FindAllLocalMapsAndCleanup(std::numeric_limits<int64_t>::max() /* latestVersion */, localFiles);
|
||||
|
||||
for (auto const & file : localFiles)
|
||||
{
|
||||
// Always load World.mwm, important for search.
|
||||
auto const & name = file.GetCountryName();
|
||||
if (name != WORLD_FILE_NAME && !check(name))
|
||||
continue;
|
||||
|
||||
auto const res = m_dataSource.RegisterMap(file);
|
||||
if (res.second == MwmSet::RegResult::Success)
|
||||
{
|
||||
auto const & info = res.first.GetInfo();
|
||||
OnMwmBuilt(*info);
|
||||
}
|
||||
else
|
||||
CHECK_EQUAL(res.second, MwmSet::RegResult::VersionAlreadyExists, ());
|
||||
}
|
||||
}
|
||||
|
||||
void TestWithCustomMwms::RegisterLocalMapsInViewport(m2::RectD const & viewport)
|
||||
{
|
||||
auto const countriesInfo = storage::CountryInfoReader::CreateCountryInfoGetter(GetPlatform());
|
||||
|
||||
RegisterLocalMapsImpl([&](std::string const & name)
|
||||
{ return countriesInfo->GetLimitRectForLeaf(name).IsIntersect(viewport); });
|
||||
}
|
||||
|
||||
void TestWithCustomMwms::RegisterLocalMapsByPrefix(std::string const & prefix)
|
||||
{
|
||||
RegisterLocalMapsImpl([&](std::string const & name) { return name.starts_with(prefix); });
|
||||
}
|
||||
|
||||
} // namespace tests_support
|
||||
} // namespace generator
|
||||
90
generator/generator_tests_support/test_with_custom_mwms.hpp
Normal file
90
generator/generator_tests_support/test_with_custom_mwms.hpp
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#pragma once
|
||||
|
||||
#include "generator/generator_tests_support/test_mwm_builder.hpp"
|
||||
#include "generator/generator_tests_support/test_with_classificator.hpp"
|
||||
|
||||
#include "editor/editable_data_source.hpp"
|
||||
|
||||
#include "indexer/data_header.hpp"
|
||||
#include "indexer/mwm_set.hpp"
|
||||
|
||||
#include "platform/country_file.hpp"
|
||||
#include "platform/local_country_file.hpp"
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#include "base/assert.hpp"
|
||||
#include "base/stl_helpers.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace generator
|
||||
{
|
||||
namespace tests_support
|
||||
{
|
||||
class TestWithCustomMwms : public TestWithClassificator
|
||||
{
|
||||
public:
|
||||
TestWithCustomMwms();
|
||||
~TestWithCustomMwms() override;
|
||||
|
||||
// Creates a physical country file on a disk, which will be removed
|
||||
// at the end of the test. |fn| is a delegate that accepts a single
|
||||
// argument - TestMwmBuilder and adds all necessary features to the
|
||||
// country file.
|
||||
template <typename BuildFn>
|
||||
MwmSet::MwmId BuildMwm(std::string name, feature::DataHeader::MapType type, BuildFn && fn)
|
||||
{
|
||||
m_files.emplace_back(GetPlatform().WritableDir(), platform::CountryFile(std::move(name)), 0 /* version */);
|
||||
auto & file = m_files.back();
|
||||
Cleanup(file);
|
||||
|
||||
{
|
||||
generator::tests_support::TestMwmBuilder builder(file, type, m_version);
|
||||
fn(builder);
|
||||
}
|
||||
|
||||
auto result = m_dataSource.RegisterMap(file);
|
||||
CHECK_EQUAL(result.second, MwmSet::RegResult::Success, ());
|
||||
|
||||
auto id = result.first;
|
||||
auto const info = id.GetInfo();
|
||||
CHECK(info.get(), ());
|
||||
OnMwmBuilt(*info);
|
||||
return id;
|
||||
}
|
||||
|
||||
void DeregisterMap(std::string const & name);
|
||||
|
||||
template <typename BuildFn>
|
||||
MwmSet::MwmId BuildWorld(BuildFn && fn)
|
||||
{
|
||||
return BuildMwm("testWorld", feature::DataHeader::MapType::World, fn);
|
||||
}
|
||||
|
||||
template <typename BuildFn>
|
||||
MwmSet::MwmId BuildCountry(std::string_view name, BuildFn && fn)
|
||||
{
|
||||
return BuildMwm(std::string(name), feature::DataHeader::MapType::Country, fn);
|
||||
}
|
||||
|
||||
void SetMwmVersion(uint32_t version) { m_version = version; }
|
||||
|
||||
void RegisterLocalMapsInViewport(m2::RectD const & viewport);
|
||||
void RegisterLocalMapsByPrefix(std::string const & prefix);
|
||||
|
||||
protected:
|
||||
template <class FnT>
|
||||
void RegisterLocalMapsImpl(FnT && check);
|
||||
|
||||
static void Cleanup(platform::LocalCountryFile const & file);
|
||||
|
||||
virtual void OnMwmBuilt(MwmInfo const & /* info */) {}
|
||||
|
||||
EditableDataSource m_dataSource;
|
||||
std::vector<platform::LocalCountryFile> m_files;
|
||||
uint32_t m_version = 0;
|
||||
};
|
||||
} // namespace tests_support
|
||||
} // namespace generator
|
||||
Loading…
Add table
Add a link
Reference in a new issue