From f2928828a725100690d9767cfac8d846b0e2e3bc Mon Sep 17 00:00:00 2001
From: Guillaume Pasero <guillaume.pasero@c-s.fr>
Date: Tue, 3 Jul 2012 10:46:58 +0200
Subject: [PATCH] ENH: image envelope can be sampled also on edges

---
 Applications/Projections/otbImageEnvelope.cxx |  7 ++
 .../otbImageToEnvelopeVectorDataFilter.h      |  6 ++
 .../otbImageToEnvelopeVectorDataFilter.txx    | 69 ++++++++++++++++++-
 3 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/Applications/Projections/otbImageEnvelope.cxx b/Applications/Projections/otbImageEnvelope.cxx
index 4d2899893a..9c7511215c 100644
--- a/Applications/Projections/otbImageEnvelope.cxx
+++ b/Applications/Projections/otbImageEnvelope.cxx
@@ -67,6 +67,12 @@ private:
     AddParameter(ParameterType_OutputVectorData,  "out",   "Output Vector Data");
     SetParameterDescription("out", "Vector data file containing the envelope");
 
+    AddParameter(ParameterType_Int, "sr", "Sampling Rate");
+    SetParameterDescription("sr", "Sampling rate for image edges (in pixel)");
+    SetDefaultParameterInt("sr",0);
+    MandatoryOff("sr");
+    DisableParameter("sr");
+    
     // Elevation
     ElevationParametersHandler::AddElevationParameters(this, "elev");
     
@@ -90,6 +96,7 @@ private:
     
     m_Envelope = EnvelopeFilterType::New();
     m_Envelope->SetInput(input);
+    m_Envelope->SetSamplingRate(GetParameterInt("sr"));
     
     // Elevation through the elevation handler
     if (ElevationParametersHandler::IsElevationEnabled(this, "elev"))
diff --git a/Code/Projections/otbImageToEnvelopeVectorDataFilter.h b/Code/Projections/otbImageToEnvelopeVectorDataFilter.h
index dc53122ff4..a0ab42b162 100644
--- a/Code/Projections/otbImageToEnvelopeVectorDataFilter.h
+++ b/Code/Projections/otbImageToEnvelopeVectorDataFilter.h
@@ -28,6 +28,8 @@ namespace otb
   * \brief Build a vector data containing the polygon of the image envelope
   *
   * This filter uses the GenericRSTransform to project the four corners of the image into ground position.
+  * If the sampling rate is not null, the image edges are also projected (using one point every 
+  * "m_SamplingRate" pixels).
   * In case of raw image geometry, a DEM directory or average elevation can be set for better accuracy.
   *
   * This filter supports user-specified output projection. If no projection is defined, the standard WGS84
@@ -91,6 +93,9 @@ public:
 
   itkSetMacro(AverageElevation, double);
   itkGetMacro(AverageElevation, double);
+  
+  itkSetMacro(SamplingRate, unsigned int);
+  itkGetMacro(SamplingRate, unsigned int);
 
 protected:
   ImageToEnvelopeVectorDataFilter();
@@ -113,6 +118,7 @@ private:
   std::string                  m_DEMDirectory;
   std::string                  m_GeoidFile;
   double                       m_AverageElevation;
+  unsigned int                 m_SamplingRate;      // Sampling rate for edges (in pixels)
 };
 
 } // end namespace otb
diff --git a/Code/Projections/otbImageToEnvelopeVectorDataFilter.txx b/Code/Projections/otbImageToEnvelopeVectorDataFilter.txx
index d748f5d124..4aefba743b 100644
--- a/Code/Projections/otbImageToEnvelopeVectorDataFilter.txx
+++ b/Code/Projections/otbImageToEnvelopeVectorDataFilter.txx
@@ -29,7 +29,8 @@ namespace otb
 template <class TInputImage, class TOutputVectorData>
 ImageToEnvelopeVectorDataFilter<TInputImage, TOutputVectorData>
 ::ImageToEnvelopeVectorDataFilter() : m_DEMDirectory(""), m_GeoidFile(""),
