Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
test-geo.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 2; coding: utf-8 -*- */
2 /*
3  Copyright (C) 2010-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_circle(void);
30 void test_in_rectangle(void);
31 void data_distance_rectangle(void);
32 void test_distance_rectangle(gconstpointer data);
33 void test_distance_sphere(void);
34 void test_distance_ellipsoid(void);
36 
37 static gchar *tmp_directory;
38 
39 static grn_ctx *context;
40 static grn_obj *database;
41 
42 #define DEFINE_GEO_POINT(name) \
43  static grn_obj *name ## _tokyo, *name ## _wgs84, *name ## _text
44 DEFINE_GEO_POINT(nezu_no_taiyaki);
45 DEFINE_GEO_POINT(takane);
46 DEFINE_GEO_POINT(sazare);
47 DEFINE_GEO_POINT(yanagi_ya);
48 DEFINE_GEO_POINT(hiiragi);
49 DEFINE_GEO_POINT(tokyo);
50 DEFINE_GEO_POINT(shinjuku);
51 #undef DEFINE_GEO_POINT
52 
53 static grn_obj *takane, *shinjuku;
54 
55 void
57 {
58  tmp_directory = g_build_filename(grn_test_get_tmp_dir(),
59  "geo",
60  NULL);
61 }
62 
63 void
65 {
66  g_free(tmp_directory);
67 }
68 
69 static void
70 remove_tmp_directory(void)
71 {
72  cut_remove_path(tmp_directory, NULL);
73 }
74 
75 static grn_obj *
76 tokyo_geo_point_open(int latitude, int longitude)
77 {
78  grn_obj *point;
79 
80  point = grn_obj_open(context, GRN_BULK, 0, GRN_DB_TOKYO_GEO_POINT);
81  /* TODO: latitude and longitude are wgs84 format. They
82  * should be converted to tokyo from wgs84. */
83  GRN_GEO_POINT_SET(context, point, latitude, longitude);
84  return point;
85 }
86 
87 static grn_obj *
88 wgs84_geo_point_open(int latitude, int longitude)
89 {
90  grn_obj *point;
91 
92  point = grn_obj_open(context, GRN_BULK, 0, GRN_DB_WGS84_GEO_POINT);
93  GRN_GEO_POINT_SET(context, point, latitude, longitude);
94  return point;
95 }
96 
97 static grn_obj *
98 text_geo_point_open(int latitude, int longitude)
99 {
100  grn_obj *point;
101 
102  point = grn_obj_open(context, GRN_BULK, 0, GRN_DB_SHORT_TEXT);
103  GRN_TEXT_PUTS(context, point, cut_take_printf("%d,%d", latitude, longitude));
104  return point;
105 }
106 
107 static void
108 setup_values(void)
109 {
110 #define SETUP_GEO_POINT(name, latitude, longitude) \
111  name ## _tokyo = tokyo_geo_point_open(latitude, longitude); \
112  name ## _wgs84 = wgs84_geo_point_open(latitude, longitude); \
113  name ## _text = text_geo_point_open(latitude, longitude)
114 
115  SETUP_GEO_POINT(nezu_no_taiyaki, 128592911, 503145263);
116  SETUP_GEO_POINT(takane, 128514964, 502419287);
117  SETUP_GEO_POINT(sazare, 128572751, 502866155);
118  SETUP_GEO_POINT(yanagi_ya, 128467228, 503222332);
119  SETUP_GEO_POINT(hiiragi, 128331724, 502961461);
120 
121  SETUP_GEO_POINT(tokyo, 128452975, 503157902);
122  SETUP_GEO_POINT(shinjuku, 128487316, 502920929);
123 
124 #undef SETUP_GEO_POINT
125 }
126 
127 void
129 {
130  const gchar *database_path;
131 
132  cut_set_fixture_data_dir(grn_test_get_base_dir(),
133  "fixtures",
134  "story",
135  "taiyaki",
136  NULL);
137 
138  remove_tmp_directory();
139  g_mkdir_with_parents(tmp_directory, 0700);
140 
141  context = g_new0(grn_ctx, 1);
142  grn_ctx_init(context, 0);
143 
144  database_path = cut_build_path(tmp_directory, "database.groonga", NULL);
145  database = grn_db_create(context, database_path, NULL);
146 
147  setup_values();
148 }
149 
150 static void
151 teardown_values(void)
152 {
153 #define UNLINK_GEO_POINT(name) \
154  grn_obj_unlink(context, name ## _tokyo); \
155  grn_obj_unlink(context, name ## _wgs84); \
156  grn_obj_unlink(context, name ## _text)
157 
158  UNLINK_GEO_POINT(nezu_no_taiyaki);
159  UNLINK_GEO_POINT(takane);
160  UNLINK_GEO_POINT(sazare);
161  UNLINK_GEO_POINT(yanagi_ya);
162  UNLINK_GEO_POINT(hiiragi);
163 
164  UNLINK_GEO_POINT(tokyo);
165  UNLINK_GEO_POINT(shinjuku);
166 
167 #undef UNLINK_GEO_POINT
168 }
169 
170 void
172 {
173  teardown_values();
174 
175  grn_obj_close(context, database);
176  grn_ctx_fin(context);
177  g_free(context);
178 
179  remove_tmp_directory();
180 }
181 
182 void
184 {
185  cut_assert_true(grn_geo_in_circle(context,
186  hiiragi_wgs84,
187  shinjuku_wgs84,
188  tokyo_wgs84,
190  cut_assert_false(grn_geo_in_circle(context,
191  takane_wgs84,
192  shinjuku_wgs84,
193  tokyo_wgs84,
195 }
196 
197 void
199 {
200  cut_assert_true(grn_geo_in_rectangle(context,
201  shinjuku_wgs84,
202  sazare_wgs84,
203  hiiragi_wgs84));
204  cut_assert_false(grn_geo_in_rectangle(context,
205  tokyo_wgs84,
206  sazare_wgs84,
207  hiiragi_wgs84));
208 }
209 
210 static void
211 assign_shinjuku_and_takane(gconstpointer data)
212 {
213  switch (gcut_data_get_int(data, "shinjuku-geographic-coordinate-system")) {
215  shinjuku = shinjuku_tokyo;
216  break;
218  shinjuku = shinjuku_wgs84;
219  break;
220  default:
221  shinjuku = shinjuku_text;
222  break;
223  }
224 
225  switch (gcut_data_get_int(data, "takane-geographic-coordinate-system")) {
227  takane = takane_tokyo;
228  break;
230  takane = takane_wgs84;
231  break;
232  default:
233  takane = takane_text;
234  break;
235  }
236 }
237 
238 void
240 {
241 #define ADD_DATUM(label, shinjuku, takane) \
242  gcut_add_datum(label, \
243  "shinjuku-geographic-coordinate-system", \
244  G_TYPE_INT, shinjuku, \
245  "takane-geographic-coordinate-system", \
246  G_TYPE_INT, takane, \
247  NULL)
248 
249 /*
250  ADD_DATUM("tokyo - tokyo",
251  GRN_DB_TOKYO_GEO_POINT, GRN_DB_TOKYO_GEO_POINT);
252  ADD_DATUM("tokyo - wgs84",
253  GRN_DB_TOKYO_GEO_POINT, GRN_DB_WGS84_GEO_POINT);
254  ADD_DATUM("tokyo - text",
255  GRN_DB_TOKYO_GEO_POINT, GRN_DB_SHORT_TEXT);
256  ADD_DATUM("wgs84 - tokyo",
257  GRN_DB_WGS84_GEO_POINT, GRN_DB_TOKYO_GEO_POINT);
258 */
259  ADD_DATUM("wgs84 - wgs84",
261  ADD_DATUM("wgs84 - text",
263 /*
264  ADD_DATUM("text - tokyo",
265  GRN_DB_SHORT_TEXT, GRN_DB_TOKYO_GEO_POINT);
266 */
267  ADD_DATUM("text - wgs84",
269  ADD_DATUM("text - text",
271 
272 #undef ADD_DATUM
273 }
274 
275 void
276 test_distance_rectangle(gconstpointer data)
277 {
278  assign_shinjuku_and_takane(data);
279  cut_assert_equal_double(12585.4, 10,
280  grn_geo_distance_rectangle(context, shinjuku, takane));
281 }
282 
283 void
285 {
286  cut_assert_equal_double(12585.4, 10,
287  grn_geo_distance_sphere(context,
288  shinjuku_wgs84,
289  takane_wgs84));
290 }
291 
292 void
294 {
295  cut_assert_equal_double(12640.8, 10,
297  shinjuku_wgs84,
298  takane_wgs84));
299 }
300 
301 void
303 {
304  grn_obj *location_index;
305 
306  assert_send_commands(cut_get_fixture_data_string("ddl.grn", NULL));
307  assert_send_command(cut_get_fixture_data_string("shops.grn", NULL));
308 
309  location_index = get("Locations.shop");
310  cut_assert_equal_int(4,
312  location_index,
313  sazare_wgs84,
314  tokyo_wgs84));
315 }