Coverage Report

Created: 2025-06-13 06:29

/src/gdal/ogr/ogrtriangulatedsurface.cpp
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  OpenGIS Simple Features Reference Implementation
4
 * Purpose:  The OGRTriangulatedSurface geometry class.
5
 * Author:   Avyav Kumar Singh <avyavkumar at gmail dot com>
6
 *
7
 ******************************************************************************
8
 * Copyright (c) 2016, Avyav Kumar Singh <avyavkumar at gmail dot com>
9
 * Copyright (c) 2016, Even Rouault <even.roauult at spatialys.com>
10
 *
11
 * SPDX-License-Identifier: MIT
12
 ****************************************************************************/
13
14
#include "ogr_geometry.h"
15
#include "ogr_p.h"
16
#include "ogr_api.h"
17
18
/************************************************************************/
19
/*        OGRTriangulatedSurface( const OGRTriangulatedSurface& )       */
20
/************************************************************************/
21
22
/**
23
 * \brief Copy constructor.
24
 *
25
 */
26
27
OGRTriangulatedSurface::OGRTriangulatedSurface(
28
    const OGRTriangulatedSurface &other)
29
0
    : OGRPolyhedralSurface()
30
0
{
31
0
    *this = other;
32
0
}
33
34
/************************************************************************/
35
/*                 operator=( const OGRTriangulatedSurface&)            */
36
/************************************************************************/
37
38
/**
39
 * \brief Assignment operator.
40
 *
41
 */
42
43
OGRTriangulatedSurface &
44
OGRTriangulatedSurface::operator=(const OGRTriangulatedSurface &other)
45
0
{
46
0
    if (this != &other)
47
0
    {
48
        // We need to do it manually. We cannot rely on the = operator
49
        // of OGRPolyhedralSurface since it will be confused by a multipolygon
50
        // of triangles.
51
0
        OGRSurface::operator=(other);
52
0
        for (const auto *poPoly : other.oMP)
53
0
        {
54
0
            OGRTriangulatedSurface::addGeometry(poPoly);
55
0
        }
56
0
    }
57
0
    return *this;
58
0
}
59
60
/************************************************************************/
61
/*                               clone()                                */
62
/************************************************************************/
63
64
OGRTriangulatedSurface *OGRTriangulatedSurface::clone() const
65
66
0
{
67
0
    return new (std::nothrow) OGRTriangulatedSurface(*this);
68
0
}
69
70
/************************************************************************/
71
/*                          getGeometryName()                           */
72
/************************************************************************/
73
74
/**
75
 * \brief Returns the geometry name of the TriangulatedSurface
76
 *
77
 * @return "TIN"
78
 *
79
 */
80
81
const char *OGRTriangulatedSurface::getGeometryName() const
82
1
{
83
1
    return "TIN";
84
1
}
85
86
/************************************************************************/
87
/*                          getGeometryType()                           */
88
/************************************************************************/
89
90
/**
91
 * \brief Returns the WKB Type of TriangulatedSurface
92
 *
93
 */
94
95
OGRwkbGeometryType OGRTriangulatedSurface::getGeometryType() const
96
0
{
97
0
    if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED))
98
0
        return wkbTINZM;
99
0
    else if (flags & OGR_G_MEASURED)
100
0
        return wkbTINM;
101
0
    else if (flags & OGR_G_3D)
102
0
        return wkbTINZ;
103
0
    else
104
0
        return wkbTIN;
