null+****@clear*****
null+****@clear*****
2010年 8月 5日 (木) 15:19:04 JST
Kouhei Sutou 2010-08-05 06:19:04 +0000 (Thu, 05 Aug 2010)
New Revision: 0c69cf29dd7e650547100cc972cc282a4bc9cbcd
Log:
move grn_geo_search() to geo.c from proc.c.
Modified files:
lib/expr.c
lib/geo.c
lib/geo.h
lib/proc.c
Modified: lib/expr.c (+1 -3)
===================================================================
--- lib/expr.c 2010-08-05 06:12:34 +0000 (b40f8a8)
+++ lib/expr.c 2010-08-05 06:19:04 +0000 (7eadab8)
@@ -20,6 +20,7 @@
#include <string.h>
#include <float.h>
#include "ii.h"
+#include "geo.h"
grn_obj *
grn_expr_alloc(grn_ctx *ctx, grn_obj *expr, grn_id domain, grn_obj_flags flags)
@@ -3768,9 +3769,6 @@ grn_view_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
GRN_LOG(ctx, GRN_LOG_NONE, "%08x|:%012llu %s(%d)", (intptr_t)ctx, et, msg, num);\
}
-grn_rc grn_geo_search(grn_ctx *ctx, grn_obj *obj, grn_obj **args, int nargs,
- grn_obj *res, grn_operator op);
-
grn_obj *
grn_table_select(grn_ctx *ctx, grn_obj *table, grn_obj *expr,
grn_obj *res, grn_operator op)
Modified: lib/geo.c (+87 -0)
===================================================================
--- lib/geo.c 2010-08-05 06:12:34 +0000 (8465000)
+++ lib/geo.c 2010-08-05 06:19:04 +0000 (f1a0d8b)
@@ -21,6 +21,93 @@
#include "ii.h"
#include "db.h"
+grn_rc
+grn_geo_search(grn_ctx *ctx, grn_obj *obj, grn_obj **args, int nargs,
+ grn_obj *res, grn_operator op)
+{
+ grn_id domain;
+ double lng0, lat0, lng1, lat1, lng2, lat2, x, y, d;
+ grn_obj *proc, *pat, *pos1, *pos2, pos1_, pos2_;
+ if (nargs != 4) { goto exit; }
+ pat = grn_ctx_at(ctx, obj->header.domain);
+ proc = args[0];
+ pos1 = args[2];
+ pos2 = args[3];
+ domain = pat->header.domain;
+ if (domain != GRN_DB_TOKYO_GEO_POINT && domain != GRN_DB_WGS84_GEO_POINT) { goto exit; }
+ if (pos1->header.domain != domain) {
+ GRN_OBJ_INIT(&pos1_, GRN_BULK, 0, domain);
+ if (grn_obj_cast(ctx, pos1, &pos1_, 0)) { goto exit; }
+ pos1 = &pos1_;
+ }
+ lng1 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(pos1))->longitude);
+ lat1 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(pos1))->latitude);
+ switch (pos2->header.domain) {
+ case GRN_DB_INT32 :
+ d = GRN_INT32_VALUE(pos2);
+ d = (d / GRN_GEO_RADIOUS) * (d / GRN_GEO_RADIOUS);
+ break;
+ case GRN_DB_UINT32 :
+ d = GRN_UINT32_VALUE(pos2);
+ d = (d / GRN_GEO_RADIOUS) * (d / GRN_GEO_RADIOUS);
+ break;
+ case GRN_DB_INT64 :
+ d = GRN_INT64_VALUE(pos2);
+ d = (d / GRN_GEO_RADIOUS) * (d / GRN_GEO_RADIOUS);
+ break;
+ case GRN_DB_UINT64 :
+ d = GRN_UINT64_VALUE(pos2);
+ d = (d / GRN_GEO_RADIOUS) * (d / GRN_GEO_RADIOUS);
+ break;
+ case GRN_DB_FLOAT :
+ d = GRN_FLOAT_VALUE(pos2);
+ d = (d / GRN_GEO_RADIOUS) * (d / GRN_GEO_RADIOUS);
+ break;
+ case GRN_DB_SHORT_TEXT :
+ case GRN_DB_TEXT :
+ case GRN_DB_LONG_TEXT :
+ GRN_OBJ_INIT(&pos2_, GRN_BULK, 0, domain);
+ if (grn_obj_cast(ctx, pos2, &pos2_, 0)) { goto exit; }
+ pos2 = &pos2_;
+ /* fallthru */
+ case GRN_DB_TOKYO_GEO_POINT :
+ case GRN_DB_WGS84_GEO_POINT :
+ if (domain != pos2->header.domain) { /* todo */ goto exit; }
+ lng2 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(pos2))->longitude);
+ lat2 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(pos2))->latitude);
+ x = (lng2 - lng1) * cos((lat1 + lat2) * 0.5);
+ y = (lat2 - lat1);
+ d = ((x * x) + (y * y));
+ break;
+ default :
+ goto exit;
+ }
+ {
+ uint32_t s, h;
+ grn_id tid;
+ grn_geo_point pos;
+ grn_table_cursor *tc = grn_table_cursor_open(ctx, pat, NULL, 0,
+ GRN_BULK_HEAD(pos1),
+ sizeof(grn_geo_point),
+ 0, -1, GRN_CURSOR_PREFIX);
+ for (s = 0, h = 256; s <= h * 16 && (tid = grn_table_cursor_next(ctx, tc)); s++) {
+ grn_table_get_key(ctx, pat, tid, &pos, sizeof(grn_geo_point));
+ lng0 = GRN_GEO_INT2RAD(pos.longitude);
+ lat0 = GRN_GEO_INT2RAD(pos.latitude);
+ x = (lng1 - lng0) * cos((lat0 + lat1) * 0.5);
+ y = (lat1 - lat0);
+ if (((x * x) + (y * y)) <= d) {
+ grn_ii_at(ctx, (grn_ii *)obj, tid, (grn_hash *)res, op);
+ h++;
+ }
+ }
+ grn_table_cursor_close(ctx, tc);
+ }
+exit :
+ grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
+ return ctx->rc;
+}
+
unsigned
grn_geo_in_circle(grn_ctx *ctx, grn_obj *point, grn_obj *center,
grn_obj *radius_or_point)
Modified: lib/geo.h (+3 -0)
===================================================================
--- lib/geo.h 2010-08-05 06:12:34 +0000 (bf03b0e)
+++ lib/geo.h 2010-08-05 06:19:04 +0000 (6db6309)
@@ -44,6 +44,9 @@ extern "C" {
_longitude = GRN_GEO_INT2RAD(_val->longitude);\
} while (0)
+grn_rc grn_geo_search(grn_ctx *ctx, grn_obj *obj, grn_obj **args, int nargs,
+ grn_obj *res, grn_operator op);
+
unsigned grn_geo_in_circle(grn_ctx *ctx, grn_obj *point, grn_obj *center,
grn_obj *radius_or_point);
unsigned grn_geo_in_rectangle(grn_ctx *ctx, grn_obj *point,
Modified: lib/proc.c (+0 -97)
===================================================================
--- lib/proc.c 2010-08-05 06:12:34 +0000 (85bdf5e)
+++ lib/proc.c 2010-08-05 06:19:04 +0000 (0a3b709)
@@ -2050,16 +2050,6 @@ func_now(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
return obj;
}
-#define GEO_RESOLUTION 3600000
-#define GEO_RADIOUS 6357303
-#define GEO_BES_C1 6334834
-#define GEO_BES_C2 6377397
-#define GEO_BES_C3 0.006674
-#define GEO_GRS_C1 6335439
-#define GEO_GRS_C2 6378137
-#define GEO_GRS_C3 0.006694
-#define GEO_INT2RAD(x) ((M_PI / (GEO_RESOLUTION * 180)) * x)
-
static grn_obj *
func_geo_in_circle(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{
@@ -2074,93 +2064,6 @@ func_geo_in_circle(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_
return obj;
}
-grn_rc
-grn_geo_search(grn_ctx *ctx, grn_obj *obj, grn_obj **args, int nargs,
- grn_obj *res, grn_operator op)
-{
- grn_id domain;
- double lng0, lat0, lng1, lat1, lng2, lat2, x, y, d;
- grn_obj *proc, *pat, *pos1, *pos2, pos1_, pos2_;
- if (nargs != 4) { goto exit; }
- pat = grn_ctx_at(ctx, obj->header.domain);
- proc = args[0];
- pos1 = args[2];
- pos2 = args[3];
- domain = pat->header.domain;
- if (domain != GRN_DB_TOKYO_GEO_POINT && domain != GRN_DB_WGS84_GEO_POINT) { goto exit; }
- if (pos1->header.domain != domain) {
- GRN_OBJ_INIT(&pos1_, GRN_BULK, 0, domain);
- if (grn_obj_cast(ctx, pos1, &pos1_, 0)) { goto exit; }
- pos1 = &pos1_;
- }
- lng1 = GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(pos1))->longitude);
- lat1 = GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(pos1))->latitude);
- switch (pos2->header.domain) {
- case GRN_DB_INT32 :
- d = GRN_INT32_VALUE(pos2);
- d = (d / GEO_RADIOUS) * (d / GEO_RADIOUS);
- break;
- case GRN_DB_UINT32 :
- d = GRN_UINT32_VALUE(pos2);
- d = (d / GEO_RADIOUS) * (d / GEO_RADIOUS);
- break;
- case GRN_DB_INT64 :
- d = GRN_INT64_VALUE(pos2);
- d = (d / GEO_RADIOUS) * (d / GEO_RADIOUS);
- break;
- case GRN_DB_UINT64 :
- d = GRN_UINT64_VALUE(pos2);
- d = (d / GEO_RADIOUS) * (d / GEO_RADIOUS);
- break;
- case GRN_DB_FLOAT :
- d = GRN_FLOAT_VALUE(pos2);
- d = (d / GEO_RADIOUS) * (d / GEO_RADIOUS);
- break;
- case GRN_DB_SHORT_TEXT :
- case GRN_DB_TEXT :
- case GRN_DB_LONG_TEXT :
- GRN_OBJ_INIT(&pos2_, GRN_BULK, 0, domain);
- if (grn_obj_cast(ctx, pos2, &pos2_, 0)) { goto exit; }
- pos2 = &pos2_;
- /* fallthru */
- case GRN_DB_TOKYO_GEO_POINT :
- case GRN_DB_WGS84_GEO_POINT :
- if (domain != pos2->header.domain) { /* todo */ goto exit; }
- lng2 = GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(pos2))->longitude);
- lat2 = GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(pos2))->latitude);
- x = (lng2 - lng1) * cos((lat1 + lat2) * 0.5);
- y = (lat2 - lat1);
- d = ((x * x) + (y * y));
- break;
- default :
- goto exit;
- }
- {
- uint32_t s, h;
- grn_id tid;
- grn_geo_point pos;
- grn_table_cursor *tc = grn_table_cursor_open(ctx, pat, NULL, 0,
- GRN_BULK_HEAD(pos1),
- sizeof(grn_geo_point),
- 0, -1, GRN_CURSOR_PREFIX);
- for (s = 0, h = 256; s <= h * 16 && (tid = grn_table_cursor_next(ctx, tc)); s++) {
- grn_table_get_key(ctx, pat, tid, &pos, sizeof(grn_geo_point));
- lng0 = GEO_INT2RAD(pos.longitude);
- lat0 = GEO_INT2RAD(pos.latitude);
- x = (lng1 - lng0) * cos((lat0 + lat1) * 0.5);
- y = (lat1 - lat0);
- if (((x * x) + (y * y)) <= d) {
- grn_ii_at(ctx, (grn_ii *)obj, tid, (grn_hash *)res, op);
- h++;
- }
- }
- grn_table_cursor_close(ctx, tc);
- }
-exit :
- grn_ii_resolve_sel_and(ctx, (grn_hash *)res, op);
- return ctx->rc;
-}
-
static grn_obj *
func_geo_in_rectangle(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data)
{