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);
}