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 #include <SFCGAL/Geometry.h>
22 
23 #include <SFCGAL/Point.h>
24 #include <SFCGAL/GeometryVisitor.h>
25 #include <SFCGAL/detail/io/WktWriter.h>
26 #include <SFCGAL/detail/GetPointsVisitor.h>
27 
28 #include <SFCGAL/algorithm/BoundaryVisitor.h>
29 #include <SFCGAL/algorithm/distance.h>
30 #include <SFCGAL/algorithm/distance3d.h>
31 
32 #include <SFCGAL/detail/EnvelopeVisitor.h>
33 
34 #include <SFCGAL/detail/transform/RoundTransform.h>
35 
36 #include <SFCGAL/Kernel.h>
37 
38 namespace SFCGAL {
39 
40 ///
41 ///
42 ///
asText(const int & numDecimals) const43 std::string Geometry::asText( const int& numDecimals ) const
44 {
45     std::ostringstream oss;
46 
47     if ( numDecimals >= 0 ) {
48         oss << std::fixed ;
49         oss.precision( numDecimals );
50     }
51 
52     detail::io::WktWriter writer( oss );
53     bool exact = false;
54 
55     if ( numDecimals == -1 ) {
56         exact = true;
57     }
58 
59     writer.write( *this, exact );
60     return oss.str();
61 }
62 
63 ///
64 ///
65 ///
envelope() const66 Envelope   Geometry::envelope() const
67 {
68     Envelope box ;
69     detail::EnvelopeVisitor envelopeVisitor( box );
70     accept( envelopeVisitor );
71     return box ;
72 }
73 
74 ///
75 ///
76 ///
boundary() const77 std::unique_ptr< Geometry > Geometry::boundary() const
78 {
79     algorithm::BoundaryVisitor visitor ;
80     accept( visitor );
81     return std::unique_ptr< Geometry >( visitor.releaseBoundary() ) ;
82 }
83 
84 
85 ///
86 ///
87 ///
distance(const Geometry & other) const88 double Geometry::distance( const Geometry& other ) const
89 {
90     return algorithm::distance( *this, other ) ;
91 }
92 
93 ///
94 ///
95 ///
distance3D(const Geometry & other) const96 double Geometry::distance3D( const Geometry& other ) const
97 {
98     return algorithm::distance3D( *this, other ) ;
99 }
100 
101 ///
102 ///
103 ///
round(const long & scale)104 void Geometry::round( const long& scale )
105 {
106     transform::RoundTransform roundTransform( scale );
107     accept( roundTransform ) ;
108 }
109 
110 ///
111 ///
112 ///
numGeometries() const113 size_t Geometry::numGeometries() const
114 {
115     return 1 ;
116 }
117 
118 ///
119 ///
120 ///
geometryN(size_t const & n) const121 const Geometry&    Geometry::geometryN( size_t const& n ) const
122 {
123     BOOST_ASSERT( n == 0 );
124     ( void )n;
125     return *this ;
126 }
127 
128 ///
129 ///
130 ///
geometryN(size_t const & n)131 Geometry&   Geometry::geometryN( size_t const& n )
132 {
133     BOOST_ASSERT( n == 0 );
134     ( void )n;
135     return *this ;
136 }
137 
138 ///
139 ///
140 ///
Geometry()141 Geometry::Geometry() : validityFlag_( false )
142 {
143 
144 }
145 
hasValidityFlag() const146 bool Geometry::hasValidityFlag() const
147 {
148         return validityFlag_;
149 }
150 
forceValidityFlag(bool valid)151 void Geometry::forceValidityFlag( bool valid )
152 {
153         validityFlag_ = valid;
154 }
155 
156 ///
157 /// Function used to compare geometries
158 /// FIXME
159 /// Since we do not have (yet) a real "equals" operator, we only compare points coordinates
operator ==(const Geometry & ga,const Geometry & gb)160 bool operator == ( const Geometry& ga, const Geometry& gb )
161 {
162     if ( ga.geometryTypeId() != gb.geometryTypeId() ) {
163         return false;
164     }
165 
166     detail::GetPointsVisitor get_points_a, get_points_b;
167     ga.accept( get_points_a );
168     gb.accept( get_points_b );
169 
170     if ( get_points_a.points.size() != get_points_b.points.size() ) {
171         return false;
172     }
173 
174     for ( size_t i = 0; i < get_points_a.points.size(); ++i ) {
175         bool found = false;
176 
177         for ( size_t j = 0; j < get_points_b.points.size(); ++j ) {
178             const Point& pta = *( get_points_a.points[i] );
179             const Point& ptb = *( get_points_b.points[j] );
180 
181             if ( pta == ptb ) {
182                 found = true;
183                 break;
184             }
185         }
186 
187         if ( ! found ) {
188             return false;
189         }
190     }
191 
192     return true;
193 }
194 
195 }//SFCGAL
196 
197