Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: The OGRTriangulatedSurface 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_p.h" 16 : #include "ogr_api.h" 17 : 18 : /************************************************************************/ 19 : /* OGRTriangulatedSurface( const OGRTriangulatedSurface& ) */ 20 : /************************************************************************/ 21 : 22 : /** 23 : * \brief Copy constructor. 24 : * 25 : */ 26 : 27 1509 : OGRTriangulatedSurface::OGRTriangulatedSurface( 28 1509 : const OGRTriangulatedSurface &other) 29 1509 : : OGRPolyhedralSurface() 30 : { 31 1509 : *this = other; 32 1509 : } 33 : 34 : /************************************************************************/ 35 : /* operator=( const OGRTriangulatedSurface&) */ 36 : /************************************************************************/ 37 : 38 : /** 39 : * \brief Assignment operator. 40 : * 41 : */ 42 : 43 : OGRTriangulatedSurface & 44 1514 : OGRTriangulatedSurface::operator=(const OGRTriangulatedSurface &other) 45 : { 46 1514 : if (this != &other) 47 : { 48 : // We need to do it manually. We cannot rely on the = operator 49 : // of OGRPolyhedralSurface since it will be confused by a multipolygon 50 : // of triangles. 51 1513 : OGRSurface::operator=(other); 52 54629 : for (const auto *poPoly : other.oMP) 53 : { 54 53116 : OGRTriangulatedSurface::addGeometry(poPoly); 55 : } 56 : } 57 1514 : return *this; 58 : } 59 : 60 : /************************************************************************/ 61 : /* clone() */ 62 : /************************************************************************/ 63 : 64 1505 : OGRTriangulatedSurface *OGRTriangulatedSurface::clone() const 65 : 66 : { 67 1505 : return new (std::nothrow) OGRTriangulatedSurface(*this); 68 : } 69 : 70 : /************************************************************************/ 71 : /* getGeometryName() */ 72 : /************************************************************************/ 73 : 74 : /** 75 : * \brief Returns the geometry name of the TriangulatedSurface 76 : * 77 : * @return "TIN" 78 : * 79 : */ 80 : 81 331 : const char *OGRTriangulatedSurface::getGeometryName() const 82 : { 83 331 : return "TIN"; 84 : } 85 : 86 : /************************************************************************/ 87 : /* getGeometryType() */ 88 : /************************************************************************/ 89 : 90 : /** 91 : * \brief Returns the WKB Type of TriangulatedSurface 92 : * 93 : */ 94 : 95 23300 : OGRwkbGeometryType OGRTriangulatedSurface::getGeometryType() const 96 : { 97 23300 : if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED)) 98 12843 : return wkbTINZM; 99 10457 : else if (flags & OGR_G_MEASURED) 100 4 : return wkbTINM; 101 10453 : else if (flags & OGR_G_3D) 102 10032 : return wkbTINZ; 103 : else 104 421 : return wkbTIN; 105 : } 106 : 107 : /************************************************************************/ 108 : /* isCompatibleSubType() */ 109 : /************************************************************************/ 110 : 111 : //! @cond Doxygen_Suppress 112 : OGRBoolean 113 2607210 : OGRTriangulatedSurface::isCompatibleSubType(OGRwkbGeometryType eSubType) const 114 : { 115 2607210 : return wkbFlatten(eSubType) == wkbTriangle; 116 : } 117 : 118 : //! @endcond 119 : 120 : /************************************************************************/ 121 : /* getSubGeometryName() */ 122 : /************************************************************************/ 123 : 124 : //! @cond Doxygen_Suppress 125 0 : const char *OGRTriangulatedSurface::getSubGeometryName() const 126 : { 127 0 : return "TRIANGLE"; 128 : } 129 : 130 : //! @endcond 131 : 132 : /************************************************************************/ 133 : /* getSubGeometryType() */ 134 : /************************************************************************/ 135 : 136 : //! @cond Doxygen_Suppress 137 626 : OGRwkbGeometryType OGRTriangulatedSurface::getSubGeometryType() const 138 : { 139 626 : return wkbTriangle; 140 : } 141 : 142 : //! @endcond 143 : 144 : /************************************************************************/ 145 : /* addGeometry() */ 146 : /************************************************************************/ 147 : 148 1296140 : OGRErr OGRTriangulatedSurface::addGeometry(const OGRGeometry *poNewGeom) 149 : { 150 : // If the geometry is a polygon, check if it can be cast as a triangle 151 1296140 : if (EQUAL(poNewGeom->getGeometryName(), "POLYGON")) 152 : { 153 2 : OGRErr eErr = OGRERR_FAILURE; 154 : OGRTriangle *poTriangle = 155 2 : new OGRTriangle(*(poNewGeom->toPolygon()), eErr); 156 2 : if (poTriangle != nullptr && eErr == OGRERR_NONE) 157 : { 158 1 : eErr = addGeometryDirectly(poTriangle); 159 : 160 1 : if (eErr != OGRERR_NONE) 161 0 : delete poTriangle; 162 : 163 1 : return eErr; 164 : } 165 : else 166 : { 167 1 : delete poTriangle; 168 1 : return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; 169 : } 170 : } 171 : 172 1296140 : return OGRPolyhedralSurface::addGeometry(poNewGeom); 173 : } 174 : 175 : /************************************************************************/ 176 : /* GetCasterToMultiPolygon() */ 177 : /************************************************************************/ 178 : 179 : //! @cond Doxygen_Suppress 180 : OGRPolyhedralSurfaceCastToMultiPolygon 181 1054 : OGRTriangulatedSurface::GetCasterToMultiPolygon() const 182 : { 183 1054 : return OGRTriangulatedSurface::CastToMultiPolygonImpl; 184 : } 185 : 186 : /************************************************************************/ 187 : /* CastToMultiPolygon() */ 188 : /************************************************************************/ 189 : 190 : OGRMultiPolygon * 191 1054 : OGRTriangulatedSurface::CastToMultiPolygonImpl(OGRPolyhedralSurface *poTS) 192 : { 193 1054 : OGRMultiPolygon *poMultiPolygon = new OGRMultiPolygon(); 194 1054 : poMultiPolygon->assignSpatialReference(poTS->getSpatialReference()); 195 : 196 53304 : for (auto &&poSubGeom : *poTS) 197 : { 198 52250 : OGRPolygon *poPolygon = OGRSurface::CastToPolygon(poSubGeom); 199 52250 : poMultiPolygon->addGeometryDirectly(poPolygon); 200 52250 : poSubGeom = nullptr; 201 : } 202 1054 : delete poTS; 203 : 204 1054 : return poMultiPolygon; 205 : } 206 : 207 : //! @endcond 208 : 209 : /************************************************************************/ 210 : /* CastToPolyhedralSurface() */ 211 : /************************************************************************/ 212 : 213 : /** 214 : * \brief Casts the OGRTriangulatedSurface to an OGRPolyhedralSurface 215 : * 216 : * The passed in geometry is consumed and a new one returned (or NULL in case 217 : * of failure) 218 : * 219 : * @param poTS the input geometry - ownership is passed to the method. 220 : * @return new geometry. 221 : */ 222 : 223 : OGRPolyhedralSurface * 224 1 : OGRTriangulatedSurface::CastToPolyhedralSurface(OGRTriangulatedSurface *poTS) 225 : { 226 1 : OGRPolyhedralSurface *poPS = new OGRPolyhedralSurface(); 227 1 : poPS->assignSpatialReference(poTS->getSpatialReference()); 228 2 : for (auto &&poSubGeom : *poTS) 229 : { 230 1 : OGRPolygon *poPolygon = OGRSurface::CastToPolygon(poSubGeom); 231 1 : poPS->oMP.addGeometryDirectly(poPolygon); 232 1 : poSubGeom = nullptr; 233 : } 234 1 : delete poTS; 235 1 : return poPS; 236 : }