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