New version of gps track filter

This commit is contained in:
Constantin Shalnev 2015-12-17 14:32:47 +03:00
parent 164d2f18e7
commit 2fca519d21
2 changed files with 41 additions and 16 deletions

View file

@ -10,7 +10,7 @@ namespace
char const kMinHorizontalAccuracyKey[] = "GpsTrackingMinAccuracy";
// Minimal horizontal accuracy is required to skip 'bad' points.
double constexpr kMinHorizontalAccuracyMeters = 50;
double constexpr kMinHorizontalAccuracyMeters = 250;
// Required for points decimation to reduce number of close points.
double constexpr kClosePointDistanceMeters = 15;
@ -30,8 +30,7 @@ void GpsTrackFilter::StoreMinHorizontalAccuracy(double value)
GpsTrackFilter::GpsTrackFilter()
: m_minAccuracy(kMinHorizontalAccuracyMeters)
, m_lastLl(0, 0)
, m_hasLastLl(false)
, m_hasLastInfo(false)
{
Settings::Get(kMinHorizontalAccuracyKey, m_minAccuracy);
}
@ -39,25 +38,51 @@ GpsTrackFilter::GpsTrackFilter()
void GpsTrackFilter::Process(vector<location::GpsInfo> const & inPoints,
vector<location::GpsTrackInfo> & outPoints)
{
// Very simple initial implementation of filter.
// Further, it is going to be improved.
outPoints.reserve(inPoints.size());
for (auto const & originPt : inPoints)
for (location::GpsInfo const & currInfo : inPoints)
{
// Filter point by accuracy
if (m_minAccuracy > 0 && originPt.m_horizontalAccuracy > m_minAccuracy)
if (!m_hasLastInfo)
{
m_hasLastInfo = true;
m_lastInfo = currInfo;
outPoints.emplace_back(currInfo);
continue;
}
// Filter points which happens earlier than first point
if (currInfo.m_timestamp <= m_lastInfo.m_timestamp)
continue;
// Distance in meters between last and current point is, meters:
double const distance = ms::DistanceOnEarth(m_lastInfo.m_latitude, m_lastInfo.m_longitude,
currInfo.m_latitude, currInfo.m_longitude);
// Filter point by close distance
ms::LatLon const ll(originPt.m_latitude, originPt.m_longitude);
if (m_hasLastLl && ms::DistanceOnEarth(m_lastLl, ll) < kClosePointDistanceMeters)
if (distance < kClosePointDistanceMeters)
continue;
m_lastLl = ll;
m_hasLastLl = true;
// Filter point if accuracy areas are intersected
if (distance < m_lastInfo.m_horizontalAccuracy && distance < currInfo.m_horizontalAccuracy)
continue;
outPoints.emplace_back(originPt);
// Filter by point accuracy
if (currInfo.m_horizontalAccuracy > m_minAccuracy)
continue;
// Time elapsed since last info is, sec:
double const elapsedTime = currInfo.m_timestamp - m_lastInfo.m_speed;
// Prevent jumping between wifi points
// We use following heuristics: if suddenly point jumps over long
// distance in short time then we skip point
if (m_lastInfo.m_speed == 0 && currInfo.m_speed == 0)
{
if (distance > 25 && elapsedTime < 10)
continue; // we guess it is jump between wifi points
}
m_lastInfo = currInfo;
outPoints.emplace_back(currInfo);
}
}

View file

@ -37,7 +37,7 @@ public:
private:
double m_minAccuracy;
ms::LatLon m_lastLl;
bool m_hasLastLl;
location::GpsInfo m_lastInfo;
bool m_hasLastInfo;
};