Skip to content

File Polygon.h

File List > src > Polygon.h

Go to the documentation of this file

// Copyright (c) 2012-2013, IGN France.
// Copyright (c) 2012-2022, Oslandia.
// SPDX-License-Identifier: LGPL-2.0-or-later

#ifndef _SFCGAL_POLYGON_H_
#define _SFCGAL_POLYGON_H_

#include <boost/assert.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/ptr_container/serialize_ptr_vector.hpp>
#include <boost/serialization/base_object.hpp>
#include <vector>

#include <CGAL/Polygon_with_holes_2.h>

#include "SFCGAL/Kernel.h"
#include "SFCGAL/LineString.h"
#include "SFCGAL/Surface.h"

namespace SFCGAL {

class SFCGAL_API Polygon : public Surface {
public:
  typedef boost::ptr_vector<LineString>::iterator       iterator;
  typedef boost::ptr_vector<LineString>::const_iterator const_iterator;

  Polygon();
  Polygon(const std::vector<LineString> &rings);
  Polygon(const LineString &exteriorRing);
  Polygon(LineString *exteriorRing);
  Polygon(const Triangle &triangle);
  Polygon(const Polygon &other);

  Polygon(const CGAL::Polygon_2<Kernel> &other);
  Polygon(const CGAL::Polygon_with_holes_2<Kernel> &other);

  Polygon &
  operator=(Polygon other);

  ~Polygon();

  //-- SFCGAL::Geometry
  virtual Polygon *
  clone() const;

  //-- SFCGAL::Geometry
  virtual std::string
  geometryType() const;
  //-- SFCGAL::Geometry
  virtual GeometryType
  geometryTypeId() const;
  //-- SFCGAL::Geometry
  virtual int
  coordinateDimension() const;
  //-- SFCGAL::Geometry
  virtual bool
  isEmpty() const;
  //-- SFCGAL::Geometry
  virtual bool
  is3D() const;
  //-- SFCGAL::Geometry
  virtual bool
  isMeasured() const;

  bool
  isCounterClockWiseOriented() const;

  void
  reverse();

  inline const LineString &
  exteriorRing() const
  {
    return _rings.front();
  }
  inline LineString &
  exteriorRing()
  {
    return _rings.front();
  }
  inline void
  setExteriorRing(const LineString &ring)
  {
    _rings.front() = ring;
  }
  inline void
  setExteriorRing(LineString *ring)
  {
    _rings.replace(0, ring);
  }

  inline bool
  hasInteriorRings() const
  {
    return _rings.size() > 1;
  }

  inline size_t
  numInteriorRings() const
  {
    return _rings.size() - 1;
  }
  inline const LineString &
  interiorRingN(const size_t &n) const
  {
    return _rings[n + 1];
  }
  inline LineString &
  interiorRingN(const size_t &n)
  {
    return _rings[n + 1];
  }

  inline size_t
  numRings() const
  {
    return _rings.size();
  }
  inline const LineString &
  ringN(const size_t &n) const
  {
    BOOST_ASSERT(n < _rings.size());
    return _rings[n];
  }
  inline LineString &
  ringN(const size_t &n)
  {
    BOOST_ASSERT(n < _rings.size());
    return _rings[n];
  }

  inline void
  addInteriorRing(const LineString &ls)
  {
    _rings.push_back(ls.clone());
  }
  inline void
  addInteriorRing(LineString *ls)
  {
    BOOST_ASSERT(ls != NULL);
    _rings.push_back(ls);
  }

  inline void
  addRing(const LineString &ls)
  {
    _rings.push_back(ls.clone());
  }
  inline void
  addRing(LineString *ls)
  {
    BOOST_ASSERT(ls != NULL);
    _rings.push_back(ls);
  }

  inline iterator
  begin()
  {
    return _rings.begin();
  }
  inline const_iterator
  begin() const
  {
    return _rings.begin();
  }

  inline iterator
  end()
  {
    return _rings.end();
  }
  inline const_iterator
  end() const
  {
    return _rings.end();
  }

  /*
   * @brief Convert to CGAL::Polygon_2. Does not consider holes, if any
   * @param forceCounterClocksize force exterior ring orientation to counter
   * clocksize
   */
  CGAL::Polygon_2<Kernel>
  toPolygon_2(bool fixOrientation = true) const;

  /*
   * @brief Convert to CGAL::Polygon_with_holes_2.
   * @param forceCounterClocksize force exterior ring orientation to counter
   * clocksize and interior ring to clocksize.
   */
  CGAL::Polygon_with_holes_2<Kernel>
  toPolygon_with_holes_2(bool fixOrientation = true) const;

  //-- visitors

  //-- SFCGAL::Geometry
  virtual void
  accept(GeometryVisitor &visitor);
  //-- SFCGAL::Geometry
  virtual void
  accept(ConstGeometryVisitor &visitor) const;

  template <class Archive>
  void
  serialize(Archive &ar, const unsigned int /*version*/)
  {
    ar &boost::serialization::base_object<Geometry>(*this);
    ar &_rings;
  }

private:
  boost::ptr_vector<LineString> _rings;

  void
  swap(Polygon &other)
  {
    std::swap(_rings, other._rings);
  }
};

} // namespace SFCGAL

#endif