tizen beta release
[platform/core/location/lbs-location.git] / location / location-common-util.c
1 /*
2  * libslp-location
3  *
4  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Youngae Kang <youngae.kang@samsung.com>, Yunhan Kim <yhan.kim@samsung.com>,
7  *          Genie Kim <daejins.kim@samsung.com>, Minjune Kim <sena06.kim@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #include "location.h"
23 #include "location-common-util.h"
24 #include "location-setting.h"
25 #include "location-log.h"
26
27 static gint compare_position (gconstpointer a, gconstpointer b)
28 {
29         g_return_val_if_fail(a, 1);
30         g_return_val_if_fail(b, -1);
31
32         if(location_position_equal((LocationPosition*) a, (LocationPosition *)b) == TRUE) {
33                 return 0;
34         }
35
36         return -1;
37 }
38
39 static int
40 boundary_compare (gconstpointer comp1, gconstpointer comp2)
41 {
42         g_return_val_if_fail(comp1, 1);
43         g_return_val_if_fail(comp2, -1);
44
45         int ret = -1;
46
47         LocationBoundary *boundary1 = (LocationBoundary *)comp1;
48         LocationBoundary *boundary2 = (LocationBoundary *)comp2;
49
50         if (boundary1->type == boundary2->type) {
51                 switch (boundary1->type) {
52                         case LOCATION_BOUNDARY_CIRCLE: {
53                                 if (location_position_equal(boundary1->circle.center, boundary2->circle.center)
54                                         && boundary1->circle.radius == boundary2->circle.radius) {
55                                         ret = 0;
56                                 }
57                                 break;
58                         }
59                         case LOCATION_BOUNDARY_RECT: {
60                                 if (location_position_equal(boundary1->rect.left_top, boundary2->rect.left_top)
61                                         && location_position_equal(boundary1->rect.right_bottom, boundary2->rect.right_bottom)) {
62                                         ret = 0;
63                                 }
64                                 break;
65                         }
66                         case LOCATION_BOUNDARY_POLYGON: {
67
68                                 GList *boundary1_next = NULL;
69                                 GList *boundary2_start = NULL, *boundary2_prev = NULL, *boundary2_next = NULL;
70                                 if (g_list_length(boundary1->polygon.position_list) != g_list_length(boundary2->polygon.position_list)) {
71                                         return -1;
72                                 }
73
74                                 // Find a matching index of Boundary2 with Boundary1's 1st postion.
75                                 boundary2_start = g_list_find_custom(boundary2->polygon.position_list, g_list_nth_data(boundary1->polygon.position_list, 0), (GCompareFunc) compare_position);
76                                 if (boundary2_start == NULL) return -1;
77
78                                 boundary2_prev = g_list_previous(boundary2_start);
79                                 boundary2_next = g_list_next(boundary2_start);
80                                 if (boundary2_prev == NULL) boundary2_prev = g_list_last(boundary2->polygon.position_list);
81                                 if (boundary2_next == NULL) boundary2_next = g_list_first(boundary2->polygon.position_list);
82
83                                 boundary1_next = g_list_next(boundary1->polygon.position_list);
84                                 if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*)boundary2_prev->data) == TRUE){
85                                         boundary1_next = g_list_next(boundary1_next);
86                                         while (boundary1_next) {
87                                                 boundary2_prev = g_list_previous(boundary2_prev);
88                                                 if (boundary2_prev == NULL) boundary2_prev = g_list_last(boundary2->polygon.position_list);
89                                                 if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*) boundary2_prev->data) == FALSE){
90                                                         return -1;
91                                                 }
92                                                 boundary1_next = g_list_next(boundary1_next);
93                                         }
94                                         ret = 0;
95                                 }
96                                 else if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*)boundary2_next->data) == TRUE) {
97                                         boundary1_next = g_list_next(boundary1_next);
98                                         while(boundary1_next) {
99                                                 boundary2_next = g_list_next(boundary2_next);
100                                                 if (boundary2_next == NULL) boundary2_next = g_list_first(boundary2->polygon.position_list);
101                                                 if (location_position_equal((LocationPosition*)boundary1_next->data, (LocationPosition*) boundary2_next->data) == FALSE){
102                                                         return -1;
103                                                 }
104                                                 boundary1_next = g_list_next(boundary1_next);
105                                         }
106                                         ret = 0;
107                                 }
108                                 else {
109                                         return -1;
110                                 }
111                                 break;
112                         }
113                         default:{
114                                  ret = -1;
115                                  break;
116                         }
117
118                 }
119         }
120
121         return ret;
122 }
123
124 int set_prop_boundary(GList **prev_boundary_list, GList *new_boundary_list)
125 {
126         g_return_val_if_fail(new_boundary_list, LOCATION_ERROR_PARAMETER);
127
128         int index;
129         GList *check_list = NULL;
130
131         LocationBoundary *new_boundary = NULL;
132         LocationBoundary *copy_boundary = NULL;
133
134         index = 0;
135         while((new_boundary = (LocationBoundary*) g_list_nth_data(new_boundary_list, index)) != NULL) {
136
137                 check_list = g_list_find_custom(*prev_boundary_list, new_boundary, (GCompareFunc)boundary_compare);
138                 if (check_list == NULL) {
139                         LOCATION_LOGD("Set Prop >> boundary type: [%d]", new_boundary->type);
140                         copy_boundary = location_boundary_copy(new_boundary);
141                         *prev_boundary_list = g_list_append(*prev_boundary_list, copy_boundary);
142                 }
143                 index++;
144         }
145         *prev_boundary_list = g_list_first(*prev_boundary_list);
146
147         return LOCATION_ERROR_NONE;
148 }
149
150
151
152 int set_prop_removal_boundary(GList **prev_boundary_list, LocationBoundary* boundary)
153 {
154         g_return_val_if_fail(*prev_boundary_list, LOCATION_ERROR_PARAMETER);
155
156         GList *check_list = NULL;
157
158         check_list = g_list_find_custom (*prev_boundary_list, boundary, (GCompareFunc) boundary_compare);
159         if (check_list) {
160                 LOCATION_LOGD("Found");
161                 *prev_boundary_list = g_list_delete_link(*prev_boundary_list, check_list);
162         }
163
164         if (g_list_length(*prev_boundary_list) == 0 ) {
165                 LOCATION_LOGD("Boundary List is empty");
166                 g_list_free(*prev_boundary_list);
167                 *prev_boundary_list = NULL;
168         }
169
170         return LOCATION_ERROR_NONE;
171 }
172
173 int get_last_known_position (LocationMethod method, LocationLastPosition *last_pos)
174 {
175         int timestamp = 0;
176         double longitude = 0.0, latitude = 0.0, altitude = 0.0;
177         double hor_accuracy = 0.0, ver_accuracy = 0.0;
178         LOCATION_LOGD("Method [%d]", method);
179         switch (method) {
180                 case LOCATION_METHOD_SPS:
181                         if (vconf_get_int(SPS_LAST_TIMESTAMP, &timestamp) ||
182                                 vconf_get_dbl(SPS_LAST_LATITUDE, &latitude) ||
183                                 vconf_get_dbl(SPS_LAST_LONGITUDE, &longitude) ||
184                                 vconf_get_dbl(SPS_LAST_ALTITUDE, &altitude) ||
185                                 vconf_get_dbl(SPS_LAST_HORACCURACY, &hor_accuracy) ||
186                                 vconf_get_dbl(SPS_LAST_VERACCURACY, &ver_accuracy)) {
187                                 return -1;
188                         }
189                         break;
190                 case LOCATION_METHOD_WPS:
191                         if (vconf_get_int(WPS_LAST_TIMESTAMP, &timestamp) ||
192                                 vconf_get_dbl(WPS_LAST_LATITUDE, &latitude) ||
193                                 vconf_get_dbl(WPS_LAST_LONGITUDE, &longitude) ||
194                                 vconf_get_dbl(WPS_LAST_ALTITUDE, &altitude) ||
195                                 vconf_get_dbl(WPS_LAST_HORACCURACY, &hor_accuracy)) {
196                                 return -1;
197                         }
198                         break;
199                 case LOCATION_METHOD_GPS:
200                         if (vconf_get_int(GPS_LAST_TIMESTAMP, &timestamp) ||
201                                 vconf_get_dbl(GPS_LAST_LATITUDE, &latitude) ||
202                                 vconf_get_dbl(GPS_LAST_LONGITUDE, &longitude) ||
203                                 vconf_get_dbl(GPS_LAST_ALTITUDE, &altitude) ||
204                                 vconf_get_dbl(GPS_LAST_HORACCURACY, &hor_accuracy) ||
205                                 vconf_get_dbl(GPS_LAST_VERACCURACY, &ver_accuracy)) {
206                                 return -1;
207                         }
208                         break;
209                 case LOCATION_METHOD_HYBRID:
210                 default:
211                         return -1;
212
213         }
214
215         last_pos->method = method;
216         last_pos->timestamp = (guint) timestamp;
217         last_pos->longitude = (gdouble) longitude;
218         last_pos->latitude = (gdouble) latitude;
219         last_pos->altitude = (gdouble) altitude;
220         last_pos->horizontal_accuracy = (gdouble) hor_accuracy;
221         last_pos->vertical_accuracy = (gdouble) ver_accuracy;
222
223         return 0;
224 }
225
226