-                                      m_AverageElevation(-32768.0)
+                                      m_AverageElevation(-32768.0),
+                                      m_SamplingRate(0)
 {
   this->SetNumberOfInputs(1);
   this->SetNumberOfOutputs(1);
@@ -148,6 +149,9 @@ ImageToEnvelopeVectorDataFilter<TInputImage, TOutputVectorData>
   inputPtr->TransformIndexToPhysicalPoint(ll, llp);
 
   this->InstantiateTransform();
+  
+  typename InputImageType::IndexType edgeIndex;
+  typename InputImageType::PointType edgePoint;
 
   // Build envelope polygon
   typename PolygonType::Pointer envelope = PolygonType::New();
@@ -156,18 +160,81 @@ ImageToEnvelopeVectorDataFilter<TInputImage, TOutputVectorData>
   vertex[0] = current[0];
   vertex[1] = current[1];
   envelope->AddVertex(vertex);
+  
+  if (m_SamplingRate>0)
+    {
+    edgeIndex = ul;
+    edgeIndex[0]+=m_SamplingRate;
+    while (edgeIndex[0]<ur[0])
+      {
+      inputPtr->TransformIndexToPhysicalPoint(edgeIndex, edgePoint);
+      current = m_Transform->TransformPoint(edgePoint);
+      vertex[0] = current[0];
+      vertex[1] = current[1];
+      envelope->AddVertex(vertex);
+      edgeIndex[0]+=m_SamplingRate;
+      }
+    }
+  
   current = m_Transform->TransformPoint(urp);
   vertex[0] = current[0];
   vertex[1] = current[1];
   envelope->AddVertex(vertex);
+  
+  if (m_SamplingRate>0)
+    {
+    edgeIndex = ur;
+    edgeIndex[1]+=m_SamplingRate;
+    while (edgeIndex[1]<lr[1])
+      {
+      inputPtr->TransformIndexToPhysicalPoint(edgeIndex, edgePoint);
+      current = m_Transform->TransformPoint(edgePoint);
+      vertex[0] = current[0];
+      vertex[1] = current[1];
+      envelope->AddVertex(vertex);
+      edgeIndex[1]+=m_SamplingRate;
+      }
+    }
+  
   current = m_Transform->TransformPoint(lrp);
   vertex[0] = current[0];
   vertex[1] = current[1];
   envelope->AddVertex(vertex);
+  
+  if (m_SamplingRate>0)
+    {
+    edgeIndex = lr;
+    edgeIndex[0]-=m_SamplingRate;
+    while (edgeIndex[0]>ll[0])
+      {
+      inputPtr->TransformIndexToPhysicalPoint(edgeIndex, edgePoint);
+      current = m_Transform->TransformPoint(edgePoint);
+      vertex[0] = current[0];
+      vertex[1] = current[1];
+      envelope->AddVertex(vertex);
+      edgeIndex[0]-=m_SamplingRate;
+      }
+    }
+  
   current = m_Transform->TransformPoint(llp);
   vertex[0] = current[0];
   vertex[1] = current[1];
   envelope->AddVertex(vertex);
+  
+  if (m_SamplingRate>0)
+    {
+    edgeIndex = ll;
+    edgeIndex[1]-=m_SamplingRate;
+    while (edgeIndex[1]>ul[1])
+      {
+      inputPtr->TransformIndexToPhysicalPoint(edgeIndex, edgePoint);
+      current = m_Transform->TransformPoint(edgePoint);
+      vertex[0] = current[0];
+      vertex[1] = current[1];
+      envelope->AddVertex(vertex);
+      edgeIndex[1]-=m_SamplingRate;
+      }
+    }
 
   // Add polygon to the VectorData tree
   OutputDataTreePointerType tree = outputPtr->GetDataTree();
-- 
GitLab