OTB  10.0.0
Orfeo Toolbox
otbOGRDataSourceToLabelImageFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2024 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 otbOGRDataSourceToLabelImageFilter_hxx
22 #define otbOGRDataSourceToLabelImageFilter_hxx
23 
25 #include "otbOGRIOHelper.h"
26 #include "otbGdalDataTypeBridge.h"
28 #include "itkMetaDataObject.h"
29 #include "otbMetaDataKey.h"
30 #include "otbImage.h"
31 #include "otbNoDataHelper.h"
33 
34 #include "gdal_alg.h"
35 #include "stdint.h" //needed for uintptr_t
36 
37 namespace otb
38 {
39 template <class TOutputImage>
41  : m_BurnAttribute("DN"), m_BackgroundValue(0), m_ForegroundValue(255), m_BurnAttributeMode(true), m_AllTouchedMode(false)
42 {
43  this->SetNumberOfRequiredInputs(1);
44 
45  // Output parameters initialization
46  m_OutputSpacing.Fill(1.0);
47  m_OutputSize.Fill(0);
48  m_OutputStartIndex.Fill(0);
49  m_BandsToBurn.clear();
50  m_BandsToBurn.push_back(1);
51 }
52 
53 template <class TOutputImage>
55 {
56  this->itk::ProcessObject::PushBackInput(ds);
57 }
58 
59 template <class TOutputImage>
61 {
62  return static_cast<const OGRDataSourceType*>(this->itk::ProcessObject::GetInput(idx));
63 }
64 
65 template <class TOutputImage>
67 {
68  if (this->m_OutputSpacing != spacing)
69  {
70  this->m_OutputSpacing = spacing;
71  this->Modified();
72  }
73 }
74 
75 template <class TOutputImage>
77 {
78  OutputSpacingType s(spacing);
79  this->SetOutputSpacing(s);
80 }
81 
82 template <class TOutputImage>
84 {
85  itk::Vector<float, 2> sf(spacing);
87  s.CastFrom(sf);
88  this->SetOutputSpacing(s);
89 }
90 
91 template <class TOutputImage>
93 {
94  OutputOriginType p(origin);
95  this->SetOutputOrigin(p);
96 }
97 
98 template <class TOutputImage>
100 {
101  itk::Point<float, 2> of(origin);
103  p.CastFrom(of);
104  this->SetOutputOrigin(p);
105 }
106 
107 template <class TOutputImage>
108 template <class ImagePointerType>
110 {
111  this->SetOutputOrigin(src->GetOrigin());
112  this->SetOutputSpacing(src->GetSignedSpacing());
113  this->SetOutputSize(src->GetLargestPossibleRegion().GetSize());
114  this->SetOutputProjectionRef(src->GetProjectionRef());
115 }
116 
117 template <class TOutputImage>
119 {
120  // get pointer to the output
121  OutputImagePointer outputPtr = this->GetOutput();
122  if (!outputPtr)
123  {
124  return;
125  }
126 
127  // Set the size of the output region
128  typename TOutputImage::RegionType outputLargestPossibleRegion;
129  outputLargestPossibleRegion.SetSize(m_OutputSize);
130  // outputLargestPossibleRegion.SetIndex(m_OutputStartIndex);
131  outputPtr->SetLargestPossibleRegion(outputLargestPossibleRegion);
132 
133  // Set spacing and origin
134  outputPtr->SetSignedSpacing(m_OutputSpacing);
135  outputPtr->SetOrigin(m_OutputOrigin);
136  outputPtr->SetProjectionRef(this->GetOutputProjectionRef());
137 
138  // Generate the OGRLayers from the input OGRDataSource
139  for (unsigned int idx = 0; idx < this->GetNumberOfInputs(); ++idx)
140  {
141  OGRDataSourcePointerType ogrDS = dynamic_cast<OGRDataSourceType*>(this->itk::ProcessObject::GetInput(idx));
142  const unsigned int nbLayers = ogrDS->GetLayersCount();
143 
144  for (unsigned int layer = 0; layer < nbLayers; ++layer)
145  {
146  m_SrcDataSetLayers.push_back(&(ogrDS->GetLayer(layer).ogr()));
147  }
148  }
149 
150  // Set the NoData value using the background
151  const unsigned int& nbBands = outputPtr->GetNumberOfComponentsPerPixel();
152  std::vector<bool> noDataValueAvailable;
153  noDataValueAvailable.resize(nbBands, true);
154  std::vector<double> noDataValue;
155  noDataValue.resize(nbBands, static_cast<double>(m_BackgroundValue));
156 
157  WriteNoDataFlags(noDataValueAvailable, noDataValue, outputPtr->GetImageMetadata());
158 }
159 
160 template <class TOutputImage>
162 {
163  // Call Superclass GenerateData
164  this->AllocateOutputs();
165 
166  // Get the buffered region
167  OutputImageRegionType bufferedRegion = this->GetOutput()->GetBufferedRegion();
168 
169  // nb bands
170  const unsigned int& nbBands = this->GetOutput()->GetNumberOfComponentsPerPixel();
171 
174  this->GetOutput()->GetBufferPointer(),
175  bufferedRegion.GetSize()[0],
176  bufferedRegion.GetSize()[1],
177  GdalDataTypeBridge::GetGDALDataType<OutputImageInternalPixelType>(),
178  sizeof(OutputImageInternalPixelType), nbBands,
180  );
181  // Add the projection ref to the dataset
182  GDALSetProjection(dataset->GetDataSet(), this->GetOutput()->GetProjectionRef().c_str());
183 
184  // Set the nodata value
185  for (unsigned int band = 0; band < nbBands; ++band)
186  {
187  GDALRasterBandH hBand = GDALGetRasterBand(dataset->GetDataSet(), band + 1);
188  GDALFillRaster(hBand, m_BackgroundValue, 0);
189  }
190 
191  // add the geoTransform to the dataset
192  itk::VariableLengthVector<double> geoTransform(6);
193 
194  // Reporting origin and spacing of the buffered region
195  // the spacing is unchanged, the origin is relative to the buffered region
196  OutputIndexType bufferIndexOrigin = bufferedRegion.GetIndex();
197  OutputOriginType bufferOrigin;
198  this->GetOutput()->TransformIndexToPhysicalPoint(bufferIndexOrigin, bufferOrigin);
199  geoTransform[0] = bufferOrigin[0] - 0.5 * this->GetOutput()->GetSignedSpacing()[0];
200  geoTransform[3] = bufferOrigin[1] - 0.5 * this->GetOutput()->GetSignedSpacing()[1];
201  geoTransform[1] = this->GetOutput()->GetSignedSpacing()[0];
202  geoTransform[5] = this->GetOutput()->GetSignedSpacing()[1];
203 
204  // FIXME: Here component 1 and 4 should be replaced by the orientation parameters
205  geoTransform[2] = 0.;
206  geoTransform[4] = 0.;
207  GDALSetGeoTransform(dataset->GetDataSet(), const_cast<double*>(geoTransform.GetDataPointer()));
208 
209  // Burn the geometries into the dataset
210  if (dataset->GetDataSet() != nullptr)
211  {
212  std::vector<std::string> options;
213 
214  std::vector<double> foreground(nbBands * m_SrcDataSetLayers.size(), m_ForegroundValue);
215 
216  if (m_BurnAttributeMode)
217  {
218  options.push_back("ATTRIBUTE=" + m_BurnAttribute);
219  }
220  if (m_AllTouchedMode)
221  {
222  options.push_back("ALL_TOUCHED=TRUE");
223  }
224 
225  GDALRasterizeLayers(dataset->GetDataSet(), nbBands, &m_BandsToBurn[0], m_SrcDataSetLayers.size(), &(m_SrcDataSetLayers[0]), nullptr, nullptr, &foreground[0],
226  ogr::StringListConverter(options).to_ogr(), nullptr, nullptr);
227  }
228 }
229 
230 template <class TOutputImage>
231 void OGRDataSourceToLabelImageFilter<TOutputImage>::PrintSelf(std::ostream& os, itk::Indent indent) const
232 {
233  Superclass::PrintSelf(os, indent);
234 }
235 
236 } // end namespace otb
237 
238 #endif
itk::SmartPointer< Self > Pointer
static GDALDriverManagerWrapper & GetInstance()
GDALDatasetWrapper::Pointer OpenFromMemory(void *mem_ptr, const uint64_t &width, const uint64_t &height, const GDALDataType pix_type, const uint32_t byte_per_pixel, const uint16_t nb_bands=1, const uint64_t &band_offset=1) const
const OGRDataSourceType * GetInput(unsigned int idx)
OutputImageType::InternalPixelType OutputImageInternalPixelType
virtual void AddOGRDataSource(const OGRDataSourceType *ds)
void SetOutputParametersFromImage(const ImagePointerType image)
virtual void SetOutputOrigin(OutputOriginType _arg)
virtual void SetOutputSpacing(const OutputSpacingType &spacing)
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Collection of geometric objects.
int GetLayersCount() const
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
void OTBMetadata_EXPORT WriteNoDataFlags(const std::vector< bool > &flags, const std::vector< double > &values, ImageMetadata &imd)
Helper class to convert a set of standard C++ string into char** as OGR API expects.
Definition: otbOGRHelpers.h:74