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);
163 location_position_free(position);
168 g_list_free_full(position_list, (GDestroyNotify) __free_position_list);
169 return LOCATION_BOUNDS_ERROR_INVALID_PARAMETER;
172 if (position_list == NULL) {
173 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
174 g_list_free_full(position_list, (GDestroyNotify) __free_position_list);
175 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
178 location_bounds_s *handle = (location_bounds_s *) malloc(sizeof(location_bounds_s));
179 if (handle == NULL) {
180 LOCATIONS_LOGE("OUT_OF_MEMORY(0x%08x)", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
181 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
183 memset(handle, 0, sizeof(location_bounds_s));
185 handle->is_added = FALSE;
186 handle->boundary = location_boundary_new_for_polygon(position_list);
187 if (handle->boundary == NULL) {
188 int ret = get_last_result();
190 if (ret == LOCATION_ERROR_PARAMETER) {
191 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INVALID_PARAMETER(0x%08x) fail to location_boundary_new_for_polygon", LOCATION_BOUNDS_ERROR_INVALID_PARAMETER);
192 return LOCATION_BOUNDS_ERROR_INVALID_PARAMETER;
194 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_boundary_new_for_polygon", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
195 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
198 handle->user_cb = NULL;
199 handle->user_data = NULL;
201 *bounds = (location_bounds_h) handle;
202 return LOCATION_BOUNDS_ERROR_NONE;
205 EXPORT_API bool location_bounds_contains_coordinates(location_bounds_h bounds, location_coords_s coords)
207 if (__is_location_supported() == LOCATIONS_ERROR_NOT_SUPPORTED) {
208 set_last_result(LOCATIONS_ERROR_NOT_SUPPORTED);
213 set_last_result(LOCATION_BOUNDS_ERROR_INVALID_PARAMETER);
217 if (coords.latitude < -90 || coords.latitude > 90 || coords.longitude < -180 || coords.longitude > 180) {
218 set_last_result(LOCATION_BOUNDS_ERROR_INVALID_PARAMETER);
222 LocationPosition *pos = location_position_new(0, coords.latitude, coords.longitude, 0, LOCATION_STATUS_2D_FIX);
224 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
225 set_last_result(LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
228 location_bounds_s *handle = (location_bounds_s *) bounds;
229 gboolean is_inside = location_boundary_if_inside(handle->boundary, pos);
230 location_position_free(pos);
231 bool result = is_inside ? TRUE : FALSE;
233 set_last_result(LOCATION_BOUNDS_ERROR_NONE);
237 EXPORT_API int location_bounds_get_type(location_bounds_h bounds, location_bounds_type_e *type)
239 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
240 LOCATIONS_NULL_ARG_CHECK(bounds);
241 LOCATIONS_NULL_ARG_CHECK(type);
243 location_bounds_s *handle = (location_bounds_s *) bounds;
244 *type = __convert_bounds_type(handle->boundary->type);
245 return LOCATION_BOUNDS_ERROR_NONE;
248 EXPORT_API int location_bounds_get_rect_coords(location_bounds_h bounds, location_coords_s *top_left, location_coords_s *bottom_right)
250 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
251 LOCATIONS_NULL_ARG_CHECK(bounds);
252 LOCATIONS_NULL_ARG_CHECK(top_left);
253 LOCATIONS_NULL_ARG_CHECK(bottom_right);
255 location_bounds_s *handle = (location_bounds_s *) bounds;
256 if (__convert_bounds_type(handle->boundary->type) != LOCATION_BOUNDS_RECT) {
257 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INCORRECT_TYPE(0x%08x)", LOCATION_BOUNDS_ERROR_INCORRECT_TYPE);
258 return LOCATION_BOUNDS_ERROR_INCORRECT_TYPE;
261 top_left->latitude = handle->boundary->rect.left_top->latitude;
262 top_left->longitude = handle->boundary->rect.left_top->longitude;
263 bottom_right->latitude = handle->boundary->rect.right_bottom->latitude;
264 bottom_right->longitude = handle->boundary->rect.right_bottom->longitude;
265 return LOCATION_BOUNDS_ERROR_NONE;
268 EXPORT_API int location_bounds_get_circle_coords(location_bounds_h bounds, location_coords_s *center, double *radius)
270 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
271 LOCATIONS_NULL_ARG_CHECK(bounds);
272 LOCATIONS_NULL_ARG_CHECK(center);
273 LOCATIONS_NULL_ARG_CHECK(radius);
275 location_bounds_s *handle = (location_bounds_s *) bounds;
276 if (__convert_bounds_type(handle->boundary->type) != LOCATION_BOUNDS_CIRCLE) {
277 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INCORRECT_TYPE(0x%08x)", LOCATION_BOUNDS_ERROR_INCORRECT_TYPE);
278 return LOCATION_BOUNDS_ERROR_INCORRECT_TYPE;
281 center->latitude = handle->boundary->circle.center->latitude;
282 center->longitude = handle->boundary->circle.center->longitude;
283 *radius = handle->boundary->circle.radius;
284 return LOCATION_BOUNDS_ERROR_NONE;
287 EXPORT_API int location_bounds_foreach_polygon_coords(location_bounds_h bounds, polygon_coords_cb callback, void *user_data)
289 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
290 LOCATIONS_NULL_ARG_CHECK(bounds);
291 LOCATIONS_NULL_ARG_CHECK(callback);
293 location_bounds_s *handle = (location_bounds_s *) bounds;
294 if (__convert_bounds_type(handle->boundary->type) != LOCATION_BOUNDS_POLYGON) {
295 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INCORRECT_TYPE(0x%08x)", LOCATION_BOUNDS_ERROR_INCORRECT_TYPE);
296 return LOCATION_BOUNDS_ERROR_INCORRECT_TYPE;
299 GList *list = handle->boundary->polygon.position_list;
301 LocationPosition *pos = list->data;
302 location_coords_s coords;
303 coords.latitude = pos->latitude;
304 coords.longitude = pos->longitude;
306 if (callback(coords, user_data) != TRUE) {
307 LOCATIONS_LOGI("User quit the loop ");
310 list = g_list_next(list);
312 return LOCATION_BOUNDS_ERROR_NONE;
315 EXPORT_API int location_bounds_destroy(location_bounds_h bounds)
317 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
318 LOCATIONS_NULL_ARG_CHECK(bounds);
320 location_bounds_s *handle = (location_bounds_s *) bounds;
321 if (handle->is_added) {
322 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_IS_ADDED(0x%08x)", LOCATION_BOUNDS_ERROR_IS_ADDED);
323 return LOCATION_BOUNDS_ERROR_IS_ADDED;
325 location_boundary_free(handle->boundary);
326 handle->user_cb = NULL;
327 handle->user_data = NULL;
330 return LOCATION_BOUNDS_ERROR_NONE;
333 EXPORT_API int location_bounds_set_state_changed_cb(location_bounds_h bounds, location_bounds_state_changed_cb callback, void *user_data)
335 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
336 LOCATIONS_NULL_ARG_CHECK(bounds);
337 LOCATIONS_NULL_ARG_CHECK(callback);
339 location_bounds_s *handle = (location_bounds_s *) bounds;
340 handle->user_cb = callback;
341 handle->user_data = user_data;
342 return LOCATION_BOUNDS_ERROR_NONE;
345 EXPORT_API int location_bounds_unset_state_changed_cb(location_bounds_h bounds)
347 LOCATIONS_NOT_SUPPORTED_CHECK(__is_location_supported());
348 LOCATIONS_NULL_ARG_CHECK(bounds);
350 location_bounds_s *handle = (location_bounds_s *) bounds;
351 handle->user_cb = NULL;
352 handle->user_data = NULL;
353 return LOCATION_BOUNDS_ERROR_NONE;