forked from organicmaps/organicmaps
New version of gps track filter
This commit is contained in:
parent
164d2f18e7
commit
2fca519d21
2 changed files with 41 additions and 16 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ public:
|
|||
|
||||
private:
|
||||
double m_minAccuracy;
|
||||
ms::LatLon m_lastLl;
|
||||
bool m_hasLastLl;
|
||||
location::GpsInfo m_lastInfo;
|
||||
bool m_hasLastInfo;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue