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