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 : * 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_p.h" 33 : #include "ogr_api.h" 34 : 35 : /************************************************************************/ 36 : /* OGRTriangulatedSurface() */ 37 : /************************************************************************/ 38 : 39 : /** 40 : * \brief Constructor. 41 : * 42 : */ 43 : 44 : OGRTriangulatedSurface::OGRTriangulatedSurface() = default; 45 : 46 : /************************************************************************/ 47 : /* OGRTriangulatedSurface( const OGRTriangulatedSurface& ) */ 48 : /************************************************************************/ 49 : 50 : /** 51 : * \brief Copy constructor. 52 : * 53 : */ 54 : 55 699 : OGRTriangulatedSurface::OGRTriangulatedSurface( 56 699 : const OGRTriangulatedSurface &other) 57 699 : : OGRPolyhedralSurface() 58 : { 59 699 : *this = other; 60 699 : } 61 : 62 : /************************************************************************/ 63 : /* ~OGRTriangulatedSurface() */ 64 : /************************************************************************/ 65 : 66 : /** 67 : * \brief Destructor 68 : * 69 : */ 70 : 71 : OGRTriangulatedSurface::~OGRTriangulatedSurface() = default; 72 : 73 : /************************************************************************/ 74 : /* operator=( const OGRTriangulatedSurface&) */ 75 : /************************************************************************/ 76 : 77 : /** 78 : * \brief Assignment operator. 79 : * 80 : */ 81 : 82 : OGRTriangulatedSurface & 83 704 : OGRTriangulatedSurface::operator=(const OGRTriangulatedSurface &other) 84 : { 85 704 : if (this != &other) 86 : { 87 : // We need to do it manually. We cannot rely on the = operator 88 : // of OGRPolyhedralSurface since it will be confused by a multipolygon 89 : // of triangles. 90 703 : OGRSurface::operator=(other); 91 703 : empty(); 92 703 : set3D(other.Is3D()); 93 703 : setMeasured(other.IsMeasured()); 94 703 : assignSpatialReference(other.getSpatialReference()); 95 1933 : for (int i = 0; i < other.oMP.nGeomCount; i++) 96 : { 97 1230 : OGRTriangulatedSurface::addGeometry(other.oMP.getGeometryRef(i)); 98 : } 99 : } 100 704 : return *this; 101 : } 102 : 103 : /************************************************************************/ 104 : /* clone() */ 105 : /************************************************************************/ 106 : 107 697 : OGRTriangulatedSurface *OGRTriangulatedSurface::clone() const 108 : 109 : { 110 697 : return new (std::nothrow) OGRTriangulatedSurface(*this); 111 : } 112 : 113 : /************************************************************************/ 114 : /* getGeometryName() */ 115 : /************************************************************************/ 116 : 117 : /** 118 : * \brief Returns the geometry name of the TriangulatedSurface 119 : * 120 : * @return "TIN" 121 : * 122 : */ 123 : 124 326 : const char *OGRTriangulatedSurface::getGeometryName() const 125 : { 126 326 : return "TIN"; 127 : } 128 : 129 : /************************************************************************/ 130 : /* getGeometryType() */ 131 : /************************************************************************/ 132 : 133 : /** 134 : * \brief Returns the WKB Type of TriangulatedSurface 135 : * 136 : */ 137 : 138 16974 : OGRwkbGeometryType OGRTriangulatedSurface::getGeometryType() const 139 : { 140 16974 : if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED)) 141 12843 : return wkbTINZM; 142 4131 : else if (flags & OGR_G_MEASURED) 143 4 : return wkbTINM; 144 4127 : else if (flags & OGR_G_3D) 145 4050 : return wkbTINZ; 146 : else 147 77 : return wkbTIN; 148 : } 149 : 150 : /************************************************************************/ 151 : /* isCompatibleSubType() */ 152 : /************************************************************************/ 153 : 154 : //! @cond Doxygen_Suppress 155 : OGRBoolean 156 17375 : OGRTriangulatedSurface::isCompatibleSubType(OGRwkbGeometryType eSubType) const 157 : { 158 17375 : return wkbFlatten(eSubType) == wkbTriangle; 159 : } 160 : 161 : //! @endcond 162 : 163 : /************************************************************************/ 164 : /* getSubGeometryName() */ 165 : /************************************************************************/ 166 : 167 : //! @cond Doxygen_Suppress 168 0 : const char *OGRTriangulatedSurface::getSubGeometryName() const 169 : { 170 0 : return "TRIANGLE"; 171 : } 172 : 173 : //! @endcond 174 : 175 : /************************************************************************/ 176 : /* getSubGeometryType() */ 177 : /************************************************************************/ 178 : 179 : //! @cond Doxygen_Suppress 180 624 : OGRwkbGeometryType OGRTriangulatedSurface::getSubGeometryType() const 181 : { 182 624 : return wkbTriangle; 183 : } 184 : 185 : //! @endcond 186 : 187 : /************************************************************************/ 188 : /* addGeometry() */ 189 : /************************************************************************/ 190 : 191 1234 : OGRErr OGRTriangulatedSurface::addGeometry(const OGRGeometry *poNewGeom) 192 : { 193 : // If the geometry is a polygon, check if it can be cast as a triangle 194 1234 : if (EQUAL(poNewGeom->getGeometryName(), "POLYGON")) 195 : { 196 2 : OGRErr eErr = OGRERR_FAILURE; 197 : OGRTriangle *poTriangle = 198 2 : new OGRTriangle(*(poNewGeom->toPolygon()), eErr); 199 2 : if (poTriangle != nullptr && eErr == OGRERR_NONE) 200 : { 201 1 : eErr = addGeometryDirectly(poTriangle); 202 : 203 1 : if (eErr != OGRERR_NONE) 204 0 : delete poTriangle; 205 : 206 1 : return eErr; 207 : } 208 : else 209 : { 210 1 : delete poTriangle; 211 1 : return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; 212 : } 213 : } 214 : 215 1232 : return OGRPolyhedralSurface::addGeometry(poNewGeom); 216 : } 217 : 218 : /************************************************************************/ 219 : /* GetCasterToMultiPolygon() */ 220 : /************************************************************************/ 221 : 222 : //! @cond Doxygen_Suppress 223 : OGRPolyhedralSurfaceCastToMultiPolygon 224 258 : OGRTriangulatedSurface::GetCasterToMultiPolygon() const 225 : { 226 258 : return OGRTriangulatedSurface::CastToMultiPolygonImpl; 227 : } 228 : 229 : /************************************************************************/ 230 : /* CastToMultiPolygon() */ 231 : /************************************************************************/ 232 : 233 : OGRMultiPolygon * 234 258 : OGRTriangulatedSurface::CastToMultiPolygonImpl(OGRPolyhedralSurface *poTS) 235 : { 236 258 : OGRMultiPolygon *poMultiPolygon = new OGRMultiPolygon(); 237 258 : poMultiPolygon->assignSpatialReference(poTS->getSpatialReference()); 238 : 239 738 : for (auto &&poSubGeom : *poTS) 240 : { 241 480 : OGRPolygon *poPolygon = OGRSurface::CastToPolygon(poSubGeom); 242 480 : poMultiPolygon->addGeometryDirectly(poPolygon); 243 480 : poSubGeom = nullptr; 244 : } 245 258 : delete poTS; 246 : 247 258 : return poMultiPolygon; 248 : } 249 : 250 : //! @endcond 251 : 252 : /************************************************************************/ 253 : /* CastToPolyhedralSurface() */ 254 : /************************************************************************/ 255 : 256 : /** 257 : * \brief Casts the OGRTriangulatedSurface to an OGRPolyhedralSurface 258 : * 259 : * The passed in geometry is consumed and a new one returned (or NULL in case 260 : * of failure) 261 : * 262 : * @param poTS the input geometry - ownership is passed to the method. 263 : * @return new geometry. 264 : */ 265 : 266 : OGRPolyhedralSurface * 267 1 : OGRTriangulatedSurface::CastToPolyhedralSurface(OGRTriangulatedSurface *poTS) 268 : { 269 1 : OGRPolyhedralSurface *poPS = new OGRPolyhedralSurface(); 270 1 : poPS->assignSpatialReference(poTS->getSpatialReference()); 271 2 : for (auto &&poSubGeom : *poTS) 272 : { 273 1 : OGRPolygon *poPolygon = OGRSurface::CastToPolygon(poSubGeom); 274 1 : poPS->oMP.addGeometryDirectly(poPolygon); 275 1 : poSubGeom = nullptr; 276 : } 277 1 : delete poTS; 278 1 : return poPS; 279 : }