Line data Source code
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 : 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 13 : OGRTriangle::OGRTriangle(const OGRPolygon &other, OGRErr &eErr) 43 : { 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 13 : const OGRCurve *poCurve = other.getExteriorRingCurve(); 48 26 : if (other.getNumInteriorRings() == 0 && poCurve != nullptr && 49 26 : poCurve->get_IsClosed() && poCurve->getNumPoints() == 4) 50 : { 51 : // everything is fine 52 12 : eErr = addRing(const_cast<OGRCurve *>(poCurve)); 53 12 : if (eErr != OGRERR_NONE) 54 0 : CPLError(CE_Failure, CPLE_NotSupported, "Invalid Triangle"); 55 : } 56 13 : assignSpatialReference(other.getSpatialReference()); 57 13 : } 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 1246630 : OGRTriangle::OGRTriangle(const OGRPoint &p, const OGRPoint &q, 72 1246630 : const OGRPoint &r) 73 : { 74 1246630 : OGRLinearRing *poCurve = new OGRLinearRing(); 75 1246630 : poCurve->addPoint(&p); 76 1246630 : poCurve->addPoint(&q); 77 1246630 : poCurve->addPoint(&r); 78 1246630 : poCurve->addPoint(&p); 79 : 80 1246630 : oCC.addCurveDirectly(this, poCurve, TRUE); 81 1246630 : } 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 5 : OGRTriangle &OGRTriangle::operator=(const OGRTriangle &other) 97 : { 98 5 : if (this != &other) 99 : { 100 4 : OGRPolygon::operator=(other); 101 : } 102 5 : return *this; 103 : } 104 : 105 : /************************************************************************/ 106 : /* clone() */ 107 : /************************************************************************/ 108 : 109 1296170 : OGRTriangle *OGRTriangle::clone() const 110 : 111 : { 112 1296170 : return new (std::nothrow) OGRTriangle(*this); 113 : } 114 : 115 : /************************************************************************/ 116 : /* getGeometryName() */ 117 : /************************************************************************/ 118 : 119 1296490 : const char *OGRTriangle::getGeometryName() const 120 : { 121 1296490 : return "TRIANGLE"; 122 : } 123 : 124 : /************************************************************************/ 125 : /* getGeometryType() */ 126 : /************************************************************************/ 127 : 128 2846590 : OGRwkbGeometryType OGRTriangle::getGeometryType() const 129 : { 130 2846590 : if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED)) 131 36366 : return wkbTriangleZM; 132 2810230 : else if (flags & OGR_G_MEASURED) 133 15 : return wkbTriangleM; 134 2810210 : else if (flags & OGR_G_3D) 135 2810040 : return wkbTriangleZ; 136 : else 137 174 : return wkbTriangle; 138 : } 139 : 140 : /************************************************************************/ 141 : /* quickValidityCheck() */ 142 : /************************************************************************/ 143 : 144 14034 : bool OGRTriangle::quickValidityCheck() const 145 : { 146 28062 : return oCC.nCurveCount == 0 || 147 14028 : (oCC.nCurveCount == 1 && oCC.papoCurves[0]->getNumPoints() == 4 && 148 28045 : oCC.papoCurves[0]->get_IsClosed()); 149 : } 150 : 151 : /************************************************************************/ 152 : /* importFromWkb() */ 153 : /************************************************************************/ 154 : 155 14326 : OGRErr OGRTriangle::importFromWkb(const unsigned char *pabyData, size_t nSize, 156 : OGRwkbVariant eWkbVariant, 157 : size_t &nBytesConsumedOut) 158 : { 159 14326 : OGRErr eErr = OGRPolygon::importFromWkb(pabyData, nSize, eWkbVariant, 160 : nBytesConsumedOut); 161 14326 : if (eErr != OGRERR_NONE) 162 663 : return eErr; 163 : 164 13663 : if (!quickValidityCheck()) 165 : { 166 1740 : CPLDebug("OGR", "Triangle is not made of a closed rings of 3 points"); 167 1740 : empty(); 168 1740 : return OGRERR_CORRUPT_DATA; 169 : } 170 : 171 11923 : return OGRERR_NONE; 172 : } 173 : 174 : /*! @cond Doxygen_Suppress */ 175 : /************************************************************************/ 176 : /* importFromWKTListOnly() */ 177 : /* */ 178 : /* Instantiate from "((x y, x y, ...),(x y, ...),...)" */ 179 : /************************************************************************/ 180 : 181 372 : OGRErr OGRTriangle::importFromWKTListOnly(const char **ppszInput, int bHasZ, 182 : int bHasM, OGRRawPoint *&paoPoints, 183 : int &nMaxPoints, double *&padfZ) 184 : 185 : { 186 372 : OGRErr eErr = OGRPolygon::importFromWKTListOnly( 187 : ppszInput, bHasZ, bHasM, paoPoints, nMaxPoints, padfZ); 188 372 : if (eErr == OGRERR_NONE) 189 : { 190 371 : if (!quickValidityCheck()) 191 : { 192 6 : CPLDebug("OGR", 193 : "Triangle is not made of a closed rings of 3 points"); 194 6 : empty(); 195 6 : eErr = OGRERR_CORRUPT_DATA; 196 : } 197 : } 198 : 199 372 : return eErr; 200 : } 201 : 202 : /*! @endcond */ 203 : 204 : /************************************************************************/ 205 : /* addRingDirectly() */ 206 : /************************************************************************/ 207 : 208 16 : OGRErr OGRTriangle::addRingDirectly(OGRCurve *poNewRing) 209 : { 210 16 : if (oCC.nCurveCount == 0) 211 16 : return addRingDirectlyInternal(poNewRing, TRUE); 212 : else 213 0 : return OGRERR_FAILURE; 214 : } 215 : 216 : //! @cond Doxygen_Suppress 217 : /************************************************************************/ 218 : /* GetCasterToPolygon() */ 219 : /************************************************************************/ 220 : 221 52257 : OGRPolygon *OGRTriangle::CasterToPolygon(OGRSurface *poSurface) 222 : { 223 52257 : OGRTriangle *poTriangle = poSurface->toTriangle(); 224 52257 : OGRPolygon *poRet = new OGRPolygon(*poTriangle); 225 52257 : delete poTriangle; 226 52257 : return poRet; 227 : } 228 : 229 52257 : OGRSurfaceCasterToPolygon OGRTriangle::GetCasterToPolygon() const 230 : { 231 52257 : return OGRTriangle::CasterToPolygon; 232 : } 233 : 234 : /************************************************************************/ 235 : /* CastToPolygon() */ 236 : /************************************************************************/ 237 : 238 2 : OGRGeometry *OGRTriangle::CastToPolygon(OGRGeometry *poGeom) 239 : { 240 2 : OGRGeometry *poRet = new OGRPolygon(*(poGeom->toPolygon())); 241 2 : delete poGeom; 242 2 : return poRet; 243 : } 244 : 245 : //! @endcond