Coverage Report

Created: 2025-06-13 06:29

/src/gdal/ogr/ogrtriangle.cpp
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Project:  OpenGIS Simple Features Reference Implementation
4
 * Purpose:  The OGRTriangle 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_api.h"
16
#include "cpl_error.h"
17
18
/************************************************************************/
19
/*                             OGRTriangle()                            */
20
/************************************************************************/
21
22
/**
23
 * \brief Copy constructor.
24
 *
25
 */
26
27
0
OGRTriangle::OGRTriangle(const OGRTriangle &) = default;
28
29
/************************************************************************/
30
/*                             OGRTriangle()                            */
31
/************************************************************************/
32
33
/**
34
 * \brief Constructs an OGRTriangle from a valid OGRPolygon. In case of error,
35
 * NULL is returned.
36
 *
37
 * @param other the Polygon we wish to construct a triangle from
38
 * @param eErr encapsulates an error code; contains OGRERR_NONE if the triangle
39
 * is constructed successfully
40
 */
41
42
OGRTriangle::OGRTriangle(const OGRPolygon &other, OGRErr &eErr)
43
0
{
44
    // In case of Polygon, we have to check that it is a valid triangle -
45
    // closed and contains one external ring of four points
46
    // If not, then eErr will contain the error description
47
0
    const OGRCurve *poCurve = other.getExteriorRingCurve();
48
0
    if (other.getNumInteriorRings() == 0 && poCurve != nullptr &&
49
0
        poCurve->get_IsClosed() && poCurve->getNumPoints() == 4)
50
0
    {
51
        // everything is fine
52
0
        eErr = addRing(const_cast<OGRCurve *>(poCurve));
53
0
        if (eErr != OGRERR_NONE)
54
0
            CPLError(CE_Failure, CPLE_NotSupported, "Invalid Triangle");
55
0
    }
56
0
    assignSpatialReference(other.getSpatialReference());
57
0
}
58
59
/************************************************************************/
60
/*                             OGRTriangle()                            */
61
/************************************************************************/
62
63
/**
64
 * \brief Construct a triangle from points
65
 *
66
 * @param p Point 1
67
 * @param q Point 2
68
 * @param r Point 3
69
 */
70
71
OGRTriangle::OGRTriangle(const OGRPoint &p, const OGRPoint &q,
72
                         const OGRPoint &r)
73
0
{
74
0
    OGRLinearRing *poCurve = new OGRLinearRing();
75
0
    poCurve->addPoint(&p);
76
0
    poCurve->addPoint(&q);
77
0
    poCurve->addPoint(&r);
78
0
    poCurve->addPoint(&p);
79
80
0
    oCC.addCurveDirectly(this, poCurve, TRUE);
81
0
}
82
83
/************************************************************************/
84
/*                    operator=( const OGRGeometry&)                    */
85
/************************************************************************/
86
87
/**
88
 * \brief Assignment operator
89
 *
90
 * @param other A triangle passed as a parameter
91
 *
92
 * @return OGRTriangle A copy of other
93
 *
94
 */
95
96
OGRTriangle &OGRTriangle::operator=(const OGRTriangle &other)
97
0
{
98
0
    if (this != &other)
99
0
    {
100
0
        OGRPolygon::operator=(other);
101
0
    }
102
0
    return *this;
103
0
}
104
105
/************************************************************************/
106
/*                               clone()                                */
107
/************************************************************************/
108
109
OGRTriangle *OGRTriangle::clone() const
110
111
0
{
112
0
    return new (std::nothrow) OGRTriangle(*this);
113
0
}
114
115
/************************************************************************/
116
/*                          getGeometryName()                           */
117
/************************************************************************/
118
119
const char *OGRTriangle::getGeometryName() const
120
1
{
121
1
    return "TRIANGLE";
122
1
}
123
124
/************************************************************************/
125
/*                          getGeometryType()                           */
126
/************************************************************************/
127
128
OGRwkbGeometryType OGRTriangle::getGeometryType() const
129
0
{
130
0
    if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED))
131
0
        return wkbTriangleZM;
132
0
    else if (flags & OGR_G_MEASURED)
133
0
        return wkbTriangleM;
134
0
    else if (flags & OGR_G_3D)
