[Groonga-commit] groonga/groonga [master] move grn_geo_search() to geo.c from proc.c.

Back to archive index

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)
 {




Groonga-commit メーリングリストの案内
Back to archive index