1 /******************************************************************************
2 * $Id: ogrtriangulatedsurface.cpp 464e5bd63b59963407c8adc30fcbd5899731eddc 2021-03-16 15:06:30 +0100 Even Rouault $
3 *
4 * Project: OpenGIS Simple Features Reference Implementation
5 * Purpose: The OGRTriangulatedSurface geometry class.
6 * Author: Avyav Kumar Singh <avyavkumar at gmail dot com>
7 *
8 ******************************************************************************
9 * Copyright (c) 2016, Avyav Kumar Singh <avyavkumar at gmail dot com>
10 * Copyright (c) 2016, Even Rouault <even.roauult at spatialys.com>
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice shall be included
20 * in all copies or substantial portions of the Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 * DEALINGS IN THE SOFTWARE.
29 ****************************************************************************/
30
31 #include "ogr_geometry.h"
32 #include "ogr_p.h"
33 #include "ogr_api.h"
34
35 CPL_CVSID("$Id: ogrtriangulatedsurface.cpp 464e5bd63b59963407c8adc30fcbd5899731eddc 2021-03-16 15:06:30 +0100 Even Rouault $")
36
37 /************************************************************************/
38 /* OGRTriangulatedSurface() */
39 /************************************************************************/
40
41 /**
42 * \brief Constructor.
43 *
44 */
45
46 OGRTriangulatedSurface::OGRTriangulatedSurface() = default;
47
48 /************************************************************************/
49 /* OGRTriangulatedSurface( const OGRTriangulatedSurface& ) */
50 /************************************************************************/
51
52 /**
53 * \brief Copy constructor.
54 *
55 */
56
OGRTriangulatedSurface(const OGRTriangulatedSurface & other)57 OGRTriangulatedSurface::OGRTriangulatedSurface(
58 const OGRTriangulatedSurface& other ) :
59 OGRPolyhedralSurface()
60 {
61 *this = other;
62 }
63
64 /************************************************************************/
65 /* ~OGRTriangulatedSurface() */
66 /************************************************************************/
67
68 /**
69 * \brief Destructor
70 *
71 */
72
73 OGRTriangulatedSurface::~OGRTriangulatedSurface() = default;
74
75 /************************************************************************/
76 /* operator=( const OGRTriangulatedSurface&) */
77 /************************************************************************/
78
79 /**
80 * \brief Assignment operator.
81 *
82 */
83
operator =(const OGRTriangulatedSurface & other)84 OGRTriangulatedSurface& OGRTriangulatedSurface::operator=(
85 const OGRTriangulatedSurface& other )
86 {
87 if( this != &other)
88 {
89 // We need to do it manually. We cannot rely on the = operator
90 // of OGRPolyhedralSurface since it will be confused by a multipolygon
91 // of triangles.
92 OGRSurface::operator=( other );
93 empty();
94 set3D( other.Is3D() );
95 setMeasured( other.IsMeasured() );
96 assignSpatialReference( other.getSpatialReference() );
97 for(int i=0;i<other.oMP.nGeomCount;i++)
98 {
99 OGRTriangulatedSurface::addGeometry( other.oMP.getGeometryRef(i) );
100 }
101 }
102 return *this;
103 }
104
105 /************************************************************************/
106 /* clone() */
107 /************************************************************************/
108
clone() const109 OGRTriangulatedSurface *OGRTriangulatedSurface::clone() const
110
111 {
112 return new (std::nothrow) OGRTriangulatedSurface(*this);
113 }
114
115 /************************************************************************/
116 /* getGeometryName() */
117 /************************************************************************/
118
119 /**
120 * \brief Returns the geometry name of the TriangulatedSurface
121 *
122 * @return "TIN"
123 *
124 */
125
getGeometryName() const126 const char* OGRTriangulatedSurface::getGeometryName() const
127 {
128 return "TIN" ;
129 }
130
131 /************************************************************************/
132 /* getGeometryType() */
133 /************************************************************************/
134
135 /**
136 * \brief Returns the WKB Type of TriangulatedSurface
137 *
138 */
139
getGeometryType() const140 OGRwkbGeometryType OGRTriangulatedSurface::getGeometryType() const
141 {
142 if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) )
143 return wkbTINZM;
144 else if( flags & OGR_G_MEASURED )
145 return wkbTINM;
146 else if( flags & OGR_G_3D )
147 return wkbTINZ;
148 else
149 return wkbTIN;
150 }
151
152 /************************************************************************/
153 /* isCompatibleSubType() */
154 /************************************************************************/
155
156 //! @cond Doxygen_Suppress
isCompatibleSubType(OGRwkbGeometryType eSubType) const157 OGRBoolean OGRTriangulatedSurface::isCompatibleSubType(
158 OGRwkbGeometryType eSubType ) const
159 {
160 return wkbFlatten( eSubType ) == wkbTriangle;
161 }
162 //! @endcond
163
164 /************************************************************************/
165 /* getSubGeometryName() */
166 /************************************************************************/
167
168 //! @cond Doxygen_Suppress
getSubGeometryName() const169 const char* OGRTriangulatedSurface::getSubGeometryName() const
170 {
171 return "TRIANGLE";
172 }
173 //! @endcond
174
175 /************************************************************************/
176 /* getSubGeometryType() */
177 /************************************************************************/
178
179 //! @cond Doxygen_Suppress
getSubGeometryType() const180 OGRwkbGeometryType OGRTriangulatedSurface::getSubGeometryType() const
181 {
182 return wkbTriangle;
183 }
184 //! @endcond
185
186 /************************************************************************/
187 /* addGeometry() */
188 /************************************************************************/
189
addGeometry(const OGRGeometry * poNewGeom)190 OGRErr OGRTriangulatedSurface::addGeometry (const OGRGeometry *poNewGeom)
191 {
192 // If the geometry is a polygon, check if it can be cast as a triangle
193 if( EQUAL(poNewGeom->getGeometryName(),"POLYGON") )
194 {
195 OGRErr eErr = OGRERR_FAILURE;
196 OGRTriangle *poTriangle = new OGRTriangle(
197 *(poNewGeom->toPolygon()), eErr);
198 if (poTriangle != nullptr && eErr == OGRERR_NONE)
199 {
200 eErr = addGeometryDirectly(poTriangle);
201
202 if( eErr != OGRERR_NONE )
203 delete poTriangle;
204
205 return eErr;
206 }
207 else
208 {
209 delete poTriangle;
210 return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
211 }
212 }
213
214 return OGRPolyhedralSurface::addGeometry(poNewGeom);
215 }
216
217 /************************************************************************/
218 /* GetCasterToMultiPolygon() */
219 /************************************************************************/
220
221 //! @cond Doxygen_Suppress
222 OGRPolyhedralSurfaceCastToMultiPolygon
GetCasterToMultiPolygon() const223 OGRTriangulatedSurface::GetCasterToMultiPolygon() const
224 {
225 return OGRTriangulatedSurface::CastToMultiPolygonImpl;
226 }
227
228 /************************************************************************/
229 /* CastToMultiPolygon() */
230 /************************************************************************/
231
CastToMultiPolygonImpl(OGRPolyhedralSurface * poTS)232 OGRMultiPolygon* OGRTriangulatedSurface::CastToMultiPolygonImpl(
233 OGRPolyhedralSurface* poTS)
234 {
235 OGRMultiPolygon *poMultiPolygon = new OGRMultiPolygon();
236 poMultiPolygon->assignSpatialReference(poTS->getSpatialReference());
237
238 for( auto&& poSubGeom: *poTS )
239 {
240 OGRPolygon *poPolygon = OGRSurface::CastToPolygon(poSubGeom);
241 poMultiPolygon->addGeometryDirectly(poPolygon);
242 poSubGeom = nullptr;
243 }
244 delete poTS;
245
246 return poMultiPolygon;
247 }
248 //! @endcond
249
250 /************************************************************************/
251 /* CastToPolyhedralSurface() */
252 /************************************************************************/
253
254 /**
255 * \brief Casts the OGRTriangulatedSurface to an OGRPolyhedralSurface
256 *
257 * The passed in geometry is consumed and a new one returned (or NULL in case
258 * of failure)
259 *
260 * @param poTS the input geometry - ownership is passed to the method.
261 * @return new geometry.
262 */
263
264
CastToPolyhedralSurface(OGRTriangulatedSurface * poTS)265 OGRPolyhedralSurface* OGRTriangulatedSurface::CastToPolyhedralSurface(
266 OGRTriangulatedSurface* poTS)
267 {
268 OGRPolyhedralSurface* poPS = new OGRPolyhedralSurface();
269 poPS->assignSpatialReference(poTS->getSpatialReference());
270 for( auto&& poSubGeom: *poTS )
271 {
272 OGRPolygon *poPolygon = OGRSurface::CastToPolygon(poSubGeom);
273 poPS->oMP.addGeometryDirectly(poPolygon);
274 poSubGeom = nullptr;
275 }
276 delete poTS;
277 return poPS;
278 }
279