[Groonga-commit] groonga/groonga [master] [geo] implement TokyoGeoPoint <-> WGS84GeoPoint conversion.

Back to archive index

null+****@clear***** null+****@clear*****
2011年 9月 17日 (土) 13:52:57 JST


Kouhei Sutou	2011-09-17 04:52:57 +0000 (Sat, 17 Sep 2011)

  New Revision: 9ab80568ad2c06e203f3fafca43a01cc30b06e83

  Log:
    [geo] implement TokyoGeoPoint <-> WGS84GeoPoint conversion.
    
    Based on expressions at http://www.jalan.net/jw/jwp0200/jww0203.do :
    
      jx: longitude in degree in Tokyo Geodetic System.
      jy: latitude in degree in Tokyo Geodetic System.
      wx: longitude in degree in WGS 84.
      wy: latitude in degree in WGS 84.
    
      jy = wy * 1.000106961 - wx * 0.000017467 - 0.004602017
      jx = wx * 1.000083049 + wy * 0.000046047 - 0.010041046
    
      wy = jy - jy * 0.00010695 + jx * 0.000017464 + 0.0046017
      wx = jx - jy * 0.000046038 - jx * 0.000083043 + 0.010040

  Modified files:
    lib/db.c
    test/unit/core/test-cast-basic.c

  Modified: lib/db.c (+54 -1)
===================================================================
--- lib/db.c    2011-09-16 07:02:53 +0000 (1531670)
+++ lib/db.c    2011-09-17 04:52:57 +0000 (23aac34)
@@ -4293,7 +4293,60 @@ grn_obj_cast(grn_ctx *ctx, grn_obj *src, grn_obj *dest, int addp)
     if (src->header.domain == dest->header.domain) {
       GRN_TEXT_PUT(ctx, dest, GRN_TEXT_VALUE(src), GRN_TEXT_LEN(src));
     } else {
-      rc = GRN_FUNCTION_NOT_IMPLEMENTED;
+      int latitude, longitude;
+      double latitude_in_degree, longitude_in_degree;
+      GRN_GEO_POINT_VALUE(src, latitude, longitude);
+      latitude_in_degree = GRN_GEO_MSEC2DEGREE(latitude);
+      longitude_in_degree = GRN_GEO_MSEC2DEGREE(longitude);
+      /* TokyoGeoPoint <-> WGS84GeoPoint is based on
+         http://www.jalan.net/jw/jwp0200/jww0203.do
+
+         jx: longitude in degree in Tokyo Geodetic System.
+         jy: latitude in degree in Tokyo Geodetic System.
+         wx: longitude in degree in WGS 84.
+         wy: latitude in degree in WGS 84.
+
+         jy = wy * 1.000106961 - wx * 0.000017467 - 0.004602017
+         jx = wx * 1.000083049 + wy * 0.000046047 - 0.010041046
+
+         wy = jy - jy * 0.00010695 + jx * 0.000017464 + 0.0046017
+         wx = jx - jy * 0.000046038 - jx * 0.000083043 + 0.010040
+      */
+      if (dest->header.domain == GRN_DB_TOKYO_GEO_POINT) {
+        double wgs84_latitude_in_degree = latitude_in_degree;
+        double wgs84_longitude_in_degree = longitude_in_degree;
+        int tokyo_latitude, tokyo_longitude;
+        double tokyo_latitude_in_degree, tokyo_longitude_in_degree;
+        tokyo_latitude_in_degree =
+          wgs84_latitude_in_degree * 1.000106961 -
+          wgs84_longitude_in_degree * 0.000017467 -
+          0.004602017;
+        tokyo_longitude_in_degree =
+          wgs84_longitude_in_degree * 1.000083049 +
+          wgs84_latitude_in_degree  * 0.000046047 -
+          0.010041046;
+        tokyo_latitude = GRN_GEO_DEGREE2MSEC(tokyo_latitude_in_degree);
+        tokyo_longitude = GRN_GEO_DEGREE2MSEC(tokyo_longitude_in_degree);
+        GRN_GEO_POINT_SET(ctx, dest, tokyo_latitude, tokyo_longitude);
+      } else {
+        double tokyo_latitude_in_degree = latitude_in_degree;
+        double tokyo_longitude_in_degree = longitude_in_degree;
+        int wgs84_latitude, wgs84_longitude;
+        double wgs84_latitude_in_degree, wgs84_longitude_in_degree;
+        wgs84_latitude_in_degree =
+          tokyo_latitude_in_degree -
+          tokyo_latitude_in_degree * 0.00010695 +
+          tokyo_longitude_in_degree * 0.000017464 +
+          0.0046017;
+        wgs84_longitude_in_degree =
+          tokyo_longitude_in_degree -
+          tokyo_latitude_in_degree * 0.000046038 -
+          tokyo_longitude_in_degree * 0.000083043 +
+          0.010040;
+        wgs84_latitude = GRN_GEO_DEGREE2MSEC(wgs84_latitude_in_degree);
+        wgs84_longitude = GRN_GEO_DEGREE2MSEC(wgs84_longitude_in_degree);
+        GRN_GEO_POINT_SET(ctx, dest, wgs84_latitude, wgs84_longitude);
+      }
     }
     break;
   case GRN_VOID :

  Modified: test/unit/core/test-cast-basic.c (+75 -11)
