From 2e72af2de9ea1732593530d0638cbe0dee51ff03 Mon Sep 17 00:00:00 2001
From: Julien Michel <julien.michel@orfeo-toolbox.org>
Date: Wed, 21 Nov 2012 16:04:21 +0100
Subject: [PATCH] ENH: Adding an optionnal output with vector matches

---
 .../otbHomologousPointsExtraction.cxx         | 64 ++++++++++++++++---
 1 file changed, 54 insertions(+), 10 deletions(-)

diff --git a/Applications/FeatureExtraction/otbHomologousPointsExtraction.cxx b/Applications/FeatureExtraction/otbHomologousPointsExtraction.cxx
index c479c4a0a8..6c1328ee58 100644
--- a/Applications/FeatureExtraction/otbHomologousPointsExtraction.cxx
+++ b/Applications/FeatureExtraction/otbHomologousPointsExtraction.cxx
@@ -34,6 +34,8 @@
 #include "itkPointSet.h"
 #include "itkEuclideanDistance.h"
 #include "otbGenericRSTransform.h"
+#include "otbOGRDataSourceWrapper.h"
+#include "ogrsf_frmts.h"
 
 namespace otb
 {
@@ -144,6 +146,11 @@ private:
 
     AddParameter(ParameterType_OutputFilename,"out","Output file with tie points");
     SetParameterDescription("out","File containing the list of tie points");
+
+    AddParameter(ParameterType_OutputFilename,"outvector","Output vector file with tie points");
+    SetParameterDescription("outvector","File containing segments representing matches ");
+    MandatoryOff("outvector");
+    DisableParameter("outvector");
   }
 
   void DoUpdateParameters()
@@ -151,7 +158,7 @@ private:
 
   }
 
