21 #ifndef otbOGRLayerStreamStitchingFilter_hxx
22 #define otbOGRLayerStreamStitchingFilter_hxx
25 #include "itkContinuousIndex.h"
28 #include "ogrsf_frmts.h"
34 template <
class TImage>
40 template <
class TInputImage>
43 this->Superclass::SetNthInput(0,
const_cast<InputImageType*
>(input));
46 template <
class TInputImage>
49 if (this->GetNumberOfInputs() < 1)
54 return static_cast<const InputImageType*
>(this->Superclass::GetInput(0));
57 template <
class TInputImage>
60 m_OGRLayer = ogrLayer;
64 template <
class TInputImage>
70 template <
class TInputImage>
73 double dfLength = 0.0;
74 for (
int iGeom = 0; iGeom < intersection->getNumGeometries(); iGeom++)
76 OGRGeometry* geom = intersection->getGeometryRef(iGeom);
77 switch (wkbFlatten(geom->getGeometryType()))
81 dfLength += ((OGRCurve*)geom)->get_Length();
83 case wkbGeometryCollection:
84 dfLength += GetLengthOGRGeometryCollection(
dynamic_cast<OGRGeometryCollection*
>(geom));
92 template <
class TInputImage>
95 typename InputImageType::ConstPointer inputImage = this->GetInput();
98 SizeType imageSize = this->GetInput()->GetLargestPossibleRegion().GetSize();
99 unsigned int nbRowStream =
static_cast<unsigned int>(imageSize[1] / m_StreamSize[1] + 1);
100 unsigned int nbColStream =
static_cast<unsigned int>(imageSize[0] / m_StreamSize[0] + 1);
116 for (
unsigned int x = 1; x <= nbColStream; x++)
118 OGRErr errStart = m_OGRLayer.ogr().StartTransaction();
120 if (errStart != OGRERR_NONE)
122 itkExceptionMacro(<<
"Unable to start transaction for OGR layer " << m_OGRLayer.ogr().GetName() <<
".");
125 for (
unsigned int y = 1; y <= nbRowStream; y++)
129 OGRLineString streamLine;
130 itk::ContinuousIndex<double, 2> startIndex;
131 itk::ContinuousIndex<double, 2> endIndex;
135 startIndex[0] =
static_cast<double>(m_StreamSize[0] * x) - 0.5;
136 startIndex[1] =
static_cast<double>(m_StreamSize[1] * (y - 1)) - 0.5;
137 endIndex = startIndex;
138 endIndex[1] +=
static_cast<double>(m_StreamSize[1]);
142 startIndex[0] =
static_cast<double>(m_StreamSize[0] * (x - 1)) - 0.5;
143 startIndex[1] =
static_cast<double>(m_StreamSize[1] * y) - 0.5;
144 endIndex = startIndex;
145 endIndex[0] +=
static_cast<double>(m_StreamSize[0]);
148 inputImage->TransformContinuousIndexToPhysicalPoint(startIndex, startPoint);
150 inputImage->TransformContinuousIndexToPhysicalPoint(endIndex, endPoint);
151 streamLine.addPoint(startPoint[0], startPoint[1]);
152 streamLine.addPoint(endPoint[0], endPoint[1]);
156 std::vector<FeatureStruct> upperStreamFeatureList;
157 upperStreamFeatureList.clear();
165 UpperLeftCorner[0] = x * m_StreamSize[0] - 1 - m_Radius;
166 UpperLeftCorner[1] = m_StreamSize[1] * (y - 1);
168 LowerRightCorner[0] = m_StreamSize[0] * x - 1;
169 LowerRightCorner[1] = m_StreamSize[1] * y - 1;
174 UpperLeftCorner[0] = (x - 1) * m_StreamSize[0];
175 UpperLeftCorner[1] = m_StreamSize[1] * y - 1 - m_Radius;
177 LowerRightCorner[0] = m_StreamSize[0] * x - 1;
178 LowerRightCorner[1] = m_StreamSize[1] * y - 1;
182 inputImage->TransformIndexToPhysicalPoint(UpperLeftCorner, ulCorner);
184 inputImage->TransformIndexToPhysicalPoint(LowerRightCorner, lrCorner);
186 m_OGRLayer.SetSpatialFilterRect(ulCorner[0], lrCorner[1], lrCorner[0], ulCorner[1]);
188 std::set<unsigned int> upperFIDs;
190 for (; featIt != m_OGRLayer.end(); ++featIt)
195 upperStreamFeatureList.push_back(s);
196 upperFIDs.insert((*featIt).GetFID());
200 std::vector<FeatureStruct> lowerStreamFeatureList;
201 lowerStreamFeatureList.clear();
206 UpperLeftCorner[0] = x * m_StreamSize[0];
207 UpperLeftCorner[1] = m_StreamSize[1] * (y - 1);
209 LowerRightCorner[0] = m_StreamSize[0] * x + m_Radius;
210 LowerRightCorner[1] = m_StreamSize[1] * y - 1;
215 UpperLeftCorner[0] = (x - 1) * m_StreamSize[0];
216 UpperLeftCorner[1] = m_StreamSize[1] * y;
218 LowerRightCorner[0] = m_StreamSize[0] * x - 1;
219 LowerRightCorner[1] = m_StreamSize[1] * y + m_Radius;
222 inputImage->TransformIndexToPhysicalPoint(UpperLeftCorner, ulCorner);
223 inputImage->TransformIndexToPhysicalPoint(LowerRightCorner, lrCorner);
225 m_OGRLayer.SetSpatialFilterRect(ulCorner[0], lrCorner[1], lrCorner[0], ulCorner[1]);
227 for (featIt = m_OGRLayer.begin(); featIt != m_OGRLayer.end(); ++featIt)
229 if (upperFIDs.find((*featIt).GetFID()) == upperFIDs.end())
234 lowerStreamFeatureList.push_back(s);
238 unsigned int nbUpperPolygons = upperStreamFeatureList.size();
239 unsigned int nbLowerPolygons = lowerStreamFeatureList.size();
240 std::vector<FusionStruct> fusionList;
242 for (
unsigned int u = 0; u < nbUpperPolygons; u++)
244 for (
unsigned int l = 0; l < nbLowerPolygons; l++)
262 if (intersection->getGeometryType() == wkbPolygon)
264 fusion.
overlap =
dynamic_cast<OGRPolygon*
>(intersection.get())->get_Area();
266 else if (intersection->getGeometryType() == wkbMultiPolygon)
268 fusion.
overlap =
dynamic_cast<OGRMultiPolygon*
>(intersection.get())->get_Area();
270 else if (intersection->getGeometryType() == wkbGeometryCollection)
272 fusion.
overlap =
dynamic_cast<OGRGeometryCollection*
>(intersection.get())->get_Area();
274 else if (intersection->getGeometryType() == wkbLineString)
276 fusion.
overlap =
dynamic_cast<OGRLineString*
>(intersection.get())->get_Length();
278 else if (intersection->getGeometryType() == wkbMultiLineString)
280 fusion.
overlap =
dynamic_cast<OGRMultiLineString*
>(intersection.get())->get_Length();
287 fusionList.push_back(fusion);
293 unsigned int fusionListSize = fusionList.size();
294 std::sort(fusionList.begin(), fusionList.end(), SortFeature);
295 for (
unsigned int i = 0; i < fusionListSize; i++)
297 FeatureStruct upper = upperStreamFeatureList.at(fusionList.at(i).indStream1);
298 FeatureStruct lower = lowerStreamFeatureList.at(fusionList.at(i).indStream2);
301 upperStreamFeatureList[fusionList[i].indStream1].fusioned =
true;
302 lowerStreamFeatureList[fusionList[i].indStream2].fusioned =
true;
315 fusionFeature[0].SetValue(field.
GetValue<GIntBig>());
320 fusionFeature[0].SetValue(field.
GetValue<
int>());
323 m_OGRLayer.CreateFeature(fusionFeature);
324 m_OGRLayer.DeleteFeature(lower.
feat.
GetFID());
325 m_OGRLayer.DeleteFeature(upper.
feat.
GetFID());
327 catch (itk::ExceptionObject& err)
335 progress.CompletedPixel();
339 if (m_OGRLayer.ogr().TestCapability(
"Transactions"))
342 OGRErr errCommitX = m_OGRLayer.ogr().CommitTransaction();
343 if (errCommitX != OGRERR_NONE)
345 itkExceptionMacro(<<
"Unable to commit transaction for OGR layer " << m_OGRLayer.ogr().GetName() <<
".");
350 template <
class TImage>
355 itkExceptionMacro(<<
"Input OGR layer is null!");
358 this->InvokeEvent(itk::StartEvent());
360 typename InputImageType::ConstPointer inputImage = this->GetInput();
363 SizeType imageSize = this->GetInput()->GetLargestPossibleRegion().GetSize();
364 unsigned int nbRowStream =
static_cast<unsigned int>(imageSize[1] / m_StreamSize[1] + 1);
365 unsigned int nbColStream =
static_cast<unsigned int>(imageSize[0] / m_StreamSize[0] + 1);
367 itk::ProgressReporter progress(
this, 0, 2 * nbRowStream * nbColStream, 100, 0);
369 this->ProcessStreamingLine(
false, progress);
371 this->ProcessStreamingLine(
true, progress);
373 this->InvokeEvent(itk::EndEvent());