2 * Copyright (c) 2011 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 <location_bounds.h>
21 #include <locations_private.h>
24 #define LOCATIONS_NULL_ARG_CHECK(arg) \
25 LOCATIONS_CHECK_CONDITION((arg != NULL),LOCATION_BOUNDS_ERROR_INVALID_PARAMETER,"LOCATION_BOUNDS_ERROR_INVALID_PARAMETER") \
27 static void __free_position_list(gpointer data)
32 LocationPosition *position = (LocationPosition *) data;
33 location_position_free(position);
36 static location_bounds_type_e __convert_bounds_type(LocationBoundaryType type)
38 location_bounds_type_e ret;
40 case LOCATION_BOUNDARY_CIRCLE:
41 ret = LOCATION_BOUNDS_CIRCLE;
43 case LOCATION_BOUNDARY_POLYGON:
44 ret = LOCATION_BOUNDS_POLYGON;
46 case LOCATION_BOUNDARY_NONE:
47 case LOCATION_BOUNDARY_RECT:
49 ret = LOCATION_BOUNDS_RECT;
55 int location_bounds_create_rect(location_coords_s top_left, location_coords_s bottom_right, location_bounds_h * bounds)
57 LOCATIONS_NULL_ARG_CHECK(bounds);
58 LOCATIONS_CHECK_CONDITION(top_left.latitude>=-90 && top_left.latitude<=90,LOCATION_BOUNDS_ERROR_INVALID_PARAMETER,"LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
59 LOCATIONS_CHECK_CONDITION(top_left.longitude>=-180 && top_left.longitude<=180,LOCATION_BOUNDS_ERROR_INVALID_PARAMETER, "LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
60 LOCATIONS_CHECK_CONDITION(bottom_right.latitude>=-90 && bottom_right.latitude<=90,LOCATION_BOUNDS_ERROR_INVALID_PARAMETER, "LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
61 LOCATIONS_CHECK_CONDITION(bottom_right.longitude>=-180 && bottom_right.longitude<=180,LOCATION_BOUNDS_ERROR_INVALID_PARAMETER, "LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
63 LocationPosition *lt = location_position_new(0, top_left.latitude, top_left.longitude, 0, LOCATION_STATUS_2D_FIX);
65 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
66 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
69 LocationPosition *rb = location_position_new(0, bottom_right.latitude, bottom_right.longitude, 0, LOCATION_STATUS_2D_FIX);
71 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
72 location_position_free(lt);
73 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
76 location_bounds_s *handle = (location_bounds_s *) malloc(sizeof(location_bounds_s));
78 LOCATIONS_LOGE("OUT_OF_MEMORY(0x%08x)", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
79 location_position_free(rb);
80 location_position_free(lt);
81 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
83 memset(handle, 0, sizeof(location_bounds_s));
85 handle->is_added = FALSE;
86 handle->boundary = location_boundary_new_for_rect(lt, rb);
87 location_position_free(rb);
88 location_position_free(lt);
89 if (handle->boundary == NULL) {
90 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_boundary_new_for_rect", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
92 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
94 handle->user_cb = NULL;
95 handle->user_data = NULL;
97 *bounds = (location_bounds_h) handle;
98 return LOCATION_BOUNDS_ERROR_NONE;
101 int location_bounds_create_circle(location_coords_s center, double radius, location_bounds_h * bounds)
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 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_boundary_new_for_circle", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
128 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
130 handle->user_cb = NULL;
131 handle->user_data = NULL;
133 *bounds = (location_bounds_h) handle;
134 return LOCATION_BOUNDS_ERROR_NONE;
137 int location_bounds_create_polygon(location_coords_s * coords_list, int length, location_bounds_h * bounds)
139 LOCATIONS_NULL_ARG_CHECK(coords_list);
140 LOCATIONS_NULL_ARG_CHECK(bounds);
141 LOCATIONS_CHECK_CONDITION(length>=3, LOCATION_BOUNDS_ERROR_INVALID_PARAMETER, "LOCATION_BOUNDS_ERROR_INVALID_PARAMETER");
144 GList *position_list = NULL;
145 LocationPosition *position = NULL;
148 for (i = 0; i < length; i++) {
149 if (coords_list[i].latitude < -90 || coords_list[i].latitude > 90 || coords_list[i].longitude < -180 || coords_list[i].longitude > 180) {
150 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INVALID_PARAMETER(0x%08x)", LOCATION_BOUNDS_ERROR_INVALID_PARAMETER);
154 position = location_position_new(0, coords_list[i].latitude, coords_list[i].longitude, 0.0, LOCATION_STATUS_2D_FIX);
155 position_list = g_list_append(position_list, position);
156 location_position_free(position);
161 g_list_free_full(position_list, (GDestroyNotify) __free_position_list);
162 return LOCATION_BOUNDS_ERROR_INVALID_PARAMETER;
165 if (position_list == NULL) {
166 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
167 g_list_free_full(position_list, (GDestroyNotify) __free_position_list);
168 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
171 location_bounds_s *handle = (location_bounds_s *) malloc(sizeof(location_bounds_s));
172 if (handle == NULL) {
173 LOCATIONS_LOGE("OUT_OF_MEMORY(0x%08x)", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
174 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
176 memset(handle, 0, sizeof(location_bounds_s));
178 handle->is_added = FALSE;
179 handle->boundary = location_boundary_new_for_polygon(position_list);
180 if (handle->boundary == NULL) {
181 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_boundary_new_for_polygon", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
183 return LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY;
185 handle->user_cb = NULL;
186 handle->user_data = NULL;
188 *bounds = (location_bounds_h) handle;
189 return LOCATION_BOUNDS_ERROR_NONE;
192 bool location_bounds_contains_coordinates(location_bounds_h bounds, location_coords_s coords)
197 if (coords.latitude < -90 || coords.latitude > 90 || coords.longitude < -180 || coords.longitude > 180)
200 LocationPosition *pos = location_position_new(0, coords.latitude, coords.longitude, 0, LOCATION_STATUS_2D_FIX);
202 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY(0x%08x) : fail to location_position_new", LOCATION_BOUNDS_ERROR_OUT_OF_MEMORY);
205 location_bounds_s *handle = (location_bounds_s *) bounds;
206 gboolean is_inside = location_boundary_if_inside(handle->boundary, pos);
207 location_position_free(pos);
208 bool result = is_inside ? TRUE : FALSE;
212 int location_bounds_get_type(location_bounds_h bounds, location_bounds_type_e * type)
214 LOCATIONS_NULL_ARG_CHECK(bounds);
215 LOCATIONS_NULL_ARG_CHECK(type);
216 location_bounds_s *handle = (location_bounds_s *) bounds;
217 *type = __convert_bounds_type(handle->boundary->type);
218 return LOCATION_BOUNDS_ERROR_NONE;
221 int location_bounds_get_rect_coords(location_bounds_h bounds, location_coords_s * top_left, location_coords_s * bottom_right)
223 LOCATIONS_NULL_ARG_CHECK(bounds);
224 LOCATIONS_NULL_ARG_CHECK(top_left);
225 LOCATIONS_NULL_ARG_CHECK(bottom_right);
226 location_bounds_s *handle = (location_bounds_s *) bounds;
227 if (__convert_bounds_type(handle->boundary->type) != LOCATION_BOUNDS_RECT) {
228 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INCORRECT_TYPE(0x%08x)", LOCATION_BOUNDS_ERROR_INCORRECT_TYPE);
229 return LOCATION_BOUNDS_ERROR_INCORRECT_TYPE;
232 top_left->latitude = handle->boundary->rect.left_top->latitude;
233 top_left->longitude = handle->boundary->rect.left_top->longitude;
234 bottom_right->latitude = handle->boundary->rect.right_bottom->latitude;
235 bottom_right->longitude = handle->boundary->rect.right_bottom->longitude;
236 return LOCATION_BOUNDS_ERROR_NONE;
239 int location_bounds_get_circle_coords(location_bounds_h bounds, location_coords_s * center, double *radius)
241 LOCATIONS_NULL_ARG_CHECK(bounds);
242 LOCATIONS_NULL_ARG_CHECK(center);
243 LOCATIONS_NULL_ARG_CHECK(radius);
244 location_bounds_s *handle = (location_bounds_s *) bounds;
245 if (__convert_bounds_type(handle->boundary->type) != LOCATION_BOUNDS_CIRCLE) {
246 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INCORRECT_TYPE(0x%08x)", LOCATION_BOUNDS_ERROR_INCORRECT_TYPE);
247 return LOCATION_BOUNDS_ERROR_INCORRECT_TYPE;
250 center->latitude = handle->boundary->circle.center->latitude;
251 center->longitude = handle->boundary->circle.center->longitude;
252 *radius = handle->boundary->circle.radius;
253 return LOCATION_BOUNDS_ERROR_NONE;
256 int location_bounds_foreach_polygon_coords(location_bounds_h bounds, polygon_coords_cb callback, void *user_data)
258 LOCATIONS_NULL_ARG_CHECK(bounds);
259 LOCATIONS_NULL_ARG_CHECK(callback);
260 location_bounds_s *handle = (location_bounds_s *) bounds;
261 if (__convert_bounds_type(handle->boundary->type) != LOCATION_BOUNDS_POLYGON) {
262 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_INCORRECT_TYPE(0x%08x)", LOCATION_BOUNDS_ERROR_INCORRECT_TYPE);
263 return LOCATION_BOUNDS_ERROR_INCORRECT_TYPE;
266 GList *list = handle->boundary->polygon.position_list;
268 LocationPosition *pos = list->data;
269 location_coords_s coords;
270 coords.latitude = pos->latitude;
271 coords.longitude = pos->longitude;
273 if (callback(coords, user_data) != TRUE) {
274 LOCATIONS_LOGI("User quit the loop ");
277 list = g_list_next(list);
279 return LOCATION_BOUNDS_ERROR_NONE;
282 int location_bounds_destroy(location_bounds_h bounds)
284 LOCATIONS_NULL_ARG_CHECK(bounds);
285 location_bounds_s *handle = (location_bounds_s *) bounds;
286 if (handle->is_added) {
287 LOCATIONS_LOGE("LOCATION_BOUNDS_ERROR_IS_ADDED(0x%08x)", LOCATION_BOUNDS_ERROR_IS_ADDED);
288 return LOCATION_BOUNDS_ERROR_IS_ADDED;
290 location_boundary_free(handle->boundary);
291 handle->user_cb = NULL;
292 handle->user_data = NULL;
295 return LOCATION_BOUNDS_ERROR_NONE;
298 int location_bounds_set_state_changed_cb(location_bounds_h bounds, location_bounds_state_changed_cb callback, void *user_data)
300 LOCATIONS_NULL_ARG_CHECK(bounds);
301 LOCATIONS_NULL_ARG_CHECK(callback);
302 location_bounds_s *handle = (location_bounds_s *) bounds;
303 handle->user_cb = callback;
304 handle->user_data = user_data;
305 return LOCATION_BOUNDS_ERROR_NONE;
308 int location_bounds_unset_state_changed_cb(location_bounds_h bounds)
310 LOCATIONS_NULL_ARG_CHECK(bounds);
311 location_bounds_s *handle = (location_bounds_s *) bounds;
312 handle->user_cb = NULL;
313 handle->user_data = NULL;
314 return LOCATION_BOUNDS_ERROR_NONE;