===================================================================
--- test/unit/core/test-cast-basic.c    2011-09-16 07:02:53 +0000 (f39b02f)
+++ test/unit/core/test-cast-basic.c    2011-09-17 04:52:57 +0000 (61f3415)
@@ -1,6 +1,6 @@
 /* -*- c-basic-offset: 2; coding: utf-8 -*- */
 /*
-  Copyright (C) 2009-2010  Kouhei Sutou <kou****@clear*****>
+  Copyright (C) 2009-2011  Kouhei Sutou <kou****@clear*****>
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -103,8 +103,10 @@ void test_uint64_to_uint64(void);
 void test_uint64_to_float(void);
 void test_uint64_to_time(void);
 
-void test_geo_point_to_geo_point_same(void);
-void test_geo_point_to_geo_point_different(void);
+void test_tokyo_geo_point_to_tokyo_geo_point(void);
+void test_tokyo_geo_point_to_wgs84_geo_point(void);
+void test_wgs84_geo_point_to_wgs84_geo_point(void);
+void test_wgs84_geo_point_to_tokyo_geo_point(void);
 
 static grn_logger_info *logger;
 static grn_ctx context;
@@ -928,27 +930,89 @@ test_uint64_to_text(void)
 }
 
 void
-test_geo_point_to_geo_point_same(void)
+test_tokyo_geo_point_to_tokyo_geo_point(void)
 {
   gint takane_latitude, takane_longitude;
+  gint takane_latitude_in_tokyo_geodetic_system = 130183139;
+  gint takane_longitude_in_tokyo_geodetic_system = 503813760;
+
+  grn_obj_reinit(&context, &src, GRN_DB_TOKYO_GEO_POINT, 0);
+  GRN_GEO_POINT_SET(&context, &src,
+                    takane_latitude_in_tokyo_geodetic_system,
+                    takane_longitude_in_tokyo_geodetic_system);
+
+  grn_obj_reinit(&context, &dest, GRN_DB_TOKYO_GEO_POINT, 0);
+  grn_test_assert(grn_obj_cast(&context, &src, &dest, GRN_FALSE));
+  GRN_GEO_POINT_VALUE(&dest, takane_latitude, takane_longitude);
+  cut_assert_equal_int(takane_latitude_in_tokyo_geodetic_system,
+                       takane_latitude);
+  cut_assert_equal_int(takane_longitude_in_tokyo_geodetic_system,
+                       takane_longitude);
+}
+
+void
+test_tokyo_geo_point_to_wgs84_geo_point(void)
+{
+  gint takane_latitude, takane_longitude;
+  gint takane_latitude_in_tokyo_geodetic_system = 130183139;
+  gint takane_longitude_in_tokyo_geodetic_system = 503813760;
+  gint takane_latitude_in_wgs84 = 130194580;
+  gint takane_longitude_in_wgs84 = 503802072;
+
+  grn_obj_reinit(&context, &src, GRN_DB_TOKYO_GEO_POINT, 0);
+  GRN_GEO_POINT_SET(&context, &src,
+                    takane_latitude_in_tokyo_geodetic_system,
+                    takane_longitude_in_tokyo_geodetic_system);
+
+  grn_obj_reinit(&context, &dest, GRN_DB_WGS84_GEO_POINT, 0);
+  grn_test_assert(grn_obj_cast(&context, &src, &dest, GRN_FALSE));
+  GRN_GEO_POINT_VALUE(&dest, takane_latitude, takane_longitude);
+  cut_assert_equal_int(takane_latitude_in_wgs84,
+                       takane_latitude);
+  cut_assert_equal_int(takane_longitude_in_wgs84,
+                       takane_longitude);
+}
+
+void
+test_wgs84_geo_point_to_wgs84_geo_point(void)
+{
+  gint takane_latitude, takane_longitude;
+  gint takane_latitude_in_wgs84 = 130194581;
+  gint takane_longitude_in_wgs84 = 503802073;
 
   grn_obj_reinit(&context, &src, GRN_DB_WGS84_GEO_POINT, 0);
-  GRN_GEO_POINT_SET(&context, &src, 130194581, 503802073);
+  GRN_GEO_POINT_SET(&context, &src,
+                    takane_latitude_in_wgs84,
+                    takane_longitude_in_wgs84);
 
   grn_obj_reinit(&context, &dest, GRN_DB_WGS84_GEO_POINT, 0);
   grn_test_assert(grn_obj_cast(&context, &src, &dest, GRN_FALSE));
   GRN_GEO_POINT_VALUE(&dest, takane_latitude, takane_longitude);
-  cut_assert_equal_int(130194581, takane_latitude);
-  cut_assert_equal_int(503802073, takane_longitude);
+  cut_assert_equal_int(takane_latitude_in_wgs84,
+                       takane_latitude);
+  cut_assert_equal_int(takane_longitude_in_wgs84,
+                       takane_longitude);
 }
 
 void
-test_geo_point_to_geo_point_different(void)
+test_wgs84_geo_point_to_tokyo_geo_point(void)
 {
+  gint takane_latitude, takane_longitude;
+  gint takane_latitude_in_wgs84 = 130194581;
+  gint takane_longitude_in_wgs84 = 503802073;
+  gint takane_latitude_in_tokyo_geodetic_system = 130183139;
+  gint takane_longitude_in_tokyo_geodetic_system = 503813760;
+
   grn_obj_reinit(&context, &src, GRN_DB_WGS84_GEO_POINT, 0);
-  GRN_GEO_POINT_SET(&context, &src, 130194581, 503802073);
+  GRN_GEO_POINT_SET(&context, &src,
+                    takane_latitude_in_wgs84,
+                    takane_longitude_in_wgs84);
 
   grn_obj_reinit(&context, &dest, GRN_DB_TOKYO_GEO_POINT, 0);
-  grn_test_assert_equal_rc(GRN_FUNCTION_NOT_IMPLEMENTED,
-                           grn_obj_cast(&context, &src, &dest, GRN_FALSE));
+  grn_test_assert(grn_obj_cast(&context, &src, &dest, GRN_FALSE));
+  GRN_GEO_POINT_VALUE(&dest, takane_latitude, takane_longitude);
+  cut_assert_equal_int(takane_latitude_in_tokyo_geodetic_system,
+                       takane_latitude);
+  cut_assert_equal_int(takane_longitude_in_tokyo_geodetic_system,
+                       takane_longitude);
 }




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