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-04-21 16:24:39 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:16:11 +0300
commit3c634e71c76c31a3e8074f2d4772c1c6e1811208 (patch)
tree4834d2ce9efe07546c7c58ebff060ad2788cf13c
parented69886a7e4c909b86c99d12f7f98280e6145703 (diff)
Added mac and ios location services implementation to platform
-rw-r--r--platform/apple_location_service.mm167
-rw-r--r--platform/location.cpp52
-rw-r--r--platform/location.hpp72
-rw-r--r--platform/platform.pro25
-rw-r--r--platform/windows_location_service.cpp23
5 files changed, 332 insertions, 7 deletions
diff --git a/platform/apple_location_service.mm b/platform/apple_location_service.mm
new file mode 100644
index 0000000000..a507af0985
--- /dev/null
+++ b/platform/apple_location_service.mm
@@ -0,0 +1,167 @@
+#include "location.hpp"
+
+#include "../std/target_os.hpp"
+
+#import <CoreLocation/CoreLocation.h>
+
+class AppleLocationService;
+
+@interface LocationManagerWrapper : NSObject <CLLocationManagerDelegate> {
+@private
+ AppleLocationService * m_service;
+}
+- (id)initWithService:(AppleLocationService *) service;
+@end
+
+using namespace location;
+
+#define ROUGH_ACCURACY kCLLocationAccuracyNearestTenMeters
+
+class AppleLocationService : public LocationService
+{
+ LocationManagerWrapper * m_objCppWrapper;
+ CLLocationManager * m_locationManager;
+
+ TLocationStatus m_status;
+
+public:
+ AppleLocationService() : m_status(ENotSupported)
+ {
+ m_objCppWrapper = [[LocationManagerWrapper alloc] initWithService:this];
+ m_locationManager = [[CLLocationManager alloc] init];
+ m_locationManager.delegate = m_objCppWrapper;
+ }
+
+ ~AppleLocationService()
+ {
+ [m_locationManager release];
+ [m_objCppWrapper release];
+ }
+
+ void OnLocationUpdate(GpsInfo & newLocation)
+ {
+ newLocation.m_status = m_status;
+ NotifySubscribers(newLocation);
+ }
+
+// 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)
+ {
+ if (![CLLocationManager locationServicesEnabled])
+ {
+ m_status = EDisabledByUser;
+ GpsInfo info;
+ info.m_status = m_status;
+ NotifySubscribers(info);
+ }
+ else
+ {
+ if (useAccurateMode)
+ {
+ m_status = EAccurateMode;
+ m_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
+ // also enable compass
+#ifdef OMIM_OS_IPHONE
+ if ([CLLocationManager headingAvailable])
+ [m_locationManager startHeadingUpdate];
+#endif
+ }
+ else
+ {
+ m_status = ERoughMode;
+ m_locationManager.desiredAccuracy = ROUGH_ACCURACY;
+ // also disable compass
+#ifdef OMIM_OS_IPHONE
+ if ([CLLocationManager headingAvailable])
+ [m_locationManager stopHeadingUpdate];
+#endif
+ }
+ [m_locationManager startUpdatingLocation];
+ }
+ }
+
+ virtual void StopUpdate()
+ {
+#ifdef OMIM_OS_IPHONE
+ if ([CLLocationManager headingAvailable])
+ [m_locationManager stopHeadingUpdate];
+#endif
+ [m_locationManager stopUpdatingLocation];
+ }
+};
+
+@implementation LocationManagerWrapper
+
+- (id)initWithService:(AppleLocationService *) service
+{
+ self = [super init];
+ if (self) {
+ 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];
+}
+
+- (void)locationManager:(CLLocationManager *)manager
+ didUpdateToLocation:(CLLocation *)newLocation
+ fromLocation:(CLLocation *)oldLocation
+{
+ GpsInfo newInfo;
+ [LocationManagerWrapper location:newLocation toGpsInfo:newInfo];
+ m_service->OnLocationUpdate(newInfo);
+}
+
+- (void)locationManager:(CLLocationManager *)manager
+ didFailWithError:(NSError *)error
+{
+ NSLog(@"locationManager failed with error: %d, %@", error.code, error.description);
+ if (error.code == kCLErrorDenied)
+ {
+ GpsInfo info;
+ info.m_status = EDisabledByUser;
+ m_service->OnLocationUpdate(info);
+ }
+}
+
+@end
+
+extern "C" location::LocationService & GetLocationService()
+{
+ static AppleLocationService ls;
+ return ls;
+}
diff --git a/platform/location.cpp b/platform/location.cpp
new file mode 100644
index 0000000000..ef93075b04
--- /dev/null
+++ b/platform/location.cpp
@@ -0,0 +1,52 @@
+#include "location.hpp"
+
+#include "../std/algorithm.hpp"
+
+#include <boost/bind.hpp>
+
+namespace location
+{
+ void LocationService::NotifySubscribers(GpsInfo const & info)
+ {
+ for (GpsObserversT::iterator it = m_gpsObservers.begin();
+ it != m_gpsObservers.end(); ++it)
+ (*it)(info);
+ }
+
+ void LocationService::NotifySubscribers(CompassInfo const & info)
+ {
+ for (CompassObserversT::iterator it = m_compassObservers.begin();
+ it != m_compassObservers.end(); ++it)
+ (*it)(info);
+ }
+
+ void LocationService::SubscribeToGpsUpdates(TGpsCallback observer)
+ {
+// if (std::find(m_gpsObservers.begin(), m_gpsObservers.end(), boost::bind(&observer))
+// == m_gpsObservers.end())
+ m_gpsObservers.push_back(observer);
+ }
+
+ void LocationService::SubscribeToCompassUpdates(TCompassCallback observer)
+ {
+// if (std::find(m_compassObservers.begin(), m_compassObservers.end(), observer)
+// == m_compassObservers.end())
+ m_compassObservers.push_back(observer);
+ }
+
+// void LocationService::Unsubscribe(TGpsCallback observer)
+// {
+// GpsObserversT::iterator found =
+// std::find(m_gpsObservers.begin(), m_gpsObservers.end(), observer);
+// if (found != m_gpsObservers.end())
+// m_gpsObservers.erase(found);
+// }
+
+// void LocationService::Unsubscribe(TCompassCallback observer)
+// {
+// CompassObserversT::iterator found =
+// std::find(m_compassObservers.begin(), m_compassObservers.end(), observer);
+// if (found != m_compassObservers.end())
+// m_compassObservers.erase(found);
+// }
+}
diff --git a/platform/location.hpp b/platform/location.hpp
new file mode 100644
index 0000000000..c9cf3d148a
--- /dev/null
+++ b/platform/location.hpp
@@ -0,0 +1,72 @@
+#pragma once
+
+#include "../std/string.hpp"
+#include "../std/vector.hpp"
+
+#include <boost/function.hpp>
+
+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
+ };
+
+ /// @note always check m_status before using this structure
+ struct GpsInfo
+ {
+ TLocationStatus m_status;
+ double m_timestamp; //!< seconds from 01/01/1970
+ double m_latitude; //!< degrees @TODO mercator
+ double m_longitude; //!< degrees @TODO mercator
+ 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
+ };
+
+ struct CompassInfo
+ {
+ double m_timestamp; //!< seconds from 01/01/1970
+ 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;
+ };
+
+ typedef boost::function1<void, GpsInfo const &> TGpsCallback;
+ typedef boost::function1<void, CompassInfo const &> TCompassCallback;
+
+ class LocationService
+ {
+ typedef vector<TGpsCallback> GpsObserversT;
+ GpsObserversT m_gpsObservers;
+ typedef vector<TCompassCallback> CompassObserversT;
+ CompassObserversT m_compassObservers;
+
+ protected:
+ void NotifySubscribers(GpsInfo const & info);
+ void NotifySubscribers(CompassInfo const & info);
+
+ public:
+ /// @note unsubscribe doesn't work with boost::function
+ void SubscribeToGpsUpdates(TGpsCallback observer);
+ void SubscribeToCompassUpdates(TCompassCallback observer);
+// void Unsubscribe(TGpsCallback observer);
+// void Unsubscribe(TCompassCallback observer);
+
+ /// to change active accuracy mode just call it again
+ /// @param useAccurateMode if true also enables compass if it's available
+ virtual void StartUpdate(bool useAccurateMode) = 0;
+ virtual void StopUpdate() = 0;
+ };
+
+}
+
+extern "C" location::LocationService & GetLocationService();
diff --git a/platform/platform.pro b/platform/platform.pro
index a7d9c5dceb..ccbac00b5e 100644
--- a/platform/platform.pro
+++ b/platform/platform.pro
@@ -12,12 +12,23 @@ include($$ROOT_DIR/common.pri)
QT *= core network
SOURCES += \
- qtplatform.cpp \
- qt_download_manager.cpp \
- qt_download.cpp \
+ qtplatform.cpp \
+ qt_download_manager.cpp \
+ qt_download.cpp \
+ location.cpp \
HEADERS += \
- platform.hpp \
- download_manager.hpp \
- qt_download_manager.hpp \
- qt_download.hpp \
+ platform.hpp \
+ download_manager.hpp \
+ qt_download_manager.hpp \
+ qt_download.hpp \
+ location.hpp \
+
+mac|iphone* {
+ OBJECTIVE_SOURCES += apple_location_service.mm
+ LIBS += -framework CoreLocation -framework Foundation
+}
+
+win {
+ SOURCES += windows_location_service.cpp
+}
diff --git a/platform/windows_location_service.cpp b/platform/windows_location_service.cpp
new file mode 100644
index 0000000000..4799567a5a
--- /dev/null
+++ b/platform/windows_location_service.cpp
@@ -0,0 +1,23 @@
+#include "location.hpp"
+
+using namespace location;
+
+class WindowsLocationService : public LocationService
+{
+public:
+ virtual void StartUpdate(bool useAccurateMode)
+ {
+ // @TODO
+ }
+
+ virtual void StopUpdate()
+ {
+ // @TODO
+ }
+};
+
+extern "C" location::LocationService & GetLocationService()
+{
+ static WindowsLocationService ls;
+ return ls;
+}