2 * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <system_info.h>
21 #include "location_bounds.h"
22 #include "location_internal.h"
25 static void __free_position_list(gpointer data)
30 LocationPosition *position = (LocationPosition *) data;
31 location_position_free(position);
34 static location_bounds_type_e __convert_bounds_type(LocationBoundaryType type)
36 location_bounds_type_e ret;
38 case LOCATION_BOUNDARY_CIRCLE:
39 ret = LOCATION_BOUNDS_CIRCLE;
41 case LOCATION_BOUNDARY_POLYGON:
42 ret = LOCATION_BOUNDS_POLYGON;
44 case LOCATION_BOUNDARY_NONE:
45 case LOCATION_BOUNDARY_RECT:
47 ret = LOCATION_BOUNDS_RECT;
53 EXPORT_API int location_bounds_create_rect(location_coords_s top_left, location_coords_s bottom_right, location_bounds_h *bounds)
55 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
56 LOCATIONS_NULL_ARG_CHECK(bounds);
57 LOCATIONS_CHECK_CONDITION(top_left.latitude >= -90 && top_left.latitude <= 90, LOCATION_BOUNDS_ERROR_INVALID_PARAMETER, "LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
58 LOCATIONS_CHECK_CONDITION(top_left.longitude >= -180 && top_left.longitude <= 180, LOCATION_BOUNDS_ERROR_INVALID_PARAMETER, "LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
59 LOCATIONS_CHECK_CONDITION(bottom_right.latitude >= -90 && bottom_right.latitude <= 90, LOCATION_BOUNDS_ERROR_INVALID_PARAMETER, "LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
60 LOCATIONS_CHECK_CONDITION(bottom_right.longitude >= -180 && bottom_right.longitude <= 180, LOCATION_BOUNDS_ERROR_INVALID_PARAMETER, "LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
62 LocationPosition *lt = location_position_new(0, top_left.latitude, top_left.longitude, 0, LOCATION_STATUS_2D_FIX);
64 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
65 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
68 LocationPosition *rb = location_position_new(0, bottom_right.latitude, bottom_right.longitude, 0, LOCATION_STATUS_2D_FIX);
70 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
71 location_position_free(lt);
72 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
75 location_bounds_s *handle = (location_bounds_s *) malloc(sizeof(location_bounds_s));
77 LOCATIONS_LOGE("OUT_OF_MEMORY(0x%08x)", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
78 location_position_free(rb);
79 location_position_free(lt);
80 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
82 memset(handle, 0, sizeof(location_bounds_s));
84 handle->is_added = FALSE;
85 handle->boundary = location_boundary_new_for_rect(lt, rb);
86 location_position_free(rb);
87 location_position_free(lt);
88 if (handle->boundary == NULL) {
89 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_boundary_new_for_rect", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
91 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
93 handle->user_cb = NULL;
94 handle->user_data = NULL;
96 *bounds = (location_bounds_h) handle;
97 return LOCATION_BOUNDS_ERROR_NONE;
100 EXPORT_API int location_bounds_create_circle(location_coords_s center, double radius, location_bounds_h *bounds)
102 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
103 LOCATIONS_NULL_ARG_CHECK(bounds);
104 LOCATIONS_CHECK_CONDITION(radius >= 0, LOCATION_BOUNDS_ERROR_INVALID_PARAMETER, "LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
105 LOCATIONS_CHECK_CONDITION(center.latitude >= -90 && center.latitude <= 90, LOCATION_BOUNDS_ERROR_INVALID_PARAMETER, "LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
106 LOCATIONS_CHECK_CONDITION(center.longitude >= -180 && center.longitude <= 180, LOCATION_BOUNDS_ERROR_INVALID_PARAMETER, "LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
108 LocationPosition *ct = location_position_new(0, center.latitude, center.longitude, 0, LOCATION_STATUS_2D_FIX);
110 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
111 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
114 location_bounds_s *handle = (location_bounds_s *) malloc(sizeof(location_bounds_s));
115 if (handle == NULL) {
116 LOCATIONS_LOGE("OUT_OF_MEMORY(0x%08x)", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
117 location_position_free(ct);
118 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
120 memset(handle, 0, sizeof(location_bounds_s));
122 handle->is_added = FALSE;
123 handle->boundary = location_boundary_new_for_circle(ct, radius);
124 location_position_free(ct);
125 if (handle->boundary == NULL) {
126 int ret = get_last_result();
128 if (ret == LOCATION_ERROR_PARAMETER) {
129 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INVALID_PARAMETER(0x%08x) fail to location_boundary_new_for_circle", LOCATION_BOUNDS_ERROR_INVALID_PARAMETER);
130 return LOCATION_BOUNDS_ERROR_INVALID_PARAMETER;
132 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_boundary_new_for_circle", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
133 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
136 handle->user_cb = NULL;
137 handle->user_data = NULL;
139 *bounds = (location_bounds_h) handle;
140 return LOCATION_BOUNDS_ERROR_NONE;
143 EXPORT_API int location_bounds_create_polygon(location_coords_s *coords_list, int length, location_bounds_h *bounds)
145 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
146 LOCATIONS_NULL_ARG_CHECK(coords_list);
147 LOCATIONS_NULL_ARG_CHECK(bounds);
148 LOCATIONS_CHECK_CONDITION(length >= 3, LOCATION_BOUNDS_ERROR_INVALID_PARAMETER, "LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
151 GList *position_list = NULL;
152 LocationPosition *position = NULL;
155 for (i = 0; i < length; i++) {
156 if (coords_list[i].latitude < -90 || coords_list[i].latitude > 90 || coords_list[i].longitude < -180 || coords_list[i].longitude > 180) {
157 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INVALID_PARAMETER(0x%08x)", LOCATION_BOUNDS_ERROR_INVALID_PARAMETER);
161 position = location_position_new(0, coords_list[i].latitude, coords_list[i].longitude, 0.0, LOCATION_STATUS_2D_FIX);
162 position_list = g_list_append(position_list, position);
164 /* We should not remove position
165 location_position_free(position);
171 g_list_free_full(position_list, (GDestroyNotify) __free_position_list);
172 return LOCATION_BOUNDS_ERROR_INVALID_PARAMETER;
175 if (position_list == NULL) {
176 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
177 g_list_free_full(position_list, (GDestroyNotify) __free_position_list);
178 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
181 location_bounds_s *handle = (location_bounds_s *) malloc(sizeof(location_bounds_s));
182 if (handle == NULL) {
183 LOCATIONS_LOGE("OUT_OF_MEMORY(0x%08x)", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
184 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
186 memset(handle, 0, sizeof(location_bounds_s));
188 handle->is_added = FALSE;
189 handle->boundary = location_boundary_new_for_polygon(position_list);
190 if (handle->boundary == NULL) {
191 int ret = get_last_result();
193 if (ret == LOCATION_ERROR_PARAMETER) {
194 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INVALID_PARAMETER(0x%08x) fail to location_boundary_new_for_polygon", LOCATION_BOUNDS_ERROR_INVALID_PARAMETER);
195 return LOCATION_BOUNDS_ERROR_INVALID_PARAMETER;
197 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_boundary_new_for_polygon", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
198 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
202 handle->user_cb = NULL;
203 handle->user_data = NULL;
205 *bounds = (location_bounds_h) handle;
206 return LOCATION_BOUNDS_ERROR_NONE;
209 EXPORT_API bool location_bounds_contains_coordinates(location_bounds_h bounds, location_coords_s coords)
211 if (__is_location_supported() == LOCATIONS_ERROR_NOT_SUPPORTED) {
212 set_last_result(LOCATIONS_ERROR_NOT_SUPPORTED);
217 set_last_result(LOCATION_BOUNDS_ERROR_INVALID_PARAMETER);
221 if (coords.latitude < -90 || coords.latitude > 90 || coords.longitude < -180 || coords.longitude > 180) {
222 set_last_result(LOCATION_BOUNDS_ERROR_INVALID_PARAMETER);
226 LocationPosition *pos = location_position_new(0, coords.latitude, coords.longitude, 0, LOCATION_STATUS_2D_FIX);
228 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
229 set_last_result(LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
232 location_bounds_s *handle = (location_bounds_s *) bounds;
233 gboolean is_inside = location_boundary_if_inside(handle->boundary, pos);
234 location_position_free(pos);
235 bool result = is_inside ? TRUE : FALSE;
237 set_last_result(LOCATION_BOUNDS_ERROR_NONE);
241 EXPORT_API int location_bounds_get_type(location_bounds_h bounds, location_bounds_type_e *type)
243 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
244 LOCATIONS_NULL_ARG_CHECK(bounds);
245 LOCATIONS_NULL_ARG_CHECK(type);
247 location_bounds_s *handle = (location_bounds_s *) bounds;
248 *type = __convert_bounds_type(handle->boundary->type);
249 return LOCATION_BOUNDS_ERROR_NONE;
252 EXPORT_API int location_bounds_get_rect_coords(location_bounds_h bounds, location_coords_s *top_left, location_coords_s *bottom_right)
254 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
255 LOCATIONS_NULL_ARG_CHECK(bounds);
256 LOCATIONS_NULL_ARG_CHECK(top_left);
257 LOCATIONS_NULL_ARG_CHECK(bottom_right);
259 location_bounds_s *handle = (location_bounds_s *) bounds;
260 if (__convert_bounds_type(handle->boundary->type) != LOCATION_BOUNDS_RECT) {
261 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INCORRECT_TYPE(0x%08x)", LOCATION_BOUNDS_ERROR_INCORRECT_TYPE);
262 return LOCATION_BOUNDS_ERROR_INCORRECT_TYPE;
265 top_left->latitude = handle->boundary->rect.left_top->latitude;
266 top_left->longitude = handle->boundary->rect.left_top->longitude;
267 bottom_right->latitude = handle->boundary->rect.right_bottom->latitude;
268 bottom_right->longitude = handle->boundary->rect.right_bottom->longitude;
269 return LOCATION_BOUNDS_ERROR_NONE;
272 EXPORT_API int location_bounds_get_circle_coords(location_bounds_h bounds, location_coords_s *center, double *radius)
274 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
275 LOCATIONS_NULL_ARG_CHECK(bounds);
276 LOCATIONS_NULL_ARG_CHECK(center);
277 LOCATIONS_NULL_ARG_CHECK(radius);
279 location_bounds_s *handle = (location_bounds_s *) bounds;
280 if (__convert_bounds_type(handle->boundary->type) != LOCATION_BOUNDS_CIRCLE) {
281 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INCORRECT_TYPE(0x%08x)", LOCATION_BOUNDS_ERROR_INCORRECT_TYPE);
282 return LOCATION_BOUNDS_ERROR_INCORRECT_TYPE;
285 center->latitude = handle->boundary->circle.center->latitude;
286 center->longitude = handle->boundary->circle.center->longitude;
287 *radius = handle->boundary->circle.radius;
288 return LOCATION_BOUNDS_ERROR_NONE;
291 EXPORT_API int location_bounds_foreach_polygon_coords(location_bounds_h bounds, polygon_coords_cb callback, void *user_data)
293 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
294 LOCATIONS_NULL_ARG_CHECK(bounds);
295 LOCATIONS_NULL_ARG_CHECK(callback);
297 location_bounds_s *handle = (location_bounds_s *) bounds;
298 if (__convert_bounds_type(handle->boundary->type) != LOCATION_BOUNDS_POLYGON) {
299 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INCORRECT_TYPE(0x%08x)", LOCATION_BOUNDS_ERROR_INCORRECT_TYPE);
300 return LOCATION_BOUNDS_ERROR_INCORRECT_TYPE;
303 GList *list = handle->boundary->polygon.position_list;
305 LocationPosition *pos = list->data;
306 location_coords_s coords;
307 coords.latitude = pos->latitude;
308 coords.longitude = pos->longitude;
310 if (callback(coords, user_data) != TRUE) {
311 LOCATIONS_LOGI("User quit the loop ");
314 list = g_list_next(list);
316 return LOCATION_BOUNDS_ERROR_NONE;
319 EXPORT_API int location_bounds_destroy(location_bounds_h bounds)
321 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
322 LOCATIONS_NULL_ARG_CHECK(bounds);
324 location_bounds_s *handle = (location_bounds_s *) bounds;
325 if (handle->is_added) {
326 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_IS_ADDED(0x%08x)", LOCATION_BOUNDS_ERROR_IS_ADDED);
327 return LOCATION_BOUNDS_ERROR_IS_ADDED;
329 location_boundary_free(handle->boundary);
330 handle->user_cb = NULL;
331 handle->user_data = NULL;
334 return LOCATION_BOUNDS_ERROR_NONE;
337 EXPORT_API int location_bounds_set_state_changed_cb(location_bounds_h bounds, location_bounds_state_changed_cb callback, void *user_data)
339 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
340 LOCATIONS_NULL_ARG_CHECK(bounds);
341 LOCATIONS_NULL_ARG_CHECK(callback);
343 location_bounds_s *handle = (location_bounds_s *) bounds;
344 handle->user_cb = callback;
345 handle->user_data = user_data;
346 return LOCATION_BOUNDS_ERROR_NONE;
349 EXPORT_API int location_bounds_unset_state_changed_cb(location_bounds_h bounds)
351 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
352 LOCATIONS_NULL_ARG_CHECK(bounds);
354 location_bounds_s *handle = (location_bounds_s *) bounds;
355 handle->user_cb = NULL;
356 handle->user_data = NULL;
357 return LOCATION_BOUNDS_ERROR_NONE;