(Location) Implement horizontal and vertical accuracy - Android's

location API only provides horizontal API but iOS/OSX API supports
both horizontal and vertical. Maybe consider implementing vertical
accuracy for Android by hand later
This commit is contained in:
twinaphex 2013-12-19 17:36:27 +01:00
parent 2f1327bf3e
commit da6e360e49
6 changed files with 52 additions and 28 deletions

View File

@ -215,11 +215,13 @@ LocationListener
} }
/* /*
* Gets the accuracy of the current location in meters. * Gets the horizontal accuracy of the current location
* in meters. (NOTE: There seems to be no vertical accuracy
* for a given location with the Android location API)
* *
* @return the accuracy of the current position. * @return the horizontal accuracy of the current position.
*/ */
public float onLocationGetAccuracy() public float onLocationGetHorizontalAccuracy()
{ {
return mCurrentLocation.getAccuracy(); return mCurrentLocation.getAccuracy();
} }

View File

@ -26,6 +26,8 @@ static CLLocationManager *locationManager;
static bool locationChanged; static bool locationChanged;
static CLLocationDegrees currentLatitude; static CLLocationDegrees currentLatitude;
static CLLocationDegrees currentLongitude; static CLLocationDegrees currentLongitude;
sttaic CLLocationAccuracy currentHorizontalAccuracy;
sttaic CLLocationAccuracy currentVerticalAccuracy;
// Define compatibility symbols and categories // Define compatibility symbols and categories
#ifdef IOS #ifdef IOS
@ -364,10 +366,14 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
return currentLongitude; return currentLongitude;
} }
- (double)onLocationGetAccuracy - (double)onLocationGetHorizontalAccuracy
{ {
/* TODO/FIXME - implement */ return currentHorizontalAccuracy;
return 0.0; }
- (double)onLocationGetVerticalAccuracy
{
return currentVerticalAccuracy;
} }
- (bool)onLocationHasChanged - (bool)onLocationHasChanged
@ -383,14 +389,19 @@ didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
locationChanged = true; locationChanged = true;
currentLatitude = newLocation.coordinate.latitude; currentLatitude = newLocation.coordinate.latitude;
currentLongitude = newLocation.coordinate.longitude; currentLongitude = newLocation.coordinate.longitude;
currentHorizontalAccuracy = newLocation.horizontalAccuracy;
currentVerticalAccuracy = newLocation.verticalAccuracy;
RARCH_LOG("didUpdateToLocation - latitude %f, longitude %f\n", (float)currentLatitude, (float)currentLongitude); RARCH_LOG("didUpdateToLocation - latitude %f, longitude %f\n", (float)currentLatitude, (float)currentLongitude);
} }
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{ {
locationChanged = true; locationChanged = true;
currentLatitude = [[locations objectAtIndex:([locations count]-1)] coordinate].latitude; CLLocation *location = [locations objectAtIndex:([locations count]-1)];
currentLongitude = [[locations objectAtIndex:([locations count]-1)] coordinate].longitude; currentLatitude = [location coordinate].latitude;
currentLongitude = [location coordinate].longitude;
currentHorizontalAccuracy = [location horizontalAccuracy];
currentVerticalAccuracy = [location verticalAccuracy];
RARCH_LOG("didUpdateLocations - latitude %f, longitude %f\n", (float)currentLatitude, (float)currentLongitude); RARCH_LOG("didUpdateLocations - latitude %f, longitude %f\n", (float)currentLatitude, (float)currentLongitude);
} }
@ -761,7 +772,8 @@ static void apple_location_stop(void *data)
[[RAGameView get] onLocationStop]; [[RAGameView get] onLocationStop];
} }
static bool apple_location_get_position(void *data, double *lat, double *lon, double *accuracy) static bool apple_location_get_position(void *data, double *lat, double *lon, double *horiz_accuracy,
double *vert_accuracy)
{ {
(void)data; (void)data;
@ -772,13 +784,15 @@ static bool apple_location_get_position(void *data, double *lat, double *lon, do
*lat = [[RAGameView get] onLocationGetLatitude]; *lat = [[RAGameView get] onLocationGetLatitude];
*lon = [[RAGameView get] onLocationGetLongitude]; *lon = [[RAGameView get] onLocationGetLongitude];
*accuracy = [[RAGameView get] onLocationGetAccuracy]; *horiz_accuracy = [[RAGameView get] onLocationGetHorizontalAccuracy];
*vert_accuracy = [[RAGameView get] onLocationGetVerticalAccuracy];
return true; return true;
fail: fail:
*lat = 0.0; *lat = 0.0;
*lon = 0.0; *lon = 0.0;
*accuracy = 0.0; *horiz_accuracy = 0.0;
*vert_accuracy = 0.0;
return false; return false;
} }

View File

@ -648,14 +648,16 @@ void driver_location_set_interval(unsigned interval_msecs, unsigned interval_dis
driver.location->set_interval(driver.location_data, interval_msecs, interval_distance); driver.location->set_interval(driver.location_data, interval_msecs, interval_distance);
} }
bool driver_location_get_position(double *lat, double *lon, double *accuracy) bool driver_location_get_position(double *lat, double *lon, double *horiz_accuracy,
double *vert_accuracy)
{ {
if (driver.location && driver.location_data) if (driver.location && driver.location_data)
return driver.location->get_position(driver.location_data, lat, lon, accuracy); return driver.location->get_position(driver.location_data, lat, lon, horiz_accuracy, vert_accuracy);
*lat = 0.0; *lat = 0.0;
*lon = 0.0; *lon = 0.0;
*accuracy = 0.0; *horiz_accuracy = 0.0;
*vert_accuracy = 0.0;
return false; return false;
} }
#endif #endif

