diff options
author | Добрый Ээх <bukharaev@gmail.com> | 2017-05-19 20:07:42 +0300 |
---|---|---|
committer | Yuri Gorshenin <mipt.vi002@gmail.com> | 2017-08-11 17:46:36 +0300 |
commit | 24be21937413f41eac710c3909ff62c5d9ece5c9 (patch) | |
tree | 48f12c8beee0c229d08773b87f151babb577bc46 /track_analyzing | |
parent | 993debefd3a717769da5859963ddee8fd66180c5 (diff) |
[routing] Pull request #6082 review fixes
Diffstat (limited to 'track_analyzing')
-rw-r--r-- | track_analyzing/CMakeLists.txt | 1 | ||||
-rw-r--r-- | track_analyzing/exceptions.hpp | 4 | ||||
-rw-r--r-- | track_analyzing/log_parser.cpp | 68 | ||||
-rw-r--r-- | track_analyzing/log_parser.hpp | 6 | ||||
-rw-r--r-- | track_analyzing/serialization.hpp | 14 | ||||
-rw-r--r-- | track_analyzing/track.cpp | 29 | ||||
-rw-r--r-- | track_analyzing/track.hpp | 33 | ||||
-rw-r--r-- | track_analyzing/track_analyzer/CMakeLists.txt | 3 | ||||
-rw-r--r-- | track_analyzing/track_analyzer/cmd_cpp_track.cpp | 8 | ||||
-rw-r--r-- | track_analyzing/track_analyzer/cmd_match.cpp | 94 | ||||
-rw-r--r-- | track_analyzing/track_analyzer/cmd_table.cpp | 86 | ||||
-rw-r--r-- | track_analyzing/track_analyzer/cmd_track.cpp | 8 | ||||
-rw-r--r-- | track_analyzing/track_analyzer/cmd_tracks.cpp | 66 | ||||
-rw-r--r-- | track_analyzing/track_analyzer/track_analyzer.cpp | 54 | ||||
-rw-r--r-- | track_analyzing/track_matcher.cpp | 111 | ||||
-rw-r--r-- | track_analyzing/track_matcher.hpp | 27 | ||||
-rw-r--r-- | track_analyzing/utils.cpp | 80 | ||||
-rw-r--r-- | track_analyzing/utils.hpp | 60 |
18 files changed, 390 insertions, 362 deletions
diff --git a/track_analyzing/CMakeLists.txt b/track_analyzing/CMakeLists.txt index 6008a3ea25..32e32cbf68 100644 --- a/track_analyzing/CMakeLists.txt +++ b/track_analyzing/CMakeLists.txt @@ -6,6 +6,7 @@ set( log_parser.cpp log_parser.hpp serialization.hpp + track.cpp track.hpp track_matcher.cpp track_matcher.hpp diff --git a/track_analyzing/exceptions.hpp b/track_analyzing/exceptions.hpp index a76337f841..a52050f20b 100644 --- a/track_analyzing/exceptions.hpp +++ b/track_analyzing/exceptions.hpp @@ -2,7 +2,7 @@ #include "base/exception.hpp" -namespace tracking +namespace track_analyzing { DECLARE_EXCEPTION(MessageException, RootException); -} // namespace tracking +} // namespace track_analyzing diff --git a/track_analyzing/log_parser.cpp b/track_analyzing/log_parser.cpp index c1dd61c7a6..709bea3455 100644 --- a/track_analyzing/log_parser.cpp +++ b/track_analyzing/log_parser.cpp @@ -1,30 +1,34 @@ -#include <generator/borders_generator.hpp> -#include <coding/file_name_utils.hpp> -#include <generator/borders_loader.hpp> -#include <regex> -#include <fstream> -#include <unordered_set> -#include <platform/platform.hpp> -#include <base/timer.hpp> -#include <coding/hex.hpp> #include "track_analyzing/log_parser.hpp" + +#include "track_analyzing/exceptions.hpp" + +#include "generator/borders_generator.hpp" +#include "generator/borders_loader.hpp" + +#include "platform/platform.hpp" + +#include "coding/file_name_utils.hpp" +#include "coding/hex.hpp" + +#include "geometry/mercator.hpp" + +#include "base/timer.hpp" + #include <cstdint> -#include <geometry/mercator.hpp> +#include <fstream> +#include <regex> +#include <unordered_set> using namespace std; -using namespace tracking; +using namespace track_analyzing; namespace { vector<DataPoint> ReadDataPoints(string const & data) { string const decoded = FromHex(data); - vector<uint8_t> buffer; - for (auto c : decoded) - buffer.push_back(static_cast<uint8_t>(c)); - vector<DataPoint> points; - MemReader memReader(buffer.data(), buffer.size()); + MemReader memReader(decoded.data(), decoded.size()); ReaderSource<MemReader> src(memReader); coding::TrafficGPSEncoder::DeserializeDataPoints(1 /* version */, src, points); return points; @@ -52,11 +56,8 @@ public: routing::NumMwmId result = routing::kFakeNumMwmId; m2::RectD const rect = MercatorBounds::RectByCenterXYAndSizeInMeters(point, 1); m_mwmTree->ForEachInRect(rect, [&](routing::NumMwmId numMwmId) { - if (m2::RegionsContain(GetBorders(numMwmId), point)) - { + if (result == routing::kFakeNumMwmId && m2::RegionsContain(GetBorders(numMwmId), point)) result = numMwmId; - return; - } }); return result; @@ -75,7 +76,7 @@ private: }; } // namespace -namespace tracking +namespace track_analyzing { LogParser::LogParser(shared_ptr<routing::NumMwmIds> numMwmIds, unique_ptr<m4::Tree<routing::NumMwmId>> mwmTree, string const & dataDir) @@ -97,15 +98,15 @@ void LogParser::ParseUserTracks(string const & logFile, UserToTrack & userToTrac my::Timer timer; std::ifstream stream(logFile); - CHECK(stream.is_open(), ("Can't open file", logFile)); + if (!stream) + MYTHROW(MessageException, ("Can't open file", logFile, "to parse tracks")); - std::regex const base_regex( - ".*(DataV0|CurrentData)\\s+aloha_id\\s*:\\s*(\\S+)\\s+.*\\|(\\w+)\\|"); + std::regex const base_regex(R"(.*(DataV0|CurrentData)\s+aloha_id\s*:\s*(\S+)\s+.*\|(\w+)\|)"); std::unordered_set<string> usersWithOldVersion; - size_t linesCount = 0; + uint64_t linesCount = 0; size_t pointsCount = 0; - for (string line; getline(stream, line);) + for (string line; getline(stream, line); ++linesCount) { std::smatch base_match; if (!std::regex_match(line, base_match, base_regex)) @@ -127,10 +128,9 @@ void LogParser::ParseUserTracks(string const & logFile, UserToTrack & userToTrac if (!packet.empty()) { Track & track = userToTrack[userId]; - track.insert(track.end(), packet.begin(), packet.end()); + track.insert(track.end(), packet.cbegin(), packet.cend()); } - ++linesCount; pointsCount += packet.size(); }; @@ -146,10 +146,10 @@ void LogParser::SplitIntoMwms(UserToTrack const & userToTrack, MwmToTracks & mwm PointToMwmId const pointToMwmId(m_mwmTree, *m_numMwmIds, m_dataDir); - for (auto & it : userToTrack) + for (auto const & kv : userToTrack) { - string const & user = it.first; - Track const & track = it.second; + string const & user = kv.first; + Track const & track = kv.second; routing::NumMwmId mwmId = routing::kFakeNumMwmId; for (DataPoint const & point : track) @@ -162,7 +162,7 @@ void LogParser::SplitIntoMwms(UserToTrack const & userToTrack, MwmToTracks & mwm } } - LOG(LINFO, ("Data was splitted into", mwmToTracks.size(), "mwms, elapsed:", - timer.ElapsedSeconds(), "seconds")); + LOG(LINFO, ("Data was split into", mwmToTracks.size(), "mwms, elapsed:", timer.ElapsedSeconds(), + "seconds")); } -} // namespace tracking +} // namespace track_analyzing diff --git a/track_analyzing/log_parser.hpp b/track_analyzing/log_parser.hpp index 63df4fda87..de9c38884c 100644 --- a/track_analyzing/log_parser.hpp +++ b/track_analyzing/log_parser.hpp @@ -8,10 +8,8 @@ #include <memory> #include <string> -#include <unordered_map> -#include <vector> -namespace tracking +namespace track_analyzing { class LogParser final { @@ -29,4 +27,4 @@ private: std::shared_ptr<m4::Tree<routing::NumMwmId>> m_mwmTree; std::string const m_dataDir; }; -} // namespace tracking +} // namespace track_analyzing diff --git a/track_analyzing/serialization.hpp b/track_analyzing/serialization.hpp index f0d0b87865..6408be458c 100644 --- a/track_analyzing/serialization.hpp +++ b/track_analyzing/serialization.hpp @@ -21,13 +21,13 @@ #include <memory> #include <vector> -namespace tracking +namespace track_analyzing { class MwmToMatchedTracksSerializer final { public: MwmToMatchedTracksSerializer(std::shared_ptr<routing::NumMwmIds> numMwmIds) - : m_numMwmIds(numMwmIds) + : m_numMwmIds(move(numMwmIds)) { } @@ -61,6 +61,7 @@ public: Serialize(point.GetSegment(), sink); std::vector<DataPoint> dataPoints; + dataPoints.reserve(track.size()); for (MatchedTrackPoint const & point : track) dataPoints.push_back(point.GetDataPoint()); @@ -126,6 +127,7 @@ public: CHECK_EQUAL(numSegments, dataPoints.size(), ("mwm:", mwmName, "user:", user)); MatchedTrack & track = tracks[iTrack]; + track.reserve(numSegments); for (size_t iPoint = 0; iPoint < numSegments; ++iPoint) track.emplace_back(dataPoints[iPoint], segments[iPoint]); @@ -135,8 +137,8 @@ public: } private: - static constexpr uint8_t kForward = 0; - static constexpr uint8_t kBackward = 1; + static uint8_t constexpr kForward = 0; + static uint8_t constexpr kBackward = 1; template <class Sink> static void WriteSize(Sink & sink, size_t size) @@ -160,7 +162,7 @@ private: } template <class Source> - void Deserialize(routing::NumMwmId numMwmId, routing::Segment & segment, Source & src) + static void Deserialize(routing::NumMwmId numMwmId, routing::Segment & segment, Source & src) { auto const featureId = ReadPrimitiveFromSource<uint32_t>(src); auto const segmentIdx = ReadPrimitiveFromSource<uint32_t>(src); @@ -170,4 +172,4 @@ private: std::shared_ptr<routing::NumMwmIds> m_numMwmIds; }; -} // namespace tracking +} // namespace track_analyzing diff --git a/track_analyzing/track.cpp b/track_analyzing/track.cpp new file mode 100644 index 0000000000..fa924eeefc --- /dev/null +++ b/track_analyzing/track.cpp @@ -0,0 +1,29 @@ +#include "track_analyzing/track.hpp" + +namespace track_analyzing +{ +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 +{ + if (duration < m_minDuration) + return false; + + if (length < m_minLength) + return false; + + if (speed < m_minSpeed || speed > m_maxSpeed) + return false; + + return !(m_ignoreTraffic && hasTrafficPoints); +} +} // namespace track_analyzing diff --git a/track_analyzing/track.hpp b/track_analyzing/track.hpp index cf9acd9b89..316a2e15c4 100644 --- a/track_analyzing/track.hpp +++ b/track_analyzing/track.hpp @@ -9,7 +9,7 @@ #include <unordered_map> #include <vector> -namespace tracking +namespace track_analyzing { using DataPoint = coding::TrafficGPSEncoder::DataPoint; using Track = std::vector<DataPoint>; @@ -28,8 +28,8 @@ public: routing::Segment const & GetSegment() const { return m_segment; } private: - DataPoint m_dataPoint; - routing::Segment m_segment; + DataPoint const m_dataPoint; + routing::Segment const m_segment; }; using MatchedTrack = std::vector<MatchedTrackPoint>; @@ -40,34 +40,15 @@ class TrackFilter final { public: 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 Passes(uint64_t duration, double length, double speed, bool hasTrafficPoints) const - { - if (duration < m_minDuration) - return false; + bool ignoreTraffic); - if (length < m_minLength) - return false; - - if (speed < m_minSpeed || speed > m_maxSpeed) - return false; - - return !(m_ignoreTraffic && hasTrafficPoints); - } + bool Passes(uint64_t duration, double length, double speed, bool hasTrafficPoints) const; private: uint64_t const m_minDuration; double const m_minLength; double const m_minSpeed; double const m_maxSpeed; - bool m_ignoreTraffic; + bool const m_ignoreTraffic; }; -} // namespace tracking +} // namespace track_analyzing diff --git a/track_analyzing/track_analyzer/CMakeLists.txt b/track_analyzing/track_analyzer/CMakeLists.txt index 83c6e0235d..106876fce5 100644 --- a/track_analyzing/track_analyzer/CMakeLists.txt +++ b/track_analyzing/track_analyzer/CMakeLists.txt @@ -42,7 +42,4 @@ omim_link_libraries( ${LIBZ} ) -find_package(Boost COMPONENTS filesystem REQUIRED) -target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES}) - link_qt5_core(${PROJECT_NAME}) diff --git a/track_analyzing/track_analyzer/cmd_cpp_track.cpp b/track_analyzing/track_analyzer/cmd_cpp_track.cpp index a072e2cebf..108ca43f8c 100644 --- a/track_analyzing/track_analyzer/cmd_cpp_track.cpp +++ b/track_analyzing/track_analyzer/cmd_cpp_track.cpp @@ -8,7 +8,7 @@ using namespace routing; using namespace std; -namespace tracking +namespace track_analyzing { void CmdCppTrack(string const & trackFile, string const & mwmName, string const & user, size_t trackIdx) @@ -21,11 +21,13 @@ void CmdCppTrack(string const & trackFile, string const & mwmName, string const MatchedTrack const & track = GetMatchedTrack(mwmToMatchedTracks, *numMwmIds, mwmName, user, trackIdx); - cout.precision(numeric_limits<double>::max_digits10); + auto const backupPrecision = cout.precision(); + cout.precision(8); for (MatchedTrackPoint const & point : track) { cout << " {" << point.GetDataPoint().m_latLon.lat << ", " << point.GetDataPoint().m_latLon.lon << "}," << endl; } + cout.precision(backupPrecision); } -} // namespace tracking +} // namespace track_analyzing diff --git a/track_analyzing/track_analyzer/cmd_match.cpp b/track_analyzing/track_analyzer/cmd_match.cpp index f196f6c422..8c903f69a0 100644 --- a/track_analyzing/track_analyzer/cmd_match.cpp +++ b/track_analyzing/track_analyzer/cmd_match.cpp @@ -23,7 +23,7 @@ using namespace routing; using namespace std; -using namespace tracking; +using namespace track_analyzing; namespace { @@ -32,55 +32,57 @@ void MatchTracks(MwmToTracks const & mwmToTracks, storage::Storage const & stora { my::Timer timer; - size_t tracksCount = 0; - size_t shortTracksCount = 0; - size_t pointsCount = 0; - size_t shortTrackPointsCount = 0; - size_t nonMatchedPointsCount = 0; - - ForTracksSortedByMwmName( - [&](string const & mwmName, UserToTrack const & userToTrack) { - auto const countryFile = platform::CountryFile(mwmName); - auto const mwmId = numMwmIds.GetId(countryFile); - TrackMatcher matcher(storage, mwmId, countryFile); - - auto & userToMatchedTracks = mwmToMatchedTracks[mwmId]; - - for (auto const & it : userToTrack) - { - auto & matchedTracks = userToMatchedTracks[it.first]; - matcher.MatchTrack(it.second, matchedTracks); - - if (matchedTracks.empty()) - userToMatchedTracks.erase(it.first); - } - - if (userToMatchedTracks.empty()) - mwmToMatchedTracks.erase(mwmId); - - tracksCount += matcher.GetTracksCount(); - shortTracksCount += matcher.GetShortTracksCount(); - pointsCount += matcher.GetPointsCount(); - shortTrackPointsCount += matcher.GetShortTrackPointsCount(); - nonMatchedPointsCount += matcher.GetNonMatchedPointsCount(); - - LOG(LINFO, (numMwmIds.GetFile(mwmId).GetName(), ", users:", userToTrack.size(), ", tracks:", - matcher.GetTracksCount(), ", short tracks:", matcher.GetShortTracksCount(), - ", points:", matcher.GetPointsCount(), ", short track points", - matcher.GetShortTrackPointsCount(), ", non matched points:", - matcher.GetNonMatchedPointsCount())); - }, - mwmToTracks, numMwmIds); + uint64_t tracksCount = 0; + uint64_t pointsCount = 0; + uint64_t nonMatchedPointsCount = 0; + + 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); + + auto & userToMatchedTracks = mwmToMatchedTracks[mwmId]; + + for (auto const & it : userToTrack) + { + string const & user = it.first; + auto & matchedTracks = userToMatchedTracks[user]; + try + { + matcher.MatchTrack(it.second, matchedTracks); + } + catch (RootException const & e) + { + LOG(LERROR, ("Can't match track for mwm:", mwmName, ", user:", user)); + LOG(LERROR, (" ", e.what())); + } + + if (matchedTracks.empty()) + userToMatchedTracks.erase(user); + } + + if (userToMatchedTracks.empty()) + mwmToMatchedTracks.erase(mwmId); + + tracksCount += matcher.GetTracksCount(); + 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())); + }; + + ForTracksSortedByMwmName(mwmToTracks, numMwmIds, processMwm); LOG(LINFO, ("Matching finished, elapsed:", timer.ElapsedSeconds(), "seconds, tracks:", tracksCount, - ", short tracks:", shortTracksCount, ", points:", pointsCount, ", short track points", - shortTrackPointsCount, ", non matched points:", nonMatchedPointsCount)); + ", points:", pointsCount, ", non matched points:", nonMatchedPointsCount)); } } // namespace -namespace tracking +namespace track_analyzing { void CmdMatch(string const & logFile, string const & trackFile) { @@ -97,7 +99,7 @@ void CmdMatch(string const & logFile, string const & trackFile) storage::CountryInfoReader::CreateCountryInfoReader(platform); unique_ptr<m4::Tree<NumMwmId>> mwmTree = MakeNumMwmTree(*numMwmIds, *countryInfoGetter); - tracking::LogParser parser(numMwmIds, move(mwmTree), dataDir); + LogParser parser(numMwmIds, move(mwmTree), dataDir); MwmToTracks mwmToTracks; parser.Parse(logFile, mwmToTracks); @@ -107,6 +109,6 @@ void CmdMatch(string const & logFile, string const & trackFile) FileWriter writer(trackFile, FileWriter::OP_WRITE_TRUNCATE); MwmToMatchedTracksSerializer serializer(numMwmIds); serializer.Serialize(mwmToMatchedTracks, writer); - LOG(LINFO, ("Matched track was saved to", trackFile)); + LOG(LINFO, ("Matched tracks were saved to", trackFile)); } -} // namespace tracking +} // namespace track_analyzing diff --git a/track_analyzing/track_analyzer/cmd_table.cpp b/track_analyzing/track_analyzer/cmd_table.cpp index fa8acddb1f..90692bf6af 100644 --- a/track_analyzing/track_analyzer/cmd_table.cpp +++ b/track_analyzing/track_analyzer/cmd_table.cpp @@ -11,6 +11,7 @@ #include "traffic/speed_groups.hpp" #include "indexer/classificator.hpp" +#include "indexer/feature_data.hpp" #include "storage/storage.hpp" @@ -20,7 +21,7 @@ using namespace routing; using namespace std; -using namespace tracking; +using namespace track_analyzing; namespace { @@ -32,21 +33,6 @@ string RoadTypeToString(uint32_t type) return classif().GetReadableObjectName(type); } -bool FeatureHasType(FeatureType const & feature, uint32_t type) -{ - bool result = false; - - feature.ForEachType([&](uint32_t featureType) { - if (featureType == type) - { - result = true; - return; - } - }); - - return result; -} - class CarModelTypes final { public: @@ -67,9 +53,10 @@ public: uint32_t GetType(FeatureType const & feature) const { + feature::TypesHolder holder(feature); for (uint32_t type : m_tags) { - if (FeatureHasType(feature, type)) + if (holder.Has(type)) return type; } @@ -137,17 +124,14 @@ private: class MoveTypeAggregator final { public: - void Add(MoveType const moveType, MatchedTrack const & track, size_t begin, size_t end, - Geometry & geometry) + void Add(MoveType const moveType, MatchedTrack::const_iterator begin, + MatchedTrack::const_iterator end, Geometry & geometry) { - CHECK_LESS_OR_EQUAL(end, track.size(), ()); - if (begin + 1 >= end) return; - uint64_t const time = - track[end - 1].GetDataPoint().m_timestamp - track[begin].GetDataPoint().m_timestamp; - double const length = CalcSubtrackLength(track, begin, end, geometry); + uint64_t const time = (end - 1)->GetDataPoint().m_timestamp - begin->GetDataPoint().m_timestamp; + double const length = CalcSubtrackLength(begin, end, geometry); m_moveInfos[moveType].Add(length, time); } @@ -167,13 +151,9 @@ public: { MoveInfo const & speedInfo = it.second; if (firstIteration) - { firstIteration = false; - } else - { out << " "; - } out << it.first.ToString() << ": " << speedInfo.GetDistance() << " / " << speedInfo.GetTime(); } @@ -207,7 +187,6 @@ private: FeatureType feature; m_featuresVector.GetVector().GetByIndex(featureId, feature); - feature.ParseTypes(); m_prevFeatureId = featureId; m_prevRoadType = m_carModelTypes.GetType(feature); @@ -221,10 +200,10 @@ private: }; } // namespace -namespace tracking +namespace track_analyzing { -void CmdTagsTable(string const & filepath, string const & trackExtension, string const & mwmFilter, - string const & userFilter) +void CmdTagsTable(string const & filepath, string const & trackExtension, StringFilter mwmFilter, + StringFilter userFilter) { cout << "mwm user track_idx start length time speed ... type: meters / seconds" << endl; @@ -232,25 +211,23 @@ void CmdTagsTable(string const & filepath, string const & trackExtension, string auto numMwmIds = CreateNumMwmIds(storage); auto processMwm = [&](string const & mwmName, UserToMatchedTracks const & userToMatchedTracks) { - if (IsFiltered(mwmFilter, mwmName)) + if (mwmFilter(mwmName)) return; shared_ptr<IVehicleModel> vehicleModel = CarModelFactory().GetVehicleModelForCountry(mwmName); - string const mwmFile = - my::JoinPath(GetPlatform().WritableDir(), to_string(storage.GetCurrentDataVersion()), - mwmName + DATA_FILE_EXTENSION); + string const mwmFile = GetCurrentVersionMwmFile(storage, mwmName); MatchedTrackPointToMoveType pointToMoveType(mwmFile); Geometry geometry(GeometryLoader::CreateFromFile(mwmFile, vehicleModel)); - for (auto uIt : userToMatchedTracks) + for (auto const & kv : userToMatchedTracks) { - string const & user = uIt.first; - if (IsFiltered(userFilter, user)) + string const & user = kv.first; + if (userFilter(user)) continue; - for (size_t trackIdx = 0; trackIdx < uIt.second.size(); ++trackIdx) + for (size_t trackIdx = 0; trackIdx < kv.second.size(); ++trackIdx) { - MatchedTrack const & track = uIt.second[trackIdx]; + MatchedTrack const & track = kv.second[trackIdx]; uint64_t const start = track.front().GetDataPoint().m_timestamp; uint64_t const timeElapsed = track.back().GetDataPoint().m_timestamp - start; double const length = CalcTrackLength(track, geometry); @@ -258,20 +235,17 @@ void CmdTagsTable(string const & filepath, string const & trackExtension, string MoveTypeAggregator aggregator; - MoveType currentType(numeric_limits<uint32_t>::max(), traffic::SpeedGroup::Count); - size_t subTrackBegin = 0; - - for (size_t i = 0; i < track.size(); ++i) + for (auto subTrackBegin = track.begin(); subTrackBegin != track.end();) { - MoveType const type = pointToMoveType.GetMoveType(track[i]); - if (type == currentType) - continue; - - aggregator.Add(currentType, track, subTrackBegin, i, geometry); - currentType = type; - subTrackBegin = i; + auto moveType = pointToMoveType.GetMoveType(*subTrackBegin); + auto subTrackEnd = subTrackBegin + 1; + while (subTrackEnd != track.end() && + pointToMoveType.GetMoveType(*subTrackEnd) == moveType) + ++subTrackEnd; + + aggregator.Add(moveType, subTrackBegin, subTrackEnd, geometry); + subTrackBegin = subTrackEnd; } - aggregator.Add(currentType, track, subTrackBegin, track.size(), geometry); cout << mwmName << " " << user << " " << trackIdx << " " << my::SecondsSinceEpochToString(start) << " " << length << " " << timeElapsed << " " @@ -282,9 +256,9 @@ void CmdTagsTable(string const & filepath, string const & trackExtension, string auto processTrack = [&](string const & filename, MwmToMatchedTracks const & mwmToMatchedTracks) { LOG(LINFO, ("Processing", filename)); - ForTracksSortedByMwmName(processMwm, mwmToMatchedTracks, *numMwmIds); + ForTracksSortedByMwmName(mwmToMatchedTracks, *numMwmIds, processMwm); }; - ForEachTrackFile(processTrack, filepath, trackExtension, numMwmIds); + ForEachTrackFile(filepath, trackExtension, numMwmIds, processTrack); } -} // namespace tracking +} // namespace track_analyzing diff --git a/track_analyzing/track_analyzer/cmd_track.cpp b/track_analyzing/track_analyzer/cmd_track.cpp index 48df1303ae..e3fc660f4e 100644 --- a/track_analyzing/track_analyzer/cmd_track.cpp +++ b/track_analyzing/track_analyzer/cmd_track.cpp @@ -20,7 +20,7 @@ using namespace routing; using namespace std; -namespace tracking +namespace track_analyzing { void CmdTrack(string const & trackFile, string const & mwmName, string const & user, size_t trackIdx) @@ -33,9 +33,7 @@ void CmdTrack(string const & trackFile, string const & mwmName, string const & u MatchedTrack const & track = GetMatchedTrack(mwmToMatchedTracks, *numMwmIds, mwmName, user, trackIdx); - string const mwmFile = - my::JoinPath(GetPlatform().WritableDir(), to_string(storage.GetCurrentDataVersion()), - mwmName + DATA_FILE_EXTENSION); + string const mwmFile = GetCurrentVersionMwmFile(storage, mwmName); shared_ptr<IVehicleModel> vehicleModel = CarModelFactory().GetVehicleModelForCountry(mwmName); FeaturesVectorTest featuresVector(FilesContainerR(make_unique<FileReader>(mwmFile))); Geometry geometry(GeometryLoader::CreateFromFile(mwmFile, vehicleModel)); @@ -74,4 +72,4 @@ void CmdTrack(string const & trackFile, string const & mwmName, string const & u ", speed:", speed)); } } -} // namespace tracking +} // namespace track_analyzing diff --git a/track_analyzing/track_analyzer/cmd_tracks.cpp b/track_analyzing/track_analyzer/cmd_tracks.cpp index 57e3da6f32..69cb29e02f 100644 --- a/track_analyzing/track_analyzer/cmd_tracks.cpp +++ b/track_analyzing/track_analyzer/cmd_tracks.cpp @@ -20,19 +20,20 @@ #include <algorithm> #include <iostream> +#include <sstream> using namespace routing; using namespace std; -using namespace tracking; +using namespace track_analyzing; namespace { class TrackStats final { public: - void AddUsers(size_t numUsers) { m_numUsers += numUsers; } - void AddTracks(size_t numTracks) { m_numTracks += numTracks; } - void AddPoints(size_t numPoints) { m_numPoints += numPoints; } + void AddUsers(uint64_t numUsers) { m_numUsers += numUsers; } + void AddTracks(uint64_t numTracks) { m_numTracks += numTracks; } + void AddPoints(uint64_t numPoints) { m_numPoints += numPoints; } void Add(TrackStats const & rhs) { @@ -51,9 +52,9 @@ public: bool IsEmpty() const { return m_numPoints == 0; } private: - size_t m_numUsers = 0; - size_t m_numTracks = 0; - size_t m_numPoints = 0; + uint64_t m_numUsers = 0; + uint64_t m_numTracks = 0; + uint64_t m_numPoints = 0; }; class ErrorStat final @@ -67,10 +68,18 @@ public: m_max = max(m_max, value); } - double GetDeviation() const + double GetStdDev() const { - CHECK_GREATER(m_count, 0.0, ()); - return std::sqrt(m_squares / m_count); + CHECK_GREATER(m_count, 1.0, ()); + return std::sqrt(m_squares / (m_count - 1.0)); + } + + string GetStdDevString() const + { + if (m_count <= 1.0) + return "N/A"; + + return to_string(GetStdDev()); } double GetMin() const { return m_min; } @@ -115,42 +124,37 @@ double EstimateDuration(MatchedTrack const & track, shared_ptr<EdgeEstimator> es } } // namespace -namespace tracking +namespace track_analyzing { -void CmdTracks(string const & filepath, string const & trackExtension, string const & mwmFilter, - string const & userFilter, TrackFilter const & filter, bool noTrackLogs, +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); - if (!mwmFilter.empty() && !numMwmIds->ContainsFile(platform::CountryFile(mwmFilter))) - MYTHROW(MessageException, ("Mwm", mwmFilter, "does not exist")); - map<string, TrackStats> mwmToStats; ErrorStat absoluteError; ErrorStat relativeError; auto processMwm = [&](string const & mwmName, UserToMatchedTracks const & userToMatchedTracks) { - if (IsFiltered(mwmFilter, mwmName)) + if (mwmFilter(mwmName)) return; TrackStats & mwmStats = mwmToStats[mwmName]; shared_ptr<IVehicleModel> vehicleModel = CarModelFactory().GetVehicleModelForCountry(mwmName); - Geometry geometry(GeometryLoader::CreateFromFile( - my::JoinPath(GetPlatform().WritableDir(), to_string(storage.GetCurrentDataVersion()), - mwmName + DATA_FILE_EXTENSION), - vehicleModel)); + Geometry geometry( + GeometryLoader::CreateFromFile(GetCurrentVersionMwmFile(storage, mwmName), vehicleModel)); - shared_ptr<EdgeEstimator> estimator = - EdgeEstimator::CreateForCar(nullptr, vehicleModel->GetMaxSpeed()); + shared_ptr<EdgeEstimator> estimator = EdgeEstimator::Create( + VehicleType::Car, vehicleModel->GetMaxSpeed(), nullptr /* trafficStash */); for (auto it : userToMatchedTracks) { string const & user = it.first; - if (IsFiltered(userFilter, user)) + if (userFilter(user)) continue; vector<MatchedTrack> const & tracks = it.second; @@ -200,15 +204,15 @@ void CmdTracks(string const & filepath, string const & trackExtension, string co auto processFile = [&](string const & filename, MwmToMatchedTracks const & mwmToMatchedTracks) { LOG(LINFO, ("Processing", filename)); - ForTracksSortedByMwmName(processMwm, mwmToMatchedTracks, *numMwmIds); + ForTracksSortedByMwmName(mwmToMatchedTracks, *numMwmIds, processMwm); }; - ForEachTrackFile(processFile, filepath, trackExtension, numMwmIds); + ForEachTrackFile(filepath, trackExtension, numMwmIds, processFile); if (!noMwmLogs) { cout << endl; - for (auto it : mwmToStats) + for (auto const & it : mwmToStats) { if (!it.second.IsEmpty()) cout << it.first << ": " << it.second.GetSummary() << endl; @@ -218,16 +222,16 @@ void CmdTracks(string const & filepath, string const & trackExtension, string co if (!noWorldLogs) { TrackStats worldStats; - for (auto it : mwmToStats) + for (auto const & it : mwmToStats) worldStats.Add(it.second); cout << endl << "World: " << worldStats.GetSummary() << endl; cout << fixed << setprecision(1) - << "Absolute error: deviation: " << absoluteError.GetDeviation() + << "Absolute error: deviation: " << absoluteError.GetStdDevString() << ", min: " << absoluteError.GetMin() << ", max: " << absoluteError.GetMax() << endl; cout << fixed << setprecision(3) - << "Relative error: deviation: " << relativeError.GetDeviation() + << "Relative error: deviation: " << relativeError.GetStdDevString() << ", min: " << relativeError.GetMin() << ", max: " << relativeError.GetMax() << endl; } } -} // namespace tracking +} // namespace track_analyzing diff --git a/track_analyzing/track_analyzer/track_analyzer.cpp b/track_analyzing/track_analyzer/track_analyzer.cpp index c73c0d8246..9b5e149d8e 100644 --- a/track_analyzing/track_analyzer/track_analyzer.cpp +++ b/track_analyzing/track_analyzer/track_analyzer.cpp @@ -1,5 +1,6 @@ #include "track_analyzing/exceptions.hpp" #include "track_analyzing/track.hpp" +#include "track_analyzing/utils.hpp" #include "indexer/classificator.hpp" #include "indexer/classificator_loader.hpp" @@ -7,14 +8,14 @@ #include "3party/gflags/src/gflags/gflags.h" using namespace std; -using namespace tracking; +using namespace track_analyzing; namespace { #define DEFINE_string_ext(name, value, description) \ DEFINE_string(name, value, description); \ \ - string const & Demand_##name() \ + string const & Checked_##name() \ { \ if (FLAGS_##name.empty()) \ MYTHROW(MessageException, (string("Specify the argument --") + #name)); \ @@ -34,39 +35,53 @@ DEFINE_bool(no_world_logs, false, "don't print world summary logs"); DEFINE_bool(no_mwm_logs, false, "don't print logs per mwm"); DEFINE_bool(no_track_logs, false, "don't print logs per track"); -DEFINE_uint64(min_duration, 5 * 60, "minimal track duration in seconds"); -DEFINE_double(min_length, 1000.0, "minimal track length in meters"); -DEFINE_double(min_speed, 15.0, "minimal track average speed in km/hour"); +DEFINE_uint64(min_duration, 5 * 60, "minimum track duration in seconds"); +DEFINE_double(min_length, 1000.0, "minimum track length in meters"); +DEFINE_double(min_speed, 15.0, "minimum track average speed in km/hour"); DEFINE_double(max_speed, 110.0, "maximum track average speed in km/hour"); DEFINE_bool(ignore_traffic, true, "ignore tracks with traffic data"); -size_t Demand_track() +size_t Checked_track() { if (FLAGS_track < 0) MYTHROW(MessageException, ("Specify the --track key")); return static_cast<size_t>(FLAGS_track); } + +StringFilter MakeFilter(string const & filter) +{ + return [&](string const & value) { + if (filter.empty()) + return false; + return value != filter; + }; +} } // namespace -namespace tracking +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); +// Match raw gps logs to tracks. void CmdMatch(string const & logFile, string const & trackFile); -void CmdTagsTable(string const & filepath, string const & trackExtension, string const & mwmFilter, - string const & userFilter); +// Print aggregated tracks to csv table. +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 CmdTracks(string const & filepath, string const & trackExtension, string const & mwmFilter, - string const & userFilter, TrackFilter const & filter, bool noTrackLogs, +// Print tracks statistics. +void CmdTracks(string const & filepath, string const & trackExtension, StringFilter mwmFilter, + StringFilter userFilter, TrackFilter const & filter, bool noTrackLogs, bool noMwmLogs, bool noWorldLogs); -} // namespace tracking +} // namespace track_analyzing int main(int argc, char ** argv) { google::ParseCommandLineFlags(&argc, &argv, true); - string const & cmd = Demand_cmd(); + string const & cmd = Checked_cmd(); classificator::Load(); classif().SortClassificator(); @@ -75,27 +90,28 @@ int main(int argc, char ** argv) { if (cmd == "match") { - string const & logFile = Demand_in(); + string const & logFile = Checked_in(); CmdMatch(logFile, FLAGS_out.empty() ? logFile + ".track" : FLAGS_out); } else if (cmd == "tracks") { TrackFilter const filter(FLAGS_min_duration, FLAGS_min_length, FLAGS_min_speed, FLAGS_max_speed, FLAGS_ignore_traffic); - CmdTracks(Demand_in(), FLAGS_track_extension, FLAGS_mwm, FLAGS_user, filter, - FLAGS_no_track_logs, FLAGS_no_mwm_logs, FLAGS_no_world_logs); + 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") { - CmdTrack(Demand_in(), Demand_mwm(), Demand_user(), Demand_track()); + CmdTrack(Checked_in(), Checked_mwm(), Checked_user(), Checked_track()); } else if (cmd == "cpptrack") { - CmdCppTrack(Demand_in(), Demand_mwm(), Demand_user(), Demand_track()); + CmdCppTrack(Checked_in(), Checked_mwm(), Checked_user(), Checked_track()); } else if (cmd == "table") { - CmdTagsTable(Demand_in(), FLAGS_track_extension, FLAGS_mwm, FLAGS_user); + CmdTagsTable(Checked_in(), FLAGS_track_extension, MakeFilter(FLAGS_mwm), + MakeFilter(FLAGS_user)); } else { diff --git a/track_analyzing/track_matcher.cpp b/track_analyzing/track_matcher.cpp index 068a2485e4..f98fd25735 100644 --- a/track_analyzing/track_matcher.cpp +++ b/track_analyzing/track_matcher.cpp @@ -1,5 +1,7 @@ #include "track_analyzing/track_matcher.hpp" +#include "track_analyzing/exceptions.hpp" + #include <routing/index_graph_loader.hpp> #include <routing_common/car_model.hpp> @@ -8,14 +10,16 @@ #include <geometry/distance.hpp> -using namespace tracking; +using namespace routing; using namespace std; +using namespace track_analyzing; namespace { +// Matching range in meters. double constexpr kMatchingRange = 20.0; -uint64_t constexpr kShortTrackDuration = 60; +// Mercator distance from segment to point in meters. double DistanceToSegment(m2::PointD const & segmentBegin, m2::PointD const & segmentEnd, m2::PointD const & point) { @@ -25,14 +29,13 @@ double DistanceToSegment(m2::PointD const & segmentBegin, m2::PointD const & seg return MercatorBounds::DistanceOnEarth(point, projectionPoint); } -double DistanceToSegment(routing::Segment const & segment, m2::PointD const & point, - routing::IndexGraph & indexGraph) +double DistanceToSegment(Segment const & segment, m2::PointD const & point, IndexGraph & indexGraph) { return DistanceToSegment(indexGraph.GetGeometry().GetPoint(segment.GetRoadPoint(false)), indexGraph.GetGeometry().GetPoint(segment.GetRoadPoint(true)), point); } -bool EdgesContain(vector<routing::SegmentEdge> const & edges, routing::Segment const & segment) +bool EdgesContain(vector<SegmentEdge> const & edges, Segment const & segment) { for (auto const & edge : edges) { @@ -44,13 +47,13 @@ bool EdgesContain(vector<routing::SegmentEdge> const & edges, routing::Segment c } } // namespace -namespace tracking +namespace track_analyzing { // TrackMatcher ------------------------------------------------------------------------------------ -TrackMatcher::TrackMatcher(storage::Storage const & storage, routing::NumMwmId mwmId, +TrackMatcher::TrackMatcher(storage::Storage const & storage, NumMwmId mwmId, platform::CountryFile const & countryFile) : m_mwmId(mwmId) - , m_vehicleModel(routing::CarModelFactory().GetVehicleModelForCountry(countryFile.GetName())) + , m_vehicleModel(CarModelFactory().GetVehicleModelForCountry(countryFile.GetName())) { auto localCountryFile = storage.GetLatestLocalFile(countryFile); CHECK(localCountryFile, ("Can't find latest country file for", countryFile.GetName())); @@ -58,13 +61,13 @@ TrackMatcher::TrackMatcher(storage::Storage const & storage, routing::NumMwmId m CHECK_EQUAL(registerResult.second, MwmSet::RegResult::Success, ("Can't register mwm", countryFile.GetName())); - m_graph = make_unique<routing::IndexGraph>( - routing::GeometryLoader::Create(m_index, registerResult.first, m_vehicleModel), - routing::EdgeEstimator::CreateForCar(nullptr /* trafficStash */, - m_vehicleModel->GetMaxSpeed())); - MwmSet::MwmHandle const handle = m_index.GetMwmHandleByCountryFile(countryFile); - routing::DeserializeIndexGraph(*handle.GetValue<MwmValue>(), *m_graph); + m_graph = make_unique<IndexGraph>( + GeometryLoader::Create(m_index, handle, m_vehicleModel, false /* loadAltitudes */), + EdgeEstimator::Create(VehicleType::Car, m_vehicleModel->GetMaxSpeed(), + nullptr /* trafficStash */)); + + DeserializeIndexGraph(*handle.GetValue<MwmValue>(), kCarMask, *m_graph); } void TrackMatcher::MatchTrack(vector<DataPoint> const & track, vector<MatchedTrack> & matchedTracks) @@ -72,6 +75,7 @@ void TrackMatcher::MatchTrack(vector<DataPoint> const & track, vector<MatchedTra m_pointsCount += track.size(); vector<Step> steps; + steps.reserve(track.size()); for (auto const & routePoint : track) steps.emplace_back(routePoint); @@ -79,7 +83,8 @@ void TrackMatcher::MatchTrack(vector<DataPoint> const & track, vector<MatchedTra { for (; trackBegin < steps.size(); ++trackBegin) { - steps[trackBegin].FillCandidatesWithNearbySegments(m_index, *m_vehicleModel, m_mwmId); + steps[trackBegin].FillCandidatesWithNearbySegments(m_index, *m_graph, *m_vehicleModel, + m_mwmId); if (steps[trackBegin].HasCandidates()) break; @@ -93,7 +98,8 @@ void TrackMatcher::MatchTrack(vector<DataPoint> const & track, vector<MatchedTra for (; trackEnd < steps.size() - 1; ++trackEnd) { Step & nextStep = steps[trackEnd + 1]; - nextStep.FillCandidates(steps[trackEnd], *m_graph); + Step const & prevStep = steps[trackEnd]; + nextStep.FillCandidates(prevStep, *m_graph); if (!nextStep.HasCandidates()) break; } @@ -105,22 +111,12 @@ void TrackMatcher::MatchTrack(vector<DataPoint> const & track, vector<MatchedTra ++m_tracksCount; - uint64_t const trackTime = - steps[trackEnd].GetDataPoint().m_timestamp - steps[trackBegin].GetDataPoint().m_timestamp; - if (trackTime < kShortTrackDuration) - { - ++m_shortTracksCount; - m_shortTrackPointsCount += trackEnd + 1 - trackBegin; - } - else + matchedTracks.push_back({}); + MatchedTrack & matchedTrack = matchedTracks.back(); + for (size_t i = trackBegin; i <= trackEnd; ++i) { - matchedTracks.push_back({}); - MatchedTrack & matchedTrack = matchedTracks.back(); - for (size_t i = trackBegin; i <= trackEnd; ++i) - { - Step const & step = steps[i]; - matchedTrack.emplace_back(step.GetDataPoint(), step.GetSegment()); - } + Step const & step = steps[i]; + matchedTrack.emplace_back(step.GetDataPoint(), step.GetSegment()); } trackBegin = trackEnd + 1; @@ -133,8 +129,10 @@ TrackMatcher::Step::Step(DataPoint const & dataPoint) { } -void TrackMatcher::Step::FillCandidatesWithNearbySegments( - Index const & index, routing::IVehicleModel const & vehicleModel, routing::NumMwmId mwmId) +void TrackMatcher::Step::FillCandidatesWithNearbySegments(Index const & index, + IndexGraph const & graph, + IVehicleModel const & vehicleModel, + NumMwmId mwmId) { index.ForEachInRect( [&](FeatureType const & ft) { @@ -155,14 +153,16 @@ void TrackMatcher::Step::FillCandidatesWithNearbySegments( DistanceToSegment(ft.GetPoint(segIdx), ft.GetPoint(segIdx + 1), m_point); if (distance < kMatchingRange) { - m_candidates.emplace_back( - routing::Segment(mwmId, ft.GetID().m_index, static_cast<uint32_t>(segIdx), true), - distance); + AddCandidate(Segment(mwmId, ft.GetID().m_index, static_cast<uint32_t>(segIdx), + true /* forward */), + distance, graph); if (!vehicleModel.IsOneWay(ft)) - m_candidates.emplace_back( - routing::Segment(mwmId, ft.GetID().m_index, static_cast<uint32_t>(segIdx), false), - distance); + { + AddCandidate(Segment(mwmId, ft.GetID().m_index, static_cast<uint32_t>(segIdx), + false /* forward */), + distance, graph); + } } } }, @@ -170,21 +170,21 @@ void TrackMatcher::Step::FillCandidatesWithNearbySegments( scales::GetUpperScale()); } -void TrackMatcher::Step::FillCandidates(Step const & previousStep, routing::IndexGraph & graph) +void TrackMatcher::Step::FillCandidates(Step const & previousStep, IndexGraph & graph) { - vector<routing::SegmentEdge> edges; + vector<SegmentEdge> edges; for (Candidate const & candidate : previousStep.m_candidates) { - routing::Segment const & segment = candidate.GetSegment(); + Segment const & segment = candidate.GetSegment(); m_candidates.emplace_back(segment, DistanceToSegment(segment, m_point, graph)); edges.clear(); - graph.GetEdgeList(segment, true, edges); + graph.GetEdgeList(segment, true /* isOutgoing */, edges); - for (routing::SegmentEdge const & edge : edges) + for (SegmentEdge const & edge : edges) { - routing::Segment const & target = edge.GetTarget(); + Segment const & target = edge.GetTarget(); if (!segment.IsInverse(target)) m_candidates.emplace_back(target, DistanceToSegment(target, m_point, graph)); } @@ -199,15 +199,15 @@ void TrackMatcher::Step::FillCandidates(Step const & previousStep, routing::Inde m_candidates.end()); } -void TrackMatcher::Step::ChooseSegment(Step const & nextStep, routing::IndexGraph & indexGraph) +void TrackMatcher::Step::ChooseSegment(Step const & nextStep, IndexGraph & indexGraph) { CHECK(!m_candidates.empty(), ()); double minDistance = numeric_limits<double>::max(); - vector<routing::SegmentEdge> edges; - indexGraph.GetEdgeList(nextStep.m_segment, false, edges); - edges.emplace_back(nextStep.m_segment, 0.0 /* weight */); + vector<SegmentEdge> edges; + indexGraph.GetEdgeList(nextStep.m_segment, false /* isOutgoing */, edges); + edges.emplace_back(nextStep.m_segment, RouteWeight(0.0)); for (Candidate const & candidate : m_candidates) { @@ -218,8 +218,8 @@ void TrackMatcher::Step::ChooseSegment(Step const & nextStep, routing::IndexGrap } } - CHECK_LESS(minDistance, numeric_limits<double>::max(), - ("Can't find previous segment for", nextStep.m_segment)); + if (minDistance == numeric_limits<double>::max()) + MYTHROW(MessageException, ("Can't find previous step for", nextStep.m_segment)); } void TrackMatcher::Step::ChooseNearestSegment() @@ -237,4 +237,11 @@ void TrackMatcher::Step::ChooseNearestSegment() } } } -} // namespace tracking + +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); +} +} // namespace track_analyzing diff --git a/track_analyzing/track_matcher.hpp b/track_analyzing/track_matcher.hpp index 376f8abd1b..8f8fab782b 100644 --- a/track_analyzing/track_matcher.hpp +++ b/track_analyzing/track_matcher.hpp @@ -16,7 +16,7 @@ #include <string> #include <vector> -namespace tracking +namespace track_analyzing { class TrackMatcher final { @@ -26,11 +26,9 @@ public: void MatchTrack(std::vector<DataPoint> const & track, std::vector<MatchedTrack> & matchedTracks); - size_t GetTracksCount() const { return m_tracksCount; } - size_t GetShortTracksCount() const { return m_shortTracksCount; } - size_t GetPointsCount() const { return m_pointsCount; } - size_t GetShortTrackPointsCount() const { return m_shortTrackPointsCount; } - size_t GetNonMatchedPointsCount() const { return m_nonMatchedPointsCount; } + uint64_t GetTracksCount() const { return m_tracksCount; } + uint64_t GetPointsCount() const { return m_pointsCount; } + uint64_t GetNonMatchedPointsCount() const { return m_nonMatchedPointsCount; } private: class Candidate final @@ -57,10 +55,8 @@ 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(Index const & index, + void FillCandidatesWithNearbySegments(Index const & index, routing::IndexGraph const & graph, routing::IVehicleModel const & vehicleModel, routing::NumMwmId mwmId); void FillCandidates(Step const & previousStep, routing::IndexGraph & graph); @@ -68,6 +64,9 @@ private: void ChooseNearestSegment(); private: + void AddCandidate(routing::Segment const & segment, double distance, + routing::IndexGraph const & graph); + DataPoint m_dataPoint; m2::PointD m_point; routing::Segment m_segment; @@ -78,10 +77,8 @@ private: Index m_index; std::shared_ptr<routing::IVehicleModel> m_vehicleModel; std::unique_ptr<routing::IndexGraph> m_graph; - size_t m_tracksCount = 0; - size_t m_shortTracksCount = 0; - size_t m_pointsCount = 0; - size_t m_shortTrackPointsCount = 0; - size_t m_nonMatchedPointsCount = 0; + uint64_t m_tracksCount = 0; + uint64_t m_pointsCount = 0; + uint64_t m_nonMatchedPointsCount = 0; }; -} // namespace tracking +} // namespace track_analyzing diff --git a/track_analyzing/utils.cpp b/track_analyzing/utils.cpp index c19d397c8e..1860f7064b 100644 --- a/track_analyzing/utils.cpp +++ b/track_analyzing/utils.cpp @@ -4,28 +4,32 @@ #include "routing/segment.hpp" +#include "platform/platform.hpp" + +#include "coding/file_name_utils.hpp" + #include <cstdint> using namespace routing; using namespace std; -namespace tracking +namespace track_analyzing { -double CalcSubtrackLength(MatchedTrack const & track, size_t begin, size_t end, Geometry & geometry) +double CalcSubtrackLength(MatchedTrack::const_iterator begin, MatchedTrack::const_iterator end, + Geometry & geometry) { - CHECK_LESS_OR_EQUAL(end, track.size(), ()); - double length = 0.0; Segment prevSegment; - for (size_t i = begin; i < end; ++i) + for (auto it = begin; it != end; ++it) { - MatchedTrackPoint const & point = track[i]; + MatchedTrackPoint const & point = *it; Segment const & segment = point.GetSegment(); if (segment != prevSegment) { - length += MercatorBounds::DistanceOnEarth(geometry.GetPoint(segment.GetRoadPoint(false)), - geometry.GetPoint(segment.GetRoadPoint(true))); + length += MercatorBounds::DistanceOnEarth( + geometry.GetPoint(segment.GetRoadPoint(false /* front */)), + geometry.GetPoint(segment.GetRoadPoint(true /* front */))); prevSegment = segment; } } @@ -35,7 +39,7 @@ double CalcSubtrackLength(MatchedTrack const & track, size_t begin, size_t end, double CalcTrackLength(MatchedTrack const & track, Geometry & geometry) { - return CalcSubtrackLength(track, 0, track.size(), geometry); + return CalcSubtrackLength(track.begin(), track.end(), geometry); } double CalcSpeedKMpH(double meters, uint64_t secondsElapsed) @@ -45,11 +49,6 @@ double CalcSpeedKMpH(double meters, uint64_t secondsElapsed) return kMPS2KMPH * meters / static_cast<double>(secondsElapsed); } -bool IsFiltered(string const & argument, string const & variable) -{ - return !argument.empty() && variable != argument; -} - void ReadTracks(shared_ptr<NumMwmIds> numMwmIds, string const & filename, MwmToMatchedTracks & mwmToMatchedTracks) { @@ -71,7 +70,7 @@ MatchedTrack const & GetMatchedTrack(MwmToMatchedTracks const & mwmToMatchedTrac auto mIt = mwmToMatchedTracks.find(numMwmId); if (mIt == mwmToMatchedTracks.cend()) - MYTHROW(MessageException, ("There is no tracks for mwm", mwmName)); + MYTHROW(MessageException, ("There are no tracks for mwm", mwmName)); UserToMatchedTracks const & userToMatchedTracks = mIt->second; @@ -89,4 +88,53 @@ MatchedTrack const & GetMatchedTrack(MwmToMatchedTracks const & mwmToMatchedTrac return tracks[trackIdx]; } -} // namespace tracking
\ No newline at end of file + +std::string GetCurrentVersionMwmFile(storage::Storage const & storage, std::string const & mwmName) +{ + return my::JoinPath(GetPlatform().WritableDir(), to_string(storage.GetCurrentDataVersion()), + mwmName + DATA_FILE_EXTENSION); +} + +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::FILE_TYPE_UNKNOWN; + Platform::EError const result = Platform::GetFileType(filepath, fileType); + + if (result == Platform::ERR_FILE_DOES_NOT_EXIST) + MYTHROW(MessageException, ("File doesn't exist", filepath)); + + if (result != Platform::ERR_OK) + MYTHROW(MessageException, ("Can't get file type for", filepath, "result:", result)); + + if (fileType == Platform::FILE_TYPE_REGULAR) + { + MwmToMatchedTracks mwmToMatchedTracks; + ReadTracks(numMwmIds, filepath, mwmToMatchedTracks); + toDo(filepath, mwmToMatchedTracks); + return; + } + + if (fileType == Platform::FILE_TYPE_DIRECTORY) + { + Platform::FilesList filesList; + Platform::GetFilesRecursively(filepath, filesList); + + for (string const & file : filesList) + { + if (my::GetFileExtension(file) != extension) + continue; + + MwmToMatchedTracks mwmToMatchedTracks; + ReadTracks(numMwmIds, file, mwmToMatchedTracks); + toDo(file, mwmToMatchedTracks); + } + + return; + } + + MYTHROW(MessageException, (filepath, "is neither a regular file nor a directory't exist")); +} +} // namespace track_analyzing diff --git a/track_analyzing/utils.hpp b/track_analyzing/utils.hpp index b10f180d81..a1b7d1391e 100644 --- a/track_analyzing/utils.hpp +++ b/track_analyzing/utils.hpp @@ -6,30 +6,35 @@ #include "routing/geometry.hpp" #include "routing/num_mwm_id.hpp" -#include <boost/filesystem.hpp> +#include "storage/storage.hpp" + +#include "platform/platform.hpp" #include <cstdint> +#include <functional> #include <memory> #include <string> #include <vector> -namespace tracking +namespace track_analyzing { -double CalcSubtrackLength(MatchedTrack const & track, size_t begin, size_t end, +using StringFilter = std::function<bool(std::string const &)>; + +double CalcSubtrackLength(MatchedTrack::const_iterator begin, MatchedTrack::const_iterator end, routing::Geometry & geometry); double CalcTrackLength(MatchedTrack const & track, routing::Geometry & geometry); double CalcSpeedKMpH(double meters, uint64_t secondsElapsed); -bool IsFiltered(std::string const & argument, std::string const & variable); 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); +std::string GetCurrentVersionMwmFile(storage::Storage const & storage, std::string const & mwmName); template <typename MwmToTracks, typename ToDo> -void ForTracksSortedByMwmName(ToDo && toDo, MwmToTracks const & mwmToTracks, - routing::NumMwmIds const & numMwmIds) +void ForTracksSortedByMwmName(MwmToTracks const & mwmToTracks, routing::NumMwmIds const & numMwmIds, + ToDo && toDo) { std::vector<std::string> mwmNames; mwmNames.reserve(mwmToTracks.size()); @@ -46,41 +51,8 @@ void ForTracksSortedByMwmName(ToDo && toDo, MwmToTracks const & mwmToTracks, } } -template <typename ToDo> -void ForEachTrackFile(ToDo && toDo, std::string const & filepath, std::string const & extension, - shared_ptr<routing::NumMwmIds> numMwmIds) -{ - if (!boost::filesystem::exists(filepath.c_str())) - MYTHROW(MessageException, ("File doesn't exist", filepath)); - - if (boost::filesystem::is_regular(filepath)) - { - MwmToMatchedTracks mwmToMatchedTracks; - ReadTracks(numMwmIds, filepath, mwmToMatchedTracks); - toDo(filepath, mwmToMatchedTracks); - return; - } - - if (boost::filesystem::is_directory(filepath)) - { - for (boost::filesystem::recursive_directory_iterator it(filepath.c_str()), end; it != end; ++it) - { - boost::filesystem::path const & path = it->path(); - if (!boost::filesystem::is_regular(path)) - continue; - - if (path.extension() != extension) - continue; - - MwmToMatchedTracks mwmToMatchedTracks; - string const & filename = path.string(); - ReadTracks(numMwmIds, filename, mwmToMatchedTracks); - toDo(filename, mwmToMatchedTracks); - } - - return; - } - - MYTHROW(MessageException, (filepath, "is neither a regular file nor a directory't exist")); -} -} // namespace tracking +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); +} // namespace track_analyzing |