null+****@clear*****
null+****@clear*****
2010年 8月 5日 (木) 10:01:41 JST
Kouhei Sutou 2010-08-05 01:01:41 +0000 (Thu, 05 Aug 2010)
New Revision: 5e312b7f7e78c5de6330b2ab5a228d8a4d219668
Log:
add GRN_GEO_POINT_VALUE_RADIUS() and use it.
Modified files:
lib/geo.c
lib/geo.h
Modified: lib/geo.c (+17 -28)
===================================================================
--- lib/geo.c 2010-08-05 00:55:16 +0000 (2c05970)
+++ lib/geo.c 2010-08-05 01:01:41 +0000 (0fddfbc)
@@ -35,10 +35,8 @@ grn_geo_in_circle(grn_ctx *ctx, grn_obj *point, grn_obj *center,
if (grn_obj_cast(ctx, center, ¢er_, 0)) { goto exit; }
center = ¢er_;
}
- lng0 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point))->longitude);
- lat0 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point))->latitude);
- lng1 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(center))->longitude);
- lat1 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(center))->latitude);
+ GRN_GEO_POINT_VALUE_RADIUS(point, lat0, lng0);
+ GRN_GEO_POINT_VALUE_RADIUS(center, lat1, lng1);
x = (lng1 - lng0) * cos((lat0 + lat1) * 0.5);
y = (lat1 - lat0);
d = (x * x) + (y * y);
@@ -68,8 +66,7 @@ grn_geo_in_circle(grn_ctx *ctx, grn_obj *point, grn_obj *center,
case GRN_DB_TOKYO_GEO_POINT :
case GRN_DB_WGS84_GEO_POINT :
if (domain != radius_or_point->header.domain) { /* todo */ goto exit; }
- lng2 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(radius_or_point))->longitude);
- lat2 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(radius_or_point))->latitude);
+ GRN_GEO_POINT_VALUE_RADIUS(radius_or_point, lat2, lng2);
x = (lng2 - lng1) * cos((lat1 + lat2) * 0.5);
y = (lat2 - lat1);
r = d <= (x * x) + (y * y);
@@ -90,9 +87,9 @@ grn_geo_in_rectangle(grn_ctx *ctx, grn_obj *point,
{
unsigned r = GRN_FALSE;
grn_obj top_left_, bottom_right_;
- grn_geo_point *p, *p1, *p2;
grn_id domain = point->header.domain;
if (domain == GRN_DB_TOKYO_GEO_POINT || domain == GRN_DB_WGS84_GEO_POINT) {
+ int lat0, lng0, lat1, lng1, lat2, lng2;
if (top_left->header.domain != domain) {
GRN_OBJ_INIT(&top_left_, GRN_BULK, 0, domain);
if (grn_obj_cast(ctx, top_left, &top_left_, 0)) { goto exit; }
@@ -103,11 +100,11 @@ grn_geo_in_rectangle(grn_ctx *ctx, grn_obj *point,
if (grn_obj_cast(ctx, bottom_right, &bottom_right_, 0)) { goto exit; }
bottom_right = &bottom_right_;
}
- p = ((grn_geo_point *)GRN_BULK_HEAD(point));
- p1 = ((grn_geo_point *)GRN_BULK_HEAD(top_left));
- p2 = ((grn_geo_point *)GRN_BULK_HEAD(bottom_right));
- r = ((p1->longitude <= p->longitude) && (p->longitude <= p2->longitude) &&
- (p2->latitude <= p->latitude) && (p->latitude <= p1->latitude));
+ GRN_GEO_POINT_VALUE(point, lat0, lng0);
+ GRN_GEO_POINT_VALUE(top_left, lat1, lng1);
+ GRN_GEO_POINT_VALUE(bottom_right, lat2, lng2);
+ r = ((lng1 <= lng0) && (lng0 <= lng2) &&
+ (lat2 <= lat0) && (lat0 <= lat1));
} else {
/* todo */
}
@@ -128,10 +125,8 @@ grn_geo_distance(grn_ctx *ctx, grn_obj *point1, grn_obj *point2)
if (grn_obj_cast(ctx, point2, &point2_, 0)) { goto exit; }
point2 = &point2_;
}
- lng1 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point1))->longitude);
- lat1 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point1))->latitude);
- lng2 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point2))->longitude);
- lat2 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point2))->latitude);
+ GRN_GEO_POINT_VALUE_RADIUS(point1, lat1, lng1);
+ GRN_GEO_POINT_VALUE_RADIUS(point2, lat2, lng2);
x = (lng2 - lng1) * cos((lat1 + lat2) * 0.5);
y = (lat2 - lat1);
d = sqrt((x * x) + (y * y)) * GRN_GEO_RADIOUS;
@@ -155,10 +150,8 @@ grn_geo_distance2(grn_ctx *ctx, grn_obj *point1, grn_obj *point2)
if (grn_obj_cast(ctx, point2, &point2_, 0)) { goto exit; }
point2 = &point2_;
}
- lng1 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point1))->longitude);
- lat1 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point1))->latitude);
- lng2 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point2))->longitude);
- lat2 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point2))->latitude);
+ GRN_GEO_POINT_VALUE_RADIUS(point1, lat1, lng1);
+ GRN_GEO_POINT_VALUE_RADIUS(point2, lat2, lng2);
x = sin(fabs(lng2 - lng1) * 0.5);
y = sin(fabs(lat2 - lat1) * 0.5);
d = asin(sqrt((y * y) + cos(lat1) * cos(lat2) * x * x)) * 2 * GRN_GEO_RADIOUS;
@@ -184,10 +177,8 @@ grn_geo_distance3(grn_ctx *ctx, grn_obj *point1, grn_obj *point2)
if (grn_obj_cast(ctx, point2, &point2_, 0)) { goto exit; }
point2 = &point2_;
}
- lng1 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point1))->longitude);
- lat1 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point1))->latitude);
- lng2 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point2))->longitude);
- lat2 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point2))->latitude);
+ GRN_GEO_POINT_VALUE_RADIUS(point1, lat1, lng1);
+ GRN_GEO_POINT_VALUE_RADIUS(point2, lat2, lng2);
p = (lat1 + lat2) * 0.5;
q = (1 - GRN_GEO_BES_C3 * sin(p) * sin(p));
r = sqrt(q);
@@ -206,10 +197,8 @@ grn_geo_distance3(grn_ctx *ctx, grn_obj *point1, grn_obj *point2)
if (grn_obj_cast(ctx, point2, &point2_, 0)) { goto exit; }
point2 = &point2_;
}
- lng1 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point1))->longitude);
- lat1 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point1))->latitude);
- lng2 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point2))->longitude);
- lat2 = GRN_GEO_INT2RAD(((grn_geo_point *)GRN_BULK_HEAD(point2))->latitude);
+ GRN_GEO_POINT_VALUE_RADIUS(point1, lat1, lng1);
+ GRN_GEO_POINT_VALUE_RADIUS(point2, lat2, lng2);
p = (lat1 + lat2) * 0.5;
q = (1 - GRN_GEO_GRS_C3 * sin(p) * sin(p));
r = sqrt(q);
Modified: lib/geo.h (+6 -0)
===================================================================
--- lib/geo.h 2010-08-05 00:55:16 +0000 (4c82796)
+++ lib/geo.h 2010-08-05 01:01:41 +0000 (4fb6291)
@@ -37,6 +37,12 @@ extern "C" {
#define GRN_GEO_GRS_C3 0.006694
#define GRN_GEO_INT2RAD(x) ((M_PI / (GRN_GEO_RESOLUTION * 180)) * x)
+#define GRN_GEO_POINT_VALUE_RADIUS(obj,_latitude,_longitude) do {\
+ grn_geo_point *_val = (grn_geo_point *)GRN_BULK_HEAD(obj);\
+ _latitude = GRN_GEO_INT2RAD(_val->latitude);\
+ _longitude = GRN_GEO_INT2RAD(_val->longitude);\
+} while (0)
+
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,