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_GEOMETRY_H_
22 #define _SFCGAL_GEOMETRY_H_
23 
24 #include <SFCGAL/config.h>
25 
26 #include <boost/shared_ptr.hpp>
27 
28 #include <memory>
29 #include <string>
30 #include <sstream>
31 
32 #include <boost/assert.hpp>
33 
34 namespace CGAL {
35 class Object;
36 }
37 
38 namespace SFCGAL {
39 class Geometry ;
40 class Point ;
41 class LineString ;
42 class Polygon ;
43 class GeometryCollection ;
44 class MultiPoint ;
45 class MultiLineString ;
46 class MultiPolygon ;
47 
48 class Triangle ;
49 class TriangulatedSurface ;
50 class PolyhedralSurface ;
51 
52 //not SFA, appears in GML/CityGML
53 class Solid ;
54 //not SFA, appears in GML/CityGML
55 class MultiSolid ;
56 
57 class Envelope ;
58 
59 class GeometryVisitor ;
60 class ConstGeometryVisitor ;
61 }
62 
63 namespace SFCGAL {
64 
65 /**
66  * [OGC/SFA]8.2.3 "A common list of codes for geometric types"
67  *
68  * @todo solid and triangles as non OGC/SFA geometric types?
69  * @warning codes for abstract classes and unimplemented classes are hidden
70  * @warning code values have are important for WKB
71  *
72  * @ingroup public_api
73  */
74 enum GeometryType {
75 //      TYPE_GEOMETRY            = 0, //abstract
76     TYPE_POINT               = 1,
77     TYPE_LINESTRING          = 2,
78     TYPE_POLYGON             = 3,
79     TYPE_MULTIPOINT          = 4,
80     TYPE_MULTILINESTRING     = 5,
81     TYPE_MULTIPOLYGON        = 6,
82     TYPE_GEOMETRYCOLLECTION  = 7,
83 //     TYPE_CIRCULARSTRING      = 8, // not yet supported
84 //     TYPE_COMPOUNDCURVE       = 9, // not yet supported
85 //     TYPE_CURVEPOLYGON        = 10, // not yet supported
86 //     TYPE_MULTICURVE          = 11, //abstract
87 //     TYPE_MULTISURFACE        = 12, //abstract
88 //     TYPE_CURVE               = 13, //abstract
89 //     TYPE_SURFACE             = 14, //abstract
90     TYPE_POLYHEDRALSURFACE   = 15,
91     TYPE_TRIANGULATEDSURFACE = 16,
92 
93     //-- not official codes
94     TYPE_TRIANGLE            = 100, //17 in Wikipedia???
95     TYPE_SOLID               = 101,
96     TYPE_MULTISOLID          = 102
97 };
98 
99 
100 /**
101  * @brief coordinate types (XY, XYZ, XYM, etc.)
102  * @see SFA 2.8.3 LineStringZ = 1003 ( coordinateType + geometryType)
103  * @ingroup public_api
104  */
105 typedef enum {
106     COORDINATE_XY   = 0 ,
107     COORDINATE_XYZ  = 1000,
108     COORDINATE_XYM  = 2000,
109     COORDINATE_XYZM = 3000
110 } CoordinateType ;
111 
112 /**
113  * @brief OGC/SFA based Geometry abstract class
114  *
115  * @ingroup public_api
116  */
117 class SFCGAL_API Geometry {
118 public:
119 
120     /**
121      * @brief Default constructor.
122      */
123     Geometry();
124 
125     /**
126      * @brief Copy constructor.
127      */
128     Geometry( const Geometry& ) = default;
129 
130     /**
131      * @brief Copy assignemnt operator.
132      */
133     Geometry& operator=( const Geometry& other ) = default;
134 
135     /**
136      * @brief Destructor.
137      */
138     virtual ~Geometry() = default;
139 
140     /**
141      * @brief Get a deep copy of the geometry
142      */
143     virtual Geometry*   clone() const = 0 ;
144 
145     /**
146      * @brief [OGC/SFA]returns the geometry type
147      * @warning use CamelCase (LineString, not LINESTRING)
148      */
149     virtual std::string  geometryType() const = 0 ;
150     /**
151      * @brief Returns a code corresponding to the type
152      * @warning not standard
153      */
154     virtual GeometryType geometryTypeId() const = 0 ;
155 
156     /**
157      * [OGC/SFA]Dimension of the Geometry ( 0 : punctual, 1 : curve, ...)
158      * @warning empty geometries provide the dimension corresponding to the object
159      */
160     virtual int          dimension() const = 0 ;
161     /**
162      * [OGC/SFA]returns the dimension of the coordinates
163      * @pre suppose no mix of 2D/3D coordinates
164      */
165     virtual int          coordinateDimension() const = 0 ;
166     /**
167      * [OGC/SFA]test if geometry is empty
168      */
169     virtual bool         isEmpty() const = 0 ;
170 
171     /**
172      * [OGC/SFA]test if geometry is 3d
173      * @pre suppose no mix of 2D/3D coordinates
174      */
175     virtual bool         is3D() const = 0 ;
176     /**
177      * [OGC/SFA]test if geometry is measured (has an m)
178      * @pre suppose no mix of M/!M points
179      */
180     virtual bool         isMeasured() const = 0 ;
181 
182     //virtual bool         isSimple() const = 0 ;
183 
184 
185     /**
186      * Force the state of the validity flag. The validity flag allows to bypass validity checks
187      * If the flag is true, it means the geometry is considered valid
188      * If the flag is false, it means the validity state of the geometry is unknown
189      * The flag is only changed for this geometry and not the internal geometries.
190      * @see propagateValidityFlag
191      */
192     void forceValidityFlag( bool validity );
193 
194     /** Returns the validity flag */
195     bool hasValidityFlag() const;
196 
197     /**
198      * [OGC/SFA]returns the WKT string
199      * @param numDecimals extension specify fix precision output
200      */
201     std::string          asText( const int& numDecimals = -1 ) const ;
202 
203     /**
204      * [OGC/SFA]Returns a polygon representing the BBOX of the geometry
205      * @todo In order to adapt to 3D, would be better to define an "Envelope type",
206      * otherway would lead to Polygon and PolyhedralSurface
207      */
208     //std::unique_ptr< Geometry > envelope() const = 0 ;
209     Envelope              envelope() const ;
210 
211     /**
212      * @brief [OGC/SFA]Returns the boundary of the geometry
213      */
214     virtual std::unique_ptr< Geometry > boundary() const ;
215 
216     /**
217      * @brief Computes the distance to an other geometry
218      */
219     double distance( const Geometry& other ) const ;
220     /**
221      * @brief Computes the 3D distance to an other geometry
222      */
223     double distance3D( const Geometry& other ) const ;
224 
225 
226     //-- helpers
227 
228     /**
229      * @brief round the geometry with a corresponding scale factor
230      * @param scale the scale factor (1 corresponds to the nearest integer, 1000 to a 0.001 tolerance)
231      */
232     void round( const long& scale = 1 ) ;
233 
234 
235     /**
236      * @brief [OGC/SFA]Gets the number of geometries in a collection of geometries
237      * @warning 1 for Point, LineString, Polygon, Triangle
238      */
239     virtual size_t             numGeometries() const ;
240     /**
241      * @brief [OGC/SFA]Returns the n-th geometry
242      * @warning *this for Point, LineString, Polygon, Triangle
243      */
244     virtual const Geometry&    geometryN( size_t const& n ) const ;
245     /**
246      * @brief [OGC/SFA]Returns the n-th geometry
247      * @warning *this for Point, LineString, Polygon, Triangle
248      */
249     virtual Geometry&           geometryN( size_t const& n ) ;
250 
251 
252     /**
253      * @brief Tests if geometry is of "Derived" type given as template parameter
254      * @warning not optimized (slow with dynamic_cast)
255      */
256     template < typename Derived >
is()257     inline bool is() const {
258         return dynamic_cast< Derived const* >( this ) != NULL ;
259     }
260 
261 
262     /**
263      * @brief Downcast to a "Derived" class
264      * @warning performs check if boost assertions are enabled
265     * @pre The cast must be doable
266            */
267     template < typename Derived >
as()268     inline const Derived&   as() const {
269         BOOST_ASSERT( is< Derived >() );
270         return *static_cast< Derived const* >( this );
271     }
272     /**
273      * @brief Downcast to a "Derived" class
274      * @warning performs check if boost assertions are enabled
275     * @pre The cast must be doable
276            */
277     template < typename Derived >
as()278     inline Derived&         as() {
279         BOOST_ASSERT( is< Derived >() );
280         return *static_cast< Derived* >( this );
281     }
282 
283     /**
284      * @brief [visitor]dispatch visitor
285     * @ingroup detail
286            */
287     virtual void accept( GeometryVisitor& visitor ) = 0 ;
288     /**
289      * @brief [visitor]dispatch visitor
290     * @ingroup detail
291            */
292     virtual void accept( ConstGeometryVisitor& visitor ) const = 0 ;
293 
294     /**
295      * Serializer
296     * @ingroup detail
297            */
298     template <class Archive>
serialize(Archive &,const unsigned int)299     void serialize( Archive& /*ar*/, const unsigned int /*version*/ ) {
300     }
301 
302 protected:
303 
304     bool validityFlag_;
305 };
306 
307 /**
308  * Equality operator
309  * @todo only compare coordinate points
310  * @pre the two geometries must be valid
311  */
312 SFCGAL_API bool operator==( const Geometry&, const Geometry& );
313 
314 } // namespace SFCGAL
315 
316 #endif
317