OTB  6.7.0
Orfeo Toolbox
otbRasterizeVectorDataFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbRasterizeVectorDataFilter_hxx
22 #define otbRasterizeVectorDataFilter_hxx
23 
25 #include "otbOGRIOHelper.h"
26 #include "otbGdalDataTypeBridge.h"
27 
28 namespace otb
29 {
30 template<class TVectorData, class TInputImage, class TOutputImage>
33  : m_OGRDataSourcePointer(nullptr),
34  m_AllTouchedMode(false)
35 {
36  this->SetNumberOfRequiredInputs(1);
37 }
38 
39 template<class TVectorData, class TInputImage, class TOutputImage>
40 void
43 {
44  // Process object is not const-correct so the const_cast is required
45  // here
46  if (this->GetNumberOfInputs() < 1)
47  {
48  this->itk::ProcessObject::SetNthInput(1, const_cast<VectorDataType *>(vd) );
49  }
50  else
51  {
53  }
54 }
55 
56 
57 template<class TVectorData, class TInputImage, class TOutputImage>
58 void
61 {
62  Superclass::GenerateOutputInformation();
63 
64  // Generate the OGRLayers from the input VectorDatas
65  // iteration begin from 1 cause the 0th input is a image
66  for (unsigned int idx = 1; idx < this->GetNumberOfInputs(); ++idx)
67  {
68  const VectorDataType* vd = dynamic_cast< const VectorDataType*>(this->itk::ProcessObject::GetInput(idx));
69 
70  // Get the projection ref of the current VectorData
71  std::string projectionRefWkt = vd->GetProjectionRef();
72  bool projectionInformationAvailable = !projectionRefWkt.empty();
73  OGRSpatialReference * oSRS = nullptr;
74 
75  if (projectionInformationAvailable)
76  {
77  oSRS = static_cast<OGRSpatialReference *>(OSRNewSpatialReference(projectionRefWkt.c_str()));
78  }
79  else
80  {
81  otbMsgDevMacro(<< "Projection information unavailable");
82  }
83 
84  // Retrieving root node
85  DataTreeConstPointerType tree = vd->GetDataTree();
86 
87  // Get the input tree root
88  InternalTreeNodeType * inputRoot = const_cast<InternalTreeNodeType *>(tree->GetRoot());
89 
90  // Iterative method to build the layers from a VectorData
91  OGRRegisterAll();
92  OGRLayer * ogrCurrentLayer = nullptr;
93  std::vector<OGRLayer *> ogrLayerVector;
95 
96  // The method ConvertDataTreeNodeToOGRLayers create the
97  // OGRDataSource but don t release it. Destruction is done in the
98  // desctructor
99  m_OGRDataSourcePointer = nullptr;
100  ogrLayerVector = IOConversion->ConvertDataTreeNodeToOGRLayers(inputRoot,
101  m_OGRDataSourcePointer,
102  ogrCurrentLayer,
103  oSRS);
104 
105  // Cast OGRLayer* to OGRLayerH
106  for (unsigned int idx2 = 0; idx2 < ogrLayerVector.size(); ++idx2)
107  {
108  m_SrcDataSetLayers.push_back( (OGRLayerH)(ogrLayerVector[idx2]) );
109  }
110 
111  // Destroy the oSRS
112  if (oSRS != nullptr)
113  {
114  OSRRelease(oSRS);
115  }
116  }
117 
118  // Some checking : Check the consistency between the band list
119  // to burn and the burn values :
120  // There should be "m_BandsToBurn.size()" burn values for each layer.
121  // If not, burn values vector will be cloned as many time as the number of
122  // OGRLayer we have
123  if (m_BurnValues.size() != m_BandsToBurn.size() * m_SrcDataSetLayers.size())
124  {
125  std::ostringstream oss;
126  oss <<"Inconsistency detected : expected burn vector size to be equal to( bandToBurn * nb layers = "
127  << m_BandsToBurn.size() * m_SrcDataSetLayers.size()
128  << " ), got : "<< m_BurnValues.size()<<std::endl;
129  itkWarningMacro(<<oss.str());
130  }
131 
132  // Clone the burn values to fit the condition
133  for (unsigned int idx =0; idx < m_SrcDataSetLayers.size(); ++idx)
134  {
135  for (unsigned int burnidx = 0; burnidx < m_BurnValues.size(); ++burnidx)
136  {
137  m_FullBurnValues.push_back(m_BurnValues[burnidx]);
138  }
139  }
140 }
141 
142 template<class TVectorData, class TInputImage, class TOutputImage>
143 void
145 {
146  // Call Superclass GenerateData
147  Superclass::GenerateData();
148 
149  // Get the buffered region
150  OutputImageRegionType bufferedRegion = this->GetOutput()->GetBufferedRegion();
151 
152  // nb bands
153  unsigned int nbBands = this->GetOutput()->GetNumberOfComponentsPerPixel();
154 
155  // register drivers
156  GDALAllRegister();
157 
158  std::ostringstream stream;
159  stream << "MEM:::"
160  << "DATAPOINTER=" << (uintptr_t)(this->GetOutput()->GetBufferPointer()) << ","
161  << "PIXELS=" << bufferedRegion.GetSize()[0] << ","
162  << "LINES=" << bufferedRegion.GetSize()[1]<< ","
163  << "BANDS=" << nbBands << ","
164  << "DATATYPE=" << GDALGetDataTypeName(GdalDataTypeBridge::GetGDALDataType<OutputImageInternalPixelType>()) << ","
165  << "PIXELOFFSET=" << sizeof(OutputImageInternalPixelType) * nbBands << ","
166  << "LINEOFFSET=" << sizeof(OutputImageInternalPixelType)*nbBands*bufferedRegion.GetSize()[0] << ","
167  << "BANDOFFSET=" << sizeof(OutputImageInternalPixelType);
168 
169  GDALDatasetH dataset = GDALOpen(stream.str().c_str(), GA_Update);
170 
171  // Add the projection ref to the dataset
172  GDALSetProjection (dataset, this->GetOutput()->GetProjectionRef().c_str());
173 
174  // add the geoTransform to the dataset
175  itk::VariableLengthVector<double> geoTransform(6);
176 
177  // Reporting origin and spacing of the buffered region
178  // the spacing is unchanged, the origin is relative to the buffered region
179  InputIndexType bufferIndexOrigin = bufferedRegion.GetIndex();
180  InputPointType bufferOrigin;
181  this->GetOutput()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin);
182  geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetOutput()->GetSignedSpacing()[0];
183  geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetOutput()->GetSignedSpacing()[1];
184  geoTransform[1] = this->GetOutput()->GetSignedSpacing()[0];
185  geoTransform[5] = this->GetOutput()->GetSignedSpacing()[1];
186 
187  // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
188  geoTransform[2] = 0.;
189  geoTransform[4] = 0.;
190  GDALSetGeoTransform(dataset,const_cast<double*>(geoTransform.GetDataPointer()));
191 
192  char **options = nullptr;
193  if (m_AllTouchedMode)
194  {
195  options = CSLSetNameValue(options, "ALL_TOUCHED", "TRUE");
196  }
197 
198  // Burn the geometries into the dataset
199  if (dataset != nullptr)
200  {
201  GDALRasterizeLayers( dataset, m_BandsToBurn.size(),
202  &(m_BandsToBurn[0]),
203  m_SrcDataSetLayers.size(),
204  &(m_SrcDataSetLayers[0]),
205  nullptr, nullptr, &(m_FullBurnValues[0]),
206  options,
207  GDALDummyProgress, nullptr );
208 
209  CSLDestroy(options);
210 
211  // release the dataset
212  GDALClose( dataset );
213  }
214 }
215 
216 template<class TVectorData, class TInputImage, class TOutputImage>
217 void
219 ::PrintSelf(std::ostream& os, itk::Indent indent) const
220 {
221  Superclass::PrintSelf(os, indent);
222 }
223 
224 } // end namespace otb
225 
226 #endif
DataTreeType::TreeNodeType InternalTreeNodeType
virtual void AddVectorData(const VectorDataType *vd)
DataTreeType::ConstPointer DataTreeConstPointerType
OutputImageType::InternalPixelType OutputImageInternalPixelType
virtual void PushBackInput(const DataObject *input)
const TValue * GetDataPointer() const noexcept
DataObject * GetInput(const DataObjectIdentifierType &key)
Superclass::OutputImageRegionType OutputImageRegionType
void PrintSelf(std::ostream &os, itk::Indent indent) const override
static Pointer New()
virtual void SetNthInput(DataObjectPointerArraySizeType num, DataObject *input)
typedef::vcl_size_t uintptr_t
#define otbMsgDevMacro(x)
Definition: otbMacro.h:66