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());
double GetLengthOGRGeometryCollection(OGRGeometryCollection *intersection)
const OGRLayerType & GetOGRLayer(void) const
void SetOGRLayer(const OGRLayerType &ogrLayer)
void ProcessStreamingLine(bool line, itk::ProgressReporter &progress)
virtual const InputImageType * GetInput(void)
InputImageType::PointType OriginType
TInputImage InputImageType
virtual void SetInput(const InputImageType *input)
void GenerateData() override
InputImageType::IndexType IndexType
OGRLayerStreamStitchingFilter()
InputImageType::SizeType SizeType
Geometric object with descriptive fields.
OGRGeometry const * GetGeometry() const
void SetGeometry(OGRGeometry const *geometry)
Encapsulation of OGRField Instances of Field are expected to be built from an existing Feature with w...
OGRFieldType GetType() const
Field type accessor.
Implementation class for Feature iterator. This iterator is a single pass iterator....
Layer of geometric objects.
OTBGdalAdapters_EXPORT bool Intersects(OGRGeometry const &lhs, OGRGeometry const &rhs)
Do these features intersect?
OTBGdalAdapters_EXPORT UniqueGeometryPtr Intersection(OGRGeometry const &lhs, OGRGeometry const &rhs)
Computes intersection.
boost::interprocess::unique_ptr< OGRGeometry, internal::GeometryDeleter > UniqueGeometryPtr
OTBGdalAdapters_EXPORT UniqueGeometryPtr Union(OGRGeometry const &lhs, OGRGeometry const &rhs)
Computes union.
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
#define otbWarningMacro(x)