| 123 | } |
| 124 | |
| 125 | void CmdTracks(string const & filepath, string const & trackExtension, StringFilter mwmFilter, StringFilter userFilter, |
| 126 | TrackFilter const & filter, bool noTrackLogs, bool noMwmLogs, bool noWorldLogs) |
| 127 | { |
| 128 | storage::Storage storage; |
| 129 | auto numMwmIds = CreateNumMwmIds(storage); |
| 130 | |
| 131 | map<string, TrackStats> mwmToStats; |
| 132 | ErrorStat absoluteError; |
| 133 | ErrorStat relativeError; |
| 134 | |
| 135 | auto processMwm = [&](string const & mwmName, UserToMatchedTracks const & userToMatchedTracks) |
| 136 | { |
| 137 | if (mwmFilter(mwmName)) |
| 138 | return; |
| 139 | |
| 140 | TrackStats & mwmStats = mwmToStats[mwmName]; |
| 141 | |
| 142 | shared_ptr<VehicleModelInterface> vehicleModel = CarModelFactory({}).GetVehicleModelForCountry(mwmName); |
| 143 | |
| 144 | Geometry geometry(GeometryLoader::CreateFromFile(GetCurrentVersionMwmFile(storage, mwmName), vehicleModel)); |
| 145 | |
| 146 | shared_ptr<EdgeEstimator> estimator = EdgeEstimator::Create( |
| 147 | VehicleType::Car, *vehicleModel, nullptr /* trafficStash */, nullptr /* dataSource */, nullptr /* numMwmIds */); |
| 148 | |
| 149 | for (auto const & it : userToMatchedTracks) |
| 150 | { |
| 151 | string const & user = it.first; |
| 152 | if (userFilter(user)) |
| 153 | continue; |
| 154 | |
| 155 | vector<MatchedTrack> const & tracks = it.second; |
| 156 | if (!noTrackLogs) |
| 157 | cout << mwmName << ", user: " << user << endl; |
| 158 | |
| 159 | bool thereAreUnfilteredTracks = false; |
| 160 | for (MatchedTrack const & track : tracks) |
| 161 | { |
| 162 | DataPoint const & start = track.front().GetDataPoint(); |
| 163 | DataPoint const & finish = track.back().GetDataPoint(); |
| 164 | |
| 165 | double const length = CalcTrackLength(track, geometry); |
| 166 | uint64_t const duration = finish.m_timestamp - start.m_timestamp; |
| 167 | double const speed = CalcSpeedKMpH(length, duration); |
| 168 | bool const hasTrafficPoints = TrackHasTrafficPoints(track); |
| 169 | |
| 170 | if (!filter.Passes(duration, length, speed, hasTrafficPoints)) |
| 171 | continue; |
| 172 | |
| 173 | double const estimatedDuration = EstimateDuration(track, estimator, geometry); |
| 174 | double const timeError = estimatedDuration - static_cast<double>(duration); |
| 175 | |
| 176 | if (!noTrackLogs) |
| 177 | { |
| 178 | cout << fixed << setprecision(1) << " points: " << track.size() << ", length: " << length |
| 179 | << ", duration: " << duration << ", estimated duration: " << estimatedDuration << ", speed: " << speed |
| 180 | << ", traffic: " << hasTrafficPoints |
| 181 | << ", departure: " << base::SecondsSinceEpochToString(start.m_timestamp) |
| 182 | << ", arrival: " << base::SecondsSinceEpochToString(finish.m_timestamp) |
no test coverage detected