1 /** 2 * SFCGAL 3 * 4 * Copyright (C) 2012-2013 Oslandia <infos@oslandia.com> 5 * Copyright (C) 2012-2013 IGN (http://www.ign.fr) 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Library General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Library General Public License for more details. 16 17 * You should have received a copy of the GNU Library General Public 18 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #ifndef _SFCGAL_POLYGON_H_ 22 #define _SFCGAL_POLYGON_H_ 23 24 #include <vector> 25 #include <boost/assert.hpp> 26 #include <boost/ptr_container/ptr_vector.hpp> 27 #include <boost/serialization/base_object.hpp> 28 #include <boost/ptr_container/serialize_ptr_vector.hpp> 29 30 #include <CGAL/Polygon_with_holes_2.h> 31 32 #include <SFCGAL/LineString.h> 33 #include <SFCGAL/Surface.h> 34 #include <SFCGAL/Kernel.h> 35 36 namespace SFCGAL { 37 38 /** 39 * A Polygon in SFA with holes 40 * @ingroup public_api 41 */ 42 class SFCGAL_API Polygon : public Surface { 43 public: 44 typedef boost::ptr_vector< LineString >::iterator iterator ; 45 typedef boost::ptr_vector< LineString >::const_iterator const_iterator ; 46 47 /** 48 * Empty Polygon constructor 49 */ 50 Polygon() ; 51 /** 52 * Constructor with an exterior ring 53 */ 54 Polygon( const std::vector< LineString >& rings ) ; 55 /** 56 * Constructor with an exterior ring 57 */ 58 Polygon( const LineString& exteriorRing ) ; 59 /** 60 * Constructor with an exterior ring (takes ownership) 61 */ 62 Polygon( LineString* exteriorRing ) ; 63 /** 64 * Constructor with a Triangle 65 */ 66 Polygon( const Triangle& triangle ) ; 67 /** 68 * Copy constructor 69 */ 70 Polygon( const Polygon& other ) ; 71 72 /** 73 * Constructor from CGAL::Polygon_with_holes_2<K> 74 */ 75 Polygon( const CGAL::Polygon_2< Kernel >& other ); 76 /** 77 * Constructor from CGAL::Polygon_with_holes_2<K> 78 */ 79 Polygon( const CGAL::Polygon_with_holes_2< Kernel >& other ); 80 81 /** 82 * assign operator 83 */ 84 Polygon& operator = ( Polygon other ) ; 85 86 /** 87 * destructor 88 */ 89 ~Polygon() ; 90 91 //-- SFCGAL::Geometry 92 virtual Polygon* clone() const ; 93 94 //-- SFCGAL::Geometry 95 virtual std::string geometryType() const ; 96 //-- SFCGAL::Geometry 97 virtual GeometryType geometryTypeId() const ; 98 //-- SFCGAL::Geometry 99 virtual int coordinateDimension() const ; 100 //-- SFCGAL::Geometry 101 virtual bool isEmpty() const ; 102 //-- SFCGAL::Geometry 103 virtual bool is3D() const ; 104 //-- SFCGAL::Geometry 105 virtual bool isMeasured() const ; 106 107 /** 108 * Check whether the 2D polygon is pointing up 109 */ 110 bool isCounterClockWiseOriented() const; 111 112 /** 113 * reverse Polygon orientation 114 */ 115 void reverse() ; 116 117 118 /** 119 * [OGC/SFA]returns the exterior ring 120 */ exteriorRing()121 inline const LineString& exteriorRing() const { 122 return _rings.front(); 123 } 124 /** 125 * [OGC/SFA]returns the exterior ring 126 */ exteriorRing()127 inline LineString& exteriorRing() { 128 return _rings.front(); 129 } 130 /** 131 * Sets the exterior ring 132 */ setExteriorRing(const LineString & ring)133 inline void setExteriorRing( const LineString& ring ) { 134 _rings.front() = ring ; 135 } 136 /** 137 * Sets the exterior ring (takes ownership) 138 */ setExteriorRing(LineString * ring)139 inline void setExteriorRing( LineString* ring ) { 140 _rings.replace( 0, ring ); 141 } 142 143 /** 144 * Test if the polygon has interior rings 145 */ hasInteriorRings()146 inline bool hasInteriorRings() const { 147 return _rings.size() > 1 ; 148 } 149 150 /** 151 * [OGC/SFA]returns the exterior ring 152 */ numInteriorRings()153 inline size_t numInteriorRings() const { 154 return _rings.size() - 1 ; 155 } 156 /** 157 * [OGC/SFA]returns the exterior ring 158 */ interiorRingN(const size_t & n)159 inline const LineString& interiorRingN( const size_t& n ) const { 160 return _rings[n+1]; 161 } 162 /** 163 * [OGC/SFA]returns the exterior ring 164 */ interiorRingN(const size_t & n)165 inline LineString& interiorRingN( const size_t& n ) { 166 return _rings[n+1]; 167 } 168 169 /** 170 * Returns the number of rings 171 */ numRings()172 inline size_t numRings() const { 173 return _rings.size() ; 174 } 175 /** 176 * Returns the n-th ring, 0 is exteriorRing 177 * @warning not standard, avoid conditionnal to access rings 178 */ ringN(const size_t & n)179 inline const LineString& ringN( const size_t& n ) const { 180 BOOST_ASSERT( n < _rings.size() ); 181 return _rings[n]; 182 } 183 /** 184 * Returns the n-th ring, 0 is exteriorRing 185 * @warning not standard, avoid conditionnal to access rings 186 */ ringN(const size_t & n)187 inline LineString& ringN( const size_t& n ) { 188 BOOST_ASSERT( n < _rings.size() ); 189 return _rings[n]; 190 } 191 192 /** 193 * append a ring to the Polygon 194 */ addInteriorRing(const LineString & ls)195 inline void addInteriorRing( const LineString& ls ) { 196 _rings.push_back( ls.clone() ) ; 197 } 198 /** 199 * append a ring to the Polygon (take ownership) 200 */ addInteriorRing(LineString * ls)201 inline void addInteriorRing( LineString* ls ) { 202 BOOST_ASSERT( ls != NULL ); 203 _rings.push_back( ls ) ; 204 } 205 206 /** 207 * append a ring to the Polygon 208 * @deprecated addInteriorRing 209 */ addRing(const LineString & ls)210 inline void addRing( const LineString& ls ) { 211 _rings.push_back( ls.clone() ) ; 212 } 213 /** 214 * append a ring to the Polygon (take ownership) 215 * @deprecated addInteriorRing 216 */ addRing(LineString * ls)217 inline void addRing( LineString* ls ) { 218 BOOST_ASSERT( ls != NULL ); 219 _rings.push_back( ls ) ; 220 } 221 begin()222 inline iterator begin() { 223 return _rings.begin() ; 224 } begin()225 inline const_iterator begin() const { 226 return _rings.begin() ; 227 } 228 end()229 inline iterator end() { 230 return _rings.end() ; 231 } end()232 inline const_iterator end() const { 233 return _rings.end() ; 234 } 235 236 237 /* 238 * @brief Convert to CGAL::Polygon_2. Does not consider holes, if any 239 * @param forceCounterClocksize force exterior ring orientation to counter clocksize 240 */ 241 CGAL::Polygon_2<Kernel> toPolygon_2( bool fixOrientation = true ) const; 242 243 /* 244 * @brief Convert to CGAL::Polygon_with_holes_2. 245 * @param forceCounterClocksize force exterior ring orientation to counter clocksize and 246 * interior ring to clocksize. 247 */ 248 CGAL::Polygon_with_holes_2<Kernel> toPolygon_with_holes_2( bool fixOrientation = true ) const; 249 250 //-- visitors 251 252 //-- SFCGAL::Geometry 253 virtual void accept( GeometryVisitor& visitor ) ; 254 //-- SFCGAL::Geometry 255 virtual void accept( ConstGeometryVisitor& visitor ) const ; 256 257 /** 258 * Serializer 259 */ 260 template <class Archive> serialize(Archive & ar,const unsigned int)261 void serialize( Archive& ar, const unsigned int /*version*/ ) { 262 ar& boost::serialization::base_object<Geometry>( *this ); 263 ar& _rings; 264 } 265 private: 266 /** 267 * rings forming the polygon (size() >= 1) 268 * 269 * _ring[0] is the interior ring 270 * 271 * @warning never empty, empty LineString as exteriorRing for empty Polygon 272 */ 273 boost::ptr_vector< LineString > _rings ; 274 swap(Polygon & other)275 void swap( Polygon& other ) { 276 std::swap( _rings, other._rings ); 277 } 278 }; 279 280 281 } 282 283 #endif 284