Location: Using Location Information and Service
This tutorial demonstrates how you can retrieve and use location information, and track routes.
Warm-up
Become familiar with the Location API basics by learning about:
-
Initializing the Location Service
Fulfill the prerequisites, start the location service, and stop it when no longer needed.
-
Getting the Last Known Location
Retrieve the last known position of the device.
-
Getting Location Updates
Retrieve the device position (given as coordinates) and track position updates.
-
Using Location Bounds
Create a location area and monitor when the device crosses the area bounds.
-
Getting Satellite Information
Retrieve information on satellites, which connect with the device to get location information.
Follow-up
Once we have learned the basics of the Location API, we can now move on to more advanced tasks, including:
-
Tracking the Route
Get information about the current position, velocity, and distance.
Initializing the Location Service
-
To use the functions and data types of the Location Manager API (in mobile and wearable applications), include the <locations.h> header file in your application:
#include <locations.h>
-
Create a location manager handle using the location_manager_create() function before you use the location service.
In this example, the GPS is used as the source of the position data, so the first parameter is LOCATIONS_METHOD_GPS. You can use other values of the location_method_e enumeration (in mobile and wearable applications), such as LOCATIONS_METHOD_HYBRID or LOCATIONS_METHOD_WPS, but they are less accurate.
location_manager_h manager; location_manager_create(LOCATIONS_METHOD_GPS, &manager);
Each location manager is an independent service. Multiple location managers can be created in the same application to provide different services, such as GPS and Bluetooth. Callbacks are set for a given location manager and are called only if the service is started for their manager.
-
Start the location service using the location_manager_start() function. This call is asynchronous and only initiates the process of starting the location manager service. Once the manager is started, the registered callbacks are invoked when their corresponding events take place. To know when the service becomes enabled, use the location_manager_set_service_state_changed_cb() function.
location_manager_start(manager);
-
Using the location service is power consuming, so if the service is not used, stop updating the location using the location_manager_stop() function. Call the location_manager_start() function again if the update position information is needed.
location_manager_stop(manager);
-
At the end of the application, destroy all used resources, such as the location manager (location_manager_destroy()):
location_manager_destroy(manager); manager = NULL;
If you destroy the handle, there is no need to call the location_manager_stop() function to stop the service. The service is automatically stopped. Also, you do not have to unset previously set callbacks.
Getting the Last Known Location
To retrieve synchronously the last known location of the device:
- Register a callback function for location service state changes and start the Location Manager:
ret = location_manager_set_service_state_changed_cb(manager, __state_changed_cb, NULL); ret = location_manager_start(manager);
The __state_changed_cb function is a callback, which is called when the status of the location service state changes.
static location_service_state_e service_state; static void __state_changed_cb(location_service_state_e state, void *user_data) { service_state = state; }
- After starting the Location Manager, call the location_manager_get_last_location() function to get the last location information, including the altitude, latitude, and direction:
double altitude, latitude, longitude, climb, direction, speed; double horizontal, vertical; location_accuracy_level_e level; time_t timestamp; ret = location_manager_get_last_location(manager, &altitude, &latitude, &longitude, &climb, &direction, &speed, &level, &horizontal, &vertical, ×tamp);
The function returns the last location stored in the system. When the current location is not fixed, the last location may not be the current location, but the old location.
Use this function instead of repeatedly requesting current locations to spare the Location Manager from running costly positioning systems.
- To get the current location information, call the location_manager_get_location() function after the service is enabled:
static void __state_changed_cb(location_service_state_e state, void *user_data) { double altitude, latitude, longitude, climb, direction, speed; double horizontal, vertical; location_accuracy_level_e level; time_t timestamp; if (state == LOCATIONS_SERVICE_ENABLED) { ret = location_manager_get_location(manager, &altitude, &latitude, &longitude, &climb, &direction, &speed, &level, &horizontal, &vertical, ×tamp); } }
- When you no longer need the state updates, unset the callback:
location_manager_unset_service_state_changed_cb(manager);
Getting Location Updates
You can get a notification of the position update using the position update callback. The callback is invoked periodically, receiving the device's current position with every call. You can use the callback to retrieve the device position (given as coordinates) and convert it to the corresponding address.
-
Register the callback using the location_manager_set_position_updated_cb() function:
location_manager_set_position_updated_cb(manager, position_updated, 2, NULL);
The third parameter determines the frequency of callback calls. In this example, the callback is called every 2 seconds.
-
When the update is received, you can, for example, update the variables that store the current position:
static double user_latitude, user_longitude; static void position_updated(double latitude, double longitude, double altitude, time_t timestamp, void *user_data) { user_latitude = latitude; user_longitude = longitude; }
Note The callback is called only if the Location Manager has been started. The same holds for all other callbacks registered with the manager.
Using Location Bounds
You can define a virtual perimeter, which is monitored to see whether the device enters or exits the area.
To use location bounds:
- Create location bounds with the required area type (rectangle, circle, or polygon) needed for your application (each type has its own API sets):
int poly_size = 3; // Triangle shaped bounds location_coords_s coord_list[poly_size]; coord_list[0].latitude = 37; // Temporary value coord_list[0].longitude = 126; coord_list[1].latitude = 38; coord_list[1].longitude = 128; coord_list[2].latitude = 35; coord_list[2].longitude = 128; location_bounds_h bounds_poly; ret = location_bounds_create_polygon(coord_list, poly_size, &bounds_poly);
When a circular bound is needed, use the location_bounds_create_circle() function.
- To get the generated polygon bounds, register a callback function to notify you of the polygon coordinates:
ret = location_bounds_foreach_polygon_coords(bounds_poly, capi_poly_coords_cb, NULL);
Implement the callback function (the second parameter in the function above) separately:
static double latitude, longitude; static bool capi_poly_coords_cb(location_coords_s coords, void *user_data) { latitude = coords.latitude; longitude = coords.longitude; return true; }
-
Register a callback, which is called when you enter or exit the defined region, using the location_bounds_set_state_changed_cb() function:
location_bounds_set_state_changed_cb(bounds_poly, bounds_state_changed_cb, NULL);
Implement the bounds_state_changed_cb callback separately:
static location_boundary_state_e bound_state; static void bounds_state_changed_cb(location_boundary_state_e state, void *user_data) { bound_state = state; }
-
Call the location_manager_add_boundary() function to add the bounds to a location manager:
location_manager_add_boundary(manager, bounds_poly);
- When the bounds are no longer needed, destroy them:
location_bounds_destroy(bounds_poly);
Getting Satellite Information
You can retrieve and update information of the satellite connected with the device. The information includes azimuth, elevation, PRN, SNR, and NMEA data. You can also get a notification of the satellite update using the satellite update callback. The callback is invoked periodically, receiving the information of connected satellites with every call.
-
Register the callback using the location_manager_set_satellite_updated_cb() function:
gps_status_set_satellite_updated_cb(manager, capi_gps_status_satellite_updated_cb, 10, NULL);
The third parameter determines the frequency of callback calls. In this example, the callback is called every 10 seconds.
- When the update is received, the callback containing brief satellite information is called. To get the detailed satellite information in the sky, call the gps_status_foreach_satellites_in_view() function in the callback. Variables that store the current satellite information are updated.
int cur_azimuth, cur_elevation, cur_prn, cur_snr; static bool capi_gps_status_get_satellites_cb(unsigned int azimuth, unsigned int elevation, unsigned int prn, int snr, bool is_in_use, void *user_data) { cur_azimuth = azimuth; cur_elevation = elevation; cur_prn = prn; cur_snr = snr; return true; } static int numofactive, numofinview; static void capi_gps_status_satellite_updated_cb(int num_of_active, int num_of_inview, time_t timestamp, void *user_data) { numofinview = num_of_active; if (num_of_inview > 0) { gps_status_foreach_satellites_in_view(manager, capi_gps_status_get_satellites_cb, NULL); } }
Note The callback is called only if the location manager has been started. The same holds for all other callbacks registered with the manager.
Tracking the Route
To get information about the current position, velocity, and distance:
- Receive periodic notifications.
-
To get notifications of the position and velocity updates, register the position and velocity update callbacks. The callbacks are invoked periodically, receiving the device's current position or velocity with every call.
-
Register the position update callback using the location_manager_set_position_updated_cb() function:
location_manager_set_position_updated_cb(manager, position_updated, 2, NULL);
-
Register the velocity update callback using the location_manager_set_velocity_updated_cb() function:
location_manager_set_position_updated_cb(manager, velocity_updated, 2, NULL);
The third parameter determines the frequency of the callback calls. In this example, the callbacks are called every 2 seconds.
-
-
Define the position and velocity callback functions:
void position_updated(double latitude, double longitude, double altitude, time_t timestamp, void *user_data) {} void velocity_updated(double speed, double direction, double climb, time_t timestamp, void *user_data) {}
Within the callback, you can collect obtained data to get the points you have visited, to calculate traveled distance more precisely, or to calculate the average speed or climb.
-
- Receive the current information.
You can get the current information about position, velocity, or location accuracy:
- To get information about the current position (altitude, latitude, and longitude), use the location_manager_get_position() function:
time_t timestamp; double altitude; double latitude; double longitude; location_manager_get_position(manager, &altitude, &latitude, &longitude, ×tamp);
-
To get information about the current velocity (climb in km/h, direction as degrees from the north, and speed in km/h), use the location_manager_get_velocity() function:
double climb; double direction; double speed; location_manager_get_velocity(manager, &climb, &direction, &speed, ×tamp);
-
To get information about the current accuracy level (see the location_accuracy_level_e enumeration in mobile and wearable applications), and horizontal and vertical accuracy, use the location_manager_get_accuracy() function:
location_accuracy_level_e level; double horizontal; double vertical; location_manager_get_accuracy(manager, &level, &horizontal, &vertical);
-
Use the location_manager_get_location() function to get all of the above 10 values at once:
location_manager_get_location(manager, &altitude, &latitude, &longitude, &climb, &direction, &speed, &level, &horizontal, &vertical, ×tamp);
-
If the location service is currently unavailable, get the last values recorded by the location manager when the GPS signal was available. To get the information, use the following functions:
- location_manager_get_last_position()
- location_manager_get_last_velocity()
- location_manager_get_last_accuracy()
- location_manager_get_last_location()
The syntax of these functions corresponds to the functions presented above.
- To get information about the current position (altitude, latitude, and longitude), use the location_manager_get_position() function:
- Get the distance.
To get a distance (in meters) between 2 points, use the location_manager_get_distance() function. The obtained value is a great-circle distance; the shortest distance between 2 points on the sphere.
Provide the latitude and longitude of the starting point, the latitude and longitude of the end point, and the variable to store the obtained distance.
double distance; location_manager_get_distance(37.28, 127.01, 52.23, 21.01, &distance);
To get more a precise traveled distance, sum the distances between each 2 consecutive points, delivered by the periodic position update callback.