Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
test-geo-in-rectangle.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2; coding: utf-8 -*- */
2 /*
3  Copyright (C) 2011 Kouhei Sutou <kou@clear-code.com>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License version 2.1 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 #include <gcutter.h>
20 #include <glib/gstdio.h>
21 
22 #include "../lib/grn-assertions.h"
23 
24 #include <str.h>
25 #include <geo.h>
26 
27 #define get(name) grn_ctx_get(context, name, strlen(name))
28 
29 void test_in(void);
30 void test_not_in(void);
31 void test_select(void);
32 void data_cursor(void);
33 void test_cursor(gconstpointer data);
34 void test_estimate(void);
35 
36 static gchar *tmp_directory;
37 
38 static grn_ctx *context;
39 static grn_obj *database, *shops, *location_index, *result;
40 
41 #define DEFINE_GEO_POINT(name) \
42  static grn_obj *name ## _wgs84, *name ## _text
43 DEFINE_GEO_POINT(nezu_no_taiyaki);
44 DEFINE_GEO_POINT(takane);
45 DEFINE_GEO_POINT(sazare);
46 DEFINE_GEO_POINT(yanagi_ya);
47 DEFINE_GEO_POINT(hiiragi);
48 DEFINE_GEO_POINT(tokyo);
49 DEFINE_GEO_POINT(shinjuku);
50 DEFINE_GEO_POINT(nerima);
51 #undef DEFINE_GEO_POINT
52 
53 void
55 {
56  tmp_directory = g_build_filename(grn_test_get_tmp_dir(),
57  "geo-in-rectangle",
58  NULL);
59 }
60 
61 void
63 {
64  g_free(tmp_directory);
65 }
66 
67 static void
68 remove_tmp_directory(void)
69 {
70  cut_remove_path(tmp_directory, NULL);
71 }
72 
73 static grn_obj *
74 text_geo_point_open(double latitude, double longitude)
75 {
76  grn_obj *point;
77 
78  point = grn_obj_open(context, GRN_BULK, 0, GRN_DB_SHORT_TEXT);
79  GRN_TEXT_PUTS(context, point, cut_take_printf("%f,%f", latitude, longitude));
80  return point;
81 }
82 
83 static grn_obj *
84 wgs84_geo_point_open(double latitude, double longitude)
85 {
86  grn_obj *point, *point_text;
87 
88  point_text = text_geo_point_open(latitude, longitude);
89  point = grn_obj_open(context, GRN_BULK, 0, GRN_DB_WGS84_GEO_POINT);
90  grn_obj_cast(context, point_text, point, GRN_FALSE);
91  grn_obj_unlink(context, point_text);
92  return point;
93 }
94 
95 static void
96 setup_values(void)
97 {
98 #define SETUP_GEO_POINT(name, latitude, longitude) \
99  name ## _wgs84 = wgs84_geo_point_open(latitude, longitude); \
100  name ## _text = text_geo_point_open(latitude, longitude)
101 
102  SETUP_GEO_POINT(nezu_no_taiyaki, 35.720253, 139.762573);
103  SETUP_GEO_POINT(takane, 35.698601, 139.560913);
104  SETUP_GEO_POINT(sazare, 35.714653, 139.685043);
105  SETUP_GEO_POINT(yanagi_ya, 35.685341, 139.783981);
106  SETUP_GEO_POINT(hiiragi, 35.647701, 139.711517);
107 
108  SETUP_GEO_POINT(tokyo, 35.6814, 139.7660);
109  SETUP_GEO_POINT(shinjuku, 35.6908, 139.7002);
110  SETUP_GEO_POINT(nerima, 35.7377, 139.6535);
111 
112 #undef SETUP_GEO_POINT
113 }
114 
115 static void
116 load_data(void)
117 {
118  assert_send_commands(cut_get_fixture_data_string("ddl.grn", NULL));
119  assert_send_command(cut_get_fixture_data_string("shops.grn", NULL));
120 }
121 
122 void
124 {
125  const gchar *database_path;
126 
127  cut_set_fixture_data_dir(grn_test_get_base_dir(),
128  "fixtures",
129  "story",
130  "taiyaki",
131  NULL);
132 
133  remove_tmp_directory();
134  g_mkdir_with_parents(tmp_directory, 0700);
135 
136  context = g_new0(grn_ctx, 1);
137  grn_ctx_init(context, 0);
138 
139  database_path = cut_build_path(tmp_directory, "database.groonga", NULL);
140  database = grn_db_create(context, database_path, NULL);
141 
142  setup_values();
143  load_data();
144 
145  shops = get("Shops");
146  location_index = get("Locations.shop");
147 
148  result = grn_table_create(context,
149  NULL, 0,
150  NULL,
152  shops, NULL);
153 }
154 
155 static void
156 teardown_values(void)
157 {
158 #define UNLINK_GEO_POINT(name) \
159  grn_obj_unlink(context, name ## _wgs84); \
160  grn_obj_unlink(context, name ## _text)
161 
162  UNLINK_GEO_POINT(nezu_no_taiyaki);
163  UNLINK_GEO_POINT(takane);
164  UNLINK_GEO_POINT(sazare);
165  UNLINK_GEO_POINT(yanagi_ya);
166  UNLINK_GEO_POINT(hiiragi);
167 
168  UNLINK_GEO_POINT(tokyo);
169  UNLINK_GEO_POINT(shinjuku);
170  UNLINK_GEO_POINT(nerima);
171 
172 #undef UNLINK_GEO_POINT
173 }
174 
175 void
177 {
178  teardown_values();
179 
180  grn_obj_unlink(context, result);
181  grn_obj_unlink(context, location_index);
182  grn_obj_close(context, database);
183  grn_ctx_fin(context);
184  g_free(context);
185 
186  remove_tmp_directory();
187 }
188 
189 void
190 test_in(void)
191 {
192  cut_assert_true(grn_geo_in_rectangle(context,
193  shinjuku_wgs84,
194  sazare_wgs84,
195  hiiragi_wgs84));
196 }
197 
198 void
200 {
201  cut_assert_false(grn_geo_in_rectangle(context,
202  tokyo_wgs84,
203  sazare_wgs84,
204  hiiragi_wgs84));
205 }
206 
207 static GList *
208 result_to_list(void)
209 {
210  GList *list = NULL;
211  grn_table_cursor *cursor;
212 
213  cursor = grn_table_cursor_open(context, result,
214  NULL, 0,
215  NULL, 0,
216  0, -1,
218  while ((grn_table_cursor_next(context, cursor))) {
219  void *result_key;
220  gint result_key_size;
221  grn_id shop_id;
222  gchar key[GRN_TABLE_MAX_KEY_SIZE];
223  gint key_size;
224 
225  result_key_size = grn_table_cursor_get_key(context, cursor, &result_key);
226  memcpy(&shop_id, result_key, result_key_size);
227  key_size = grn_table_get_key(context, shops, shop_id,
228  &key, GRN_TABLE_MAX_KEY_SIZE);
229  list = g_list_append(list, g_strndup(key, key_size));
230  }
231  gcut_take_list(list, g_free);
232 
233  return list;
234 }
235 
236 void
238 {
240  location_index,
241  nerima_wgs84, tokyo_wgs84,
242  result, GRN_OP_OR));
243  gcut_assert_equal_list_string(
244  gcut_take_new_list_string("soba-taiyaki-ku",
245  "sazare",
246  "hirose-ya",
247  "taiyaki-kataoka",
248  "kuruma",
249  "nezu-no-taiyaki",
250  NULL),
251  result_to_list());
252 }
253 
254 void
255 data_cursor(void)
256 {
257 #define ADD_DATA(label, expected, offset, limit) \
258  gcut_add_datum(label, \
259  "expected", G_TYPE_POINTER, expected, gcut_list_string_free, \
260  "offset", G_TYPE_INT, offset, \
261  "limit", G_TYPE_INT, limit, \
262  NULL)
263 
264  ADD_DATA("all",
265  gcut_list_string_new("soba-taiyaki-ku",
266  "sazare",
267  "hirose-ya",
268  "taiyaki-kataoka",
269  "kuruma",
270  "nezu-no-taiyaki",
271  NULL),
272  0, -1);
273  ADD_DATA("offset",
274  gcut_list_string_new("hirose-ya",
275  "taiyaki-kataoka",
276  "kuruma",
277  "nezu-no-taiyaki",
278  NULL),
279  2, -1);
280  ADD_DATA("limit",
281  gcut_list_string_new("soba-taiyaki-ku",
282  "sazare",
283  "hirose-ya",
284  NULL),
285  0, 3);
286  ADD_DATA("offset - limit",
287  gcut_list_string_new("hirose-ya",
288  "taiyaki-kataoka",
289  "kuruma",
290  NULL),
291  2, 3);
292  ADD_DATA("over offset",
293  NULL,
294  100, -1);
295  ADD_DATA("0 limit",
296  NULL,
297  0, 0);
298 
299 #undef ADD_DATA
300 }
301 
302 void
303 test_cursor(gconstpointer data)
304 {
305  GList *expected, *records = NULL;
306  gint offset, limit;
307  grn_obj *geo_cursor;
308  grn_posting *posting;
309 
310  offset = gcut_data_get_int(data, "offset");
311  limit = gcut_data_get_int(data, "limit");
312  geo_cursor = grn_geo_cursor_open_in_rectangle(context,
313  location_index,
314  nerima_wgs84, tokyo_wgs84,
315  offset, limit);
316  while ((posting = grn_geo_cursor_next(context, geo_cursor))) {
317  grn_id shop_id = posting->rid;
318  gchar key[GRN_TABLE_MAX_KEY_SIZE];
319  gint key_size;
320 
321  key_size = grn_table_get_key(context, shops, shop_id,
322  &key, GRN_TABLE_MAX_KEY_SIZE);
323  records = g_list_append(records, g_strndup(key, key_size));
324  }
325  grn_obj_unlink(context, geo_cursor);
326 
327  expected = (GList *)gcut_data_get_pointer(data, "expected");
328  gcut_take_list(records, g_free);
329  gcut_assert_equal_list_string(expected, records);
330 }
331 
332 void
334 {
335  cut_assert_equal_int(4,
337  location_index,
338  sazare_wgs84,
339  tokyo_wgs84));
340 }