Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Zolotarev <deathbaba@gmail.com>2011-10-21 19:39:00 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:26:32 +0300
commit946bf7b727cce9dbc8a0c1b0f7f7ddec2d2d16cb (patch)
tree1750b08be8882e1d656ca42253085b3fc7909230 /platform/location_service.cpp
parent43a0bd87f5856a303d552ca895dd0fea72a1ecda (diff)
[qt][ios] Refactored location manager
Diffstat (limited to 'platform/location_service.cpp')
-rw-r--r--platform/location_service.cpp116
1 files changed, 116 insertions, 0 deletions
diff --git a/platform/location_service.cpp b/platform/location_service.cpp
new file mode 100644
index 0000000000..9ecd552b7c
--- /dev/null
+++ b/platform/location_service.cpp
@@ -0,0 +1,116 @@
+#include "location_service.hpp"
+
+#include "../std/target_os.hpp"
+#include "../std/vector.hpp"
+#include "../std/ctime.hpp"
+
+namespace
+{
+
+static double ApproxDistanceSquareInMetres(double lat1, double lon1, double lat2, double lon2)
+{
+ double const m1 = (lat1 - lat2) / 111111.;
+ double const m2 = (lon1 - lon2) / 111111.;
+ return m1 * m1 + m2 * m2;
+}
+
+/// Chooses most accurate data from different position services
+class PositionFilter
+{
+ location::GpsInfo * m_prevLocation;
+public:
+ PositionFilter() : m_prevLocation(NULL) {}
+ ~PositionFilter() { delete m_prevLocation; }
+ /// @return true if location should be sent to observers
+ bool Passes(location::GpsInfo const & newLocation)
+ {
+ if (time(NULL) - newLocation.m_timestamp > location::POSITION_TIMEOUT_SECONDS)
+ return false;
+
+ bool passes = true;
+ if (m_prevLocation)
+ {
+ if (newLocation.m_timestamp < m_prevLocation->m_timestamp)
+ passes = false;
+ else if (newLocation.m_source != m_prevLocation->m_source
+ && newLocation.m_horizontalAccuracy > m_prevLocation->m_horizontalAccuracy
+ && ApproxDistanceSquareInMetres(newLocation.m_latitude,
+ newLocation.m_longitude,
+ m_prevLocation->m_latitude,
+ m_prevLocation->m_longitude)
+ > newLocation.m_horizontalAccuracy * newLocation.m_horizontalAccuracy)
+ passes = false;
+ }
+ else
+ m_prevLocation = new location::GpsInfo(newLocation);
+ return passes;
+ }
+};
+
+} // namespace
+
+extern "C" location::LocationService * CreateAppleLocationService(location::LocationObserver &);
+extern "C" location::LocationService * CreateWiFiLocationService(location::LocationObserver &);
+
+namespace location
+{
+ class DesktopLocationService : public LocationService, public LocationObserver
+ {
+ vector<LocationService *> m_services;
+ PositionFilter m_filter;
+ bool m_reportFirstEvent;
+
+ virtual void OnLocationStatusChanged(location::TLocationStatus newStatus)
+ {
+ m_observer.OnLocationStatusChanged(newStatus);
+ }
+
+ virtual void OnGpsUpdated(GpsInfo const & info)
+ {
+ if (m_reportFirstEvent)
+ {
+ m_observer.OnLocationStatusChanged(location::EFirstEvent);
+ m_reportFirstEvent = false;
+ }
+ if (m_filter.Passes(info))
+ m_observer.OnGpsUpdated(info);
+ }
+
+ public:
+ DesktopLocationService(LocationObserver & observer)
+ : LocationService(observer), m_reportFirstEvent(true)
+ {
+#if defined(OMIM_OS_MAC)
+ m_services.push_back(CreateAppleLocationService(*this));
+#endif
+
+#if defined(OMIM_OS_DESKTOP)
+ m_services.push_back(CreateWiFiLocationService(*this));
+#endif
+ }
+
+ virtual ~DesktopLocationService()
+ {
+ for (size_t i = 0; i < m_services.size(); ++i)
+ delete m_services[i];
+ }
+
+ virtual void Start()
+ {
+ for (size_t i = 0; i < m_services.size(); ++i)
+ m_services[i]->Start();
+ }
+
+ virtual void Stop()
+ {
+ for (size_t i = 0; i < m_services.size(); ++i)
+ m_services[i]->Stop();
+ m_reportFirstEvent = true;
+ }
+ };
+}
+
+location::LocationService * CreateDesktopLocationService(location::LocationObserver & observer)
+{
+ return new location::DesktopLocationService(observer);
+}