[niepce] Add Gps coordinate decoding from XMP.



commit 650c0942f4144599b859d61ee41e3340c0cffc38
Author: Hubert Figuière <hub figuiere net>
Date:   Wed Jul 9 23:30:58 2014 -0400

    Add Gps coordinate decoding from XMP.

 src/fwk/utils/exempi.cpp  |   66 +++++++++++++++++++++++++++++++++++++++++++++
 src/fwk/utils/exempi.hpp  |    3 ++
 src/fwk/utils/testxmp.cpp |   28 ++++++++++++++++++-
 3 files changed, 96 insertions(+), 1 deletions(-)
---
diff --git a/src/fwk/utils/exempi.cpp b/src/fwk/utils/exempi.cpp
index bd9ca8a..996e7b7 100644
--- a/src/fwk/utils/exempi.cpp
+++ b/src/fwk/utils/exempi.cpp
@@ -21,6 +21,8 @@
 #include <string.h>
 #include <time.h>
 
+#include <boost/lexical_cast.hpp>
+
 #include <glib.h>
 #include <giomm/file.h>
 
@@ -249,6 +251,70 @@ const std::vector< std::string > & XmpMeta::keywords() const
     return m_keywords;
 }
 
+double
+XmpMeta::gpsCoordFromXmp(const std::string & xmps)
+{
+    double coord = NAN;
+
+    const char* s = xmps.c_str();
+
+    // step 1 - degrees
+//    auto iter;
+    const char* current = strchr(s, ',');
+    if (current == nullptr) {
+        return NAN;
+    }
+
+    std::string degs = std::string(s, current - s);
+
+    current++;
+    if (!*current) {
+        return NAN;
+    }
+    // step 2 - minutes
+    size_t len = strlen(current);
+    if (len <= 1) {
+        // too short
+        return NAN;
+    }
+    const char *orientation = current + len - 1;
+    if (*orientation != 'N' &&
+        *orientation != 'S' &&
+        *orientation != 'E' &&
+        *orientation != 'W') {
+
+        return NAN;
+    }
+
+    const char *next = strchr(current, ',');
+    if (next) {
+        // DD,mm,ss
+
+    }
+    else {
+        // DD,mm.mm ?
+        std::string minutes = std::string(current, len - 1);
+        double fminutes = 0.;
+        try {
+            coord = boost::lexical_cast<int>(degs);
+            if (coord > 180) {
+                return NAN;
+            }
+            fminutes = boost::lexical_cast<double>(minutes);
+        }
+        catch(const std::exception & e) {
+            return NAN;
+        }
+        coord += fminutes / 60.f;
+
+        if (*orientation == 'S' || *orientation == 'W') {
+            coord = -coord;
+        }
+    }
+
+    return coord;
+}
+
 }
 
 /*
diff --git a/src/fwk/utils/exempi.hpp b/src/fwk/utils/exempi.hpp
index 30ea848..7e4ac12 100644
--- a/src/fwk/utils/exempi.hpp
+++ b/src/fwk/utils/exempi.hpp
@@ -132,6 +132,9 @@ public:
     fwk::Date  creation_date() const;
     std::string creation_date_str() const;
     const std::vector< std::string > & keywords() const;
+
+    static double gpsCoordFromXmp(const std::string & s);
+
 private:
 
     XmpPtr m_xmp;
diff --git a/src/fwk/utils/testxmp.cpp b/src/fwk/utils/testxmp.cpp
index e2da1e6..4e7f604 100644
--- a/src/fwk/utils/testxmp.cpp
+++ b/src/fwk/utils/testxmp.cpp
@@ -21,6 +21,7 @@
 #include <boost/test/minimal.hpp>
 
 #include <stdlib.h>
+#include <math.h>
 #include <vector>
 
 #include <glibmm/init.h>
@@ -51,7 +52,32 @@ int test_main( int, char *[] )             // note the name!
        BOOST_CHECK(keywords[2] == "ontario");
        BOOST_CHECK(keywords[3] == "ottawa");
        BOOST_CHECK(keywords[4] == "parliament of canada");
-       
+
+        double output = fwk::XmpMeta::gpsCoordFromXmp("foobar");
+        BOOST_CHECK(isnan(output));
+
+        // malformed 1
+        output = fwk::XmpMeta::gpsCoordFromXmp("45,29.6681666667");
+        BOOST_CHECK(isnan(output));
+
+        // malformed 2
+        output = fwk::XmpMeta::gpsCoordFromXmp("45,W");
+        BOOST_CHECK(isnan(output));
+
+        // out of bounds
+        output = fwk::XmpMeta::gpsCoordFromXmp("200,29.6681666667N");
+        BOOST_CHECK(isnan(output));
+
+        // well-formed 1
+        std::string gps1 = "45,29.6681666667N";
+        output = fwk::XmpMeta::gpsCoordFromXmp(gps1);
+        BOOST_CHECK(output == 45.494469444445002181964810006320476531982421875);
+
+        // well-formed 2
+        std::string gps2 = "73,38.2871666667W";
+        output = fwk::XmpMeta::gpsCoordFromXmp(gps2);
+        BOOST_CHECK(output == -73.6381194444449960201382054947316646575927734375);
+
        return 0;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]