/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 | 0 | { |
121 | 0 | return "TRIANGLE"; |
122 | 0 | } |
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 |