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