[niepce] Add Gps coordinate decoding from XMP.
- From: Hubert Figuière <hub src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [niepce] Add Gps coordinate decoding from XMP.
- Date: Sat, 12 Jul 2014 17:01:57 +0000 (UTC)
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]