From 3b7343b5bc3682311764d67d5b1660bb2ffae42e Mon Sep 17 00:00:00 2001
From: Guillaume Pasero <guillaume.pasero@c-s.fr>
Date: Wed, 13 Sep 2017 17:07:32 +0200
Subject: [PATCH] BUG: Mantis-1432: enhance SRS detection

---
 .../include/otbGeoInformationConversion.h     | 11 ++++++-
 .../src/otbGeoInformationConversion.cxx       | 31 +++++++++++++++++++
 .../src/mvdAbstractLayerModel.cxx             | 29 ++++++-----------
 3 files changed, 51 insertions(+), 20 deletions(-)

diff --git a/Modules/Core/Transform/include/otbGeoInformationConversion.h b/Modules/Core/Transform/include/otbGeoInformationConversion.h
index 3fd9b45d62..d20f786f7c 100644
--- a/Modules/Core/Transform/include/otbGeoInformationConversion.h
+++ b/Modules/Core/Transform/include/otbGeoInformationConversion.h
@@ -33,7 +33,9 @@ namespace otb
  *  \brief Helper functions to do the geo information conversions used frequently.
  *
  *  This namespace provides helpers functions to build a WKT from a valid EPSG number using
- *  the method ToWKT(int srid).
+ *  the method ToWKT(int srid), and also to retrieve an EPSG number from a WKT
+ *  using the method ToEPSG(const std::string &)
+ *
  */
 namespace GeoInformationConversion
 {
@@ -43,6 +45,13 @@ namespace GeoInformationConversion
 
   /** this method try to morph a wkt to ESRI WKT format and returns the error code**/
   OTBTransform_EXPORT bool IsESRIValidWKT(const std::string &Wkt);
+
+  /** Function used to get an epsg number from a wkt string.
+   *  Returns -1 if the wkt is neither a PROJCS nor a GEOGCS.
+   *  Returns 0 if no authority code is found but wkt has a PROJCS or a GEOGCS.
+   *  Otherwise the EPSG authority code is returned
+   */
+  OTBTransform_EXPORT int ToEPSG(const std::string &wkt);
 }
 
 } // End namespace otb
diff --git a/Modules/Core/Transform/src/otbGeoInformationConversion.cxx b/Modules/Core/Transform/src/otbGeoInformationConversion.cxx
index 635b8cf8f8..4beb0cd9ec 100644
--- a/Modules/Core/Transform/src/otbGeoInformationConversion.cxx
+++ b/Modules/Core/Transform/src/otbGeoInformationConversion.cxx
@@ -73,4 +73,35 @@ bool GeoInformationConversion::IsESRIValidWKT(const std::string &wkt)
   return SRS.Validate()==OGRERR_NONE;
 }
 
+int GeoInformationConversion::ToEPSG(const std::string &wkt)
+{
+  int code = -1;
+  OGRSpatialReference srs(wkt.c_str());
+  srs.Fixup();
+  srs.AutoIdentifyEPSG();
+  const char * epsg = nullptr;
+  if (srs.IsGeographic())
+    {
+    code = 0;
+    epsg = srs.GetAuthorityCode("GEOGCS");
+    }
+  else if (srs.IsProjected())
+    {
+    code = 0;
+    epsg = srs.GetAuthorityCode("PROJCS");
+    }
+  if (epsg!=nullptr && strcmp( epsg, "" )!=0 )
+    {
+    try
+      {
+      code = boost::lexical_cast<int>(epsg);
+      }
+    catch(boost::bad_lexical_cast &)
+      {
+      code = 0;
+      }
+    }
+  return code;
+}
+
 } // End namespace otb
diff --git a/Modules/Visualization/MonteverdiCore/src/mvdAbstractLayerModel.cxx b/Modules/Visualization/MonteverdiCore/src/mvdAbstractLayerModel.cxx
index 4598db5f84..caac49abe2 100644
--- a/Modules/Visualization/MonteverdiCore/src/mvdAbstractLayerModel.cxx
+++ b/Modules/Visualization/MonteverdiCore/src/mvdAbstractLayerModel.cxx
@@ -37,7 +37,7 @@
 
 //
 // OTB includes (sorted by alphabetic order)
-
+#include "otbGeoInformationConversion.h"
 //
 // Monteverdi includes (sorted by alphabetic order)
 #include "mvdAlgorithm.h"
@@ -62,6 +62,7 @@ namespace
 {
 char const * const STR_SENSOR = QT_TRANSLATE_NOOP( "mvd::AbstractLayerModel", "Sensor" );
 char const * const STR_UNKNOWN = QT_TRANSLATE_NOOP( "mvd::AbstractLayerModel", "Unknown" );
+char const * const STR_NOEPSG = QT_TRANSLATE_NOOP( "mvd::AbstractLayerModel", "No EPSG" );
 } // end of anonymous namespace.
 
 
@@ -98,16 +99,12 @@ GetSpatialReferenceType( const std::string & wkt, bool hasKwl )
 
   OGRSpatialReference ogr_sr( wkt.c_str() );
 
-  const char * epsg = ogr_sr.GetAuthorityCode( "PROJCS" );
+  if(ogr_sr.IsGeographic())
+    return SRT_GEO;
 
-  if( epsg!=NULL && strcmp( epsg, "" )!=0 )
+  if(ogr_sr.IsProjected())
     return SRT_CARTO;
 
-  epsg = ogr_sr.GetAuthorityCode( "GEOGCS" );
-
-  if( epsg!=NULL && strcmp( epsg, "" )!=0 )
-    return SRT_GEO;
-
   return SRT_UNKNOWN;
 }
 
@@ -158,19 +155,13 @@ AbstractLayerModel
 	  ? ToStdString( tr( STR_SENSOR ) )
 	  : ToStdString( tr( STR_UNKNOWN ) ) );
 
-  OGRSpatialReference ogr_sr( wkt.c_str() );
-
-  const char * epsg = ogr_sr.GetAuthorityCode( "PROJCS" );
-
-  if( epsg!=NULL && strcmp( epsg, "" )!=0 )
-    return epsg;
-
-  epsg = ogr_sr.GetAuthorityCode( "GEOGCS" );
-
-  if( epsg==NULL || strcmp( epsg, "" )==0 )
+  int code = otb::GeoInformationConversion::ToEPSG(wkt);
+  if(code < 0)
     return ToStdString( tr( STR_UNKNOWN ) );
+  else if(code == 0)
+    return ToStdString( tr( STR_NOEPSG ) );
 
-  return epsg;
+  return boost::lexical_cast<std::string>(code);
 }
 
 /*******************************************************************************/
-- 
GitLab