[Groonga-commit] groonga/grnxx at 12f6683 [master] Update GeoPoint. (#94)

アーカイブの一覧に戻る

susumu.yata null+****@clear*****
Tue Dec 16 10:42:05 JST 2014


susumu.yata	2014-11-07 13:35:39 +0900 (Fri, 07 Nov 2014)

  New Revision: 12f6683a8c0bf2c74b257edf0216cf7cadbdf9a9
  https://github.com/groonga/grnxx/commit/12f6683a8c0bf2c74b257edf0216cf7cadbdf9a9

  Message:
    Update GeoPoint. (#94)

  Modified files:
    include/grnxx/data_types/scalar/geo_point.hpp
    test/test_column.cpp

  Modified: include/grnxx/data_types/scalar/geo_point.hpp (+115 -25)
===================================================================
--- include/grnxx/data_types/scalar/geo_point.hpp    2014-11-07 10:25:08 +0900 (d7f114d)
+++ include/grnxx/data_types/scalar/geo_point.hpp    2014-11-07 13:35:39 +0900 (89eda4f)
@@ -6,37 +6,86 @@
 
 #include "grnxx/data_types/data_type.hpp"
 #include "grnxx/data_types/na.hpp"
+#include "grnxx/data_types/scalar/float.hpp"
+#include "grnxx/data_types/scalar/int.hpp"
 
 namespace grnxx {
 
+// NOTE: GeoPoint uses int32_t to represent latitude and longitude, but uses
+//       int64_t for I/O in order to avoid problems caused by int32_t overflow
+//       and implicit type conversion from int64_t to int32_t.
 class GeoPoint {
  public:
   GeoPoint() = default;
   ~GeoPoint() = default;
 
-  // NOTE: GeoPoint uses int32_t to represent latitude and longitude, but this
-  //       constructor takes int64_t in order to avoid problems caused by
-  //       implicit type conversion from int64_t to int32_t.
-  // NOTE: gcc-4.8 does not support use of the value being constructed in
-  //       a constant exression.
-  GeoPoint(int64_t latitude, int64_t longitude)
-      : latitude_(((latitude < min_latitude()) ||
-                   (latitude > max_latitude()) ||
-                   (longitude < min_longitude()) ||
-                   (longitude > max_longitude())) ?
-                  na_latitude() : latitude),
-        longitude_((latitude_ == na_latitude()) ?
-                   na_longitude() : longitude) {}
+  // NOTE: The following implementation assumes that Int::na()::value() returns
+  //       a value less than min_latitude/longitude() or greater than
+  //       max_latitude/longitude().
+  GeoPoint(Int latitude_in_milliseconds, Int longitude_in_milliseconds)
+      : latitude_(),
+        longitude_() {
+    int64_t latitude = latitude_in_milliseconds.value();
+    int64_t longitude = longitude_in_milliseconds.value();
+    if ((latitude >= min_latitude()) && (latitude <= max_latitude()) &&
+        (longitude >= min_longitude()) && (longitude <= max_longitude())) {
+      if ((latitude == min_latitude()) || (latitude == max_latitude())) {
+        longitude = 0;
+      } else if (longitude == max_longitude()) {
+        longitude = min_longitude();
+      }
+      latitude_ = latitude;
+      longitude_ = longitude;
+    } else {
+      latitude_ = na_latitude();
+      longitude_ = na_longitude();
+    }
+  }
+  GeoPoint(Float latitude_in_degrees, Float longitude_in_degrees)
+      : latitude_(),
+        longitude_() {
+    // N/A (NaN) is rejected due to LOGICAL_AND.
+    if ((latitude_in_degrees.value() >= -90.0) &&
+        (latitude_in_degrees.value() <= 90.0) &&
+        (longitude_in_degrees.value() <= -180.0) &&
+        (longitude_in_degrees.value() <= 180.0)) {
+      int64_t latitude = latitude_in_degrees.value() * 60 * 60 * 1000;
+      int64_t longitude = longitude_in_degrees.value() * 60 * 60 * 1000;
+      if ((latitude <= min_latitude()) || (latitude >= max_latitude())) {
+        longitude = 0;
+      } else if (longitude == max_longitude()) {
+        longitude = min_longitude();
+      }
+      latitude_ = latitude;
+      longitude_ = longitude;
+    } else {
+      latitude_ = na_latitude();
+      longitude_ = na_longitude();
+    }
+  }
   explicit constexpr GeoPoint(NA)
       : latitude_(na_latitude()),
         longitude_(na_longitude()) {}
 
-  constexpr int32_t latitude() const {
+  constexpr int64_t latitude() const {
     return latitude_;
   }
-  constexpr int32_t longitude() const {
+  constexpr Int latitude_in_milliseconds() const {
+    return in_milliseconds(latitude_);
+  }
+  constexpr Float latitude_in_degrees() const {
+    return in_degrees(latitude_);
+  }
+
+  constexpr int64_t longitude() const {
     return longitude_;
   }
+  constexpr Int longitude_in_milliseconds() const {
+    return in_milliseconds(longitude_);
+  }
+  constexpr Float longitude_in_degrees() const {
+    return in_degrees(longitude_);
+  }
 
   constexpr bool is_na() const {
     return latitude_ == na_latitude();
@@ -61,31 +110,72 @@ class GeoPoint {
     return GeoPoint(NA());
   }
 
-  static constexpr int32_t min_latitude() {
+  static constexpr int64_t min_latitude() {
     return degrees(-90);
   }
-  static constexpr int32_t max_latitude() {
+  static constexpr Int min_latitude_in_milliseconds() {
+    return in_milliseconds(min_latitude());
+  }
+  static constexpr Float min_latitude_in_degrees() {
+    return in_degrees(min_latitude());
+  }
+  static constexpr int64_t max_latitude() {
     return degrees(90);
   }
-  static constexpr int32_t na_latitude() {
-    return std::numeric_limits<int32_t>::min();
+  static constexpr Int max_latitude_in_milliseconds() {
+    return in_milliseconds(max_latitude());
+  }
+  static constexpr Float max_latitude_in_degrees() {
+    return in_degrees(max_latitude());
+  }
+  static constexpr int64_t na_latitude() {
+    return na_value();
   }
-  static constexpr int32_t min_longitude() {
+
+  static constexpr int64_t min_longitude() {
     return degrees(-180);
   }
-  static constexpr int32_t max_longitude() {
+  static constexpr Int min_longitude_in_milliseconds() {
+    return in_milliseconds(min_longitude());
+  }
+  static constexpr Float min_longitude_in_degrees() {
+    return in_degrees(min_longitude());
+  }
+  static constexpr int64_t max_longitude() {
     return degrees(180);
   }
-  static constexpr int32_t na_longitude() {
-    return std::numeric_limits<int32_t>::min();
+  static constexpr Int max_longitude_in_milliseconds() {
+    return in_milliseconds(max_longitude());
+  }
+  static constexpr Float max_longitude_in_degrees() {
+    return in_degrees(max_longitude());
+  }
+  static constexpr int64_t na_longitude() {
+    return na_value();
   }
 
  private:
   int32_t latitude_;   // Latitude in milliseconds.
   int32_t longitude_;  // Longitude in milliseconds.
 
-  static constexpr int32_t degrees(int32_t value) {
-    return value * 60 * 60 * 1000;
+  // Return a value that indicates N/A.
+  static constexpr int64_t na_value() {
+    return std::numeric_limits<int32_t>::min();
+  }
+
+  // Return the number of milliseconds for "n" degrees.
+  static constexpr int64_t degrees(int64_t n) {
+    return n * 60 * 60 * 1000;
+  }
+
+  // Express "value" in milliseconds with Int.
+  static constexpr Int in_milliseconds(int64_t value) {
+    return (value == na_value()) ? Int::na() : Int(value);
+  }
+  // Express "value" in degrees with Float.
+  static constexpr Float in_degrees(int64_t value) {
+    return (value == na_value()) ?
+           Float::na() : Float(value / double(60 * 60 * 1000));
   }
 };
 

  Modified: test/test_column.cpp (+3 -2)
===================================================================
--- test/test_column.cpp    2014-11-07 10:25:08 +0900 (c8f397b)
+++ test/test_column.cpp    2014-11-07 13:35:39 +0900 (e69b332)
@@ -234,10 +234,11 @@ void test_column() {
   assert(datum.type() == grnxx::FLOAT_DATA);
   assert(datum.as_float() == grnxx::Float(1.25));
 
-  geo_point_column->set(row_id, grnxx::GeoPoint(123, 456));
+  grnxx::GeoPoint geo_point(grnxx::Int(123), grnxx::Int(456));
+  geo_point_column->set(row_id, geo_point);
   geo_point_column->get(row_id, &datum);
   assert(datum.type() == grnxx::GEO_POINT_DATA);
-  assert(datum.as_geo_point() == grnxx::GeoPoint(123, 456));
+  assert(datum.as_geo_point() == geo_point);
 
   reference_column->set(row_id, row_id);
   reference_column->get(row_id, &datum);
-------------- next part --------------
HTML����������������������������...
ダウンロード 



More information about the Groonga-commit mailing list
アーカイブの一覧に戻る