Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: OpenGIS Simple Features Reference Implementation 4 : * Purpose: The OGRMultiPolygon class. 5 : * Author: Frank Warmerdam, warmerdam@pobox.com 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 1999, Frank Warmerdam 9 : * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com> 10 : * 11 : * SPDX-License-Identifier: MIT 12 : ****************************************************************************/ 13 : 14 : #include "cpl_port.h" 15 : #include "ogr_geometry.h" 16 : 17 : #include "ogr_api.h" 18 : #include "ogr_core.h" 19 : #include "ogr_p.h" 20 : 21 : /************************************************************************/ 22 : /* OGRMultiPolygon( const OGRMultiPolygon& ) */ 23 : /************************************************************************/ 24 : 25 : /** 26 : * \brief Copy constructor. 27 : * 28 : * Note: before GDAL 2.1, only the default implementation of the constructor 29 : * existed, which could be unsafe to use. 30 : * 31 : * @since GDAL 2.1 32 : */ 33 : 34 : OGRMultiPolygon::OGRMultiPolygon(const OGRMultiPolygon &) = default; 35 : 36 : /************************************************************************/ 37 : /* operator=( const OGRMultiPolygon&) */ 38 : /************************************************************************/ 39 : 40 : /** 41 : * \brief Assignment operator. 42 : * 43 : * Note: before GDAL 2.1, only the default implementation of the operator 44 : * existed, which could be unsafe to use. 45 : * 46 : * @since GDAL 2.1 47 : */ 48 : 49 9 : OGRMultiPolygon &OGRMultiPolygon::operator=(const OGRMultiPolygon &other) 50 : { 51 9 : if (this != &other) 52 : { 53 8 : OGRMultiSurface::operator=(other); 54 : } 55 9 : return *this; 56 : } 57 : 58 : /************************************************************************/ 59 : /* clone() */ 60 : /************************************************************************/ 61 : 62 17060 : OGRMultiPolygon *OGRMultiPolygon::clone() const 63 : 64 : { 65 17060 : return new (std::nothrow) OGRMultiPolygon(*this); 66 : } 67 : 68 : /************************************************************************/ 69 : /* getGeometryType() */ 70 : /************************************************************************/ 71 : 72 49495 : OGRwkbGeometryType OGRMultiPolygon::getGeometryType() const 73 : 74 : { 75 49495 : if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED)) 76 3256 : return wkbMultiPolygonZM; 77 46239 : else if (flags & OGR_G_MEASURED) 78 345 : return wkbMultiPolygonM; 79 45894 : else if (flags & OGR_G_3D) 80 7480 : return wkbMultiPolygon25D; 81 : else 82 38414 : return wkbMultiPolygon; 83 : } 84 : 85 : /************************************************************************/ 86 : /* getGeometryName() */ 87 : /************************************************************************/ 88 : 89 3107 : const char *OGRMultiPolygon::getGeometryName() const 90 : 91 : { 92 3107 : return "MULTIPOLYGON"; 93 : } 94 : 95 : /************************************************************************/ 96 : /* isCompatibleSubType() */ 97 : /************************************************************************/ 98 : 99 : OGRBoolean 100 126358 : OGRMultiPolygon::isCompatibleSubType(OGRwkbGeometryType eGeomType) const 101 : { 102 126358 : return wkbFlatten(eGeomType) == wkbPolygon; 103 : } 104 : 105 : /************************************************************************/ 106 : /* importFromWkb() */ 107 : /************************************************************************/ 108 : 109 2075 : OGRErr OGRMultiPolygon::importFromWkb(const unsigned char *pabyData, 110 : size_t nSize, OGRwkbVariant eWkbVariant, 111 : size_t &nBytesConsumedOut) 112 : 113 : { 114 2075 : if (nGeomCount == 1 && nSize >= 9 && flags == 0 && pabyData[0] == wkbNDR && 115 3 : memcmp(pabyData + 1, "\x06\x00\x00\x00\x01\x00\x00\x00", 8) == 0) 116 : { 117 : // Optimization to import a Intel-ordered 1-part multipolyon on 118 : // top of an existing 1-part multipolygon, to save dynamic memory 119 : // allocations. 120 3 : const size_t nDataOffset = 9; 121 3 : size_t nBytesConsumedPolygon = 0; 122 : // cppcheck-suppress knownConditionTrueFalse 123 3 : if (nSize != static_cast<size_t>(-1)) 124 2 : nSize -= nDataOffset; 125 : OGRErr eErr = 126 3 : cpl::down_cast<OGRPolygon *>(papoGeoms[0]) 127 3 : ->OGRPolygon::importFromWkb(pabyData + nDataOffset, nSize, 128 : eWkbVariant, nBytesConsumedPolygon); 129 3 : if (eErr == OGRERR_NONE) 130 : { 131 2 : nBytesConsumedOut = nDataOffset + nBytesConsumedPolygon; 132 : } 133 : else 134 : { 135 1 : empty(); 136 : } 137 3 : return eErr; 138 : } 139 : 140 2072 : return OGRGeometryCollection::importFromWkbInternal( 141 2072 : pabyData, nSize, /*nRecLevel=*/0, eWkbVariant, nBytesConsumedOut); 142 : } 143 : 144 : /************************************************************************/ 145 : /* exportToWkt() */ 146 : /************************************************************************/ 147 : 148 500 : std::string OGRMultiPolygon::exportToWkt(const OGRWktOptions &opts, 149 : OGRErr *err) const 150 : { 151 500 : return exportToWktInternal(opts, err, "POLYGON"); 152 : } 153 : 154 : /************************************************************************/ 155 : /* hasCurveGeometry() */ 156 : /************************************************************************/ 157 : 158 6631 : OGRBoolean OGRMultiPolygon::hasCurveGeometry(int /* bLookForNonLinear */) const 159 : { 160 6631 : return FALSE; 161 : } 162 : 163 : /************************************************************************/ 164 : /* CastToMultiSurface() */ 165 : /************************************************************************/ 166 : 167 : /** 168 : * \brief Cast to multisurface. 169 : * 170 : * The passed in geometry is consumed and a new one returned . 171 : * 172 : * @param poMP the input geometry - ownership is passed to the method. 173 : * @return new geometry. 174 : */ 175 : 176 15 : OGRMultiSurface *OGRMultiPolygon::CastToMultiSurface(OGRMultiPolygon *poMP) 177 : { 178 15 : OGRMultiSurface *poMS = new OGRMultiSurface(); 179 15 : TransferMembersAndDestroy(poMP, poMS); 180 15 : return poMS; 181 : } 182 : 183 : /************************************************************************/ 184 : /* _addGeometryWithExpectedSubGeometryType() */ 185 : /* Only to be used in conjunction with OGRPolyhedralSurface. */ 186 : /* DO NOT USE IT ELSEWHERE. */ 187 : /************************************************************************/ 188 : 189 : //! @cond Doxygen_Suppress 190 0 : OGRErr OGRMultiPolygon::_addGeometryWithExpectedSubGeometryType( 191 : const OGRGeometry *poNewGeom, OGRwkbGeometryType eSubGeometryType) 192 : 193 : { 194 0 : OGRGeometry *poClone = poNewGeom->clone(); 195 : OGRErr eErr; 196 : 197 0 : if (poClone == nullptr) 198 0 : return OGRERR_FAILURE; 199 0 : eErr = _addGeometryDirectlyWithExpectedSubGeometryType(poClone, 200 : eSubGeometryType); 201 0 : if (eErr != OGRERR_NONE) 202 0 : delete poClone; 203 : 204 0 : return eErr; 205 : } 206 : 207 : //! @endcond 208 : 209 : /************************************************************************/ 210 : /* _addGeometryDirectlyWithExpectedSubGeometryType() */ 211 : /* Only to be used in conjunction with OGRPolyhedralSurface. */ 212 : /* DO NOT USE IT ELSEWHERE. */ 213 : /************************************************************************/ 214 : 215 : //! @cond Doxygen_Suppress 216 424 : OGRErr OGRMultiPolygon::_addGeometryDirectlyWithExpectedSubGeometryType( 217 : OGRGeometry *poNewGeom, OGRwkbGeometryType eSubGeometryType) 218 : { 219 424 : if (wkbFlatten(poNewGeom->getGeometryType()) != eSubGeometryType) 220 0 : return OGRERR_UNSUPPORTED_GEOMETRY_TYPE; 221 : 222 424 : HomogenizeDimensionalityWith(poNewGeom); 223 : 224 : OGRGeometry **papoNewGeoms = static_cast<OGRGeometry **>( 225 424 : VSI_REALLOC_VERBOSE(papoGeoms, sizeof(void *) * (nGeomCount + 1))); 226 424 : if (papoNewGeoms == nullptr) 227 0 : return OGRERR_FAILURE; 228 : 229 424 : papoGeoms = papoNewGeoms; 230 424 : papoGeoms[nGeomCount] = poNewGeom; 231 424 : nGeomCount++; 232 : 233 424 : return OGRERR_NONE; 234 : } 235 : 236 : //! @endcond