[Groonga-commit] groonga/groonga [master] geo: return the value of correct distance according to quadrant type

Back to archive index

null+****@clear***** null+****@clear*****
2012年 6月 12日 (火) 13:32:13 JST


HAYASHI Kentaro	2012-06-12 13:32:13 +0900 (Tue, 12 Jun 2012)

  New Revision: 53f12db9a3fef51e9f2b0aa95977743f0c79ffe3

  Log:
    geo: return the value of correct distance according to quadrant type
    
    refs #1388

  Modified files:
    lib/geo.c

  Modified: lib/geo.c (+24 -4)
===================================================================
--- lib/geo.c    2012-06-12 12:50:37 +0900 (3975959)
+++ lib/geo.c    2012-06-12 13:32:13 +0900 (11ae5fb)
@@ -1924,9 +1924,11 @@ double
 grn_geo_distance_rectangle_raw(grn_ctx *ctx,
                                grn_geo_point *point1, grn_geo_point *point2)
 {
+#define M_2PI 6.28318530717958647692
+
   double lng1, lat1, lng2, lat2, x, y, distance;
   double slope, intercept, longitude_delta, latitude_delta;
-  double east_distance, west_distance;
+  double east_distance, west_distance, intercept_edge;
   distance_type dist_type;
   quadrant_type quad_type;
 
@@ -1957,12 +1959,30 @@ grn_geo_distance_rectangle_raw(grn_ctx *ctx,
                                                  lat2);
       distance = (east_distance + west_distance) * GRN_GEO_RADIUS;
     } else {
-      x = (lng2 - lng1) * cos((lat1 + lat2) * 0.5);
-      y = (lat2 - lat1);
-      distance = sqrt((x * x) + (y * y)) * GRN_GEO_RADIUS;
+      if (quad_type == QUADRANT_1ST_TO_2ND) {
+        longitude_delta = lng2 + M_2PI - lng1;
+        latitude_delta = lat2 - lat1;
+        slope = latitude_delta / longitude_delta;
+        intercept = lat1 - slope * lng1;
+        intercept_edge = slope * M_PI + intercept;
+        east_distance = geo_distance_rectangle_abs(lng1,
+                                                   lat1,
+                                                   M_PI,
+                                                   intercept_edge);
+        west_distance = geo_distance_rectangle_abs(-lng2,
+                                                   lat2,
+                                                   M_PI,
+                                                   intercept_edge);
+        distance = (east_distance + west_distance) * GRN_GEO_RADIUS;
+      } else {
+        x = (lng2 - lng1) * cos((lat1 + lat2) * 0.5);
+        y = (lat2 - lat1);
+        distance = sqrt((x * x) + (y * y)) * GRN_GEO_RADIUS;
+      }
     }
   }
   return distance;
+#undef M_2PI
 }
 
 double




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