135
0
        return wkbTriangleZ;
136
0
    else
137
0
        return wkbTriangle;
138
0
}
139
140
/************************************************************************/
141
/*                        quickValidityCheck()                          */
142
/************************************************************************/
143
144
bool OGRTriangle::quickValidityCheck() const
145
0
{
146
0
    return oCC.nCurveCount == 0 ||
147
0
           (oCC.nCurveCount == 1 && oCC.papoCurves[0]->getNumPoints() == 4 &&
148
0
            oCC.papoCurves[0]->get_IsClosed());
149
0
}
150
151
/************************************************************************/
152
/*                           importFromWkb()                            */
153
/************************************************************************/
154
155
OGRErr OGRTriangle::importFromWkb(const unsigned char *pabyData, size_t nSize,
156
                                  OGRwkbVariant eWkbVariant,
157
                                  size_t &nBytesConsumedOut)
158
0
{
159
0
    OGRErr eErr = OGRPolygon::importFromWkb(pabyData, nSize, eWkbVariant,
160
0
                                            nBytesConsumedOut);
161
0
    if (eErr != OGRERR_NONE)
162
0
        return eErr;
163
164
0
    if (!quickValidityCheck())
165
0
    {
166
0
        CPLDebug("OGR", "Triangle is not made of a closed rings of 3 points");
167
0
        empty();
168
0
        return OGRERR_CORRUPT_DATA;
169
0
    }
170
171
0
    return OGRERR_NONE;
172
0
}
173
174
/*! @cond Doxygen_Suppress */
175
/************************************************************************/
176
/*                        importFromWKTListOnly()                       */
177
/*                                                                      */
178
/*      Instantiate from "((x y, x y, ...),(x y, ...),...)"             */
179
/************************************************************************/
180
181
OGRErr OGRTriangle::importFromWKTListOnly(const char **ppszInput, int bHasZ,
182
                                          int bHasM, OGRRawPoint *&paoPoints,
183
                                          int &nMaxPoints, double *&padfZ)
184
185
0
{
186
0
    OGRErr eErr = OGRPolygon::importFromWKTListOnly(
187
0
        ppszInput, bHasZ, bHasM, paoPoints, nMaxPoints, padfZ);
188
0
    if (eErr == OGRERR_NONE)
189
0
    {
190
0
        if (!quickValidityCheck())
191
0
        {
192
0
            CPLDebug("OGR",
193
0
                     "Triangle is not made of a closed rings of 3 points");
194
0
            empty();
195
0
            eErr = OGRERR_CORRUPT_DATA;
196
0
        }
197
0
    }
198
199
0
    return eErr;
200
0
}
201
202
/*! @endcond */
203
204
/************************************************************************/
205
/*                           addRingDirectly()                          */
206
/************************************************************************/
207
208
OGRErr OGRTriangle::addRingDirectly(OGRCurve *poNewRing)
209
0
{
210
0
    if (oCC.nCurveCount == 0)
211
0
        return addRingDirectlyInternal(poNewRing, TRUE);
212
0
    else
213
0
        return OGRERR_FAILURE;
214
0
}
215
216
//! @cond Doxygen_Suppress
217
/************************************************************************/
218
/*                      GetCasterToPolygon()                            */
219
/************************************************************************/
220
221
OGRPolygon *OGRTriangle::CasterToPolygon(OGRSurface *poSurface)
222
0
{
223
0
    OGRTriangle *poTriangle = poSurface->toTriangle();
224
0
    OGRPolygon *poRet = new OGRPolygon(*poTriangle);
225
0
    delete poTriangle;
226
0
    return poRet;
227
0
}
228
229
OGRSurfaceCasterToPolygon OGRTriangle::GetCasterToPolygon() const
230
0
{
231
0
    return OGRTriangle::CasterToPolygon;
232
0
}
233
234
/************************************************************************/
235
/*                        CastToPolygon()                               */
236
/************************************************************************/
237
238
OGRGeometry *OGRTriangle::CastToPolygon(OGRGeometry *poGeom)
239
0
{
240
0
    OGRGeometry *poRet = new OGRPolygon(*(poGeom->toPolygon()));
241
0
    delete poGeom;
242
0
    return poRet;
243
0
}
244
245
//! @endcond