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 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included
19 * in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
28 ****************************************************************************/
29
30 #include "cpl_port.h"
31 #include "ogr_geometry.h"
32
33 #include "ogr_api.h"
34 #include "ogr_core.h"
35 #include "ogr_p.h"
36
37 CPL_CVSID("$Id: ogrmultipolygon.cpp 464e5bd63b59963407c8adc30fcbd5899731eddc 2021-03-16 15:06:30 +0100 Even Rouault $")
38
39 /************************************************************************/
40 /* OGRMultiPolygon() */
41 /************************************************************************/
42
43 /**
44 * \brief Create an empty multi polygon collection.
45 */
46
47 OGRMultiPolygon::OGRMultiPolygon() = default;
48
49 /************************************************************************/
50 /* OGRMultiPolygon( const OGRMultiPolygon& ) */
51 /************************************************************************/
52
53 /**
54 * \brief Copy constructor.
55 *
56 * Note: before GDAL 2.1, only the default implementation of the constructor
57 * existed, which could be unsafe to use.
58 *
59 * @since GDAL 2.1
60 */
61
62 OGRMultiPolygon::OGRMultiPolygon( const OGRMultiPolygon& ) = default;
63
64 /************************************************************************/
65 /* ~OGRMultiPolygon() */
66 /************************************************************************/
67
68 OGRMultiPolygon::~OGRMultiPolygon() = default;
69
70 /************************************************************************/
71 /* operator=( const OGRMultiPolygon&) */
72 /************************************************************************/
73
74 /**
75 * \brief Assignment operator.
76 *
77 * Note: before GDAL 2.1, only the default implementation of the operator
78 * existed, which could be unsafe to use.
79 *
80 * @since GDAL 2.1
81 */
82
operator =(const OGRMultiPolygon & other)83 OGRMultiPolygon& OGRMultiPolygon::operator=( const OGRMultiPolygon& other )
84 {
85 if( this != &other)
86 {
87 OGRMultiSurface::operator=( other );
88 }
89 return *this;
90 }
91
92 /************************************************************************/
93 /* clone() */
94 /************************************************************************/
95
clone() const96 OGRMultiPolygon *OGRMultiPolygon::clone() const
97
98 {
99 return new (std::nothrow) OGRMultiPolygon(*this);
100 }
101
102 /************************************************************************/
103 /* getGeometryType() */
104 /************************************************************************/
105
getGeometryType() const106 OGRwkbGeometryType OGRMultiPolygon::getGeometryType() const
107
108 {
109 if( (flags & OGR_G_3D) && (flags & OGR_G_MEASURED) )
110 return wkbMultiPolygonZM;
111 else if( flags & OGR_G_MEASURED )
112 return wkbMultiPolygonM;
113 else if( flags & OGR_G_3D )
114 return wkbMultiPolygon25D;
115 else
116 return wkbMultiPolygon;
117 }
118
119 /************************************************************************/
120 /* getGeometryName() */
121 /************************************************************************/
122
getGeometryName() const123 const char * OGRMultiPolygon::getGeometryName() const
124
125 {
126 return "MULTIPOLYGON";
127 }
128
129 /************************************************************************/
130 /* isCompatibleSubType() */
131 /************************************************************************/
132
133 OGRBoolean
isCompatibleSubType(OGRwkbGeometryType eGeomType) const134 OGRMultiPolygon::isCompatibleSubType( OGRwkbGeometryType eGeomType ) const
135 {
136 return wkbFlatten(eGeomType) == wkbPolygon;
137 }
138
139 /************************************************************************/
140 /* exportToWkt() */
141 /************************************************************************/
142
exportToWkt(const OGRWktOptions & opts,OGRErr * err) const143 std::string OGRMultiPolygon::exportToWkt(const OGRWktOptions& opts, OGRErr *err) const
144 {
145 return exportToWktInternal(opts, err, "POLYGON");
146 }
147
148 /************************************************************************/
149 /* hasCurveGeometry() */
150 /************************************************************************/
151
152 OGRBoolean
hasCurveGeometry(int) const153 OGRMultiPolygon::hasCurveGeometry( int /* bLookForNonLinear */ ) const
154 {
155 return FALSE;
156 }
157
158 /************************************************************************/
159 /* CastToMultiSurface() */
160 /************************************************************************/
161
162 /**
163 * \brief Cast to multisurface.
164 *
165 * The passed in geometry is consumed and a new one returned .
166 *
167 * @param poMP the input geometry - ownership is passed to the method.
168 * @return new geometry.
169 */
170
CastToMultiSurface(OGRMultiPolygon * poMP)171 OGRMultiSurface* OGRMultiPolygon::CastToMultiSurface( OGRMultiPolygon* poMP )
172 {
173 OGRMultiSurface* poMS = new OGRMultiSurface();
174 TransferMembersAndDestroy(poMP, poMS);
175 return poMS;
176 }
177
178
179 /************************************************************************/
180 /* _addGeometryWithExpectedSubGeometryType() */
181 /* Only to be used in conjunction with OGRPolyhedralSurface. */
182 /* DO NOT USE IT ELSEWHERE. */
183 /************************************************************************/
184
185 //! @cond Doxygen_Suppress
_addGeometryWithExpectedSubGeometryType(const OGRGeometry * poNewGeom,OGRwkbGeometryType eSubGeometryType)186 OGRErr OGRMultiPolygon::_addGeometryWithExpectedSubGeometryType(
187 const OGRGeometry * poNewGeom,
188 OGRwkbGeometryType eSubGeometryType )
189
190 {
191 OGRGeometry *poClone = poNewGeom->clone();
192 OGRErr eErr;
193
194 if( poClone == nullptr )
195 return OGRERR_FAILURE;
196 eErr = _addGeometryDirectlyWithExpectedSubGeometryType( poClone, eSubGeometryType );
197 if( eErr != OGRERR_NONE )
198 delete poClone;
199
200 return eErr;
201 }
202 //! @endcond
203
204 /************************************************************************/
205 /* _addGeometryDirectlyWithExpectedSubGeometryType() */
206 /* Only to be used in conjunction with OGRPolyhedralSurface. */
207 /* DO NOT USE IT ELSEWHERE. */
208 /************************************************************************/
209
210 //! @cond Doxygen_Suppress
_addGeometryDirectlyWithExpectedSubGeometryType(OGRGeometry * poNewGeom,OGRwkbGeometryType eSubGeometryType)211 OGRErr OGRMultiPolygon::_addGeometryDirectlyWithExpectedSubGeometryType(
212 OGRGeometry * poNewGeom,
213 OGRwkbGeometryType eSubGeometryType )
214 {
215 if ( wkbFlatten(poNewGeom->getGeometryType()) != eSubGeometryType)
216 return OGRERR_UNSUPPORTED_GEOMETRY_TYPE;
217
218 HomogenizeDimensionalityWith(poNewGeom);
219
220 OGRGeometry** papoNewGeoms = static_cast<OGRGeometry **>(
221 VSI_REALLOC_VERBOSE( papoGeoms, sizeof(void*) * (nGeomCount+1) ));
222 if( papoNewGeoms == nullptr )
223 return OGRERR_FAILURE;
224
225 papoGeoms = papoNewGeoms;
226 papoGeoms[nGeomCount] = poNewGeom;
227 nGeomCount++;
228
229 return OGRERR_NONE;
230 }
231 //! @endcond
232
233