text: /*
   * Copyright (C) 2005-2020 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 otbOGRGeometryWrapper_h
  #define otbOGRGeometryWrapper_h
  
  #if defined(__GNUC__) || defined(__clang__)
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wshadow"
  #include <boost/interprocess/smart_ptr/unique_ptr.hpp>
  #pragma GCC diagnostic pop
  #else
  #include <boost/interprocess/smart_ptr/unique_ptr.hpp>
  #endif
  
  #include "OTBGdalAdaptersExport.h"
  
  class OGRGeometry;
  
  namespace otb
  {
  namespace ogr
  {
  namespace internal
  {
  /**\ingroup GeometryInternals
   * Deleter dedicated to \c OGRGeometry.
   * \internal
   * Unlike OGR, works as a no-op on null geometries.
   *
   * Unlike the other deleters used, the type of this one needs to be known in the
   * header file in order to define the type \c UniqueGeometryPtr. As a
   * consequence, it is not in an anonymous namespace , but in \c
   * otb::ogr::internal.
   */
  struct OTBGdalAdapters_EXPORT GeometryDeleter
  {
    void operator()(OGRGeometry* p);
  };
  } // internal namespace
  
  
  // we don't encapsulate OGRGeometry, but please, don't create new geometries with a new.
  
  /**\ingroup gGeometry
   * \defgroup OGRGeometryWrapper OGRGeometry Wrappers
   * %Helper definition to handle \c OGRGeometry objects.
   *
   * \note %OTB doesn't provide anything on top of \c OGRGeometryFactory to create
   * new factories. Please, never create new \c OGRGeometry by hand with
   * <tt>new</tt> operator as there is no garanty they'll get destroyed within the
   * proper memory context when released from an owning \c OGRFeature.
   *
   * Thus, always use \c OGRGeometryFactory functions to create new geometries.
   * You can then manage their lifetime manually or rely on \c UniqueGeometryPtr
   * that provides a non-copyable, but movable RAII wrapper around \c OGRGeometry.
   * \since OTB v 3.14.0
   * @{
   */
  
  /**
   * Smart-pointer over \c OGRGeometry, with \em move-semantics.
   * In a few words:
   * - When a function receives a \em unique_ptr<>, it implicitly assumes
   * responsibility of the received pointer.
   * - When a function returns a \em unique_ptr<>, the client code implicitly
   * assumes responsibility of the returned pointer.
   * - When exiting a scope, the pointer is destroyed. Which means, as long as we
   * keep using \em unique_ptr<> around functions calls, there is no need to
   * burden our mind with the lifetime of the encapsulated pointers.
   * - Moreover, we can specify how pointers are deleted; property that we
   * exploit to use the ad'hoc destruction function from OGR API, see \c
   * GeometryDeleter.
   *
   * \see http://www2.research.att.com/~bs/C++0xFAQ.html#rval about \em move-semantics.
   * \see http://www2.research.att.com/~bs/C++0xFAQ.html#std-unique_ptr about \c
   * std::unique_ptr<>
   * \see GOTW \#103, \#104 about \c unique_ptr<> as well: http://herbsutter.com/gotw/_103/
   *
   * \note You may experiment difficulties to copy \c UniqueGeometryPtr. This is
   * likelly to be normal. You'll have to emulate \c std::move() with \c
   * boost::move() (with Boost v1.48+, or with \c boost::interprocess::move()
   * otherwise). Check for instance \c Feature::StealGeometry(), or \c
   * Feature::SetGeometryDirectly() to see examples.
   *
   * \internal
   * This should be defined on top of C++11 \c std::unique_ptr<>. By the mean
   * time, we are using an emulation provided in boost.interprocess.
   * \todo When CMake provides a way to detect C++11 features, use a \c #ifdef to
   * use the correct type.
   */
  typedef boost::interprocess::unique_ptr<OGRGeometry, internal::GeometryDeleter> UniqueGeometryPtr;
  /// Do these features intersect?
  OTBGdalAdapters_EXPORT bool Intersects(OGRGeometry const& lhs, OGRGeometry const& rhs);
  /// Returns wheither if two geometries are equivalent.
  OTBGdalAdapters_EXPORT bool Equals(OGRGeometry const& lhs, OGRGeometry const& rhs);
  /// Tests for disjointness.
  OTBGdalAdapters_EXPORT bool Disjoint(OGRGeometry const& lhs, OGRGeometry const& rhs);
  /// Tests for touching.
  OTBGdalAdapters_EXPORT bool Touches(OGRGeometry const& lhs, OGRGeometry const& rhs);
  /// Tests for crossing.
  OTBGdalAdapters_EXPORT bool Crosses(OGRGeometry const& lhs, OGRGeometry const& rhs);
  /// Tests for containment.
  OTBGdalAdapters_EXPORT bool Within(OGRGeometry const& lhs, OGRGeometry const& rhs);
  /// Tests for containment.
  OTBGdalAdapters_EXPORT bool Contains(OGRGeometry const& lhs, OGRGeometry const& rhs);
  /// Tests for overlap.
  OTBGdalAdapters_EXPORT bool Overlaps(OGRGeometry const& lhs, OGRGeometry const& rhs);
  /// Computes distance between two geometries.
  OTBGdalAdapters_EXPORT double Distance(OGRGeometry const& lhs, OGRGeometry const& rhs);
  
  /// Computes intersection.
  OTBGdalAdapters_EXPORT UniqueGeometryPtr Intersection(OGRGeometry const& lhs, OGRGeometry const& rhs);
  /// Computes union.
  OTBGdalAdapters_EXPORT UniqueGeometryPtr Union(OGRGeometry const& lhs, OGRGeometry const& rhs);
  /// Computes union using cascading.
  OTBGdalAdapters_EXPORT UniqueGeometryPtr UnionCascaded(OGRGeometry const& this_);
  /// Computes difference.
  OTBGdalAdapters_EXPORT UniqueGeometryPtr Difference(OGRGeometry const& lhs, OGRGeometry const& rhs);
  /// Computes symmetric difference.
  OTBGdalAdapters_EXPORT UniqueGeometryPtr SymDifference(OGRGeometry const& lhs, OGRGeometry const& rhs); // -1.8
  
  /** Simplifies Geometry.
   * This function tries to uses the best simplication algorithm available in the
   * current version of GDAL. <em>Best</em> in the sense of topology preservation.
   * i.e. With GDAL v1.8.0, \c OGRGeometry::Simplify() is used; with GDAL v1.9.0+,
   * \c OGRGeometry::SimplifyPreserveTopology() is used.
   * \pre Requires GDAL 1.8.0
   * \sa \c OGRGeometry::Simplify()
   * \sa \c OGRGeometry::SimplifyPreserveTopology()
   */
  OTBGdalAdapters_EXPORT UniqueGeometryPtr Simplify(OGRGeometry const& g, double tolerance);
  
  /** Simplifies Geometry with no guarantee of preserving the geometry.
   * \pre Requires GDAL 1.8.0
   * \sa \c OGRGeometry::Simplify()
   */
  OTBGdalAdapters_EXPORT UniqueGeometryPtr SimplifyDontPreserveTopology(OGRGeometry const& g, double tolerance);
  
  /** Simplifies Geometry while preserving topology.
   * \pre Requires GDAL 1.9.0
   * \sa \c OGRGeometry::SimplifyPreserveTopology()
   */
  OTBGdalAdapters_EXPORT UniqueGeometryPtr SimplifyPreserveTopology(OGRGeometry const& g, double tolerance);
  
  /** @} */
  }
  } // end namespace otb::ogr
  
  #ifndef OTB_MANUAL_INSTANTIATION
  // #include "otbOGRGeometryWrapper.hxx"
  #endif
  
  #endif // otbOGRGeometryWrapper_h
  