View File

@ -375,7 +375,7 @@ typedef struct location_driver
bool (*start)(void *data); bool (*start)(void *data);
void (*stop)(void *data); void (*stop)(void *data);
bool (*get_position)(void *data, double *lat, double *lon, double *accuracy); bool (*get_position)(void *data, double *lat, double *lon, double *horiz_accuracy, double *vert_accuracy);
void (*set_interval)(void *data, unsigned interval_msecs, unsigned interval_distance); void (*set_interval)(void *data, unsigned interval_msecs, unsigned interval_distance);
const char *ident; const char *ident;
} location_driver_t; } location_driver_t;
@ -603,7 +603,7 @@ void driver_camera_poll(void);
#ifdef HAVE_LOCATION #ifdef HAVE_LOCATION
bool driver_location_start(void); bool driver_location_start(void);
void driver_location_stop(void); void driver_location_stop(void);
bool driver_location_get_position(double *lat, double *lon, double *accuracy); bool driver_location_get_position(double *lat, double *lon, double *horiz_accuracy, double *vert_accuracy);
void driver_location_set_interval(unsigned interval_msecs, unsigned interval_distance); void driver_location_set_interval(unsigned interval_msecs, unsigned interval_distance);
#endif #endif

View File

@ -766,7 +766,8 @@ typedef void (*retro_location_stop_t)(void);
// Get the position of the current location. Will set parameters to 0 if no new // Get the position of the current location. Will set parameters to 0 if no new
// location update has happened since the last time. // location update has happened since the last time.
typedef bool (*retro_location_get_position_t)(double *lat, double *lon, double *accuracy); typedef bool (*retro_location_get_position_t)(double *lat, double *lon, double *horiz_accuracy,
double *vert_accuracy);
struct retro_location_callback struct retro_location_callback
{ {

View File

@ -26,7 +26,7 @@ typedef struct android_location
jmethodID onLocationSetInterval; jmethodID onLocationSetInterval;
jmethodID onLocationGetLongitude; jmethodID onLocationGetLongitude;
jmethodID onLocationGetLatitude; jmethodID onLocationGetLatitude;
jmethodID onLocationGetAccuracy; jmethodID onLocationGetHorizontalAccuracy;
jmethodID onLocationHasChanged; jmethodID onLocationHasChanged;
} androidlocation_t; } androidlocation_t;
@ -72,8 +72,8 @@ static void *android_location_init(void)
if (!androidlocation->onLocationGetLongitude) if (!androidlocation->onLocationGetLongitude)
goto dealloc; goto dealloc;
GET_METHOD_ID(env, androidlocation->onLocationGetAccuracy, class, "onLocationGetAccuracy", "()F"); GET_METHOD_ID(env, androidlocation->onLocationGetHorizontalAccuracy, class, "onLocationGetHorizontalAccuracy", "()F");
if (!androidlocation->onLocationGetAccuracy) if (!androidlocation->onLocationGetHorizontalAccuracy)
goto dealloc; goto dealloc;
GET_METHOD_ID(env, androidlocation->onLocationGetLongitude, class, "onLocationSetInterval", "(II)V"); GET_METHOD_ID(env, androidlocation->onLocationGetLongitude, class, "onLocationSetInterval", "(II)V");
@ -129,7 +129,8 @@ static void android_location_stop(void *data)
CALL_VOID_METHOD(env, android_app->activity->clazz, androidlocation->onLocationStop); CALL_VOID_METHOD(env, android_app->activity->clazz, androidlocation->onLocationStop);
} }
static bool android_location_get_position(void *data, double *latitude, double *longitude, double *accuracy) static bool android_location_get_position(void *data, double *latitude, double *longitude, double *horiz_accuracy,
double *vert_accuracy)
{ {
struct android_app *android_app = (struct android_app*)g_android; struct android_app *android_app = (struct android_app*)g_android;
androidlocation_t *androidlocation = (androidlocation_t*)data; androidlocation_t *androidlocation = (androidlocation_t*)data;
@ -137,7 +138,7 @@ static bool android_location_get_position(void *data, double *latitude, double *
if (!env) if (!env)
goto fail; goto fail;
jdouble lat, lon, accuhurtz; jdouble lat, lon, horiz_accu;
jboolean newLocation; jboolean newLocation;
CALL_BOOLEAN_METHOD(env, newLocation, android_app->activity->clazz, androidlocation->onLocationHasChanged); CALL_BOOLEAN_METHOD(env, newLocation, android_app->activity->clazz, androidlocation->onLocationHasChanged);
@ -147,21 +148,25 @@ static bool android_location_get_position(void *data, double *latitude, double *
CALL_DOUBLE_METHOD(env, lat, android_app->activity->clazz, androidlocation->onLocationGetLatitude); CALL_DOUBLE_METHOD(env, lat, android_app->activity->clazz, androidlocation->onLocationGetLatitude);
CALL_DOUBLE_METHOD(env, lon, android_app->activity->clazz, androidlocation->onLocationGetLongitude); CALL_DOUBLE_METHOD(env, lon, android_app->activity->clazz, androidlocation->onLocationGetLongitude);
CALL_DOUBLE_METHOD(env, accuhurtz, android_app->activity->clazz, androidlocation->onLocationGetAccuracy); CALL_DOUBLE_METHOD(env, horiz_accu, android_app->activity->clazz, androidlocation->onLocationGetHorizontalAccuracy);
if (lat != 0.0) if (lat != 0.0)
*latitude = lat; *latitude = lat;
if (lon != 0.0) if (lon != 0.0)
*longitude = lon; *longitude = lon;
if (accuhurtz != 0.0) if (horiz_accu != 0.0)
*accuracy = accuhurtz; *horiz_accuracy = horiz_accu;
/* TODO/FIXME - custom implement vertical accuracy since Android location API does not have it? */
*vert_accuracy = 0.0;
return true; return true;
fail: fail:
*latitude = 0.0; *latitude = 0.0;
*longitude = 0.0; *longitude = 0.0;
*accuracy = 0.0; *horiz_accuracy = 0.0;
*vert_accuracy = 0.0;
return false; return false;
} }