OTB  7.1.0
Orfeo Toolbox
otbImageRegionTileMapSplitter.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 otbImageRegionTileMapSplitter_hxx
22 #define otbImageRegionTileMapSplitter_hxx
23 
25 #include "otbMath.h"
26 #include "otbMacro.h"
27 
28 namespace otb
29 {
30 
34 template <unsigned int VImageDimension>
35 unsigned int ImageRegionTileMapSplitter<VImageDimension>::GetNumberOfSplits(const RegionType& region, unsigned int requestedNumber)
36 {
37  const SizeType& regionSize = region.GetSize();
38  const IndexType& regionIndex = region.GetIndex();
40 
41  // requested number of splits per dimension
42  unsigned int numPieces = 1;
43 
44  // determine the actual number of pieces that will be generated
45  for (unsigned int j = VImageDimension; j > 0; --j)
46  {
47  // otbMsgDevMacro(<< "*** Dimension: " << j-1);
48  unsigned long int remainingToDo = static_cast<unsigned long int>(std::ceil(static_cast<double>(requestedNumber) / numPieces));
49  unsigned int maxPieces = (regionIndex[j - 1] + regionSize[j - 1] - 1) / m_AlignStep - regionIndex[j - 1] / m_AlignStep + 1;
50  unsigned int stepPerPiece = 1;
51  if (remainingToDo < maxPieces)
52  {
53  stepPerPiece = static_cast<unsigned int>(std::floor(static_cast<double>(maxPieces) / remainingToDo));
54  if ((remainingToDo - 1) * (stepPerPiece + 1) < maxPieces)
55  {
56  stepPerPiece += 1;
57  }
58  }
59  unsigned int maxPieceUsed = static_cast<unsigned int>(std::ceil(static_cast<double>(maxPieces) / stepPerPiece));
60  m_SplitsPerDimension[j - 1] = maxPieceUsed;
61  // otbMsgDevMacro("*** maxPieces stepPerPiece maxPieceUsed " << maxPieces
62  // << " " << stepPerPiece << " " << maxPieceUsed);
63  numPieces *= maxPieceUsed;
64  }
65  // otbMsgDevMacro("*** numPieces " << numPieces);
66  return numPieces;
67 }
68 
72 template <unsigned int VImageDimension>
73 itk::ImageRegion<VImageDimension> ImageRegionTileMapSplitter<VImageDimension>::GetSplit(unsigned int i, unsigned int numberOfPieces, const RegionType& region)
74 {
75  RegionType splitRegion;
76  IndexType splitIndex, regionIndex;
77  SizeType splitSize, regionSize;
78 
79  // Initialize the splitRegion to the requested region
80  splitRegion = region;
81  splitIndex = splitRegion.GetIndex();
82  splitSize = splitRegion.GetSize();
83 
84  regionSize = region.GetSize();
85  regionIndex = region.GetIndex();
86 
87  unsigned int numPieces = GetNumberOfSplits(region, numberOfPieces);
88  if (i > numPieces)
89  {
90  itkDebugMacro(" Cannot Split");
91  return splitRegion;
92  }
93 
94  unsigned int stackSize = 1;
95  for (unsigned int j = 0; j < VImageDimension; ++j)
96  {
97  unsigned int slicePos = (i % (stackSize * m_SplitsPerDimension[j])) / stackSize;
98  stackSize *= m_SplitsPerDimension[j];
99 
100  unsigned int generalSplitSize =
101  static_cast<unsigned int>(std::ceil(static_cast<double>(regionSize[j]) / (m_SplitsPerDimension[j] * m_AlignStep))) * m_AlignStep;
102  if (slicePos == 0)
103  {
104  splitIndex[j] = regionIndex[j];
105  }
106  else
107  {
108  splitIndex[j] = (regionIndex[j] / generalSplitSize + slicePos) * generalSplitSize;
109  }
110  if (slicePos == 0)
111  {
112  splitSize[j] = generalSplitSize - (regionIndex[j] % generalSplitSize);
113  }
114  else if (slicePos == m_SplitsPerDimension[j] - 1)
115  {
116  splitSize[j] = regionSize[j] - (generalSplitSize - (regionIndex[j] % generalSplitSize)) - (m_SplitsPerDimension[j] - 2) * generalSplitSize;
117  }
118  else
119  {
120  splitSize[j] = generalSplitSize;
121  }
122  }
123 
124  // set the split region ivars
125  splitRegion.SetIndex(splitIndex);
126  splitRegion.SetSize(splitSize);
127 
128  return splitRegion;
129 }
130 
134 template <unsigned int VImageDimension>
135 void ImageRegionTileMapSplitter<VImageDimension>::PrintSelf(std::ostream& os, itk::Indent indent) const
136 {
137  Superclass::PrintSelf(os, indent);
138 }
139 
140 } // end namespace itk
141 
142 #endif
RegionType GetSplit(unsigned int i, unsigned int numberOfPieces, const RegionType &region) override
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
itk::ImageRegion< VImageDimension > RegionType
void PrintSelf(std::ostream &os, itk::Indent indent) const override
unsigned int GetNumberOfSplits(const RegionType &region, unsigned int requestedNumber) override