/* * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES) * * This file is part of Orfeo Toolbox * * https://www.orfeo-toolbox.org/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef otbPolyLineParametricPathWithValue_hxx #define otbPolyLineParametricPathWithValue_hxx #include "otbPolyLineParametricPathWithValue.h" #include "itkNumericTraits.h" namespace otb { /** * Constructor */ template PolyLineParametricPathWithValue::PolyLineParametricPathWithValue() : m_Key("Value"), m_Length(-1.0), m_LengthIsValid(false), m_BoundingRegion(), m_BoundingRegionIsValid(false) { itk::MetaDataDictionary& dict = this->GetMetaDataDictionary(); ValueType v; itk::EncapsulateMetaData(dict, m_Key, itk::NumericTraits::ZeroValue(v)); } template void PolyLineParametricPathWithValue::AddVertex(const ContinuousIndexType& vertex) { Superclass::AddVertex(vertex); this->Modified(); } template double PolyLineParametricPathWithValue::GetLength() const { if (!m_LengthIsValid) { ComputeLength(); } return m_Length; } template void PolyLineParametricPathWithValue::ComputeLength() const { double length = 0.0; VertexListConstIteratorType it = this->GetVertexList()->Begin(); if (this->GetVertexList()->Size() > 1) { VertexType pt1 = it.Value(); // just init, won't be used like that VertexType pt2 = it.Value(); ++it; while (it != this->GetVertexList()->End()) { pt1 = pt2; pt2 = it.Value(); double accum = 0.0; for (unsigned int i = 0; i < VDimension; ++i) { accum += (pt1[i] - pt2[i]) * (pt1[i] - pt2[i]); } length += std::sqrt(accum); ++it; } } else // if there is strictly less than 2 points, length is 0 { length = 0.0; } m_Length = length; m_LengthIsValid = true; } /** * PrintSelf Method */ template void PolyLineParametricPathWithValue::PrintSelf(std::ostream& os, itk::Indent indent) const { Superclass::PrintSelf(os, indent); VertexListConstIteratorType it = this->GetVertexList()->Begin(); while (it != this->GetVertexList()->End()) { os << it.Value() << " - "; ++it; } os << std::endl; } template typename PolyLineParametricPathWithValue::RegionType PolyLineParametricPathWithValue::GetBoundingRegion() const { if (!m_BoundingRegionIsValid) { ComputeBoundingRegion(); } return m_BoundingRegion; } /** * Bounding Box computation */ template void PolyLineParametricPathWithValue::ComputeBoundingRegion() const { SizeType size; IndexType index; size.Fill(0); index.Fill(0); IndexType maxId; maxId.Fill(0); VertexListConstIteratorType it = this->GetVertexList()->Begin(); double x = 0.0; double y = 0.0; if (this->GetVertexList()->Size() > 0) { x = static_cast(it.Value()[0]); y = static_cast(it.Value()[1]); index[0] = x; index[1] = y; maxId[0] = x; maxId[1] = y; ++it; while (it != this->GetVertexList()->End()) { x = static_cast(it.Value()[0]); y = static_cast(it.Value()[1]); // Index search if (x < index[0]) { index[0] = x; } if (y < index[1]) { index[1] = y; } // Max Id search for size computation if (x > maxId[0]) { maxId[0] = x; } if (y > maxId[1]) { maxId[1] = y; } ++it; } size[0] = maxId[0] - index[0]; size[1] = maxId[1] - index[1]; } m_BoundingRegion.SetSize(size); m_BoundingRegion.SetOrigin(index); m_BoundingRegionIsValid = true; } template void PolyLineParametricPathWithValue::Modified() const { m_LengthIsValid = false; m_BoundingRegionIsValid = false; } } // end namespace otb #endif