-  void Match(FloatImageType * im1, FloatImageType * im2, RSTransformType * rsTransform, RSTransformType * rsTransform2ToWGS84, std::ofstream & file)
+  void Match(FloatImageType * im1, FloatImageType * im2, RSTransformType * rsTransform, RSTransformType * rsTransform1ToWGS84,RSTransformType * rsTransform2ToWGS84, std::ofstream & file, OGRMultiLineString * mls = NULL)
   {
     MatchingFilterType::Pointer matchingFilter = MatchingFilterType::New();
 
@@ -212,16 +219,16 @@ private:
         PointType point2 = it.Get()->GetPoint2();
         
         double error = 0;
-        PointType pprime;
+        PointType pprime1,pprime2;
         
         bool filtered = false;
         
         if(IsParameterEnabled("mfilter"))
           {
-          pprime = rsTransform->TransformPoint(point1);
-          error = vcl_sqrt((point2[0]-pprime[0])*(point2[0]-pprime[0])+(point2[1]-pprime[1])*(point2[1]-pprime[1]));
+          pprime1 = rsTransform->TransformPoint(point1);
+          error = vcl_sqrt((point2[0]-pprime1[0])*(point2[0]-pprime1[0])+(point2[1]-pprime1[1])*(point2[1]-pprime1[1]));
           
-          if(error>GetParameterFloat("precision"))
+          if(error>GetParameterFloat("precision")*vcl_sqrt(vcl_abs(im2->GetSpacing()[0]*im2->GetSpacing()[1])))
             {
             filtered = true;
             }
@@ -231,14 +238,26 @@ private:
           {
           if(IsParameterEnabled("2wgs84"))
             {
-            pprime = rsTransform2ToWGS84->TransformPoint(point2);
+            pprime2 = rsTransform2ToWGS84->TransformPoint(point2);
             
-            file<<point1[0]<<"\t"<<point1[1]<<"\t"<<pprime[0]<<"\t"<<pprime[1]<<std::endl;
+            file<<point1[0]<<"\t"<<point1[1]<<"\t"<<pprime2[0]<<"\t"<<pprime2[1]<<std::endl;
             }
           else
             {
             file<<point1[0]<<"\t"<<point1[1]<<"\t"<<point2[0]<<"\t"<<point2[1]<<std::endl;
             }
+          
+          if(mls)
+            {
+             pprime1 = rsTransform1ToWGS84->TransformPoint(point1);
+             pprime2 = rsTransform2ToWGS84->TransformPoint(point2);
+
+             OGRLineString ls;
+             ls.addPoint(pprime1[0],pprime1[1]);
+             ls.addPoint(pprime2[0],pprime2[1]);
+             mls->addGeometry(&ls);
+            }
+
           }
         else
           {
@@ -256,6 +275,8 @@ private:
 
   void DoExecute()
   {
+    OGRMultiLineString mls;
+
     // Setting up RS Transform
     RSTransformType::Pointer rsTransform = RSTransformType::New();
     rsTransform->SetInputKeywordList(this->GetParameterImage("in1")->GetImageKeywordlist());
@@ -263,10 +284,13 @@ private:
     rsTransform->SetOutputKeywordList(this->GetParameterImage("in2")->GetImageKeywordlist());
     rsTransform->SetOutputProjectionRef(this->GetParameterImage("in2")->GetProjectionRef());
 
+    RSTransformType::Pointer rsTransform1ToWGS84 = RSTransformType::New();
+    rsTransform1ToWGS84->SetInputKeywordList(this->GetParameterImage("in1")->GetImageKeywordlist());
+    rsTransform1ToWGS84->SetInputProjectionRef(this->GetParameterImage("in1")->GetProjectionRef());
+
     RSTransformType::Pointer rsTransform2ToWGS84 = RSTransformType::New();
     rsTransform2ToWGS84->SetInputKeywordList(this->GetParameterImage("in2")->GetImageKeywordlist());
     rsTransform2ToWGS84->SetInputProjectionRef(this->GetParameterImage("in2")->GetProjectionRef());
-    
 
     // Setting up output file
     std::ofstream file;
@@ -287,13 +311,14 @@ private:
     otb::Wrapper::ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(this,"elev");
 
     rsTransform->InstanciateTransform();
+    rsTransform1ToWGS84->InstanciateTransform();
     rsTransform2ToWGS84->InstanciateTransform();
 
 
     if(GetParameterString("mode")=="full")
       {
       // Launch detection on whole images
-      Match(extractChannel1->GetOutput(),extractChannel2->GetOutput(),rsTransform,rsTransform2ToWGS84,file);
+      Match(extractChannel1->GetOutput(),extractChannel2->GetOutput(),rsTransform,rsTransform1ToWGS84,rsTransform2ToWGS84,file,&mls);
 
       }
     else if(GetParameterString("mode")=="geobins")
@@ -385,12 +410,31 @@ private:
 
             extractChannel2->SetExtractionRegion(region2);
 
-            Match(extractChannel1->GetOutput(),extractChannel2->GetOutput(),rsTransform,rsTransform2ToWGS84,file);
+            Match(extractChannel1->GetOutput(),extractChannel2->GetOutput(),rsTransform,rsTransform1ToWGS84,rsTransform2ToWGS84,file,&mls);
             }
           }
         
         }
       file.close();
+
+      if(IsParameterEnabled("outvector"))
+        {
+        // Create the datasource (for matches export)
+        otb::ogr::Layer layer(NULL, false);
+        otb::ogr::DataSource::Pointer ogrDS;
+       
+        ogrDS = otb::ogr::DataSource::New(GetParameterString("outvector"), otb::ogr::DataSource::Modes::Overwrite);
+        std::string projref = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4326\"]]";
+        OGRSpatialReference oSRS(projref.c_str());
+      
+        // and create the layer
+        layer = ogrDS->CreateLayer("matches", &oSRS, wkbMultiLineString);
+        OGRFeatureDefn & defn = layer.GetLayerDefn();
+        ogr::Feature feature(defn);
+        
+        feature.SetGeometry(&mls);
+        layer.CreateFeature(feature);
+        }
       }
   }
 };
-- 
GitLab