diff options
author | Alex Zolotarev <deathbaba@gmail.com> | 2011-10-21 19:39:00 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:26:32 +0300 |
commit | 946bf7b727cce9dbc8a0c1b0f7f7ddec2d2d16cb (patch) | |
tree | 1750b08be8882e1d656ca42253085b3fc7909230 /platform | |
parent | 43a0bd87f5856a303d552ca895dd0fea72a1ecda (diff) |
[qt][ios] Refactored location manager
Diffstat (limited to 'platform')
-rw-r--r-- | platform/apple_location_service.mm | 131 | ||||
-rw-r--r-- | platform/location.hpp | 71 | ||||
-rw-r--r-- | platform/location_service.cpp (renamed from platform/location_manager.cpp) | 66 | ||||
-rw-r--r-- | platform/location_service.hpp | 30 | ||||
-rw-r--r-- | platform/platform.pro | 14 | ||||
-rw-r--r-- | platform/wifi_location_service.cpp | 17 |
6 files changed, 129 insertions, 200 deletions
diff --git a/platform/apple_location_service.mm b/platform/apple_location_service.mm index 24ddc14bb8..4a28b14385 100644 --- a/platform/apple_location_service.mm +++ b/platform/apple_location_service.mm @@ -1,4 +1,4 @@ -#include "location.hpp" +#include "location_service.hpp" #include "../std/target_os.hpp" @@ -23,89 +23,60 @@ class AppleLocationService : public LocationService CLLocationManager * m_locationManager; public: - AppleLocationService() + AppleLocationService(LocationObserver & observer) : LocationService(observer) { m_objCppWrapper = [[LocationManagerWrapper alloc] initWithService:this]; m_locationManager = [[CLLocationManager alloc] init]; m_locationManager.delegate = m_objCppWrapper; + m_locationManager.desiredAccuracy = kCLLocationAccuracyBest; + m_locationManager.purpose = @"Location services are needed to display your current position on the map."; } - ~AppleLocationService() + virtual ~AppleLocationService() { [m_locationManager release]; [m_objCppWrapper release]; } - void OnLocationUpdate(GpsInfo & newLocation) + void OnLocationUpdate(GpsInfo const & info) { - NotifyGpsObserver(newLocation); + m_observer.OnGpsUpdated(info); } - void OnHeadingUpdate(CompassInfo & newHeading) + void OnDeniedError() { - NotifyCompassObserver(newHeading); + m_observer.OnLocationStatusChanged(location::EDisabledByUser); } -// virtual bool IsServiceSupported() -// { -// // Mac OS 10.6+ and iOS 4.0+ support this definitely -// return true; -// } - -// virtual bool IsServiceEnabled() -// { -// return [CLLocationManager locationServicesEnabled]; -// } - -// virtual bool IsCompassAvailable() -// { -//#ifdef OMIM_OS_MAC -// return false; -//#else // iOS 4.0+ have it -// return [CLLocationManager headingAvailable]; -//#endif -// } - - virtual void StartUpdate(bool useAccurateMode) + virtual void Start() { if (![CLLocationManager locationServicesEnabled]) { - GpsInfo info; - info.m_status = EDisabledByUser; - info.m_source = location::EAppleNative; - info.m_timestamp = [[NSDate date] timeIntervalSince1970]; - NotifyGpsObserver(info); + // @TODO correctly handle situation in GUI when wifi is working and native is disabled + // m_observer.OnLocationStatusChanged(location::ENotSupported); } else { - if (useAccurateMode) - m_locationManager.desiredAccuracy = kCLLocationAccuracyBest; - else - m_locationManager.desiredAccuracy = ROUGH_ACCURACY; - [m_locationManager startUpdatingLocation]; - // enable compass -#ifdef OMIM_OS_IPHONE - if ([CLLocationManager headingAvailable]) + switch([CLLocationManager authorizationStatus]) { - m_locationManager.headingFilter = 1.0; - [m_locationManager startUpdatingHeading]; + case kCLAuthorizationStatusAuthorized: + case kCLAuthorizationStatusNotDetermined: + [m_locationManager startUpdatingLocation]; + m_observer.OnLocationStatusChanged(location::EStarted); + break; + case kCLAuthorizationStatusRestricted: + case kCLAuthorizationStatusDenied: + // @TODO correctly handle situation in GUI when wifi is working and native is disabled + //m_observer.OnLocationStatusChanged(location::EDisabledByUser); + break; } -#endif } } - virtual void StopUpdate() + virtual void Stop() { -#ifdef OMIM_OS_IPHONE - if ([CLLocationManager headingAvailable]) - [m_locationManager stopUpdatingHeading]; -#endif [m_locationManager stopUpdatingLocation]; - } - - bool IsAccurateMode() const - { - return m_locationManager.desiredAccuracy == kCLLocationAccuracyBest; + m_observer.OnLocationStatusChanged(location::EStopped); } }; @@ -113,29 +84,22 @@ public: - (id)initWithService:(AppleLocationService *) service { - self = [super init]; - if (self) { + if (self = [super init]) m_service = service; - } return self; } -- (void)dealloc -{ - [super dealloc]; -} - + (void)location:(CLLocation *)location toGpsInfo:(GpsInfo &) info { - info.m_altitude = location.altitude; - info.m_course = location.course; - info.m_speed = location.speed; info.m_horizontalAccuracy = location.horizontalAccuracy; - info.m_verticalAccuracy = location.verticalAccuracy; info.m_latitude = location.coordinate.latitude; info.m_longitude = location.coordinate.longitude; info.m_timestamp = [location.timestamp timeIntervalSince1970]; info.m_source = location::EAppleNative; + //info.m_verticalAccuracy = location.verticalAccuracy; + //info.m_altitude = location.altitude; + //info.m_course = location.course; + //info.m_speed = location.speed; } - (void)locationManager:(CLLocationManager *)manager @@ -144,49 +108,20 @@ public: { GpsInfo newInfo; [LocationManagerWrapper location:newLocation toGpsInfo:newInfo]; - newInfo.m_status = m_service->IsAccurateMode() ? EAccurateMode : ERoughMode; m_service->OnLocationUpdate(newInfo); } -#ifdef OMIM_OS_IPHONE -- (void)locationManager:(CLLocationManager *)manager - didUpdateHeading:(CLHeading *)newHeading -{ - CompassInfo newInfo; - newInfo.m_magneticHeading = newHeading.magneticHeading; - newInfo.m_trueHeading = newHeading.trueHeading; - newInfo.m_accuracy = newHeading.headingAccuracy; - newInfo.m_x = newHeading.x; - newInfo.m_y = newHeading.y; - newInfo.m_z = newHeading.z; - newInfo.m_timestamp = [newHeading.timestamp timeIntervalSince1970]; - m_service->OnHeadingUpdate(newInfo); -} -#endif - - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog(@"locationManager failed with error: %ld, %@", error.code, error.description); if (error.code == kCLErrorDenied) - { - GpsInfo info; - info.m_status = EDisabledByUser; - info.m_source = location::EAppleNative; - info.m_timestamp = [[NSDate date] timeIntervalSince1970]; - m_service->OnLocationUpdate(info); - } -} - -// Display compass calibration dialog automatically -- (BOOL)locationManagerShouldDisplayHeadingCalibration:(CLLocationManager *)manager -{ - return YES; + m_service->OnDeniedError(); } @end -location::LocationService * CreateAppleLocationService() +extern "C" location::LocationService * CreateAppleLocationService(LocationObserver & observer) { - return new AppleLocationService(); + return new AppleLocationService(observer); } diff --git a/platform/location.hpp b/platform/location.hpp index 76008bf526..7342298854 100644 --- a/platform/location.hpp +++ b/platform/location.hpp @@ -11,11 +11,13 @@ namespace location enum TLocationStatus { - ENotSupported, //!< GpsInfo fields are not valid with this value - EDisabledByUser, //!< GpsInfo fields are not valid with this value - EAccurateMode, - ERoughMode //!< in this mode compass is turned off + EStopped, + EStarted, + EFirstEvent, //!< Sent when first valid coorinate is received + ENotSupported, + EDisabledByUser }; + enum TLocationSource { EAppleNative, @@ -28,15 +30,14 @@ namespace location { public: TLocationSource m_source; - TLocationStatus m_status; double m_timestamp; //!< seconds from 1st Jan 1970 double m_latitude; //!< degrees double m_longitude; //!< degrees double m_horizontalAccuracy; //!< metres - double m_altitude; //!< metres - double m_verticalAccuracy; //!< metres - double m_course; //!< positive degrees from the true North - double m_speed; //!< metres per second +// double m_altitude; //!< metres +// double m_verticalAccuracy; //!< metres +// double m_course; //!< positive degrees from the true North +// double m_speed; //!< metres per second }; /// @note always check m_status before using this structure @@ -47,52 +48,8 @@ namespace location double m_magneticHeading; //!< positive degrees from the magnetic North double m_trueHeading; //!< positive degrees from the true North double m_accuracy; //!< offset from magnetic to true North - int m_x; - int m_y; - int m_z; +// int m_x; +// int m_y; +// int m_z; }; - - typedef function<void (GpsInfo const &)> TGpsCallback; - typedef function<void (CompassInfo const &)> TCompassCallback; - - class LocationService - { - TGpsCallback m_gpsObserver; - TCompassCallback m_compassObserver; - - protected: - void NotifyGpsObserver(GpsInfo const & info) - { - if (m_gpsObserver) - m_gpsObserver(info); - } - void NotifyCompassObserver(CompassInfo const & info) - { - if (m_compassObserver) - m_compassObserver(info); - } - - public: - virtual ~LocationService() {} - - void SetGpsObserver(TGpsCallback observer) - { - m_gpsObserver = observer; - } - - void SetCompassObserver(TCompassCallback observer) - { - m_compassObserver = observer; - } - - /// to change active accuracy mode just call it again - /// @note also enables compass if it's available - virtual void StartUpdate(bool useAccurateMode) = 0; - virtual void StopUpdate() = 0; - }; - -} - -extern "C" location::LocationService & GetLocationManager(); -extern "C" location::LocationService * CreateAppleLocationService(); -extern "C" location::LocationService * CreateWiFiLocationService(); +} // namespace location diff --git a/platform/location_manager.cpp b/platform/location_service.cpp index 969242d848..9ecd552b7c 100644 --- a/platform/location_manager.cpp +++ b/platform/location_service.cpp @@ -1,12 +1,13 @@ -#include "location.hpp" +#include "location_service.hpp" #include "../std/target_os.hpp" #include "../std/vector.hpp" -#include "../std/bind.hpp" #include "../std/ctime.hpp" +namespace +{ -double ApproxDistanceSquareInMetres(double lat1, double lon1, double lat2, double lon2) +static double ApproxDistanceSquareInMetres(double lat1, double lon1, double lat2, double lon2) { double const m1 = (lat1 - lat2) / 111111.; double const m2 = (lon1 - lon2) / 111111.; @@ -42,69 +43,74 @@ public: } else m_prevLocation = new location::GpsInfo(newLocation); - return true; + return passes; } }; +} // namespace + +extern "C" location::LocationService * CreateAppleLocationService(location::LocationObserver &); +extern "C" location::LocationService * CreateWiFiLocationService(location::LocationObserver &); + namespace location { - class LocationManager : public LocationService + class DesktopLocationService : public LocationService, public LocationObserver { vector<LocationService *> m_services; PositionFilter m_filter; + bool m_reportFirstEvent; - void OnGpsUpdate(GpsInfo const & info) + virtual void OnLocationStatusChanged(location::TLocationStatus newStatus) { - if (m_filter.Passes(info)) - NotifyGpsObserver(info); + m_observer.OnLocationStatusChanged(newStatus); } - void OnCompassUpdate(CompassInfo const & info) + virtual void OnGpsUpdated(GpsInfo const & info) { - NotifyCompassObserver(info); + if (m_reportFirstEvent) + { + m_observer.OnLocationStatusChanged(location::EFirstEvent); + m_reportFirstEvent = false; + } + if (m_filter.Passes(info)) + m_observer.OnGpsUpdated(info); } public: - LocationManager() + DesktopLocationService(LocationObserver & observer) + : LocationService(observer), m_reportFirstEvent(true) { - LocationService * service; - -#if defined(OMIM_OS_IPHONE) || defined(OMIM_OS_MAC) - service = CreateAppleLocationService(); - service->SetGpsObserver(bind(&LocationManager::OnGpsUpdate, this, _1)); - service->SetCompassObserver(bind(&LocationManager::OnCompassUpdate, this, _1)); - m_services.push_back(service); +#if defined(OMIM_OS_MAC) + m_services.push_back(CreateAppleLocationService(*this)); #endif -#if defined(OMIM_OS_WINDOWS) || defined(OMIM_OS_MAC) - service = CreateWiFiLocationService(); - service->SetGpsObserver(bind(&LocationManager::OnGpsUpdate, this, _1)); - m_services.push_back(service); +#if defined(OMIM_OS_DESKTOP) + m_services.push_back(CreateWiFiLocationService(*this)); #endif } - virtual ~LocationManager() + virtual ~DesktopLocationService() { for (size_t i = 0; i < m_services.size(); ++i) delete m_services[i]; } - virtual void StartUpdate(bool useAccurateMode) + virtual void Start() { for (size_t i = 0; i < m_services.size(); ++i) - m_services[i]->StartUpdate(useAccurateMode); + m_services[i]->Start(); } - virtual void StopUpdate() + virtual void Stop() { for (size_t i = 0; i < m_services.size(); ++i) - m_services[i]->StopUpdate(); + m_services[i]->Stop(); + m_reportFirstEvent = true; } }; } -location::LocationService & GetLocationManager() +location::LocationService * CreateDesktopLocationService(location::LocationObserver & observer) { - static location::LocationManager mgr; - return mgr; + return new location::DesktopLocationService(observer); } diff --git a/platform/location_service.hpp b/platform/location_service.hpp new file mode 100644 index 0000000000..ae66d3d5d3 --- /dev/null +++ b/platform/location_service.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "location.hpp" + +namespace location +{ + +class LocationObserver +{ +public: + virtual void OnLocationStatusChanged(TLocationStatus newStatus) = 0; + virtual void OnGpsUpdated(GpsInfo const & info) = 0; +}; + +class LocationService +{ +protected: + LocationObserver & m_observer; + +public: + LocationService(LocationObserver & observer) : m_observer(observer) {} + virtual ~LocationService() {} + + virtual void Start() = 0; + virtual void Stop() = 0; +}; + +} // namespace location + +extern "C" location::LocationService * CreateDesktopLocationService(location::LocationObserver & observer); diff --git a/platform/platform.pro b/platform/platform.pro index 74ba8b35f3..495d672a96 100644 --- a/platform/platform.pro +++ b/platform/platform.pro @@ -18,17 +18,20 @@ QT *= core network wifi_location_service.cpp \ qt_download_manager.cpp \ qt_download.cpp \ - qt_concurrent_runner.cpp + qt_concurrent_runner.cpp \ + location_service.cpp HEADERS += qt_download_manager.hpp \ qt_download.hpp \ - wifi_info.hpp + wifi_info.hpp \ + location_service.hpp win32* { SOURCES += platform_win.cpp \ wifi_info_windows.cpp } else:macx* { OBJECTIVE_SOURCES += platform_mac.mm \ wifi_info_mac.mm \ - apple_video_timer.mm + apple_video_timer.mm \ + apple_location_service.mm } else:linux* { SOURCES += platform_linux.cpp } @@ -40,10 +43,6 @@ QT *= core network SOURCES += platform_android.cpp } -macx|iphone* { - OBJECTIVE_SOURCES += apple_location_service.mm -} - # common sources for all platforms HEADERS += \ @@ -58,7 +57,6 @@ HEADERS += \ url_generator.hpp \ SOURCES += \ - location_manager.cpp \ preferred_languages.cpp \ settings.cpp \ video_timer.cpp \ diff --git a/platform/wifi_location_service.cpp b/platform/wifi_location_service.cpp index eba5f5d6eb..20aa87a6b9 100644 --- a/platform/wifi_location_service.cpp +++ b/platform/wifi_location_service.cpp @@ -1,4 +1,4 @@ -#include "location.hpp" +#include "location_service.hpp" #include "wifi_info.hpp" #include "download_manager.hpp" @@ -46,10 +46,9 @@ namespace location info.m_longitude = json_real_value(lon); info.m_horizontalAccuracy = json_real_value(acc); // @TODO introduce flags to mark valid values - info.m_status = EAccurateMode; info.m_timestamp = static_cast<double>(time(NULL)); info.m_source = location::EGoogle; - NotifyGpsObserver(info); + m_observer.OnGpsUpdated(info); return; } } @@ -91,21 +90,25 @@ namespace location } public: - virtual void StartUpdate(bool) + WiFiLocationService(LocationObserver & observer) : LocationService(observer) + { + } + + virtual void Start() { m_wifiInfo.RequestWiFiBSSIDs(bind(&WiFiLocationService::OnWifiScanCompleted, this, _1)); } - virtual void StopUpdate() + virtual void Stop() { m_wifiInfo.Stop(); } }; } -location::LocationService * CreateWiFiLocationService() +extern "C" location::LocationService * CreateWiFiLocationService(location::LocationObserver & observer) { // small hack - create and initialize downloader in main thread GetDownloadManager(); - return new location::WiFiLocationService(); + return new location::WiFiLocationService(observer); } |