Format all C++ and Java code via clang-format

Signed-off-by: Konstantin Pastbin <konstantin.pastbin@gmail.com>
This commit is contained in:
Konstantin Pastbin
2025-08-17 14:32:37 +07:00
parent 9f0290c0ec
commit bfffa1fff4
2169 changed files with 56441 additions and 64188 deletions

View File

@@ -67,9 +67,8 @@ m2::PointD FindCenter(FeatureType & f)
ClosestPoint closest(f.GetLimitRect(FeatureType::BEST_GEOMETRY).Center());
if (f.GetGeomType() == feature::GeomType::Area)
{
f.ForEachTriangle([&closest](m2::PointD const & p1, m2::PointD const & p2,
m2::PointD const & p3) { closest((p1 + p2 + p3) / 3); },
FeatureType::BEST_GEOMETRY);
f.ForEachTriangle([&closest](m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3)
{ closest((p1 + p2 + p3) / 3); }, FeatureType::BEST_GEOMETRY);
}
else
{
@@ -93,7 +92,7 @@ string GetReadableType(FeatureType & f)
string GetWheelchairType(FeatureType & f)
{
static const uint32_t wheelchair = classif().GetTypeByPath({"wheelchair"});
static uint32_t const wheelchair = classif().GetTypeByPath({"wheelchair"});
string result;
f.ForEachType([&result](uint32_t type)
{
@@ -110,9 +109,10 @@ string GetWheelchairType(FeatureType & f)
bool HasAtm(FeatureType & f)
{
static const uint32_t atm = classif().GetTypeByPath({"amenity", "atm"});
static uint32_t const atm = classif().GetTypeByPath({"amenity", "atm"});
bool result = false;
f.ForEachType([&result](uint32_t type) {
f.ForEachType([&result](uint32_t type)
{
if (type == atm)
result = true;
});
@@ -122,8 +122,7 @@ bool HasAtm(FeatureType & f)
string BuildUniqueId(ms::LatLon const & coords, string const & name)
{
ostringstream ss;
ss << strings::to_string_dac(coords.m_lat, 6) << ','
<< strings::to_string_dac(coords.m_lon, 6) << ',' << name;
ss << strings::to_string_dac(coords.m_lat, 6) << ',' << strings::to_string_dac(coords.m_lon, 6) << ',' << name;
uint32_t hash = 0;
for (char const c : ss.str())
hash = hash * 101 + c;
@@ -191,10 +190,7 @@ public:
void ClearCache() { m_villagesCache.Clear(); }
void operator()(FeatureType & f, map<uint32_t, base::GeoObjectId> const & ft2osm)
{
Process(f, ft2osm);
}
void operator()(FeatureType & f, map<uint32_t, base::GeoObjectId> const & ft2osm) { Process(f, ft2osm); }
void Process(FeatureType & f, map<uint32_t, base::GeoObjectId> const & ft2osm)
{
@@ -205,8 +201,7 @@ public:
auto const metaOperator = meta.Get(feature::Metadata::FMD_OPERATOR);
auto const & osmIt = ft2osm.find(f.GetID().m_index);
if ((!f.HasName() && metaOperator.empty()) ||
(f.GetGeomType() == feature::GeomType::Line && category != "highway-pedestrian") ||
category.empty())
(f.GetGeomType() == feature::GeomType::Line && category != "highway-pedestrian") || category.empty())
{
return;
}
@@ -217,9 +212,7 @@ public:
string_view city;
m_finder.GetLocality(center, [&city](search::LocalityItem const & item)
{
item.GetSpecifiedOrDefaultName(StringUtf8Multilang::kDefaultCode, city);
});
{ item.GetSpecifiedOrDefaultName(StringUtf8Multilang::kDefaultCode, city); });
string const & mwmName = f.GetID().GetMwmName();
@@ -276,11 +269,39 @@ public:
string const fee = category.ends_with("-fee") ? "yes" : "";
string const atm = HasAtm(f) ? "yes" : "";
vector<string> columns = {
osmId, uid, lat, lon, mwmName, category, name, std::string(city),
addrStreet, addrHouse, phone, website, stars, std::string(metaOperator), internet,
denomination, wheelchair, opening_hours, check_date, check_date_opening_hours, wikipedia, floor, fee, atm, contact_facebook,
contact_instagram, contact_twitter, contact_vk, contact_line, contact_fediverse, contact_bluesky, wikimedia_commons, panoramax};
vector<string> columns = {osmId,
uid,
lat,
lon,
mwmName,
category,
name,
std::string(city),
addrStreet,
addrHouse,
phone,
website,
stars,
std::string(metaOperator),
internet,
denomination,
wheelchair,
opening_hours,
check_date,
check_date_opening_hours,
wikipedia,
floor,
fee,
atm,
contact_facebook,
contact_instagram,
contact_twitter,
contact_vk,
contact_line,
contact_fediverse,
contact_bluesky,
wikimedia_commons,
panoramax};
AppendNames(f, columns);
PrintAsCSV(columns, ';', cout);
@@ -289,12 +310,40 @@ public:
void PrintHeader()
{
vector<string> columns = {"id", "old_id", "lat", "lon", "mwm",
"category", "name", "city", "street", "house",
"phone", "website", "cuisines", "stars", "operator",
"internet", "denomination", "wheelchair", "opening_hours", "check_date", "check_date_opening_hours", "wikipedia",
"floor", "fee", "atm", "contact_facebook", "contact_instagram",
"contact_twitter", "contact_vk", "contact_line", "contact_fediverse", "contact_bluesky", "wikimedia_commons", "panoramax"};
vector<string> columns = {"id",
"old_id",
"lat",
"lon",
"mwm",
"category",
"name",
"city",
"street",
"house",
"phone",
"website",
"cuisines",
"stars",
"operator",
"internet",
"denomination",
"wheelchair",
"opening_hours",
"check_date",
"check_date_opening_hours",
"wikipedia",
"floor",
"fee",
"atm",
"contact_facebook",
"contact_instagram",
"contact_twitter",
"contact_vk",
"contact_line",
"contact_fediverse",
"contact_bluesky",
"wikimedia_commons",
"panoramax"};
// Append all supported name languages in order.
for (uint8_t idx = 1; idx < kLangCount; idx++)
columns.push_back("name_" + string(StringUtf8Multilang::GetLangByCode(idx)));
@@ -304,15 +353,12 @@ void PrintHeader()
bool ParseFeatureIdToOsmIdMapping(string const & path, map<uint32_t, base::GeoObjectId> & mapping)
{
return generator::ForEachOsmId2FeatureId(
path, [&](auto const & compositeId, uint32_t const featureId) {
mapping[featureId] = compositeId.m_mainId;
});
path, [&](auto const & compositeId, uint32_t const featureId) { mapping[featureId] = compositeId.m_mainId; });
}
void DidDownload(storage::CountryId const & /* countryId */,
shared_ptr<platform::LocalCountryFile> const & /* localFile */)
{
}
{}
bool WillDelete(storage::CountryId const & /* countryId */,
shared_ptr<platform::LocalCountryFile> const & /* localFile */)
@@ -325,8 +371,7 @@ int main(int argc, char ** argv)
platform::tests_support::ChangeMaxNumberOfOpenFiles(search::search_quality::kMaxOpenFiles);
if (argc <= 1)
{
LOG(LERROR, ("Usage:", argc == 1 ? argv[0] : "feature_list",
"<mwm_path> [<data_path>] [<mwm_prefix>]"));
LOG(LERROR, ("Usage:", argc == 1 ? argv[0] : "feature_list", "<mwm_path> [<data_path>] [<mwm_prefix>]"));
return 1;
}
@@ -350,8 +395,7 @@ int main(int argc, char ** argv)
FrozenDataSource dataSource;
vector<platform::LocalCountryFile> mwms;
platform::FindAllLocalMapsAndCleanup(numeric_limits<int64_t>::max() /* the latest version */,
mwms);
platform::FindAllLocalMapsAndCleanup(numeric_limits<int64_t>::max() /* the latest version */, mwms);
for (auto & mwm : mwms)
{
mwm.SyncWithDisk();
@@ -372,17 +416,15 @@ int main(int argc, char ** argv)
if (argc > 3 && !(mwmInfo->GetCountryName() + DATA_FILE_EXTENSION).starts_with(argv[3]))
continue;
LOG(LINFO, ("Processing", mwmInfo->GetCountryName()));
string osmToFeatureFile = base::JoinPath(
argv[1], mwmInfo->GetCountryName() + DATA_FILE_EXTENSION + OSM2FEATURE_FILE_EXTENSION);
string osmToFeatureFile =
base::JoinPath(argv[1], mwmInfo->GetCountryName() + DATA_FILE_EXTENSION + OSM2FEATURE_FILE_EXTENSION);
map<uint32_t, base::GeoObjectId> featureIdToOsmId;
ParseFeatureIdToOsmIdMapping(osmToFeatureFile, featureIdToOsmId);
MwmSet::MwmId mwmId(mwmInfo);
FeaturesLoaderGuard loader(dataSource, mwmId);
for (uint32_t ftIndex = 0; ftIndex < loader.GetNumFeatures(); ftIndex++)
{
if (auto ft = loader.GetFeatureByIndex(static_cast<uint32_t>(ftIndex)))
doProcess.Process(*ft, featureIdToOsmId);
}
doProcess.ClearCache();
}

View File

@@ -5,4 +5,4 @@
namespace openlr
{
size_t constexpr kCacheLineSize = 64;
} // namespace
} // namespace openlr

View File

@@ -62,9 +62,8 @@ bool CandidatePathsGetter::Link::IsPointOnPath(geometry::PointWithAltitude const
}
// CandidatePathsGetter ----------------------------------------------------------------------------
bool CandidatePathsGetter::GetLineCandidatesForPoints(
vector<LocationReferencePoint> const & points,
vector<vector<Graph::EdgeVector>> & lineCandidates)
bool CandidatePathsGetter::GetLineCandidatesForPoints(vector<LocationReferencePoint> const & points,
vector<vector<Graph::EdgeVector>> & lineCandidates)
{
for (size_t i = 0; i < points.size(); ++i)
{
@@ -77,14 +76,11 @@ bool CandidatePathsGetter::GetLineCandidatesForPoints(
lineCandidates.emplace_back();
auto const isLastPoint = i == points.size() - 1;
double const distanceToNextPointM =
(isLastPoint ? points[i - 1] : points[i]).m_distanceToNextPoint;
double const distanceToNextPointM = (isLastPoint ? points[i - 1] : points[i]).m_distanceToNextPoint;
vector<m2::PointD> pointCandidates;
m_pointsGetter.GetCandidatePoints(mercator::FromLatLon(points[i].m_latLon),
pointCandidates);
GetLineCandidates(points[i], isLastPoint, distanceToNextPointM, pointCandidates,
lineCandidates.back());
m_pointsGetter.GetCandidatePoints(mercator::FromLatLon(points[i].m_latLon), pointCandidates);
GetLineCandidates(points[i], isLastPoint, distanceToNextPointM, pointCandidates, lineCandidates.back());
if (lineCandidates.back().empty())
{
@@ -117,11 +113,9 @@ void CandidatePathsGetter::GetStartLines(vector<m2::PointD> const & points, bool
base::SortUnique(edges, less<Graph::Edge>(), EdgesAreAlmostEqual);
}
void CandidatePathsGetter::GetAllSuitablePaths(Graph::EdgeVector const & startLines,
bool isLastPoint, double bearDistM,
FunctionalRoadClass functionalRoadClass,
FormOfWay formOfWay, double distanceToNextPointM,
vector<LinkPtr> & allPaths)
void CandidatePathsGetter::GetAllSuitablePaths(Graph::EdgeVector const & startLines, bool isLastPoint, double bearDistM,
FunctionalRoadClass functionalRoadClass, FormOfWay formOfWay,
double distanceToNextPointM, vector<LinkPtr> & allPaths)
{
queue<LinkPtr> q;
@@ -179,9 +173,9 @@ void CandidatePathsGetter::GetAllSuitablePaths(Graph::EdgeVector const & startLi
}
}
void CandidatePathsGetter::GetBestCandidatePaths(
vector<LinkPtr> const & allPaths, bool const isLastPoint, uint32_t const requiredBearing,
double const bearDistM, m2::PointD const & startPoint, vector<Graph::EdgeVector> & candidates)
void CandidatePathsGetter::GetBestCandidatePaths(vector<LinkPtr> const & allPaths, bool const isLastPoint,
uint32_t const requiredBearing, double const bearDistM,
m2::PointD const & startPoint, vector<Graph::EdgeVector> & candidates)
{
set<CandidatePath> candidatePaths;
set<CandidatePath> fakeEndingsCandidatePaths;
@@ -212,8 +206,7 @@ void CandidatePathsGetter::GetBestCandidatePaths(
--traceBackIterationsLeft;
auto const bearEndPoint =
pointsSelector.GetEndPoint(part->m_edge, part->m_distanceM);
auto const bearEndPoint = pointsSelector.GetEndPoint(part->m_edge, part->m_distanceM);
auto const bearing = cpg::Bearing(bearStartPoint, bearEndPoint);
auto const bearingDiff = AbsDifference(bearing, requiredBearing);
@@ -228,21 +221,16 @@ void CandidatePathsGetter::GetBestCandidatePaths(
}
}
ASSERT(
none_of(begin(candidatePaths), end(candidatePaths), mem_fn(&CandidatePath::HasFakeEndings)),
());
ASSERT(fakeEndingsCandidatePaths.empty() ||
any_of(begin(fakeEndingsCandidatePaths), end(fakeEndingsCandidatePaths),
mem_fn(&CandidatePath::HasFakeEndings)),
ASSERT(none_of(begin(candidatePaths), end(candidatePaths), mem_fn(&CandidatePath::HasFakeEndings)), ());
ASSERT(fakeEndingsCandidatePaths.empty() || any_of(begin(fakeEndingsCandidatePaths), end(fakeEndingsCandidatePaths),
mem_fn(&CandidatePath::HasFakeEndings)),
());
vector<CandidatePath> paths;
copy_n(begin(candidatePaths), min(static_cast<size_t>(kMaxCandidates), candidatePaths.size()),
back_inserter(paths));
copy_n(begin(candidatePaths), min(static_cast<size_t>(kMaxCandidates), candidatePaths.size()), back_inserter(paths));
copy_n(begin(fakeEndingsCandidatePaths),
min(static_cast<size_t>(kMaxFakeCandidates), fakeEndingsCandidatePaths.size()),
back_inserter(paths));
min(static_cast<size_t>(kMaxFakeCandidates), fakeEndingsCandidatePaths.size()), back_inserter(paths));
LOG(LDEBUG, ("List candidate paths..."));
for (auto const & path : paths)
@@ -258,8 +246,7 @@ void CandidatePathsGetter::GetBestCandidatePaths(
}
}
void CandidatePathsGetter::GetLineCandidates(openlr::LocationReferencePoint const & p,
bool const isLastPoint,
void CandidatePathsGetter::GetLineCandidates(openlr::LocationReferencePoint const & p, bool const isLastPoint,
double const distanceToNextPointM,
vector<m2::PointD> const & pointCandidates,
vector<Graph::EdgeVector> & candidates)
@@ -280,8 +267,8 @@ void CandidatePathsGetter::GetLineCandidates(openlr::LocationReferencePoint cons
auto const startPoint = mercator::FromLatLon(p.m_latLon);
vector<LinkPtr> allPaths;
GetAllSuitablePaths(startLines, isLastPoint, bearDistM, p.m_functionalRoadClass, p.m_formOfWay,
distanceToNextPointM, allPaths);
GetAllSuitablePaths(startLines, isLastPoint, bearDistM, p.m_functionalRoadClass, p.m_formOfWay, distanceToNextPointM,
allPaths);
GetBestCandidatePaths(allPaths, isLastPoint, p.m_bearing, bearDistM, startPoint, candidates);
LOG(LDEBUG, (candidates.size(), "candidate paths found for point (LatLon)", p.m_latLon));
}

View File

@@ -20,11 +20,13 @@ class CandidatePointsGetter;
class CandidatePathsGetter
{
public:
CandidatePathsGetter(CandidatePointsGetter & pointsGetter, Graph & graph,
RoadInfoGetter & infoGetter, v2::Stats & stat)
: m_pointsGetter(pointsGetter), m_graph(graph), m_infoGetter(infoGetter), m_stats(stat)
{
}
CandidatePathsGetter(CandidatePointsGetter & pointsGetter, Graph & graph, RoadInfoGetter & infoGetter,
v2::Stats & stat)
: m_pointsGetter(pointsGetter)
, m_graph(graph)
, m_infoGetter(infoGetter)
, m_stats(stat)
{}
bool GetLineCandidatesForPoints(std::vector<LocationReferencePoint> const & points,
std::vector<std::vector<Graph::EdgeVector>> & lineCandidates);
@@ -44,8 +46,7 @@ private:
, m_edge(edge)
, m_distanceM(distanceM)
, m_hasFake((parent && parent->m_hasFake) || edge.IsFake())
{
}
{}
bool IsPointOnPath(geometry::PointWithAltitude const & point) const;
@@ -71,8 +72,7 @@ private:
, m_bearingDiff(bearingDiff)
, m_pathDistanceDiff(pathDistanceDiff)
, m_startPointDistance(startPointDistance)
{
}
{}
bool operator<(CandidatePath const & o) const { return GetPenalty() < o.GetPenalty(); }
@@ -102,21 +102,18 @@ private:
// distance-to-next point is taken from point 3. You can learn more in
// TomTom OpenLR spec.
void GetStartLines(std::vector<m2::PointD> const & points, bool const isLastPoint,
Graph::EdgeVector & edges);
void GetStartLines(std::vector<m2::PointD> const & points, bool const isLastPoint, Graph::EdgeVector & edges);
void GetAllSuitablePaths(Graph::EdgeVector const & startLines, bool isLastPoint, double bearDistM,
FunctionalRoadClass functionalRoadClass, FormOfWay formOfWay,
double distanceToNextPointM, std::vector<LinkPtr> & allPaths);
FunctionalRoadClass functionalRoadClass, FormOfWay formOfWay, double distanceToNextPointM,
std::vector<LinkPtr> & allPaths);
void GetBestCandidatePaths(std::vector<LinkPtr> const & allPaths, bool const isLastPoint,
uint32_t const requiredBearing, double const bearDistM,
m2::PointD const & startPoint,
uint32_t const requiredBearing, double const bearDistM, m2::PointD const & startPoint,
std::vector<Graph::EdgeVector> & candidates);
void GetLineCandidates(openlr::LocationReferencePoint const & p, bool const isLastPoint,
double const distanceToNextPointM,
std::vector<m2::PointD> const & pointCandidates,
double const distanceToNextPointM, std::vector<m2::PointD> const & pointCandidates,
std::vector<Graph::EdgeVector> & candidates);
CandidatePointsGetter & m_pointsGetter;

View File

@@ -18,22 +18,21 @@ using namespace routing;
namespace openlr
{
void CandidatePointsGetter::FillJunctionPointCandidates(m2::PointD const & p,
std::vector<m2::PointD> & candidates)
void CandidatePointsGetter::FillJunctionPointCandidates(m2::PointD const & p, std::vector<m2::PointD> & candidates)
{
// TODO(mgsergio): Get optimal value using experiments on a sample.
// Or start with small radius and scale it up when there are too few points.
size_t const kRectSideMeters = 110;
auto const rect = mercator::RectByCenterXYAndSizeInMeters(p, kRectSideMeters);
auto const selectCandidates = [&rect, &candidates](FeatureType & ft) {
auto const selectCandidates = [&rect, &candidates](FeatureType & ft)
{
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
ft.ForEachPoint(
[&rect, &candidates](m2::PointD const & candidate) {
if (rect.IsPointInside(candidate))
candidates.emplace_back(candidate);
},
scales::GetUpperScale());
ft.ForEachPoint([&rect, &candidates](m2::PointD const & candidate)
{
if (rect.IsPointInside(candidate))
candidates.emplace_back(candidate);
}, scales::GetUpperScale());
};
m_dataSource.ForEachInRect(selectCandidates, rect, scales::GetUpperScale());
@@ -44,17 +43,14 @@ void CandidatePointsGetter::FillJunctionPointCandidates(m2::PointD const & p,
// later. The idea to fix this was to move SortUnique to the stage
// after enriching with projections.
base::SortUnique(candidates,
[&p](m2::PointD const & a, m2::PointD const & b) {
return mercator::DistanceOnEarth(a, p) < mercator::DistanceOnEarth(b, p);
},
base::SortUnique(candidates, [&p](m2::PointD const & a, m2::PointD const & b)
{ return mercator::DistanceOnEarth(a, p) < mercator::DistanceOnEarth(b, p); },
[](m2::PointD const & a, m2::PointD const & b) { return a == b; });
candidates.resize(std::min(m_maxJunctionCandidates, candidates.size()));
}
void CandidatePointsGetter::EnrichWithProjectionPoints(m2::PointD const & p,
std::vector<m2::PointD> & candidates)
void CandidatePointsGetter::EnrichWithProjectionPoints(m2::PointD const & p, std::vector<m2::PointD> & candidates)
{
m_graph.ResetFakes();

View File

@@ -22,8 +22,7 @@ public:
, m_maxProjectionCandidates(maxProjectionCandidates)
, m_dataSource(dataSource)
, m_graph(graph)
{
}
{}
void GetCandidatePoints(m2::PointD const & p, std::vector<m2::PointD> & candidates)
{

View File

@@ -15,7 +15,7 @@
#define THROW_IF_NODE_IS_EMPTY(node, exc, msg) \
if (!node) \
MYTHROW(exc, msg)
MYTHROW(exc, msg)
namespace
{
@@ -81,10 +81,7 @@ void WriteAsMappingForSpark(std::string const & fileName, std::vector<DecodedPat
WriteAsMappingForSpark(ofs, paths);
if (ofs.fail())
{
MYTHROW(DecodedPathSaveError,
("An error occured while writing file", fileName, strerror(errno)));
}
MYTHROW(DecodedPathSaveError, ("An error occured while writing file", fileName, strerror(errno)));
}
void WriteAsMappingForSpark(std::ostream & ost, std::vector<DecodedPath> const & paths)
@@ -105,11 +102,9 @@ void WriteAsMappingForSpark(std::ostream & ost, std::vector<DecodedPath> const &
for (auto it = std::begin(p.m_path); it != std::end(p.m_path); ++it)
{
auto const & fid = it->GetFeatureId();
ost << fid.m_mwmId.GetInfo()->GetCountryName()
<< kFieldSep << fid.m_index
<< kFieldSep << it->GetSegId()
<< kFieldSep << (it->IsForward() ? "fwd" : "bwd")
<< kFieldSep << mercator::DistanceOnEarth(GetStart(*it), GetEnd(*it));
ost << fid.m_mwmId.GetInfo()->GetCountryName() << kFieldSep << fid.m_index << kFieldSep << it->GetSegId()
<< kFieldSep << (it->IsForward() ? "fwd" : "bwd") << kFieldSep
<< mercator::DistanceOnEarth(GetStart(*it), GetEnd(*it));
if (std::next(it) != std::end(p.m_path))
ost << kSegmentSep;
@@ -135,10 +130,10 @@ void PathFromXML(pugi::xml_node const & node, DataSource const & dataSource, Pat
LatLonFromXML(e.child("StartJunction"), start);
LatLonFromXML(e.child("EndJunction"), end);
p.push_back(Edge::MakeReal(
fid, isForward, segmentId,
geometry::PointWithAltitude(mercator::FromLatLon(start), geometry::kDefaultAltitudeMeters),
geometry::PointWithAltitude(mercator::FromLatLon(end), geometry::kDefaultAltitudeMeters)));
p.push_back(
Edge::MakeReal(fid, isForward, segmentId,
geometry::PointWithAltitude(mercator::FromLatLon(start), geometry::kDefaultAltitudeMeters),
geometry::PointWithAltitude(mercator::FromLatLon(end), geometry::kDefaultAltitudeMeters)));
}
}

View File

@@ -42,8 +42,14 @@ void PathToXML(Path const & path, pugi::xml_node & node);
namespace routing
{
inline m2::PointD GetStart(Edge const & e) { return e.GetStartJunction().GetPoint(); }
inline m2::PointD GetEnd(Edge const & e) { return e.GetEndJunction().GetPoint(); }
inline m2::PointD GetStart(Edge const & e)
{
return e.GetStartJunction().GetPoint();
}
inline m2::PointD GetEnd(Edge const & e)
{
return e.GetEndJunction().GetPoint();
}
std::vector<m2::PointD> GetPoints(routing::RoadGraphBase::EdgeVector const & p);
} // namespace routing

View File

@@ -15,13 +15,10 @@ namespace openlr
{
namespace
{
using EdgeGetter = void (IRoadGraph::*)(geometry::PointWithAltitude const &,
RoadGraphBase::EdgeListT &) const;
using EdgeGetter = void (IRoadGraph::*)(geometry::PointWithAltitude const &, RoadGraphBase::EdgeListT &) const;
void GetRegularEdges(geometry::PointWithAltitude const & junction, IRoadGraph const & graph,
EdgeGetter const edgeGetter,
Graph::EdgeCacheT & cache,
Graph::EdgeListT & edges)
EdgeGetter const edgeGetter, Graph::EdgeCacheT & cache, Graph::EdgeListT & edges)
{
auto const it = cache.find(junction);
if (it == end(cache))
@@ -39,9 +36,9 @@ void GetRegularEdges(geometry::PointWithAltitude const & junction, IRoadGraph co
} // namespace
Graph::Graph(DataSource & dataSource, shared_ptr<CarModelFactory> carModelFactory)
: m_dataSource(dataSource, nullptr /* numMwmIDs */), m_graph(m_dataSource, IRoadGraph::Mode::ObeyOnewayTag, carModelFactory)
{
}
: m_dataSource(dataSource, nullptr /* numMwmIDs */)
, m_graph(m_dataSource, IRoadGraph::Mode::ObeyOnewayTag, carModelFactory)
{}
void Graph::GetOutgoingEdges(Junction const & junction, EdgeListT & edges)
{
@@ -68,9 +65,8 @@ void Graph::GetRegularIngoingEdges(Junction const & junction, EdgeListT & edges)
void Graph::FindClosestEdges(m2::PointD const & point, uint32_t const count,
vector<pair<Edge, Junction>> & vicinities) const
{
m_graph.FindClosestEdges(
mercator::RectByCenterXYAndSizeInMeters(point, FeaturesRoadGraph::kClosestEdgesRadiusM),
count, vicinities);
m_graph.FindClosestEdges(mercator::RectByCenterXYAndSizeInMeters(point, FeaturesRoadGraph::kClosestEdgesRadiusM),
count, vicinities);
}
void Graph::AddIngoingFakeEdge(Edge const & e)

View File

@@ -53,6 +53,7 @@ public:
void GetFeatureTypes(FeatureID const & featureId, feature::TypesHolder & types) const;
using EdgeCacheT = std::map<Junction, EdgeListT>;
private:
routing::MwmDataSource m_dataSource;
routing::FeaturesRoadGraph m_graph;

View File

@@ -12,7 +12,6 @@
#include <optional>
#include <sstream>
namespace
{
using namespace openlr;
@@ -34,8 +33,7 @@ openlr::FunctionalRoadClass HighwayClassToFunctionalRoadClass(ftypes::HighwayCla
}
/// \returns nullopt if |e| doesn't conform to |functionalRoadClass| and score otherwise.
optional<Score> GetFrcScore(Graph::Edge const & e, FunctionalRoadClass functionalRoadClass,
RoadInfoGetter & infoGetter)
optional<Score> GetFrcScore(Graph::Edge const & e, FunctionalRoadClass functionalRoadClass, RoadInfoGetter & infoGetter)
{
CHECK(!e.IsFake(), ());
Score constexpr kMaxScoreForFrc = 25;
@@ -54,38 +52,31 @@ optional<Score> GetFrcScore(Graph::Edge const & e, FunctionalRoadClass functiona
return hwClass == HighwayClass::Trunk ? optional<Score>(kMaxScoreForFrc) : nullopt;
case FunctionalRoadClass::FRC1:
return (hwClass == HighwayClass::Trunk || hwClass == HighwayClass::Primary)
? optional<Score>(kMaxScoreForFrc)
: nullopt;
return (hwClass == HighwayClass::Trunk || hwClass == HighwayClass::Primary) ? optional<Score>(kMaxScoreForFrc)
: nullopt;
case FunctionalRoadClass::FRC2:
case FunctionalRoadClass::FRC3:
if (hwClass == HighwayClass::Secondary || hwClass == HighwayClass::Tertiary)
return optional<Score>(kMaxScoreForFrc);
return hwClass == HighwayClass::Primary || hwClass == HighwayClass::LivingStreet
? optional<Score>(0)
: nullopt;
return hwClass == HighwayClass::Primary || hwClass == HighwayClass::LivingStreet ? optional<Score>(0) : nullopt;
case FunctionalRoadClass::FRC4:
if (hwClass == HighwayClass::LivingStreet || hwClass == HighwayClass::Service)
return optional<Score>(kMaxScoreForFrc);
return (hwClass == HighwayClass::Tertiary || hwClass == HighwayClass::Secondary)
? optional<Score>(0)
: nullopt;
return (hwClass == HighwayClass::Tertiary || hwClass == HighwayClass::Secondary) ? optional<Score>(0) : nullopt;
case FunctionalRoadClass::FRC5:
case FunctionalRoadClass::FRC6:
case FunctionalRoadClass::FRC7:
return (hwClass == HighwayClass::LivingStreet ||
hwClass == HighwayClass::Service ||
return (hwClass == HighwayClass::LivingStreet || hwClass == HighwayClass::Service ||
hwClass == HighwayClass::ServiceMinor)
? optional<Score>(kMaxScoreForFrc)
: nullopt;
? optional<Score>(kMaxScoreForFrc)
: nullopt;
case FunctionalRoadClass::NotAValue:
UNREACHABLE();
case FunctionalRoadClass::NotAValue: UNREACHABLE();
}
UNREACHABLE();
}
@@ -95,9 +86,9 @@ namespace openlr
{
// BearingPointsSelector ---------------------------------------------------------------------------
BearingPointsSelector::BearingPointsSelector(uint32_t bearDistM, bool isLastPoint)
: m_bearDistM(bearDistM), m_isLastPoint(isLastPoint)
{
}
: m_bearDistM(bearDistM)
, m_isLastPoint(isLastPoint)
{}
m2::PointD BearingPointsSelector::GetStartPoint(Graph::Edge const & e) const
{
@@ -131,8 +122,7 @@ double EdgeLength(Graph::Edge const & e)
bool EdgesAreAlmostEqual(Graph::Edge const & e1, Graph::Edge const & e2)
{
// TODO(mgsergio): Do I need to check fields other than points?
return PointsAreClose(e1.GetStartPoint(), e2.GetStartPoint()) &&
PointsAreClose(e1.GetEndPoint(), e2.GetEndPoint());
return PointsAreClose(e1.GetStartPoint(), e2.GetStartPoint()) && PointsAreClose(e1.GetEndPoint(), e2.GetEndPoint());
}
string LogAs2GisPath(Graph::EdgeVector const & path)
@@ -157,10 +147,13 @@ string LogAs2GisPath(Graph::EdgeVector const & path)
return ost.str();
}
string LogAs2GisPath(Graph::Edge const & e) { return LogAs2GisPath(Graph::EdgeVector({e})); }
string LogAs2GisPath(Graph::Edge const & e)
{
return LogAs2GisPath(Graph::EdgeVector({e}));
}
bool PassesRestriction(Graph::Edge const & e, FunctionalRoadClass restriction, FormOfWay formOfWay,
int frcThreshold, RoadInfoGetter & infoGetter)
bool PassesRestriction(Graph::Edge const & e, FunctionalRoadClass restriction, FormOfWay formOfWay, int frcThreshold,
RoadInfoGetter & infoGetter)
{
if (e.IsFake() || restriction == FunctionalRoadClass::NotAValue)
return true;
@@ -169,8 +162,8 @@ bool PassesRestriction(Graph::Edge const & e, FunctionalRoadClass restriction, F
return static_cast<int>(frc) <= static_cast<int>(restriction) + frcThreshold;
}
bool PassesRestrictionV3(Graph::Edge const & e, FunctionalRoadClass functionalRoadClass,
FormOfWay formOfWay, RoadInfoGetter & infoGetter, Score & score)
bool PassesRestrictionV3(Graph::Edge const & e, FunctionalRoadClass functionalRoadClass, FormOfWay formOfWay,
RoadInfoGetter & infoGetter, Score & score)
{
CHECK(!e.IsFake(), ("Edges should not be fake:", e));
auto const frcScore = GetFrcScore(e, functionalRoadClass, infoGetter);
@@ -185,8 +178,8 @@ bool PassesRestrictionV3(Graph::Edge const & e, FunctionalRoadClass functionalRo
return true;
}
bool ConformLfrcnp(Graph::Edge const & e, FunctionalRoadClass lowestFrcToNextPoint,
int frcThreshold, RoadInfoGetter & infoGetter)
bool ConformLfrcnp(Graph::Edge const & e, FunctionalRoadClass lowestFrcToNextPoint, int frcThreshold,
RoadInfoGetter & infoGetter)
{
if (e.IsFake() || lowestFrcToNextPoint == FunctionalRoadClass::NotAValue)
return true;
@@ -195,8 +188,7 @@ bool ConformLfrcnp(Graph::Edge const & e, FunctionalRoadClass lowestFrcToNextPoi
return static_cast<int>(frc) <= static_cast<int>(lowestFrcToNextPoint) + frcThreshold;
}
bool ConformLfrcnpV3(Graph::Edge const & e, FunctionalRoadClass lowestFrcToNextPoint,
RoadInfoGetter & infoGetter)
bool ConformLfrcnpV3(Graph::Edge const & e, FunctionalRoadClass lowestFrcToNextPoint, RoadInfoGetter & infoGetter)
{
return GetFrcScore(e, lowestFrcToNextPoint, infoGetter).has_value();
}

View File

@@ -38,27 +38,25 @@ bool EdgesAreAlmostEqual(Graph::Edge const & e1, Graph::Edge const & e2);
std::string LogAs2GisPath(Graph::EdgeVector const & path);
std::string LogAs2GisPath(Graph::Edge const & e);
template <typename T, typename U,
std::enable_if_t<!(std::is_signed<T>::value ^ std::is_signed<U>::value), int> = 0>
template <typename T, typename U, std::enable_if_t<!(std::is_signed<T>::value ^ std::is_signed<U>::value), int> = 0>
std::common_type_t<T, U> AbsDifference(T const a, U const b)
{
return a >= b ? a - b : b - a;
}
bool PassesRestriction(Graph::Edge const & e, FunctionalRoadClass restriction, FormOfWay formOfWay,
int frcThreshold, RoadInfoGetter & infoGetter);
bool PassesRestriction(Graph::Edge const & e, FunctionalRoadClass restriction, FormOfWay formOfWay, int frcThreshold,
RoadInfoGetter & infoGetter);
/// \returns true if |e| conforms |functionalRoadClass| and |formOfWay| and false otherwise.
/// \note If the method returns true |score| should be considered next.
bool PassesRestrictionV3(Graph::Edge const & e, FunctionalRoadClass functionalRoadClass,
FormOfWay formOfWay, RoadInfoGetter & infoGetter, Score & score);
bool PassesRestrictionV3(Graph::Edge const & e, FunctionalRoadClass functionalRoadClass, FormOfWay formOfWay,
RoadInfoGetter & infoGetter, Score & score);
/// \returns true if edge |e| conforms Lowest Functional Road Class to Next Point.
/// \note frc means Functional Road Class. Please see openlr documentation for details:
/// http://www.openlr.org/data/docs/whitepaper/1_0/OpenLR-Whitepaper_v1.0.pdf
bool ConformLfrcnp(Graph::Edge const & e, FunctionalRoadClass lowestFrcToNextPoint,
int frcThreshold, RoadInfoGetter & infoGetter);
bool ConformLfrcnpV3(Graph::Edge const & e, FunctionalRoadClass lowestFrcToNextPoint,
RoadInfoGetter & infoGetter);
bool ConformLfrcnp(Graph::Edge const & e, FunctionalRoadClass lowestFrcToNextPoint, int frcThreshold,
RoadInfoGetter & infoGetter);
bool ConformLfrcnpV3(Graph::Edge const & e, FunctionalRoadClass lowestFrcToNextPoint, RoadInfoGetter & infoGetter);
size_t IntersectionLen(Graph::EdgeVector a, Graph::EdgeVector b);

View File

@@ -90,17 +90,15 @@ bool IsRealVertex(m2::PointD const & p, FeatureID const & fid, DataSource const
FeaturesLoaderGuard g(dataSource, fid.m_mwmId);
auto const ft = g.GetOriginalFeatureByIndex(fid.m_index);
bool matched = false;
ft->ForEachPoint(
[&p, &matched](m2::PointD const & fp) {
if (p == fp)
matched = true;
},
FeatureType::BEST_GEOMETRY);
ft->ForEachPoint([&p, &matched](m2::PointD const & fp)
{
if (p == fp)
matched = true;
}, FeatureType::BEST_GEOMETRY);
return matched;
}
void ExpandFake(Graph::EdgeVector & path, Graph::EdgeVector::iterator edgeIt, DataSource const & dataSource,
Graph & g)
void ExpandFake(Graph::EdgeVector & path, Graph::EdgeVector::iterator edgeIt, DataSource const & dataSource, Graph & g)
{
if (!edgeIt->IsFake())
return;
@@ -120,16 +118,18 @@ void ExpandFake(Graph::EdgeVector & path, Graph::EdgeVector::iterator edgeIt, Da
CHECK(!edges.empty(), ());
auto it = find_if(begin(edges), end(edges), [&edgeIt](Graph::Edge const & real) {
if (real.GetFeatureId() == edgeIt->GetFeatureId() && real.GetSegId() == edgeIt->GetSegId())
return true;
return false;
});
auto it = find_if(begin(edges), end(edges), [&edgeIt](Graph::Edge const & real)
{
if (real.GetFeatureId() == edgeIt->GetFeatureId() && real.GetSegId() == edgeIt->GetSegId())
return true;
return false;
});
// For features which cross mwm border FeatureIds may not match. Check geometry.
if (it == end(edges))
{
it = find_if(begin(edges), end(edges), [&edgeIt, &startIsFake](Graph::Edge const & real) {
it = find_if(begin(edges), end(edges), [&edgeIt, &startIsFake](Graph::Edge const & real)
{
// Features from the same mwm should be already matched.
if (real.GetFeatureId().m_mwmId == edgeIt->GetFeatureId().m_mwmId)
return false;
@@ -170,8 +170,7 @@ void ExpandFakes(DataSource const & dataSource, Graph & g, Graph::EdgeVector & p
// to some point along that path and drop everything form the start to that point or from
// that point to the end.
template <typename InputIterator>
InputIterator CutOffset(InputIterator start, InputIterator stop, double offset,
bool keepEnd)
InputIterator CutOffset(InputIterator start, InputIterator stop, double offset, bool keepEnd)
{
if (offset == 0.0)
return start;
@@ -193,8 +192,8 @@ InputIterator CutOffset(InputIterator start, InputIterator stop, double offset,
}
template <typename InputIterator, typename OutputIterator>
void CopyWithoutOffsets(InputIterator start, InputIterator stop, OutputIterator out,
uint32_t positiveOffset, uint32_t negativeOffset, bool keepEnds)
void CopyWithoutOffsets(InputIterator start, InputIterator stop, OutputIterator out, uint32_t positiveOffset,
uint32_t negativeOffset, bool keepEnds)
{
auto from = start;
auto to = stop;
@@ -203,8 +202,9 @@ void CopyWithoutOffsets(InputIterator start, InputIterator stop, OutputIterator
{
from = CutOffset(start, stop, positiveOffset, keepEnds);
// |to| points past the last edge we need to take.
to = CutOffset(reverse_iterator<InputIterator>(stop), reverse_iterator<InputIterator>(start),
negativeOffset, keepEnds).base();
to = CutOffset(reverse_iterator<InputIterator>(stop), reverse_iterator<InputIterator>(start), negativeOffset,
keepEnds)
.base();
}
if (!keepEnds)
@@ -216,14 +216,14 @@ void CopyWithoutOffsets(InputIterator start, InputIterator stop, OutputIterator
copy(from, to, out);
}
class SegmentsDecoderV2
{
public:
SegmentsDecoderV2(DataSource & dataSource, unique_ptr<CarModelFactory> cmf)
: m_dataSource(dataSource), m_graph(dataSource, std::move(cmf)), m_infoGetter(dataSource)
{
}
: m_dataSource(dataSource)
, m_graph(dataSource, std::move(cmf))
, m_infoGetter(dataSource)
{}
bool DecodeSegment(LinearSegment const & segment, DecodedPath & path, v2::Stats & stat)
{
@@ -241,8 +241,7 @@ public:
lineCandidates.reserve(points.size());
LOG(LDEBUG, ("Decoding segment:", segment.m_segmentId, "with", points.size(), "points"));
CandidatePointsGetter pointsGetter(kMaxJunctionCandidates, kMaxProjectionCandidates,
m_dataSource, m_graph);
CandidatePointsGetter pointsGetter(kMaxJunctionCandidates, kMaxProjectionCandidates, m_dataSource, m_graph);
CandidatePathsGetter pathsGetter(pointsGetter, m_graph, m_infoGetter, stat);
if (!pathsGetter.GetLineCandidatesForPoints(points, lineCandidates))
@@ -261,7 +260,7 @@ public:
// Sum app all distances between points. Last point's m_distanceToNextPoint
// should be equal to zero, but let's skip it just in case.
CHECK(!points.empty(), ());
for (auto it = begin(points); it != prev(end(points)); ++it)
for (auto it = begin(points); it != prev(end(points)); ++it)
requiredRouteDistanceM += it->m_distanceToNextPoint;
double actualRouteDistanceM = 0.0;
@@ -269,8 +268,8 @@ public:
actualRouteDistanceM += EdgeLength(e);
auto const scale = actualRouteDistanceM / requiredRouteDistanceM;
LOG(LDEBUG, ("actualRouteDistance:", actualRouteDistanceM,
"requiredRouteDistance:", requiredRouteDistanceM, "scale:", scale));
LOG(LDEBUG, ("actualRouteDistance:", actualRouteDistanceM, "requiredRouteDistance:", requiredRouteDistanceM,
"scale:", scale));
auto const positiveOffsetM = segment.m_locationReference.m_positiveOffsetMeters * scale;
auto const negativeOffsetM = segment.m_locationReference.m_negativeOffsetMeters * scale;
@@ -284,8 +283,8 @@ public:
ExpandFakes(m_dataSource, m_graph, route);
ASSERT(none_of(begin(route), end(route), mem_fn(&Graph::Edge::IsFake)), (segment.m_segmentId));
CopyWithoutOffsets(begin(route), end(route), back_inserter(path.m_path), positiveOffsetM,
negativeOffsetM, false /* keep ends */);
CopyWithoutOffsets(begin(route), end(route), back_inserter(path.m_path), positiveOffsetM, negativeOffsetM,
false /* keep ends */);
if (path.m_path.empty())
{
@@ -310,9 +309,10 @@ class SegmentsDecoderV3
{
public:
SegmentsDecoderV3(DataSource & dataSource, unique_ptr<CarModelFactory> carModelFactory)
: m_dataSource(dataSource), m_graph(dataSource, std::move(carModelFactory)), m_infoGetter(dataSource)
{
}
: m_dataSource(dataSource)
, m_graph(dataSource, std::move(carModelFactory))
, m_infoGetter(dataSource)
{}
bool DecodeSegment(LinearSegment const & segment, DecodedPath & path, v2::Stats & stat)
{
@@ -329,8 +329,7 @@ public:
lineCandidates.reserve(points.size());
LOG(LINFO, ("Decoding segment:", segment.m_segmentId, "with", points.size(), "points"));
ScoreCandidatePointsGetter pointsGetter(kMaxJunctionCandidates, kMaxProjectionCandidates,
m_dataSource, m_graph);
ScoreCandidatePointsGetter pointsGetter(kMaxJunctionCandidates, kMaxProjectionCandidates, m_dataSource, m_graph);
ScoreCandidatePathsGetter pathsGetter(pointsGetter, m_graph, m_infoGetter, stat);
if (!pathsGetter.GetLineCandidatesForPoints(points, segment.m_source, lineCandidates))
@@ -355,7 +354,7 @@ public:
// Sum up all distances between points. Last point's m_distanceToNextPoint
// should be equal to zero, but let's skip it just in case.
CHECK(!points.empty(), ());
for (auto it = points.begin(); it != prev(points.end()); ++it)
for (auto it = points.begin(); it != prev(points.end()); ++it)
requiredRouteDistanceM += it->m_distanceToNextPoint;
double actualRouteDistanceM = 0.0;
@@ -363,11 +362,10 @@ public:
actualRouteDistanceM += EdgeLength(e);
auto const scale = actualRouteDistanceM / requiredRouteDistanceM;
LOG(LINFO, ("actualRouteDistance:", actualRouteDistanceM,
"requiredRouteDistance:", requiredRouteDistanceM, "scale:", scale));
LOG(LINFO, ("actualRouteDistance:", actualRouteDistanceM, "requiredRouteDistance:", requiredRouteDistanceM,
"scale:", scale));
if (segment.m_locationReference.m_positiveOffsetMeters +
segment.m_locationReference.m_negativeOffsetMeters >=
if (segment.m_locationReference.m_positiveOffsetMeters + segment.m_locationReference.m_negativeOffsetMeters >=
requiredRouteDistanceM)
{
++stat.m_wrongOffsets;
@@ -379,8 +377,8 @@ public:
auto const negativeOffsetM = segment.m_locationReference.m_negativeOffsetMeters * scale;
CHECK(none_of(route.begin(), route.end(), mem_fn(&Graph::Edge::IsFake)), (segment.m_segmentId));
CopyWithoutOffsets(route.begin(), route.end(), back_inserter(path.m_path), positiveOffsetM,
negativeOffsetM, true /* keep ends */);
CopyWithoutOffsets(route.begin(), route.end(), back_inserter(path.m_path), positiveOffsetM, negativeOffsetM,
true /* keep ends */);
if (path.m_path.empty())
{
@@ -403,16 +401,15 @@ size_t constexpr GetOptimalBatchSize()
// This code computes the most optimal (in the sense of cache lines
// occupancy) batch size.
size_t constexpr a = math::LCM(sizeof(LinearSegment), kCacheLineSize) / sizeof(LinearSegment);
size_t constexpr b =
math::LCM(sizeof(IRoadGraph::EdgeVector), kCacheLineSize) / sizeof(IRoadGraph::EdgeVector);
size_t constexpr b = math::LCM(sizeof(IRoadGraph::EdgeVector), kCacheLineSize) / sizeof(IRoadGraph::EdgeVector);
return math::LCM(a, b);
}
} // namespace
// OpenLRDecoder::SegmentsFilter -------------------------------------------------------------
OpenLRDecoder::SegmentsFilter::SegmentsFilter(string const & idsPath,
bool const multipointsOnly)
: m_idsSet(false), m_multipointsOnly(multipointsOnly)
OpenLRDecoder::SegmentsFilter::SegmentsFilter(string const & idsPath, bool const multipointsOnly)
: m_idsSet(false)
, m_multipointsOnly(multipointsOnly)
{
if (idsPath.empty())
return;
@@ -437,9 +434,9 @@ bool OpenLRDecoder::SegmentsFilter::Matches(LinearSegment const & segment) const
// OpenLRDecoder -----------------------------------------------------------------------------
OpenLRDecoder::OpenLRDecoder(vector<FrozenDataSource> & dataSources,
CountryParentNameGetter const & countryParentNameGetter)
: m_dataSources(dataSources), m_countryParentNameGetter(countryParentNameGetter)
{
}
: m_dataSources(dataSources)
, m_countryParentNameGetter(countryParentNameGetter)
{}
void OpenLRDecoder::DecodeV2(vector<LinearSegment> const & segments, uint32_t const numThreads,
vector<DecodedPath> & paths)
@@ -447,15 +444,14 @@ void OpenLRDecoder::DecodeV2(vector<LinearSegment> const & segments, uint32_t co
Decode<SegmentsDecoderV2, v2::Stats>(segments, numThreads, paths);
}
void OpenLRDecoder::DecodeV3(vector<LinearSegment> const & segments, uint32_t numThreads,
vector<DecodedPath> & paths)
void OpenLRDecoder::DecodeV3(vector<LinearSegment> const & segments, uint32_t numThreads, vector<DecodedPath> & paths)
{
Decode<SegmentsDecoderV3, v2::Stats>(segments, numThreads, paths);
}
template <typename Decoder, typename Stats>
void OpenLRDecoder::Decode(vector<LinearSegment> const & segments,
uint32_t const numThreads, vector<DecodedPath> & paths)
void OpenLRDecoder::Decode(vector<LinearSegment> const & segments, uint32_t const numThreads,
vector<DecodedPath> & paths)
{
auto const worker = [&](size_t threadNum, DataSource & dataSource, Stats & stat)
{
@@ -476,8 +472,7 @@ void OpenLRDecoder::Decode(vector<LinearSegment> const & segments,
if (stat.m_routesHandled % kProgressFrequency == 0 || i == segments.size() - 1)
{
LOG(LINFO, ("Thread", threadNum, "processed", stat.m_routesHandled,
"failed:", stat.m_routesFailed));
LOG(LINFO, ("Thread", threadNum, "processed", stat.m_routesHandled, "failed:", stat.m_routesFailed));
timer.Reset();
}
}

View File

@@ -40,20 +40,17 @@ public:
bool const m_multipointsOnly;
};
OpenLRDecoder(std::vector<FrozenDataSource> & dataSources,
CountryParentNameGetter const & countryParentNameGetter);
OpenLRDecoder(std::vector<FrozenDataSource> & dataSources, CountryParentNameGetter const & countryParentNameGetter);
// Maps partner segments to mwm paths. |segments| should be sorted by partner id.
void DecodeV2(std::vector<LinearSegment> const & segments, uint32_t const numThreads,
std::vector<DecodedPath> & paths);
void DecodeV3(std::vector<LinearSegment> const & segments, uint32_t numThreads,
std::vector<DecodedPath> & paths);
void DecodeV3(std::vector<LinearSegment> const & segments, uint32_t numThreads, std::vector<DecodedPath> & paths);
private:
template <typename Decoder, typename Stats>
void Decode(std::vector<LinearSegment> const & segments, uint32_t const numThreads,
std::vector<DecodedPath> & paths);
void Decode(std::vector<LinearSegment> const & segments, uint32_t const numThreads, std::vector<DecodedPath> & paths);
std::vector<FrozenDataSource> & m_dataSources;
CountryParentNameGetter m_countryParentNameGetter;

View File

@@ -53,48 +53,38 @@ public:
: m_framework(framework)
, m_drapeApi(m_framework.GetDrapeApi())
, m_bm(framework.GetBookmarkManager())
{
}
{}
void SetViewportCenter(m2::PointD const & center) override
{
m_framework.SetViewportCenter(center);
}
void SetViewportCenter(m2::PointD const & center) override { m_framework.SetViewportCenter(center); }
void DrawDecodedSegments(std::vector<m2::PointD> const & points) override
{
CHECK(!points.empty(), ("Points must not be empty."));
LOG(LINFO, ("Decoded segment", points));
m_drapeApi.AddLine(kDecodedLineId,
df::DrapeApiLineData(points, dp::Color(0, 0, 255, 255))
.Width(3.0f).ShowPoints(true /* markPoints */));
m_drapeApi.AddLine(
kDecodedLineId,
df::DrapeApiLineData(points, dp::Color(0, 0, 255, 255)).Width(3.0f).ShowPoints(true /* markPoints */));
}
void DrawEncodedSegment(std::vector<m2::PointD> const & points) override
{
LOG(LINFO, ("Encoded segment", points));
m_drapeApi.AddLine(kEncodedLineId,
df::DrapeApiLineData(points, dp::Color(255, 0, 0, 255))
.Width(3.0f).ShowPoints(true /* markPoints */));
m_drapeApi.AddLine(
kEncodedLineId,
df::DrapeApiLineData(points, dp::Color(255, 0, 0, 255)).Width(3.0f).ShowPoints(true /* markPoints */));
}
void DrawGoldenPath(std::vector<m2::PointD> const & points) override
{
m_drapeApi.AddLine(kGoldenLineId,
df::DrapeApiLineData(points, dp::Color(255, 127, 36, 255))
.Width(4.0f).ShowPoints(true /* markPoints */));
m_drapeApi.AddLine(
kGoldenLineId,
df::DrapeApiLineData(points, dp::Color(255, 127, 36, 255)).Width(4.0f).ShowPoints(true /* markPoints */));
}
void ClearGoldenPath() override
{
m_drapeApi.RemoveLine(kGoldenLineId);
}
void ClearGoldenPath() override { m_drapeApi.RemoveLine(kGoldenLineId); }
void ClearAllPaths() override
{
m_drapeApi.Clear();
}
void ClearAllPaths() override { m_drapeApi.Clear(); }
void VisualizePoints(std::vector<m2::PointD> const & points) override
{
@@ -104,10 +94,7 @@ public:
editSession.CreateUserMark<DebugMarkPoint>(p);
}
void ClearAllVisualizedPoints() override
{
m_bm.GetEditSession().ClearGroup(UserMark::Type::DEBUG_MARK);
}
void ClearAllVisualizedPoints() override { m_bm.GetEditSession().ClearGroup(UserMark::Type::DEBUG_MARK); }
private:
Framework & m_framework;
@@ -129,8 +116,7 @@ public:
, m_dataSource(const_cast<DataSource &>(GetDataSource()), nullptr /* numMwmIDs */)
, m_roadGraph(m_dataSource, routing::IRoadGraph::Mode::ObeyOnewayTag,
std::make_unique<routing::CarModelFactory>(storage::CountryParentGetter{}))
{
}
{}
std::vector<m2::PointD> GetAllJunctionPointsInViewport() const override
{
@@ -141,10 +127,8 @@ public:
if (!rect.IsPointInside(point))
return;
for (auto const & p : points)
{
if (PointsMatch(point, p))
return;
}
points.push_back(point);
};
@@ -155,11 +139,8 @@ public:
/// @todo Transported (railway=rail) are also present here :)
auto const roadClass = ftypes::GetHighwayClass(feature::TypesHolder(ft));
if (roadClass == ftypes::HighwayClass::Undefined ||
roadClass == ftypes::HighwayClass::Pedestrian)
{
if (roadClass == ftypes::HighwayClass::Undefined || roadClass == ftypes::HighwayClass::Pedestrian)
return;
}
ft.ForEachPoint(pushPoint, scales::GetUpperScale());
};
@@ -167,8 +148,7 @@ public:
return points;
}
std::pair<std::vector<FeaturePoint>, m2::PointD> GetCandidatePoints(
m2::PointD const & p) const override
std::pair<std::vector<FeaturePoint>, m2::PointD> GetCandidatePoints(m2::PointD const & p) const override
{
auto constexpr kInvalidIndex = std::numeric_limits<size_t>::max();
@@ -207,8 +187,7 @@ public:
std::vector<m2::PointD> GetReachablePoints(m2::PointD const & p) const override
{
routing::FeaturesRoadGraph::EdgeListT edges;
m_roadGraph.GetOutgoingEdges(geometry::PointWithAltitude(p, geometry::kDefaultAltitudeMeters),
edges);
m_roadGraph.GetOutgoingEdges(geometry::PointWithAltitude(p, geometry::kDefaultAltitudeMeters), edges);
std::vector<m2::PointD> points;
for (auto const & e : edges)
@@ -216,8 +195,7 @@ public:
return points;
}
ClickType CheckClick(m2::PointD const & clickPoint,
m2::PointD const & lastClickedPoint,
ClickType CheckClick(m2::PointD const & clickPoint, m2::PointD const & lastClickedPoint,
std::vector<m2::PointD> const & reachablePoints) const override
{
// == Comparison is safe here since |clickPoint| is adjusted by GetFeaturesPointsByPoint
@@ -225,10 +203,8 @@ public:
if (clickPoint == lastClickedPoint)
return ClickType::Remove;
for (auto const & p : reachablePoints)
{
if (PointsMatch(clickPoint, p))
return ClickType::Add;
}
return ClickType::Miss;
}
@@ -241,9 +217,7 @@ private:
};
} // namespace
MainWindow::MainWindow(Framework & framework)
: m_framework(framework)
MainWindow::MainWindow(Framework & framework) : m_framework(framework)
{
m_mapWidget = new MapWidget(m_framework, this /* parent */);
@@ -264,37 +238,37 @@ MainWindow::MainWindow(Framework & framework)
fileMenu->addAction("Open sample", QKeySequence("Ctrl+O"), this, &MainWindow::OnOpenTrafficSample);
m_closeTrafficSampleAction = fileMenu->addAction("Close sample", QKeySequence("Ctrl+W"), this, &MainWindow::OnCloseTrafficSample);
m_saveTrafficSampleAction = fileMenu->addAction("Save sample", QKeySequence("Ctrl+S"), this, &MainWindow::OnSaveTrafficSample);
m_closeTrafficSampleAction =
fileMenu->addAction("Close sample", QKeySequence("Ctrl+W"), this, &MainWindow::OnCloseTrafficSample);
m_saveTrafficSampleAction =
fileMenu->addAction("Save sample", QKeySequence("Ctrl+S"), this, &MainWindow::OnSaveTrafficSample);
fileMenu->addSeparator();
m_goldifyMatchedPathAction = fileMenu->addAction("Goldify", QKeySequence("Ctrl+G"), [this] { m_trafficMode->GoldifyMatchedPath(); });
m_startEditingAction = fileMenu->addAction("Edit", QKeySequence("Ctrl+E"),
[this] {
m_trafficMode->StartBuildingPath();
m_mapWidget->SetMode(MapWidget::Mode::TrafficMarkup);
m_commitPathAction->setEnabled(true /* enabled */);
m_cancelPathAction->setEnabled(true /* enabled */);
});
m_commitPathAction = fileMenu->addAction("Accept path",
QKeySequence("Ctrl+A"),
[this] {
m_trafficMode->CommitPath();
m_mapWidget->SetMode(MapWidget::Mode::Normal);
});
m_cancelPathAction = fileMenu->addAction("Revert path",
QKeySequence("Ctrl+R"),
[this] {
m_trafficMode->RollBackPath();
m_mapWidget->SetMode(MapWidget::Mode::Normal);
});
m_ignorePathAction = fileMenu->addAction("Ignore path",
QKeySequence("Ctrl+I"),
[this] {
m_trafficMode->IgnorePath();
m_mapWidget->SetMode(MapWidget::Mode::Normal);
});
m_goldifyMatchedPathAction =
fileMenu->addAction("Goldify", QKeySequence("Ctrl+G"), [this] { m_trafficMode->GoldifyMatchedPath(); });
m_startEditingAction = fileMenu->addAction("Edit", QKeySequence("Ctrl+E"), [this]
{
m_trafficMode->StartBuildingPath();
m_mapWidget->SetMode(MapWidget::Mode::TrafficMarkup);
m_commitPathAction->setEnabled(true /* enabled */);
m_cancelPathAction->setEnabled(true /* enabled */);
});
m_commitPathAction = fileMenu->addAction("Accept path", QKeySequence("Ctrl+A"), [this]
{
m_trafficMode->CommitPath();
m_mapWidget->SetMode(MapWidget::Mode::Normal);
});
m_cancelPathAction = fileMenu->addAction("Revert path", QKeySequence("Ctrl+R"), [this]
{
m_trafficMode->RollBackPath();
m_mapWidget->SetMode(MapWidget::Mode::Normal);
});
m_ignorePathAction = fileMenu->addAction("Ignore path", QKeySequence("Ctrl+I"), [this]
{
m_trafficMode->IgnorePath();
m_mapWidget->SetMode(MapWidget::Mode::Normal);
});
m_goldifyMatchedPathAction->setEnabled(false /* enabled */);
m_closeTrafficSampleAction->setEnabled(false /* enabled */);
@@ -307,15 +281,12 @@ MainWindow::MainWindow(Framework & framework)
void MainWindow::CreateTrafficPanel(std::string const & dataFilePath)
{
m_trafficMode = new TrafficMode(dataFilePath,
m_framework.GetDataSource(),
std::make_unique<TrafficDrawerDelegate>(m_framework),
std::make_unique<PointsControllerDelegate>(m_framework));
m_trafficMode =
new TrafficMode(dataFilePath, m_framework.GetDataSource(), std::make_unique<TrafficDrawerDelegate>(m_framework),
std::make_unique<PointsControllerDelegate>(m_framework));
connect(m_mapWidget, &MapWidget::TrafficMarkupClick,
m_trafficMode, &TrafficMode::OnClick);
connect(m_trafficMode, &TrafficMode::EditingStopped,
this, &MainWindow::OnPathEditingStop);
connect(m_mapWidget, &MapWidget::TrafficMarkupClick, m_trafficMode, &TrafficMode::OnClick);
connect(m_trafficMode, &TrafficMode::EditingStopped, this, &MainWindow::OnPathEditingStop);
connect(m_trafficMode, &TrafficMode::SegmentSelected,
[](int segmentId) { QApplication::clipboard()->setText(QString::number(segmentId)); });
@@ -391,11 +362,7 @@ void MainWindow::OnSaveTrafficSample()
return;
if (!m_trafficMode->SaveSampleAs(fileName.toStdString()))
{
QMessageBox::critical(
this, "Saving error",
QString("Can't save file: ") + strerror(errno));
}
QMessageBox::critical(this, "Saving error", QString("Can't save file: ") + strerror(errno));
}
void MainWindow::OnPathEditingStop()

View File

@@ -16,7 +16,7 @@ namespace openlr
class MapWidget;
class TrafficMode;
class WebView;
}
} // namespace openlr
namespace df
{
@@ -52,7 +52,7 @@ private:
QAction * m_saveTrafficSampleAction = nullptr;
QAction * m_closeTrafficSampleAction = nullptr;
QAction * m_startEditingAction = nullptr;
QAction * m_commitPathAction = nullptr;
QAction * m_commitPathAction = nullptr;
QAction * m_cancelPathAction = nullptr;
QAction * m_ignorePathAction = nullptr;

View File

@@ -8,10 +8,7 @@
namespace openlr
{
MapWidget::MapWidget(Framework & framework, QWidget * parent)
: Base(framework, false /* screenshotMode */, parent)
{
}
MapWidget::MapWidget(Framework & framework, QWidget * parent) : Base(framework, false /* screenshotMode */, parent) {}
void MapWidget::mousePressEvent(QMouseEvent * e)
{

View File

@@ -29,10 +29,7 @@ public:
void SetMode(Mode const mode) { m_mode = mode; }
QSize sizeHint() const override
{
return QSize(800, 600);
}
QSize sizeHint() const override { return QSize(800, 600); }
signals:
void TrafficMarkupClick(m2::PointD const & p, Qt::MouseButton const b);

View File

@@ -28,13 +28,11 @@ public:
virtual std::vector<m2::PointD> GetAllJunctionPointsInViewport() const = 0;
/// Returns all junction points at a given location in the form of feature id and
/// point index in the feature.
virtual std::pair<std::vector<FeaturePoint>, m2::PointD> GetCandidatePoints(
m2::PointD const & p) const = 0;
virtual std::pair<std::vector<FeaturePoint>, m2::PointD> GetCandidatePoints(m2::PointD const & p) const = 0;
// Returns all points that are one step reachable from |p|.
virtual std::vector<m2::PointD> GetReachablePoints(m2::PointD const & p) const = 0;
virtual ClickType CheckClick(m2::PointD const & clickPoint,
m2::PointD const & lastClickedPoint,
virtual ClickType CheckClick(m2::PointD const & clickPoint, m2::PointD const & lastClickedPoint,
std::vector<m2::PointD> const & reachablePoints) const = 0;
};
} // namespace openlr

View File

@@ -19,11 +19,9 @@ SegmentCorrespondence::SegmentCorrespondence(SegmentCorrespondence const & sc)
m_status = sc.m_status;
}
SegmentCorrespondence::SegmentCorrespondence(openlr::LinearSegment const & segment,
uint32_t positiveOffset, uint32_t negativeOffset,
openlr::Path const & matchedPath,
openlr::Path const & fakePath,
openlr::Path const & goldenPath,
SegmentCorrespondence::SegmentCorrespondence(openlr::LinearSegment const & segment, uint32_t positiveOffset,
uint32_t negativeOffset, openlr::Path const & matchedPath,
openlr::Path const & fakePath, openlr::Path const & goldenPath,
pugi::xml_node const & partnerSegmentXML)
: m_partnerSegment(segment)
, m_positiveOffset(positiveOffset)

View File

@@ -18,12 +18,9 @@ public:
};
SegmentCorrespondence(SegmentCorrespondence const & sc);
SegmentCorrespondence(openlr::LinearSegment const & segment,
uint32_t positiveOffset, uint32_t negativeOffset,
openlr::Path const & matchedPath,
openlr::Path const & fakePath,
openlr::Path const & goldenPath,
pugi::xml_node const & partnerSegmentXML);
SegmentCorrespondence(openlr::LinearSegment const & segment, uint32_t positiveOffset, uint32_t negativeOffset,
openlr::Path const & matchedPath, openlr::Path const & fakePath,
openlr::Path const & goldenPath, pugi::xml_node const & partnerSegmentXML);
openlr::Path const & GetMatchedPath() const { return m_matchedPath; }
bool HasMatchedPath() const { return !m_matchedPath.empty(); }

View File

@@ -16,14 +16,12 @@ namespace
{
void RemovePointFromPull(m2::PointD const & toBeRemoved, std::vector<m2::PointD> & pool)
{
pool.erase(
remove_if(begin(pool), end(pool),
[&toBeRemoved](m2::PointD const & p) { return p.EqualDxDy(toBeRemoved, 1e-6); }),
end(pool));
pool.erase(remove_if(begin(pool), end(pool),
[&toBeRemoved](m2::PointD const & p) { return p.EqualDxDy(toBeRemoved, 1e-6); }),
end(pool));
}
std::vector<m2::PointD> GetReachablePoints(m2::PointD const & srcPoint,
std::vector<m2::PointD> const path,
std::vector<m2::PointD> GetReachablePoints(m2::PointD const & srcPoint, std::vector<m2::PointD> const path,
PointsControllerDelegateBase const & pointsDelegate,
size_t const lookbackIndex)
{
@@ -46,8 +44,7 @@ size_t const RoadPointCandidate::kInvalidId = std::numeric_limits<size_t>::max()
/// I.e. it is a set of all pairs <FeatureID, point index>
/// located at a specified coordinate.
/// Only one point at a time is considered active.
RoadPointCandidate::RoadPointCandidate(std::vector<FeaturePoint> const & points,
m2::PointD const & coord)
RoadPointCandidate::RoadPointCandidate(std::vector<FeaturePoint> const & points, m2::PointD const & coord)
: m_coord(coord)
, m_points(points)
{
@@ -98,8 +95,7 @@ void RoadPointCandidate::SetActivePoint(FeatureID const & fid)
// TrafficMode -------------------------------------------------------------------------------------
TrafficMode::TrafficMode(std::string const & dataFileName, DataSource const & dataSource,
std::unique_ptr<TrafficDrawerDelegateBase> drawerDelegate,
std::unique_ptr<PointsControllerDelegateBase> pointsDelegate,
QObject * parent)
std::unique_ptr<PointsControllerDelegateBase> pointsDelegate, QObject * parent)
: QAbstractTableModel(parent)
, m_dataSource(dataSource)
, m_drawerDelegate(std::move(drawerDelegate))
@@ -153,8 +149,7 @@ TrafficMode::TrafficMode(std::string const & dataFileName, DataSource const & da
{
if (auto const locationReference = method.child("olr:locationReference"))
{
if (auto const optionLinearLocationReference = locationReference
.child("olr:optionLinearLocationReference"))
if (auto const optionLinearLocationReference = locationReference.child("olr:optionLinearLocationReference"))
{
if (auto const positiveOffset = optionLinearLocationReference.child("olr:positiveOffset"))
positiveOffsetM = UintValueFromXML(positiveOffset);
@@ -166,8 +161,8 @@ TrafficMode::TrafficMode(std::string const & dataFileName, DataSource const & da
}
}
m_segments.emplace_back(segment, positiveOffsetM, negativeOffsetM, matchedPath, fakePath,
goldenPath, partnerSegmentXML);
m_segments.emplace_back(segment, positiveOffsetM, negativeOffsetM, matchedPath, fakePath, goldenPath,
partnerSegmentXML);
if (auto const status = xmlSegment.child("Ignored"))
{
if (status.text().as_bool())
@@ -198,9 +193,7 @@ bool TrafficMode::SaveSampleAs(std::string const & fileName) const
segment.append_copy(sc.GetPartnerXMLSegment());
if (sc.GetStatus() == SegmentCorrespondence::Status::Ignored)
{
segment.append_child("Ignored").text() = true;
}
if (sc.HasMatchedPath())
{
auto node = segment.append_child("Route");
@@ -222,14 +215,17 @@ bool TrafficMode::SaveSampleAs(std::string const & fileName) const
return true;
}
int TrafficMode::rowCount(const QModelIndex & parent) const
int TrafficMode::rowCount(QModelIndex const & parent) const
{
return static_cast<int>(m_segments.size());
}
int TrafficMode::columnCount(const QModelIndex & parent) const { return 4; }
int TrafficMode::columnCount(QModelIndex const & parent) const
{
return 4;
}
QVariant TrafficMode::data(const QModelIndex & index, int role) const
QVariant TrafficMode::data(QModelIndex const & index, int role) const
{
if (!index.isValid())
return QVariant();
@@ -255,8 +251,7 @@ QVariant TrafficMode::data(const QModelIndex & index, int role) const
return QVariant();
}
QVariant TrafficMode::headerData(int section, Qt::Orientation orientation,
int role /* = Qt::DisplayRole */) const
QVariant TrafficMode::headerData(int section, Qt::Orientation orientation, int role /* = Qt::DisplayRole */) const
{
if (orientation != Qt::Horizontal && role != Qt::DisplayRole)
return QVariant();
@@ -309,8 +304,7 @@ void TrafficMode::GoldifyMatchedPath()
{
if (!m_currentSegment->HasMatchedPath())
{
QMessageBox::information(nullptr /* parent */, "Error",
"The selected segment does not have a matched path");
QMessageBox::information(nullptr /* parent */, "Error", "The selected segment does not have a matched path");
return;
}
@@ -384,10 +378,10 @@ void TrafficMode::CommitPath()
auto const & prevFt = prevPoint.GetPoint();
auto const & ft = point.GetPoint();
path.push_back(Edge::MakeReal(
ft.first, prevFt.second < ft.second /* forward */, base::checked_cast<uint32_t>(prevFt.second),
geometry::PointWithAltitude(prevPoint.GetCoordinate(), 0 /* altitude */),
geometry::PointWithAltitude(point.GetCoordinate(), 0 /* altitude */)));
path.push_back(Edge::MakeReal(ft.first, prevFt.second < ft.second /* forward */,
base::checked_cast<uint32_t>(prevFt.second),
geometry::PointWithAltitude(prevPoint.GetCoordinate(), 0 /* altitude */),
geometry::PointWithAltitude(point.GetCoordinate(), 0 /* altitude */)));
}
m_currentSegment->SetGoldenPath(path);
@@ -417,9 +411,8 @@ void TrafficMode::IgnorePath()
if (m_currentSegment->HasGoldenPath())
{
auto const btn =
QMessageBox::question(nullptr /* parent */, "Override warning",
"The selected segment has a golden path. Do you want to discard it?");
auto const btn = QMessageBox::question(nullptr /* parent */, "Override warning",
"The selected segment has a golden path. Do you want to discard it?");
if (btn == QMessageBox::No)
return;
}
@@ -466,9 +459,7 @@ void TrafficMode::HandlePoint(m2::PointD clickPoint, Qt::MouseButton const butto
return;
auto const currentPathLength = GetPointsCount();
auto const lastClickedPoint = currentPathLength != 0
? GetLastPoint()
: m2::PointD::Zero();
auto const lastClickedPoint = currentPathLength != 0 ? GetLastPoint() : m2::PointD::Zero();
auto const & p = m_pointsDelegate->GetCandidatePoints(clickPoint);
auto const & candidatePoints = p.first;
@@ -476,14 +467,14 @@ void TrafficMode::HandlePoint(m2::PointD clickPoint, Qt::MouseButton const butto
if (candidatePoints.empty())
return;
auto reachablePoints = GetReachablePoints(clickPoint, GetGoldenPathPoints(), *m_pointsDelegate,
0 /* lookBackIndex */);
auto const & clickablePoints = currentPathLength != 0
? GetReachablePoints(lastClickedPoint, GetGoldenPathPoints(), *m_pointsDelegate,
1 /* lookbackIndex */)
// TODO(mgsergio): This is not quite correct since view port can change
// since first call to visualize points. But it's ok in general.
: m_pointsDelegate->GetAllJunctionPointsInViewport();
auto reachablePoints =
GetReachablePoints(clickPoint, GetGoldenPathPoints(), *m_pointsDelegate, 0 /* lookBackIndex */);
auto const & clickablePoints =
currentPathLength != 0
? GetReachablePoints(lastClickedPoint, GetGoldenPathPoints(), *m_pointsDelegate, 1 /* lookbackIndex */)
// TODO(mgsergio): This is not quite correct since view port can change
// since first call to visualize points. But it's ok in general.
: m_pointsDelegate->GetAllJunctionPointsInViewport();
using ClickType = PointsControllerDelegateBase::ClickType;
switch (m_pointsDelegate->CheckClick(clickPoint, lastClickedPoint, clickablePoints))
@@ -518,8 +509,8 @@ void TrafficMode::HandlePoint(m2::PointD clickPoint, Qt::MouseButton const butto
}
else
{
m_drawerDelegate->VisualizePoints(GetReachablePoints(
GetLastPoint(), GetGoldenPathPoints(), *m_pointsDelegate, 1 /* lookBackIndex */));
m_drawerDelegate->VisualizePoints(
GetReachablePoints(GetLastPoint(), GetGoldenPathPoints(), *m_pointsDelegate, 1 /* lookBackIndex */));
}
if (GetPointsCount() > 1)
@@ -546,9 +537,8 @@ bool TrafficMode::StartBuildingPathChecks() const
if (m_currentSegment->HasGoldenPath())
{
auto const btn = QMessageBox::question(
nullptr /* parent */, "Override warning",
"The selected segment already has a golden path. Do you want to override?");
auto const btn = QMessageBox::question(nullptr /* parent */, "Override warning",
"The selected segment already has a golden path. Do you want to override?");
if (btn == QMessageBox::No)
return false;
}

View File

@@ -18,7 +18,6 @@
#include <QAbstractTableModel>
class QItemSelection;
class Selection;
@@ -35,8 +34,7 @@ namespace impl
class RoadPointCandidate
{
public:
RoadPointCandidate(std::vector<openlr::FeaturePoint> const & points,
m2::PointD const & coord);
RoadPointCandidate(std::vector<openlr::FeaturePoint> const & points, m2::PointD const & coord);
void ActivateCommonPoint(RoadPointCandidate const & rpc);
openlr::FeaturePoint const & GetPoint() const;
@@ -64,25 +62,22 @@ public:
// TODO(mgsergio): Check we are on the right mwm. I.e. right mwm version and everything.
TrafficMode(std::string const & dataFileName, DataSource const & dataSource,
std::unique_ptr<TrafficDrawerDelegateBase> drawerDelegate,
std::unique_ptr<PointsControllerDelegateBase> pointsDelegate,
QObject * parent = Q_NULLPTR);
std::unique_ptr<PointsControllerDelegateBase> pointsDelegate, QObject * parent = Q_NULLPTR);
bool SaveSampleAs(std::string const & fileName) const;
int rowCount(const QModelIndex & parent = QModelIndex()) const Q_DECL_OVERRIDE;
int columnCount(const QModelIndex & parent = QModelIndex()) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
int rowCount(QModelIndex const & parent = QModelIndex()) const Q_DECL_OVERRIDE;
int columnCount(QModelIndex const & parent = QModelIndex()) const Q_DECL_OVERRIDE;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE;
QVariant data(const QModelIndex & index, int role) const Q_DECL_OVERRIDE;
QVariant data(QModelIndex const & index, int role) const Q_DECL_OVERRIDE;
Qt::ItemFlags flags(QModelIndex const & index) const Q_DECL_OVERRIDE;
bool IsBuildingPath() const { return m_buildingPath; }
void GoldifyMatchedPath();
void StartBuildingPath();
void PushPoint(m2::PointD const & coord,
std::vector<FeaturePoint> const & points);
void PushPoint(m2::PointD const & coord, std::vector<FeaturePoint> const & points);
void PopPoint();
void CommitPath();
void RollBackPath();
@@ -95,10 +90,7 @@ public:
public slots:
void OnItemSelected(QItemSelection const & selected, QItemSelection const &);
void OnClick(m2::PointD const & clickPoint, Qt::MouseButton const button)
{
HandlePoint(clickPoint, button);
}
void OnClick(m2::PointD const & clickPoint, Qt::MouseButton const button) { HandlePoint(clickPoint, button); }
signals:
void EditingStopped();

View File

@@ -11,10 +11,7 @@
namespace openlr
{
// ComboBoxDelegate --------------------------------------------------------------------------------
ComboBoxDelegate::ComboBoxDelegate(QObject * parent)
: QStyledItemDelegate(parent)
{
}
ComboBoxDelegate::ComboBoxDelegate(QObject * parent) : QStyledItemDelegate(parent) {}
QWidget * ComboBoxDelegate::createEditor(QWidget * parent, QStyleOptionViewItem const & option,
QModelIndex const & index) const
@@ -30,13 +27,12 @@ QWidget * ComboBoxDelegate::createEditor(QWidget * parent, QStyleOptionViewItem
void ComboBoxDelegate::setEditorData(QWidget * editor, QModelIndex const & index) const
{
auto const value = index.model()->data(index, Qt::EditRole).toString();
static_cast<QComboBox*>(editor)->setCurrentText(value);
static_cast<QComboBox *>(editor)->setCurrentText(value);
}
void ComboBoxDelegate::setModelData(QWidget * editor, QAbstractItemModel * model,
QModelIndex const & index) const
void ComboBoxDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, QModelIndex const & index) const
{
model->setData(index, static_cast<QComboBox*>(editor)->currentText(), Qt::EditRole);
model->setData(index, static_cast<QComboBox *>(editor)->currentText(), Qt::EditRole);
}
void ComboBoxDelegate::updateEditorGeometry(QWidget * editor, QStyleOptionViewItem const & option,
@@ -46,8 +42,7 @@ void ComboBoxDelegate::updateEditorGeometry(QWidget * editor, QStyleOptionViewIt
}
// TrafficPanel ------------------------------------------------------------------------------------
TrafficPanel::TrafficPanel(QAbstractItemModel * trafficModel, QWidget * parent)
: QWidget(parent)
TrafficPanel::TrafficPanel(QAbstractItemModel * trafficModel, QWidget * parent) : QWidget(parent)
{
CreateTable(trafficModel);
@@ -75,8 +70,7 @@ void TrafficPanel::CreateTable(QAbstractItemModel * trafficModel)
m_table->setModel(trafficModel);
m_table->setItemDelegate(new ComboBoxDelegate());
connect(m_table->selectionModel(),
SIGNAL(selectionChanged(QItemSelection const &, QItemSelection const &)),
connect(m_table->selectionModel(), SIGNAL(selectionChanged(QItemSelection const &, QItemSelection const &)),
trafficModel, SLOT(OnItemSelected(QItemSelection const &, QItemSelection const &)));
}
} // namespace openlr

View File

@@ -21,8 +21,7 @@ public:
void setEditorData(QWidget * editor, QModelIndex const & index) const Q_DECL_OVERRIDE;
void setModelData(QWidget * editor, QAbstractItemModel * model,
QModelIndex const & index) const Q_DECL_OVERRIDE;
void setModelData(QWidget * editor, QAbstractItemModel * model, QModelIndex const & index) const Q_DECL_OVERRIDE;
void updateEditorGeometry(QWidget * editor, QStyleOptionViewItem const & option,
QModelIndex const & index) const Q_DECL_OVERRIDE;

View File

@@ -14,9 +14,7 @@ std::string const kDataFilePath = "LastOpenlrAssessmentDataFilePath";
namespace openlr
{
TrafficModeInitDlg::TrafficModeInitDlg(QWidget * parent) :
QDialog(parent),
m_ui(new Ui::TrafficModeInitDlg)
TrafficModeInitDlg::TrafficModeInitDlg(QWidget * parent) : QDialog(parent), m_ui(new Ui::TrafficModeInitDlg)
{
m_ui->setupUi(this);
@@ -24,9 +22,8 @@ TrafficModeInitDlg::TrafficModeInitDlg(QWidget * parent) :
if (settings::Get(kDataFilePath, lastDataFilePath))
m_ui->dataFileName->setText(QString::fromStdString(lastDataFilePath));
connect(m_ui->chooseDataFileButton, &QPushButton::clicked, [this](bool) {
SetFilePathViaDialog(*m_ui->dataFileName, tr("Choose data file"), "*.xml");
});
connect(m_ui->chooseDataFileButton, &QPushButton::clicked,
[this](bool) { SetFilePathViaDialog(*m_ui->dataFileName, tr("Choose data file"), "*.xml"); });
}
TrafficModeInitDlg::~TrafficModeInitDlg()
@@ -41,8 +38,7 @@ void TrafficModeInitDlg::accept()
QDialog::accept();
}
void TrafficModeInitDlg::SetFilePathViaDialog(QLineEdit & dest, QString const & title,
QString const & filter)
void TrafficModeInitDlg::SetFilePathViaDialog(QLineEdit & dest, QString const & title, QString const & filter)
{
QFileDialog openFileDlg(nullptr, title, {} /* directory */, filter);
openFileDlg.exec();

View File

@@ -20,9 +20,7 @@ bool IntegerFromXML(pugi::xml_node const & node, Value & value)
{
if (!node)
return false;
value = static_cast<Value>(is_signed<Value>::value
? node.text().as_int()
: node.text().as_uint());
value = static_cast<Value>(is_signed<Value>::value ? node.text().as_int() : node.text().as_uint());
return true;
}
@@ -33,11 +31,8 @@ std::optional<double> DoubleFromXML(pugi::xml_node const & node)
bool GetLatLon(pugi::xml_node const & node, int32_t & lat, int32_t & lon)
{
if (!IntegerFromXML(node.child("olr:latitude"), lat) ||
!IntegerFromXML(node.child("olr:longitude"), lon))
{
if (!IntegerFromXML(node.child("olr:latitude"), lat) || !IntegerFromXML(node.child("olr:longitude"), lon))
return false;
}
return true;
}
@@ -49,9 +44,8 @@ bool TableValueFromXML(pugi::xml_node const & node, Value & value)
{
if (!node)
return false;
value = static_cast<Value>(is_signed<Value>::value
? node.attribute("olr:code").as_int()
: node.attribute("olr:code").as_uint());
value = static_cast<Value>(is_signed<Value>::value ? node.attribute("olr:code").as_int()
: node.attribute("olr:code").as_uint());
return true;
}
@@ -66,7 +60,6 @@ pugi::xml_node GetCoordinates(pugi::xml_node const & node)
return node.select_node(".//coordinates").node();
}
bool IsLocationReferenceTag(pugi::xml_node const & node)
{
return node.select_node(".//olr:locationReference").node();
@@ -119,8 +112,7 @@ std::optional<ms::LatLon> LatLonFormXML(pugi::xml_node const & node)
return lat && lon ? ms::LatLon(*lat, *lon) : ms::LatLon::Zero();
}
bool CoordinateFromXML(pugi::xml_node const & node, ms::LatLon const & prevCoord,
ms::LatLon & latLon)
bool CoordinateFromXML(pugi::xml_node const & node, ms::LatLon const & prevCoord, ms::LatLon & latLon)
{
int32_t lat, lon;
if (!GetLatLon(node.child("olr:coordinate"), lat, lon))
@@ -136,8 +128,7 @@ bool CoordinateFromXML(pugi::xml_node const & node, ms::LatLon const & prevCoord
return true;
}
bool LinePropertiesFromXML(pugi::xml_node const & linePropNode,
openlr::LocationReferencePoint & locPoint)
bool LinePropertiesFromXML(pugi::xml_node const & linePropNode, openlr::LocationReferencePoint & locPoint)
{
if (!linePropNode)
{
@@ -166,8 +157,7 @@ bool LinePropertiesFromXML(pugi::xml_node const & linePropNode,
return true;
}
bool PathPropertiesFromXML(pugi::xml_node const & locPointNode,
openlr::LocationReferencePoint & locPoint)
bool PathPropertiesFromXML(pugi::xml_node const & locPointNode, openlr::LocationReferencePoint & locPoint)
{
// Last point does not contain path properties.
if (strcmp(locPointNode.name(), "olr:last") == 0)
@@ -203,8 +193,7 @@ bool PathPropertiesFromXML(pugi::xml_node const & locPointNode,
return true;
}
bool LocationReferencePointFromXML(pugi::xml_node const & locPointNode,
openlr::LocationReferencePoint & locPoint)
bool LocationReferencePointFromXML(pugi::xml_node const & locPointNode, openlr::LocationReferencePoint & locPoint)
{
if (!FirstCoordinateFromXML(locPointNode, locPoint.m_latLon))
{
@@ -216,8 +205,7 @@ bool LocationReferencePointFromXML(pugi::xml_node const & locPointNode,
PathPropertiesFromXML(locPointNode, locPoint);
}
bool LocationReferencePointFromXML(pugi::xml_node const & locPointNode,
ms::LatLon const & firstPoint,
bool LocationReferencePointFromXML(pugi::xml_node const & locPointNode, ms::LatLon const & firstPoint,
openlr::LocationReferencePoint & locPoint)
{
if (!CoordinateFromXML(locPointNode, firstPoint, locPoint.m_latLon))
@@ -230,8 +218,7 @@ bool LocationReferencePointFromXML(pugi::xml_node const & locPointNode,
PathPropertiesFromXML(locPointNode, locPoint);
}
bool LinearLocationReferenceFromXML(pugi::xml_node const & locRefNode,
openlr::LinearLocationReference & locRef)
bool LinearLocationReferenceFromXML(pugi::xml_node const & locRefNode, openlr::LinearLocationReference & locRef)
{
if (!locRefNode)
{
@@ -256,8 +243,7 @@ bool LinearLocationReferenceFromXML(pugi::xml_node const & locRefNode,
{
openlr::LocationReferencePoint point;
if (!LocationReferencePointFromXML(locRefNode.child("olr:last"),
locRef.m_points.back().m_latLon, point))
if (!LocationReferencePointFromXML(locRefNode.child("olr:last"), locRef.m_points.back().m_latLon, point))
return false;
locRef.m_points.push_back(point);
}
@@ -268,7 +254,7 @@ bool LinearLocationReferenceFromXML(pugi::xml_node const & locRefNode,
return false;
}
if(!ParseValueIfExists(locRefNode.child("olr:negativeOffset"), locRef.m_negativeOffsetMeters))
if (!ParseValueIfExists(locRefNode.child("olr:negativeOffset"), locRef.m_negativeOffsetMeters))
{
LOG(LERROR, ("Can't parse negative offset"));
return false;

View File

@@ -35,8 +35,7 @@ DEFINE_string(input, "", "Path to OpenLR file.");
DEFINE_string(spark_output, "", "Path to output file in spark-oriented format");
DEFINE_string(assessment_output, "", "Path to output file in assessment-tool oriented format");
DEFINE_string(non_matched_ids, "non-matched-ids.txt",
"Path to a file ids of non-matched segments will be saved to");
DEFINE_string(non_matched_ids, "non-matched-ids.txt", "Path to a file ids of non-matched segments will be saved to");
DEFINE_string(mwms_path, "", "Path to a folder with mwms.");
DEFINE_string(resources_path, "", "Path to a folder with resources.");
DEFINE_int32(limit, -1, "Max number of segments to handle. -1 for all.");
@@ -56,8 +55,7 @@ int32_t const kMinNumThreads = 1;
int32_t const kMaxNumThreads = 128;
int32_t const kHandleAllSegments = -1;
void LoadDataSources(std::string const & pathToMWMFolder,
std::vector<FrozenDataSource> & dataSources)
void LoadDataSources(std::string const & pathToMWMFolder, std::vector<FrozenDataSource> & dataSources)
{
CHECK(Platform::IsDirectory(pathToMWMFolder), (pathToMWMFolder, "must be a directory."));
@@ -73,8 +71,7 @@ void LoadDataSources(std::string const & pathToMWMFolder,
{
auto const fullFileName = base::JoinPath(pathToMWMFolder, fileName);
ModelReaderPtr reader(GetPlatform().GetReader(fullFileName, "f"));
platform::LocalCountryFile localFile(pathToMWMFolder,
platform::CountryFile(base::FilenameWithoutExt(fileName)),
platform::LocalCountryFile localFile(pathToMWMFolder, platform::CountryFile(base::FilenameWithoutExt(fileName)),
version::ReadVersionDate(reader));
LOG(LINFO, ("Found mwm:", fullFileName));
@@ -98,18 +95,15 @@ void LoadDataSources(std::string const & pathToMWMFolder,
}
for (size_t i = 0; i < numDataSources; ++i)
{
if (numCountries[i] == 0)
LOG(LWARNING, ("No countries for thread", i));
}
}
bool ValidateLimit(char const * flagname, int32_t value)
{
if (value < -1)
{
LOG(LINFO, ("Valid value for --", std::string(flagname), ":", value,
"must be greater or equal to -1."));
LOG(LINFO, ("Valid value for --", std::string(flagname), ":", value, "must be greater or equal to -1."));
return false;
}
@@ -120,8 +114,8 @@ bool ValidateNumThreads(char const * flagname, int32_t value)
{
if (value < kMinNumThreads || value > kMaxNumThreads)
{
LOG(LINFO, ("Valid value for --", std::string(flagname), ":", value, "must be between",
kMinNumThreads, "and", kMaxNumThreads));
LOG(LINFO, ("Valid value for --", std::string(flagname), ":", value, "must be between", kMinNumThreads, "and",
kMaxNumThreads));
return false;
}
@@ -157,8 +151,7 @@ bool ValidateVersion(char const * flagname, int32_t value)
}
bool const g_limitDummy = gflags::RegisterFlagValidator(&FLAGS_limit, &ValidateLimit);
bool const g_numThreadsDummy =
gflags::RegisterFlagValidator(&FLAGS_num_threads, &ValidateNumThreads);
bool const g_numThreadsDummy = gflags::RegisterFlagValidator(&FLAGS_num_threads, &ValidateNumThreads);
bool const g_mwmsPathDummy = gflags::RegisterFlagValidator(&FLAGS_mwms_path, &ValidateMwmPath);
bool const g_algoVersion = gflags::RegisterFlagValidator(&FLAGS_algo_version, &ValidateVersion);
@@ -169,10 +162,8 @@ void SaveNonMatchedIds(std::string const & filename, std::vector<DecodedPath> co
std::ofstream ofs(filename);
for (auto const & p : paths)
{
if (p.m_path.empty())
ofs << p.m_segmentId << std::endl;
}
}
std::vector<LinearSegment> LoadSegments(pugi::xml_document & document)
@@ -185,14 +176,10 @@ std::vector<LinearSegment> LoadSegments(pugi::xml_document & document)
}
OpenLRDecoder::SegmentsFilter filter(FLAGS_ids_path, FLAGS_multipoints_only);
if (FLAGS_limit != kHandleAllSegments && FLAGS_limit >= 0 &&
static_cast<size_t>(FLAGS_limit) < segments.size())
{
if (FLAGS_limit != kHandleAllSegments && FLAGS_limit >= 0 && static_cast<size_t>(FLAGS_limit) < segments.size())
segments.resize(FLAGS_limit);
}
base::EraseIf(segments,
[&filter](LinearSegment const & segment) { return !filter.Matches(segment); });
base::EraseIf(segments, [&filter](LinearSegment const & segment) { return !filter.Matches(segment); });
std::sort(segments.begin(), segments.end(), base::LessBy(&LinearSegment::m_segmentId));
@@ -261,8 +248,8 @@ int main(int argc, char * argv[])
LoadDataSources(FLAGS_mwms_path, dataSources);
OpenLRDecoder decoder(dataSources, storage::CountryParentGetter(FLAGS_countries_filename,
GetPlatform().ResourcesDir()));
OpenLRDecoder decoder(dataSources,
storage::CountryParentGetter(FLAGS_countries_filename, GetPlatform().ResourcesDir()));
pugi::xml_document document;
auto const load_result = document.load_file(FLAGS_input.data());

View File

@@ -14,8 +14,8 @@
#include "platform/platform_tests_support/scoped_dir.hpp"
#include "platform/platform_tests_support/scoped_file.hpp"
#include "base/file_name_utils.hpp"
#include "base/checked_cast.hpp"
#include "base/file_name_utils.hpp"
#include <algorithm>
#include <iomanip>
@@ -43,7 +43,10 @@ double RoughUpToFive(double d)
return d;
}
m2::PointD RoughPoint(m2::PointD const & p) { return {RoughUpToFive(p.x), RoughUpToFive(p.y)}; }
m2::PointD RoughPoint(m2::PointD const & p)
{
return {RoughUpToFive(p.x), RoughUpToFive(p.y)};
}
geometry::PointWithAltitude RoughJunction(geometry::PointWithAltitude const & j)
{
@@ -52,8 +55,7 @@ geometry::PointWithAltitude RoughJunction(geometry::PointWithAltitude const & j)
routing::Edge RoughEdgeJunctions(routing::Edge const & e)
{
return routing::Edge::MakeReal(e.GetFeatureId(), e.IsForward(), e.GetSegId(),
RoughJunction(e.GetStartJunction()),
return routing::Edge::MakeReal(e.GetFeatureId(), e.IsForward(), e.GetSegId(), RoughJunction(e.GetStartJunction()),
RoughJunction(e.GetEndJunction()));
}
@@ -103,10 +105,8 @@ openlr::Path MakePath(FeatureType const & road, bool const forward)
auto const from = road.GetPoint(current);
auto const to = road.GetPoint(next);
path.push_back(routing::Edge::MakeReal(
road.GetID(), forward,
base::checked_cast<uint32_t>(current - static_cast<size_t>(!forward)) /* segId */,
geometry::PointWithAltitude(from, 0 /* altitude */),
geometry::PointWithAltitude(to, 0 /* altitude */)));
road.GetID(), forward, base::checked_cast<uint32_t>(current - static_cast<size_t>(!forward)) /* segId */,
geometry::PointWithAltitude(from, 0 /* altitude */), geometry::PointWithAltitude(to, 0 /* altitude */)));
}
RoughJunctionsInPath(path);
@@ -124,8 +124,7 @@ void WithRoad(vector<m2::PointD> const & points, Func && fn)
LocalCountryFile country(mwmPath, CountryFile(kTestMwm), 0 /* version */);
ScopedDir testScopedDir(kTestDir);
ScopedFile testScopedMwm(base::JoinPath(kTestDir, kTestMwm + DATA_FILE_EXTENSION),
ScopedFile::Mode::Create);
ScopedFile testScopedMwm(base::JoinPath(kTestDir, kTestMwm + DATA_FILE_EXTENSION), ScopedFile::Mode::Create);
{
TestMwmBuilder builder(country, feature::DataHeader::MapType::Country);
@@ -150,21 +149,20 @@ void WithRoad(vector<m2::PointD> const & points, Func && fn)
UNIT_TEST(MakePath_Test)
{
std::vector<m2::PointD> const points{{0, 0}, {0, 1}, {1, 0}, {1, 1}};
WithRoad(points, [&points](DataSource const & dataSource, FeatureType & road) {
WithRoad(points, [&points](DataSource const & dataSource, FeatureType & road)
{
auto const & id = road.GetID();
{
openlr::Path const expected{
routing::Edge::MakeReal(id, true /* forward */, 0 /* segId*/, points[0], points[1]),
routing::Edge::MakeReal(id, true /* forward */, 1 /* segId*/, points[1], points[2]),
routing::Edge::MakeReal(id, true /* forward */, 2 /* segId*/, points[2], points[3])};
openlr::Path const expected{routing::Edge::MakeReal(id, true /* forward */, 0 /* segId*/, points[0], points[1]),
routing::Edge::MakeReal(id, true /* forward */, 1 /* segId*/, points[1], points[2]),
routing::Edge::MakeReal(id, true /* forward */, 2 /* segId*/, points[2], points[3])};
auto const path = MakePath(road, true /* forward */);
TEST_EQUAL(path, expected, ());
}
{
openlr::Path const expected{
routing::Edge::MakeReal(id, false /* forward */, 2 /* segId*/, points[3], points[2]),
routing::Edge::MakeReal(id, false /* forward */, 1 /* segId*/, points[2], points[1]),
routing::Edge::MakeReal(id, false /* forward */, 0 /* segId*/, points[1], points[0])};
openlr::Path const expected{routing::Edge::MakeReal(id, false /* forward */, 2 /* segId*/, points[3], points[2]),
routing::Edge::MakeReal(id, false /* forward */, 1 /* segId*/, points[2], points[1]),
routing::Edge::MakeReal(id, false /* forward */, 0 /* segId*/, points[1], points[0])};
{
auto const path = MakePath(road, false /* forward */);
TEST_EQUAL(path, expected, ());
@@ -175,7 +173,8 @@ UNIT_TEST(MakePath_Test)
UNIT_TEST(PathSerializeDeserialize_Test)
{
WithRoad({{0, 0}, {0, 1}, {1, 0}, {1, 1}}, [](DataSource const & dataSource, FeatureType & road) {
WithRoad({{0, 0}, {0, 1}, {1, 0}, {1, 1}}, [](DataSource const & dataSource, FeatureType & road)
{
{
auto const path = MakePath(road, true /* forward */);
TestSerializeDeserialize(path, dataSource);
@@ -190,7 +189,8 @@ UNIT_TEST(PathSerializeDeserialize_Test)
UNIT_TEST(GetPoints_Test)
{
vector<m2::PointD> const points{{0, 0}, {0, 1}, {1, 0}, {1, 1}};
WithRoad(points, [&points](DataSource const &, FeatureType & road) {
WithRoad(points, [&points](DataSource const &, FeatureType & road)
{
{
auto path = MakePath(road, true /* forward */);
// RoughJunctionsInPath(path);

View File

@@ -16,24 +16,20 @@ namespace openlr
{
namespace
{
bool ValidatePath(Graph::EdgeVector const & path,
double const distanceToNextPoint,
double const pathLengthTolerance)
bool ValidatePath(Graph::EdgeVector const & path, double const distanceToNextPoint, double const pathLengthTolerance)
{
double pathLen = 0.0;
for (auto const & e : path)
pathLen += EdgeLength(e);
double pathDiffPercent = AbsDifference(static_cast<double>(distanceToNextPoint), pathLen) /
static_cast<double>(distanceToNextPoint);
double pathDiffPercent =
AbsDifference(static_cast<double>(distanceToNextPoint), pathLen) / static_cast<double>(distanceToNextPoint);
LOG(LDEBUG, ("Validating path:", LogAs2GisPath(path)));
if (pathDiffPercent > pathLengthTolerance)
{
LOG(LDEBUG,
("Shortest path doest not meet required length constraints, error:", pathDiffPercent));
LOG(LDEBUG, ("Shortest path doest not meet required length constraints, error:", pathDiffPercent));
return false;
}
@@ -41,14 +37,12 @@ bool ValidatePath(Graph::EdgeVector const & path,
}
} // namespace
PathsConnector::PathsConnector(double pathLengthTolerance, Graph & graph,
RoadInfoGetter & infoGetter, v2::Stats & stat)
PathsConnector::PathsConnector(double pathLengthTolerance, Graph & graph, RoadInfoGetter & infoGetter, v2::Stats & stat)
: m_pathLengthTolerance(pathLengthTolerance)
, m_graph(graph)
, m_infoGetter(infoGetter)
, m_stat(stat)
{
}
{}
bool PathsConnector::ConnectCandidates(vector<LocationReferencePoint> const & points,
vector<vector<Graph::EdgeVector>> const & lineCandidates,
@@ -79,16 +73,14 @@ bool PathsConnector::ConnectCandidates(vector<LocationReferencePoint> const & po
{
resultPathPart.clear();
found = ConnectAdjacentCandidateLines(fromCandidates[fromInd], toCandidates[toInd],
point.m_lfrcnp, distanceToNextPoint,
resultPathPart);
found = ConnectAdjacentCandidateLines(fromCandidates[fromInd], toCandidates[toInd], point.m_lfrcnp,
distanceToNextPoint, resultPathPart);
if (!found)
continue;
found = ValidatePath(resultPathPart, distanceToNextPoint, m_pathLengthTolerance);
if (fakePath.empty() && found &&
(resultPathPart.front().IsFake() || resultPathPart.back().IsFake()))
if (fakePath.empty() && found && (resultPathPart.front().IsFake() || resultPathPart.back().IsFake()))
{
fakePath = resultPathPart;
found = false;
@@ -127,10 +119,7 @@ bool PathsConnector::FindShortestPath(Graph::Edge const & from, Graph::Edge cons
{
State(Graph::Edge const & e, uint32_t const s) : m_edge(e), m_score(s) {}
bool operator>(State const & o) const
{
return make_tuple(m_score, m_edge) > make_tuple(o.m_score, o.m_edge);
}
bool operator>(State const & o) const { return make_tuple(m_score, m_edge) > make_tuple(o.m_score, o.m_edge); }
Graph::Edge m_edge;
uint32_t m_score;
@@ -196,10 +185,8 @@ bool PathsConnector::FindShortestPath(Graph::Edge const & from, Graph::Edge cons
return false;
}
bool PathsConnector::ConnectAdjacentCandidateLines(Graph::EdgeVector const & from,
Graph::EdgeVector const & to,
FunctionalRoadClass lowestFrcToNextPoint,
double distanceToNextPoint,
bool PathsConnector::ConnectAdjacentCandidateLines(Graph::EdgeVector const & from, Graph::EdgeVector const & to,
FunctionalRoadClass lowestFrcToNextPoint, double distanceToNextPoint,
Graph::EdgeVector & resultPath)
{
@@ -217,8 +204,7 @@ bool PathsConnector::ConnectAdjacentCandidateLines(Graph::EdgeVector const & fro
ASSERT(from.back() != to.front(), ());
Graph::EdgeVector shortestPath;
auto const found =
FindShortestPath(from.back(), to.front(), lowestFrcToNextPoint, distanceToNextPoint, shortestPath);
auto const found = FindShortestPath(from.back(), to.front(), lowestFrcToNextPoint, distanceToNextPoint, shortestPath);
if (!found)
return false;

View File

@@ -14,21 +14,19 @@ namespace openlr
class PathsConnector
{
public:
PathsConnector(double pathLengthTolerance, Graph & graph, RoadInfoGetter & infoGetter,
v2::Stats & stat);
PathsConnector(double pathLengthTolerance, Graph & graph, RoadInfoGetter & infoGetter, v2::Stats & stat);
bool ConnectCandidates(std::vector<LocationReferencePoint> const & points,
std::vector<std::vector<Graph::EdgeVector>> const & lineCandidates,
std::vector<Graph::EdgeVector> & resultPath);
private:
bool FindShortestPath(Graph::Edge const & from, Graph::Edge const & to,
FunctionalRoadClass lowestFrcToNextPoint, uint32_t maxPathLength,
Graph::EdgeVector & path);
bool FindShortestPath(Graph::Edge const & from, Graph::Edge const & to, FunctionalRoadClass lowestFrcToNextPoint,
uint32_t maxPathLength, Graph::EdgeVector & path);
bool ConnectAdjacentCandidateLines(Graph::EdgeVector const & from, Graph::EdgeVector const & to,
FunctionalRoadClass lowestFrcToNextPoint,
double distanceToNextPoint, Graph::EdgeVector & resultPath);
FunctionalRoadClass lowestFrcToNextPoint, double distanceToNextPoint,
Graph::EdgeVector & resultPath);
double m_pathLengthTolerance;
Graph & m_graph;

View File

@@ -1,8 +1,8 @@
#include "openlr/road_info_getter.hpp"
#include "indexer/classificator.hpp"
#include "indexer/feature.hpp"
#include "indexer/data_source.hpp"
#include "indexer/feature.hpp"
#include "base/assert.hpp"
@@ -14,14 +14,10 @@ RoadInfoGetter::RoadInfo::RoadInfo(FeatureType & ft)
, m_link(ftypes::IsLinkChecker::Instance()(ft))
, m_oneWay(ftypes::IsOneWayChecker::Instance()(ft))
, m_isRoundabout(ftypes::IsRoundAboutChecker::Instance()(ft))
{
}
{}
// RoadInfoGetter ----------------------------------------------------------------------------------
RoadInfoGetter::RoadInfoGetter(DataSource const & dataSource)
: m_dataSource(dataSource)
{
}
RoadInfoGetter::RoadInfoGetter(DataSource const & dataSource) : m_dataSource(dataSource) {}
RoadInfoGetter::RoadInfo RoadInfoGetter::Get(FeatureID const & fid)
{

View File

@@ -34,8 +34,7 @@ public:
RoadInfo Get(FeatureID const & fid);
private:
private:
DataSource const & m_dataSource;
std::map<FeatureID, RoadInfo> m_cache;
};

View File

@@ -83,16 +83,14 @@ bool Router::Vertex::Score::operator==(Score const & rhs) const
}
// Router::Vertex ----------------------------------------------------------------------------------
Router::Vertex::Vertex(geometry::PointWithAltitude const & junction,
geometry::PointWithAltitude const & stageStart, double stageStartDistance,
size_t stage, bool bearingChecked)
Router::Vertex::Vertex(geometry::PointWithAltitude const & junction, geometry::PointWithAltitude const & stageStart,
double stageStartDistance, size_t stage, bool bearingChecked)
: m_junction(junction)
, m_stageStart(stageStart)
, m_stageStartDistance(stageStartDistance)
, m_stage(stage)
, m_bearingChecked(bearingChecked)
{
}
{}
bool Router::Vertex::operator<(Vertex const & rhs) const
{
@@ -116,9 +114,11 @@ bool Router::Vertex::operator==(Vertex const & rhs) const
// Router::Edge ------------------------------------------------------------------------------------
Router::Edge::Edge(Vertex const & u, Vertex const & v, routing::Edge const & raw, bool isSpecial)
: m_u(u), m_v(v), m_raw(raw), m_isSpecial(isSpecial)
{
}
: m_u(u)
, m_v(v)
, m_raw(raw)
, m_isSpecial(isSpecial)
{}
// static
Router::Edge Router::Edge::MakeNormal(Vertex const & u, Vertex const & v, routing::Edge const & raw)
@@ -146,20 +146,18 @@ std::pair<m2::PointD, m2::PointD> Router::Edge::ToPairRev() const
// Router::Router ----------------------------------------------------------------------------------
Router::Router(routing::FeaturesRoadGraph & graph, RoadInfoGetter & roadInfoGetter)
: m_graph(graph), m_roadInfoGetter(roadInfoGetter)
{
}
: m_graph(graph)
, m_roadInfoGetter(roadInfoGetter)
{}
bool Router::Go(std::vector<WayPoint> const & points, double positiveOffsetM,
double negativeOffsetM, Path & path)
bool Router::Go(std::vector<WayPoint> const & points, double positiveOffsetM, double negativeOffsetM, Path & path)
{
if (!Init(points, positiveOffsetM, negativeOffsetM))
return false;
return FindPath(path);
}
bool Router::Init(std::vector<WayPoint> const & points, double positiveOffsetM,
double negativeOffsetM)
bool Router::Init(std::vector<WayPoint> const & points, double positiveOffsetM, double negativeOffsetM)
{
CHECK_GREATER_OR_EQUAL(points.size(), 2, ());
@@ -177,8 +175,7 @@ bool Router::Init(std::vector<WayPoint> const & points, double positiveOffsetM,
std::vector<std::pair<routing::Edge, geometry::PointWithAltitude>> vicinity;
m_graph.FindClosestEdges(
mercator::RectByCenterXYAndSizeInMeters(m_points[i].m_point,
routing::FeaturesRoadGraph::kClosestEdgesRadiusM),
mercator::RectByCenterXYAndSizeInMeters(m_points[i].m_point, routing::FeaturesRoadGraph::kClosestEdgesRadiusM),
kMaxRoadCandidates, vicinity);
for (auto const & v : vicinity)
{
@@ -197,20 +194,18 @@ bool Router::Init(std::vector<WayPoint> const & points, double positiveOffsetM,
{
m_sourceJunction = geometry::PointWithAltitude(m_points.front().m_point, 0 /* altitude */);
std::vector<std::pair<routing::Edge, geometry::PointWithAltitude>> sourceVicinity;
m_graph.FindClosestEdges(
mercator::RectByCenterXYAndSizeInMeters(m_sourceJunction.GetPoint(),
routing::FeaturesRoadGraph::kClosestEdgesRadiusM),
kMaxRoadCandidates, sourceVicinity);
m_graph.FindClosestEdges(mercator::RectByCenterXYAndSizeInMeters(m_sourceJunction.GetPoint(),
routing::FeaturesRoadGraph::kClosestEdgesRadiusM),
kMaxRoadCandidates, sourceVicinity);
m_graph.AddFakeEdges(m_sourceJunction, sourceVicinity);
}
{
m_targetJunction = geometry::PointWithAltitude(m_points.back().m_point, 0 /* altitude */);
std::vector<std::pair<routing::Edge, geometry::PointWithAltitude>> targetVicinity;
m_graph.FindClosestEdges(
mercator::RectByCenterXYAndSizeInMeters(m_targetJunction.GetPoint(),
routing::FeaturesRoadGraph::kClosestEdgesRadiusM),
kMaxRoadCandidates, targetVicinity);
m_graph.FindClosestEdges(mercator::RectByCenterXYAndSizeInMeters(m_targetJunction.GetPoint(),
routing::FeaturesRoadGraph::kClosestEdgesRadiusM),
kMaxRoadCandidates, targetVicinity);
m_graph.AddFakeEdges(m_targetJunction, targetVicinity);
}
@@ -224,9 +219,9 @@ bool Router::FindPath(Path & path)
std::map<Vertex, Vertex::Score> scores;
Links links;
auto const pushVertex = [&queue, &scores, &links](Vertex const & u, Vertex const & v,
Vertex::Score const & vertexScore,
Edge const & e) {
auto const pushVertex =
[&queue, &scores, &links](Vertex const & u, Vertex const & v, Vertex::Score const & vertexScore, Edge const & e)
{
if ((scores.count(v) == 0 || scores[v].GetScore() > vertexScore.GetScore() + kEps) && u != v)
{
scores[v] = vertexScore;
@@ -279,11 +274,8 @@ bool Router::FindPath(Path & path)
// max(kDistanceAccuracyM, m_distanceToNextPointM) is added here
// to throw out quite long paths.
if (ud > u.m_stageStartDistance + distanceToNextPointM +
std::max(kDistanceAccuracyM, distanceToNextPointM))
{
if (ud > u.m_stageStartDistance + distanceToNextPointM + std::max(kDistanceAccuracyM, distanceToNextPointM))
continue;
}
if (NearNextStage(u, piU) && !u.m_bearingChecked)
{
@@ -303,14 +295,12 @@ bool Router::FindPath(Path & path)
if (MayMoveToNextStage(u, piU))
{
Vertex v(u.m_junction, u.m_junction, ud /* stageStartDistance */, stage + 1,
false /* bearingChecked */);
Vertex v(u.m_junction, u.m_junction, ud /* stageStartDistance */, stage + 1, false /* bearingChecked */);
double const piV = GetPotential(v);
Vertex::Score sv = su;
sv.AddDistance(std::max(piV - piU, 0.0));
sv.AddIntermediateErrorPenalty(
mercator::DistanceOnEarth(v.m_junction.GetPoint(), m_points[v.m_stage].m_point));
sv.AddIntermediateErrorPenalty(mercator::DistanceOnEarth(v.m_junction.GetPoint(), m_points[v.m_stage].m_point));
if (IsFinalVertex(v))
{
@@ -322,7 +312,8 @@ bool Router::FindPath(Path & path)
pushVertex(u, v, sv, Edge::MakeSpecial(u, v));
}
ForEachEdge(u, true /* outgoing */, m_points[stage].m_lfrcnp, [&](routing::Edge const & edge) {
ForEachEdge(u, true /* outgoing */, m_points[stage].m_lfrcnp, [&](routing::Edge const & edge)
{
Vertex v = u;
v.m_junction = edge.GetEndJunction();
@@ -338,8 +329,7 @@ bool Router::FindPath(Path & path)
CHECK(!NeedToCheckBearing(u, ud), ());
double const delta = vd - v.m_stageStartDistance - kBearingDist;
auto const p = PointAtSegment(edge.GetStartJunction().GetPoint(),
edge.GetEndJunction().GetPoint(), delta);
auto const p = PointAtSegment(edge.GetStartJunction().GetPoint(), edge.GetEndJunction().GetPoint(), delta);
if (v.m_stageStart.GetPoint() != p)
{
int const expected = m_points[stage].m_bearing;
@@ -423,8 +413,7 @@ uint32_t Router::GetReverseBearing(Vertex const & u, Links const & links) const
if (passed + weight >= kBearingDist)
{
double const delta = kBearingDist - passed;
b = PointAtSegment(edge.GetEndJunction().GetPoint(), edge.GetStartJunction().GetPoint(),
delta);
b = PointAtSegment(edge.GetEndJunction().GetPoint(), edge.GetStartJunction().GetPoint(), delta);
found = true;
break;
}
@@ -453,25 +442,20 @@ void Router::ForEachEdge(Vertex const & u, bool outgoing, FunctionalRoadClass re
}
}
void Router::GetOutgoingEdges(geometry::PointWithAltitude const & u,
routing::IRoadGraph::EdgeListT & edges)
void Router::GetOutgoingEdges(geometry::PointWithAltitude const & u, routing::IRoadGraph::EdgeListT & edges)
{
GetEdges(u, &routing::IRoadGraph::GetRegularOutgoingEdges,
&routing::IRoadGraph::GetFakeOutgoingEdges, m_outgoingCache, edges);
GetEdges(u, &routing::IRoadGraph::GetRegularOutgoingEdges, &routing::IRoadGraph::GetFakeOutgoingEdges,
m_outgoingCache, edges);
}
void Router::GetIngoingEdges(geometry::PointWithAltitude const & u,
routing::IRoadGraph::EdgeListT & edges)
void Router::GetIngoingEdges(geometry::PointWithAltitude const & u, routing::IRoadGraph::EdgeListT & edges)
{
GetEdges(u, &routing::IRoadGraph::GetRegularIngoingEdges,
&routing::IRoadGraph::GetFakeIngoingEdges, m_ingoingCache, edges);
GetEdges(u, &routing::IRoadGraph::GetRegularIngoingEdges, &routing::IRoadGraph::GetFakeIngoingEdges, m_ingoingCache,
edges);
}
void Router::GetEdges(
geometry::PointWithAltitude const & u, RoadGraphEdgesGetter getRegular,
RoadGraphEdgesGetter getFake,
EdgeCacheT & cache,
routing::IRoadGraph::EdgeListT & edges)
void Router::GetEdges(geometry::PointWithAltitude const & u, RoadGraphEdgesGetter getRegular,
RoadGraphEdgesGetter getFake, EdgeCacheT & cache, routing::IRoadGraph::EdgeListT & edges)
{
auto const it = cache.find(u);
if (it == cache.end())
@@ -489,24 +473,22 @@ void Router::GetEdges(
}
template <typename Fn>
void Router::ForEachNonFakeEdge(Vertex const & u, bool outgoing, FunctionalRoadClass restriction,
Fn && fn)
void Router::ForEachNonFakeEdge(Vertex const & u, bool outgoing, FunctionalRoadClass restriction, Fn && fn)
{
ForEachEdge(u, outgoing, restriction, [&fn](routing::Edge const & edge) {
ForEachEdge(u, outgoing, restriction, [&fn](routing::Edge const & edge)
{
if (!edge.IsFake())
fn(edge);
});
}
template <typename Fn>
void Router::ForEachNonFakeClosestEdge(Vertex const & u, FunctionalRoadClass const restriction,
Fn && fn)
void Router::ForEachNonFakeClosestEdge(Vertex const & u, FunctionalRoadClass const restriction, Fn && fn)
{
std::vector<std::pair<routing::Edge, geometry::PointWithAltitude>> vicinity;
m_graph.FindClosestEdges(
mercator::RectByCenterXYAndSizeInMeters(u.m_junction.GetPoint(),
routing::FeaturesRoadGraph::kClosestEdgesRadiusM),
kMaxRoadCandidates, vicinity);
m_graph.FindClosestEdges(mercator::RectByCenterXYAndSizeInMeters(u.m_junction.GetPoint(),
routing::FeaturesRoadGraph::kClosestEdgesRadiusM),
kMaxRoadCandidates, vicinity);
for (auto const & p : vicinity)
{
@@ -652,64 +634,61 @@ bool Router::ReconstructPath(std::vector<Edge> & edges, Path & path)
{
auto toPair = [](auto && e) { return e.ToPair(); };
size_t const n = FindPrefixLengthToConsume(
make_transform_iterator(edges.begin(), toPair),
make_transform_iterator(edges.end(), toPair), m_positiveOffsetM);
size_t const n = FindPrefixLengthToConsume(make_transform_iterator(edges.begin(), toPair),
make_transform_iterator(edges.end(), toPair), m_positiveOffsetM);
CHECK_LESS_OR_EQUAL(n, edges.size(), ());
edges.erase(edges.begin(), edges.begin() + n);
}
{
auto toPairRev = [](auto && e) { return e.ToPairRev(); };
size_t const n = FindPrefixLengthToConsume(
make_transform_iterator(edges.rbegin(), toPairRev),
make_transform_iterator(edges.rend(), toPairRev), m_negativeOffsetM);
size_t const n = FindPrefixLengthToConsume(make_transform_iterator(edges.rbegin(), toPairRev),
make_transform_iterator(edges.rend(), toPairRev), m_negativeOffsetM);
CHECK_LESS_OR_EQUAL(n, edges.size(), ());
edges.erase(edges.begin() + edges.size() - n, edges.end());
}
double frontEdgeScore = -1.0;
routing::Edge frontEdge;
ForStagePrefix(edges.begin(), edges.end(), 0, [&](EdgeIt e) {
ForEachNonFakeEdge(e->m_u, false /* outgoing */, m_points[0].m_lfrcnp,
[&](routing::Edge const & edge) {
auto toPairRev = [](auto && e) { return e.ToPairRev(); };
double const score = GetMatchingScore(
edge.GetEndJunction().GetPoint(), edge.GetStartJunction().GetPoint(),
make_transform_iterator(EdgeItRev(e), toPairRev),
make_transform_iterator(edges.rend(), toPairRev));
if (score > frontEdgeScore)
{
frontEdgeScore = score;
frontEdge = edge.GetReverseEdge();
}
});
ForStagePrefix(edges.begin(), edges.end(), 0, [&](EdgeIt e)
{
ForEachNonFakeEdge(e->m_u, false /* outgoing */, m_points[0].m_lfrcnp, [&](routing::Edge const & edge)
{
auto toPairRev = [](auto && e) { return e.ToPairRev(); };
double const score = GetMatchingScore(edge.GetEndJunction().GetPoint(), edge.GetStartJunction().GetPoint(),
make_transform_iterator(EdgeItRev(e), toPairRev),
make_transform_iterator(edges.rend(), toPairRev));
if (score > frontEdgeScore)
{
frontEdgeScore = score;
frontEdge = edge.GetReverseEdge();
}
});
});
double backEdgeScore = -1.0;
routing::Edge backEdge;
ForStagePrefix(edges.rbegin(), edges.rend(), m_points.size() - 2 /* stage */, [&](EdgeItRev e) {
ForStagePrefix(edges.rbegin(), edges.rend(), m_points.size() - 2 /* stage */, [&](EdgeItRev e)
{
ForEachNonFakeEdge(e->m_v, true /* outgoing */, m_points[m_points.size() - 2].m_lfrcnp,
[&](routing::Edge const & edge) {
auto toPair = [](auto && e) { return e.ToPair(); };
double const score = GetMatchingScore(
edge.GetStartJunction().GetPoint(), edge.GetEndJunction().GetPoint(),
make_transform_iterator(e.base(), toPair),
make_transform_iterator(edges.end(), toPair));
if (score > backEdgeScore)
{
backEdgeScore = score;
backEdge = edge;
}
});
[&](routing::Edge const & edge)
{
auto toPair = [](auto && e) { return e.ToPair(); };
double const score =
GetMatchingScore(edge.GetStartJunction().GetPoint(), edge.GetEndJunction().GetPoint(),
make_transform_iterator(e.base(), toPair), make_transform_iterator(edges.end(), toPair));
if (score > backEdgeScore)
{
backEdgeScore = score;
backEdge = edge;
}
});
});
path.clear();
for (auto const & e : edges)
{
if (!e.IsFake())
path.push_back(e.m_raw);
}
if (frontEdgeScore >= kFakeCoverageThreshold && !path.empty() && path.front() != frontEdge)
path.insert(path.begin(), frontEdge);
@@ -742,11 +721,11 @@ void Router::FindSingleEdgeApproximation(std::vector<Edge> const & edges, Path &
double bestCoverage = -1.0;
routing::Edge bestEdge;
auto checkEdge = [&](routing::Edge const & edge) {
auto checkEdge = [&](routing::Edge const & edge)
{
double const weight = GetWeight(edge);
double const fraction =
GetCoverage(edge.GetStartJunction().GetPoint(), edge.GetEndJunction().GetPoint(),
edges.begin(), edges.end());
GetCoverage(edge.GetStartJunction().GetPoint(), edge.GetEndJunction().GetPoint(), edges.begin(), edges.end());
double const coverage = weight * fraction;
if (coverage >= bestCoverage)
{

View File

@@ -35,20 +35,20 @@ private:
{
public:
// A weight for total length of true fake edges.
static const int kTrueFakeCoeff = 10;
static int const kTrueFakeCoeff = 10;
// A weight for total length of fake edges that are parts of some
// real edges.
static constexpr double kFakeCoeff = 0.001;
// A weight for passing too far from pivot points.
static const int kIntermediateErrorCoeff = 3;
static int const kIntermediateErrorCoeff = 3;
// A weight for excess of distance limit.
static const int kDistanceErrorCoeff = 3;
static int const kDistanceErrorCoeff = 3;
// A weight for deviation from bearing.
static const int kBearingErrorCoeff = 5;
static int const kBearingErrorCoeff = 5;
void AddDistance(double p) { m_distance += p; }
void AddFakePenalty(double p, bool partOfReal);
@@ -73,9 +73,8 @@ private:
};
Vertex() = default;
Vertex(geometry::PointWithAltitude const & junction,
geometry::PointWithAltitude const & stageStart, double stageStartDistance, size_t stage,
bool bearingChecked);
Vertex(geometry::PointWithAltitude const & junction, geometry::PointWithAltitude const & stageStart,
double stageStartDistance, size_t stage, bool bearingChecked);
bool operator<(Vertex const & rhs) const;
bool operator==(Vertex const & rhs) const;
@@ -137,8 +136,8 @@ private:
using Links = std::map<Vertex, std::pair<Vertex, Edge>>;
using RoadGraphEdgesGetter = void (routing::IRoadGraph::*)(
geometry::PointWithAltitude const & junction, routing::IRoadGraph::EdgeListT & edges) const;
using RoadGraphEdgesGetter = void (routing::IRoadGraph::*)(geometry::PointWithAltitude const & junction,
routing::IRoadGraph::EdgeListT & edges) const;
bool Init(std::vector<WayPoint> const & points, double positiveOffsetM, double negativeOffsetM);
bool FindPath(Path & path);
@@ -162,8 +161,7 @@ private:
double GetWeight(routing::Edge const & e) const
{
return mercator::DistanceOnEarth(e.GetStartJunction().GetPoint(),
e.GetEndJunction().GetPoint());
return mercator::DistanceOnEarth(e.GetStartJunction().GetPoint(), e.GetEndJunction().GetPoint());
}
double GetWeight(Edge const & e) const { return GetWeight(e.m_raw); }
@@ -173,20 +171,15 @@ private:
template <typename Fn>
void ForEachEdge(Vertex const & u, bool outgoing, FunctionalRoadClass restriction, Fn && fn);
void GetOutgoingEdges(geometry::PointWithAltitude const & u,
routing::IRoadGraph::EdgeListT & edges);
void GetIngoingEdges(geometry::PointWithAltitude const & u,
routing::IRoadGraph::EdgeListT & edges);
void GetOutgoingEdges(geometry::PointWithAltitude const & u, routing::IRoadGraph::EdgeListT & edges);
void GetIngoingEdges(geometry::PointWithAltitude const & u, routing::IRoadGraph::EdgeListT & edges);
using EdgeCacheT = std::map<geometry::PointWithAltitude, routing::IRoadGraph::EdgeListT>;
void GetEdges(geometry::PointWithAltitude const & u, RoadGraphEdgesGetter getRegular,
RoadGraphEdgesGetter getFake,
EdgeCacheT & cache,
routing::IRoadGraph::EdgeListT & edges);
void GetEdges(geometry::PointWithAltitude const & u, RoadGraphEdgesGetter getRegular, RoadGraphEdgesGetter getFake,
EdgeCacheT & cache, routing::IRoadGraph::EdgeListT & edges);
template <typename Fn>
void ForEachNonFakeEdge(Vertex const & u, bool outgoing, FunctionalRoadClass restriction,
Fn && fn);
void ForEachNonFakeEdge(Vertex const & u, bool outgoing, FunctionalRoadClass restriction, Fn && fn);
template <typename Fn>
void ForEachNonFakeClosestEdge(Vertex const & u, FunctionalRoadClass const restriction, Fn && fn);

View File

@@ -55,16 +55,14 @@ double DifferenceInDeg(double a1, double a2)
void EdgeSortUniqueByStartAndEndPoints(Graph::EdgeListT & edges)
{
base::SortUnique(
edges,
[](Edge const & e1, Edge const & e2) {
if (e1.GetStartPoint() != e2.GetStartPoint())
return e1.GetStartPoint() < e2.GetStartPoint();
return e1.GetEndPoint() < e2.GetEndPoint();
},
[](Edge const & e1, Edge const & e2) {
return e1.GetStartPoint() == e2.GetStartPoint() && e1.GetEndPoint() == e2.GetEndPoint();
});
base::SortUnique(edges,
[](Edge const & e1, Edge const & e2)
{
if (e1.GetStartPoint() != e2.GetStartPoint())
return e1.GetStartPoint() < e2.GetStartPoint();
return e1.GetEndPoint() < e2.GetEndPoint();
}, [](Edge const & e1, Edge const & e2)
{ return e1.GetStartPoint() == e2.GetStartPoint() && e1.GetEndPoint() == e2.GetEndPoint(); });
}
} // namespace scpg
@@ -93,9 +91,9 @@ bool ScoreCandidatePathsGetter::Link::IsJunctionInPath(geometry::PointWithAltitu
}
// ScoreCandidatePathsGetter ----------------------------------------------------------------------------
bool ScoreCandidatePathsGetter::GetLineCandidatesForPoints(
vector<LocationReferencePoint> const & points, LinearSegmentSource source,
vector<ScorePathVec> & lineCandidates)
bool ScoreCandidatePathsGetter::GetLineCandidatesForPoints(vector<LocationReferencePoint> const & points,
LinearSegmentSource source,
vector<ScorePathVec> & lineCandidates)
{
CHECK_GREATER(points.size(), 1, ());
@@ -110,15 +108,12 @@ bool ScoreCandidatePathsGetter::GetLineCandidatesForPoints(
lineCandidates.emplace_back();
auto const isLastPoint = i == points.size() - 1;
double const distanceToNextPointM =
(isLastPoint ? points[i - 1] : points[i]).m_distanceToNextPoint;
double const distanceToNextPointM = (isLastPoint ? points[i - 1] : points[i]).m_distanceToNextPoint;
ScoreEdgeVec edgesCandidates;
m_pointsGetter.GetEdgeCandidates(mercator::FromLatLon(points[i].m_latLon),
isLastPoint, edgesCandidates);
m_pointsGetter.GetEdgeCandidates(mercator::FromLatLon(points[i].m_latLon), isLastPoint, edgesCandidates);
GetLineCandidates(points[i], source, isLastPoint, distanceToNextPointM, edgesCandidates,
lineCandidates.back());
GetLineCandidates(points[i], source, isLastPoint, distanceToNextPointM, edgesCandidates, lineCandidates.back());
if (lineCandidates.back().empty())
{
@@ -132,13 +127,10 @@ bool ScoreCandidatePathsGetter::GetLineCandidatesForPoints(
return true;
}
void ScoreCandidatePathsGetter::GetAllSuitablePaths(ScoreEdgeVec const & startLines,
LinearSegmentSource source, bool isLastPoint,
double bearDistM,
FunctionalRoadClass functionalRoadClass,
FormOfWay formOfWay,
double distanceToNextPointM,
vector<shared_ptr<Link>> & allPaths)
void ScoreCandidatePathsGetter::GetAllSuitablePaths(ScoreEdgeVec const & startLines, LinearSegmentSource source,
bool isLastPoint, double bearDistM,
FunctionalRoadClass functionalRoadClass, FormOfWay formOfWay,
double distanceToNextPointM, vector<shared_ptr<Link>> & allPaths)
{
CHECK_NOT_EQUAL(source, LinearSegmentSource::NotValid, ());
@@ -146,15 +138,14 @@ void ScoreCandidatePathsGetter::GetAllSuitablePaths(ScoreEdgeVec const & startLi
for (auto const & e : startLines)
{
Score roadScore = 0; // Score based on functional road class and form of way.
Score roadScore = 0; // Score based on functional road class and form of way.
if (source == LinearSegmentSource::FromLocationReferenceTag &&
!PassesRestrictionV3(e.m_edge, functionalRoadClass, formOfWay, m_infoGetter, roadScore))
{
continue;
}
q.push(
make_shared<Link>(nullptr /* parent */, e.m_edge, 0 /* distanceM */, e.m_score, roadScore));
q.push(make_shared<Link>(nullptr /* parent */, e.m_edge, 0 /* distanceM */, e.m_score, roadScore));
}
// Filling |allPaths| staring from |startLines| which have passed functional road class
@@ -214,8 +205,8 @@ void ScoreCandidatePathsGetter::GetAllSuitablePaths(ScoreEdgeVec const & startLi
// Road score for a path is minimum value of score of segments based on functional road class
// of the segments and form of way of the segments.
q.emplace(make_shared<Link>(u, e, u->m_distanceM + currentEdgeLen, u->m_pointScore,
min(roadScore, u->m_minRoadScore)));
q.emplace(
make_shared<Link>(u, e, u->m_distanceM + currentEdgeLen, u->m_pointScore, min(roadScore, u->m_minRoadScore)));
}
}
}
@@ -223,8 +214,7 @@ void ScoreCandidatePathsGetter::GetAllSuitablePaths(ScoreEdgeVec const & startLi
void ScoreCandidatePathsGetter::GetBestCandidatePaths(vector<shared_ptr<Link>> const & allPaths,
LinearSegmentSource source, bool isLastPoint,
uint32_t requiredBearing, double bearDistM,
m2::PointD const & startPoint,
ScorePathVec & candidates)
m2::PointD const & startPoint, ScorePathVec & candidates)
{
CHECK_NOT_EQUAL(source, LinearSegmentSource::NotValid, ());
CHECK_LESS_OR_EQUAL(requiredBearing, 255, ());
@@ -269,8 +259,7 @@ void ScoreCandidatePathsGetter::GetBestCandidatePaths(vector<shared_ptr<Link>> c
size_t constexpr kMaxCandidates = 7;
vector<CandidatePath> paths;
copy_n(candidatePaths.begin(), min(static_cast<size_t>(kMaxCandidates), candidatePaths.size()),
back_inserter(paths));
copy_n(candidatePaths.begin(), min(static_cast<size_t>(kMaxCandidates), candidatePaths.size()), back_inserter(paths));
for (auto const & path : paths)
{
@@ -285,12 +274,9 @@ void ScoreCandidatePathsGetter::GetBestCandidatePaths(vector<shared_ptr<Link>> c
}
}
void ScoreCandidatePathsGetter::GetLineCandidates(openlr::LocationReferencePoint const & p,
LinearSegmentSource source,
bool isLastPoint,
double distanceToNextPointM,
ScoreEdgeVec const & edgeCandidates,
ScorePathVec & candidates)
void ScoreCandidatePathsGetter::GetLineCandidates(openlr::LocationReferencePoint const & p, LinearSegmentSource source,
bool isLastPoint, double distanceToNextPointM,
ScoreEdgeVec const & edgeCandidates, ScorePathVec & candidates)
{
double constexpr kDefaultBearDistM = 25.0;
double const bearDistM = min(kDefaultBearDistM, distanceToNextPointM);
@@ -303,11 +289,10 @@ void ScoreCandidatePathsGetter::GetLineCandidates(openlr::LocationReferencePoint
auto const startPoint = mercator::FromLatLon(p.m_latLon);
vector<shared_ptr<Link>> allPaths;
GetAllSuitablePaths(startLines, source, isLastPoint, bearDistM, p.m_functionalRoadClass,
p.m_formOfWay, distanceToNextPointM, allPaths);
GetAllSuitablePaths(startLines, source, isLastPoint, bearDistM, p.m_functionalRoadClass, p.m_formOfWay,
distanceToNextPointM, allPaths);
GetBestCandidatePaths(allPaths, source, isLastPoint, p.m_bearing, bearDistM, startPoint,
candidates);
GetBestCandidatePaths(allPaths, source, isLastPoint, p.m_bearing, bearDistM, startPoint, candidates);
// Sorting by increasing order.
sort(candidates.begin(), candidates.end(),
[](ScorePath const & s1, ScorePath const & s2) { return s1.m_score > s2.m_score; });
@@ -316,8 +301,8 @@ void ScoreCandidatePathsGetter::GetLineCandidates(openlr::LocationReferencePoint
bool ScoreCandidatePathsGetter::GetBearingScore(BearingPointsSelector const & pointsSelector,
ScoreCandidatePathsGetter::Link const & part,
m2::PointD const & bearStartPoint,
uint32_t requiredBearing, Score & score)
m2::PointD const & bearStartPoint, uint32_t requiredBearing,
Score & score)
{
auto const bearEndPoint = pointsSelector.GetEndPoint(part.m_edge, part.m_distanceM);
@@ -333,8 +318,7 @@ bool ScoreCandidatePathsGetter::GetBearingScore(BearingPointsSelector const & po
double constexpr kMaxScoreForBearing = 60.0;
double constexpr kAngleDeviationFactor = 1.0 / 4.3;
score =
static_cast<Score>(kMaxScoreForBearing / (1.0 + angleDeviationDeg * kAngleDeviationFactor));
score = static_cast<Score>(kMaxScoreForBearing / (1.0 + angleDeviationDeg * kAngleDeviationFactor));
return true;
}

View File

@@ -1,7 +1,7 @@
#pragma once
#include "openlr/helpers.hpp"
#include "openlr/graph.hpp"
#include "openlr/helpers.hpp"
#include "openlr/openlr_model.hpp"
#include "openlr/road_info_getter.hpp"
#include "openlr/score_types.hpp"
@@ -23,21 +23,22 @@ class ScoreCandidatePointsGetter;
class ScoreCandidatePathsGetter
{
public:
ScoreCandidatePathsGetter(ScoreCandidatePointsGetter & pointsGetter, Graph & graph,
RoadInfoGetter & infoGetter, v2::Stats & stat)
: m_pointsGetter(pointsGetter), m_graph(graph), m_infoGetter(infoGetter), m_stats(stat)
{
}
ScoreCandidatePathsGetter(ScoreCandidatePointsGetter & pointsGetter, Graph & graph, RoadInfoGetter & infoGetter,
v2::Stats & stat)
: m_pointsGetter(pointsGetter)
, m_graph(graph)
, m_infoGetter(infoGetter)
, m_stats(stat)
{}
bool GetLineCandidatesForPoints(std::vector<LocationReferencePoint> const & points,
LinearSegmentSource source,
bool GetLineCandidatesForPoints(std::vector<LocationReferencePoint> const & points, LinearSegmentSource source,
std::vector<ScorePathVec> & lineCandidates);
private:
struct Link
{
Link(std::shared_ptr<Link> const & parent, Graph::Edge const & edge, double distanceM,
Score pointScore, Score rfcScore)
Link(std::shared_ptr<Link> const & parent, Graph::Edge const & edge, double distanceM, Score pointScore,
Score rfcScore)
: m_parent(parent)
, m_edge(edge)
, m_distanceM(distanceM)
@@ -69,8 +70,7 @@ private:
, m_pointScore(pointScore)
, m_roadScore(rfcScore)
, m_bearingScore(bearingScore)
{
}
{}
bool operator>(CandidatePath const & o) const { return GetScore() > o.GetScore(); }
@@ -97,23 +97,18 @@ private:
/// \brief Fills |allPaths| with paths near start or finish point starting from |startLines|.
/// To extract a path from |allPaths| a item from |allPaths| should be taken,
/// then should be taken the member |m_parent| of the item and so on till the beginning.
void GetAllSuitablePaths(ScoreEdgeVec const & startLines, LinearSegmentSource source,
bool isLastPoint, double bearDistM,
FunctionalRoadClass functionalRoadClass, FormOfWay formOfWay,
double distanceToNextPointM,
std::vector<std::shared_ptr<Link>> & allPaths);
void GetAllSuitablePaths(ScoreEdgeVec const & startLines, LinearSegmentSource source, bool isLastPoint,
double bearDistM, FunctionalRoadClass functionalRoadClass, FormOfWay formOfWay,
double distanceToNextPointM, std::vector<std::shared_ptr<Link>> & allPaths);
void GetBestCandidatePaths(std::vector<std::shared_ptr<Link>> const & allPaths,
LinearSegmentSource source, bool isLastPoint, uint32_t requiredBearing,
double bearDistM, m2::PointD const & startPoint,
ScorePathVec & candidates);
void GetBestCandidatePaths(std::vector<std::shared_ptr<Link>> const & allPaths, LinearSegmentSource source,
bool isLastPoint, uint32_t requiredBearing, double bearDistM,
m2::PointD const & startPoint, ScorePathVec & candidates);
void GetLineCandidates(openlr::LocationReferencePoint const & p, LinearSegmentSource source,
bool isLastPoint, double distanceToNextPointM,
ScoreEdgeVec const & edgeCandidates, ScorePathVec & candidates);
void GetLineCandidates(openlr::LocationReferencePoint const & p, LinearSegmentSource source, bool isLastPoint,
double distanceToNextPointM, ScoreEdgeVec const & edgeCandidates, ScorePathVec & candidates);
bool GetBearingScore(BearingPointsSelector const & pointsSelector,
ScoreCandidatePathsGetter::Link const & part,
bool GetBearingScore(BearingPointsSelector const & pointsSelector, ScoreCandidatePathsGetter::Link const & part,
m2::PointD const & bearStartPoint, uint32_t requiredBearing, Score & score);
ScoreCandidatePointsGetter & m_pointsGetter;

View File

@@ -28,7 +28,7 @@ namespace
{
// Ends of segments and intermediate points of segments are considered only within this radius.
double const kRadius = 30.0;
} // namespace
} // namespace
namespace openlr
{
@@ -36,17 +36,17 @@ void ScoreCandidatePointsGetter::GetJunctionPointCandidates(m2::PointD const & p
ScoreEdgeVec & edgeCandidates)
{
ScorePointVec pointCandidates;
auto const selectCandidates = [&p, &pointCandidates, this](FeatureType & ft) {
auto const selectCandidates = [&p, &pointCandidates, this](FeatureType & ft)
{
ft.ParseGeometry(FeatureType::BEST_GEOMETRY);
if (ft.GetGeomType() != feature::GeomType::Line || !routing::IsRoad(feature::TypesHolder(ft)))
return;
ft.ForEachPoint(
[&p, &pointCandidates, this](m2::PointD const & candidate) {
if (mercator::DistanceOnEarth(p, candidate) < kRadius)
pointCandidates.emplace_back(GetScoreByDistance(p, candidate), candidate);
},
scales::GetUpperScale());
ft.ForEachPoint([&p, &pointCandidates, this](m2::PointD const & candidate)
{
if (mercator::DistanceOnEarth(p, candidate) < kRadius)
pointCandidates.emplace_back(GetScoreByDistance(p, candidate), candidate);
}, scales::GetUpperScale());
};
m_dataSource.ForEachInRect(selectCandidates, mercator::RectByCenterXYAndSizeInMeters(p, kRadius),
@@ -70,8 +70,7 @@ void ScoreCandidatePointsGetter::GetJunctionPointCandidates(m2::PointD const & p
}
}
void ScoreCandidatePointsGetter::EnrichWithProjectionPoints(m2::PointD const & p,
ScoreEdgeVec & edgeCandidates)
void ScoreCandidatePointsGetter::EnrichWithProjectionPoints(m2::PointD const & p, ScoreEdgeVec & edgeCandidates)
{
m_graph.ResetFakes();
@@ -115,8 +114,7 @@ bool ScoreCandidatePointsGetter::IsJunction(m2::PointD const & p)
return ids.size() >= 3;
}
Score ScoreCandidatePointsGetter::GetScoreByDistance(m2::PointD const & point,
m2::PointD const & candidate)
Score ScoreCandidatePointsGetter::GetScoreByDistance(m2::PointD const & point, m2::PointD const & candidate)
{
// Maximum possible score for the distance between an openlr segment ends and an osm segments.
Score constexpr kMaxScoreForDist = 70;
@@ -128,10 +126,9 @@ Score ScoreCandidatePointsGetter::GetScoreByDistance(m2::PointD const & point,
double const junctionFactor = IsJunction(candidate) ? 1.1 : 1.0;
double const distM = mercator::DistanceOnEarth(point, candidate);
double const score =
distM <= kMaxScoreDistM
? kMaxScoreForDist * junctionFactor
: static_cast<double>(kMaxScoreForDist) * junctionFactor / (1.0 + distM - kMaxScoreDistM);
double const score = distM <= kMaxScoreDistM
? kMaxScoreForDist * junctionFactor
: static_cast<double>(kMaxScoreForDist) * junctionFactor / (1.0 + distM - kMaxScoreDistM);
CHECK_GREATER_OR_EQUAL(score, 0.0, ());
CHECK_LESS_OR_EQUAL(score, static_cast<double>(kMaxScoreForDist) * junctionFactor, ());

View File

@@ -23,8 +23,7 @@ public:
, m_maxProjectionCandidates(maxProjectionCandidates)
, m_dataSource(dataSource)
, m_graph(graph)
{
}
{}
void GetEdgeCandidates(m2::PointD const & p, bool isLastPoint, ScoreEdgeVec & edges)
{
@@ -33,8 +32,7 @@ public:
}
private:
void GetJunctionPointCandidates(m2::PointD const & p, bool isLastPoint,
ScoreEdgeVec & edgeCandidates);
void GetJunctionPointCandidates(m2::PointD const & p, bool isLastPoint, ScoreEdgeVec & edgeCandidates);
void EnrichWithProjectionPoints(m2::PointD const & p, ScoreEdgeVec & edgeCandidates);
/// \returns true if |p| is a junction and false otherwise.

View File

@@ -13,8 +13,8 @@
#include <algorithm>
#include <cmath>
#include <map>
#include <string>
#include <queue>
#include <string>
#include <tuple>
using namespace std;
@@ -48,10 +48,8 @@ public:
{
CHECK(hwClass != ftypes::HighwayClass::Undefined, (edge));
m_minHwClass = static_cast<ftypes::HighwayClass>(
min(base::Underlying(m_minHwClass), base::Underlying(hwClass)));
m_maxHwClass = static_cast<ftypes::HighwayClass>(
max(base::Underlying(m_maxHwClass), base::Underlying(hwClass)));
m_minHwClass = static_cast<ftypes::HighwayClass>(min(base::Underlying(m_minHwClass), base::Underlying(hwClass)));
m_maxHwClass = static_cast<ftypes::HighwayClass>(max(base::Underlying(m_maxHwClass), base::Underlying(hwClass)));
if (m_oneWay.m_allEqual && m_oneWay.m_field != ftypes::IsOneWayChecker::Instance()(types))
m_oneWay.m_allEqual = false;
@@ -96,8 +94,8 @@ private:
/// \returns true if |path| may be used as a candidate. In that case |lenScore| is filled
/// with score of this candidate based on length. The closer length of the |path| to
/// |distanceToNextPoint| the more score.
bool ValidatePathByLength(Graph::EdgeVector const & path, double distanceToNextPoint,
LinearSegmentSource source, Score & lenScore)
bool ValidatePathByLength(Graph::EdgeVector const & path, double distanceToNextPoint, LinearSegmentSource source,
Score & lenScore)
{
CHECK(!path.empty(), ());
CHECK_NOT_EQUAL(source, LinearSegmentSource::NotValid, ());
@@ -109,12 +107,10 @@ bool ValidatePathByLength(Graph::EdgeVector const & path, double distanceToNextP
pathLen += EdgeLength(e);
// 0 <= |pathDiffRatio| <= 1. The more pathDiffRatio the closer |distanceToNextPoint| and |pathLen|.
double const pathDiffRatio =
1.0 - abs(distanceToNextPoint - pathLen) / max(distanceToNextPoint, pathLen);
double const pathDiffRatio = 1.0 - abs(distanceToNextPoint - pathLen) / max(distanceToNextPoint, pathLen);
bool const shortPath = path.size() <= 2;
double const kMinValidPathDiffRation =
source == LinearSegmentSource::FromLocationReferenceTag ? 0.6 : 0.25;
double const kMinValidPathDiffRation = source == LinearSegmentSource::FromLocationReferenceTag ? 0.6 : 0.25;
if (pathDiffRatio <= kMinValidPathDiffRation && !shortPath)
return false;
@@ -126,21 +122,20 @@ bool ValidatePathByLength(Graph::EdgeVector const & path, double distanceToNextP
bool AreEdgesEqualWithoutAltitude(Graph::Edge const & e1, Graph::Edge const & e2)
{
return make_tuple(e1.GetType(), e1.GetFeatureId(), e1.IsForward(), e1.GetSegId(),
e1.GetStartPoint(), e1.GetEndPoint()) ==
make_tuple(e2.GetType(), e2.GetFeatureId(), e2.IsForward(), e2.GetSegId(),
e2.GetStartPoint(), e2.GetEndPoint());
return make_tuple(e1.GetType(), e1.GetFeatureId(), e1.IsForward(), e1.GetSegId(), e1.GetStartPoint(),
e1.GetEndPoint()) == make_tuple(e2.GetType(), e2.GetFeatureId(), e2.IsForward(), e2.GetSegId(),
e2.GetStartPoint(), e2.GetEndPoint());
}
} // namespace
ScorePathsConnector::ScorePathsConnector(Graph & graph, RoadInfoGetter & infoGetter, v2::Stats & stat)
: m_graph(graph), m_infoGetter(infoGetter), m_stat(stat)
{
}
: m_graph(graph)
, m_infoGetter(infoGetter)
, m_stat(stat)
{}
bool ScorePathsConnector::FindBestPath(vector<LocationReferencePoint> const & points,
vector<vector<ScorePath>> const & lineCandidates,
LinearSegmentSource source,
vector<vector<ScorePath>> const & lineCandidates, LinearSegmentSource source,
vector<Graph::EdgeVector> & resultPath)
{
CHECK_NOT_EQUAL(source, LinearSegmentSource::NotValid, ());
@@ -166,9 +161,8 @@ bool ScorePathsConnector::FindBestPath(vector<LocationReferencePoint> const & po
for (size_t toInd = 0; toInd < toCandidates.size(); ++toInd)
{
Graph::EdgeVector path;
if (!ConnectAdjacentCandidateLines(fromCandidates[fromInd].m_path,
toCandidates[toInd].m_path, source, point.m_lfrcnp,
distanceToNextPoint, path))
if (!ConnectAdjacentCandidateLines(fromCandidates[fromInd].m_path, toCandidates[toInd].m_path, source,
point.m_lfrcnp, distanceToNextPoint, path))
{
continue;
}
@@ -177,8 +171,8 @@ bool ScorePathsConnector::FindBestPath(vector<LocationReferencePoint> const & po
if (!ValidatePathByLength(path, distanceToNextPoint, source, pathLenScore))
continue;
auto const score = pathLenScore + GetScoreForUniformity(path) +
fromCandidates[fromInd].m_score + toCandidates[toInd].m_score;
auto const score =
pathLenScore + GetScoreForUniformity(path) + fromCandidates[fromInd].m_score + toCandidates[toInd].m_score;
result.emplace_back(score, std::move(path));
}
}
@@ -194,9 +188,8 @@ bool ScorePathsConnector::FindBestPath(vector<LocationReferencePoint> const & po
return false;
}
auto const it = max_element(
result.cbegin(), result.cend(),
[](ScorePath const & o1, ScorePath const & o2) { return o1.m_score < o2.m_score; });
auto const it = max_element(result.cbegin(), result.cend(),
[](ScorePath const & o1, ScorePath const & o2) { return o1.m_score < o2.m_score; });
// Note. In case of source == LinearSegmentSource::FromCoordinatesTag there is less
// information about a openlr segment so less score is collected.
@@ -217,10 +210,9 @@ bool ScorePathsConnector::FindBestPath(vector<LocationReferencePoint> const & po
return true;
}
bool ScorePathsConnector::FindShortestPath(Graph::Edge const & from, Graph::Edge const & to,
LinearSegmentSource source,
FunctionalRoadClass lowestFrcToNextPoint,
uint32_t maxPathLength, Graph::EdgeVector & path)
bool ScorePathsConnector::FindShortestPath(Graph::Edge const & from, Graph::Edge const & to, LinearSegmentSource source,
FunctionalRoadClass lowestFrcToNextPoint, uint32_t maxPathLength,
Graph::EdgeVector & path)
{
double constexpr kLengthToleranceFactor = 1.1;
uint32_t constexpr kMinLengthTolerance = 20;
@@ -231,10 +223,7 @@ bool ScorePathsConnector::FindShortestPath(Graph::Edge const & from, Graph::Edge
{
State(Graph::Edge const & e, uint32_t const s) : m_edge(e), m_score(s) {}
bool operator>(State const & o) const
{
return tie(m_score, m_edge) > tie(o.m_score, o.m_edge);
}
bool operator>(State const & o) const { return tie(m_score, m_edge) > tie(o.m_score, o.m_edge); }
Graph::Edge m_edge;
uint32_t m_score;
@@ -300,12 +289,10 @@ bool ScorePathsConnector::FindShortestPath(Graph::Edge const & from, Graph::Edge
return false;
}
bool ScorePathsConnector::ConnectAdjacentCandidateLines(Graph::EdgeVector const & from,
Graph::EdgeVector const & to,
bool ScorePathsConnector::ConnectAdjacentCandidateLines(Graph::EdgeVector const & from, Graph::EdgeVector const & to,
LinearSegmentSource source,
FunctionalRoadClass lowestFrcToNextPoint,
double distanceToNextPoint,
Graph::EdgeVector & resultPath)
double distanceToNextPoint, Graph::EdgeVector & resultPath)
{
CHECK(!to.empty(), ());
@@ -322,9 +309,8 @@ bool ScorePathsConnector::ConnectAdjacentCandidateLines(Graph::EdgeVector const
CHECK_NOT_EQUAL(from, to, ());
Graph::EdgeVector shortestPath;
auto const found =
FindShortestPath(from.back(), to.front(), source, lowestFrcToNextPoint,
static_cast<uint32_t>(ceil(distanceToNextPoint)), shortestPath);
auto const found = FindShortestPath(from.back(), to.front(), source, lowestFrcToNextPoint,
static_cast<uint32_t>(ceil(distanceToNextPoint)), shortestPath);
if (!found)
return false;
@@ -332,8 +318,7 @@ bool ScorePathsConnector::ConnectAdjacentCandidateLines(Graph::EdgeVector const
resultPath.insert(resultPath.end(), from.cbegin(), prev(from.cend()));
resultPath.insert(resultPath.end(), shortestPath.cbegin(), shortestPath.cend());
CHECK(AreEdgesEqualWithoutAltitude(to.front(), shortestPath.back()),
(to.front(), shortestPath.back()));
CHECK(AreEdgesEqualWithoutAltitude(to.front(), shortestPath.back()), (to.front(), shortestPath.back()));
resultPath.insert(resultPath.end(), next(to.begin()), to.end());
return !resultPath.empty();
@@ -348,17 +333,16 @@ Score ScorePathsConnector::GetScoreForUniformity(Graph::EdgeVector const & path)
auto const hwClassDiff = edgeContainer.GetHighwayClassDiff();
Score constexpr kScoreForTheSameHwClass = 40;
Score constexpr kScoreForNeighboringHwClasses = 15;
Score const hwClassScore = hwClassDiff == 0
? kScoreForTheSameHwClass
: hwClassDiff == 1 ? kScoreForNeighboringHwClasses : 0;
Score const hwClassScore = hwClassDiff == 0 ? kScoreForTheSameHwClass
: hwClassDiff == 1 ? kScoreForNeighboringHwClasses
: 0;
Score constexpr kScoreForOneWayOnly = 17;
Score constexpr kScoreForRoundaboutOnly = 18;
Score constexpr kScoreForLinkOnly = 10;
Score const allEqualScore =
(edgeContainer.AreAllOneWaysEqual() ? kScoreForOneWayOnly : 0) +
(edgeContainer.AreAllRoundaboutEqual() ? kScoreForRoundaboutOnly : 0) +
(edgeContainer.AreAllLinksEqual() ? kScoreForLinkOnly : 0);
Score const allEqualScore = (edgeContainer.AreAllOneWaysEqual() ? kScoreForOneWayOnly : 0) +
(edgeContainer.AreAllRoundaboutEqual() ? kScoreForRoundaboutOnly : 0) +
(edgeContainer.AreAllLinksEqual() ? kScoreForLinkOnly : 0);
return hwClassScore + allEqualScore;
}

View File

@@ -21,18 +21,15 @@ public:
/// if there's a good enough.
/// \returns true if the best path is found and false otherwise.
bool FindBestPath(std::vector<LocationReferencePoint> const & points,
std::vector<std::vector<ScorePath>> const & lineCandidates,
LinearSegmentSource source,
std::vector<std::vector<ScorePath>> const & lineCandidates, LinearSegmentSource source,
std::vector<Graph::EdgeVector> & resultPath);
private:
bool FindShortestPath(Graph::Edge const & from, Graph::Edge const & to,
LinearSegmentSource source, FunctionalRoadClass lowestFrcToNextPoint,
uint32_t maxPathLength, Graph::EdgeVector & path);
bool FindShortestPath(Graph::Edge const & from, Graph::Edge const & to, LinearSegmentSource source,
FunctionalRoadClass lowestFrcToNextPoint, uint32_t maxPathLength, Graph::EdgeVector & path);
bool ConnectAdjacentCandidateLines(Graph::EdgeVector const & from, Graph::EdgeVector const & to,
LinearSegmentSource source,
FunctionalRoadClass lowestFrcToNextPoint,
LinearSegmentSource source, FunctionalRoadClass lowestFrcToNextPoint,
double distanceToNextPoint, Graph::EdgeVector & resultPath);
Score GetScoreForUniformity(Graph::EdgeVector const & path);

View File

@@ -20,15 +20,9 @@ struct ScorePoint
ScorePoint() = default;
ScorePoint(Score score, m2::PointD const & point) : m_score(score), m_point(point) {}
bool operator<(ScorePoint const & o) const
{
return std::tie(m_score, m_point) < std::tie(o.m_score, o.m_point);
}
bool operator<(ScorePoint const & o) const { return std::tie(m_score, m_point) < std::tie(o.m_score, o.m_point); }
bool operator==(ScorePoint const & o) const
{
return m_score == o.m_score && m_point == o.m_point;
}
bool operator==(ScorePoint const & o) const { return m_score == o.m_score && m_point == o.m_point; }
Score m_score = 0;
m2::PointD m_point;

View File

@@ -44,5 +44,5 @@ struct alignas(kCacheLineSize) Stats
// Number of zeroed distance-to-next point values in the input.
uint32_t m_zeroDistToNextPointCount = 0;
};
} // namespace V2
} // namespace v2
} // namespace openlr

View File

@@ -16,8 +16,7 @@ struct WayPoint final
, m_distanceToNextPointM(lrp.m_distanceToNextPoint)
, m_bearing(lrp.m_bearing)
, m_lfrcnp(lrp.m_functionalRoadClass)
{
}
{}
m2::PointD m_point;
double m_distanceToNextPointM = 0.0;

View File

@@ -50,8 +50,7 @@ bool IsReversedIntervals(size_t fromDst, size_t toDst, size_t fromSrc, size_t to
return (fromDst > toDst) != (fromSrc > toSrc);
}
std::vector<m2::PointD> AppendPointsWithAnyDirection(std::vector<MarkedPoint> const & copyFrom,
size_t from, size_t to)
std::vector<m2::PointD> AppendPointsWithAnyDirection(std::vector<MarkedPoint> const & copyFrom, size_t from, size_t to)
{
std::vector<m2::PointD> result;
if (from > to)
@@ -63,16 +62,14 @@ std::vector<m2::PointD> AppendPointsWithAnyDirection(std::vector<MarkedPoint> co
return result;
}
double AbsAreaDiff(std::vector<m2::PointD> const & firstPolygon,
std::vector<m2::PointD> const & secondPolygon)
double AbsAreaDiff(std::vector<m2::PointD> const & firstPolygon, std::vector<m2::PointD> const & secondPolygon)
{
auto const firstArea = generator::AreaOnEarth(firstPolygon);
auto const secondArea = generator::AreaOnEarth(secondPolygon);
return std::abs(secondArea - firstArea);
}
bool NeedReplace(std::vector<m2::PointD> const & curSubpolygon,
std::vector<m2::PointD> const & anotherSubpolygon)
bool NeedReplace(std::vector<m2::PointD> const & curSubpolygon, std::vector<m2::PointD> const & anotherSubpolygon)
{
auto const areaDiff = AbsAreaDiff(curSubpolygon, anotherSubpolygon);
double constexpr kMaxAreaDiffMetersSquared = 20000.0;
@@ -195,7 +192,7 @@ void BordersData::Init(std::string const & bordersDir)
void BordersData::DumpPolyFiles(std::string const & targetDir)
{
size_t n = m_bordersPolygons.size();
for (size_t i = 0; i < n; )
for (size_t i = 0; i < n;)
{
// Russia_Moscow.poly1 -> Russia_Moscow.poly
auto name = RemoveIndexFromMwmName(m_indexToPolyFileName.at(i));
@@ -270,11 +267,9 @@ void BordersData::PrintDiff()
CHECK_NOT_EQUAL(allNumberBeforeCount, 0, ("Empty input?"));
std::cout << "Number of removed points: " << m_removedPointsCount << std::endl
<< "Removed duplicate point: " << m_duplicatedPointsCount << std::endl
<< "Total removed points: " << m_removedPointsCount + m_duplicatedPointsCount
<< std::endl;
<< "Total removed points: " << m_removedPointsCount + m_duplicatedPointsCount << std::endl;
std::cout << "Points number before processing: " << allNumberBeforeCount << ", remove( "
<< static_cast<double>(m_removedPointsCount + m_duplicatedPointsCount) /
allNumberBeforeCount * 100.0
<< static_cast<double>(m_removedPointsCount + m_duplicatedPointsCount) / allNumberBeforeCount * 100.0
<< "% )" << std::endl;
}
@@ -298,8 +293,8 @@ void BordersData::RemoveEmptySpaceBetweenBorders()
size_t constexpr kMaxLookAhead = 5;
for (size_t shift = 1; shift <= kMaxLookAhead; ++shift)
{
if (TryToReplace(curBorderId, curPointId /* curLeftPointId */,
curPointId + shift /* curRightPointId */) == base::ControlFlow::Break)
if (TryToReplace(curBorderId, curPointId /* curLeftPointId */, curPointId + shift /* curRightPointId */) ==
base::ControlFlow::Break)
{
break;
}
@@ -310,8 +305,7 @@ void BordersData::RemoveEmptySpaceBetweenBorders()
DoReplace();
}
base::ControlFlow BordersData::TryToReplace(size_t curBorderId, size_t & curLeftPointId,
size_t curRightPointId)
base::ControlFlow BordersData::TryToReplace(size_t curBorderId, size_t & curLeftPointId, size_t curRightPointId)
{
auto & curPolygon = m_bordersPolygons[curBorderId];
if (curRightPointId >= curPolygon.m_points.size())
@@ -348,10 +342,9 @@ base::ControlFlow BordersData::TryToReplace(size_t curBorderId, size_t & curLeft
}
auto const anotherSubpolygon =
AppendPointsWithAnyDirection(anotherPolygon.m_points, anotherLeftPointId, anotherRightPointId);
AppendPointsWithAnyDirection(anotherPolygon.m_points, anotherLeftPointId, anotherRightPointId);
auto const curSubpolygon =
AppendPointsWithAnyDirection(curPolygon.m_points, curLeftPointId, curRightPointId);
auto const curSubpolygon = AppendPointsWithAnyDirection(curPolygon.m_points, curLeftPointId, curRightPointId);
if (!NeedReplace(curSubpolygon, anotherSubpolygon))
return base::ControlFlow::Break;
@@ -361,26 +354,25 @@ base::ControlFlow BordersData::TryToReplace(size_t curBorderId, size_t & curLeft
bool const curLenIsLess = curSubpolygon.size() < anotherSubpolygon.size();
size_t dstFrom = curLenIsLess ? anotherLeftPointId : curLeftPointId;
size_t dstTo = curLenIsLess ? anotherRightPointId : curRightPointId;
size_t dstTo = curLenIsLess ? anotherRightPointId : curRightPointId;
size_t srcFrom = curLenIsLess ? curLeftPointId : anotherLeftPointId;
size_t srcTo = curLenIsLess ? curRightPointId : anotherRightPointId;
size_t srcFrom = curLenIsLess ? curLeftPointId : anotherLeftPointId;
size_t srcTo = curLenIsLess ? curRightPointId : anotherRightPointId;
size_t const borderIdWhereAreaWillBeChanged = curLenIsLess ? anotherBorderId : curBorderId;
size_t const srcBorderId = curLenIsLess ? curBorderId : anotherBorderId;
bool const reversed = IsReversedIntervals(dstFrom, dstTo, srcFrom, srcTo);
m_additionalAreaMetersSqr[borderIdWhereAreaWillBeChanged] +=
AbsAreaDiff(curSubpolygon, anotherSubpolygon);
m_additionalAreaMetersSqr[borderIdWhereAreaWillBeChanged] += AbsAreaDiff(curSubpolygon, anotherSubpolygon);
SwapIfNeeded(dstFrom, dstTo);
SwapIfNeeded(srcFrom, srcTo);
// Save info for |borderIdWhereAreaWillBeChanged| - where from it should gets info about
// replacement.
m_bordersPolygons[borderIdWhereAreaWillBeChanged].AddReplaceInfo(
dstFrom, dstTo, srcFrom, srcTo, srcBorderId, reversed);
m_bordersPolygons[borderIdWhereAreaWillBeChanged].AddReplaceInfo(dstFrom, dstTo, srcFrom, srcTo, srcBorderId,
reversed);
// And say for |srcBorderId| that points in segment: [srcFrom, srcTo] are frozen and cannot
// be used anywhere (because we use them to replace points in segment: [dstFrom, dstTo]).

View File

@@ -30,12 +30,10 @@ private:
/// points and leaves only unique.
size_t RemoveDuplicatePoints();
template <class PointsT> static size_t RemoveDuplicatingPointImpl(PointsT & points)
template <class PointsT>
static size_t RemoveDuplicatingPointImpl(PointsT & points)
{
auto const equalFn = [](auto const & p1, auto const & p2)
{
return p1.EqualDxDy(p2, kEqualityEpsilon);
};
auto const equalFn = [](auto const & p1, auto const & p2) { return p1.EqualDxDy(p2, kEqualityEpsilon); };
auto const last = std::unique(points.begin(), points.end(), equalFn);
size_t count = std::distance(last, points.end());
@@ -53,8 +51,7 @@ private:
/// \brief Checks whether we can replace points from segment: [curLeftPointId, curRightPointId]
/// of |curBorderId| to points from another border in order to get rid of empty space
/// between curBorder and anotherBorder.
base::ControlFlow TryToReplace(size_t curBorderId, size_t & curLeftPointId,
size_t curRightPointId);
base::ControlFlow TryToReplace(size_t curBorderId, size_t & curLeftPointId, size_t curRightPointId);
bool HasLinkAt(size_t curBorderId, size_t pointId);

View File

@@ -57,8 +57,7 @@ bool Polygon::IsFrozen(size_t a, size_t b) const
return m_replaced.Intersects(a, b);
}
void Polygon::AddReplaceInfo(size_t dstFrom, size_t dstTo,
size_t srcFrom, size_t srcTo, size_t srcBorderId,
void Polygon::AddReplaceInfo(size_t dstFrom, size_t dstTo, size_t srcFrom, size_t srcTo, size_t srcBorderId,
bool reversed)
{
CHECK_LESS_OR_EQUAL(dstFrom, dstTo, ());
@@ -73,10 +72,8 @@ void Polygon::AddReplaceInfo(size_t dstFrom, size_t dstTo,
std::set<ReplaceData>::const_iterator Polygon::FindReplaceData(size_t index)
{
for (auto it = m_replaceData.cbegin(); it != m_replaceData.cend(); ++it)
{
if (it->m_dstFrom <= index && index <= it->m_dstTo)
return it;
}
return m_replaceData.cend();
}

View File

@@ -31,14 +31,15 @@ struct Link
/// \note Using next semantic here: [replaceFrom, replaceTo], [replaceFromSrc, replaceToSrc].
struct ReplaceData
{
ReplaceData(size_t replaceFrom, size_t replaceTo, size_t replaceFromSrc, size_t replaceToSrc,
size_t borderIdSrc, bool reversed)
ReplaceData(size_t replaceFrom, size_t replaceTo, size_t replaceFromSrc, size_t replaceToSrc, size_t borderIdSrc,
bool reversed)
: m_dstFrom(replaceFrom)
, m_dstTo(replaceTo)
, m_srcReplaceFrom(replaceFromSrc)
, m_srcReplaceTo(replaceToSrc)
, m_srcBorderId(borderIdSrc)
, m_reversed(reversed) {}
, m_reversed(reversed)
{}
bool operator<(ReplaceData const & rhs) const;
@@ -62,10 +63,7 @@ struct MarkedPoint
std::optional<Link> GetLink(size_t curBorderId) const;
bool EqualDxDy(MarkedPoint const & p, double eps) const
{
return m_point.EqualDxDy(p.m_point, eps);
}
bool EqualDxDy(MarkedPoint const & p, double eps) const { return m_point.EqualDxDy(p.m_point, eps); }
m2::PointD m_point;
std::set<Link> m_links;
@@ -78,10 +76,7 @@ struct Polygon
{
m_points.assign(points.begin(), points.end());
}
Polygon(m2::RectD const & rect, std::vector<MarkedPoint> && points)
: m_rect(rect), m_points(std::move(points))
{
}
Polygon(m2::RectD const & rect, std::vector<MarkedPoint> && points) : m_rect(rect), m_points(std::move(points)) {}
Polygon(Polygon &&) = default;
Polygon & operator=(Polygon &&) noexcept = default;
@@ -93,9 +88,8 @@ struct Polygon
// @}
// [replaceFrom, replaceTo], [replaceFromSrc, replaceToSrc]
void AddReplaceInfo(size_t replaceFrom, size_t replaceTo,
size_t replaceFromSrc, size_t replaceToSrc, size_t borderIdSrc,
bool reversed);
void AddReplaceInfo(size_t replaceFrom, size_t replaceTo, size_t replaceFromSrc, size_t replaceToSrc,
size_t borderIdSrc, bool reversed);
std::set<ReplaceData>::const_iterator FindReplaceData(size_t index);

View File

@@ -39,12 +39,10 @@ void CheckByMask(Polygon const & polygons, vector<bool> markedMask)
{
CHECK_EQUAL(polygons.m_points.size(), markedMask.size(), ());
for (size_t i = 0; i < polygons.m_points.size(); ++i)
{
if (markedMask[i])
TestMarked(polygons, i);
else
TestNotMarked(polygons, i);
}
}
UNIT_TEST(PolyBordersPostprocessor_MarkPoints_1)
@@ -55,21 +53,13 @@ UNIT_TEST(PolyBordersPostprocessor_MarkPoints_1)
m2::PointD a(-1.0, -1.0);
m2::PointD b(-1.0, 1.0);
vector<vector<m2::PointD>> polygons1 = {
{a, b, {1.0, 1.0}, {1.0, -1.0}}
};
vector<vector<m2::PointD>> polygons1 = {{a, b, {1.0, 1.0}, {1.0, -1.0}}};
vector<vector<bool>> markedMask1 = {
{true, true, false, false}
};
vector<vector<bool>> markedMask1 = {{true, true, false, false}};
vector<vector<m2::PointD>> polygons2 = {
{a, b, {2.0, 1.0}, {5.0, -1.0}}
};
vector<vector<m2::PointD>> polygons2 = {{a, b, {2.0, 1.0}, {5.0, -1.0}}};
vector<vector<bool>> markedMask2 = {
{true, true, false, false}
};
vector<vector<bool>> markedMask2 = {{true, true, false, false}};
vector<shared_ptr<ScopedFile>> files;
files.emplace_back(CreatePolyBorderFileByPolygon(kTestDir, "First", polygons1));
@@ -90,21 +80,13 @@ UNIT_TEST(PolyBordersPostprocessor_MarkPoints_2)
ScopedDir const scopedDir(kTestDir);
string const & bordersDir = scopedDir.GetFullPath();
vector<vector<m2::PointD>> polygons1 = {
{{-1.0, -1.0}, {-1.0, 1.0}, {1.0, 1.0}, {1.0, -1.0}}
};
vector<vector<m2::PointD>> polygons1 = {{{-1.0, -1.0}, {-1.0, 1.0}, {1.0, 1.0}, {1.0, -1.0}}};
vector<vector<bool>> markedMask1 = {
{false, false, false, false}
};
vector<vector<bool>> markedMask1 = {{false, false, false, false}};
vector<vector<m2::PointD>> polygons2 = {
{{-12.0, -1.0}, {-10.0, 1.0}, {2.0, 1.0}, {5.0, -1.0}}
};
vector<vector<m2::PointD>> polygons2 = {{{-12.0, -1.0}, {-10.0, 1.0}, {2.0, 1.0}, {5.0, -1.0}}};
vector<vector<bool>> markedMask2 = {
{false, false, false, false}
};
vector<vector<bool>> markedMask2 = {{false, false, false, false}};
vector<shared_ptr<ScopedFile>> files;
files.emplace_back(CreatePolyBorderFileByPolygon(kTestDir, "First", polygons1));
@@ -132,37 +114,21 @@ UNIT_TEST(PolyBordersPostprocessor_MarkPoints_3)
m2::PointD e(-4.0, 2.0);
m2::PointD f(-1.0, 4.0);
vector<vector<m2::PointD>> polygons1 = {
{a, b, c, {1.0, -3.0}, d}
};
vector<vector<m2::PointD>> polygons1 = {{a, b, c, {1.0, -3.0}, d}};
vector<vector<bool>> markedMask1 = {
{true, true, true, false, true}
};
vector<vector<bool>> markedMask1 = {{true, true, true, false, true}};
vector<vector<m2::PointD>> polygons2 = {
{b, f, {2.0, 5.0}, {6.0, 3.0}, c}
};
vector<vector<m2::PointD>> polygons2 = {{b, f, {2.0, 5.0}, {6.0, 3.0}, c}};
vector<vector<bool>> markedMask2 = {
{true, true, false, false, true}
};
vector<vector<bool>> markedMask2 = {{true, true, false, false, true}};
vector<vector<m2::PointD>> polygons3 = {
{a, b, f, {-3.0, 4.0}, e}
};
vector<vector<m2::PointD>> polygons3 = {{a, b, f, {-3.0, 4.0}, e}};
vector<vector<bool>> markedMask3 = {
{true, true, true, false, true}
};
vector<vector<bool>> markedMask3 = {{true, true, true, false, true}};
vector<vector<m2::PointD>> polygons4 = {
{a, e, {-3.0, -1.0}, d}
};
vector<vector<m2::PointD>> polygons4 = {{a, e, {-3.0, -1.0}, d}};
vector<vector<bool>> markedMask4 = {
{true, true, false, true}
};
vector<vector<bool>> markedMask4 = {{true, true, false, true}};
vector<shared_ptr<ScopedFile>> files;
files.emplace_back(CreatePolyBorderFileByPolygon(kTestDir, "First", polygons1));
@@ -194,23 +160,14 @@ UNIT_TEST(PolyBordersPostprocessor_MarkPoints_4)
m2::PointD a(6.0, 2.0);
m2::PointD b(6.0, 4.0);
vector<vector<m2::PointD>> polygons1 = {
{{-2.0, -2.0}, {-2.0, 2.0}, {2.0, 2.0}, {2.0, -2.0}},
{{4.0, 2.0}, {4.0, 4.0}, a, b}
};
vector<vector<m2::PointD>> polygons1 = {{{-2.0, -2.0}, {-2.0, 2.0}, {2.0, 2.0}, {2.0, -2.0}},
{{4.0, 2.0}, {4.0, 4.0}, a, b}};
vector<vector<bool>> markedMask1 = {
{false, false, false, false},
{false, false, true, true}
};
vector<vector<bool>> markedMask1 = {{false, false, false, false}, {false, false, true, true}};
vector<vector<m2::PointD>> polygons2 = {
{a, b, {8.0, 6.0}, {8.0, 0.0}}
};
vector<vector<m2::PointD>> polygons2 = {{a, b, {8.0, 6.0}, {8.0, 0.0}}};
vector<vector<bool>> markedMask2 = {
{true, true, false, false}
};
vector<vector<bool>> markedMask2 = {{true, true, false, false}};
vector<shared_ptr<ScopedFile>> files;
files.emplace_back(CreatePolyBorderFileByPolygon(kTestDir, "First", polygons1));
@@ -219,10 +176,12 @@ UNIT_TEST(PolyBordersPostprocessor_MarkPoints_4)
BordersData bordersData;
bordersData.Init(bordersDir);
auto const & firstBordersPolygon1 = bordersData.GetBordersPolygonByName("First" + BordersData::kBorderExtension + "1");
auto const & firstBordersPolygon1 =
bordersData.GetBordersPolygonByName("First" + BordersData::kBorderExtension + "1");
CheckByMask(firstBordersPolygon1, markedMask1[0]);
auto const & secondBordersPolygon1 = bordersData.GetBordersPolygonByName("First" + BordersData::kBorderExtension + "2");
auto const & secondBordersPolygon1 =
bordersData.GetBordersPolygonByName("First" + BordersData::kBorderExtension + "2");
CheckByMask(secondBordersPolygon1, markedMask1[1]);
auto const & bordersPolygon2 = bordersData.GetBordersPolygonByName("Second" + BordersData::kBorderExtension + "1");

View File

@@ -40,8 +40,7 @@ bool ConsistsOf(Polygon const & polygon, vector<m2::PointD> const & points)
for (size_t i = 0; i < polygon.m_points.size(); ++i)
{
static double constexpr kEps = 1e-5;
if (AlmostEqualAbs(point, polygon.m_points[i].m_point, kEps) &&
used.count(i) == 0)
if (AlmostEqualAbs(point, polygon.m_points[i].m_point, kEps) && used.count(i) == 0)
{
used.emplace(i);
break;
@@ -63,13 +62,9 @@ UNIT_TEST(PolyBordersPostprocessor_RemoveEmptySpaces_1)
m2::PointD d(3.0, 0.0);
m2::PointD e(4.0, 0.0);
vector<vector<m2::PointD>> polygons1 = {
{a, b, c, d, e}
};
vector<vector<m2::PointD>> polygons1 = {{a, b, c, d, e}};
vector<vector<m2::PointD>> polygons2 = {
{a, b, c, d, e}
};
vector<vector<m2::PointD>> polygons2 = {{a, b, c, d, e}};
vector<shared_ptr<ScopedFile>> files;
files.emplace_back(CreatePolyBorderFileByPolygon(kTestDir, "First", polygons1));
@@ -99,13 +94,9 @@ UNIT_TEST(PolyBordersPostprocessor_RemoveEmptySpaces_2)
m2::PointD e(4.0, 0.0);
// Point |c| is absent from polygons2, algorithm should remove |c| from polygon1.
vector<vector<m2::PointD>> polygons1 = {
{a, b, c, d, e}
};
vector<vector<m2::PointD>> polygons1 = {{a, b, c, d, e}};
vector<vector<m2::PointD>> polygons2 = {
{a, b, d, e}
};
vector<vector<m2::PointD>> polygons2 = {{a, b, d, e}};
vector<shared_ptr<ScopedFile>> files;
files.emplace_back(CreatePolyBorderFileByPolygon(kTestDir, "First", polygons1));
@@ -138,13 +129,9 @@ UNIT_TEST(PolyBordersPostprocessor_RemoveEmptySpaces_3)
m2::PointD f(5.0, 0.0);
// Point |c| and |d| is absent from polygons2, algorithm should remove |c| from polygon1.
vector<vector<m2::PointD>> polygons1 = {
{a, b, c, d, e, f}
};
vector<vector<m2::PointD>> polygons1 = {{a, b, c, d, e, f}};
vector<vector<m2::PointD>> polygons2 = {
{a, b, e, f}
};
vector<vector<m2::PointD>> polygons2 = {{a, b, e, f}};
vector<shared_ptr<ScopedFile>> files;
files.emplace_back(CreatePolyBorderFileByPolygon(kTestDir, "First", polygons1));
@@ -172,13 +159,9 @@ UNIT_TEST(PolyBordersPostprocessor_RemoveEmptySpaces_4)
m2::PointD d(4.0, 0.0);
m2::PointD e(5.0, 0.0);
vector<vector<m2::PointD>> polygons1 = {
{a, b, c, d, e}
};
vector<vector<m2::PointD>> polygons1 = {{a, b, c, d, e}};
vector<vector<m2::PointD>> polygons2 = {
{a, b, d, e}
};
vector<vector<m2::PointD>> polygons2 = {{a, b, d, e}};
vector<shared_ptr<ScopedFile>> files;
files.emplace_back(CreatePolyBorderFileByPolygon(kTestDir, "First", polygons1));
@@ -210,13 +193,9 @@ UNIT_TEST(PolyBordersPostprocessor_RemoveEmptySpaces_5)
m2::PointD c2(c1 + kSmallPointShift);
m2::PointD d2(d1 + kSmallPointShift);
vector<vector<m2::PointD>> polygons1 = {
{a, c1, d1, e1, b}
};
vector<vector<m2::PointD>> polygons1 = {{a, c1, d1, e1, b}};
vector<vector<m2::PointD>> polygons2 = {
{a, c2, d2, b}
};
vector<vector<m2::PointD>> polygons2 = {{a, c2, d2, b}};
vector<shared_ptr<ScopedFile>> files;
files.emplace_back(CreatePolyBorderFileByPolygon(kTestDir, "First", polygons1));
@@ -244,13 +223,9 @@ UNIT_TEST(PolyBordersPostprocessor_RemoveEmptySpaces_6)
m2::PointD d(4.0, 0.0);
m2::PointD e(5.0, 0.0);
vector<vector<m2::PointD>> polygons1 = {
{a, b, c, d, d, d, e, e, e}
};
vector<vector<m2::PointD>> polygons1 = {{a, b, c, d, d, d, e, e, e}};
vector<vector<m2::PointD>> polygons2 = {
{a, d, d, d, e}
};
vector<vector<m2::PointD>> polygons2 = {{a, d, d, d, e}};
vector<shared_ptr<ScopedFile>> files;
files.emplace_back(CreatePolyBorderFileByPolygon(kTestDir, "First", polygons1));

View File

@@ -15,8 +15,7 @@ using namespace platform::tests_support;
namespace
{
std::vector<m2::RegionD> ConvertFromPointsVector(
std::vector<std::vector<m2::PointD>> const & polygons)
std::vector<m2::RegionD> ConvertFromPointsVector(std::vector<std::vector<m2::PointD>> const & polygons)
{
std::vector<m2::RegionD> res;
res.reserve(polygons.size());
@@ -29,9 +28,8 @@ std::vector<m2::RegionD> ConvertFromPointsVector(
namespace poly_borders
{
std::shared_ptr<ScopedFile> CreatePolyBorderFileByPolygon(
std::string const & relativeDirPath, std::string const & name,
std::vector<std::vector<m2::PointD>> const & polygons)
std::shared_ptr<ScopedFile> CreatePolyBorderFileByPolygon(std::string const & relativeDirPath, std::string const & name,
std::vector<std::vector<m2::PointD>> const & polygons)
{
std::string path = base::JoinPath(relativeDirPath, name + BordersData::kBorderExtension);

View File

@@ -10,8 +10,7 @@
namespace poly_borders
{
std::shared_ptr<platform::tests_support::ScopedFile>
CreatePolyBorderFileByPolygon(std::string const & relativeDirPath,
std::string const & name,
std::vector<std::vector<m2::PointD>> const & polygons);
std::shared_ptr<platform::tests_support::ScopedFile> CreatePolyBorderFileByPolygon(
std::string const & relativeDirPath, std::string const & name,
std::vector<std::vector<m2::PointD>> const & polygons);
} // namespace poly_borders

View File

@@ -19,14 +19,15 @@ using namespace poly_borders;
int main(int argc, char ** argv)
{
gflags::ParseCommandLineFlags(&argc, &argv, true);
gflags::SetUsageMessage("\n\n\tThe tool is used to process *.poly borders files. We use such files\n"
"\tto cut the planet into mwms in generator. The problem is that we have\n"
"\tempty spaces between neighbouring borders. This tool creates new borders\n"
"\tbased on input data by removing points from borders in such a way that the\n"
"\tchanged area of each border will not be too large.\n"
"\tArguments:\n"
"\t\t--borders_path=/path/to/directory/with/borders\n"
"\t\t--output_path=/path/to/directory/where/new/borders/will/be/placed\n");
gflags::SetUsageMessage(
"\n\n\tThe tool is used to process *.poly borders files. We use such files\n"
"\tto cut the planet into mwms in generator. The problem is that we have\n"
"\tempty spaces between neighbouring borders. This tool creates new borders\n"
"\tbased on input data by removing points from borders in such a way that the\n"
"\tchanged area of each border will not be too large.\n"
"\tArguments:\n"
"\t\t--borders_path=/path/to/directory/with/borders\n"
"\t\t--output_path=/path/to/directory/where/new/borders/will/be/placed\n");
if (FLAGS_borders_path.empty() || FLAGS_output_path.empty())
{

View File

@@ -9,28 +9,26 @@
#include <iostream>
#include <iterator>
#include <QtXml/QDomElement>
#include <QtXml/QDomDocument>
#include <QtCore/QDir>
#include <QtXml/QDomDocument>
#include <QtXml/QDomElement>
namespace tools
{
namespace
{
static constexpr double kLargeIconSize = 24.0; // Size of the -l SVG icons
static constexpr double kMediumIconSize = 18.0; // size of the -m SVG icons
static constexpr double kLargeIconSize = 24.0; // Size of the -l SVG icons
static constexpr double kMediumIconSize = 18.0; // size of the -m SVG icons
struct GreaterHeight
{
bool operator() (SkinGenerator::SymbolInfo const & left,
SkinGenerator::SymbolInfo const & right) const
bool operator()(SkinGenerator::SymbolInfo const & left, SkinGenerator::SymbolInfo const & right) const
{
QString symbolIDleft = left.m_fullFileName.left(left.m_fullFileName.lastIndexOf("."));
QString symbolIDright = right.m_fullFileName.left(right.m_fullFileName.lastIndexOf("."));
if (left.m_size.height() == right.m_size.height()) {
if (left.m_size.height() == right.m_size.height())
return symbolIDleft > symbolIDright;
}
return (left.m_size.height() > right.m_size.height());
}
};
@@ -40,8 +38,7 @@ struct MaxDimensions
uint32_t & m_width;
uint32_t & m_height;
MaxDimensions(uint32_t & width, uint32_t & height)
: m_width(width), m_height(height)
MaxDimensions(uint32_t & width, uint32_t & height) : m_width(width), m_height(height)
{
m_width = 0;
m_height = 0;
@@ -65,12 +62,10 @@ uint32_t NextPowerOf2(uint32_t n)
return n + 1;
}
}
} // namespace
void SkinGenerator::ProcessSymbols(std::string const & svgDataDir,
std::string const & skinName,
std::vector<QSize> const & symbolSizes,
std::vector<std::string> const & suffixes)
void SkinGenerator::ProcessSymbols(std::string const & svgDataDir, std::string const & skinName,
std::vector<QSize> const & symbolSizes, std::vector<std::string> const & suffixes)
{
for (size_t j = 0; j < symbolSizes.size(); ++j)
{
@@ -97,7 +92,7 @@ void SkinGenerator::ProcessSymbols(std::string const & svgDataDir,
QString fullFileName = QString(dir.absolutePath()) + "/" + fileName;
if (m_svgRenderer.load(fullFileName))
{
QSize svgSize = m_svgRenderer.defaultSize(); // Size of the SVG file
QSize svgSize = m_svgRenderer.defaultSize(); // Size of the SVG file
// Capping svg symbol to kLargeIconSize maximum, keeping aspect ratio
/*if (svgSize.width() > kLargeIconSize)
@@ -153,8 +148,8 @@ bool SkinGenerator::RenderPages(uint32_t maxSize)
for (auto & s : page.m_symbols)
{
s.m_handle = page.m_packer.pack(static_cast<uint32_t>(s.m_size.width()),
static_cast<uint32_t>(s.m_size.height()));
s.m_handle =
page.m_packer.pack(static_cast<uint32_t>(s.m_size.width()), static_cast<uint32_t>(s.m_size.height()));
if (m_overflowDetected)
break;
}
@@ -221,7 +216,7 @@ void SkinGenerator::MarkOverflow()
m_overflowDetected = true;
}
bool SkinGenerator::WriteToFileNewStyle(std::string const &skinName)
bool SkinGenerator::WriteToFileNewStyle(std::string const & skinName)
{
QDomDocument doc = QDomDocument("skin");
QDomElement rootElem = doc.createElement("root");
@@ -254,4 +249,4 @@ bool SkinGenerator::WriteToFileNewStyle(std::string const &skinName)
ts << doc.toString();
return true;
}
} // namespace tools
} // namespace tools

View File

@@ -1,16 +1,16 @@
#pragma once
#include "geometry/rect2d.hpp"
#include "geometry/packer.hpp"
#include "geometry/rect2d.hpp"
#include "coding/writer.hpp"
#include "base/base.hpp"
#include <QtGui/QPainter>
#include <QtGui/QImage>
#include <QtCore/QFileInfo>
#include <QtCore/QSize>
#include <QtGui/QImage>
#include <QtGui/QPainter>
#include <QtSvg/QSvgRenderer>
#include <cstdint>
@@ -35,7 +35,9 @@ public:
SymbolInfo() {}
SymbolInfo(QSize size, QString const & fullFileName, QString const & symbolID)
: m_size(size), m_fullFileName(fullFileName), m_symbolID(symbolID)
: m_size(size)
, m_fullFileName(fullFileName)
, m_symbolID(symbolID)
{}
};
@@ -53,8 +55,7 @@ public:
};
void ProcessSymbols(std::string const & symbolsDir, std::string const & skinName,
std::vector<QSize> const & symbolSizes,
std::vector<std::string> const & suffix);
std::vector<QSize> const & symbolSizes, std::vector<std::string> const & suffix);
bool RenderPages(uint32_t maxSize);
bool WriteToFileNewStyle(std::string const & skinName);

View File

@@ -1,17 +1,18 @@
#include "generator.hpp"
#include "base/logging.hpp"
#include <iostream>
#include "base/logging.hpp"
#include <QApplication>
#include <QtCore/QFile>
#include <QtCore/QString>
#include <QtCore/QHash>
#include <QtCore/QString>
#include <gflags/gflags.h>
DEFINE_string(fontFileName, "../../data/01_dejavusans.ttf", "path to TrueType font file");
DEFINE_string(symbolsFile, "../../data/results.unicode", "file with 2bytes symbols for which the skin should be generated");
DEFINE_string(symbolsFile, "../../data/results.unicode",
"file with 2bytes symbols for which the skin should be generated");
DEFINE_string(symbolsDir, "../../data/styles/symbols", "directory with svg symbol files");
DEFINE_int32(symbolWidth, 24, "width of the rendered symbol");
DEFINE_int32(symbolHeight, 24, "height of the rendered symbol");
@@ -21,9 +22,9 @@ DEFINE_int32(searchIconWidth, 24, "width of the search category icon");
DEFINE_int32(searchIconHeight, 24, "height of the search category icon");
DEFINE_int32(maxSize, 4096, "max width/height of output textures");
int main(int argc, char *argv[])
int main(int argc, char * argv[])
{
// Used to lock the hash seed, so the order of XML attributes is always the same.
// Used to lock the hash seed, so the order of XML attributes is always the same.
QHashSeed::setDeterministicGlobalSeed();
try
{

View File

@@ -10,10 +10,8 @@
namespace topography_generator
{
template <typename ValueType>
void GetExtendedTile(ms::LatLon const & leftBottom, size_t stepsInDegree,
size_t tileSize, size_t tileSizeExtension,
ValuesProvider<ValueType> & valuesProvider,
std::vector<ValueType> & extTileValues)
void GetExtendedTile(ms::LatLon const & leftBottom, size_t stepsInDegree, size_t tileSize, size_t tileSizeExtension,
ValuesProvider<ValueType> & valuesProvider, std::vector<ValueType> & extTileValues)
{
size_t const extendedTileSize = tileSize + 2 * tileSizeExtension;
extTileValues.resize(extendedTileSize * extendedTileSize);
@@ -22,19 +20,16 @@ void GetExtendedTile(ms::LatLon const & leftBottom, size_t stepsInDegree,
double const offset = step * tileSizeExtension;
// Store values from North to South.
ms::LatLon startPos = ms::LatLon(leftBottom.m_lat + 1.0 + offset,
leftBottom.m_lon - offset);
ms::LatLon startPos = ms::LatLon(leftBottom.m_lat + 1.0 + offset, leftBottom.m_lon - offset);
for (size_t i = 0; i < extendedTileSize; ++i)
{
for (size_t j = 0; j < extendedTileSize; ++j)
{
auto pos = ms::LatLon(startPos.m_lat - i * step,
startPos.m_lon + j * step);
auto pos = ms::LatLon(startPos.m_lat - i * step, startPos.m_lon + j * step);
auto val = valuesProvider.GetValue(pos);
if (val == valuesProvider.GetInvalidValue() &&
((i < tileSizeExtension) || (i >= tileSizeExtension + tileSize) ||
(j < tileSizeExtension) || (j >= tileSizeExtension + tileSize)))
if (val == valuesProvider.GetInvalidValue() && ((i < tileSizeExtension) || (i >= tileSizeExtension + tileSize) ||
(j < tileSizeExtension) || (j >= tileSizeExtension + tileSize)))
{
auto const ni = std::max(std::min(i, tileSizeExtension + tileSize - 1), tileSizeExtension);
auto const nj = std::max(std::min(j, tileSizeExtension + tileSize - 1), tileSizeExtension);
@@ -49,8 +44,7 @@ void GetExtendedTile(ms::LatLon const & leftBottom, size_t stepsInDegree,
template <typename ValueType>
void ProcessWithLinearKernel(std::vector<double> const & kernel, size_t tileSize, size_t tileOffset,
std::vector<ValueType> const & srcValues,
std::vector<ValueType> & dstValues,
std::vector<ValueType> const & srcValues, std::vector<ValueType> & dstValues,
ValueType invalidValue)
{
auto const kernelSize = kernel.size();
@@ -84,9 +78,7 @@ void ProcessWithLinearKernel(std::vector<double> const & kernel, size_t tileSize
}
}
for (size_t j = tileOffset; j < tileSize - tileOffset; ++j)
{
dstValues[i * tileSize + j] = tempValues[j];
}
}
for (size_t j = tileOffset; j < tileSize - tileOffset; ++j)
@@ -112,17 +104,13 @@ void ProcessWithLinearKernel(std::vector<double> const & kernel, size_t tileSize
}
}
for (size_t i = tileOffset; i < tileSize - tileOffset; ++i)
{
dstValues[i * tileSize + j] = tempValues[i];
}
}
}
template <typename ValueType>
void ProcessWithSquareKernel(std::vector<double> const & kernel, size_t kernelSize,
size_t tileSize, size_t tileOffset,
std::vector<ValueType> const & srcValues,
std::vector<ValueType> & dstValues,
void ProcessWithSquareKernel(std::vector<double> const & kernel, size_t kernelSize, size_t tileSize, size_t tileOffset,
std::vector<ValueType> const & srcValues, std::vector<ValueType> & dstValues,
ValueType invalidValue)
{
CHECK_EQUAL(kernelSize * kernelSize, kernel.size(), ());
@@ -161,10 +149,8 @@ void ProcessWithSquareKernel(std::vector<double> const & kernel, size_t kernelSi
}
template <typename ValueType>
void ProcessMedian(size_t kernelRadius, size_t tileSize, size_t tileOffset,
std::vector<ValueType> const & srcValues,
std::vector<ValueType> & dstValues,
ValueType invalidValue)
void ProcessMedian(size_t kernelRadius, size_t tileSize, size_t tileOffset, std::vector<ValueType> const & srcValues,
std::vector<ValueType> & dstValues, ValueType invalidValue)
{
CHECK_LESS_OR_EQUAL(kernelRadius, tileOffset, ());
CHECK_GREATER(tileSize, tileOffset * 2, ());

View File

@@ -25,8 +25,7 @@ size_t constexpr kArcSecondsInDegree = 60 * 60;
int constexpr kAsterTilesLatTop = 60;
int constexpr kAsterTilesLatBottom = -60;
void MercatorRectToTilesRange(m2::RectD const & rect,
int & left, int & bottom, int & right, int & top)
void MercatorRectToTilesRange(m2::RectD const & rect, int & left, int & bottom, int & right, int & top)
{
auto const leftBottom = mercator::ToLatLon(rect.LeftBottom());
auto const rightTop = mercator::ToLatLon(rect.RightTop());
@@ -65,19 +64,15 @@ bool LoadTileProfiles(std::string const & fileName, std::set<std::string> & prof
return false;
std::string line;
while (std::getline(fin, line))
{
if (!line.empty())
profileNames.insert(line);
}
return true;
}
class SrtmProvider : public ValuesProvider<Altitude>
{
public:
explicit SrtmProvider(std::string const & srtmDir):
m_srtmManager(srtmDir)
{}
explicit SrtmProvider(std::string const & srtmDir) : m_srtmManager(srtmDir) {}
void SetPrefferedTile(ms::LatLon const & pos)
{
@@ -95,10 +90,7 @@ public:
Altitude GetInvalidValue() const override { return kInvalidAltitude; }
static bool IsValidAltitude(Altitude alt)
{
return alt != kInvalidAltitude && alt > -435 && alt < 8850;
}
static bool IsValidAltitude(Altitude alt) { return alt != kInvalidAltitude && alt > -435 && alt < 8850; }
private:
Altitude GetValueImpl(ms::LatLon pos)
@@ -111,8 +103,8 @@ private:
// Try to prevent loading a new tile if the position can be found in the loaded one.
auto const latDist = pos.m_lat - m_leftBottomOfPreferredTile.m_lat;
auto const lonDist = pos.m_lon - m_leftBottomOfPreferredTile.m_lon;
if (latDist > -kPointEqualityEps && latDist < 1.0 + kPointEqualityEps &&
lonDist > -kPointEqualityEps && lonDist < 1.0 + kPointEqualityEps)
if (latDist > -kPointEqualityEps && latDist < 1.0 + kPointEqualityEps && lonDist > -kPointEqualityEps &&
lonDist < 1.0 + kPointEqualityEps)
{
if (latDist < 0.0)
pos.m_lat += kPointEqualityEps;
@@ -174,8 +166,7 @@ private:
class RawAltitudesTile : public ValuesProvider<Altitude>
{
public:
RawAltitudesTile(std::vector<Altitude> const & values,
int leftLon, int bottomLat)
RawAltitudesTile(std::vector<Altitude> const & values, int leftLon, int bottomLat)
: m_values(values)
, m_leftLon(leftLon)
, m_bottomLat(bottomLat)
@@ -209,10 +200,9 @@ private:
class SeamlessAltitudeProvider : public ValuesProvider<Altitude>
{
public:
using IsOnBorderFn = std::function<bool (ms::LatLon const & pos)>;
using IsOnBorderFn = std::function<bool(ms::LatLon const & pos)>;
SeamlessAltitudeProvider(ValuesProvider<Altitude> & originalProvider,
ValuesProvider<Altitude> & filteredProvider,
SeamlessAltitudeProvider(ValuesProvider<Altitude> & originalProvider, ValuesProvider<Altitude> & filteredProvider,
IsOnBorderFn && isOnBorderFn)
: m_originalProvider(originalProvider)
, m_filteredProvider(filteredProvider)
@@ -267,10 +257,8 @@ public:
void Do()
{
for (int lat = m_bottom; lat <= m_top; ++lat)
{
for (int lon = m_left; lon <= m_right; ++lon)
ProcessTile(lat, lon);
}
}
private:
@@ -337,8 +325,7 @@ private:
auto const outFile = GetIsolinesFilePath(lat, lon, params.m_outputDir);
if (!m_forceRegenerate && GetPlatform().IsFileExistsByFullPath(outFile))
{
LOG(LINFO, ("Isolines for", tileName, ", profile", profileName,
"are ready, skip processing."));
LOG(LINFO, ("Isolines for", tileName, ", profile", profileName, "are ready, skip processing."));
return;
}
@@ -350,11 +337,8 @@ private:
if (!params.m_filters.empty() && (lat >= kAsterTilesLatTop || lat < kAsterTilesLatBottom))
{
// Filter tiles converted from ASTER, cause they are noisy enough.
std::vector<Altitude> filteredValues = FilterTile(params.m_filters,
ms::LatLon(lat, lon),
kArcSecondsInDegree,
kArcSecondsInDegree + 1,
m_srtmProvider);
std::vector<Altitude> filteredValues = FilterTile(params.m_filters, ms::LatLon(lat, lon), kArcSecondsInDegree,
kArcSecondsInDegree + 1, m_srtmProvider);
RawAltitudesTile filteredProvider(filteredValues, lon, lat);
GenerateSeamlessContours(lat, lon, params, filteredProvider, contours);
}
@@ -363,9 +347,8 @@ private:
GenerateSeamlessContours(lat, lon, params, m_srtmProvider, contours);
}
LOG(LINFO, ("Isolines for tile", tileName, ", profile", profileName,
"min altitude", contours.m_minValue, "max altitude",
contours.m_maxValue, "invalid values count", contours.m_invalidValuesCount));
LOG(LINFO, ("Isolines for tile", tileName, ", profile", profileName, "min altitude", contours.m_minValue,
"max altitude", contours.m_maxValue, "invalid values count", contours.m_invalidValuesCount));
if (params.m_simplificationZoom > 0)
SimplifyContours(params.m_simplificationZoom, contours);
@@ -375,23 +358,21 @@ private:
}
void GenerateSeamlessContours(int lat, int lon, TileIsolinesParams const & params,
ValuesProvider<Altitude> & altProvider,
Contours<Altitude> & contours)
ValuesProvider<Altitude> & altProvider, Contours<Altitude> & contours)
{
// Avoid seam between SRTM and ASTER.
if ((lat == kAsterTilesLatTop) || (lat == kAsterTilesLatBottom - 1))
{
m_srtmProvider.SetPrefferedTile(ms::LatLon(lat == kAsterTilesLatTop ? lat - 0.5 : lat + 0.5, lon));
SeamlessAltitudeProvider seamlessAltProvider(m_srtmProvider, altProvider,
[](ms::LatLon const & pos)
{
// In case when two altitudes sources are used for altitudes extraction,
// for the same position on the border could be returned different altitudes.
// Force to use altitudes near the srtm/aster border from srtm source,
// it helps to avoid contours gaps due to different altitudes for equal positions.
return fabs(pos.m_lat - kAsterTilesLatTop) < mercator::kPointEqualityEps ||
fabs(pos.m_lat - kAsterTilesLatBottom) < mercator::kPointEqualityEps;
});
SeamlessAltitudeProvider seamlessAltProvider(m_srtmProvider, altProvider, [](ms::LatLon const & pos)
{
// In case when two altitudes sources are used for altitudes extraction,
// for the same position on the border could be returned different altitudes.
// Force to use altitudes near the srtm/aster border from srtm source,
// it helps to avoid contours gaps due to different altitudes for equal positions.
return fabs(pos.m_lat - kAsterTilesLatTop) < mercator::kPointEqualityEps ||
fabs(pos.m_lat - kAsterTilesLatBottom) < mercator::kPointEqualityEps;
});
GenerateContours(lat, lon, params, seamlessAltProvider, contours);
}
else
@@ -400,16 +381,14 @@ private:
}
}
void GenerateContours(int lat, int lon, TileIsolinesParams const & params,
ValuesProvider<Altitude> & altProvider, Contours<Altitude> & contours)
void GenerateContours(int lat, int lon, TileIsolinesParams const & params, ValuesProvider<Altitude> & altProvider,
Contours<Altitude> & contours)
{
auto const leftBottom = ms::LatLon(lat, lon);
auto const rightTop = ms::LatLon(lat + 1.0, lon + 1.0);
auto const squaresStep = 1.0 / kArcSecondsInDegree * params.m_latLonStepFactor;
MarchingSquares<Altitude> squares(leftBottom, rightTop,
squaresStep, params.m_alitudesStep,
altProvider, m_debugId);
MarchingSquares<Altitude> squares(leftBottom, rightTop, squaresStep, params.m_alitudesStep, altProvider, m_debugId);
squares.GenerateContours(contours);
}
@@ -426,9 +405,8 @@ private:
};
template <typename ParamsType>
void RunGenerateIsolinesTasks(int left, int bottom, int right, int top,
std::string const & srtmPath, ParamsType const & params,
long threadsCount, long maxCachedTilesPerThread,
void RunGenerateIsolinesTasks(int left, int bottom, int right, int top, std::string const & srtmPath,
ParamsType const & params, long threadsCount, long maxCachedTilesPerThread,
bool forceRegenerate)
{
std::vector<std::unique_ptr<TileIsolinesTask>> tasks;
@@ -447,12 +425,10 @@ void RunGenerateIsolinesTasks(int left, int bottom, int right, int top,
else
{
while (tilesRowPerTask * tilesColPerTask > static_cast<long>(maxCachedTilesPerThread))
{
if (tilesRowPerTask > tilesColPerTask)
tilesRowPerTask = (tilesRowPerTask + 1) / 2;
else
tilesColPerTask = (tilesColPerTask + 1) / 2;
}
}
base::ComputationalThreadPool threadPool(threadsCount);
@@ -463,43 +439,38 @@ void RunGenerateIsolinesTasks(int left, int bottom, int right, int top,
for (int lon = left; lon < right; lon += tilesColPerTask)
{
int const rightLon = std::min(lon + tilesColPerTask - 1, right - 1);
auto task = std::make_unique<TileIsolinesTask>(lon, lat, rightLon, topLat, srtmPath, &params,
forceRegenerate);
threadPool.SubmitWork([task = std::move(task)](){ task->Do(); });
auto task = std::make_unique<TileIsolinesTask>(lon, lat, rightLon, topLat, srtmPath, &params, forceRegenerate);
threadPool.SubmitWork([task = std::move(task)]() { task->Do(); });
}
}
}
} // namespace
Generator::Generator(std::string const & srtmPath, long threadsCount,
long maxCachedTilesPerThread, bool forceRegenerate)
Generator::Generator(std::string const & srtmPath, long threadsCount, long maxCachedTilesPerThread,
bool forceRegenerate)
: m_threadsCount(threadsCount)
, m_maxCachedTilesPerThread(maxCachedTilesPerThread)
, m_srtmPath(srtmPath)
, m_forceRegenerate(forceRegenerate)
{}
void Generator::GenerateIsolines(int left, int bottom, int right, int top,
TileIsolinesParams const & params)
void Generator::GenerateIsolines(int left, int bottom, int right, int top, TileIsolinesParams const & params)
{
RunGenerateIsolinesTasks(left, bottom, right, top, m_srtmPath, params,
m_threadsCount, m_maxCachedTilesPerThread, m_forceRegenerate);
RunGenerateIsolinesTasks(left, bottom, right, top, m_srtmPath, params, m_threadsCount, m_maxCachedTilesPerThread,
m_forceRegenerate);
}
void Generator::GenerateIsolines(int left, int bottom, int right, int top,
std::string const & tilesProfilesDir)
void Generator::GenerateIsolines(int left, int bottom, int right, int top, std::string const & tilesProfilesDir)
{
TileIsolinesProfileParams params(m_profileToTileParams, tilesProfilesDir);
RunGenerateIsolinesTasks(left, bottom, right, top, m_srtmPath, params,
m_threadsCount, m_maxCachedTilesPerThread, m_forceRegenerate);
RunGenerateIsolinesTasks(left, bottom, right, top, m_srtmPath, params, m_threadsCount, m_maxCachedTilesPerThread,
m_forceRegenerate);
}
void Generator::GenerateIsolinesForCountries()
{
auto const & pl = GetPlatform();
if (!pl.IsFileExistsByFullPath(m_isolinesTilesOutDir) &&
!pl.MkDirRecursively(m_isolinesTilesOutDir))
if (!pl.IsFileExistsByFullPath(m_isolinesTilesOutDir) && !pl.MkDirRecursively(m_isolinesTilesOutDir))
{
LOG(LERROR, ("Can't create directory", m_isolinesTilesOutDir));
return;
@@ -513,8 +484,7 @@ void Generator::GenerateIsolinesForCountries()
continue;
checkedProfiles.insert(profileName);
auto const profileTilesDir = GetTilesDir(m_isolinesTilesOutDir, profileName);
if (!pl.IsFileExistsByFullPath(profileTilesDir) &&
!pl.MkDirChecked(profileTilesDir))
if (!pl.IsFileExistsByFullPath(profileTilesDir) && !pl.MkDirChecked(profileTilesDir))
{
LOG(LERROR, ("Can't create directory", profileTilesDir));
return;
@@ -576,18 +546,16 @@ void Generator::GenerateIsolinesForCountries()
LOG(LINFO, ("Generate isolines for tiles rect", boundingRect));
GenerateIsolines(boundingRect.LeftBottom().x, boundingRect.LeftBottom().y,
boundingRect.RightTop().x + 1, boundingRect.RightTop().y + 1, tmpTileProfilesDir);
GenerateIsolines(boundingRect.LeftBottom().x, boundingRect.LeftBottom().y, boundingRect.RightTop().x + 1,
boundingRect.RightTop().y + 1, tmpTileProfilesDir);
}
void Generator::PackIsolinesForCountry(storage::CountryId const & countryId,
IsolinesPackingParams const & params)
void Generator::PackIsolinesForCountry(storage::CountryId const & countryId, IsolinesPackingParams const & params)
{
PackIsolinesForCountry(countryId, params, nullptr /*needSkipTileFn*/);
}
void Generator::PackIsolinesForCountry(storage::CountryId const & countryId,
IsolinesPackingParams const & params,
void Generator::PackIsolinesForCountry(storage::CountryId const & countryId, IsolinesPackingParams const & params,
NeedSkipTileFn const & needSkipTileFn)
{
auto const outFile = GetIsolinesFilePath(countryId, params.m_outputDir);
@@ -629,8 +597,7 @@ void Generator::PackIsolinesForCountry(storage::CountryId const & countryId,
LOG(LINFO, ("Begin packing isolines from tile", tileFilePath));
CropContours(countryRect, countryRegions, params.m_maxIsolineLength,
params.m_alitudesStepFactor, isolines);
CropContours(countryRect, countryRegions, params.m_maxIsolineLength, params.m_alitudesStepFactor, isolines);
// Simplification is done already while processing tiles in ProcessTile().
// But now a different country-specific simpificationZoom could be applied.
if (params.m_simplificationZoom > 0)
@@ -644,17 +611,15 @@ void Generator::PackIsolinesForCountry(storage::CountryId const & countryId,
for (auto & levelIsolines : isolines.m_contours)
{
auto & dst = countryIsolines.m_contours[levelIsolines.first];
std::move(levelIsolines.second.begin(), levelIsolines.second.end(),
std::back_inserter(dst));
std::move(levelIsolines.second.begin(), levelIsolines.second.end(), std::back_inserter(dst));
}
LOG(LINFO, ("End packing isolines from tile", tileFilePath));
}
}
LOG(LINFO, ("End packing isolines for country", countryId,
"min altitude", countryIsolines.m_minValue,
"max altitude", countryIsolines.m_maxValue));
LOG(LINFO, ("End packing isolines for country", countryId, "min altitude", countryIsolines.m_minValue, "max altitude",
countryIsolines.m_maxValue));
SaveContrours(outFile, std::move(countryIsolines));
@@ -684,7 +649,7 @@ void Generator::PackIsolinesForCountries()
auto const & packingParams = m_profileToPackingParams.at(params.m_profileName);
PackIsolinesForCountry(countryId, packingParams,
[&params](int lat, int lon){ return params.NeedSkipTile(lat, lon); });
[&params](int lat, int lon) { return params.NeedSkipTile(lat, lon); });
LOG(LINFO, ("End task", taskInd, "/", tasksCount, countryId));
});
@@ -703,8 +668,7 @@ void Generator::InitCountryInfoGetter(std::string const & dataDir)
}
void Generator::InitProfiles(std::string const & isolinesProfilesFileName,
std::string const & countriesToGenerateFileName,
std::string const & isolinesTilesOutDir,
std::string const & countriesToGenerateFileName, std::string const & isolinesTilesOutDir,
std::string const & isolinesCountriesOutDir)
{
CHECK(Deserialize(isolinesProfilesFileName, m_profilesCollection), ());
@@ -714,8 +678,7 @@ void Generator::InitProfiles(std::string const & isolinesProfilesFileName,
for (auto const & countryParams : m_countriesToGenerate.m_countryParams)
{
auto const & params = countryParams.second;
CHECK(profiles.find(params.m_profileName) != profiles.end(),
("Unknown profile name", params.m_profileName));
CHECK(profiles.find(params.m_profileName) != profiles.end(), ("Unknown profile name", params.m_profileName));
}
m_isolinesTilesOutDir = isolinesTilesOutDir;
@@ -735,9 +698,8 @@ void Generator::InitProfiles(std::string const & isolinesProfilesFileName,
tileParams.m_filters.emplace_back(std::make_unique<MedianFilter<Altitude>>(profileParams.m_medianFilterR));
if (profileParams.m_gaussianFilterStDev > 0.0 && profileParams.m_gaussianFilterRFactor > 0)
{
tileParams.m_filters.emplace_back(
std::make_unique<GaussianFilter<Altitude>>(profileParams.m_gaussianFilterStDev,
profileParams.m_gaussianFilterRFactor));
tileParams.m_filters.emplace_back(std::make_unique<GaussianFilter<Altitude>>(
profileParams.m_gaussianFilterStDev, profileParams.m_gaussianFilterRFactor));
}
m_profileToTileParams.emplace(profileName, std::move(tileParams));
@@ -758,10 +720,8 @@ void Generator::GetCountryRegions(storage::CountryId const & countryId, m2::Rect
size_t id;
for (id = 0; id < m_infoReader->GetCountries().size(); ++id)
{
if (m_infoReader->GetCountries().at(id).m_countryId == countryId)
break;
}
CHECK_LESS(id, m_infoReader->GetCountries().size(), ());
/// @todo Refactor using Memory[Mapped] reader for countries.

View File

@@ -1,7 +1,7 @@
#pragma once
#include "topography_generator/isolines_utils.hpp"
#include "topography_generator/isolines_profile.hpp"
#include "topography_generator/isolines_utils.hpp"
#include "topography_generator/tile_filter.hpp"
#include "storage/country_info_getter.hpp"
@@ -18,7 +18,7 @@ struct TileIsolinesParams
{
Altitude m_alitudesStep = 10;
size_t m_latLonStepFactor = 1;
int m_simplificationZoom = 17; // Value == 0 disables simplification.
int m_simplificationZoom = 17; // Value == 0 disables simplification.
FiltersSequence<Altitude> m_filters;
std::string m_outputDir;
};
@@ -27,8 +27,7 @@ using ProfileToTileIsolinesParams = std::map<std::string, TileIsolinesParams>;
struct TileIsolinesProfileParams
{
TileIsolinesProfileParams(ProfileToTileIsolinesParams const & profiles,
std::string const & tilesProfilesDir)
TileIsolinesProfileParams(ProfileToTileIsolinesParams const & profiles, std::string const & tilesProfilesDir)
: m_profiles(profiles)
, m_tilesProfilesDir(tilesProfilesDir)
{}
@@ -40,7 +39,7 @@ struct TileIsolinesProfileParams
struct IsolinesPackingParams
{
size_t m_maxIsolineLength = 1000;
int m_simplificationZoom = 17; // Value == 0 disables simplification.
int m_simplificationZoom = 17; // Value == 0 disables simplification.
size_t m_alitudesStepFactor = 1;
std::string m_isolinesTilesPath;
std::string m_outputDir;
@@ -51,32 +50,25 @@ using ProfileToIsolinesPackingParams = std::map<std::string, IsolinesPackingPara
class Generator
{
public:
Generator(std::string const & srtmPath, long threadsCount, long maxCachedTilesPerThread,
bool forceRegenerate);
Generator(std::string const & srtmPath, long threadsCount, long maxCachedTilesPerThread, bool forceRegenerate);
void InitCountryInfoGetter(std::string const & dataDir);
void GenerateIsolines(int left, int bottom, int right, int top,
TileIsolinesParams const & params);
void GenerateIsolines(int left, int bottom, int right, int top, TileIsolinesParams const & params);
void PackIsolinesForCountry(storage::CountryId const & countryId,
IsolinesPackingParams const & params);
void PackIsolinesForCountry(storage::CountryId const & countryId, IsolinesPackingParams const & params);
void InitProfiles(std::string const & isolinesProfilesFileName,
std::string const & countriesToGenerateFileName,
std::string const & isolinesTilesOutDir,
std::string const & isolinesCountriesOutDir);
void InitProfiles(std::string const & isolinesProfilesFileName, std::string const & countriesToGenerateFileName,
std::string const & isolinesTilesOutDir, std::string const & isolinesCountriesOutDir);
void GenerateIsolinesForCountries();
void PackIsolinesForCountries();
private:
void GenerateIsolines(int left, int bottom, int right, int top,
std::string const & tilesProfilesDir);
void GenerateIsolines(int left, int bottom, int right, int top, std::string const & tilesProfilesDir);
using NeedSkipTileFn = std::function<bool(int lat, int lon)>;
void PackIsolinesForCountry(storage::CountryId const & countryId,
IsolinesPackingParams const & params,
void PackIsolinesForCountry(storage::CountryId const & countryId, IsolinesPackingParams const & params,
NeedSkipTileFn const & needSkipTileFn);
void GetCountryRegions(storage::CountryId const & countryId, m2::RectD & countryRect,

View File

@@ -21,10 +21,10 @@ struct IsolinesProfile
uint32_t m_alitudesStep = 10;
uint8_t m_latLonStepFactor = 1;
uint32_t m_maxIsolinesLength = 1000;
uint8_t m_simplificationZoom = 17; // Value == 0 disables simplification.
uint8_t m_medianFilterR = 1; // Value == 0 disables filter.
double m_gaussianFilterStDev = 2.0; // Value == 0.0 disables filter.
double m_gaussianFilterRFactor = 1.0; // Value == 0.0 disables filter.
uint8_t m_simplificationZoom = 17; // Value == 0 disables simplification.
uint8_t m_medianFilterR = 1; // Value == 0 disables filter.
double m_gaussianFilterStDev = 2.0; // Value == 0.0 disables filter.
double m_gaussianFilterRFactor = 1.0; // Value == 0.0 disables filter.
DECLARE_VISITOR_AND_DEBUG_PRINT(IsolinesProfile, visitor(m_alitudesStep, "alitudesStep"),
visitor(m_latLonStepFactor, "latLonStepFactor"),
@@ -45,18 +45,14 @@ struct IsolinesProfilesCollection
struct TileCoord
{
TileCoord() = default;
TileCoord(int bottomLat, int leftLon): m_leftLon(leftLon), m_bottomLat(bottomLat) {}
TileCoord(int bottomLat, int leftLon) : m_leftLon(leftLon), m_bottomLat(bottomLat) {}
int32_t m_leftLon = 0;
int32_t m_bottomLat = 0;
bool operator==(TileCoord const & rhs) const
{
return m_leftLon == rhs.m_leftLon && m_bottomLat == rhs.m_bottomLat;
}
bool operator==(TileCoord const & rhs) const { return m_leftLon == rhs.m_leftLon && m_bottomLat == rhs.m_bottomLat; }
DECLARE_VISITOR_AND_DEBUG_PRINT(TileCoord, visitor(m_bottomLat, "bottomLat"),
visitor(m_leftLon, "leftLon"))
DECLARE_VISITOR_AND_DEBUG_PRINT(TileCoord, visitor(m_bottomLat, "bottomLat"), visitor(m_leftLon, "leftLon"))
};
struct TileCoordHash
@@ -94,7 +90,7 @@ struct CountriesToGenerate
DECLARE_VISITOR_AND_DEBUG_PRINT(CountriesToGenerate, visitor(m_countryParams, "countryParams"))
};
template<typename DataType>
template <typename DataType>
bool Serialize(std::string const & fileName, DataType const & data)
{
try
@@ -115,7 +111,7 @@ bool Serialize(std::string const & fileName, DataType const & data)
return false;
}
template<typename DataType>
template <typename DataType>
bool Deserialize(std::string const & fileName, DataType & data)
{
try

View File

@@ -12,14 +12,18 @@
DEFINE_bool(force, false, "Force to regenerate isolines for tiles and countries.");
// Options for automatic isolines generating mode.
DEFINE_string(profiles_path, "", "Automatic isolines generating mode. "
"Path to a json file with isolines profiles.");
DEFINE_string(countries_to_generate_path, "", "Automatic isolines generating mode. "
"Path to a json file with countries to generate.");
DEFINE_string(tiles_isolines_out_dir, "", "Automatic isolines generating mode. Path to output "
"intermediate directory with tiles isolines.");
DEFINE_string(countries_isolines_out_dir, "", "Automatic isolines generating mode. "
"Path to output directory with countries isolines.");
DEFINE_string(profiles_path, "",
"Automatic isolines generating mode. "
"Path to a json file with isolines profiles.");
DEFINE_string(countries_to_generate_path, "",
"Automatic isolines generating mode. "
"Path to a json file with countries to generate.");
DEFINE_string(tiles_isolines_out_dir, "",
"Automatic isolines generating mode. Path to output "
"intermediate directory with tiles isolines.");
DEFINE_string(countries_isolines_out_dir, "",
"Automatic isolines generating mode. "
"Path to output directory with countries isolines.");
// Common option for automatic isolines generating mode and custom packing mode.
DEFINE_string(data_dir, "", "Path to data directory.");
@@ -34,10 +38,8 @@ DEFINE_string(out_dir, "", "Path to output directory.");
DEFINE_uint64(simpl_zoom, 16, "Isolines simplification zoom.");
// Options for custom isolines packing mode.
DEFINE_string(countryId, "",
"Custom isolines packing mode. Pack isolines for countryId.");
DEFINE_string(isolines_path, "",
"Custom isolines packing mode. Path to the directory with isolines tiles.");
DEFINE_string(countryId, "", "Custom isolines packing mode. Pack isolines for countryId.");
DEFINE_string(isolines_path, "", "Custom isolines packing mode. Path to the directory with isolines tiles.");
DEFINE_uint64(max_length, 1000, "Custom isolines packing mode. Isolines max length.");
DEFINE_uint64(alt_step_factor, 1, "Custom isolines packing mode. Altitude step factor.");
@@ -57,40 +59,38 @@ using namespace topography_generator;
MAIN_WITH_ERROR_HANDLING([](int argc, char ** argv)
{
gflags::SetUsageMessage(
"\n\nThis tool generates isolines and works in the following modes:\n"
"1. Automatic isolines generating mode. Generates a binary file with isolines for each\n"
" country id from the countries_to_generate_path. Gets options for isolines generating\n"
" from the corresponding to the country profile in profiles_path.\n"
" Stores intermediate binary isolines tiles to tiles_isolines_out_dir and result countries\n"
" isolines to countries_isolines_out_dir.\n"
"2. Custom isolines generating mode. Generates binary tile with isolines for each SRTM tile in the\n"
" specified tile rect.\n"
" Mode activates by passing a valid tiles rect.\n"
" An isoline would be generated for each isolines_step difference in height.\n"
" Tiles for lat >= 60 && lat < -60 (converted from ASTER source) can be filtered by\n"
" median and/or gaussian filters.\n"
" Median filter activates by nonzero filter kernel radius median_r.\n"
" Gaussian filter activates by gaussian_st_dev > 0.0 && gaussian_r_factor > 0.0 parameters.\n"
" Contours generating steps through altitudes matrix of SRTM tile can be adjusted by\n"
" latlon_step_factor parameter.\n"
" Isolines simplification activates by nonzero simpl_zoom [1..17]\n"
"\n"
"3. Custom packing isolines from ready tiles into a binary file for specified country id.\n"
" Mode activates by passing a countryId parameter.\n"
" Tool gets isolines from the tiles, covered by the country regions, selects\n"
" altitude levels with alt_step_factor (if a tile stores altitudes for each 10 meters\n"
" and alt_step_factor == 5, the result binary file will store altitudes for each 50 meters).\n"
" Isolines cropped by the country regions and cut by max_length parameter.\n"
" Isolines simplification activates by nonzero simpl_zoom [1..17]\n\n");
"\n\nThis tool generates isolines and works in the following modes:\n"
"1. Automatic isolines generating mode. Generates a binary file with isolines for each\n"
" country id from the countries_to_generate_path. Gets options for isolines generating\n"
" from the corresponding to the country profile in profiles_path.\n"
" Stores intermediate binary isolines tiles to tiles_isolines_out_dir and result countries\n"
" isolines to countries_isolines_out_dir.\n"
"2. Custom isolines generating mode. Generates binary tile with isolines for each SRTM tile in the\n"
" specified tile rect.\n"
" Mode activates by passing a valid tiles rect.\n"
" An isoline would be generated for each isolines_step difference in height.\n"
" Tiles for lat >= 60 && lat < -60 (converted from ASTER source) can be filtered by\n"
" median and/or gaussian filters.\n"
" Median filter activates by nonzero filter kernel radius median_r.\n"
" Gaussian filter activates by gaussian_st_dev > 0.0 && gaussian_r_factor > 0.0 parameters.\n"
" Contours generating steps through altitudes matrix of SRTM tile can be adjusted by\n"
" latlon_step_factor parameter.\n"
" Isolines simplification activates by nonzero simpl_zoom [1..17]\n"
"\n"
"3. Custom packing isolines from ready tiles into a binary file for specified country id.\n"
" Mode activates by passing a countryId parameter.\n"
" Tool gets isolines from the tiles, covered by the country regions, selects\n"
" altitude levels with alt_step_factor (if a tile stores altitudes for each 10 meters\n"
" and alt_step_factor == 5, the result binary file will store altitudes for each 50 meters).\n"
" Isolines cropped by the country regions and cut by max_length parameter.\n"
" Isolines simplification activates by nonzero simpl_zoom [1..17]\n\n");
gflags::ParseCommandLineFlags(&argc, &argv, true);
bool isCustomGeneratingMode = false;
bool isCustomPackingMode = false;
bool const isAutomaticMode = !FLAGS_profiles_path.empty() ||
!FLAGS_countries_to_generate_path.empty() ||
!FLAGS_tiles_isolines_out_dir.empty() ||
!FLAGS_countries_isolines_out_dir.empty();
bool const isAutomaticMode = !FLAGS_profiles_path.empty() || !FLAGS_countries_to_generate_path.empty() ||
!FLAGS_tiles_isolines_out_dir.empty() || !FLAGS_countries_isolines_out_dir.empty();
if (isAutomaticMode)
{
if (FLAGS_profiles_path.empty() || FLAGS_countries_to_generate_path.empty() ||
@@ -110,9 +110,8 @@ MAIN_WITH_ERROR_HANDLING([](int argc, char ** argv)
return EXIT_FAILURE;
}
auto const validTilesRect = FLAGS_right > FLAGS_left && FLAGS_top > FLAGS_bottom &&
FLAGS_right <= 180 && FLAGS_left >= -180 &&
FLAGS_top <= 90 && FLAGS_bottom >= -90;
auto const validTilesRect = FLAGS_right > FLAGS_left && FLAGS_top > FLAGS_bottom && FLAGS_right <= 180 &&
FLAGS_left >= -180 && FLAGS_top <= 90 && FLAGS_bottom >= -90;
isCustomGeneratingMode = validTilesRect;
isCustomPackingMode = !FLAGS_countryId.empty();
@@ -155,8 +154,8 @@ MAIN_WITH_ERROR_HANDLING([](int argc, char ** argv)
if (isAutomaticMode)
{
generator.InitCountryInfoGetter(FLAGS_data_dir);
generator.InitProfiles(FLAGS_profiles_path, FLAGS_countries_to_generate_path,
FLAGS_tiles_isolines_out_dir, FLAGS_countries_isolines_out_dir);
generator.InitProfiles(FLAGS_profiles_path, FLAGS_countries_to_generate_path, FLAGS_tiles_isolines_out_dir,
FLAGS_countries_isolines_out_dir);
generator.GenerateIsolinesForCountries();
generator.PackIsolinesForCountries();
@@ -188,14 +187,12 @@ MAIN_WITH_ERROR_HANDLING([](int argc, char ** argv)
TileIsolinesParams params;
if (FLAGS_median_r > 0)
{
params.m_filters.emplace_back(std::make_unique<MedianFilter<Altitude>>(FLAGS_median_r));
}
if (FLAGS_gaussian_st_dev > 0.0 && FLAGS_gaussian_r_factor > 0)
{
params.m_filters.emplace_back(
std::make_unique<GaussianFilter<Altitude>>(FLAGS_gaussian_st_dev, FLAGS_gaussian_r_factor));
std::make_unique<GaussianFilter<Altitude>>(FLAGS_gaussian_st_dev, FLAGS_gaussian_r_factor));
}
params.m_outputDir = FLAGS_out_dir;

View File

@@ -49,10 +49,8 @@ void ContoursBuilder::AddSegment(size_t levelInd, ms::LatLon const & beginPos, m
void ContoursBuilder::BeginLine()
{
for (auto & contoursList : m_activeContours)
{
for (auto & activeContour : contoursList)
activeContour.m_active = false;
}
}
void ContoursBuilder::EndLine(bool finalLine)
@@ -80,10 +78,8 @@ ContoursBuilder::ActiveContourIter ContoursBuilder::FindContourWithStartPoint(si
{
auto & contours = m_activeContours[levelInd];
for (auto it = contours.begin(); it != contours.end(); ++it)
{
if (it->m_countour.front().EqualDxDy(pos, mercator::kPointEqualityEps))
return it;
}
return contours.end();
}
@@ -91,10 +87,8 @@ ContoursBuilder::ActiveContourIter ContoursBuilder::FindContourWithEndPoint(size
{
auto & contours = m_activeContours[levelInd];
for (auto it = contours.begin(); it != contours.end(); ++it)
{
if (it->m_countour.back().EqualDxDy(pos, mercator::kPointEqualityEps))
return it;
}
return contours.end();
}
} // namespace topography_generator

View File

@@ -8,8 +8,8 @@
#include <algorithm>
#include <deque>
#include <list>
#include <vector>
#include <unordered_map>
#include <vector>
namespace topography_generator
{
@@ -36,7 +36,7 @@ public:
Contour contourMerc;
contourMerc.reserve(contour.size());
std::transform(contour.begin(), contour.end(), std::back_inserter(contourMerc),
[](ms::LatLon const & pt){ return mercator::FromLatLon(pt); });
[](ms::LatLon const & pt) { return mercator::FromLatLon(pt); });
contours[levelValue].emplace_back(std::move(contourMerc));
}
@@ -49,9 +49,7 @@ private:
struct ActiveContour
{
explicit ActiveContour(ContourRaw && isoline)
: m_countour(std::move(isoline))
{}
explicit ActiveContour(ContourRaw && isoline) : m_countour(std::move(isoline)) {}
ContourRaw m_countour;
bool m_active = true;

View File

@@ -13,9 +13,8 @@ template <typename ValueType>
class MarchingSquares
{
public:
MarchingSquares(ms::LatLon const & leftBottom, ms::LatLon const & rightTop,
double step, ValueType valueStep, ValuesProvider<ValueType> & valuesProvider,
std::string const & debugId)
MarchingSquares(ms::LatLon const & leftBottom, ms::LatLon const & rightTop, double step, ValueType valueStep,
ValuesProvider<ValueType> & valuesProvider, std::string const & debugId)
: m_leftBottom(leftBottom)
, m_rightTop(rightTop)
, m_step(step)
@@ -58,18 +57,17 @@ public:
// This point should be calculated _exact_ the same way as in ScanValuesInRect.
// leftBottom + m_step doesn't work due to different floating results.
square.Init(
m_leftBottom.m_lon + m_step * j, // Left
m_leftBottom.m_lat + m_step * i, // Bottom
m_leftBottom.m_lon + m_step * (j + 1), // Right
m_leftBottom.m_lat + m_step * (i + 1), // Top
square.Init(m_leftBottom.m_lon + m_step * j, // Left
m_leftBottom.m_lat + m_step * i, // Bottom
m_leftBottom.m_lon + m_step * (j + 1), // Right
m_leftBottom.m_lat + m_step * (i + 1), // Top
grid[Idx(i, j)], // LB
grid[Idx(i, j + 1)], // RB
grid[Idx(i + 1, j)], // LT
grid[Idx(i + 1, j + 1)], // RT
grid[Idx(i, j)], // LB
grid[Idx(i, j + 1)], // RB
grid[Idx(i + 1, j)], // LT
grid[Idx(i + 1, j + 1)], // RT
m_valuesProvider.GetInvalidValue());
m_valuesProvider.GetInvalidValue());
square.GenerateSegments(contoursBuilder);
}

View File

@@ -2,7 +2,6 @@
#include "topography_generator/marching_squares/contours_builder.hpp"
namespace topography_generator
{
template <typename ValueType>
@@ -17,8 +16,8 @@ public:
static_assert(std::is_integral<ValueType>::value && std::is_signed<ValueType>::value);
}
void Init(double left, double bottom, double right, double top,
ValueType lb, ValueType rb, ValueType lt, ValueType rt, ValueType invalid)
void Init(double left, double bottom, double right, double top, ValueType lb, ValueType rb, ValueType lt,
ValueType rt, ValueType invalid)
{
m_isValid = true;
@@ -79,7 +78,7 @@ private:
// Shift the value slightly from the corner.
if (val == invalid)
{
//LOG(LWARNING, ("Invalid value at the position", pos, m_debugId));
// LOG(LWARNING, ("Invalid value at the position", pos, m_debugId));
m_isValid = false;
return val;
}
@@ -92,28 +91,27 @@ private:
void AddSegments(ValueType val, uint16_t ind, ContoursBuilder & builder) const
{
// Segment is a vector directed so that higher values is on the right.
static const std::pair<Rib, Rib> intersectedRibs[] =
{
{Rib::None, Rib::None}, // 0000
{Rib::Left, Rib::Bottom}, // 0001
{Rib::Top, Rib::Left}, // 0010
{Rib::Top, Rib::Bottom}, // 0011
{Rib::Right, Rib::Top}, // 0100
{Rib::Unclear, Rib::Unclear}, // 0101
{Rib::Right, Rib::Left}, // 0110
{Rib::Right, Rib::Bottom}, // 0111
{Rib::Bottom, Rib::Right}, // 1000
{Rib::Left, Rib::Right}, // 1001
{Rib::Unclear, Rib::Unclear}, // 1010
{Rib::Top, Rib::Right}, // 1011
{Rib::Bottom, Rib::Top}, // 1100
{Rib::Left, Rib::Top}, // 1101
{Rib::Bottom, Rib::Left}, // 1110
{Rib::None, Rib::None}, // 1111
};
static std::pair<Rib, Rib> const intersectedRibs[] = {
{Rib::None, Rib::None}, // 0000
{Rib::Left, Rib::Bottom}, // 0001
{Rib::Top, Rib::Left}, // 0010
{Rib::Top, Rib::Bottom}, // 0011
{Rib::Right, Rib::Top}, // 0100
{Rib::Unclear, Rib::Unclear}, // 0101
{Rib::Right, Rib::Left}, // 0110
{Rib::Right, Rib::Bottom}, // 0111
{Rib::Bottom, Rib::Right}, // 1000
{Rib::Left, Rib::Right}, // 1001
{Rib::Unclear, Rib::Unclear}, // 1010
{Rib::Top, Rib::Right}, // 1011
{Rib::Bottom, Rib::Top}, // 1100
{Rib::Left, Rib::Top}, // 1101
{Rib::Bottom, Rib::Left}, // 1110
{Rib::None, Rib::None}, // 1111
};
uint8_t const pattern = (m_valueLB > val ? 1u : 0u) | ((m_valueLT > val ? 1u : 0u) << 1u) |
((m_valueRT > val ? 1u : 0u) << 2u) | ((m_valueRB > val ? 1u : 0u) << 3u);
uint8_t const pattern = (m_valueLB > val ? 1u : 0u) | ((m_valueLT > val ? 1u : 0u) << 1u) |
((m_valueRT > val ? 1u : 0u) << 2u) | ((m_valueRB > val ? 1u : 0u) << 3u);
auto const ribs = intersectedRibs[pattern];
@@ -145,18 +143,15 @@ private:
builder.AddSegment(ind, topPos, rightPos);
}
}
else if (m_valueLB > val)
{
builder.AddSegment(ind, leftPos, bottomPos);
builder.AddSegment(ind, rightPos, topPos);
}
else
{
if (m_valueLB > val)
{
builder.AddSegment(ind, leftPos, bottomPos);
builder.AddSegment(ind, rightPos, topPos);
}
else
{
builder.AddSegment(ind, topPos, leftPos);
builder.AddSegment(ind, bottomPos, rightPos);
}
builder.AddSegment(ind, topPos, leftPos);
builder.AddSegment(ind, bottomPos, rightPos);
}
}
}
@@ -190,8 +185,7 @@ private:
val2 = static_cast<double>(m_valueRB);
lat = m_bottom;
break;
default:
UNREACHABLE();
default: UNREACHABLE();
}
CHECK_NOT_EQUAL(val, val2, (m_debugId));
@@ -200,15 +194,10 @@ private:
switch (rib)
{
case Rib::Left:
case Rib::Right:
lat = (m_bottom + m_top * coeff) / (1 + coeff);
break;
case Rib::Right: lat = (m_bottom + m_top * coeff) / (1 + coeff); break;
case Rib::Bottom:
case Rib::Top:
lon = (m_left + m_right * coeff) / (1 + coeff);
break;
default:
UNREACHABLE();
case Rib::Top: lon = (m_left + m_right * coeff) / (1 + coeff); break;
default: UNREACHABLE();
}
return {lat, lon};
@@ -230,4 +219,4 @@ private:
bool m_isValid;
};
} // topography_generator
} // namespace topography_generator

View File

@@ -11,23 +11,19 @@ public:
virtual ~FilterInterface() = default;
virtual size_t GetKernelRadius() const = 0;
virtual void Process(size_t tileSize, size_t tileOffset,
std::vector<ValueType> const & srcValues,
std::vector<ValueType> & dstValues, ValueType invalidValue) const = 0;
virtual void Process(size_t tileSize, size_t tileOffset, std::vector<ValueType> const & srcValues,
std::vector<ValueType> & dstValues, ValueType invalidValue) const = 0;
};
template <typename ValueType>
class MedianFilter : public FilterInterface<ValueType>
{
public:
explicit MedianFilter(size_t kernelRadius)
: m_kernelRadius(kernelRadius)
{}
explicit MedianFilter(size_t kernelRadius) : m_kernelRadius(kernelRadius) {}
size_t GetKernelRadius() const override { return m_kernelRadius; }
void Process(size_t tileSize, size_t tileOffset,
std::vector<ValueType> const & srcValues,
void Process(size_t tileSize, size_t tileOffset, std::vector<ValueType> const & srcValues,
std::vector<ValueType> & dstValues, ValueType invalidValue) const override
{
ProcessMedian(m_kernelRadius, tileSize, tileOffset, srcValues, dstValues, invalidValue);
@@ -47,8 +43,7 @@ public:
size_t GetKernelRadius() const override { return m_kernel.size() / 2; }
void Process(size_t tileSize, size_t tileOffset,
std::vector<ValueType> const & srcValues,
void Process(size_t tileSize, size_t tileOffset, std::vector<ValueType> const & srcValues,
std::vector<ValueType> & dstValues, ValueType invalidValue) const override
{
ProcessWithLinearKernel(m_kernel, tileSize, tileOffset, srcValues, dstValues, invalidValue);
@@ -62,10 +57,8 @@ template <typename ValueType>
using FiltersSequence = std::vector<std::unique_ptr<FilterInterface<ValueType>>>;
template <typename ValueType>
std::vector<ValueType> FilterTile(FiltersSequence<ValueType> const & filters,
ms::LatLon const & leftBottom,
size_t stepsInDegree, size_t tileSize,
ValuesProvider<ValueType> & valuesProvider)
std::vector<ValueType> FilterTile(FiltersSequence<ValueType> const & filters, ms::LatLon const & leftBottom,
size_t stepsInDegree, size_t tileSize, ValuesProvider<ValueType> & valuesProvider)
{
size_t combinedOffset = 0;
for (auto const & filter : filters)

View File

@@ -7,8 +7,8 @@
#include "indexer/scales.hpp"
#include <vector>
#include <unordered_map>
#include <vector>
namespace topography_generator
{
@@ -27,12 +27,12 @@ struct Contours
ValueType m_minValue = 0;
ValueType m_maxValue = 0;
ValueType m_valueStep = 0;
size_t m_invalidValuesCount = 0; // for debug purpose only.
size_t m_invalidValuesCount = 0; // for debug purpose only.
};
template <typename ValueType>
void CropContours(m2::RectD & rect, std::vector<m2::RegionD> & regions, size_t maxLength,
size_t valueStepFactor, Contours<ValueType> & contours)
void CropContours(m2::RectD & rect, std::vector<m2::RegionD> & regions, size_t maxLength, size_t valueStepFactor,
Contours<ValueType> & contours)
{
static_assert(std::is_integral<ValueType>::value, "Only integral types are supported.");
@@ -90,8 +90,7 @@ void SimplifyContours(int simplificationZoom, Contours<ValueType> & contours)
for (auto & contour : levelContours.second)
{
std::vector<m2::PointD> contourSimple;
feature::SimplifyPoints(m2::SquaredDistanceFromSegmentToPoint(),
simplificationZoom, contour, contourSimple);
feature::SimplifyPoints(m2::SquaredDistanceFromSegmentToPoint(), simplificationZoom, contour, contourSimple);
CHECK_GREATER(contourSimple.size(), 1, ());
// Discard closed lines which are degenerate (<=3 points) or too small for the requested zoom level.
/// @todo it doesn't fix all cases as the simplification algo

View File

@@ -2,8 +2,8 @@
#include "topography_generator/utils/contours.hpp"
#include "coding/file_writer.hpp"
#include "coding/file_reader.hpp"
#include "coding/file_writer.hpp"
#include "coding/geometry_coding.hpp"
#include "coding/internal/file_data.hpp"
@@ -13,7 +13,7 @@ template <typename ValueType>
class SerializerContours
{
public:
explicit SerializerContours(Contours<ValueType> && contours): m_contours(std::move(contours)) {}
explicit SerializerContours(Contours<ValueType> && contours) : m_contours(std::move(contours)) {}
template <typename Sink>
void Serialize(Sink & sink)
@@ -31,8 +31,7 @@ public:
private:
template <typename Sink>
void SerializeContours(Sink & sink, ValueType value,
std::vector<topography_generator::Contour> const & contours)
void SerializeContours(Sink & sink, ValueType value, std::vector<topography_generator::Contour> const & contours)
{
WriteToSink(sink, value);
WriteToSink(sink, static_cast<uint32_t>(contours.size()));
@@ -81,7 +80,7 @@ public:
private:
void DeserializeContours(NonOwningReaderSource & source, ValueType & value,
std::vector<topography_generator::Contour> & contours)
std::vector<topography_generator::Contour> & contours)
{
value = ReadPrimitiveFromSource<ValueType>(source);
size_t const contoursCount = ReadPrimitiveFromSource<uint32_t>(source);
@@ -90,8 +89,7 @@ private:
DeserializeContour(source, contour);
}
void DeserializeContour(NonOwningReaderSource & source,
topography_generator::Contour & contour)
void DeserializeContour(NonOwningReaderSource & source, topography_generator::Contour & contour)
{
serial::GeometryCodingParams codingParams;
codingParams.Load(source);
@@ -102,8 +100,7 @@ private:
};
template <typename ValueType>
bool SaveContrours(std::string const & filePath,
Contours<ValueType> && contours)
bool SaveContrours(std::string const & filePath, Contours<ValueType> && contours)
{
auto const tmpFilePath = filePath + ".tmp";
try

View File

@@ -33,8 +33,7 @@ vector<DataPoint> ReadDataPoints(string const & data)
try
{
coding::TrafficGPSEncoder::DeserializeDataPoints(coding::TrafficGPSEncoder::kLatestVersion, src,
points);
coding::TrafficGPSEncoder::DeserializeDataPoints(coding::TrafficGPSEncoder::kLatestVersion, src, points);
}
catch (Reader::SizeException const & e)
{
@@ -48,11 +47,12 @@ vector<DataPoint> ReadDataPoints(string const & data)
class PointToMwmId final
{
public:
PointToMwmId(shared_ptr<m4::Tree<routing::NumMwmId>> mwmTree,
routing::NumMwmIds const & numMwmIds, string const & dataDir)
PointToMwmId(shared_ptr<m4::Tree<routing::NumMwmId>> mwmTree, routing::NumMwmIds const & numMwmIds,
string const & dataDir)
: m_mwmTree(mwmTree)
{
numMwmIds.ForEachId([&](routing::NumMwmId numMwmId) {
numMwmIds.ForEachId([&](routing::NumMwmId numMwmId)
{
string const & mwmName = numMwmIds.GetFile(numMwmId).GetName();
string const polyFile = base::JoinPath(dataDir, BORDERS_DIR, mwmName + BORDERS_EXTENSION);
borders::LoadBorders(polyFile, m_borders[numMwmId]);
@@ -66,7 +66,8 @@ public:
routing::NumMwmId result = routing::kFakeNumMwmId;
m2::RectD const rect = mercator::RectByCenterXYAndSizeInMeters(point, 1);
m_mwmTree->ForEachInRect(rect, [&](routing::NumMwmId numMwmId) {
m_mwmTree->ForEachInRect(rect, [&](routing::NumMwmId numMwmId)
{
if (result == routing::kFakeNumMwmId && m2::RegionsContain(GetBorders(numMwmId), point))
result = numMwmId;
});
@@ -89,9 +90,11 @@ private:
namespace track_analyzing
{
LogParser::LogParser(shared_ptr<routing::NumMwmIds> numMwmIds,
unique_ptr<m4::Tree<routing::NumMwmId>> mwmTree, string const & dataDir)
: m_numMwmIds(std::move(numMwmIds)), m_mwmTree(std::move(mwmTree)), m_dataDir(dataDir)
LogParser::LogParser(shared_ptr<routing::NumMwmIds> numMwmIds, unique_ptr<m4::Tree<routing::NumMwmId>> mwmTree,
string const & dataDir)
: m_numMwmIds(std::move(numMwmIds))
, m_mwmTree(std::move(mwmTree))
, m_dataDir(dataDir)
{
CHECK(m_numMwmIds, ());
CHECK(m_mwmTree, ());
@@ -145,10 +148,9 @@ void LogParser::ParseUserTracks(string const & logFile, UserToTrack & userToTrac
pointsCount += packet.size();
};
LOG(LINFO, ("Tracks parsing finished, elapsed:", timer.ElapsedSeconds(), "seconds, lines:",
linesCount, ", points", pointsCount));
LOG(LINFO, ("Users with current version:", userToTrack.size(), ", old version:",
usersWithOldVersion.size()));
LOG(LINFO, ("Tracks parsing finished, elapsed:", timer.ElapsedSeconds(), "seconds, lines:", linesCount, ", points",
pointsCount));
LOG(LINFO, ("Users with current version:", userToTrack.size(), ", old version:", usersWithOldVersion.size()));
}
void LogParser::SplitIntoMwms(UserToTrack const & userToTrack, MwmToTracks & mwmToTracks) const
@@ -173,7 +175,6 @@ void LogParser::SplitIntoMwms(UserToTrack const & userToTrack, MwmToTracks & mwm
}
}
LOG(LINFO, ("Data was split into", mwmToTracks.size(), "mwms, elapsed:", timer.ElapsedSeconds(),
"seconds"));
LOG(LINFO, ("Data was split into", mwmToTracks.size(), "mwms, elapsed:", timer.ElapsedSeconds(), "seconds"));
}
} // namespace track_analyzing

View File

@@ -14,8 +14,8 @@ namespace track_analyzing
class LogParser final
{
public:
LogParser(std::shared_ptr<routing::NumMwmIds> numMwmIds,
std::unique_ptr<m4::Tree<routing::NumMwmId>> mwmTree, std::string const & dataDir);
LogParser(std::shared_ptr<routing::NumMwmIds> numMwmIds, std::unique_ptr<m4::Tree<routing::NumMwmId>> mwmTree,
std::string const & dataDir);
void Parse(std::string const & logFile, MwmToTracks & mwmToTracks) const;

View File

@@ -27,10 +27,7 @@ namespace track_analyzing
class MwmToMatchedTracksSerializer final
{
public:
MwmToMatchedTracksSerializer(std::shared_ptr<routing::NumMwmIds> numMwmIds)
: m_numMwmIds(std::move(numMwmIds))
{
}
MwmToMatchedTracksSerializer(std::shared_ptr<routing::NumMwmIds> numMwmIds) : m_numMwmIds(std::move(numMwmIds)) {}
template <typename Sink>
void Serialize(MwmToMatchedTracks const & mwmToMatchedTracks, Sink & sink)
@@ -68,8 +65,8 @@ public:
std::vector<uint8_t> buffer;
MemWriter<decltype(buffer)> memWriter(buffer);
coding::TrafficGPSEncoder::SerializeDataPoints(coding::TrafficGPSEncoder::kLatestVersion,
memWriter, dataPoints);
coding::TrafficGPSEncoder::SerializeDataPoints(coding::TrafficGPSEncoder::kLatestVersion, memWriter,
dataPoints);
WriteSize(sink, buffer.size());
sink.Write(buffer.data(), buffer.size());
@@ -123,8 +120,8 @@ public:
ReaderSource<MemReader> memSrc(memReader);
std::vector<DataPoint> dataPoints;
coding::TrafficGPSEncoder::DeserializeDataPoints(
coding::TrafficGPSEncoder::kLatestVersion, memSrc, dataPoints);
coding::TrafficGPSEncoder::DeserializeDataPoints(coding::TrafficGPSEncoder::kLatestVersion, memSrc,
dataPoints);
CHECK_EQUAL(numSegments, dataPoints.size(), ("mwm:", mwmName, "user:", user));
MatchedTrack & track = tracks[iTrack];

View File

@@ -10,8 +10,7 @@ TemporaryFile::TemporaryFile() : m_filePath(GetPlatform().TmpPathForFile()) {}
TemporaryFile::TemporaryFile(std::string const & namePrefix, std::string const & nameSuffix)
: m_filePath(GetPlatform().TmpPathForFile(namePrefix, nameSuffix))
{
}
{}
TemporaryFile::~TemporaryFile()
{

View File

@@ -13,10 +13,7 @@ public:
~TemporaryFile();
std::string const & GetFilePath() const
{
return m_filePath;
}
std::string const & GetFilePath() const { return m_filePath; }
void WriteData(std::string const & data);

View File

@@ -2,18 +2,15 @@
namespace track_analyzing
{
TrackFilter::TrackFilter(uint64_t minDuration, double minLength, double minSpeed, double maxSpeed,
bool ignoreTraffic)
TrackFilter::TrackFilter(uint64_t minDuration, double minLength, double minSpeed, double maxSpeed, bool ignoreTraffic)
: m_minDuration(minDuration)
, m_minLength(minLength)
, m_minSpeed(minSpeed)
, m_maxSpeed(maxSpeed)
, m_ignoreTraffic(ignoreTraffic)
{
}
{}
bool TrackFilter::Passes(uint64_t duration, double length, double speed,
bool hasTrafficPoints) const
bool TrackFilter::Passes(uint64_t duration, double length, double speed, bool hasTrafficPoints) const
{
if (duration < m_minDuration)
return false;

View File

@@ -21,9 +21,9 @@ class MatchedTrackPoint final
{
public:
MatchedTrackPoint(DataPoint const & dataPoint, routing::Segment const & segment)
: m_dataPoint(dataPoint), m_segment(segment)
{
}
: m_dataPoint(dataPoint)
, m_segment(segment)
{}
DataPoint const & GetDataPoint() const { return m_dataPoint; }
routing::Segment const & GetSegment() const { return m_segment; }
@@ -40,8 +40,7 @@ using MwmToMatchedTracks = std::unordered_map<routing::NumMwmId, UserToMatchedTr
class TrackFilter final
{
public:
TrackFilter(uint64_t minDuration, double minLength, double minSpeed, double maxSpeed,
bool ignoreTraffic);
TrackFilter(uint64_t minDuration, double minLength, double minSpeed, double maxSpeed, bool ignoreTraffic);
bool Passes(uint64_t duration, double length, double speed, bool hasTrafficPoints) const;

View File

@@ -26,11 +26,10 @@ namespace track_analyzing
{
using namespace std;
void FillTable(basic_istream<char> & tableCsvStream, MwmToDataPoints & matchedDataPoints,
vector<TableRow> & table)
void FillTable(basic_istream<char> & tableCsvStream, MwmToDataPoints & matchedDataPoints, vector<TableRow> & table)
{
for (auto const & row : coding::CSVRunner(
coding::CSVReader(tableCsvStream, true /* hasHeader */, ',' /* delimiter */)))
for (auto const & row :
coding::CSVRunner(coding::CSVReader(tableCsvStream, true /* hasHeader */, ',' /* delimiter */)))
{
CHECK_EQUAL(row.size(), kTableColumns, (row));
auto const & mwmName = row[kMwmNameCsvColumn];
@@ -39,13 +38,12 @@ void FillTable(basic_istream<char> & tableCsvStream, MwmToDataPoints & matchedDa
}
}
void RemoveKeysSmallValue(MwmToDataPoints & checkedMap, MwmToDataPoints & additionalMap,
uint64_t ignoreDataPointNumber)
void RemoveKeysSmallValue(MwmToDataPoints & checkedMap, MwmToDataPoints & additionalMap, uint64_t ignoreDataPointNumber)
{
CHECK(AreKeysEqual(additionalMap, checkedMap),
("Mwms in |checkedMap| and in |additionalMap| should have the same set of keys."));
for (auto it = checkedMap.begin() ; it != checkedMap.end();)
for (auto it = checkedMap.begin(); it != checkedMap.end();)
{
auto const dataPointNumberAfterMatching = it->second;
if (dataPointNumberAfterMatching > ignoreDataPointNumber)
@@ -72,14 +70,13 @@ MwmToDataPointFraction GetMwmToDataPointFraction(MwmToDataPoints const & numberM
return fractionMapping;
}
MwmToDataPoints CalcsMatchedDataPointsToKeepDistribution(
MwmToDataPoints const & matchedDataPoints, MwmToDataPointFraction const & distributionFractions)
MwmToDataPoints CalcsMatchedDataPointsToKeepDistribution(MwmToDataPoints const & matchedDataPoints,
MwmToDataPointFraction const & distributionFractions)
{
CHECK(!matchedDataPoints.empty(), ());
CHECK(AreKeysEqual(matchedDataPoints, distributionFractions),
("Mwms in |matchedDataPoints| and in |distributionFractions| should have the same set of keys."));
CHECK(AlmostEqualAbs(ValueSum(distributionFractions), 1.0, kSumFractionEps),
(ValueSum(distributionFractions)));
CHECK(AlmostEqualAbs(ValueSum(distributionFractions), 1.0, kSumFractionEps), (ValueSum(distributionFractions)));
auto const matchedFractions = GetMwmToDataPointFraction(matchedDataPoints);
@@ -137,17 +134,14 @@ MwmToDataPoints CalcsMatchedDataPointsToKeepDistribution(
if (matchedDataPointsToKeepDistributionForMwm == 0)
{
LOG(LWARNING, ("Zero points should be put to", mwm,
"to keep the distribution. Distribution fraction:", fraction,
"totalMatchedPointNumberToKeepDistribution:",
totalMatchedPointNumberToKeepDistribution));
LOG(LWARNING, ("Zero points should be put to", mwm, "to keep the distribution. Distribution fraction:", fraction,
"totalMatchedPointNumberToKeepDistribution:", totalMatchedPointNumberToKeepDistribution));
}
}
return matchedDataPointsToKeepDistribution;
}
MwmToDataPoints BalancedDataPointNumber(MwmToDataPoints && matchedDataPoints,
MwmToDataPoints && distribution,
MwmToDataPoints BalancedDataPointNumber(MwmToDataPoints && matchedDataPoints, MwmToDataPoints && distribution,
uint64_t ignoreDataPointsNumber)
{
// Removing every mwm from |distribution| and |matchedDataPoints| if it has
@@ -188,7 +182,7 @@ void FilterTable(MwmToDataPoints const & balancedDataPointNumbers, vector<TableR
auto it = balancedDataPointNumbers.find(mwmName);
if (it == balancedDataPointNumbers.end())
{
mwmRecordsIndices.resize(0); // No indices.
mwmRecordsIndices.resize(0); // No indices.
continue;
}
@@ -201,16 +195,13 @@ void FilterTable(MwmToDataPoints const & balancedDataPointNumbers, vector<TableR
// Refilling |table| with part of its items to corresponds |balancedDataPointNumbers| distribution.
vector<TableRow> balancedTable;
for (auto const & kv : tableIdx)
{
for (auto const idx : kv.second)
balancedTable.emplace_back(std::move(table[idx]));
}
table = std::move(balancedTable);
}
void BalanceDataPoints(basic_istream<char> & tableCsvStream,
basic_istream<char> & distributionCsvStream, uint64_t ignoreDataPointsNumber,
vector<TableRow> & balancedTable)
void BalanceDataPoints(basic_istream<char> & tableCsvStream, basic_istream<char> & distributionCsvStream,
uint64_t ignoreDataPointsNumber, vector<TableRow> & balancedTable)
{
LOG(LINFO, ("Balancing data points..."));
// Filling a map mwm to DataPoints number according to distribution csv file.
@@ -232,15 +223,14 @@ void BalanceDataPoints(basic_istream<char> & tableCsvStream,
// Removing every mwm from |distribution| if there is no such mwm in |matchedDataPoints|.
for (auto it = distribution.begin(); it != distribution.end();)
{
if (matchedDataPoints.count(it->first) == 0)
it = distribution.erase(it);
else
++it;
}
CHECK(AreKeysEqual(distribution, matchedDataPoints),
("Mwms in |distribution| and in |matchedDataPoints| should have the same set of keys.", distribution, matchedDataPoints));
("Mwms in |distribution| and in |matchedDataPoints| should have the same set of keys.", distribution,
matchedDataPoints));
// Calculating how many points should have every mwm to keep the |distribution|.
MwmToDataPoints const balancedDataPointNumber =
@@ -252,18 +242,15 @@ void BalanceDataPoints(basic_istream<char> & tableCsvStream,
// Removing some items form |tableCsvStream| (if it's necessary) to correspond to
// the distribution.
FilterTable(balancedDataPointNumber, balancedTable);
LOG(LINFO, ("Data points have balanced. Total distribution data points number:",
totalDistributionDataPointsNumber,
LOG(LINFO, ("Data points have balanced. Total distribution data points number:", totalDistributionDataPointsNumber,
"Total matched data points number:", totalMatchedDataPointsNumber,
"Total balanced data points number:", totalBalancedDataPointsNumber));
}
void CmdBalanceCsv(string const & csvPath, string const & distributionPath,
uint64_t ignoreDataPointsNumber)
void CmdBalanceCsv(string const & csvPath, string const & distributionPath, uint64_t ignoreDataPointsNumber)
{
LOG(LINFO, ("Balancing csv file", csvPath, "with distribution set in", distributionPath,
". If an mwm has", ignoreDataPointsNumber,
"data points or less it will not be considered."));
LOG(LINFO, ("Balancing csv file", csvPath, "with distribution set in", distributionPath, ". If an mwm has",
ignoreDataPointsNumber, "data points or less it will not be considered."));
ifstream table(csvPath);
CHECK(table.is_open(), ("Cannot open", csvPath));
ifstream distribution(distributionPath);

View File

@@ -32,17 +32,17 @@ typename MapCont::mapped_type ValueSum(MapCont const & mapCont)
}
/// \returns true if |map1| and |map2| have the same key and false otherwise.
template<typename Map1, typename Map2>
template <typename Map1, typename Map2>
bool AreKeysEqual(Map1 const & map1, Map2 const & map2)
{
if (map1.size() != map2.size())
{
LOG(LINFO,
("AreKeysEqual() returns false. map1.size():", map1.size(), "map2.size()", map2.size()));
LOG(LINFO, ("AreKeysEqual() returns false. map1.size():", map1.size(), "map2.size()", map2.size()));
return false;
}
return std::equal(map1.begin(), map1.end(), map2.begin(), [](auto const & kv1, auto const & kv2) {
return std::equal(map1.begin(), map1.end(), map2.begin(), [](auto const & kv1, auto const & kv2)
{
if (kv1.first == kv2.first)
return true;
@@ -68,13 +68,11 @@ MwmToDataPointFraction GetMwmToDataPointFraction(MwmToDataPoints const & numberM
/// * number of data points in the returned mapping is less than or equal to
/// number of data points in |matchedDataPoints| for every mwm
/// * distribution defined by |distributionFraction| is kept
MwmToDataPoints CalcsMatchedDataPointsToKeepDistribution(
MwmToDataPoints const & matchedDataPoints,
MwmToDataPointFraction const & distributionFractions);
MwmToDataPoints CalcsMatchedDataPointsToKeepDistribution(MwmToDataPoints const & matchedDataPoints,
MwmToDataPointFraction const & distributionFractions);
/// \returns mapping with number of matched data points for every mwm to correspond to |distribution|.
MwmToDataPoints BalancedDataPointNumber(MwmToDataPoints && matchedDataPoints,
MwmToDataPoints && distribution,
MwmToDataPoints BalancedDataPointNumber(MwmToDataPoints && matchedDataPoints, MwmToDataPoints && distribution,
uint64_t ignoreDataPointsNumber);
/// \breif Leaves in |table| only number of items according to |balancedDataPointNumbers|.
@@ -83,13 +81,11 @@ void FilterTable(MwmToDataPoints const & balancedDataPointNumbers, std::vector<T
/// \brief Fills |balancedTable| with TableRow(s) according to the distribution set in
/// |distributionCsvStream|.
void BalanceDataPoints(std::basic_istream<char> & tableCsvStream,
std::basic_istream<char> & distributionCsvStream,
void BalanceDataPoints(std::basic_istream<char> & tableCsvStream, std::basic_istream<char> & distributionCsvStream,
uint64_t ignoreDataPointsNumber, std::vector<TableRow> & balancedTable);
/// \brief Removes some data point for every mwm from |csvPath| to correspond distribution
/// set in |distributionPath|. If an mwm in |csvPath| contains data points less of equal to
/// |ignoreDataPointsNumber| than the mwm will not be taken into acount while balancing.
void CmdBalanceCsv(std::string const & csvPath, std::string const & distributionPath,
uint64_t ignoreDataPointsNumber);
void CmdBalanceCsv(std::string const & csvPath, std::string const & distributionPath, uint64_t ignoreDataPointsNumber);
} // namespace track_analyzing

View File

@@ -9,24 +9,19 @@ using namespace std;
namespace track_analyzing
{
void CmdCppTrack(string const & trackFile, string const & mwmName, string const & user,
size_t trackIdx)
void CmdCppTrack(string const & trackFile, string const & mwmName, string const & user, size_t trackIdx)
{
storage::Storage storage;
auto const numMwmIds = CreateNumMwmIds(storage);
MwmToMatchedTracks mwmToMatchedTracks;
ReadTracks(numMwmIds, trackFile, mwmToMatchedTracks);
MatchedTrack const & track =
GetMatchedTrack(mwmToMatchedTracks, *numMwmIds, mwmName, user, trackIdx);
MatchedTrack const & track = GetMatchedTrack(mwmToMatchedTracks, *numMwmIds, mwmName, user, trackIdx);
auto const backupPrecision = cout.precision();
cout.precision(8);
for (MatchedTrackPoint const & point : track)
{
cout << " {" << point.GetDataPoint().m_latLon.m_lat << ", " << point.GetDataPoint().m_latLon.m_lon
<< "}," << endl;
}
cout << " {" << point.GetDataPoint().m_latLon.m_lat << ", " << point.GetDataPoint().m_latLon.m_lon << "}," << endl;
cout.precision(backupPrecision);
}
} // namespace track_analyzing

View File

@@ -48,10 +48,7 @@ void CmdGPX(string const & logFile, string const & outputDirName, string const &
ofs << "</metadata>\n";
for (auto const & point : track.second)
{
ofs << "<wpt lat=\""
<< point.m_latLon.m_lat
<< "\" lon=\""
<< point.m_latLon.m_lon << "\">"
ofs << "<wpt lat=\"" << point.m_latLon.m_lat << "\" lon=\"" << point.m_latLon.m_lon << "\">"
<< "</wpt>\n";
}

View File

@@ -37,8 +37,8 @@ namespace
{
using Iter = typename vector<string>::iterator;
void MatchTracks(MwmToTracks const & mwmToTracks, storage::Storage const & storage,
NumMwmIds const & numMwmIds, MwmToMatchedTracks & mwmToMatchedTracks)
void MatchTracks(MwmToTracks const & mwmToTracks, storage::Storage const & storage, NumMwmIds const & numMwmIds,
MwmToMatchedTracks & mwmToMatchedTracks)
{
base::Timer timer;
@@ -46,7 +46,8 @@ void MatchTracks(MwmToTracks const & mwmToTracks, storage::Storage const & stora
uint64_t pointsCount = 0;
uint64_t nonMatchedPointsCount = 0;
auto processMwm = [&](string const & mwmName, UserToTrack const & userToTrack) {
auto processMwm = [&](string const & mwmName, UserToTrack const & userToTrack)
{
auto const countryFile = platform::CountryFile(mwmName);
auto const mwmId = numMwmIds.GetId(countryFile);
TrackMatcher matcher(storage, mwmId, countryFile);
@@ -78,23 +79,22 @@ void MatchTracks(MwmToTracks const & mwmToTracks, storage::Storage const & stora
pointsCount += matcher.GetPointsCount();
nonMatchedPointsCount += matcher.GetNonMatchedPointsCount();
LOG(LINFO, (numMwmIds.GetFile(mwmId).GetName(), ", users:", userToTrack.size(), ", tracks:",
matcher.GetTracksCount(), ", points:", matcher.GetPointsCount(),
", non matched points:", matcher.GetNonMatchedPointsCount()));
LOG(LINFO,
(numMwmIds.GetFile(mwmId).GetName(), ", users:", userToTrack.size(), ", tracks:", matcher.GetTracksCount(),
", points:", matcher.GetPointsCount(), ", non matched points:", matcher.GetNonMatchedPointsCount()));
};
ForTracksSortedByMwmName(mwmToTracks, numMwmIds, processMwm);
LOG(LINFO,
("Matching finished, elapsed:", timer.ElapsedSeconds(), "seconds, tracks:", tracksCount,
", points:", pointsCount, ", non matched points:", nonMatchedPointsCount));
LOG(LINFO, ("Matching finished, elapsed:", timer.ElapsedSeconds(), "seconds, tracks:", tracksCount,
", points:", pointsCount, ", non matched points:", nonMatchedPointsCount));
}
} // namespace
namespace track_analyzing
{
void CmdMatch(string const & logFile, string const & trackFile,
shared_ptr<NumMwmIds> const & numMwmIds, Storage const & storage, Stats & stats)
void CmdMatch(string const & logFile, string const & trackFile, shared_ptr<NumMwmIds> const & numMwmIds,
Storage const & storage, Stats & stats)
{
MwmToTracks mwmToTracks;
ParseTracks(logFile, numMwmIds, mwmToTracks);
@@ -165,8 +165,7 @@ void UnzipAndMatch(Iter begin, Iter end, string const & trackExt, Stats & stats)
void CmdMatchDir(string const & logDir, string const & trackExt, string const & inputDistribution)
{
LOG(LINFO,
("Matching dir:", logDir, ". Input distribution will be saved to:", inputDistribution));
LOG(LINFO, ("Matching dir:", logDir, ". Input distribution will be saved to:", inputDistribution));
Platform::EFileType fileType = Platform::EFileType::Unknown;
Platform::EError const result = Platform::GetFileType(logDir, fileType);

View File

@@ -69,11 +69,9 @@ bool DayTimeToBool(DayTimeType type)
switch (type)
{
case DayTimeType::Day:
case DayTimeType::PolarDay:
return true;
case DayTimeType::PolarDay: return true;
case DayTimeType::Night:
case DayTimeType::PolarNight:
return false;
case DayTimeType::PolarNight: return false;
}
UNREACHABLE();
@@ -100,15 +98,9 @@ public:
return tie(m_hwType, m_surfaceType) < tie(rhs.m_hwType, rhs.m_surfaceType);
}
bool operator==(Type const & rhs) const
{
return tie(m_hwType, m_surfaceType) == tie(rhs.m_hwType, m_surfaceType);
}
bool operator==(Type const & rhs) const { return tie(m_hwType, m_surfaceType) == tie(rhs.m_hwType, m_surfaceType); }
bool operator!=(Type const & rhs) const
{
return !(*this == rhs);
}
bool operator!=(Type const & rhs) const { return !(*this == rhs); }
string GetSummary() const
{
@@ -158,10 +150,7 @@ struct RoadInfo
tie(rhs.m_type, rhs.m_maxspeedKMpH, rhs.m_isCityRoad, rhs.m_isOneWay);
}
bool operator!=(RoadInfo const & rhs) const
{
return !(*this == rhs);
}
bool operator!=(RoadInfo const & rhs) const { return !(*this == rhs); }
bool operator<(RoadInfo const & rhs) const
{
@@ -172,11 +161,8 @@ struct RoadInfo
string GetSummary() const
{
ostringstream out;
out << TypeToString(m_type.m_hwType) << ","
<< TypeToString(m_type.m_surfaceType) << ","
<< m_maxspeedKMpH << ","
<< m_isCityRoad << ","
<< m_isOneWay;
out << TypeToString(m_type.m_hwType) << "," << TypeToString(m_type.m_surfaceType) << "," << m_maxspeedKMpH << ","
<< m_isCityRoad << "," << m_isOneWay;
return out.str();
}
@@ -193,7 +179,9 @@ public:
MoveType() = default;
MoveType(RoadInfo const & roadType, traffic::SpeedGroup speedGroup, DataPoint const & dataPoint)
: m_roadInfo(roadType), m_speedGroup(speedGroup), m_latLon(dataPoint.m_latLon)
: m_roadInfo(roadType)
, m_speedGroup(speedGroup)
, m_latLon(dataPoint.m_latLon)
{
m_isDayTime = DayTimeToBool(GetDayTime(dataPoint.m_timestamp, m_latLon.m_lat, m_latLon.m_lon));
}
@@ -213,17 +201,14 @@ public:
bool IsValid() const
{
// In order to collect cleaner data we don't use speed group lower than G5.
return m_roadInfo.m_type.m_hwType != 0 &&
m_roadInfo.m_type.m_surfaceType != 0 &&
return m_roadInfo.m_type.m_hwType != 0 && m_roadInfo.m_type.m_surfaceType != 0 &&
m_speedGroup == kValidTrafficValue;
}
string GetSummary() const
{
ostringstream out;
out << m_roadInfo.GetSummary() << ","
<< m_isDayTime << ","
<< m_latLon.m_lat << " " << m_latLon.m_lon;
out << m_roadInfo.GetSummary() << "," << m_isDayTime << "," << m_latLon.m_lat << " " << m_latLon.m_lon;
return out.str();
}
@@ -250,9 +235,7 @@ public:
string GetSummary() const
{
ostringstream out;
out << m_totalDistance << ","
<< m_totalTime << ","
<< CalcSpeedKMpH(m_totalDistance, m_totalTime) << ",";
out << m_totalDistance << "," << m_totalTime << "," << CalcSpeedKMpH(m_totalDistance, m_totalTime) << ",";
for (size_t i = 0; i < m_crossroads.size(); ++i)
{
@@ -276,8 +259,8 @@ private:
class MoveTypeAggregator final
{
public:
void Add(MoveType && moveType, IsCrossroadChecker::CrossroadInfo const & crossroads, MatchedTrack::const_iterator begin,
MatchedTrack::const_iterator end, Geometry & geometry)
void Add(MoveType && moveType, IsCrossroadChecker::CrossroadInfo const & crossroads,
MatchedTrack::const_iterator begin, MatchedTrack::const_iterator end, Geometry & geometry)
{
if (begin + 1 >= end)
return;
@@ -288,9 +271,9 @@ public:
if (time == 0)
{
LOG(LWARNING, ("Track with the same time at the beginning and at the end. Beginning:",
beginDataPoint.m_latLon, " End:", endDataPoint.m_latLon,
" Timestamp:", beginDataPoint.m_timestamp, " Segment:", begin->GetSegment()));
LOG(LWARNING, ("Track with the same time at the beginning and at the end. Beginning:", beginDataPoint.m_latLon,
" End:", endDataPoint.m_latLon, " Timestamp:", beginDataPoint.m_timestamp,
" Segment:", begin->GetSegment()));
return;
}
@@ -298,8 +281,7 @@ public:
m_moveInfos[moveType].Add(length, time, crossroads, static_cast<uint32_t>(distance(begin, end)));
}
string GetSummary(string const & user, string const & mwmName, string const & countryName,
Stats & stats) const
string GetSummary(string const & user, string const & mwmName, string const & countryName, Stats & stats) const
{
ostringstream out;
for (auto const & it : m_moveInfos)
@@ -307,8 +289,7 @@ public:
if (!it.first.IsValid())
continue;
out << user << "," << mwmName << "," << it.first.GetSummary() << ","
<< it.second.GetSummary() << '\n';
out << user << "," << mwmName << "," << it.first.GetSummary() << "," << it.second.GetSummary() << '\n';
stats.AddDataPoints(mwmName, countryName, it.second.GetDataPointsNumber());
}
@@ -324,7 +305,8 @@ class MatchedTrackPointToMoveType final
{
public:
MatchedTrackPointToMoveType(FilesContainerR const & container, VehicleModelInterface & vehicleModel)
: m_featuresVector(container), m_vehicleModel(vehicleModel)
: m_featuresVector(container)
, m_vehicleModel(vehicleModel)
{
if (container.IsExist(CITY_ROADS_FILE_TAG))
m_cityRoads.Load(container.GetReader(CITY_ROADS_FILE_TAG));
@@ -336,9 +318,7 @@ public:
MoveType GetMoveType(MatchedTrackPoint const & point)
{
auto const & dataPoint = point.GetDataPoint();
return MoveType(GetRoadInfo(point.GetSegment()),
static_cast<traffic::SpeedGroup>(dataPoint.m_traffic),
dataPoint);
return MoveType(GetRoadInfo(point.GetSegment()), static_cast<traffic::SpeedGroup>(dataPoint.m_traffic), dataPoint);
}
private:
@@ -352,15 +332,14 @@ private:
CHECK(feature, ());
auto const maxspeed = m_maxspeeds.GetMaxspeed(featureId);
auto const maxspeedValueKMpH = maxspeed.IsValid() ?
min(maxspeed.GetSpeedKmPH(segment.IsForward()), kMaxspeedTopBound) :
kInvalidSpeed;
auto const maxspeedValueKMpH =
maxspeed.IsValid() ? min(maxspeed.GetSpeedKmPH(segment.IsForward()), kMaxspeedTopBound) : kInvalidSpeed;
m_prevFeatureId = featureId;
feature::TypesHolder const types(*feature);
m_prevRoadInfo = {m_carModelTypes.GetType(types), maxspeedValueKMpH,
m_cityRoads.IsCityRoad(featureId), m_vehicleModel.IsOneWay(types)};
m_prevRoadInfo = {m_carModelTypes.GetType(types), maxspeedValueKMpH, m_cityRoads.IsCityRoad(featureId),
m_vehicleModel.IsOneWay(types)};
return m_prevRoadInfo;
}
@@ -374,7 +353,6 @@ private:
};
} // namespace
void CmdTagsTable(string const & filepath, string const & trackExtension, StringFilter mwmFilter,
StringFilter userFilter)
{
@@ -393,18 +371,17 @@ void CmdTagsTable(string const & filepath, string const & trackExtension, String
auto const countryName = storage.GetTopmostParentFor(mwmName);
auto const carModelFactory = make_shared<CarModelFactory>(VehicleModelFactory::CountryParentNameGetterFn{});
shared_ptr<VehicleModelInterface> vehicleModel =
carModelFactory->GetVehicleModelForCountry(mwmName);
shared_ptr<VehicleModelInterface> vehicleModel = carModelFactory->GetVehicleModelForCountry(mwmName);
string const mwmFile = GetCurrentVersionMwmFile(storage, mwmName);
MatchedTrackPointToMoveType pointToMoveType(FilesContainerR(make_unique<FileReader>(mwmFile)), *vehicleModel);
Geometry geometry(GeometryLoader::CreateFromFile(mwmFile, vehicleModel));
auto const vehicleType = VehicleType::Car;
auto const edgeEstimator = EdgeEstimator::Create(vehicleType, *vehicleModel,
nullptr /* trafficStash */, &dataSource, numMwmIds);
auto const edgeEstimator =
EdgeEstimator::Create(vehicleType, *vehicleModel, nullptr /* trafficStash */, &dataSource, numMwmIds);
MwmDataSource routingSource(dataSource, numMwmIds);
auto indexGraphLoader = IndexGraphLoader::Create(vehicleType, false /* loadAltitudes */,
carModelFactory, edgeEstimator, routingSource);
auto indexGraphLoader =
IndexGraphLoader::Create(vehicleType, false /* loadAltitudes */, carModelFactory, edgeEstimator, routingSource);
platform::CountryFile const countryFile(mwmName);
auto localCountryFile = storage.GetLatestLocalFile(countryFile);
@@ -412,8 +389,7 @@ void CmdTagsTable(string const & filepath, string const & trackExtension, String
if (!dataSource.IsLoaded(countryFile))
{
auto registerResult = dataSource.Register(*localCountryFile);
CHECK_EQUAL(registerResult.second, MwmSet::RegResult::Success,
("Can't register mwm", countryFile.GetName()));
CHECK_EQUAL(registerResult.second, MwmSet::RegResult::Success, ("Can't register mwm", countryFile.GetName()));
}
auto const mwmId = numMwmIds->GetId(countryFile);
@@ -440,18 +416,14 @@ void CmdTagsTable(string const & filepath, string const & trackExtension, String
// Splitting track with points where MoveType is changed.
while (end != track.end() && pointToMoveType.GetMoveType(*end) == moveType)
{
IsCrossroadChecker::MergeCrossroads(checker(prev->GetSegment(), end->GetSegment()),
info);
IsCrossroadChecker::MergeCrossroads(checker(prev->GetSegment(), end->GetSegment()), info);
prev = end;
++end;
}
// If it's not the end of the track than it could be a crossroad.
if (end != track.end())
{
IsCrossroadChecker::MergeCrossroads(checker(prev->GetSegment(), end->GetSegment()),
info);
}
IsCrossroadChecker::MergeCrossroads(checker(prev->GetSegment(), end->GetSegment()), info);
aggregator.Add(std::move(moveType), info, subtrackBegin, end, geometry);
subtrackBegin = end;

View File

@@ -23,28 +23,24 @@ using namespace std;
namespace track_analyzing
{
void CmdTrack(string const & trackFile, string const & mwmName, string const & user,
size_t trackIdx)
void CmdTrack(string const & trackFile, string const & mwmName, string const & user, size_t trackIdx)
{
storage::Storage storage;
auto const numMwmIds = CreateNumMwmIds(storage);
MwmToMatchedTracks mwmToMatchedTracks;
ReadTracks(numMwmIds, trackFile, mwmToMatchedTracks);
MatchedTrack const & track =
GetMatchedTrack(mwmToMatchedTracks, *numMwmIds, mwmName, user, trackIdx);
MatchedTrack const & track = GetMatchedTrack(mwmToMatchedTracks, *numMwmIds, mwmName, user, trackIdx);
string const mwmFile = GetCurrentVersionMwmFile(storage, mwmName);
shared_ptr<VehicleModelInterface> vehicleModel =
CarModelFactory({}).GetVehicleModelForCountry(mwmName);
shared_ptr<VehicleModelInterface> vehicleModel = CarModelFactory({}).GetVehicleModelForCountry(mwmName);
Geometry geometry(GeometryLoader::CreateFromFile(mwmFile, vehicleModel));
uint64_t const duration =
track.back().GetDataPoint().m_timestamp - track.front().GetDataPoint().m_timestamp;
uint64_t const duration = track.back().GetDataPoint().m_timestamp - track.front().GetDataPoint().m_timestamp;
double const length = CalcTrackLength(track, geometry);
double const averageSpeed = CalcSpeedKMpH(length, duration);
LOG(LINFO, ("Mwm:", mwmName, ", user:", user, ", points:", track.size(), "duration:", duration,
"length:", length, ", speed:", averageSpeed, "km/h"));
LOG(LINFO, ("Mwm:", mwmName, ", user:", user, ", points:", track.size(), "duration:", duration, "length:", length,
", speed:", averageSpeed, "km/h"));
for (size_t i = 0; i < track.size(); ++i)
{
@@ -64,10 +60,9 @@ void CmdTrack(string const & trackFile, string const & mwmName, string const & u
if (elapsed != 0)
speed = CalcSpeedKMpH(distance, elapsed);
LOG(LINFO, (base::SecondsSinceEpochToString(point.GetDataPoint().m_timestamp),
point.GetDataPoint().m_latLon, point.GetSegment(), ", traffic:",
point.GetDataPoint().m_traffic, ", distance:", distance, ", elapsed:", elapsed,
", speed:", speed));
LOG(LINFO, (base::SecondsSinceEpochToString(point.GetDataPoint().m_timestamp), point.GetDataPoint().m_latLon,
point.GetSegment(), ", traffic:", point.GetDataPoint().m_traffic, ", distance:", distance,
", elapsed:", elapsed, ", speed:", speed));
}
}
} // namespace track_analyzing

View File

@@ -22,7 +22,6 @@
#include <iostream>
#include <sstream>
namespace track_analyzing
{
using namespace routing;
@@ -105,8 +104,7 @@ bool TrackHasTrafficPoints(MatchedTrack const & track)
return false;
}
double EstimateDuration(MatchedTrack const & track, shared_ptr<EdgeEstimator> estimator,
Geometry & geometry)
double EstimateDuration(MatchedTrack const & track, shared_ptr<EdgeEstimator> estimator, Geometry & geometry)
{
double result = 0.0;
Segment segment;
@@ -117,16 +115,15 @@ double EstimateDuration(MatchedTrack const & track, shared_ptr<EdgeEstimator> es
continue;
segment = point.GetSegment();
result += estimator->CalcSegmentWeight(segment, geometry.GetRoad(segment.GetFeatureId()),
EdgeEstimator::Purpose::ETA);
result +=
estimator->CalcSegmentWeight(segment, geometry.GetRoad(segment.GetFeatureId()), EdgeEstimator::Purpose::ETA);
}
return result;
}
void CmdTracks(string const & filepath, string const & trackExtension, StringFilter mwmFilter,
StringFilter userFilter, TrackFilter const & filter, bool noTrackLogs,
bool noMwmLogs, bool noWorldLogs)
void CmdTracks(string const & filepath, string const & trackExtension, StringFilter mwmFilter, StringFilter userFilter,
TrackFilter const & filter, bool noTrackLogs, bool noMwmLogs, bool noWorldLogs)
{
storage::Storage storage;
auto numMwmIds = CreateNumMwmIds(storage);
@@ -135,21 +132,19 @@ void CmdTracks(string const & filepath, string const & trackExtension, StringFil
ErrorStat absoluteError;
ErrorStat relativeError;
auto processMwm = [&](string const & mwmName, UserToMatchedTracks const & userToMatchedTracks) {
auto processMwm = [&](string const & mwmName, UserToMatchedTracks const & userToMatchedTracks)
{
if (mwmFilter(mwmName))
return;
TrackStats & mwmStats = mwmToStats[mwmName];
shared_ptr<VehicleModelInterface> vehicleModel =
CarModelFactory({}).GetVehicleModelForCountry(mwmName);
shared_ptr<VehicleModelInterface> vehicleModel = CarModelFactory({}).GetVehicleModelForCountry(mwmName);
Geometry geometry(
GeometryLoader::CreateFromFile(GetCurrentVersionMwmFile(storage, mwmName), vehicleModel));
Geometry geometry(GeometryLoader::CreateFromFile(GetCurrentVersionMwmFile(storage, mwmName), vehicleModel));
shared_ptr<EdgeEstimator> estimator =
EdgeEstimator::Create(VehicleType::Car, *vehicleModel,
nullptr /* trafficStash */, nullptr /* dataSource */, nullptr /* numMwmIds */);
shared_ptr<EdgeEstimator> estimator = EdgeEstimator::Create(
VehicleType::Car, *vehicleModel, nullptr /* trafficStash */, nullptr /* dataSource */, nullptr /* numMwmIds */);
for (auto const & it : userToMatchedTracks)
{
@@ -181,13 +176,13 @@ void CmdTracks(string const & filepath, string const & trackExtension, StringFil
if (!noTrackLogs)
{
cout << fixed << setprecision(1) << " points: " << track.size() << ", length: " << length
<< ", duration: " << duration << ", estimated duration: " << estimatedDuration
<< ", speed: " << speed << ", traffic: " << hasTrafficPoints
<< ", duration: " << duration << ", estimated duration: " << estimatedDuration << ", speed: " << speed
<< ", traffic: " << hasTrafficPoints
<< ", departure: " << base::SecondsSinceEpochToString(start.m_timestamp)
<< ", arrival: " << base::SecondsSinceEpochToString(finish.m_timestamp)
<< setprecision(numeric_limits<double>::max_digits10)
<< ", start: " << start.m_latLon.m_lat << ", " << start.m_latLon.m_lon
<< ", finish: " << finish.m_latLon.m_lat << ", " << finish.m_latLon.m_lon << endl;
<< setprecision(numeric_limits<double>::max_digits10) << ", start: " << start.m_latLon.m_lat << ", "
<< start.m_latLon.m_lon << ", finish: " << finish.m_latLon.m_lat << ", " << finish.m_latLon.m_lon
<< endl;
}
mwmStats.AddTracks(1);
@@ -202,7 +197,8 @@ void CmdTracks(string const & filepath, string const & trackExtension, StringFil
}
};
auto processFile = [&](string const & filename, MwmToMatchedTracks const & mwmToMatchedTracks) {
auto processFile = [&](string const & filename, MwmToMatchedTracks const & mwmToMatchedTracks)
{
LOG(LINFO, ("Processing", filename));
ForTracksSortedByMwmName(mwmToMatchedTracks, *numMwmIds, processMwm);
};
@@ -213,10 +209,8 @@ void CmdTracks(string const & filepath, string const & trackExtension, StringFil
{
cout << endl;
for (auto const & it : mwmToStats)
{
if (!it.second.IsEmpty())
cout << it.first << ": " << it.second.GetSummary() << endl;
}
}
if (!noWorldLogs)
@@ -226,11 +220,9 @@ void CmdTracks(string const & filepath, string const & trackExtension, StringFil
worldStats.Add(it.second);
cout << endl << "World: " << worldStats.GetSummary() << endl;
cout << fixed << setprecision(1)
<< "Absolute error: deviation: " << absoluteError.GetStdDevString()
cout << fixed << setprecision(1) << "Absolute error: deviation: " << absoluteError.GetStdDevString()
<< ", min: " << absoluteError.GetMin() << ", max: " << absoluteError.GetMax() << endl;
cout << fixed << setprecision(3)
<< "Relative error: deviation: " << relativeError.GetStdDevString()
cout << fixed << setprecision(3) << "Relative error: deviation: " << relativeError.GetStdDevString()
<< ", min: " << relativeError.GetMin() << ", max: " << relativeError.GetMax() << endl;
}
}

View File

@@ -23,10 +23,8 @@ bool IsHighwayLink(HighwayType type)
case HighwayType::HighwayTrunkLink:
case HighwayType::HighwayPrimaryLink:
case HighwayType::HighwaySecondaryLink:
case HighwayType::HighwayTertiaryLink:
return true;
default:
return false;
case HighwayType::HighwayTertiaryLink: return true;
default: return false;
}
UNREACHABLE();
@@ -40,10 +38,8 @@ bool IsBigHighway(HighwayType type)
case HighwayType::HighwayTrunk:
case HighwayType::HighwayPrimary:
case HighwayType::HighwaySecondary:
case HighwayType::HighwayTertiary:
return true;
default:
return false;
case HighwayType::HighwayTertiary: return true;
default: return false;
}
UNREACHABLE();
@@ -54,12 +50,8 @@ bool FromSmallerToBigger(HighwayType lhs, HighwayType rhs)
CHECK_NOT_EQUAL(lhs, rhs, ());
static std::array<HighwayType, 5> constexpr kHighwayTypes = {
HighwayType::HighwayTertiary,
HighwayType::HighwaySecondary,
HighwayType::HighwayPrimary,
HighwayType::HighwayTrunk,
HighwayType::HighwayMotorway
};
HighwayType::HighwayTertiary, HighwayType::HighwaySecondary, HighwayType::HighwayPrimary,
HighwayType::HighwayTrunk, HighwayType::HighwayMotorway};
auto const lhsIt = find(kHighwayTypes.begin(), kHighwayTypes.end(), lhs);
auto const rhsIt = find(kHighwayTypes.begin(), kHighwayTypes.end(), rhs);
@@ -112,7 +104,8 @@ IsCrossroadChecker::Type IsCrossroadChecker::operator()(Segment const & current,
Type retType = Type::Count;
auto const nextRoadPoint = next.GetRoadPoint(false /* isFront */);
m_indexGraph.ForEachPoint(jointId, [&](RoadPoint const & point) {
m_indexGraph.ForEachPoint(jointId, [&](RoadPoint const & point)
{
if (retType != IsCrossroadChecker::Type::Count)
return;
@@ -129,11 +122,8 @@ IsCrossroadChecker::Type IsCrossroadChecker::operator()(Segment const & current,
if (pointHwType == nextSegmentHwType)
{
// Is the same road but parted on different features.
if (roadGeometry.IsEndPointId(point.GetPointId()) &&
roadGeometry.IsEndPointId(nextRoadPoint.GetPointId()))
{
if (roadGeometry.IsEndPointId(point.GetPointId()) && roadGeometry.IsEndPointId(nextRoadPoint.GetPointId()))
return;
}
}
if (isCurrentLink && IsBigHighway(*pointHwType))

View File

@@ -30,8 +30,7 @@ public:
Type operator()(Segment const & current, Segment const & next) const;
static void MergeCrossroads(Type from, CrossroadInfo & to);
static void MergeCrossroads(IsCrossroadChecker::CrossroadInfo const & from,
IsCrossroadChecker::CrossroadInfo & to);
static void MergeCrossroads(IsCrossroadChecker::CrossroadInfo const & from, IsCrossroadChecker::CrossroadInfo & to);
private:
IndexGraph & m_indexGraph;

View File

@@ -51,19 +51,17 @@ DEFINE_string_ext(output_dir, "", "output dir for gpx files");
DEFINE_string_ext(mwm, "", "short mwm name");
DEFINE_string_ext(user, "", "user id");
DEFINE_int32(track, -1, "track index");
DEFINE_string(
input_distribution, "",
"path to input data point distribution file. It's a csv file with data point count for "
"some mwms. Usage:\n"
"- It may be used with match and match_dir command. If so it's a path to save file with "
"data point distribution by mwm. If it's empty no file is saved.\n"
"- It may be used with balance_csv command. If so it's a path of a file with distribution which "
"will be used for normalization (balancing) the result of the command. It should not be empty.");
DEFINE_uint64(
ignore_datapoints_number, 100,
"The number of datapoints in an mwm to exclude the mwm from balancing process. If this number "
"of datapoints or less number is in an mwm after matching and tabling, the mwm will not used "
"for balancing. This param should be used with balance_csv command.");
DEFINE_string(input_distribution, "",
"path to input data point distribution file. It's a csv file with data point count for "
"some mwms. Usage:\n"
"- It may be used with match and match_dir command. If so it's a path to save file with "
"data point distribution by mwm. If it's empty no file is saved.\n"
"- It may be used with balance_csv command. If so it's a path of a file with distribution which "
"will be used for normalization (balancing) the result of the command. It should not be empty.");
DEFINE_uint64(ignore_datapoints_number, 100,
"The number of datapoints in an mwm to exclude the mwm from balancing process. If this number "
"of datapoints or less number is in an mwm after matching and tabling, the mwm will not used "
"for balancing. This param should be used with balance_csv command.");
DEFINE_string(track_extension, ".track", "track files extension");
DEFINE_bool(no_world_logs, false, "don't print world summary logs");
@@ -86,7 +84,8 @@ size_t Checked_track()
StringFilter MakeFilter(string const & filter)
{
return [&](string const & value) {
return [&](string const & value)
{
if (filter.empty())
return false;
return value != filter;
@@ -97,8 +96,7 @@ StringFilter MakeFilter(string const & filter)
namespace track_analyzing
{
// Print the specified track in C++ form that you can copy paste to C++ source for debugging.
void CmdCppTrack(string const & trackFile, string const & mwmName, string const & user,
size_t trackIdx);
void CmdCppTrack(string const & trackFile, string const & mwmName, string const & user, size_t trackIdx);
// Match raw gps logs to tracks.
void CmdMatch(string const & logFile, string const & trackFile, string const & inputDistribution);
// The same as match but applies for the directory with raw logs.
@@ -106,15 +104,13 @@ void CmdMatchDir(string const & logDir, string const & trackExt, string const &
// Parse |logFile| and save tracks (mwm name, aloha id, lats, lons, timestamps in seconds in csv).
void CmdUnmatchedTracks(string const & logFile, string const & trackFileCsv);
// Print aggregated tracks to csv table.
void CmdTagsTable(string const & filepath, string const & trackExtension,
StringFilter mwmIsFiltered, StringFilter userFilter);
void CmdTagsTable(string const & filepath, string const & trackExtension, StringFilter mwmIsFiltered,
StringFilter userFilter);
// Print track information.
void CmdTrack(string const & trackFile, string const & mwmName, string const & user,
size_t trackIdx);
void CmdTrack(string const & trackFile, string const & mwmName, string const & user, size_t trackIdx);
// Print tracks statistics.
void CmdTracks(string const & filepath, string const & trackExtension, StringFilter mwmFilter,
StringFilter userFilter, TrackFilter const & filter, bool noTrackLogs,
bool noMwmLogs, bool noWorldLogs);
void CmdTracks(string const & filepath, string const & trackExtension, StringFilter mwmFilter, StringFilter userFilter,
TrackFilter const & filter, bool noTrackLogs, bool noMwmLogs, bool noWorldLogs);
void CmdGPX(string const & logFile, string const & outputFilesDir, string const & userID);
} // namespace track_analyzing
@@ -145,10 +141,10 @@ int main(int argc, char ** argv)
}
else if (cmd == "tracks")
{
TrackFilter const filter(FLAGS_min_duration, FLAGS_min_length, FLAGS_min_speed,
FLAGS_max_speed, FLAGS_ignore_traffic);
CmdTracks(Checked_in(), FLAGS_track_extension, MakeFilter(FLAGS_mwm), MakeFilter(FLAGS_user),
filter, FLAGS_no_track_logs, FLAGS_no_mwm_logs, FLAGS_no_world_logs);
TrackFilter const filter(FLAGS_min_duration, FLAGS_min_length, FLAGS_min_speed, FLAGS_max_speed,
FLAGS_ignore_traffic);
CmdTracks(Checked_in(), FLAGS_track_extension, MakeFilter(FLAGS_mwm), MakeFilter(FLAGS_user), filter,
FLAGS_no_track_logs, FLAGS_no_mwm_logs, FLAGS_no_world_logs);
}
else if (cmd == "track")
{
@@ -160,8 +156,7 @@ int main(int argc, char ** argv)
}
else if (cmd == "table")
{
CmdTagsTable(Checked_in(), FLAGS_track_extension, MakeFilter(FLAGS_mwm),
MakeFilter(FLAGS_user));
CmdTagsTable(Checked_in(), FLAGS_track_extension, MakeFilter(FLAGS_mwm), MakeFilter(FLAGS_user));
}
else if (cmd == "balance_csv")
{
@@ -171,8 +166,7 @@ int main(int argc, char ** argv)
"distribution. Hint: this file may be saved by match or match_dir command."));
return 1;
}
CmdBalanceCsv(FLAGS_in, FLAGS_input_distribution,
base::checked_cast<uint64_t>(FLAGS_ignore_datapoints_number));
CmdBalanceCsv(FLAGS_in, FLAGS_input_distribution, base::checked_cast<uint64_t>(FLAGS_ignore_datapoints_number));
}
else if (cmd == "gpx")
{

View File

@@ -31,8 +31,7 @@ namespace
set<string> GetKeys(Stats::NameToCountMapping const & mapping)
{
set<string> keys;
transform(mapping.begin(), mapping.end(), inserter(keys, keys.end()),
[](auto const & kv) { return kv.first; });
transform(mapping.begin(), mapping.end(), inserter(keys, keys.end()), [](auto const & kv) { return kv.first; });
return keys;
}
@@ -57,8 +56,8 @@ void Add(Stats::NameToCountMapping const & addition, Stats::NameToCountMapping &
}
}
void PrintMap(string const & keyName, string const & descr,
Stats::NameToCountMapping const & mapping, ostringstream & ss)
void PrintMap(string const & keyName, string const & descr, Stats::NameToCountMapping const & mapping,
ostringstream & ss)
{
ss << descr << '\n';
if (mapping.empty())
@@ -74,17 +73,15 @@ void PrintMap(string const & keyName, string const & descr,
namespace track_analyzing
{
// Stats ===========================================================================================
Stats::Stats(NameToCountMapping const & mwmToTotalDataPoints,
NameToCountMapping const & countryToTotalDataPoint)
Stats::Stats(NameToCountMapping const & mwmToTotalDataPoints, NameToCountMapping const & countryToTotalDataPoint)
: m_mwmToTotalDataPoints(mwmToTotalDataPoints)
, m_countryToTotalDataPoints(countryToTotalDataPoint)
{
}
{}
bool Stats::operator==(Stats const & stats) const
{
return m_mwmToTotalDataPoints == stats.m_mwmToTotalDataPoints &&
m_countryToTotalDataPoints == stats.m_countryToTotalDataPoints;
m_countryToTotalDataPoints == stats.m_countryToTotalDataPoints;
}
void Stats::Add(Stats const & stats)
@@ -93,8 +90,7 @@ void Stats::Add(Stats const & stats)
::Add(stats.m_countryToTotalDataPoints, m_countryToTotalDataPoints);
}
void Stats::AddTracksStats(MwmToTracks const & mwmToTracks, NumMwmIds const & numMwmIds,
Storage const & storage)
void Stats::AddTracksStats(MwmToTracks const & mwmToTracks, NumMwmIds const & numMwmIds, Storage const & storage)
{
for (auto const & kv : mwmToTracks)
{
@@ -109,15 +105,13 @@ void Stats::AddTracksStats(MwmToTracks const & mwmToTracks, NumMwmIds const & nu
}
}
void Stats::AddDataPoints(string const & mwmName, string const & countryName,
uint64_t dataPointNum)
void Stats::AddDataPoints(string const & mwmName, string const & countryName, uint64_t dataPointNum)
{
m_mwmToTotalDataPoints[mwmName] += dataPointNum;
m_countryToTotalDataPoints[countryName] += dataPointNum;
}
void Stats::AddDataPoints(string const & mwmName, storage::Storage const & storage,
uint64_t dataPointNum)
void Stats::AddDataPoints(string const & mwmName, storage::Storage const & storage, uint64_t dataPointNum)
{
auto const countryName = storage.GetTopmostParentFor(mwmName);
// Note. In case of disputed mwms |countryName| will be empty.
@@ -126,8 +120,7 @@ void Stats::AddDataPoints(string const & mwmName, storage::Storage const & stora
void Stats::SaveMwmDistributionToCsv(string const & csvPath) const
{
LOG(LINFO, ("Saving mwm distribution to", csvPath, "m_mwmToTotalDataPoints size is",
m_mwmToTotalDataPoints.size()));
LOG(LINFO, ("Saving mwm distribution to", csvPath, "m_mwmToTotalDataPoints size is", m_mwmToTotalDataPoints.size()));
if (csvPath.empty())
return;
@@ -162,8 +155,8 @@ void Stats::LogCountries() const
LogNameToCountMapping("country", "Country name to data points number:", m_countryToTotalDataPoints);
}
void MappingToCsv(string const & keyName, Stats::NameToCountMapping const & mapping,
bool printPercentage, basic_ostream<char> & ss)
void MappingToCsv(string const & keyName, Stats::NameToCountMapping const & mapping, bool printPercentage,
basic_ostream<char> & ss)
{
struct KeyValue
{
@@ -208,8 +201,7 @@ void MappingToCsv(string const & keyName, Stats::NameToCountMapping const & mapp
void MappingFromCsv(basic_istream<char> & ss, Stats::NameToCountMapping & mapping)
{
for (auto const & row :
coding::CSVRunner(coding::CSVReader(ss, true /* hasHeader */, ',' /* kCsvDelimiter */)))
for (auto const & row : coding::CSVRunner(coding::CSVReader(ss, true /* hasHeader */, ',' /* kCsvDelimiter */)))
{
CHECK_EQUAL(row.size(), 2, (row));
auto const & key = row[0];
@@ -220,8 +212,7 @@ void MappingFromCsv(basic_istream<char> & ss, Stats::NameToCountMapping & mappin
}
}
void ParseTracks(string const & logFile, shared_ptr<NumMwmIds> const & numMwmIds,
MwmToTracks & mwmToTracks)
void ParseTracks(string const & logFile, shared_ptr<NumMwmIds> const & numMwmIds, MwmToTracks & mwmToTracks)
{
Platform const & platform = GetPlatform();
string const dataDir = platform.WritableDir();
@@ -240,8 +231,7 @@ void WriteCsvTableHeader(basic_ostream<char> & stream)
"intersection with big\n";
}
void LogNameToCountMapping(string const & keyName, string const & descr,
Stats::NameToCountMapping const & mapping)
void LogNameToCountMapping(string const & keyName, string const & descr, Stats::NameToCountMapping const & mapping)
{
ostringstream ss;
LOG(LINFO, ("\n"));

View File

@@ -23,8 +23,7 @@ public:
using NameToCountMapping = std::map<std::string, uint64_t>;
Stats() = default;
Stats(NameToCountMapping const & mwmToTotalDataPoints,
NameToCountMapping const & countryToTotalDataPoint);
Stats(NameToCountMapping const & mwmToTotalDataPoints, NameToCountMapping const & countryToTotalDataPoint);
bool operator==(Stats const & stats) const;
void Add(Stats const & stats);
@@ -34,11 +33,9 @@ public:
storage::Storage const & storage);
/// \brief Adds |dataPointNum| to |m_mwmToTotalDataPoints| and |m_countryToTotalDataPoints|.
void AddDataPoints(std::string const & mwmName, std::string const & countryName,
uint64_t dataPointNum);
void AddDataPoints(std::string const & mwmName, std::string const & countryName, uint64_t dataPointNum);
void AddDataPoints(std::string const & mwmName, storage::Storage const & storage,
uint64_t dataPointNum);
void AddDataPoints(std::string const & mwmName, storage::Storage const & storage, uint64_t dataPointNum);
/// \brief Saves csv file with numbers of DataPoints for each mwm to |csvPath|.
/// If |csvPath| is empty it does nothing.
@@ -60,8 +57,8 @@ private:
};
/// \brief Saves |mapping| as csv to |ss|.
void MappingToCsv(std::string const & keyName, Stats::NameToCountMapping const & mapping,
bool printPercentage, std::basic_ostream<char> & ss);
void MappingToCsv(std::string const & keyName, Stats::NameToCountMapping const & mapping, bool printPercentage,
std::basic_ostream<char> & ss);
/// \breif Fills |mapping| according to csv in |ss|. Csv header is skipped.
void MappingFromCsv(std::basic_istream<char> & ss, Stats::NameToCountMapping & mapping);

View File

@@ -13,7 +13,8 @@ namespace
using namespace std;
using namespace track_analyzing;
string const csv = R"(user,mwm,hw type,surface type,maxspeed km/h,is city road,is one way,is day,lat lon,distance,time,mean speed km/h,turn from smaller to bigger,turn from bigger to smaller,from link,to link,intersection with big,intersection with small,intersection with link
string const csv =
R"(user,mwm,hw type,surface type,maxspeed km/h,is city road,is one way,is day,lat lon,distance,time,mean speed km/h,turn from smaller to bigger,turn from bigger to smaller,from link,to link,intersection with big,intersection with small,intersection with link
I:D923B4DC-09E0-4B0B-B7F8-153965396B55,New Zealand,highway-trunk,psurface-paved_good,80,0,0,1,-41.4832 173.844,163.984,6,98.3902,0,0,0,0,0,1,0
I:D923B4DC-09E0-4B0B-B7F8-153965396B55,New Zealand,highway-trunk,psurface-paved_good,80,0,0,1,-41.4831 173.845,2274.59,108,75.8196,0,0,0,0,0,4,0
A:b6e31294-5c90-4105-9f7b-51a382eabfa0,Poland,highway-primary,psurface-paved_good,50,0,0,0,53.8524 21.3061,1199.34,60,71.9604,0,0,0,0,0,10,0)";
@@ -48,15 +49,12 @@ UNIT_TEST(FillTableTest)
MwmToDataPoints const expectedMatchedDataPoints = {{"New Zealand", 2 /* data points */},
{"Poland", 1 /* data points */}};
std::vector<TableRow> expectedTable = {
{"I:D923B4DC-09E0-4B0B-B7F8-153965396B55", "New Zealand", "highway-trunk",
"psurface-paved_good", "80", "0", "0", "1", "-41.4832 173.844", "163.984", "6", "98.3902",
"0", "0", "0", "0", "0", "1", "0"},
{"I:D923B4DC-09E0-4B0B-B7F8-153965396B55", "New Zealand", "highway-trunk",
"psurface-paved_good", "80", "0", "0", "1", "-41.4831 173.845", "2274.59", "108", "75.8196",
"0", "0", "0", "0", "0", "4", "0"},
{"A:b6e31294-5c90-4105-9f7b-51a382eabfa0", "Poland", "highway-primary", "psurface-paved_good",
"50", "0", "0", "0", "53.8524 21.3061", "1199.34", "60", "71.9604", "0", "0", "0", "0", "0",
"10", "0"}};
{"I:D923B4DC-09E0-4B0B-B7F8-153965396B55", "New Zealand", "highway-trunk", "psurface-paved_good", "80", "0", "0",
"1", "-41.4832 173.844", "163.984", "6", "98.3902", "0", "0", "0", "0", "0", "1", "0"},
{"I:D923B4DC-09E0-4B0B-B7F8-153965396B55", "New Zealand", "highway-trunk", "psurface-paved_good", "80", "0", "0",
"1", "-41.4831 173.845", "2274.59", "108", "75.8196", "0", "0", "0", "0", "0", "4", "0"},
{"A:b6e31294-5c90-4105-9f7b-51a382eabfa0", "Poland", "highway-primary", "psurface-paved_good", "50", "0", "0",
"0", "53.8524 21.3061", "1199.34", "60", "71.9604", "0", "0", "0", "0", "0", "10", "0"}};
TEST_EQUAL(matchedDataPoints, expectedMatchedDataPoints, ());
TEST_EQUAL(table, expectedTable, ());
@@ -69,10 +67,8 @@ UNIT_TEST(AreKeysEqualEmptyMapsTest)
UNIT_TEST(AreKeysEqualTest)
{
MwmToDataPoints const map1 = {{"Russia_Moscow", 5 /* data points */},
{"San Marino", 7 /* data points */}};
MwmToDataPoints map2 = {{"Russia_Moscow", 7 /* data points*/},
{"San Marino", 9 /* data points */}};
MwmToDataPoints const map1 = {{"Russia_Moscow", 5 /* data points */}, {"San Marino", 7 /* data points */}};
MwmToDataPoints map2 = {{"Russia_Moscow", 7 /* data points*/}, {"San Marino", 9 /* data points */}};
TEST(AreKeysEqual(map1, map2), ());
map2["Slovakia"] = 3;
@@ -90,10 +86,8 @@ UNIT_TEST(RemoveKeysSmallValueEmptyTest)
UNIT_TEST(RemoveKeysSmallValueTest)
{
MwmToDataPoints checkedMap = {{"Russia_Moscow", 3 /* data points */},
{"San Marino", 5 /* data points */}};
MwmToDataPoints additionalMap = {{"Russia_Moscow", 7 /* data points*/},
{"San Marino", 9 /* data points */}};
MwmToDataPoints checkedMap = {{"Russia_Moscow", 3 /* data points */}, {"San Marino", 5 /* data points */}};
MwmToDataPoints additionalMap = {{"Russia_Moscow", 7 /* data points*/}, {"San Marino", 9 /* data points */}};
RemoveKeysSmallValue(checkedMap, additionalMap, 4 /* ignoreDataPointNumber */);
MwmToDataPoints expectedCheckedMap = {{"San Marino", 5 /* data points */}};
@@ -110,9 +104,8 @@ UNIT_TEST(GetMwmToDataPointFractionTest)
{"Slovakia", 50 /* data points */}};
auto const fractionMapping = GetMwmToDataPointFraction(numberMapping);
MwmToDataPointFraction expectedFractionMapping{{"Russia_Moscow", 0.5 /* fraction */},
{"San Marino", 0.25 /* fraction */},
{"Slovakia", 0.25 /* fraction */}};
MwmToDataPointFraction expectedFractionMapping{
{"Russia_Moscow", 0.5 /* fraction */}, {"San Marino", 0.25 /* fraction */}, {"Slovakia", 0.25 /* fraction */}};
TEST_EQUAL(fractionMapping, expectedFractionMapping, ());
}
@@ -153,9 +146,8 @@ UNIT_TEST(BalancedDataPointNumberTheSameTest)
MwmToDataPoints const distribution = {{"Russia_Moscow", 100 /* data points */},
{"San Marino", 50 /* data points */},
{"Slovakia", 50 /* data points */}};
MwmToDataPoints const matchedDataPoints = {{"Russia_Moscow", 10 /* data points */},
{"San Marino", 5 /* data points */},
{"Slovakia", 5 /* data points */}};
MwmToDataPoints const matchedDataPoints = {
{"Russia_Moscow", 10 /* data points */}, {"San Marino", 5 /* data points */}, {"Slovakia", 5 /* data points */}};
{
// Case when the distribution is not changed. All mwms lose the same percent of data points.
auto distr = distribution;
@@ -226,7 +218,8 @@ UNIT_TEST(FilterTableTest)
ss << csv;
FillTable(ss, matchedDataPoints, csvTable);
auto const calcRecords = [](vector<TableRow> const & t, string const & mwmName) {
auto const calcRecords = [](vector<TableRow> const & t, string const & mwmName)
{
return count_if(t.cbegin(), t.cend(),
[&mwmName](TableRow const & row) { return row[kMwmNameCsvColumn] == mwmName; });
};

View File

@@ -13,8 +13,8 @@
#include "geometry/latlon.hpp"
#include <string>
#include <sstream>
#include <string>
namespace
{
@@ -43,27 +43,24 @@ UNIT_TEST(AddDataPointsTest)
stats.AddDataPoints("mwm2", "country1", 5);
stats.AddDataPoints("mwm3", "country3", 7);
Stats const expected = {
{{"mwm1", 4}, {"mwm2", 5}, {"mwm3", 7} /* Mwm to number */},
{{"country1", 9}, {"country3", 7} /* Country to number */}};
Stats const expected = {{{"mwm1", 4}, {"mwm2", 5}, {"mwm3", 7} /* Mwm to number */},
{{"country1", 9}, {"country3", 7} /* Country to number */}};
TEST_EQUAL(stats, expected, ());
}
UNIT_TEST(AddStatTest)
{
Stats stats1 = {
{{"Belarus_Minsk Region", 1}, {"Uzbekistan", 7}, {"Russia_Moscow", 5} /* Mwm to number */},
{{"Russian Federation", 10}, {"Poland", 5} /* Country to number */}};
Stats stats1 = {{{"Belarus_Minsk Region", 1}, {"Uzbekistan", 7}, {"Russia_Moscow", 5} /* Mwm to number */},
{{"Russian Federation", 10}, {"Poland", 5} /* Country to number */}};
Stats const stats2 = {{{"Belarus_Minsk Region", 2} /* Mwm to number */},
{{"Russian Federation", 1}, {"Belarus", 8} /* Country to number */}};
stats1.Add(stats2);
Stats const expected = {
{{"Belarus_Minsk Region", 3}, {"Uzbekistan", 7}, {"Russia_Moscow", 5} /* Mwm to number */},
{{"Russian Federation", 11}, {"Poland", 5}, {"Belarus", 8} /* Country to number */}};
Stats const expected = {{{"Belarus_Minsk Region", 3}, {"Uzbekistan", 7}, {"Russia_Moscow", 5} /* Mwm to number */},
{{"Russian Federation", 11}, {"Poland", 5}, {"Belarus", 8} /* Country to number */}};
TEST_EQUAL(stats1, expected, ());
}
@@ -101,8 +98,7 @@ UNIT_TEST(AddTracksStatsTest)
UNIT_TEST(MappingToCsvTest)
{
Stats::NameToCountMapping const mapping = {
{{"Belarus_Minsk Region", 2}, {"Uzbekistan", 5}, {"Russia_Moscow", 3}}};
Stats::NameToCountMapping const mapping = {{{"Belarus_Minsk Region", 2}, {"Uzbekistan", 5}, {"Russia_Moscow", 3}}};
{
std::ostringstream ss;
MappingToCsv("mwm", mapping, true /* printPercentage */, ss);
@@ -127,8 +123,7 @@ Belarus_Minsk Region,2
UNIT_TEST(MappingToCsvUint64Test)
{
Stats::NameToCountMapping const mapping = {{"Belarus_Minsk Region", 5'000'000'000},
{"Uzbekistan", 15'000'000'000}};
Stats::NameToCountMapping const mapping = {{"Belarus_Minsk Region", 5'000'000'000}, {"Uzbekistan", 15'000'000'000}};
std::stringstream ss;
MappingToCsv("mwm", mapping, true /* printPercentage */, ss);
std::string const expected = R"(mwm,number,percent
@@ -140,21 +135,17 @@ Belarus_Minsk Region,5000000000,25
UNIT_TEST(SerializationToCsvTest)
{
Stats::NameToCountMapping const mapping1 = {{"Belarus_Minsk Region", 2},
{"Uzbekistan", 5},
{"Russia_Moscow", 1},
{"Russia_Moscow Oblast_East", 2}};
Stats::NameToCountMapping const mapping1 = {
{"Belarus_Minsk Region", 2}, {"Uzbekistan", 5}, {"Russia_Moscow", 1}, {"Russia_Moscow Oblast_East", 2}};
TestSerializationToCsv(mapping1);
Stats::NameToCountMapping const mapping2 = {
{{"Belarus_Minsk Region", 2}, {"Uzbekistan", 5}, {"Russia_Moscow", 3}}};
Stats::NameToCountMapping const mapping2 = {{{"Belarus_Minsk Region", 2}, {"Uzbekistan", 5}, {"Russia_Moscow", 3}}};
TestSerializationToCsv(mapping2);
}
UNIT_TEST(SerializationToCsvWithZeroValueTest)
{
Stats::NameToCountMapping const mapping = {{"Russia_Moscow Oblast_East", 2},
{"Poland_Lesser Poland Voivodeship", 0}};
Stats::NameToCountMapping const mapping = {{"Russia_Moscow Oblast_East", 2}, {"Poland_Lesser Poland Voivodeship", 0}};
Stats::NameToCountMapping const expected = {{"Russia_Moscow Oblast_East", 2}};
std::stringstream ss;
@@ -168,9 +159,8 @@ UNIT_TEST(SerializationToCsvWithZeroValueTest)
UNIT_TEST(SerializationToCsvUint64Test)
{
Stats::NameToCountMapping const mapping = {{"Belarus_Minsk Region", 20'000'000'000},
{"Uzbekistan", 5},
{"Russia_Moscow", 7'000'000'000}};
Stats::NameToCountMapping const mapping = {
{"Belarus_Minsk Region", 20'000'000'000}, {"Uzbekistan", 5}, {"Russia_Moscow", 7'000'000'000}};
TestSerializationToCsv(mapping);
}
} // namespace

View File

@@ -11,8 +11,8 @@
#include "coding/zip_creator.hpp"
#include <optional>
#include <string>
#include <sstream>
#include <string>
#include "3party/minizip/minizip.hpp"
@@ -31,8 +31,7 @@ struct UserTrackInfo
Track m_track;
};
std::optional<UserTrackInfo> ParseLogRecord(std::string const & record,
TemporaryFile & tmpArchiveFile);
std::optional<UserTrackInfo> ParseLogRecord(std::string const & record, TemporaryFile & tmpArchiveFile);
std::optional<std::string> ParseMultipartData(std::string const & binaryData);
bool ParseTrackFile(unzip::File & zipReader, Track & trackData) noexcept;
template <typename Reader, typename Pack>
@@ -83,8 +82,8 @@ UNIT_TEST(UnpackTrackArchiveDataTest)
vector<string> trackFiles;
trackFiles.push_back(archiveFileName);
string const containerFileName("test_track_archive.zip");
TEST_EQUAL(CreateZipFromFiles(trackFiles, containerFileName, CompressionLevel::NoCompression),
true, ("Unable to create tracks archive"));
TEST_EQUAL(CreateZipFromFiles(trackFiles, containerFileName, CompressionLevel::NoCompression), true,
("Unable to create tracks archive"));
FileWriter::DeleteFileX(archiveFileName);
// Step 2.3: Read batch archive content
@@ -99,8 +98,7 @@ UNIT_TEST(UnpackTrackArchiveDataTest)
// Step 2.4: Wrap as multipart data
stringstream multipartStream;
multipartStream << "------0000000000000\r\n";
multipartStream << "Content-Disposition: form-data; name=\"file\"; filename=\""
<< containerFileName << "\"\r\n";
multipartStream << "Content-Disposition: form-data; name=\"file\"; filename=\"" << containerFileName << "\"\r\n";
multipartStream << "Content-Type: application/zip\r\n";
multipartStream << "\r\n";
multipartStream.write(buffer.data(), buffer.size());
@@ -110,16 +108,14 @@ UNIT_TEST(UnpackTrackArchiveDataTest)
string multipartData = multipartStream.str();
stringstream logStream;
logStream << testUserId << "\t1\t1577826010\t" << multipartData.size() << "\t"
<< ToHex(multipartData);
logStream << testUserId << "\t1\t1577826010\t" << multipartData.size() << "\t" << ToHex(multipartData);
string const logRecord = logStream.str();
// Unpack log record
TemporaryFile tmpArchiveFile("tmp-unittest", ".zip");
optional<track_analyzing::details::UserTrackInfo> data =
ParseLogRecord(logRecord, tmpArchiveFile);
optional<track_analyzing::details::UserTrackInfo> data = ParseLogRecord(logRecord, tmpArchiveFile);
TEST_EQUAL(bool(data), true, ("Unable parse track archive record"));
TEST_EQUAL(data->m_userId, testUserId, ());
@@ -128,10 +124,8 @@ UNIT_TEST(UnpackTrackArchiveDataTest)
for (size_t i = 0; i < testTrack.size(); ++i)
{
TEST_EQUAL(data->m_track[i].m_timestamp, testTrack[i].m_timestamp, ());
TEST_ALMOST_EQUAL_ABS(data->m_track[i].m_latLon.m_lat, testTrack[i].m_latLon.m_lat,
kAccuracyEps, ());
TEST_ALMOST_EQUAL_ABS(data->m_track[i].m_latLon.m_lon, testTrack[i].m_latLon.m_lon,
kAccuracyEps, ());
TEST_ALMOST_EQUAL_ABS(data->m_track[i].m_latLon.m_lat, testTrack[i].m_latLon.m_lat, kAccuracyEps, ());
TEST_ALMOST_EQUAL_ABS(data->m_track[i].m_latLon.m_lon, testTrack[i].m_latLon.m_lon, kAccuracyEps, ());
TEST_EQUAL(data->m_track[i].m_traffic, testTrack[i].m_traffic, ());
}
}

View File

@@ -27,7 +27,7 @@ using namespace track_analyzing;
namespace track_analyzing
{
const string kTmpArchiveFileNameTemplate("-tmp-track-archive.zip");
string const kTmpArchiveFileNameTemplate("-tmp-track-archive.zip");
// Track record fields:
// 0: user ID
@@ -124,8 +124,8 @@ optional<string> ParseMultipartData(string const & binaryData)
{
if (expectedContentType == header)
hasContentTypeHeader = true;
if (expectedContentDispositionPrefix.compare(0, string::npos, header, 0,
expectedContentDispositionPrefix.size()) == 0)
if (expectedContentDispositionPrefix.compare(0, string::npos, header, 0, expectedContentDispositionPrefix.size()) ==
0)
{
hasContentDispositionHeader = true;
}
@@ -140,8 +140,8 @@ optional<string> ParseMultipartData(string const & binaryData)
bool HasZipSignature(string const & binaryData)
{
return binaryData.size() >= 4 && binaryData[0] == 0x50 && binaryData[1] == 0x4b &&
binaryData[2] == 0x03 && binaryData[3] == 0x04;
return binaryData.size() >= 4 && binaryData[0] == 0x50 && binaryData[1] == 0x4b && binaryData[2] == 0x03 &&
binaryData[3] == 0x04;
}
template <typename Reader, typename Pack>
@@ -153,8 +153,7 @@ bool ReadTrackFromArchive(char const * data, size_t dataSize, Track & trackData)
vector<uint8_t> buffer;
inflate(data, dataSize, back_inserter(buffer));
ReaderSource<MemReaderWithExceptions> reader(
MemReaderWithExceptions(buffer.data(), buffer.size()));
ReaderSource<MemReaderWithExceptions> reader(MemReaderWithExceptions(buffer.data(), buffer.size()));
if (reader.Size() == 0)
return false;
@@ -209,13 +208,13 @@ bool ParseTrackFile(unzip::File & zipReader, Track & trackData) noexcept
bool result = false;
if (archiveInfo.m_trackType == routing::RouterType::Vehicle)
{
result = ReadTrackFromArchive<ReaderSource<MemReaderWithExceptions>, tracking::PacketCar>(
fileData.data(), dataSize, trackData);
result = ReadTrackFromArchive<ReaderSource<MemReaderWithExceptions>, tracking::PacketCar>(fileData.data(), dataSize,
trackData);
}
else
{
result = ReadTrackFromArchive<ReaderSource<MemReaderWithExceptions>, tracking::Packet>(
fileData.data(), dataSize, trackData);
result = ReadTrackFromArchive<ReaderSource<MemReaderWithExceptions>, tracking::Packet>(fileData.data(), dataSize,
trackData);
}
if (unzip::CloseCurrentFile(zipReader) != unzip::Code::Ok)
@@ -254,9 +253,7 @@ optional<Track> ParseTrackArchiveData(string const & content, TemporaryFile & tm
bool result = ParseTrackFile(zipReader, trackData);
while (result && unzip::GoToNextFile(zipReader) == unzip::Code::Ok)
{
result = ParseTrackFile(zipReader, trackData);
}
if (unzip::Close(zipReader) != unzip::Code::Ok)
LOG(LERROR, ("Unable to close temporary zip archive"));
@@ -285,8 +282,7 @@ optional<UserTrackInfo> ParseLogRecord(string const & record, TemporaryFile & tm
} // namespace details
void TrackArchiveReader::ParseUserTracksFromFile(string const & logFile,
UserToTrack & userToTrack) const
void TrackArchiveReader::ParseUserTracksFromFile(string const & logFile, UserToTrack & userToTrack) const
{
// Read file content
FileReader reader(logFile);

View File

@@ -12,7 +12,6 @@
#include "base/stl_helpers.hpp"
namespace track_analyzing
{
using namespace routing;
@@ -25,8 +24,7 @@ namespace
double constexpr kMatchingRange = 20.0;
// Mercator distance from segment to point in meters.
double DistanceToSegment(m2::PointD const & segmentBegin, m2::PointD const & segmentEnd,
m2::PointD const & point)
double DistanceToSegment(m2::PointD const & segmentBegin, m2::PointD const & segmentEnd, m2::PointD const & point)
{
m2::ParametrizedSegment<m2::PointD> const segment(segmentBegin, segmentEnd);
m2::PointD const projectionPoint = segment.ClosestPointTo(point);
@@ -36,41 +34,36 @@ double DistanceToSegment(m2::PointD const & segmentBegin, m2::PointD const & seg
double DistanceToSegment(Segment const & segment, m2::PointD const & point, IndexGraph & indexGraph)
{
auto const & road = indexGraph.GetRoadGeometry(segment.GetFeatureId());
return DistanceToSegment(
mercator::FromLatLon(road.GetPoint(segment.GetPointId(false))),
mercator::FromLatLon(road.GetPoint(segment.GetPointId(true))), point);
return DistanceToSegment(mercator::FromLatLon(road.GetPoint(segment.GetPointId(false))),
mercator::FromLatLon(road.GetPoint(segment.GetPointId(true))), point);
}
bool EdgesContain(IndexGraph::SegmentEdgeListT const & edges, Segment const & segment)
{
for (auto const & edge : edges)
{
if (edge.GetTarget() == segment)
return true;
}
return false;
}
} // namespace
// TrackMatcher ------------------------------------------------------------------------------------
TrackMatcher::TrackMatcher(storage::Storage const & storage, NumMwmId mwmId,
platform::CountryFile const & countryFile)
TrackMatcher::TrackMatcher(storage::Storage const & storage, NumMwmId mwmId, platform::CountryFile const & countryFile)
: m_mwmId(mwmId)
, m_vehicleModel(CarModelFactory({}).GetVehicleModelForCountry(countryFile.GetName()))
{
auto localCountryFile = storage.GetLatestLocalFile(countryFile);
CHECK(localCountryFile, ("Can't find latest country file for", countryFile.GetName()));
auto registerResult = m_dataSource.Register(*localCountryFile);
CHECK_EQUAL(registerResult.second, MwmSet::RegResult::Success,
("Can't register mwm", countryFile.GetName()));
CHECK_EQUAL(registerResult.second, MwmSet::RegResult::Success, ("Can't register mwm", countryFile.GetName()));
MwmSet::MwmHandle handle = m_dataSource.GetMwmHandleByCountryFile(countryFile);
m_graph = make_unique<IndexGraph>(
make_shared<Geometry>(GeometryLoader::Create(handle, m_vehicleModel, false /* loadAltitudes */)),
EdgeEstimator::Create(VehicleType::Car, *m_vehicleModel, nullptr /* trafficStash */,
nullptr /* dataSource */, nullptr /* numMvmIds */));
EdgeEstimator::Create(VehicleType::Car, *m_vehicleModel, nullptr /* trafficStash */, nullptr /* dataSource */,
nullptr /* numMvmIds */));
DeserializeIndexGraph(*handle.GetValue(), VehicleType::Car, *m_graph);
}
@@ -88,8 +81,7 @@ void TrackMatcher::MatchTrack(vector<DataPoint> const & track, vector<MatchedTra
{
for (; trackBegin < steps.size(); ++trackBegin)
{
steps[trackBegin].FillCandidatesWithNearbySegments(m_dataSource, *m_graph, *m_vehicleModel,
m_mwmId);
steps[trackBegin].FillCandidatesWithNearbySegments(m_dataSource, *m_graph, *m_vehicleModel, m_mwmId);
if (steps[trackBegin].HasCandidates())
break;
@@ -130,13 +122,12 @@ void TrackMatcher::MatchTrack(vector<DataPoint> const & track, vector<MatchedTra
// TrackMatcher::Step ------------------------------------------------------------------------------
TrackMatcher::Step::Step(DataPoint const & dataPoint)
: m_dataPoint(dataPoint), m_point(mercator::FromLatLon(dataPoint.m_latLon))
{
}
: m_dataPoint(dataPoint)
, m_point(mercator::FromLatLon(dataPoint.m_latLon))
{}
void TrackMatcher::Step::FillCandidatesWithNearbySegments(
DataSource const & dataSource, IndexGraph const & graph,
VehicleModelInterface const & vehicleModel, NumMwmId mwmId)
void TrackMatcher::Step::FillCandidatesWithNearbySegments(DataSource const & dataSource, IndexGraph const & graph,
VehicleModelInterface const & vehicleModel, NumMwmId mwmId)
{
dataSource.ForEachInRect([&](FeatureType & ft)
{
@@ -154,25 +145,20 @@ void TrackMatcher::Step::FillCandidatesWithNearbySegments(
for (size_t segIdx = 0; segIdx + 1 < ft.GetPointsCount(); ++segIdx)
{
double const distance =
DistanceToSegment(ft.GetPoint(segIdx), ft.GetPoint(segIdx + 1), m_point);
double const distance = DistanceToSegment(ft.GetPoint(segIdx), ft.GetPoint(segIdx + 1), m_point);
if (distance < kMatchingRange)
{
AddCandidate(Segment(mwmId, ft.GetID().m_index, static_cast<uint32_t>(segIdx),
true /* forward */),
distance, graph);
AddCandidate(Segment(mwmId, ft.GetID().m_index, static_cast<uint32_t>(segIdx), true /* forward */), distance,
graph);
if (!vehicleModel.IsOneWay(types))
{
AddCandidate(Segment(mwmId, ft.GetID().m_index, static_cast<uint32_t>(segIdx),
false /* forward */),
distance, graph);
AddCandidate(Segment(mwmId, ft.GetID().m_index, static_cast<uint32_t>(segIdx), false /* forward */), distance,
graph);
}
}
}
},
mercator::RectByCenterXYAndSizeInMeters(m_point, kMatchingRange),
scales::GetUpperScale());
}, mercator::RectByCenterXYAndSizeInMeters(m_point, kMatchingRange), scales::GetUpperScale());
}
void TrackMatcher::Step::FillCandidates(Step const & previousStep, IndexGraph & graph)
@@ -198,9 +184,7 @@ void TrackMatcher::Step::FillCandidates(Step const & previousStep, IndexGraph &
base::SortUnique(m_candidates);
m_candidates.erase(remove_if(m_candidates.begin(), m_candidates.end(),
[&](Candidate const & candidate) {
return candidate.GetDistance() > kMatchingRange;
}),
[&](Candidate const & candidate) { return candidate.GetDistance() > kMatchingRange; }),
m_candidates.end());
}
@@ -211,8 +195,7 @@ void TrackMatcher::Step::ChooseSegment(Step const & nextStep, IndexGraph & index
double minDistance = numeric_limits<double>::max();
IndexGraph::SegmentEdgeListT edges;
indexGraph.GetEdgeList(nextStep.m_segment, false /* isOutgoing */, true /* useRoutingOptions */,
edges);
indexGraph.GetEdgeList(nextStep.m_segment, false /* isOutgoing */, true /* useRoutingOptions */, edges);
edges.emplace_back(nextStep.m_segment, GetAStarWeightZero<RouteWeight>());
for (Candidate const & candidate : m_candidates)
@@ -244,8 +227,7 @@ void TrackMatcher::Step::ChooseNearestSegment()
}
}
void TrackMatcher::Step::AddCandidate(Segment const & segment, double distance,
IndexGraph const & graph)
void TrackMatcher::Step::AddCandidate(Segment const & segment, double distance, IndexGraph const & graph)
{
if (graph.GetAccessType(segment) == RoadAccess::Type::Yes)
m_candidates.emplace_back(segment, distance);

View File

@@ -22,8 +22,7 @@ namespace track_analyzing
class TrackMatcher final
{
public:
TrackMatcher(storage::Storage const & storage, routing::NumMwmId mwmId,
platform::CountryFile const & countryFile);
TrackMatcher(storage::Storage const & storage, routing::NumMwmId mwmId, platform::CountryFile const & countryFile);
void MatchTrack(std::vector<DataPoint> const & track, std::vector<MatchedTrack> & matchedTracks);
@@ -35,9 +34,7 @@ private:
class Candidate final
{
public:
Candidate(routing::Segment segment, double distance) : m_segment(segment), m_distance(distance)
{
}
Candidate(routing::Segment segment, double distance) : m_segment(segment), m_distance(distance) {}
routing::Segment const & GetSegment() const { return m_segment; }
double GetDistance() const { return m_distance; }
@@ -57,17 +54,14 @@ private:
DataPoint const & GetDataPoint() const { return m_dataPoint; }
routing::Segment const & GetSegment() const { return m_segment; }
bool HasCandidates() const { return !m_candidates.empty(); }
void FillCandidatesWithNearbySegments(DataSource const & dataSource,
routing::IndexGraph const & graph,
routing::VehicleModelInterface const & vehicleModel,
routing::NumMwmId mwmId);
void FillCandidatesWithNearbySegments(DataSource const & dataSource, routing::IndexGraph const & graph,
routing::VehicleModelInterface const & vehicleModel, routing::NumMwmId mwmId);
void FillCandidates(Step const & previousStep, routing::IndexGraph & graph);
void ChooseSegment(Step const & nextStep, routing::IndexGraph & indexGraph);
void ChooseNearestSegment();
private:
void AddCandidate(routing::Segment const & segment, double distance,
routing::IndexGraph const & graph);
void AddCandidate(routing::Segment const & segment, double distance, routing::IndexGraph const & graph);
DataPoint m_dataPoint;
m2::PointD m_point;

View File

@@ -17,8 +17,7 @@ using namespace std;
namespace track_analyzing
{
double CalcSubtrackLength(MatchedTrack::const_iterator begin, MatchedTrack::const_iterator end,
Geometry & geometry)
double CalcSubtrackLength(MatchedTrack::const_iterator begin, MatchedTrack::const_iterator end, Geometry & geometry)
{
double length = 0.0;
@@ -29,10 +28,8 @@ double CalcSubtrackLength(MatchedTrack::const_iterator begin, MatchedTrack::cons
Segment const & segment = point.GetSegment();
if (segment != prevSegment)
{
length +=
ms::DistanceOnEarth(
geometry.GetPoint(segment.GetRoadPoint(false /* front */)),
geometry.GetPoint(segment.GetRoadPoint(true /* front */)));
length += ms::DistanceOnEarth(geometry.GetPoint(segment.GetRoadPoint(false /* front */)),
geometry.GetPoint(segment.GetRoadPoint(true /* front */)));
prevSegment = segment;
}
}
@@ -51,8 +48,7 @@ double CalcSpeedKMpH(double meters, uint64_t secondsElapsed)
return measurement_utils::MpsToKmph(meters / static_cast<double>(secondsElapsed));
}
void ReadTracks(shared_ptr<NumMwmIds> numMwmIds, string const & filename,
MwmToMatchedTracks & mwmToMatchedTracks)
void ReadTracks(shared_ptr<NumMwmIds> numMwmIds, string const & filename, MwmToMatchedTracks & mwmToMatchedTracks)
{
FileReader reader(filename);
ReaderSource<FileReader> src(reader);
@@ -60,9 +56,8 @@ void ReadTracks(shared_ptr<NumMwmIds> numMwmIds, string const & filename,
serializer.Deserialize(mwmToMatchedTracks, src);
}
MatchedTrack const & GetMatchedTrack(MwmToMatchedTracks const & mwmToMatchedTracks,
NumMwmIds const & numMwmIds, string const & mwmName,
string const & user, size_t trackIdx)
MatchedTrack const & GetMatchedTrack(MwmToMatchedTracks const & mwmToMatchedTracks, NumMwmIds const & numMwmIds,
string const & mwmName, string const & user, size_t trackIdx)
{
auto const countryFile = platform::CountryFile(mwmName);
if (!numMwmIds.ContainsFile(countryFile))
@@ -84,8 +79,8 @@ MatchedTrack const & GetMatchedTrack(MwmToMatchedTracks const & mwmToMatchedTrac
if (trackIdx >= tracks.size())
{
MYTHROW(MessageException, ("There is no track", trackIdx, "for user", user, ", she has",
tracks.size(), "tracks only"));
MYTHROW(MessageException,
("There is no track", trackIdx, "for user", user, ", she has", tracks.size(), "tracks only"));
}
return tracks[trackIdx];
@@ -96,10 +91,9 @@ std::string GetCurrentVersionMwmFile(storage::Storage const & storage, std::stri
return storage.GetFilePath(mwmName, MapFileType::Map);
}
void ForEachTrackFile(
std::string const & filepath, std::string const & extension,
shared_ptr<routing::NumMwmIds> numMwmIds,
std::function<void(std::string const & filename, MwmToMatchedTracks const &)> && toDo)
void ForEachTrackFile(std::string const & filepath, std::string const & extension,
shared_ptr<routing::NumMwmIds> numMwmIds,
std::function<void(std::string const & filename, MwmToMatchedTracks const &)> && toDo)
{
Platform::EFileType fileType = Platform::EFileType::Unknown;
Platform::EError const result = Platform::GetFileType(filepath, fileType);

View File

@@ -29,14 +29,12 @@ double CalcSpeedKMpH(double meters, uint64_t secondsElapsed);
void ReadTracks(std::shared_ptr<routing::NumMwmIds> numMwmIds, std::string const & filename,
MwmToMatchedTracks & mwmToMatchedTracks);
MatchedTrack const & GetMatchedTrack(MwmToMatchedTracks const & mwmToMatchedTracks,
routing::NumMwmIds const & numMwmIds,
std::string const & mwmName, std::string const & user,
size_t trackIdx);
routing::NumMwmIds const & numMwmIds, std::string const & mwmName,
std::string const & user, size_t trackIdx);
std::string GetCurrentVersionMwmFile(storage::Storage const & storage, std::string const & mwmName);
template <typename MwmToTracks, typename ToDo>
void ForTracksSortedByMwmName(MwmToTracks const & mwmToTracks, routing::NumMwmIds const & numMwmIds,
ToDo && toDo)
void ForTracksSortedByMwmName(MwmToTracks const & mwmToTracks, routing::NumMwmIds const & numMwmIds, ToDo && toDo)
{
std::vector<std::string> mwmNames;
mwmNames.reserve(mwmToTracks.size());
@@ -53,8 +51,7 @@ void ForTracksSortedByMwmName(MwmToTracks const & mwmToTracks, routing::NumMwmId
}
}
void ForEachTrackFile(
std::string const & filepath, std::string const & extension,
std::shared_ptr<routing::NumMwmIds> numMwmIds,
std::function<void(std::string const & filename, MwmToMatchedTracks const &)> && toDo);
void ForEachTrackFile(std::string const & filepath, std::string const & extension,
std::shared_ptr<routing::NumMwmIds> numMwmIds,
std::function<void(std::string const & filename, MwmToMatchedTracks const &)> && toDo);
} // namespace track_analyzing

View File

@@ -13,20 +13,22 @@ DEFINE_string(inputDir, "", "Path to kmls.");
DEFINE_string(outputDir, "", "Path to converted kmls.");
DEFINE_int32(vehicleType, 0, "Numeric value of routing::VehicleType enum. "
"Pedestrian by default.");
DEFINE_int32(vehicleType, 0,
"Numeric value of routing::VehicleType enum. "
"Pedestrian by default.");
DEFINE_bool(showHelp, false, "Show help on all flags.");
int main(int argc, char ** argv)
{
gflags::SetUsageMessage("The tool is used to generate more smooth track based on "
"waypoints from the kml. The kml has to contain points "
"within LineString tag. If the router can't build the route "
"than the specific path will be untouched. Multiple kmls into "
" the directory are supported.\n\n"
"Usage example: "
"./track_generator_tool -inputDir=path/to/input/ -outputDir=/path/to/output/");
gflags::SetUsageMessage(
"The tool is used to generate more smooth track based on "
"waypoints from the kml. The kml has to contain points "
"within LineString tag. If the router can't build the route "
"than the specific path will be untouched. Multiple kmls into "
" the directory are supported.\n\n"
"Usage example: "
"./track_generator_tool -inputDir=path/to/input/ -outputDir=/path/to/output/");
gflags::ParseCommandLineFlags(&argc, &argv, false /* remove_flags */);