105
0
}
106
107
/************************************************************************/
108
/*                         isCompatibleSubType()                        */
109
/************************************************************************/
110
111
//! @cond Doxygen_Suppress
112
OGRBoolean
113
OGRTriangulatedSurface::isCompatibleSubType(OGRwkbGeometryType eSubType) const
114
0
{
115
0
    return wkbFlatten(eSubType) == wkbTriangle;
116
0
}
117
118
//! @endcond
119
120
/************************************************************************/
121
/*                         getSubGeometryName()                         */
122
/************************************************************************/
123
124
//! @cond Doxygen_Suppress
125
const char *OGRTriangulatedSurface::getSubGeometryName() const
126
0
{
127
0
    return "TRIANGLE";
128
0
}
129
130
//! @endcond
131
132
/************************************************************************/
133
/*                         getSubGeometryType()                         */
134
/************************************************************************/
135
136
//! @cond Doxygen_Suppress
137
OGRwkbGeometryType OGRTriangulatedSurface::getSubGeometryType() const
138
0
{
139
0
    return wkbTriangle;
140
0
}
141
142
//! @endcond
143
144
/************************************************************************/
145
/*                            addGeometry()                             */
146
/************************************************************************/
147
148
OGRErr OGRTriangulatedSurface::addGeometry(const OGRGeometry *poNewGeom)
149
0
{
150
    // If the geometry is a polygon, check if it can be cast as a triangle
151
0
    if (EQUAL(poNewGeom->getGeometryName(), "POLYGON"))
152
0
    {
153
0
        OGRErr eErr = OGRERR_FAILURE;
154
0
        OGRTriangle *poTriangle =
155
0
            new OGRTriangle(*(poNewGeom->toPolygon()), eErr);
156
0
        if (poTriangle != nullptr && eErr == OGRERR_NONE)
157
0
        {
158
0
            eErr = addGeometryDirectly(poTriangle);
159
160
0
            if (eErr != OGRERR_NONE)
161
0
                delete poTriangle;
162
163
0
            return eErr;
164
0
        }
165
0
        else
166
0
        {
167
0
            delete poTriangle;
168
0
            return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
169
0
        }
170
0
    }
171
172
0
    return OGRPolyhedralSurface::addGeometry(poNewGeom);
173
0
}
174
175
/************************************************************************/
176
/*                     GetCasterToMultiPolygon()                        */
177
/************************************************************************/
178
179
//! @cond Doxygen_Suppress
180
OGRPolyhedralSurfaceCastToMultiPolygon
181
OGRTriangulatedSurface::GetCasterToMultiPolygon() const
182
0
{
183
0
    return OGRTriangulatedSurface::CastToMultiPolygonImpl;
184
0
}
185
186
/************************************************************************/
187
/*                         CastToMultiPolygon()                         */
188
/************************************************************************/
189
190
OGRMultiPolygon *
191
OGRTriangulatedSurface::CastToMultiPolygonImpl(OGRPolyhedralSurface *poTS)
192
0
{
193
0
    OGRMultiPolygon *poMultiPolygon = new OGRMultiPolygon();
194
0
    poMultiPolygon->assignSpatialReference(poTS->getSpatialReference());
195
196
0
    for (auto &&poSubGeom : *poTS)
197
0
    {
198
0
        OGRPolygon *poPolygon = OGRSurface::CastToPolygon(poSubGeom);
199
0
        poMultiPolygon->addGeometryDirectly(poPolygon);
200
0
        poSubGeom = nullptr;
201
0
    }
202
0
    delete poTS;
203
204
0
    return poMultiPolygon;
205
0
}
206
207
//! @endcond
208
209
/************************************************************************/
210
/*                     CastToPolyhedralSurface()                        */
211
/************************************************************************/
212
213
/**
214
 * \brief Casts the OGRTriangulatedSurface to an OGRPolyhedralSurface
215
 *
216
 * The passed in geometry is consumed and a new one returned (or NULL in case
217
 * of failure)
218
 *
219
 * @param poTS the input geometry - ownership is passed to the method.
220
 * @return new geometry.
221
 */
222
223
OGRPolyhedralSurface *
224
OGRTriangulatedSurface::CastToPolyhedralSurface(OGRTriangulatedSurface *poTS)
225
0
{
226
0
    OGRPolyhedralSurface *poPS = new OGRPolyhedralSurface();
227
0
    poPS->assignSpatialReference(poTS->getSpatialReference());
228
0
    for (auto &&poSubGeom : *poTS)
229
0
    {
230
0
        OGRPolygon *poPolygon = OGRSurface::CastToPolygon(poSubGeom);
231
0
        poPS->oMP.addGeometryDirectly(poPolygon);
232
0
        poSubGeom = nullptr;
233
0
    }
234
0
    delete poTS;
235
0
    return poPS;
236
0
}