1 /******************************************************************************
2  * $Id: ogr_geometry.h 840a7ef3e792f283aefb26a79a9d3507c27664a5 2021-04-21 12:06:27 +0200 Even Rouault $
3  *
4  * Project:  OpenGIS Simple Features Reference Implementation
5  * Purpose:  Classes for manipulating simple features that is not specific
6  *           to a particular interface technology.
7  * Author:   Frank Warmerdam, warmerdam@pobox.com
8  *
9  ******************************************************************************
10  * Copyright (c) 1999, Frank Warmerdam
11  * Copyright (c) 2008-2014, Even Rouault <even dot rouault at spatialys.com>
12  *
13  * Permission is hereby granted, free of charge, to any person obtaining a
14  * copy of this software and associated documentation files (the "Software"),
15  * to deal in the Software without restriction, including without limitation
16  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17  * and/or sell copies of the Software, and to permit persons to whom the
18  * Software is furnished to do so, subject to the following conditions:
19  *
20  * The above copyright notice and this permission notice shall be included
21  * in all copies or substantial portions of the Software.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29  * DEALINGS IN THE SOFTWARE.
30  ****************************************************************************/
31 
32 #ifndef OGR_GEOMETRY_H_INCLUDED
33 #define OGR_GEOMETRY_H_INCLUDED
34 
35 #include "cpl_conv.h"
36 #include "cpl_json.h"
37 #include "ogr_core.h"
38 #include "ogr_spatialref.h"
39 
40 #include <cmath>
41 #include <memory>
42 
43 /**
44  * \file ogr_geometry.h
45  *
46  * Simple feature geometry classes.
47  */
48 
49 /*! @cond Doxygen_Suppress */
50 #ifndef DEFINEH_OGRGeometryH
51 #define DEFINEH_OGRGeometryH
52 #ifdef DEBUG
53 typedef struct OGRGeometryHS *OGRGeometryH;
54 #else
55 typedef void *OGRGeometryH;
56 #endif
57 #endif /* DEFINEH_OGRGeometryH */
58 /*! @endcond */
59 
60 /// WKT Output formatting options.
61 enum class OGRWktFormat
62 {
63     F,        ///< F-type formatting.
64     G,        ///< G-type formatting.
65     Default   ///< Format as F when abs(value) < 1, otherwise as G.
66 };
67 
68 /// Options for formatting WKT output
69 struct CPL_DLL OGRWktOptions
70 {
71 public:
72     /// Type of WKT output to produce.
73     OGRwkbVariant variant;
74     /// Precision of output.  Interpretation depends on \c format.
75     int precision;
76     /// Whether GDAL-special rounding should be applied.
77     bool round;
78     /// Formatting type.
79     OGRWktFormat format;
80 
81     /// Constructor.
OGRWktOptionsOGRWktOptions82     OGRWktOptions() : variant(wkbVariantOldOgc), precision(15), round(true),
83         format(OGRWktFormat::Default)
84     {
85         static int defPrecision = getDefaultPrecision();
86         static bool defRound = getDefaultRound();
87 
88         precision = defPrecision;
89         round = defRound;
90     }
91 
92     /// Copy constructor
93     OGRWktOptions(const OGRWktOptions&) = default;
94 
95 private:
96     static int getDefaultPrecision();
97     static bool getDefaultRound();
98 };
99 
100 /**
101  * Simple container for a position.
102  */
103 class OGRRawPoint
104 {
105   public:
106           /** Constructor */
OGRRawPoint()107           OGRRawPoint() : x(0.0), y(0.0) {}
108 
109           /** Constructor */
OGRRawPoint(double xIn,double yIn)110           OGRRawPoint(double xIn, double yIn) : x(xIn), y(yIn) {}
111 
112     /** x */
113     double      x;
114     /** y */
115     double      y;
116 };
117 
118 /** GEOS geometry type */
119 typedef struct GEOSGeom_t *GEOSGeom;
120 /** GEOS context handle type */
121 typedef struct GEOSContextHandle_HS *GEOSContextHandle_t;
122 /** SFCGAL geometry type */
123 typedef void sfcgal_geometry_t;
124 
125 class OGRPoint;
126 class OGRCurve;
127 class OGRCompoundCurve;
128 class OGRSimpleCurve;
129 class OGRLinearRing;
130 class OGRLineString;
131 class OGRCircularString;
132 class OGRSurface;
133 class OGRCurvePolygon;
134 class OGRPolygon;
135 class OGRMultiPoint;
136 class OGRMultiSurface;
137 class OGRMultiPolygon;
138 class OGRMultiCurve;
139 class OGRMultiLineString;
140 class OGRGeometryCollection;
141 class OGRTriangle;
142 class OGRPolyhedralSurface;
143 class OGRTriangulatedSurface;
144 
145 //! @cond Doxygen_Suppress
146 typedef OGRLineString* (*OGRCurveCasterToLineString)(OGRCurve*);
147 typedef OGRLinearRing* (*OGRCurveCasterToLinearRing)(OGRCurve*);
148 
149 typedef OGRPolygon*      (*OGRSurfaceCasterToPolygon)(OGRSurface*);
150 typedef OGRCurvePolygon* (*OGRSurfaceCasterToCurvePolygon)(OGRSurface*);
151 typedef OGRMultiPolygon* (*OGRPolyhedralSurfaceCastToMultiPolygon)(OGRPolyhedralSurface*);
152 //! @endcond
153 
154 /** OGRGeometry visitor interface.
155  * @since GDAL 2.3
156  */
157 class CPL_DLL IOGRGeometryVisitor
158 {
159     public:
160         /** Destructor/ */
161         virtual ~IOGRGeometryVisitor() = default;
162 
163         /** Visit OGRPoint. */
164         virtual void visit(OGRPoint*) = 0;
165         /** Visit OGRLineString. */
166         virtual void visit(OGRLineString*) = 0;
167         /** Visit OGRLinearRing. */
168         virtual void visit(OGRLinearRing*) = 0;
169         /** Visit OGRPolygon. */
170         virtual void visit(OGRPolygon*) = 0;
171         /** Visit OGRMultiPoint. */
172         virtual void visit(OGRMultiPoint*) = 0;
173         /** Visit OGRMultiLineString. */
174         virtual void visit(OGRMultiLineString*) = 0;
175         /** Visit OGRMultiPolygon. */
176         virtual void visit(OGRMultiPolygon*) = 0;
177         /** Visit OGRGeometryCollection. */
178         virtual void visit(OGRGeometryCollection*) = 0;
179         /** Visit OGRCircularString. */
180         virtual void visit(OGRCircularString*) = 0;
181         /** Visit OGRCompoundCurve. */
182         virtual void visit(OGRCompoundCurve*) = 0;
183         /** Visit OGRCurvePolygon. */
184         virtual void visit(OGRCurvePolygon*) = 0;
185         /** Visit OGRMultiCurve. */
186         virtual void visit(OGRMultiCurve*) = 0;
187         /** Visit OGRMultiSurface. */
188         virtual void visit(OGRMultiSurface*) = 0;
189         /** Visit OGRTriangle. */
190         virtual void visit(OGRTriangle*) = 0;
191         /** Visit OGRPolyhedralSurface. */
192         virtual void visit(OGRPolyhedralSurface*) = 0;
193         /** Visit OGRTriangulatedSurface. */
194         virtual void visit(OGRTriangulatedSurface*) = 0;
195 };
196 
197 /** OGRGeometry visitor default implementation.
198  *
199  * This default implementation will recurse down to calling
200  * visit(OGRPoint*) on each point.
201  *
202  * @since GDAL 2.3
203  */
204 class CPL_DLL OGRDefaultGeometryVisitor: public IOGRGeometryVisitor
205 {
206         void _visit(OGRSimpleCurve* poGeom);
207 
208     public:
209 
visit(OGRPoint *)210         void visit(OGRPoint*) override {}
211         void visit(OGRLineString*) override;
212         void visit(OGRLinearRing*) override;
213         void visit(OGRPolygon*) override;
214         void visit(OGRMultiPoint*) override;
215         void visit(OGRMultiLineString*) override;
216         void visit(OGRMultiPolygon*) override;
217         void visit(OGRGeometryCollection*) override;
218         void visit(OGRCircularString*) override;
219         void visit(OGRCompoundCurve*) override;
220         void visit(OGRCurvePolygon*) override;
221         void visit(OGRMultiCurve*) override;
222         void visit(OGRMultiSurface*) override;
223         void visit(OGRTriangle*) override;
224         void visit(OGRPolyhedralSurface*) override;
225         void visit(OGRTriangulatedSurface*) override;
226 };
227 
228 /** OGRGeometry visitor interface.
229  * @since GDAL 2.3
230  */
231 class CPL_DLL IOGRConstGeometryVisitor
232 {
233     public:
234         /** Destructor/ */
235         virtual ~IOGRConstGeometryVisitor() = default;
236 
237         /** Visit OGRPoint. */
238         virtual void visit(const OGRPoint*) = 0;
239         /** Visit OGRLineString. */
240         virtual void visit(const OGRLineString*) = 0;
241         /** Visit OGRLinearRing. */
242         virtual void visit(const OGRLinearRing*) = 0;
243         /** Visit OGRPolygon. */
244         virtual void visit(const OGRPolygon*) = 0;
245         /** Visit OGRMultiPoint. */
246         virtual void visit(const OGRMultiPoint*) = 0;
247         /** Visit OGRMultiLineString. */
248         virtual void visit(const OGRMultiLineString*) = 0;
249         /** Visit OGRMultiPolygon. */
250         virtual void visit(const OGRMultiPolygon*) = 0;
251         /** Visit OGRGeometryCollection. */
252         virtual void visit(const OGRGeometryCollection*) = 0;
253         /** Visit OGRCircularString. */
254         virtual void visit(const OGRCircularString*) = 0;
255         /** Visit OGRCompoundCurve. */
256         virtual void visit(const OGRCompoundCurve*) = 0;
257         /** Visit OGRCurvePolygon. */
258         virtual void visit(const OGRCurvePolygon*) = 0;
259         /** Visit OGRMultiCurve. */
260         virtual void visit(const OGRMultiCurve*) = 0;
261         /** Visit OGRMultiSurface. */
262         virtual void visit(const OGRMultiSurface*) = 0;
263         /** Visit OGRTriangle. */
264         virtual void visit(const OGRTriangle*) = 0;
265         /** Visit OGRPolyhedralSurface. */
266         virtual void visit(const OGRPolyhedralSurface*) = 0;
267         /** Visit OGRTriangulatedSurface. */
268         virtual void visit(const OGRTriangulatedSurface*) = 0;
269 };
270 
271 /** OGRGeometry visitor default implementation.
272  *
273  * This default implementation will recurse down to calling
274  * visit(const OGRPoint*) on each point.
275  *
276  * @since GDAL 2.3
277  */
278 class CPL_DLL OGRDefaultConstGeometryVisitor: public IOGRConstGeometryVisitor
279 {
280         void _visit(const OGRSimpleCurve* poGeom);
281 
282     public:
283 
visit(const OGRPoint *)284         void visit(const OGRPoint*) override {}
285         void visit(const OGRLineString*) override;
286         void visit(const OGRLinearRing*) override;
287         void visit(const OGRPolygon*) override;
288         void visit(const OGRMultiPoint*) override;
289         void visit(const OGRMultiLineString*) override;
290         void visit(const OGRMultiPolygon*) override;
291         void visit(const OGRGeometryCollection*) override;
292         void visit(const OGRCircularString*) override;
293         void visit(const OGRCompoundCurve*) override;
294         void visit(const OGRCurvePolygon*) override;
295         void visit(const OGRMultiCurve*) override;
296         void visit(const OGRMultiSurface*) override;
297         void visit(const OGRTriangle*) override;
298         void visit(const OGRPolyhedralSurface*) override;
299         void visit(const OGRTriangulatedSurface*) override;
300 };
301 
302 /************************************************************************/
303 /*                             OGRGeometry                              */
304 /************************************************************************/
305 
306 /**
307  * Abstract base class for all geometry classes.
308  *
309  * Some spatial analysis methods require that OGR is built on the GEOS library
310  * to work properly. The precise meaning of methods that describe spatial
311  * relationships between geometries is described in the SFCOM, or other simple
312  * features interface specifications, like "OpenGIS® Implementation
313  * Specification for Geographic information - Simple feature access - Part 1:
314  * Common architecture":
315  * <a href="http://www.opengeospatial.org/standards/sfa">OGC 06-103r4</a>
316  *
317  * In GDAL 2.0, the hierarchy of classes has been extended with
318  * <a href="https://portal.opengeospatial.org/files/?artifact_id=32024">
319  * (working draft) ISO SQL/MM Part 3 (ISO/IEC 13249-3)</a> curve geometries :
320  * CIRCULARSTRING (OGRCircularString), COMPOUNDCURVE (OGRCompoundCurve),
321  * CURVEPOLYGON (OGRCurvePolygon), MULTICURVE (OGRMultiCurve) and
322  * MULTISURFACE (OGRMultiSurface).
323  *
324  */
325 
326 class CPL_DLL OGRGeometry
327 {
328   private:
329     OGRSpatialReference * poSRS = nullptr;                // may be NULL
330 
331   protected:
332 //! @cond Doxygen_Suppress
333     friend class OGRCurveCollection;
334 
335     unsigned int flags = 0;
336 
337     OGRErr       importPreambleFromWkt( const char ** ppszInput,
338                                          int* pbHasZ, int* pbHasM,
339                                          bool* pbIsEmpty );
340     OGRErr       importCurveCollectionFromWkt(
341                      const char ** ppszInput,
342                      int bAllowEmptyComponent,
343                      int bAllowLineString,
344                      int bAllowCurve,
345                      int bAllowCompoundCurve,
346                      OGRErr (*pfnAddCurveDirectly)(OGRGeometry* poSelf,
347                                                    OGRCurve* poCurve) );
348     OGRErr       importPreambleFromWkb( const unsigned char * pabyData,
349                                          size_t nSize,
350                                          OGRwkbByteOrder& eByteOrder,
351                                          OGRwkbVariant eWkbVariant );
352     OGRErr       importPreambleOfCollectionFromWkb(
353                      const unsigned char * pabyData,
354                      size_t& nSize,
355                      size_t& nDataOffset,
356                      OGRwkbByteOrder& eByteOrder,
357                      size_t nMinSubGeomSize,
358                      int& nGeomCount,
359                      OGRwkbVariant eWkbVariant );
360     OGRErr       PointOnSurfaceInternal( OGRPoint * poPoint ) const;
361     OGRBoolean   IsSFCGALCompatible() const;
362 
363     void         HomogenizeDimensionalityWith( OGRGeometry* poOtherGeom );
364     std::string  wktTypeString(OGRwkbVariant variant) const;
365 
366 //! @endcond
367 
368   public:
369 
370 /************************************************************************/
371 /*                   Bit flags for OGRGeometry                          */
372 /*          The OGR_G_NOT_EMPTY_POINT is used *only* for points.        */
373 /*          Do not use these outside of the core.                       */
374 /*          Use Is3D, IsMeasured, set3D, and setMeasured instead        */
375 /************************************************************************/
376 
377 //! @cond Doxygen_Suppress
378     static const unsigned int OGR_G_NOT_EMPTY_POINT = 0x1;
379     static const unsigned int OGR_G_3D = 0x2;
380     static const unsigned int OGR_G_MEASURED = 0x4;
381 //! @endcond
382 
383                 OGRGeometry();
384                 OGRGeometry( const OGRGeometry& other );
385     virtual     ~OGRGeometry();
386 
387     OGRGeometry& operator=( const OGRGeometry& other );
388 
389     /** Returns if two geometries are equal. */
390     bool operator==( const OGRGeometry& other ) const { return CPL_TO_BOOL(Equals(&other)); }
391 
392     /** Returns if two geometries are different. */
393     bool operator!=( const OGRGeometry& other ) const { return !CPL_TO_BOOL(Equals(&other)); }
394 
395     // Standard IGeometry.
396     virtual int getDimension() const = 0;
397     virtual int getCoordinateDimension() const;
398     int CoordinateDimension() const;
399     virtual OGRBoolean  IsEmpty() const = 0;
400     virtual OGRBoolean  IsValid() const;
401     virtual OGRGeometry* MakeValid() const;
402     virtual OGRGeometry* Normalize() const;
403     virtual OGRBoolean  IsSimple() const;
404     /*! Returns whether the geometry has a Z component. */
Is3D()405     OGRBoolean  Is3D() const { return flags & OGR_G_3D; }
406     /*! Returns whether the geometry has a M component. */
IsMeasured()407     OGRBoolean  IsMeasured() const { return flags & OGR_G_MEASURED; }
408     virtual OGRBoolean  IsRing() const;
409     virtual void        empty() = 0;
410     virtual OGRGeometry *clone() const CPL_WARN_UNUSED_RESULT = 0;
411     virtual void getEnvelope( OGREnvelope * psEnvelope ) const = 0;
412     virtual void getEnvelope( OGREnvelope3D * psEnvelope ) const = 0;
413 
414     // IWks Interface.
415     virtual size_t WkbSize() const = 0;
416     OGRErr importFromWkb( const GByte*, size_t=static_cast<size_t>(-1),
417                                   OGRwkbVariant=wkbVariantOldOgc );
418     virtual OGRErr importFromWkb( const unsigned char *,
419                                   size_t,
420                                   OGRwkbVariant,
421                                   size_t& nBytesConsumedOut ) = 0;
422     virtual OGRErr exportToWkb( OGRwkbByteOrder, unsigned char *,
423                                 OGRwkbVariant=wkbVariantOldOgc ) const = 0;
424     virtual OGRErr importFromWkt( const char ** ppszInput ) = 0;
425 
426 #ifndef DOXYGEN_XML
427     /** Deprecated.
428      * @deprecated in GDAL 2.3
429      */
importFromWkt(char ** ppszInput)430     OGRErr importFromWkt( char ** ppszInput )
431 /*! @cond Doxygen_Suppress */
432         CPL_WARN_DEPRECATED("Use importFromWkt(const char**) instead")
433 /*! @endcond */
434     {
435         return importFromWkt( const_cast<const char**>(ppszInput) );
436     }
437 #endif
438 
439     OGRErr exportToWkt( char ** ppszDstText,
440         OGRwkbVariant=wkbVariantOldOgc ) const;
441 
442     /// Export a WKT geometry.
443     /// \param opts  Output options.
444     /// \param err   Pointer to error code, if desired.
445     /// \return  WKT string representing this geometry.
446     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
447                                     OGRErr *err = nullptr) const = 0;
448 
449     // Non-standard.
450     virtual OGRwkbGeometryType getGeometryType() const = 0;
451     OGRwkbGeometryType    getIsoGeometryType() const;
452     virtual const char *getGeometryName() const = 0;
453     virtual void   dumpReadable( FILE *, const char * = nullptr
454                                  , char** papszOptions = nullptr ) const;
455     virtual void   flattenTo2D() = 0;
456     virtual char * exportToGML( const char* const * papszOptions = nullptr ) const;
457     virtual char * exportToKML() const;
458     virtual char * exportToJson() const;
459 
460     /** Accept a visitor. */
461     virtual void accept(IOGRGeometryVisitor* visitor) = 0;
462 
463     /** Accept a visitor. */
464     virtual void accept(IOGRConstGeometryVisitor* visitor) const = 0;
465 
466     static GEOSContextHandle_t createGEOSContext();
467     static void freeGEOSContext( GEOSContextHandle_t hGEOSCtxt );
468     virtual GEOSGeom exportToGEOS( GEOSContextHandle_t hGEOSCtxt )
469         const CPL_WARN_UNUSED_RESULT;
470     virtual OGRBoolean hasCurveGeometry(int bLookForNonLinear = FALSE) const;
471     virtual OGRGeometry* getCurveGeometry(
472         const char* const* papszOptions = nullptr ) const CPL_WARN_UNUSED_RESULT;
473     virtual OGRGeometry* getLinearGeometry(
474         double dfMaxAngleStepSizeDegrees = 0,
475         const char* const* papszOptions = nullptr ) const CPL_WARN_UNUSED_RESULT;
476 
477     // SFCGAL interfacing methods.
478 //! @cond Doxygen_Suppress
479     static sfcgal_geometry_t* OGRexportToSFCGAL( const OGRGeometry *poGeom );
480     static OGRGeometry* SFCGALexportToOGR( const sfcgal_geometry_t* _geometry );
481 //! @endcond
482     virtual void closeRings();
483 
484     virtual void setCoordinateDimension( int nDimension );
485     virtual void set3D( OGRBoolean bIs3D );
486     virtual void setMeasured( OGRBoolean bIsMeasured );
487 
488     virtual void    assignSpatialReference( OGRSpatialReference * poSR );
getSpatialReference(void)489     OGRSpatialReference *getSpatialReference( void ) const { return poSRS; }
490 
491     virtual OGRErr  transform( OGRCoordinateTransformation *poCT ) = 0;
492     OGRErr  transformTo( OGRSpatialReference *poSR );
493 
494     virtual void segmentize(double dfMaxLength);
495 
496     // ISpatialRelation
497     virtual OGRBoolean  Intersects( const OGRGeometry * ) const;
498     virtual OGRBoolean  Equals( const OGRGeometry * ) const = 0;
499     virtual OGRBoolean  Disjoint( const OGRGeometry * ) const;
500     virtual OGRBoolean  Touches( const OGRGeometry * ) const;
501     virtual OGRBoolean  Crosses( const OGRGeometry * ) const;
502     virtual OGRBoolean  Within( const OGRGeometry * ) const;
503     virtual OGRBoolean  Contains( const OGRGeometry * ) const;
504     virtual OGRBoolean  Overlaps( const OGRGeometry * ) const;
505 //    virtual OGRBoolean  Relate( const OGRGeometry *, const char * ) const;
506 //    virtual OGRGeometry *LocateAlong( double mValue ) const;
507 //    virtual OGRGeometry *LocateBetween( double mStart, double mEnd ) const;
508 
509     virtual OGRGeometry *Boundary() const CPL_WARN_UNUSED_RESULT;
510     virtual double  Distance( const OGRGeometry * ) const ;
511     virtual OGRGeometry *ConvexHull() const CPL_WARN_UNUSED_RESULT;
512     virtual OGRGeometry *Buffer( double dfDist, int nQuadSegs = 30 )
513         const CPL_WARN_UNUSED_RESULT;
514     virtual OGRGeometry *Intersection( const OGRGeometry *)
515         const CPL_WARN_UNUSED_RESULT;
516     virtual OGRGeometry *Union( const OGRGeometry * )
517         const CPL_WARN_UNUSED_RESULT;
518     virtual OGRGeometry *UnionCascaded() const CPL_WARN_UNUSED_RESULT;
519     virtual OGRGeometry *Difference( const OGRGeometry * )
520         const CPL_WARN_UNUSED_RESULT;
521     virtual OGRGeometry *SymDifference( const OGRGeometry * )
522         const CPL_WARN_UNUSED_RESULT;
523     virtual OGRErr       Centroid( OGRPoint * poPoint ) const;
524     virtual OGRGeometry *Simplify(double dTolerance)
525         const CPL_WARN_UNUSED_RESULT;
526     OGRGeometry *SimplifyPreserveTopology(double dTolerance)
527         const CPL_WARN_UNUSED_RESULT;
528     virtual OGRGeometry *DelaunayTriangulation(
529         double dfTolerance, int bOnlyEdges ) const CPL_WARN_UNUSED_RESULT;
530 
531     virtual OGRGeometry *Polygonize() const CPL_WARN_UNUSED_RESULT;
532 
533     virtual double Distance3D( const OGRGeometry *poOtherGeom ) const;
534 
535 //! @cond Doxygen_Suppress
536     // backward compatibility to non-standard method names.
537     OGRBoolean  Intersect( OGRGeometry * )
538         const CPL_WARN_DEPRECATED("Non standard method. "
539                                   "Use Intersects() instead");
540     OGRBoolean  Equal( OGRGeometry * )
541         const CPL_WARN_DEPRECATED("Non standard method. "
542                                   "Use Equals() instead");
543     OGRGeometry *SymmetricDifference( const OGRGeometry * )
544         const CPL_WARN_DEPRECATED("Non standard method. "
545                                   "Use SymDifference() instead");
546     OGRGeometry *getBoundary()
547         const CPL_WARN_DEPRECATED("Non standard method. "
548                                   "Use Boundary() instead");
549 //! @endcond
550 
551 //! @cond Doxygen_Suppress
552     // Special HACK for DB2 7.2 support
553     static int bGenerate_DB2_V72_BYTE_ORDER;
554 //! @endcond
555 
556     virtual void        swapXY();
557 //! @cond Doxygen_Suppress
CastToIdentity(OGRGeometry * poGeom)558     static OGRGeometry* CastToIdentity( OGRGeometry* poGeom ) { return poGeom; }
559     static OGRGeometry* CastToError( OGRGeometry* poGeom );
560 //! @endcond
561 
562     /** Convert a OGRGeometry* to a OGRGeometryH.
563      * @since GDAL 2.3
564      */
ToHandle(OGRGeometry * poGeom)565     static inline OGRGeometryH ToHandle(OGRGeometry* poGeom)
566         { return reinterpret_cast<OGRGeometryH>(poGeom); }
567 
568     /** Convert a OGRGeometryH to a OGRGeometry*.
569      * @since GDAL 2.3
570      */
FromHandle(OGRGeometryH hGeom)571     static inline OGRGeometry* FromHandle(OGRGeometryH hGeom)
572         { return reinterpret_cast<OGRGeometry*>(hGeom); }
573 
574     /** Down-cast to OGRPoint*.
575      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbPoint.
576      * @since GDAL 2.3
577      */
toPoint()578     inline OGRPoint* toPoint()
579         { return cpl::down_cast<OGRPoint*>(this); }
580 
581     /** Down-cast to OGRPoint*.
582      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbPoint.
583      * @since GDAL 2.3
584      */
toPoint()585     inline const OGRPoint* toPoint() const
586         { return cpl::down_cast<const OGRPoint*>(this); }
587 
588     /** Down-cast to OGRCurve*.
589      * Implies prior checking that OGR_GT_IsSubClass(getGeometryType(), wkbCurve).
590      * @since GDAL 2.3
591      */
toCurve()592     inline OGRCurve* toCurve()
593         { return cpl::down_cast<OGRCurve*>(this); }
594 
595     /** Down-cast to OGRCurve*.
596      * Implies prior checking that OGR_GT_IsSubClass(getGeometryType(), wkbCurve).
597      * @since GDAL 2.3
598      */
toCurve()599     inline const OGRCurve* toCurve() const
600         { return cpl::down_cast<const OGRCurve*>(this); }
601 
602     /** Down-cast to OGRSimpleCurve*.
603      * Implies prior checking that getGeometryType() is wkbLineString, wkbCircularString or a derived type.
604      * @since GDAL 2.3
605      */
toSimpleCurve()606     inline OGRSimpleCurve* toSimpleCurve()
607         { return cpl::down_cast<OGRSimpleCurve*>(this); }
608 
609     /** Down-cast to OGRSimpleCurve*.
610      * Implies prior checking that getGeometryType() is wkbLineString, wkbCircularString or a derived type.
611      * @since GDAL 2.3
612      */
toSimpleCurve()613     inline const OGRSimpleCurve* toSimpleCurve() const
614         { return cpl::down_cast<const OGRSimpleCurve*>(this); }
615 
616     /** Down-cast to OGRLineString*.
617      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbLineString.
618      * @since GDAL 2.3
619      */
toLineString()620     inline OGRLineString* toLineString()
621         { return cpl::down_cast<OGRLineString*>(this); }
622 
623     /** Down-cast to OGRLineString*.
624      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbLineString.
625      * @since GDAL 2.3
626      */
toLineString()627     inline const OGRLineString* toLineString() const
628         { return cpl::down_cast<const OGRLineString*>(this); }
629 
630     /** Down-cast to OGRLinearRing*.
631      * Implies prior checking that EQUAL(getGeometryName(), "LINEARRING").
632      * @since GDAL 2.3
633      */
toLinearRing()634     inline OGRLinearRing* toLinearRing()
635         { return cpl::down_cast<OGRLinearRing*>(this); }
636 
637     /** Down-cast to OGRLinearRing*.
638      * Implies prior checking that EQUAL(getGeometryName(), "LINEARRING").
639      * @since GDAL 2.3
640      */
toLinearRing()641     inline const OGRLinearRing* toLinearRing() const
642         { return cpl::down_cast<const OGRLinearRing*>(this); }
643 
644     /** Down-cast to OGRCircularString*.
645      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbCircularString.
646      * @since GDAL 2.3
647      */
toCircularString()648     inline OGRCircularString* toCircularString()
649         { return cpl::down_cast<OGRCircularString*>(this); }
650 
651     /** Down-cast to OGRCircularString*.
652      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbCircularString.
653      * @since GDAL 2.3
654      */
toCircularString()655     inline const OGRCircularString* toCircularString() const
656         { return cpl::down_cast<const OGRCircularString*>(this); }
657 
658     /** Down-cast to OGRCompoundCurve*.
659      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbCompoundCurve.
660      * @since GDAL 2.3
661      */
toCompoundCurve()662     inline OGRCompoundCurve* toCompoundCurve()
663         { return cpl::down_cast<OGRCompoundCurve*>(this); }
664 
665     /** Down-cast to OGRCompoundCurve*.
666      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbCompoundCurve.
667      * @since GDAL 2.3
668      */
toCompoundCurve()669     inline const OGRCompoundCurve* toCompoundCurve() const
670         { return cpl::down_cast<const OGRCompoundCurve*>(this); }
671 
672     /** Down-cast to OGRSurface*.
673      * Implies prior checking that OGR_GT_IsSubClass(getGeometryType(), wkbSurface).
674      * @since GDAL 2.3
675      */
toSurface()676     inline OGRSurface* toSurface()
677         { return cpl::down_cast<OGRSurface*>(this); }
678 
679     /** Down-cast to OGRSurface*.
680      * Implies prior checking that OGR_GT_IsSubClass(getGeometryType(), wkbSurface).
681      * @since GDAL 2.3
682      */
toSurface()683     inline const OGRSurface* toSurface() const
684         { return cpl::down_cast<const OGRSurface*>(this); }
685 
686     /** Down-cast to OGRPolygon*.
687      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbPolygon or wkbTriangle.
688      * @since GDAL 2.3
689      */
toPolygon()690     inline OGRPolygon* toPolygon()
691         { return cpl::down_cast<OGRPolygon*>(this); }
692 
693     /** Down-cast to OGRPolygon*.
694      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbPolygon or wkbTriangle.
695      * @since GDAL 2.3
696      */
toPolygon()697     inline const OGRPolygon* toPolygon() const
698         { return cpl::down_cast<const OGRPolygon*>(this); }
699 
700     /** Down-cast to OGRTriangle*.
701      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbTriangle.
702      * @since GDAL 2.3
703      */
toTriangle()704     inline OGRTriangle* toTriangle()
705         { return cpl::down_cast<OGRTriangle*>(this); }
706 
707     /** Down-cast to OGRTriangle*.
708      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbTriangle.
709      * @since GDAL 2.3
710      */
toTriangle()711     inline const OGRTriangle* toTriangle() const
712         { return cpl::down_cast<const OGRTriangle*>(this); }
713 
714     /** Down-cast to OGRCurvePolygon*.
715      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbCurvePolygon or wkbPolygon or wkbTriangle.
716      * @since GDAL 2.3
717      */
toCurvePolygon()718     inline OGRCurvePolygon* toCurvePolygon()
719         { return cpl::down_cast<OGRCurvePolygon*>(this); }
720 
721     /** Down-cast to OGRCurvePolygon*.
722      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbCurvePolygon or wkbPolygon or wkbTriangle.
723      * @since GDAL 2.3
724      */
toCurvePolygon()725     inline const OGRCurvePolygon* toCurvePolygon() const
726         { return cpl::down_cast<const OGRCurvePolygon*>(this); }
727 
728     /** Down-cast to OGRGeometryCollection*.
729      * Implies prior checking that OGR_GT_IsSubClass(getGeometryType(), wkbGeometryCollection).
730      * @since GDAL 2.3
731      */
toGeometryCollection()732     inline OGRGeometryCollection* toGeometryCollection()
733         { return cpl::down_cast<OGRGeometryCollection*>(this); }
734 
735     /** Down-cast to OGRGeometryCollection*.
736      * Implies prior checking that OGR_GT_IsSubClass(getGeometryType(), wkbGeometryCollection).
737      * @since GDAL 2.3
738      */
toGeometryCollection()739     inline const OGRGeometryCollection* toGeometryCollection() const
740         { return cpl::down_cast<const OGRGeometryCollection*>(this); }
741 
742     /** Down-cast to OGRMultiPoint*.
743      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbMultiPoint.
744      * @since GDAL 2.3
745      */
toMultiPoint()746     inline OGRMultiPoint* toMultiPoint()
747         { return cpl::down_cast<OGRMultiPoint*>(this); }
748 
749     /** Down-cast to OGRMultiPoint*.
750      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbMultiPoint.
751      * @since GDAL 2.3
752      */
toMultiPoint()753     inline const OGRMultiPoint* toMultiPoint() const
754         { return cpl::down_cast<const OGRMultiPoint*>(this); }
755 
756     /** Down-cast to OGRMultiLineString*.
757      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbMultiLineString.
758      * @since GDAL 2.3
759      */
toMultiLineString()760     inline OGRMultiLineString* toMultiLineString()
761         { return cpl::down_cast<OGRMultiLineString*>(this); }
762 
763     /** Down-cast to OGRMultiLineString*.
764      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbMultiLineString.
765      * @since GDAL 2.3
766      */
toMultiLineString()767     inline const OGRMultiLineString* toMultiLineString() const
768         { return cpl::down_cast<const OGRMultiLineString*>(this); }
769 
770     /** Down-cast to OGRMultiPolygon*.
771      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbMultiPolygon.
772      * @since GDAL 2.3
773      */
toMultiPolygon()774     inline OGRMultiPolygon* toMultiPolygon()
775         { return cpl::down_cast<OGRMultiPolygon*>(this); }
776 
777     /** Down-cast to OGRMultiPolygon*.
778      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbMultiPolygon.
779      * @since GDAL 2.3
780      */
toMultiPolygon()781     inline const OGRMultiPolygon* toMultiPolygon() const
782         { return cpl::down_cast<const OGRMultiPolygon*>(this); }
783 
784     /** Down-cast to OGRMultiCurve*.
785      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbMultiCurve and derived types.
786      * @since GDAL 2.3
787      */
toMultiCurve()788     inline OGRMultiCurve* toMultiCurve()
789         { return cpl::down_cast<OGRMultiCurve*>(this); }
790 
791     /** Down-cast to OGRMultiCurve*.
792      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbMultiCurve and derived types.
793      * @since GDAL 2.3
794      */
toMultiCurve()795     inline const OGRMultiCurve* toMultiCurve() const
796         { return cpl::down_cast<const OGRMultiCurve*>(this); }
797 
798     /** Down-cast to OGRMultiSurface*.
799      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbMultiSurface and derived types.
800      * @since GDAL 2.3
801      */
toMultiSurface()802     inline OGRMultiSurface* toMultiSurface()
803         { return cpl::down_cast<OGRMultiSurface*>(this); }
804 
805     /** Down-cast to OGRMultiSurface*.
806      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbMultiSurface and derived types.
807      * @since GDAL 2.3
808      */
toMultiSurface()809     inline const OGRMultiSurface* toMultiSurface() const
810         { return cpl::down_cast<const OGRMultiSurface*>(this); }
811 
812     /** Down-cast to OGRPolyhedralSurface*.
813      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbPolyhedralSurface or wkbTIN.
814      * @since GDAL 2.3
815      */
toPolyhedralSurface()816     inline OGRPolyhedralSurface* toPolyhedralSurface()
817         { return cpl::down_cast<OGRPolyhedralSurface*>(this); }
818 
819     /** Down-cast to OGRPolyhedralSurface*.
820      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbPolyhedralSurface or wkbTIN.
821      * @since GDAL 2.3
822      */
toPolyhedralSurface()823     inline const OGRPolyhedralSurface* toPolyhedralSurface() const
824         { return cpl::down_cast<const OGRPolyhedralSurface*>(this); }
825 
826     /** Down-cast to OGRTriangulatedSurface*.
827      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbTIN.
828      * @since GDAL 2.3
829      */
toTriangulatedSurface()830     inline OGRTriangulatedSurface* toTriangulatedSurface()
831         { return cpl::down_cast<OGRTriangulatedSurface*>(this); }
832 
833     /** Down-cast to OGRTriangulatedSurface*.
834      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbTIN.
835      * @since GDAL 2.3
836      */
toTriangulatedSurface()837     inline const OGRTriangulatedSurface* toTriangulatedSurface() const
838         { return cpl::down_cast<const OGRTriangulatedSurface*>(this); }
839 
840 };
841 
842 //! @cond Doxygen_Suppress
843 struct CPL_DLL OGRGeometryUniquePtrDeleter
844 {
845     void operator()(OGRGeometry*) const;
846 };
847 //! @endcond
848 
849 /** Unique pointer type for OGRGeometry.
850  * @since GDAL 2.3
851  */
852 typedef std::unique_ptr<OGRGeometry, OGRGeometryUniquePtrDeleter> OGRGeometryUniquePtr;
853 
854 
855 //! @cond Doxygen_Suppress
856 #define OGR_FORBID_DOWNCAST_TO(name) \
857     inline OGR ## name * to ## name() = delete; \
858     inline const OGR ## name * to ## name() const = delete;
859 
860 #define OGR_FORBID_DOWNCAST_TO_POINT              OGR_FORBID_DOWNCAST_TO(Point)
861 #define OGR_FORBID_DOWNCAST_TO_CURVE              OGR_FORBID_DOWNCAST_TO(Curve)
862 #define OGR_FORBID_DOWNCAST_TO_SIMPLE_CURVE       OGR_FORBID_DOWNCAST_TO(SimpleCurve)
863 #define OGR_FORBID_DOWNCAST_TO_LINESTRING         OGR_FORBID_DOWNCAST_TO(LineString)
864 #define OGR_FORBID_DOWNCAST_TO_LINEARRING         OGR_FORBID_DOWNCAST_TO(LinearRing)
865 #define OGR_FORBID_DOWNCAST_TO_CIRCULARSTRING     OGR_FORBID_DOWNCAST_TO(CircularString)
866 #define OGR_FORBID_DOWNCAST_TO_COMPOUNDCURVE      OGR_FORBID_DOWNCAST_TO(CompoundCurve)
867 #define OGR_FORBID_DOWNCAST_TO_SURFACE            OGR_FORBID_DOWNCAST_TO(Surface)
868 #define OGR_FORBID_DOWNCAST_TO_CURVEPOLYGON       OGR_FORBID_DOWNCAST_TO(CurvePolygon)
869 #define OGR_FORBID_DOWNCAST_TO_POLYGON            OGR_FORBID_DOWNCAST_TO(Polygon)
870 #define OGR_FORBID_DOWNCAST_TO_TRIANGLE           OGR_FORBID_DOWNCAST_TO(Triangle)
871 #define OGR_FORBID_DOWNCAST_TO_MULTIPOINT         OGR_FORBID_DOWNCAST_TO(MultiPoint)
872 #define OGR_FORBID_DOWNCAST_TO_MULTICURVE         OGR_FORBID_DOWNCAST_TO(MultiCurve)
873 #define OGR_FORBID_DOWNCAST_TO_MULTILINESTRING    OGR_FORBID_DOWNCAST_TO(MultiLineString)
874 #define OGR_FORBID_DOWNCAST_TO_MULTISURFACE       OGR_FORBID_DOWNCAST_TO(MultiSurface)
875 #define OGR_FORBID_DOWNCAST_TO_MULTIPOLYGON       OGR_FORBID_DOWNCAST_TO(MultiPolygon)
876 #define OGR_FORBID_DOWNCAST_TO_GEOMETRYCOLLECTION OGR_FORBID_DOWNCAST_TO(GeometryCollection)
877 #define OGR_FORBID_DOWNCAST_TO_POLYHEDRALSURFACE  OGR_FORBID_DOWNCAST_TO(PolyhedralSurface)
878 #define OGR_FORBID_DOWNCAST_TO_TIN                OGR_FORBID_DOWNCAST_TO(TriangulatedSurface)
879 
880 #define OGR_ALLOW_UPCAST_TO(name) \
881     inline OGR ## name * to ## name() { return this; } \
882     inline const OGR ## name * to ## name() const { return this; }
883 
884 #ifndef SUPPRESS_OGR_ALLOW_CAST_TO_THIS_WARNING
885 #define CAST_TO_THIS_WARNING CPL_WARN_DEPRECATED("Casting to this is useless")
886 #else
887 #define CAST_TO_THIS_WARNING
888 #endif
889 
890 #define OGR_ALLOW_CAST_TO_THIS(name) \
891     inline OGR ## name * to ## name() CAST_TO_THIS_WARNING { return this; } \
892     inline const OGR ## name * to ## name() const CAST_TO_THIS_WARNING { return this; }
893 
894 #define OGR_FORBID_DOWNCAST_TO_ALL_CURVES \
895     OGR_FORBID_DOWNCAST_TO_CURVE \
896     OGR_FORBID_DOWNCAST_TO_SIMPLE_CURVE \
897     OGR_FORBID_DOWNCAST_TO_LINESTRING \
898     OGR_FORBID_DOWNCAST_TO_LINEARRING \
899     OGR_FORBID_DOWNCAST_TO_CIRCULARSTRING \
900     OGR_FORBID_DOWNCAST_TO_COMPOUNDCURVE
901 
902 #define OGR_FORBID_DOWNCAST_TO_ALL_SURFACES \
903     OGR_FORBID_DOWNCAST_TO_SURFACE \
904     OGR_FORBID_DOWNCAST_TO_CURVEPOLYGON \
905     OGR_FORBID_DOWNCAST_TO_POLYGON \
906     OGR_FORBID_DOWNCAST_TO_TRIANGLE \
907     OGR_FORBID_DOWNCAST_TO_POLYHEDRALSURFACE \
908     OGR_FORBID_DOWNCAST_TO_TIN
909 
910 #define OGR_FORBID_DOWNCAST_TO_ALL_SINGLES \
911     OGR_FORBID_DOWNCAST_TO_POINT \
912     OGR_FORBID_DOWNCAST_TO_ALL_CURVES \
913     OGR_FORBID_DOWNCAST_TO_ALL_SURFACES
914 
915 #define OGR_FORBID_DOWNCAST_TO_ALL_MULTI \
916     OGR_FORBID_DOWNCAST_TO_GEOMETRYCOLLECTION \
917     OGR_FORBID_DOWNCAST_TO_MULTIPOINT \
918     OGR_FORBID_DOWNCAST_TO_MULTICURVE \
919     OGR_FORBID_DOWNCAST_TO_MULTILINESTRING \
920     OGR_FORBID_DOWNCAST_TO_MULTISURFACE \
921     OGR_FORBID_DOWNCAST_TO_MULTIPOLYGON
922 
923 //! @endcond
924 
925 /************************************************************************/
926 /*                               OGRPoint                               */
927 /************************************************************************/
928 
929 /**
930  * Point class.
931  *
932  * Implements SFCOM IPoint methods.
933  */
934 
935 class CPL_DLL OGRPoint : public OGRGeometry
936 {
937     double      x;
938     double      y;
939     double      z;
940     double      m;
941 
942   public:
943     OGRPoint();
944     OGRPoint( double x, double y );
945     OGRPoint( double x, double y, double z );
946     OGRPoint( double x, double y, double z, double m );
947     OGRPoint( const OGRPoint& other );
948     static OGRPoint* createXYM( double x, double y, double m );
949     ~OGRPoint() override;
950 
951     OGRPoint& operator=( const OGRPoint& other );
952 
953     // IWks Interface
954     size_t WkbSize() const override;
955     OGRErr importFromWkb( const unsigned char *,
956                           size_t,
957                           OGRwkbVariant,
958                           size_t& nBytesConsumedOut ) override;
959     OGRErr exportToWkb( OGRwkbByteOrder, unsigned char *,
960                         OGRwkbVariant=wkbVariantOldOgc )
961         const override;
962 
963 #ifndef DOXYGEN_XML
964     using OGRGeometry::importFromWkt; /** deprecated */
965 #endif
966 
967     OGRErr importFromWkt( const char ** ) override;
968 
969 #ifndef DOXYGEN_XML
970     using OGRGeometry::exportToWkt;
971 #endif
972 
973     /// Export a point to WKT
974     /// \param opts  Output options.
975     /// \param err   Pointer to error code, if desired.
976     /// \return  WKT string representing this point.
977     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
978                                     OGRErr *err = nullptr) const override;
979 
980     // IGeometry
981     virtual int getDimension() const override;
982     virtual OGRPoint *clone() const override;
983     virtual void empty() override;
984     virtual void getEnvelope( OGREnvelope * psEnvelope ) const override;
985     virtual void getEnvelope( OGREnvelope3D * psEnvelope ) const override;
IsEmpty()986     virtual OGRBoolean  IsEmpty() const override
987         { return !(flags & OGR_G_NOT_EMPTY_POINT); }
988 
989     // IPoint
990     /** Return x */
getX()991     double      getX() const { return x; }
992     /** Return y */
getY()993     double      getY() const { return y; }
994     /** Return z */
getZ()995     double      getZ() const { return z; }
996     /** Return m */
getM()997     double      getM() const { return m; }
998 
999     // Non standard
1000     virtual void setCoordinateDimension( int nDimension ) override;
1001     /** Set x
1002      * @param xIn x
1003      */
setX(double xIn)1004     void        setX( double xIn ) { x = xIn; if( std::isnan(x) || std::isnan(y) ) flags &= ~OGR_G_NOT_EMPTY_POINT; else flags |= OGR_G_NOT_EMPTY_POINT; }
1005     /** Set y
1006      * @param yIn y
1007      */
setY(double yIn)1008     void        setY( double yIn ) { y = yIn; if( std::isnan(x) || std::isnan(y) ) flags &= ~OGR_G_NOT_EMPTY_POINT; else flags |= OGR_G_NOT_EMPTY_POINT; }
1009     /** Set z
1010      * @param zIn z
1011      */
setZ(double zIn)1012     void        setZ( double zIn )
1013         { z = zIn; flags |= OGR_G_3D; }
1014     /** Set m
1015      * @param mIn m
1016      */
setM(double mIn)1017     void        setM( double mIn )
1018         { m = mIn; flags |= OGR_G_MEASURED; }
1019 
1020     // ISpatialRelation
1021     virtual OGRBoolean  Equals( const OGRGeometry * ) const override;
1022     virtual OGRBoolean  Intersects( const OGRGeometry * ) const override;
1023     virtual OGRBoolean  Within( const OGRGeometry * ) const override;
1024 
1025     // Non standard from OGRGeometry
1026     virtual const char *getGeometryName() const override;
1027     virtual OGRwkbGeometryType getGeometryType() const override;
1028     virtual OGRErr  transform( OGRCoordinateTransformation *poCT ) override;
1029     virtual void flattenTo2D() override;
accept(IOGRGeometryVisitor * visitor)1030     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)1031     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
1032 
1033     virtual void        swapXY() override;
1034 
1035     OGR_ALLOW_CAST_TO_THIS(Point)
1036     OGR_FORBID_DOWNCAST_TO_ALL_CURVES
1037     OGR_FORBID_DOWNCAST_TO_ALL_SURFACES
1038     OGR_FORBID_DOWNCAST_TO_ALL_MULTI
1039 };
1040 
1041 /************************************************************************/
1042 /*                            OGRPointIterator                          */
1043 /************************************************************************/
1044 
1045 /**
1046  * Interface for a point iterator.
1047  *
1048  * @since GDAL 2.0
1049  */
1050 
1051 class CPL_DLL OGRPointIterator
1052 {
1053     public:
1054         virtual ~OGRPointIterator();
1055         virtual OGRBoolean getNextPoint( OGRPoint* p ) = 0;
1056 
1057         static void destroy( OGRPointIterator* );
1058 };
1059 
1060 /************************************************************************/
1061 /*                               OGRCurve                               */
1062 /************************************************************************/
1063 
1064 /**
1065  * Abstract curve base class for OGRLineString, OGRCircularString and
1066  * OGRCompoundCurve
1067  */
1068 
1069 class CPL_DLL OGRCurve : public OGRGeometry
1070 {
1071   protected:
1072 //! @cond Doxygen_Suppress
1073             OGRCurve();
1074             OGRCurve( const OGRCurve& other );
1075 
1076     virtual OGRCurveCasterToLineString GetCasterToLineString() const = 0;
1077     virtual OGRCurveCasterToLinearRing GetCasterToLinearRing() const = 0;
1078 
1079     friend class OGRCurvePolygon;
1080     friend class OGRCompoundCurve;
1081 //! @endcond
1082     virtual int ContainsPoint( const OGRPoint* p ) const;
1083     virtual int IntersectsPoint( const OGRPoint* p ) const;
1084     virtual double get_AreaOfCurveSegments() const = 0;
1085 
1086     private:
1087 
1088         class CPL_DLL ConstIterator
1089         {
1090                 struct Private;
1091                 std::unique_ptr<Private> m_poPrivate;
1092             public:
1093                 ConstIterator(const OGRCurve* poSelf, bool bStart);
1094                 ConstIterator(ConstIterator&& oOther) noexcept; // declared but not defined. Needed for gcc 5.4 at least
1095                 ~ConstIterator();
1096                 const OGRPoint& operator*() const;
1097                 ConstIterator& operator++();
1098                 bool operator!=(const ConstIterator& it) const;
1099         };
1100 
1101         friend inline ConstIterator begin(const OGRCurve*);
1102         friend inline ConstIterator end(const OGRCurve*);
1103 
1104   public:
1105     ~OGRCurve() override;
1106 
1107 //! @cond Doxygen_Suppress
1108     OGRCurve& operator=( const OGRCurve& other );
1109 //! @endcond
1110 
1111     /** Type of child elements. */
1112     typedef OGRPoint ChildType;
1113 
1114     /** Return begin of a point iterator.
1115      *
1116      * Using this iterator for standard range-based loops is safe, but
1117      * due to implementation limitations, you shouldn't try to access
1118      * (dereference) more than one iterator step at a time, since you will get
1119      * a reference to the same OGRPoint& object.
1120      * @since GDAL 2.3
1121      */
1122     ConstIterator begin() const;
1123     /** Return end of a point iterator. */
1124     ConstIterator end() const;
1125 
1126     // IGeometry
1127     virtual OGRCurve *clone() const override = 0;
1128 
1129     // ICurve methods
1130     virtual double get_Length() const = 0;
1131     virtual void StartPoint( OGRPoint * ) const = 0;
1132     virtual void EndPoint( OGRPoint * ) const = 0;
1133     virtual int  get_IsClosed() const;
1134     virtual void Value( double, OGRPoint * ) const = 0;
1135     virtual OGRLineString* CurveToLine( double dfMaxAngleStepSizeDegrees = 0,
1136                                         const char* const* papszOptions = nullptr)
1137         const = 0;
1138     virtual int getDimension() const override;
1139 
1140     // non standard
1141     virtual int getNumPoints() const = 0;
1142     virtual OGRPointIterator* getPointIterator() const = 0;
1143     virtual OGRBoolean IsConvex() const;
1144     virtual double get_Area() const = 0;
1145 
1146     /** Down-cast to OGRSimpleCurve*.
1147      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbLineString or wkbCircularString. */
toSimpleCurve()1148     inline OGRSimpleCurve* toSimpleCurve()
1149         { return cpl::down_cast<OGRSimpleCurve*>(this); }
1150 
1151     /** Down-cast to OGRSimpleCurve*.
1152      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbLineString or wkbCircularString. */
toSimpleCurve()1153     inline const OGRSimpleCurve* toSimpleCurve() const
1154         { return cpl::down_cast<const OGRSimpleCurve*>(this); }
1155 
1156     static OGRCompoundCurve* CastToCompoundCurve( OGRCurve* puCurve );
1157     static OGRLineString*    CastToLineString( OGRCurve* poCurve );
1158     static OGRLinearRing*    CastToLinearRing( OGRCurve* poCurve );
1159 
1160     OGR_FORBID_DOWNCAST_TO_POINT
1161     OGR_ALLOW_CAST_TO_THIS(Curve)
1162     OGR_FORBID_DOWNCAST_TO_ALL_SURFACES
1163     OGR_FORBID_DOWNCAST_TO_ALL_MULTI
1164 };
1165 
1166 //! @cond Doxygen_Suppress
1167 /** @see OGRCurve::begin() const */
begin(const OGRCurve * poCurve)1168 inline OGRCurve::ConstIterator begin(const OGRCurve* poCurve) { return poCurve->begin(); }
1169 /** @see OGRCurve::end() const */
end(const OGRCurve * poCurve)1170 inline OGRCurve::ConstIterator end(const OGRCurve* poCurve) { return poCurve->end(); }
1171 //! @endcond
1172 
1173 /************************************************************************/
1174 /*                             OGRSimpleCurve                           */
1175 /************************************************************************/
1176 
1177 /**
1178  * Abstract curve base class for OGRLineString and OGRCircularString
1179  *
1180  * Note: this class does not exist in SQL/MM standard and exists for
1181  * implementation convenience.
1182  *
1183  * @since GDAL 2.0
1184  */
1185 
1186 class CPL_DLL OGRSimpleCurve: public OGRCurve
1187 {
1188   protected:
1189 //! @cond Doxygen_Suppress
1190     friend class OGRGeometry;
1191 
1192     int         nPointCount;
1193     OGRRawPoint *paoPoints;
1194     double      *padfZ;
1195     double      *padfM;
1196 
1197     void        Make3D();
1198     void        Make2D();
1199     void        RemoveM();
1200     void        AddM();
1201 
1202     OGRErr      importFromWKTListOnly( const char ** ppszInput, int bHasZ, int bHasM,
1203                                        OGRRawPoint*& paoPointsIn,
1204                                        int& nMaxPoints,
1205                                        double*& padfZIn );
1206 //! @endcond
1207 
1208     virtual double get_LinearArea() const;
1209 
1210                 OGRSimpleCurve();
1211                 OGRSimpleCurve( const OGRSimpleCurve& other );
1212 
1213   private:
1214         class CPL_DLL Iterator
1215         {
1216                 struct Private;
1217                 std::unique_ptr<Private> m_poPrivate;
1218                 void update();
1219             public:
1220                 Iterator(OGRSimpleCurve* poSelf, int nPos);
1221                 Iterator(Iterator&& oOther) noexcept; // declared but not defined. Needed for gcc 5.4 at least
1222                 ~Iterator();
1223                 OGRPoint& operator*();
1224                 Iterator& operator++();
1225                 bool operator!=(const Iterator& it) const;
1226         };
1227 
1228         friend inline Iterator begin(OGRSimpleCurve*);
1229         friend inline Iterator end(OGRSimpleCurve*);
1230 
1231         class CPL_DLL ConstIterator
1232         {
1233                 struct Private;
1234                 std::unique_ptr<Private> m_poPrivate;
1235             public:
1236                 ConstIterator(const OGRSimpleCurve* poSelf, int nPos);
1237                 ConstIterator(ConstIterator&& oOther) noexcept; // declared but not defined. Needed for gcc 5.4 at least
1238                 ~ConstIterator();
1239                 const OGRPoint& operator*() const;
1240                 ConstIterator& operator++();
1241                 bool operator!=(const ConstIterator& it) const;
1242         };
1243 
1244         friend inline ConstIterator begin(const OGRSimpleCurve*);
1245         friend inline ConstIterator end(const OGRSimpleCurve*);
1246 
1247   public:
1248     ~OGRSimpleCurve() override;
1249 
1250     OGRSimpleCurve& operator=( const OGRSimpleCurve& other );
1251 
1252     /** Type of child elements. */
1253     typedef OGRPoint ChildType;
1254 
1255     /** Return begin of point iterator.
1256      *
1257      * Using this iterator for standard range-based loops is safe, but
1258      * due to implementation limitations, you shouldn't try to access
1259      * (dereference) more than one iterator step at a time, since you will get
1260      * a reference to the same OGRPoint& object.
1261      * @since GDAL 2.3
1262      */
1263     Iterator begin();
1264     /** Return end of point iterator. */
1265     Iterator end();
1266     /** Return begin of point iterator.
1267      *
1268      * Using this iterator for standard range-based loops is safe, but
1269      * due to implementation limitations, you shouldn't try to access
1270      * (dereference) more than one iterator step at a time, since you will get
1271      * a reference to the same OGRPoint& object.
1272      * @since GDAL 2.3
1273      */
1274     ConstIterator begin() const;
1275     /** Return end of point iterator. */
1276     ConstIterator end() const;
1277 
1278     // IWks Interface.
1279     virtual size_t WkbSize() const override;
1280     virtual OGRErr importFromWkb( const unsigned char *,
1281                                   size_t,
1282                                   OGRwkbVariant,
1283                                   size_t& nBytesConsumedOut ) override;
1284     virtual OGRErr exportToWkb( OGRwkbByteOrder, unsigned char *,
1285                                 OGRwkbVariant=wkbVariantOldOgc )
1286         const override;
1287 
1288 #ifndef DOXYGEN_XML
1289     using OGRGeometry::importFromWkt; /** deprecated */
1290 #endif
1291 
1292     OGRErr importFromWkt( const char ** ) override;
1293 
1294 #ifndef DOXYGEN_XML
1295     using OGRGeometry::exportToWkt;
1296 #endif
1297 
1298     /// Export a simple curve to WKT
1299     /// \param opts  Output options.
1300     /// \param err   Pointer to error code, if desired.
1301     /// \return  WKT string representing this simple curve.
1302     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
1303                                     OGRErr *err = nullptr) const override;
1304 
1305     // IGeometry interface.
1306     virtual void empty() override;
1307     virtual void getEnvelope( OGREnvelope * psEnvelope ) const override;
1308     virtual void getEnvelope( OGREnvelope3D * psEnvelope ) const override;
1309     virtual OGRBoolean  IsEmpty() const override;
1310     virtual OGRSimpleCurve *clone() const override = 0;
1311 
1312     // ICurve methods.
1313     virtual double get_Length() const override;
1314     virtual void StartPoint( OGRPoint * ) const override;
1315     virtual void EndPoint( OGRPoint * ) const override;
1316     virtual void Value( double, OGRPoint * ) const override;
1317     virtual double Project( const OGRPoint * ) const;
1318     virtual OGRLineString* getSubLine( double, double, int ) const;
1319 
1320     // ILineString methods.
getNumPoints()1321     virtual int getNumPoints() const override { return nPointCount; }
1322     void        getPoint( int, OGRPoint * ) const;
getX(int i)1323     double      getX( int i ) const { return paoPoints[i].x; }
getY(int i)1324     double      getY( int i ) const { return paoPoints[i].y; }
1325     double      getZ( int i ) const;
1326     double      getM( int i ) const;
1327 
1328     // ISpatialRelation
1329     virtual OGRBoolean  Equals( const OGRGeometry * ) const override;
1330 
1331     // non standard.
1332     virtual void setCoordinateDimension( int nDimension ) override;
1333     virtual void set3D( OGRBoolean bIs3D ) override;
1334     virtual void setMeasured( OGRBoolean bIsMeasured ) override;
1335     void        setNumPoints( int nNewPointCount,
1336                               int bZeroizeNewContent = TRUE );
1337     void        setPoint( int, OGRPoint * );
1338     void        setPoint( int, double, double );
1339     void        setZ( int, double );
1340     void        setM( int, double );
1341     void        setPoint( int, double, double, double );
1342     void        setPointM( int, double, double, double );
1343     void        setPoint( int, double, double, double, double );
1344     void        setPoints( int, const OGRRawPoint *, const double * = nullptr );
1345     void        setPointsM( int, const OGRRawPoint *, const double * );
1346     void        setPoints( int, const OGRRawPoint *, const double *, const double * );
1347     void        setPoints( int, const double * padfX, const double * padfY,
1348                            const double *padfZIn = nullptr );
1349     void        setPointsM( int, const double * padfX, const double * padfY,
1350                             const double *padfMIn = nullptr );
1351     void        setPoints( int, const double * padfX, const double * padfY,
1352                            const double *padfZIn, const double *padfMIn );
1353     void        addPoint( const OGRPoint * );
1354     void        addPoint( double, double );
1355     void        addPoint( double, double, double );
1356     void        addPointM( double, double, double );
1357     void        addPoint( double, double, double, double );
1358 
1359     bool        removePoint( int );
1360 
1361     void        getPoints( OGRRawPoint *, double * = nullptr ) const;
1362     void        getPoints( void* pabyX, int nXStride,
1363                            void* pabyY, int nYStride,
1364                            void* pabyZ = nullptr, int nZStride = 0,
1365                            void* pabyM = nullptr, int nMStride = 0 ) const;
1366 
1367     void        addSubLineString( const OGRLineString *,
1368                                   int nStartVertex = 0, int nEndVertex = -1 );
1369     void        reversePoints( void );
1370     virtual OGRPointIterator* getPointIterator() const override;
1371 
1372     // non-standard from OGRGeometry
1373     virtual OGRErr  transform( OGRCoordinateTransformation *poCT ) override;
1374     virtual void flattenTo2D() override;
1375     virtual void segmentize(double dfMaxLength) override;
1376 
1377     virtual void        swapXY() override;
1378 
1379     OGR_ALLOW_UPCAST_TO(Curve)
1380     OGR_ALLOW_CAST_TO_THIS(SimpleCurve)
1381 };
1382 
1383 //! @cond Doxygen_Suppress
1384 /** @see OGRSimpleCurve::begin() */
begin(OGRSimpleCurve * poCurve)1385 inline OGRSimpleCurve::Iterator begin(OGRSimpleCurve* poCurve) { return poCurve->begin(); }
1386 /** @see OGRSimpleCurve::end() */
end(OGRSimpleCurve * poCurve)1387 inline OGRSimpleCurve::Iterator end(OGRSimpleCurve* poCurve) { return poCurve->end(); }
1388 
1389 /** @see OGRSimpleCurve::begin() const */
begin(const OGRSimpleCurve * poCurve)1390 inline OGRSimpleCurve::ConstIterator begin(const OGRSimpleCurve* poCurve) { return poCurve->begin(); }
1391 /** @see OGRSimpleCurve::end() const */
end(const OGRSimpleCurve * poCurve)1392 inline OGRSimpleCurve::ConstIterator end(const OGRSimpleCurve* poCurve) { return poCurve->end(); }
1393 //! @endcond
1394 
1395 /************************************************************************/
1396 /*                            OGRLineString                             */
1397 /************************************************************************/
1398 
1399 /**
1400  * Concrete representation of a multi-vertex line.
1401  *
1402  * Note: for implementation convenience, we make it inherit from OGRSimpleCurve
1403  * whereas SFSQL and SQL/MM only make it inherits from OGRCurve.
1404  */
1405 
1406 class CPL_DLL OGRLineString : public OGRSimpleCurve
1407 {
1408     // cppcheck-suppress unusedPrivateFunction
1409     static OGRLinearRing*          CasterToLinearRing(OGRCurve* poCurve);
1410 
1411   protected:
1412 //! @cond Doxygen_Suppress
1413     static OGRLineString* TransferMembersAndDestroy(
1414                                             OGRLineString* poSrc,
1415                                             OGRLineString* poDst);
1416 
1417     virtual OGRCurveCasterToLineString GetCasterToLineString()
1418         const override;
1419     virtual OGRCurveCasterToLinearRing GetCasterToLinearRing()
1420         const override;
1421 
1422     virtual double get_AreaOfCurveSegments() const override;
1423 //! @endcond
1424 
1425     static OGRLinearRing* CastToLinearRing( OGRLineString* poLS );
1426 
1427   public:
1428     OGRLineString();
1429     OGRLineString( const OGRLineString& other );
1430     ~OGRLineString() override;
1431 
1432     OGRLineString& operator=(const OGRLineString& other);
1433 
1434     virtual OGRLineString *clone() const override;
1435     virtual OGRLineString* CurveToLine( double dfMaxAngleStepSizeDegrees = 0,
1436                                         const char* const* papszOptions = nullptr )
1437         const override;
1438     virtual OGRGeometry* getCurveGeometry(
1439         const char* const* papszOptions = nullptr ) const override;
1440     virtual double get_Area() const override;
1441 
1442     // Non-standard from OGRGeometry.
1443     virtual OGRwkbGeometryType getGeometryType() const override;
1444     virtual const char *getGeometryName() const override;
1445 
1446     /** Return pointer of this in upper class */
toUpperClass()1447     inline OGRSimpleCurve* toUpperClass() { return this; }
1448     /** Return pointer of this in upper class */
toUpperClass()1449     inline const OGRSimpleCurve* toUpperClass() const { return this; }
1450 
accept(IOGRGeometryVisitor * visitor)1451     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)1452     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
1453 
1454     OGR_ALLOW_UPCAST_TO(SimpleCurve)
1455     OGR_ALLOW_CAST_TO_THIS(LineString)
1456 };
1457 
1458 /************************************************************************/
1459 /*                            OGRLinearRing                             */
1460 /************************************************************************/
1461 
1462 /**
1463  * Concrete representation of a closed ring.
1464  *
1465  * This class is functionally equivalent to an OGRLineString, but has a
1466  * separate identity to maintain alignment with the OpenGIS simple feature
1467  * data model.  It exists to serve as a component of an OGRPolygon.
1468  *
1469  * The OGRLinearRing has no corresponding free standing well known binary
1470  * representation, so importFromWkb() and exportToWkb() will not actually
1471  * work.  There is a non-standard GDAL WKT representation though.
1472  *
1473  * Because OGRLinearRing is not a "proper" free standing simple features
1474  * object, it cannot be directly used on a feature via SetGeometry(), and
1475  * cannot generally be used with GEOS for operations like Intersects().
1476  * Instead the polygon should be used, or the OGRLinearRing should be
1477  * converted to an OGRLineString for such operations.
1478  *
1479  * Note: this class exists in SFSQL 1.2, but not in ISO SQL/MM Part 3.
1480  */
1481 
1482 class CPL_DLL OGRLinearRing : public OGRLineString
1483 {
1484     static OGRLineString*       CasterToLineString( OGRCurve* poCurve );
1485 
1486     // IWks Interface - Note this isn't really a first class object
1487     // for the purposes of WKB form.  These methods always fail since this
1488     // object can't be serialized on its own.
1489     virtual size_t WkbSize() const override;
1490     virtual OGRErr importFromWkb( const unsigned char *,
1491                                   size_t,
1492                                   OGRwkbVariant,
1493                                   size_t& nBytesConsumedOut ) override;
1494     virtual OGRErr exportToWkb( OGRwkbByteOrder, unsigned char *,
1495                                 OGRwkbVariant=wkbVariantOldOgc )
1496         const override;
1497 
1498   protected:
1499 //! @cond Doxygen_Suppress
1500     friend class OGRPolygon;
1501     friend class OGRTriangle;
1502 
1503     // These are not IWks compatible ... just a convenience for OGRPolygon.
1504     virtual size_t _WkbSize( int _flags ) const;
1505     virtual OGRErr _importFromWkb( OGRwkbByteOrder, int _flags,
1506                                    const unsigned char *, size_t,
1507                                    size_t& nBytesConsumedOut );
1508     virtual OGRErr _exportToWkb( OGRwkbByteOrder, int _flags,
1509                                  unsigned char * ) const;
1510 
1511     virtual OGRCurveCasterToLineString GetCasterToLineString()
1512         const override;
1513     virtual OGRCurveCasterToLinearRing GetCasterToLinearRing()
1514         const override;
1515 //! @endcond
1516 
1517     static OGRLineString* CastToLineString( OGRLinearRing* poLR );
1518 
1519   public:
1520     OGRLinearRing();
1521     OGRLinearRing( const OGRLinearRing& other );
1522     explicit OGRLinearRing( OGRLinearRing * );
1523     ~OGRLinearRing() override;
1524 
1525     OGRLinearRing& operator=( const OGRLinearRing& other );
1526 
1527     // Non standard.
1528     virtual const char *getGeometryName() const override;
1529     virtual OGRLinearRing *clone() const override;
1530     virtual int isClockwise() const;
1531     virtual void reverseWindingOrder();
1532     virtual void closeRings() override;
1533     OGRBoolean isPointInRing( const OGRPoint* pt,
1534                               int bTestEnvelope = TRUE ) const;
1535     OGRBoolean isPointOnRingBoundary( const OGRPoint* pt,
1536                                       int bTestEnvelope = TRUE ) const;
1537     virtual OGRErr  transform( OGRCoordinateTransformation *poCT ) override;
1538 
1539     /** Return pointer of this in upper class */
toUpperClass()1540     inline OGRLineString* toUpperClass() { return this; }
1541     /** Return pointer of this in upper class */
toUpperClass()1542     inline const OGRLineString* toUpperClass() const { return this; }
1543 
accept(IOGRGeometryVisitor * visitor)1544     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)1545     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
1546 
1547     OGR_ALLOW_UPCAST_TO(LineString)
1548     OGR_ALLOW_CAST_TO_THIS(LinearRing)
1549 };
1550 
1551 /************************************************************************/
1552 /*                         OGRCircularString                            */
1553 /************************************************************************/
1554 
1555 /**
1556  * Concrete representation of a circular string, that is to say a curve made
1557  * of one or several arc circles.
1558  *
1559  * Note: for implementation convenience, we make it inherit from OGRSimpleCurve
1560  * whereas SQL/MM only makes it inherits from OGRCurve.
1561  *
1562  * Compatibility: ISO SQL/MM Part 3.
1563  *
1564  * @since GDAL 2.0
1565  */
1566 
1567 class CPL_DLL OGRCircularString : public OGRSimpleCurve
1568 {
1569   private:
1570     void        ExtendEnvelopeWithCircular( OGREnvelope * psEnvelope ) const;
1571     OGRBoolean  IsValidFast() const;
1572     int         IsFullCircle( double& cx, double& cy, double& square_R ) const;
1573 
1574   protected:
1575 //! @cond Doxygen_Suppress
1576     virtual OGRCurveCasterToLineString GetCasterToLineString()
1577         const override;
1578     virtual OGRCurveCasterToLinearRing GetCasterToLinearRing()
1579         const override;
1580     virtual int    IntersectsPoint( const OGRPoint* p ) const override;
1581     virtual int    ContainsPoint( const OGRPoint* p ) const override;
1582     virtual double get_AreaOfCurveSegments() const override;
1583 //! @endcond
1584 
1585   public:
1586     OGRCircularString();
1587     OGRCircularString( const OGRCircularString& other );
1588     ~OGRCircularString() override;
1589 
1590     OGRCircularString& operator=(const OGRCircularString& other);
1591 
1592     // IWks Interface.
1593     virtual OGRErr importFromWkb( const unsigned char *,
1594                                   size_t,
1595                                   OGRwkbVariant,
1596                                   size_t& nBytesConsumedOut ) override;
1597     virtual OGRErr exportToWkb( OGRwkbByteOrder, unsigned char *,
1598                                 OGRwkbVariant=wkbVariantOldOgc )
1599         const override;
1600 
1601 #ifndef DOXYGEN_XML
1602     using OGRGeometry::importFromWkt; /** deprecated */
1603 #endif
1604 
1605     OGRErr importFromWkt( const char ** ) override;
1606 
1607 #ifndef DOXYGEN_XML
1608     using OGRGeometry::exportToWkt;
1609 #endif
1610 
1611     /// Export a circular string to WKT
1612     /// \param opts  Output options.
1613     /// \param err   Pointer to error code, if desired.
1614     /// \return  WKT string representing this circular string.
1615     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
1616                                     OGRErr *err = nullptr) const override;
1617 
1618     // IGeometry interface.
1619     virtual OGRBoolean  IsValid() const override;
1620     virtual void getEnvelope( OGREnvelope * psEnvelope ) const override;
1621     virtual void getEnvelope( OGREnvelope3D * psEnvelope ) const override;
1622     virtual OGRCircularString *clone() const override;
1623 
1624     // ICurve methods.
1625     virtual double get_Length() const override;
1626     virtual OGRLineString* CurveToLine( double dfMaxAngleStepSizeDegrees = 0,
1627                                         const char* const* papszOptions = nullptr )
1628         const override;
1629     virtual void Value( double, OGRPoint * ) const override;
1630     virtual double get_Area() const override;
1631 
1632     // Non-standard from OGRGeometry.
1633     virtual OGRwkbGeometryType getGeometryType() const override;
1634     virtual const char *getGeometryName() const override;
1635     virtual void segmentize( double dfMaxLength ) override;
1636     virtual OGRBoolean hasCurveGeometry( int bLookForNonLinear = FALSE )
1637         const override;
1638     virtual OGRGeometry* getLinearGeometry(
1639         double dfMaxAngleStepSizeDegrees = 0,
1640         const char* const* papszOptions = nullptr) const override;
1641 
1642     /** Return pointer of this in upper class */
toUpperClass()1643     inline OGRSimpleCurve* toUpperClass() { return this; }
1644     /** Return pointer of this in upper class */
toUpperClass()1645     inline const OGRSimpleCurve* toUpperClass() const { return this; }
1646 
accept(IOGRGeometryVisitor * visitor)1647     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)1648     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
1649 
1650     OGR_ALLOW_UPCAST_TO(SimpleCurve)
1651     OGR_ALLOW_CAST_TO_THIS(CircularString)
1652 };
1653 
1654 /************************************************************************/
1655 /*                           OGRCurveCollection                         */
1656 /************************************************************************/
1657 
1658 /**
1659  * Utility class to store a collection of curves. Used as a member of
1660  * OGRCompoundCurve and OGRCurvePolygon.
1661  *
1662  * This class is only exported because of linking issues. It should never
1663  * be directly used.
1664  *
1665  * @since GDAL 2.0
1666  */
1667 
1668 //! @cond Doxygen_Suppress
1669 class CPL_DLL OGRCurveCollection
1670 {
1671   protected:
1672     friend class OGRCompoundCurve;
1673     friend class OGRCurvePolygon;
1674     friend class OGRPolygon;
1675     friend class OGRTriangle;
1676 
1677     int         nCurveCount = 0;
1678     OGRCurve  **papoCurves = nullptr;
1679 
1680   public:
1681                 OGRCurveCollection();
1682                 OGRCurveCollection(const OGRCurveCollection& other);
1683                ~OGRCurveCollection();
1684 
1685     OGRCurveCollection& operator=(const OGRCurveCollection& other);
1686 
1687     /** Type of child elements. */
1688     typedef OGRCurve ChildType;
1689 
1690     /** Return begin of curve iterator.
1691      * @since GDAL 2.3
1692      */
begin()1693     OGRCurve** begin() { return papoCurves; }
1694     /** Return end of curve iterator. */
end()1695     OGRCurve** end() { return papoCurves + nCurveCount; }
1696     /** Return begin of curve iterator.
1697      * @since GDAL 2.3
1698      */
begin()1699     const OGRCurve* const* begin() const { return papoCurves; }
1700     /** Return end of curve iterator. */
end()1701     const OGRCurve* const* end() const { return papoCurves + nCurveCount; }
1702 
1703     void            empty(OGRGeometry* poGeom);
1704     OGRBoolean      IsEmpty() const;
1705     void            getEnvelope( OGREnvelope * psEnvelope ) const;
1706     void            getEnvelope( OGREnvelope3D * psEnvelope ) const;
1707 
1708     OGRErr          addCurveDirectly( OGRGeometry* poGeom, OGRCurve* poCurve,
1709                                       int bNeedRealloc );
1710     size_t          WkbSize() const;
1711     OGRErr          importPreambleFromWkb( OGRGeometry* poGeom,
1712                                             const unsigned char * pabyData,
1713                                             size_t& nSize,
1714                                             size_t& nDataOffset,
1715                                             OGRwkbByteOrder& eByteOrder,
1716                                             size_t nMinSubGeomSize,
1717                                             OGRwkbVariant eWkbVariant );
1718     OGRErr      importBodyFromWkb(
1719                     OGRGeometry* poGeom,
1720                     const unsigned char * pabyData,
1721                     size_t nSize,
1722                     bool bAcceptCompoundCurve,
1723                     OGRErr (*pfnAddCurveDirectlyFromWkb)( OGRGeometry* poGeom,
1724                                                           OGRCurve* poCurve ),
1725                     OGRwkbVariant eWkbVariant,
1726                     size_t& nBytesConsumedOut );
1727     std::string     exportToWkt(const OGRGeometry *geom, const OGRWktOptions& opts,
1728                                 OGRErr *err) const;
1729     OGRErr          exportToWkb( const OGRGeometry* poGeom, OGRwkbByteOrder,
1730                                  unsigned char *,
1731                                  OGRwkbVariant eWkbVariant ) const;
1732     OGRBoolean      Equals(const OGRCurveCollection *poOCC) const;
1733     void            setCoordinateDimension( OGRGeometry* poGeom,
1734                                             int nNewDimension );
1735     void            set3D( OGRGeometry* poGeom, OGRBoolean bIs3D );
1736     void            setMeasured( OGRGeometry* poGeom, OGRBoolean bIsMeasured );
1737     void            assignSpatialReference( OGRGeometry* poGeom, OGRSpatialReference * poSR );
1738     int             getNumCurves() const;
1739     OGRCurve       *getCurve( int );
1740     const OGRCurve *getCurve( int ) const;
1741     OGRCurve       *stealCurve( int );
1742 
1743     OGRErr          removeCurve( int iIndex, bool bDelete = true );
1744 
1745     OGRErr          transform( OGRGeometry* poGeom,
1746                                OGRCoordinateTransformation *poCT );
1747     void            flattenTo2D( OGRGeometry* poGeom );
1748     void            segmentize( double dfMaxLength );
1749     void            swapXY();
1750     OGRBoolean      hasCurveGeometry(int bLookForNonLinear) const;
1751 };
1752 //! @endcond
1753 
1754 /************************************************************************/
1755 /*                            OGRCompoundCurve                          */
1756 /************************************************************************/
1757 
1758 /**
1759  * Concrete representation of a compound curve, made of curves: OGRLineString
1760  * and OGRCircularString. Each curve is connected by its first point to
1761  * the last point of the previous curve.
1762  *
1763  * Compatibility: ISO SQL/MM Part 3.
1764  *
1765  * @since GDAL 2.0
1766  */
1767 
1768 class CPL_DLL OGRCompoundCurve : public OGRCurve
1769 {
1770   private:
1771     OGRCurveCollection oCC{};
1772 
1773     OGRErr      addCurveDirectlyInternal( OGRCurve* poCurve,
1774                                           double dfToleranceEps,
1775                                           int bNeedRealloc );
1776     static OGRErr addCurveDirectlyFromWkt( OGRGeometry* poSelf,
1777                                            OGRCurve* poCurve );
1778     static OGRErr addCurveDirectlyFromWkb( OGRGeometry* poSelf,
1779                                            OGRCurve* poCurve );
1780     OGRLineString* CurveToLineInternal( double dfMaxAngleStepSizeDegrees,
1781                                         const char* const* papszOptions,
1782                                         int bIsLinearRing ) const;
1783     // cppcheck-suppress unusedPrivateFunction
1784     static OGRLineString* CasterToLineString( OGRCurve* poCurve );
1785     // cppcheck-suppress unusedPrivateFunction
1786     static OGRLinearRing* CasterToLinearRing( OGRCurve* poCurve );
1787 
1788   protected:
1789 //! @cond Doxygen_Suppress
1790     static OGRLineString* CastToLineString( OGRCompoundCurve* poCC );
1791     static OGRLinearRing* CastToLinearRing( OGRCompoundCurve* poCC );
1792 
1793     virtual OGRCurveCasterToLineString GetCasterToLineString()
1794         const override;
1795     virtual OGRCurveCasterToLinearRing GetCasterToLinearRing()
1796         const override;
1797 //! @endcond
1798 
1799   public:
1800     OGRCompoundCurve();
1801     OGRCompoundCurve( const OGRCompoundCurve& other );
1802     ~OGRCompoundCurve() override;
1803 
1804     OGRCompoundCurve& operator=( const OGRCompoundCurve& other );
1805 
1806     /** Type of child elements. */
1807     typedef OGRCurve ChildType;
1808 
1809     /** Return begin of curve iterator.
1810      * @since GDAL 2.3
1811      */
begin()1812     ChildType** begin() { return oCC.begin(); }
1813     /** Return end of curve iterator. */
end()1814     ChildType** end() { return oCC.end(); }
1815     /** Return begin of curve iterator.
1816      * @since GDAL 2.3
1817      */
begin()1818     const ChildType* const * begin() const { return oCC.begin(); }
1819     /** Return end of curve iterator. */
end()1820     const ChildType* const * end() const { return oCC.end(); }
1821 
1822     // IWks Interface
1823     virtual size_t WkbSize() const override;
1824     virtual OGRErr importFromWkb( const unsigned char *,
1825                                   size_t,
1826                                   OGRwkbVariant,
1827                                   size_t& nBytesConsumedOut ) override;
1828     virtual OGRErr exportToWkb( OGRwkbByteOrder, unsigned char *,
1829                                 OGRwkbVariant=wkbVariantOldOgc )
1830         const override;
1831 
1832 #ifndef DOXYGEN_XML
1833     using OGRGeometry::importFromWkt; /** deprecated */
1834 #endif
1835 
1836     OGRErr importFromWkt( const char ** ) override;
1837 
1838 #ifndef DOXYGEN_XML
1839     using OGRGeometry::exportToWkt;
1840 #endif
1841 
1842     /// Export a compound curve to WKT
1843     /// \param opts  Output options.
1844     /// \param err   Pointer to error code, if desired.
1845     /// \return      WKT representation of the compound curve.
1846     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
1847                                     OGRErr *err = nullptr) const override;
1848 
1849     // IGeometry interface.
1850     virtual OGRCompoundCurve *clone() const override;
1851     virtual void empty() override;
1852     virtual void getEnvelope( OGREnvelope * psEnvelope ) const override;
1853     virtual void getEnvelope( OGREnvelope3D * psEnvelope ) const override;
1854     virtual OGRBoolean  IsEmpty() const override;
1855 
1856     // ICurve methods.
1857     virtual double get_Length() const override;
1858     virtual void StartPoint( OGRPoint * ) const override;
1859     virtual void EndPoint( OGRPoint * ) const override;
1860     virtual void Value( double, OGRPoint * ) const override;
1861     virtual OGRLineString* CurveToLine( double dfMaxAngleStepSizeDegrees = 0,
1862                                         const char* const* papszOptions = nullptr )
1863         const override;
1864 
1865     virtual int getNumPoints() const override;
1866     virtual double get_AreaOfCurveSegments() const override;
1867     virtual double get_Area() const override;
1868 
1869     // ISpatialRelation.
1870     virtual OGRBoolean  Equals( const OGRGeometry * ) const override;
1871 
1872     // ICompoundCurve method.
1873     int             getNumCurves() const;
1874     OGRCurve       *getCurve( int );
1875     const OGRCurve *getCurve( int ) const;
1876 
1877     // Non-standard.
1878     virtual void setCoordinateDimension( int nDimension ) override;
1879     virtual void set3D( OGRBoolean bIs3D ) override;
1880     virtual void setMeasured( OGRBoolean bIsMeasured ) override;
1881 
1882     virtual void    assignSpatialReference( OGRSpatialReference * poSR ) override;
1883 
1884     OGRErr         addCurve( OGRCurve*, double dfToleranceEps = 1e-14  );
1885     OGRErr         addCurveDirectly( OGRCurve*, double dfToleranceEps = 1e-14 );
1886     OGRCurve      *stealCurve( int );
1887     virtual OGRPointIterator* getPointIterator() const override;
1888 
1889     // Non-standard from OGRGeometry.
1890     virtual OGRwkbGeometryType getGeometryType() const override;
1891     virtual const char *getGeometryName() const override;
1892     virtual OGRErr  transform( OGRCoordinateTransformation *poCT ) override;
1893     virtual void flattenTo2D() override;
1894     virtual void segmentize(double dfMaxLength) override;
1895     virtual OGRBoolean hasCurveGeometry(int bLookForNonLinear = FALSE)
1896         const override;
1897     virtual OGRGeometry* getLinearGeometry(
1898         double dfMaxAngleStepSizeDegrees = 0,
1899         const char* const* papszOptions = nullptr) const override;
accept(IOGRGeometryVisitor * visitor)1900     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)1901     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
1902 
1903     virtual void        swapXY() override;
1904 
1905     OGR_ALLOW_UPCAST_TO(Curve)
1906     OGR_ALLOW_CAST_TO_THIS(CompoundCurve)
1907 };
1908 
1909 //! @cond Doxygen_Suppress
1910 /** @see OGRCompoundCurve::begin() const */
begin(const OGRCompoundCurve * poCurve)1911 inline const OGRCompoundCurve::ChildType* const * begin(const OGRCompoundCurve* poCurve) { return poCurve->begin(); }
1912 /** @see OGRCompoundCurve::end() const */
end(const OGRCompoundCurve * poCurve)1913 inline const OGRCompoundCurve::ChildType* const * end(const OGRCompoundCurve* poCurve) { return poCurve->end(); }
1914 
1915 /** @see OGRCompoundCurve::begin() */
begin(OGRCompoundCurve * poCurve)1916 inline OGRCompoundCurve::ChildType** begin(OGRCompoundCurve* poCurve) { return poCurve->begin(); }
1917 /** @see OGRCompoundCurve::end() */
end(OGRCompoundCurve * poCurve)1918 inline OGRCompoundCurve::ChildType** end(OGRCompoundCurve* poCurve) { return poCurve->end(); }
1919 //! @endcond
1920 
1921 /************************************************************************/
1922 /*                              OGRSurface                              */
1923 /************************************************************************/
1924 
1925 /**
1926  * Abstract base class for 2 dimensional objects like polygons or curve
1927  * polygons.
1928  */
1929 
1930 class CPL_DLL OGRSurface : public OGRGeometry
1931 {
1932   protected:
1933 //! @cond Doxygen_Suppress
1934     virtual OGRSurfaceCasterToPolygon      GetCasterToPolygon() const = 0;
1935     virtual OGRSurfaceCasterToCurvePolygon GetCasterToCurvePolygon() const = 0;
1936 //! @endcond
1937 
1938   public:
1939     virtual double      get_Area() const = 0;
PointOnSurface(OGRPoint * poPoint)1940     virtual OGRErr      PointOnSurface( OGRPoint * poPoint ) const
1941                                 { return PointOnSurfaceInternal(poPoint); }
1942     virtual OGRSurface *clone() const override = 0;
1943 
1944 //! @cond Doxygen_Suppress
1945     static OGRPolygon*      CastToPolygon(OGRSurface* poSurface);
1946     static OGRCurvePolygon* CastToCurvePolygon(OGRSurface* poSurface);
1947 //! @endcond
1948 
1949     OGR_FORBID_DOWNCAST_TO_POINT
1950     OGR_FORBID_DOWNCAST_TO_ALL_CURVES
1951     OGR_ALLOW_CAST_TO_THIS(Surface)
1952     OGR_FORBID_DOWNCAST_TO_ALL_MULTI
1953 };
1954 
1955 /************************************************************************/
1956 /*                          OGRCurvePolygon                             */
1957 /************************************************************************/
1958 
1959 /**
1960  * Concrete class representing curve polygons.
1961  *
1962  * Note that curve polygons consist of one outer (curve) ring, and zero or
1963  * more inner rings.  A curve polygon cannot represent disconnected
1964  * regions (such as multiple islands in a political body).  The
1965  * OGRMultiSurface must be used for this.
1966  *
1967  * Compatibility: ISO SQL/MM Part 3.
1968  *
1969  * @since GDAL 2.0
1970  */
1971 
1972 class CPL_DLL OGRCurvePolygon : public OGRSurface
1973 {
1974     static OGRPolygon*      CasterToPolygon(OGRSurface* poSurface);
1975 
1976   private:
1977     OGRBoolean      IntersectsPoint( const OGRPoint* p ) const;
1978     OGRBoolean      ContainsPoint( const OGRPoint* p ) const;
1979     virtual int   checkRing( OGRCurve * poNewRing ) const;
1980     OGRErr        addRingDirectlyInternal( OGRCurve* poCurve,
1981                                            int bNeedRealloc );
1982     static OGRErr addCurveDirectlyFromWkt( OGRGeometry* poSelf,
1983                                            OGRCurve* poCurve );
1984     static OGRErr addCurveDirectlyFromWkb( OGRGeometry* poSelf,
1985                                            OGRCurve* poCurve );
1986 
1987   protected:
1988 //! @cond Doxygen_Suppress
1989     friend class OGRPolygon;
1990     friend class OGRTriangle;
1991     OGRCurveCollection oCC{};
1992 
1993     virtual OGRSurfaceCasterToPolygon      GetCasterToPolygon()
1994         const override;
1995     virtual OGRSurfaceCasterToCurvePolygon GetCasterToCurvePolygon()
1996         const override;
1997 
1998 //! @endcond
1999 
2000     static OGRPolygon* CastToPolygon( OGRCurvePolygon* poCP );
2001 
2002   public:
2003     OGRCurvePolygon();
2004     OGRCurvePolygon( const OGRCurvePolygon& );
2005     ~OGRCurvePolygon() override;
2006 
2007     OGRCurvePolygon& operator=( const OGRCurvePolygon& other );
2008 
2009     /** Type of child elements. */
2010     typedef OGRCurve ChildType;
2011 
2012     /** Return begin of curve iterator.
2013      * @since GDAL 2.3
2014      */
begin()2015     ChildType** begin() { return oCC.begin(); }
2016     /** Return end of curve iterator. */
end()2017     ChildType** end() { return oCC.end(); }
2018     /** Return begin of curve iterator.
2019      * @since GDAL 2.3
2020      */
begin()2021     const ChildType* const * begin() const { return oCC.begin(); }
2022     /** Return end of curve iterator. */
end()2023     const ChildType* const * end() const { return oCC.end(); }
2024 
2025     // Non standard (OGRGeometry).
2026     virtual const char *getGeometryName() const override;
2027     virtual OGRwkbGeometryType getGeometryType() const override;
2028     virtual OGRCurvePolygon *clone() const override;
2029     virtual void empty() override;
2030     virtual OGRErr  transform( OGRCoordinateTransformation *poCT ) override;
2031     virtual void flattenTo2D() override;
2032     virtual OGRBoolean  IsEmpty() const override;
2033     virtual void segmentize( double dfMaxLength ) override;
2034     virtual OGRBoolean hasCurveGeometry( int bLookForNonLinear = FALSE )
2035         const override;
2036     virtual OGRGeometry* getLinearGeometry(
2037         double dfMaxAngleStepSizeDegrees = 0,
2038         const char* const* papszOptions = nullptr ) const override;
2039 
2040     // ISurface Interface
2041     virtual double      get_Area() const override;
2042 
2043     // IWks Interface
2044     virtual size_t WkbSize() const override;
2045     virtual OGRErr importFromWkb( const unsigned char *,
2046                                   size_t,
2047                                   OGRwkbVariant,
2048                                   size_t& nBytesConsumedOut ) override;
2049     virtual OGRErr exportToWkb( OGRwkbByteOrder, unsigned char *,
2050                                 OGRwkbVariant=wkbVariantOldOgc )
2051         const override;
2052 
2053 #ifndef DOXYGEN_XML
2054     using OGRGeometry::importFromWkt; /** deprecated */
2055 #endif
2056 
2057     OGRErr importFromWkt( const char ** ) override;
2058 
2059 #ifndef DOXYGEN_XML
2060     using OGRGeometry::exportToWkt;
2061 #endif
2062 
2063     /// Export a curve polygon to WKT
2064     /// \param opts  Output options.
2065     /// \param err   Pointer to error code, if desired.
2066     /// \return      WKT representation of the curve polygon.
2067     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
2068                                     OGRErr *err = nullptr) const override;
2069 
2070     // IGeometry
2071     virtual int getDimension() const override;
2072     virtual void getEnvelope( OGREnvelope * psEnvelope ) const override;
2073     virtual void getEnvelope( OGREnvelope3D * psEnvelope ) const override;
2074 
2075     // ICurvePolygon
2076     virtual OGRPolygon* CurvePolyToPoly(
2077         double dfMaxAngleStepSizeDegrees = 0,
2078         const char* const* papszOptions = nullptr ) const;
2079 
2080     // ISpatialRelation
2081     virtual OGRBoolean  Equals( const OGRGeometry * ) const override;
2082     virtual OGRBoolean  Intersects( const OGRGeometry * ) const override;
2083     virtual OGRBoolean  Contains( const OGRGeometry * ) const override;
2084 
2085     // Non standard
2086     virtual void setCoordinateDimension( int nDimension ) override;
2087     virtual void set3D( OGRBoolean bIs3D ) override;
2088     virtual void setMeasured( OGRBoolean bIsMeasured ) override;
2089 
2090     virtual void    assignSpatialReference( OGRSpatialReference * poSR ) override;
2091 
2092     virtual OGRErr addRing( OGRCurve * );
2093     virtual OGRErr addRingDirectly( OGRCurve * );
2094 
2095     OGRCurve *getExteriorRingCurve();
2096     const OGRCurve *getExteriorRingCurve() const;
2097     int         getNumInteriorRings() const;
2098     OGRCurve *getInteriorRingCurve( int );
2099     const OGRCurve *getInteriorRingCurve( int ) const;
2100 
2101     OGRCurve *stealExteriorRingCurve();
2102 
2103     OGRErr removeRing( int iIndex, bool bDelete = true );
accept(IOGRGeometryVisitor * visitor)2104     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)2105     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
2106 
2107     virtual void        swapXY() override;
2108 
2109     OGR_ALLOW_UPCAST_TO(Surface)
2110     OGR_ALLOW_CAST_TO_THIS(CurvePolygon)
2111 };
2112 
2113 //! @cond Doxygen_Suppress
2114 /** @see OGRCurvePolygon::begin() const */
begin(const OGRCurvePolygon * poGeom)2115 inline const OGRCurvePolygon::ChildType* const * begin(const OGRCurvePolygon* poGeom) { return poGeom->begin(); }
2116 /** @see OGRCurvePolygon::end() const */
end(const OGRCurvePolygon * poGeom)2117 inline const OGRCurvePolygon::ChildType* const * end(const OGRCurvePolygon* poGeom) { return poGeom->end(); }
2118 
2119 /** @see OGRCurvePolygon::begin() */
begin(OGRCurvePolygon * poGeom)2120 inline OGRCurvePolygon::ChildType** begin(OGRCurvePolygon* poGeom) { return poGeom->begin(); }
2121 /** @see OGRCurvePolygon::end() */
end(OGRCurvePolygon * poGeom)2122 inline OGRCurvePolygon::ChildType** end(OGRCurvePolygon* poGeom) { return poGeom->end(); }
2123 //! @endcond
2124 
2125 /************************************************************************/
2126 /*                              OGRPolygon                              */
2127 /************************************************************************/
2128 
2129 /**
2130  * Concrete class representing polygons.
2131  *
2132  * Note that the OpenGIS simple features polygons consist of one outer ring
2133  * (linearring), and zero or more inner rings.  A polygon cannot represent
2134  * disconnected regions (such as multiple islands in a political body).  The
2135  * OGRMultiPolygon must be used for this.
2136  */
2137 
2138 class CPL_DLL OGRPolygon : public OGRCurvePolygon
2139 {
2140     static OGRCurvePolygon*     CasterToCurvePolygon(OGRSurface* poSurface);
2141 
2142   protected:
2143 //! @cond Doxygen_Suppress
2144     friend class OGRMultiSurface;
2145     friend class OGRPolyhedralSurface;
2146     friend class OGRTriangulatedSurface;
2147 
2148     virtual int checkRing( OGRCurve * poNewRing ) const override;
2149     virtual OGRErr importFromWKTListOnly( const char ** ppszInput,
2150                                           int bHasZ, int bHasM,
2151                                           OGRRawPoint*& paoPoints,
2152                                           int& nMaxPoints,
2153                                           double*& padfZ );
2154 
2155     static OGRCurvePolygon* CastToCurvePolygon(OGRPolygon* poPoly);
2156 
2157     virtual OGRSurfaceCasterToPolygon      GetCasterToPolygon()
2158         const override;
2159     virtual OGRSurfaceCasterToCurvePolygon GetCasterToCurvePolygon()
2160         const override;
2161 //! @endcond
2162 
2163   public:
2164     OGRPolygon();
2165     OGRPolygon(const OGRPolygon& other);
2166     ~OGRPolygon() override;
2167 
2168     OGRPolygon& operator=(const OGRPolygon& other);
2169 
2170     /** Type of child elements. */
2171     typedef OGRLinearRing ChildType;
2172 
2173     /** Return begin of iterator.
2174      * @since GDAL 2.3
2175      */
begin()2176     ChildType** begin() { return reinterpret_cast<ChildType**>(oCC.begin()); }
2177     /** Return end of iterator */
end()2178     ChildType** end() { return reinterpret_cast<ChildType**>(oCC.end()); }
2179     /** Return begin of iterator.
2180      * @since GDAL 2.3
2181      */
begin()2182     const ChildType* const* begin() const { return reinterpret_cast<const ChildType* const*>(oCC.begin()); }
2183     /** Return end of iterator */
end()2184     const ChildType* const* end() const { return reinterpret_cast<const ChildType* const*>(oCC.end()); }
2185 
2186     // Non-standard (OGRGeometry).
2187     virtual const char *getGeometryName() const override;
2188     virtual OGRwkbGeometryType getGeometryType() const override;
2189     virtual OGRPolygon *clone() const override;
2190     virtual OGRBoolean hasCurveGeometry( int bLookForNonLinear = FALSE )
2191         const override;
2192     virtual OGRGeometry* getCurveGeometry(
2193     const char* const* papszOptions = nullptr ) const override;
2194     virtual OGRGeometry* getLinearGeometry(
2195         double dfMaxAngleStepSizeDegrees = 0,
2196         const char* const* papszOptions = nullptr) const override;
2197 
2198     // IWks Interface.
2199     virtual size_t WkbSize() const override;
2200     virtual OGRErr importFromWkb( const unsigned char *,
2201                                   size_t,
2202                                   OGRwkbVariant,
2203                                   size_t& nBytesConsumedOut ) override;
2204     virtual OGRErr exportToWkb( OGRwkbByteOrder, unsigned char *,
2205                                 OGRwkbVariant=wkbVariantOldOgc )
2206         const override;
2207 
2208 #ifndef DOXYGEN_XML
2209     using OGRGeometry::importFromWkt; /** deprecated */
2210 #endif
2211 
2212     OGRErr importFromWkt( const char ** ) override;
2213 
2214 #ifndef DOXYGEN_XML
2215     using OGRGeometry::exportToWkt;
2216 #endif
2217 
2218     /// Export a polygon to WKT
2219     /// \param opts  Output options.
2220     /// \param err   Pointer to error code, if desired.
2221     /// \return      WKT representation of the polygon.
2222     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
2223                                     OGRErr *err = nullptr) const override;
2224 
2225     // ICurvePolygon.
2226     virtual OGRPolygon* CurvePolyToPoly(
2227         double dfMaxAngleStepSizeDegrees = 0,
2228         const char* const* papszOptions = nullptr ) const override;
2229 
2230     OGRLinearRing *getExteriorRing();
2231     const OGRLinearRing *getExteriorRing() const;
2232     virtual OGRLinearRing *getInteriorRing( int );
2233     virtual const OGRLinearRing *getInteriorRing( int ) const;
2234 
2235     OGRLinearRing *stealExteriorRing();
2236     virtual OGRLinearRing *stealInteriorRing(int);
2237 
2238     OGRBoolean IsPointOnSurface( const OGRPoint * ) const;
2239 
2240     /** Return pointer of this in upper class */
toUpperClass()2241     inline OGRCurvePolygon* toUpperClass() { return this; }
2242     /** Return pointer of this in upper class */
toUpperClass()2243     inline const OGRCurvePolygon* toUpperClass() const { return this; }
2244 
accept(IOGRGeometryVisitor * visitor)2245     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)2246     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
2247 
2248     virtual void closeRings() override;
2249 
2250     OGR_ALLOW_UPCAST_TO(CurvePolygon)
2251     OGR_ALLOW_CAST_TO_THIS(Polygon)
2252 };
2253 
2254 //! @cond Doxygen_Suppress
2255 /** @see OGRPolygon::begin() const */
begin(const OGRPolygon * poGeom)2256 inline const OGRPolygon::ChildType* const * begin(const OGRPolygon* poGeom) { return poGeom->begin(); }
2257 /** @see OGRPolygon::end() const */
end(const OGRPolygon * poGeom)2258 inline const OGRPolygon::ChildType* const * end(const OGRPolygon* poGeom) { return poGeom->end(); }
2259 
2260 /** @see OGRPolygon::begin() */
begin(OGRPolygon * poGeom)2261 inline OGRPolygon::ChildType** begin(OGRPolygon* poGeom) { return poGeom->begin(); }
2262 /** @see OGRPolygon::end() */
end(OGRPolygon * poGeom)2263 inline OGRPolygon::ChildType** end(OGRPolygon* poGeom) { return poGeom->end(); }
2264 //! @endcond
2265 
2266 /************************************************************************/
2267 /*                              OGRTriangle                             */
2268 /************************************************************************/
2269 
2270 /**
2271  * Triangle class.
2272  *
2273  * @since GDAL 2.2
2274  */
2275 
2276 class CPL_DLL OGRTriangle : public OGRPolygon
2277 {
2278   private:
2279     // cppcheck-suppress unusedPrivateFunction
2280     static OGRPolygon*          CasterToPolygon(OGRSurface* poSurface);
2281     bool quickValidityCheck() const;
2282 
2283   protected:
2284 //! @cond Doxygen_Suppress
2285     virtual OGRSurfaceCasterToPolygon   GetCasterToPolygon() const override;
2286     virtual OGRErr importFromWKTListOnly( const char ** ppszInput,
2287                                           int bHasZ, int bHasM,
2288                                           OGRRawPoint*& paoPoints,
2289                                           int& nMaxPoints,
2290                                           double*& padfZ ) override;
2291 //! @endcond
2292 
2293   public:
2294     OGRTriangle();
2295     OGRTriangle( const OGRPoint &p, const OGRPoint &q, const OGRPoint &r );
2296     OGRTriangle( const OGRTriangle &other );
2297     OGRTriangle( const OGRPolygon &other, OGRErr &eErr );
2298     OGRTriangle& operator=( const OGRTriangle& other );
2299     ~OGRTriangle() override;
2300     virtual const char *getGeometryName() const override;
2301     virtual OGRwkbGeometryType getGeometryType() const override;
2302     virtual OGRTriangle *clone() const override;
2303 
2304     // IWks Interface.
2305     virtual OGRErr importFromWkb( const unsigned char *,
2306                                   size_t,
2307                                   OGRwkbVariant,
2308                                   size_t& nBytesConsumedOut ) override;
2309 
2310     // New methods rewritten from OGRPolygon/OGRCurvePolygon/OGRGeometry.
2311     virtual OGRErr addRingDirectly( OGRCurve * poNewRing ) override;
2312 
2313     /** Return pointer of this in upper class */
toUpperClass()2314     inline OGRPolygon* toUpperClass() { return this; }
2315     /** Return pointer of this in upper class */
toUpperClass()2316     inline const OGRPolygon* toUpperClass() const { return this; }
2317 
accept(IOGRGeometryVisitor * visitor)2318     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)2319     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
2320 
2321 //! @cond Doxygen_Suppress
2322     static OGRGeometry* CastToPolygon( OGRGeometry* poGeom );
2323 //! @endcond
2324 
2325     OGR_ALLOW_UPCAST_TO(Polygon)
2326     OGR_ALLOW_CAST_TO_THIS(Triangle)
2327 };
2328 
2329 /************************************************************************/
2330 /*                        OGRGeometryCollection                         */
2331 /************************************************************************/
2332 
2333 /**
2334  * A collection of 1 or more geometry objects.
2335  *
2336  * All geometries must share a common spatial reference system, and
2337  * Subclasses may impose additional restrictions on the contents.
2338  */
2339 
2340 class CPL_DLL OGRGeometryCollection : public OGRGeometry
2341 {
2342     OGRErr      importFromWkbInternal( const unsigned char * pabyData,
2343                                        size_t nSize,
2344                                        int nRecLevel,
2345                                        OGRwkbVariant, size_t& nBytesConsumedOut );
2346     OGRErr      importFromWktInternal( const char **ppszInput, int nRecLevel );
2347 
2348   protected:
2349 //! @cond Doxygen_Suppress
2350     int         nGeomCount = 0;
2351     OGRGeometry **papoGeoms = nullptr;
2352 
2353     std::string exportToWktInternal(const OGRWktOptions& opts, OGRErr *err,
2354         std::string exclude = std::string()) const;
2355     static OGRGeometryCollection* TransferMembersAndDestroy(
2356         OGRGeometryCollection* poSrc,
2357         OGRGeometryCollection* poDst );
2358 //! @endcond
2359     virtual OGRBoolean         isCompatibleSubType( OGRwkbGeometryType ) const;
2360 
2361   public:
2362     OGRGeometryCollection();
2363     OGRGeometryCollection( const OGRGeometryCollection& other );
2364     ~OGRGeometryCollection() override;
2365 
2366     OGRGeometryCollection& operator=( const OGRGeometryCollection& other );
2367 
2368     /** Type of child elements. */
2369     typedef OGRGeometry ChildType;
2370 
2371     /** Return begin of sub-geometry iterator.
2372      * @since GDAL 2.3
2373      */
begin()2374     ChildType** begin() { return papoGeoms; }
2375     /** Return end of sub-geometry iterator. */
end()2376     ChildType** end() { return papoGeoms + nGeomCount; }
2377     /** Return begin of sub-geometry iterator.
2378      * @since GDAL 2.3
2379      */
begin()2380     const ChildType* const* begin() const { return papoGeoms; }
2381     /** Return end of sub-geometry iterator. */
end()2382     const ChildType* const* end() const { return papoGeoms + nGeomCount; }
2383 
2384     // Non standard (OGRGeometry).
2385     virtual const char *getGeometryName() const override;
2386     virtual OGRwkbGeometryType getGeometryType() const override;
2387     virtual OGRGeometryCollection *clone() const override;
2388     virtual void empty() override;
2389     virtual OGRErr  transform( OGRCoordinateTransformation *poCT ) override;
2390     virtual void flattenTo2D() override;
2391     virtual OGRBoolean  IsEmpty() const override;
2392     virtual void segmentize(double dfMaxLength) override;
2393     virtual OGRBoolean hasCurveGeometry( int bLookForNonLinear = FALSE )
2394         const override;
2395     virtual OGRGeometry* getCurveGeometry(
2396         const char* const* papszOptions = nullptr ) const override;
2397     virtual OGRGeometry* getLinearGeometry(
2398         double dfMaxAngleStepSizeDegrees = 0,
2399         const char* const* papszOptions = nullptr ) const override;
2400 
2401     // IWks Interface
2402     virtual size_t WkbSize() const override;
2403     virtual OGRErr importFromWkb( const unsigned char *,
2404                                   size_t,
2405                                   OGRwkbVariant,
2406                                   size_t& nBytesConsumedOut ) override;
2407     virtual OGRErr exportToWkb( OGRwkbByteOrder, unsigned char *,
2408                                 OGRwkbVariant=wkbVariantOldOgc )
2409         const override;
2410 
2411 #ifndef DOXYGEN_XML
2412     using OGRGeometry::importFromWkt; /** deprecated */
2413 #endif
2414 
2415     OGRErr importFromWkt( const char ** ) override;
2416 
2417 #ifndef DOXYGEN_XML
2418     using OGRGeometry::exportToWkt;
2419 #endif
2420 
2421     /// Export a geometry collection to WKT
2422     /// \param opts  Output options.
2423     /// \param err   Pointer to error code, if desired.
2424     /// \return      WKT representation of the geometry collection.
2425     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
2426                                     OGRErr *err = nullptr) const override;
2427 
2428     virtual double get_Length() const;
2429     virtual double get_Area() const;
2430 
2431     // IGeometry methods
2432     virtual int getDimension() const override;
2433     virtual void getEnvelope( OGREnvelope * psEnvelope ) const override;
2434     virtual void getEnvelope( OGREnvelope3D * psEnvelope ) const override;
2435 
2436     // IGeometryCollection
2437     int         getNumGeometries() const;
2438     OGRGeometry *getGeometryRef( int );
2439     const OGRGeometry *getGeometryRef( int ) const;
2440 
2441     // ISpatialRelation
2442     virtual OGRBoolean  Equals( const OGRGeometry * ) const override;
2443 
2444     // Non standard
2445     virtual void setCoordinateDimension( int nDimension ) override;
2446     virtual void set3D( OGRBoolean bIs3D ) override;
2447     virtual void setMeasured( OGRBoolean bIsMeasured ) override;
2448     virtual OGRErr addGeometry( const OGRGeometry * );
2449     virtual OGRErr addGeometryDirectly( OGRGeometry * );
2450     virtual OGRErr removeGeometry( int iIndex, int bDelete = TRUE );
2451 
2452     virtual void    assignSpatialReference( OGRSpatialReference * poSR ) override;
2453 
2454     void closeRings() override;
2455 
2456     virtual void swapXY() override;
2457 
accept(IOGRGeometryVisitor * visitor)2458     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)2459     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
2460 
2461     static OGRGeometryCollection* CastToGeometryCollection(
2462         OGRGeometryCollection* poSrc );
2463 
2464     OGR_FORBID_DOWNCAST_TO_POINT
2465     OGR_FORBID_DOWNCAST_TO_ALL_CURVES
2466     OGR_FORBID_DOWNCAST_TO_ALL_SURFACES
2467     OGR_ALLOW_CAST_TO_THIS(GeometryCollection)
2468 };
2469 
2470 //! @cond Doxygen_Suppress
2471 /** @see OGRGeometryCollection::begin() const */
begin(const OGRGeometryCollection * poGeom)2472 inline const OGRGeometryCollection::ChildType* const * begin(const OGRGeometryCollection* poGeom) { return poGeom->begin(); }
2473 /** @see OGRGeometryCollection::end() const */
end(const OGRGeometryCollection * poGeom)2474 inline const OGRGeometryCollection::ChildType* const * end(const OGRGeometryCollection* poGeom) { return poGeom->end(); }
2475 
2476 /** @see OGRGeometryCollection::begin() */
begin(OGRGeometryCollection * poGeom)2477 inline OGRGeometryCollection::ChildType** begin(OGRGeometryCollection* poGeom) { return poGeom->begin(); }
2478 /** @see OGRGeometryCollection::end() */
end(OGRGeometryCollection * poGeom)2479 inline OGRGeometryCollection::ChildType** end(OGRGeometryCollection* poGeom) { return poGeom->end(); }
2480 //! @endcond
2481 
2482 /************************************************************************/
2483 /*                          OGRMultiSurface                             */
2484 /************************************************************************/
2485 
2486 /**
2487  * A collection of non-overlapping OGRSurface.
2488  *
2489  * @since GDAL 2.0
2490  */
2491 
2492 class CPL_DLL OGRMultiSurface : public OGRGeometryCollection
2493 {
2494   protected:
2495     virtual OGRBoolean isCompatibleSubType( OGRwkbGeometryType )
2496         const override;
2497 
2498   public:
2499     OGRMultiSurface();
2500     OGRMultiSurface( const OGRMultiSurface& other );
2501     ~OGRMultiSurface() override;
2502 
2503     OGRMultiSurface& operator=( const OGRMultiSurface& other );
2504 
2505     /** Type of child elements. */
2506     typedef OGRSurface ChildType;
2507 
2508     /** Return begin of iterator.
2509      * @since GDAL 2.3
2510      */
begin()2511     ChildType** begin() { return reinterpret_cast<ChildType**>(papoGeoms); }
2512     /** Return end of iterator */
end()2513     ChildType** end() { return reinterpret_cast<ChildType**>(papoGeoms + nGeomCount); }
2514     /** Return begin of iterator.
2515      * @since GDAL 2.3
2516      */
begin()2517     const ChildType* const* begin() const { return reinterpret_cast<const ChildType* const*>(papoGeoms); }
2518     /** Return end of iterator */
end()2519     const ChildType* const* end() const { return reinterpret_cast<const ChildType* const*>(papoGeoms + nGeomCount); }
2520 
2521     // Non standard (OGRGeometry).
2522     virtual const char *getGeometryName() const override;
2523     virtual OGRwkbGeometryType getGeometryType() const override;
2524     virtual OGRMultiSurface *clone() const override;
2525 
2526 #ifndef DOXYGEN_XML
2527     using OGRGeometry::importFromWkt; /** deprecated */
2528 #endif
2529 
2530     OGRErr importFromWkt( const char ** ) override;
2531 
2532 #ifndef DOXYGEN_XML
2533     using OGRGeometry::exportToWkt;
2534 #endif
2535 
2536     /// Export a geometry collection to WKT
2537     /// \param opts  Output options.
2538     /// \param err   Pointer to error code, if desired.
2539     /// \return      WKT representation of the geometry collection.
2540     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
2541                                     OGRErr *err = nullptr) const override;
2542 
2543     // IMultiSurface methods
2544     virtual OGRErr PointOnSurface( OGRPoint * poPoint ) const;
2545 
2546     // IGeometry methods
2547     virtual int getDimension() const override;
2548 
2549     // IGeometryCollection
2550     /** See OGRGeometryCollection::getGeometryRef() */
getGeometryRef(int i)2551     OGRSurface *getGeometryRef( int i) { return OGRGeometryCollection::getGeometryRef(i)->toSurface(); }
2552     /** See OGRGeometryCollection::getGeometryRef() */
getGeometryRef(int i)2553     const OGRSurface *getGeometryRef( int i ) const { return OGRGeometryCollection::getGeometryRef(i)->toSurface(); }
2554 
2555     // Non standard
2556     virtual OGRBoolean hasCurveGeometry( int bLookForNonLinear = FALSE )
2557         const override;
2558 
2559     /** Return pointer of this in upper class */
toUpperClass()2560     inline OGRGeometryCollection* toUpperClass() { return this; }
2561     /** Return pointer of this in upper class */
toUpperClass()2562     inline const OGRGeometryCollection* toUpperClass() const { return this; }
2563 
accept(IOGRGeometryVisitor * visitor)2564     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)2565     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
2566 
2567     static OGRMultiPolygon* CastToMultiPolygon( OGRMultiSurface* poMS );
2568 
2569     OGR_ALLOW_CAST_TO_THIS(MultiSurface)
2570     OGR_ALLOW_UPCAST_TO(GeometryCollection)
2571     OGR_FORBID_DOWNCAST_TO_MULTIPOINT
2572     OGR_FORBID_DOWNCAST_TO_MULTILINESTRING
2573     OGR_FORBID_DOWNCAST_TO_MULTICURVE
2574 };
2575 
2576 //! @cond Doxygen_Suppress
2577 /** @see OGRMultiSurface::begin() const */
begin(const OGRMultiSurface * poGeom)2578 inline const OGRMultiSurface::ChildType* const * begin(const OGRMultiSurface* poGeom) { return poGeom->begin(); }
2579 /** @see OGRMultiSurface::end() const */
end(const OGRMultiSurface * poGeom)2580 inline const OGRMultiSurface::ChildType* const * end(const OGRMultiSurface* poGeom) { return poGeom->end(); }
2581 
2582 /** @see OGRMultiSurface::begin() */
begin(OGRMultiSurface * poGeom)2583 inline OGRMultiSurface::ChildType** begin(OGRMultiSurface* poGeom) { return poGeom->begin(); }
2584 /** @see OGRMultiSurface::end() */
end(OGRMultiSurface * poGeom)2585 inline OGRMultiSurface::ChildType** end(OGRMultiSurface* poGeom) { return poGeom->end(); }
2586 //! @endcond
2587 
2588 /************************************************************************/
2589 /*                           OGRMultiPolygon                            */
2590 /************************************************************************/
2591 
2592 /**
2593  * A collection of non-overlapping OGRPolygon.
2594  */
2595 
2596 class CPL_DLL OGRMultiPolygon : public OGRMultiSurface
2597 {
2598   protected:
2599     virtual OGRBoolean isCompatibleSubType( OGRwkbGeometryType )
2600         const override;
2601     friend class OGRPolyhedralSurface;
2602     friend class OGRTriangulatedSurface;
2603 
2604   private:
2605 //! @cond Doxygen_Suppress
2606             OGRErr _addGeometryWithExpectedSubGeometryType(
2607                 const OGRGeometry * poNewGeom,
2608                 OGRwkbGeometryType eSubGeometryType );
2609             OGRErr _addGeometryDirectlyWithExpectedSubGeometryType(
2610                 OGRGeometry * poNewGeom,
2611                 OGRwkbGeometryType eSubGeometryType );
2612 //! @endcond
2613 
2614 
2615   public:
2616     OGRMultiPolygon();
2617     OGRMultiPolygon( const OGRMultiPolygon& other );
2618     ~OGRMultiPolygon() override;
2619 
2620     OGRMultiPolygon& operator=(const OGRMultiPolygon& other);
2621 
2622     /** Type of child elements. */
2623     typedef OGRPolygon ChildType;
2624 
2625     /** Return begin of iterator.
2626      * @since GDAL 2.3
2627      */
begin()2628     ChildType** begin() { return reinterpret_cast<ChildType**>(papoGeoms); }
2629     /** Return end of iterator */
end()2630     ChildType** end() { return reinterpret_cast<ChildType**>(papoGeoms + nGeomCount); }
2631     /** Return begin of iterator.
2632      * @since GDAL 2.3
2633      */
begin()2634     const ChildType* const* begin() const { return reinterpret_cast<const ChildType* const*>(papoGeoms); }
2635     /** Return end of iterator */
end()2636     const ChildType* const* end() const { return reinterpret_cast<const ChildType* const*>(papoGeoms + nGeomCount); }
2637 
2638     // IGeometryCollection
2639     /** See OGRGeometryCollection::getGeometryRef() */
getGeometryRef(int i)2640     OGRPolygon *getGeometryRef( int i) { return OGRGeometryCollection::getGeometryRef(i)->toPolygon(); }
2641     /** See OGRGeometryCollection::getGeometryRef() */
getGeometryRef(int i)2642     const OGRPolygon *getGeometryRef( int i ) const { return OGRGeometryCollection::getGeometryRef(i)->toPolygon(); }
2643 
2644     // Non-standard (OGRGeometry).
2645     virtual const char *getGeometryName() const override;
2646     virtual OGRwkbGeometryType getGeometryType() const override;
2647     virtual OGRMultiPolygon *clone() const override;
2648 
2649 #ifndef DOXYGEN_XML
2650     using OGRGeometry::exportToWkt;
2651 #endif
2652 
2653     /// Export a multipolygon to WKT
2654     /// \param opts  Output options.
2655     /// \param err   Pointer to error code, if desired.
2656     /// \return      WKT representation of the multipolygon.
2657     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
2658                                     OGRErr *err = nullptr) const override;
2659 
2660     // Non standard
2661     virtual OGRBoolean hasCurveGeometry( int bLookForNonLinear = FALSE )
2662         const override;
2663 
2664         /** Return pointer of this in upper class */
toUpperClass()2665     inline OGRGeometryCollection* toUpperClass() { return this; }
2666     /** Return pointer of this in upper class */
toUpperClass()2667     inline const OGRGeometryCollection* toUpperClass() const { return this; }
2668 
accept(IOGRGeometryVisitor * visitor)2669     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)2670     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
2671 
2672     static OGRMultiSurface* CastToMultiSurface( OGRMultiPolygon* poMP );
2673 
2674     OGR_ALLOW_CAST_TO_THIS(MultiPolygon)
2675     OGR_ALLOW_UPCAST_TO(MultiSurface)
2676 };
2677 
2678 //! @cond Doxygen_Suppress
2679 /** @see OGRMultiPolygon::begin() const */
begin(const OGRMultiPolygon * poGeom)2680 inline const OGRMultiPolygon::ChildType* const * begin(const OGRMultiPolygon* poGeom) { return poGeom->begin(); }
2681 /** @see OGRMultiPolygon::end() const */
end(const OGRMultiPolygon * poGeom)2682 inline const OGRMultiPolygon::ChildType* const * end(const OGRMultiPolygon* poGeom) { return poGeom->end(); }
2683 
2684 /** @see OGRMultiPolygon::begin() */
begin(OGRMultiPolygon * poGeom)2685 inline OGRMultiPolygon::ChildType** begin(OGRMultiPolygon* poGeom) { return poGeom->begin(); }
2686 /** @see OGRMultiPolygon::end() */
end(OGRMultiPolygon * poGeom)2687 inline OGRMultiPolygon::ChildType** end(OGRMultiPolygon* poGeom) { return poGeom->end(); }
2688 //! @endcond
2689 
2690 /************************************************************************/
2691 /*                         OGRPolyhedralSurface                         */
2692 /************************************************************************/
2693 
2694 /**
2695  * PolyhedralSurface class.
2696  *
2697  * @since GDAL 2.2
2698  */
2699 
2700 class CPL_DLL OGRPolyhedralSurface : public OGRSurface
2701 {
2702   protected:
2703 //! @cond Doxygen_Suppress
2704     friend class OGRTriangulatedSurface;
2705     OGRMultiPolygon oMP{};
2706     virtual OGRSurfaceCasterToPolygon      GetCasterToPolygon()
2707         const override;
2708     virtual OGRSurfaceCasterToCurvePolygon GetCasterToCurvePolygon()
2709       const override;
2710     virtual OGRBoolean         isCompatibleSubType( OGRwkbGeometryType ) const;
2711     virtual const char*        getSubGeometryName() const;
2712     virtual OGRwkbGeometryType getSubGeometryType() const;
2713     std::string exportToWktInternal (const OGRWktOptions& opts, OGRErr *err) const;
2714 
2715     virtual OGRPolyhedralSurfaceCastToMultiPolygon GetCasterToMultiPolygon()
2716         const;
2717     static OGRMultiPolygon* CastToMultiPolygonImpl(OGRPolyhedralSurface* poPS);
2718 //! @endcond
2719 
2720   public:
2721     OGRPolyhedralSurface();
2722     OGRPolyhedralSurface( const OGRPolyhedralSurface &poGeom );
2723     ~OGRPolyhedralSurface() override;
2724     OGRPolyhedralSurface& operator=(const OGRPolyhedralSurface& other);
2725 
2726     /** Type of child elements. */
2727     typedef OGRPolygon ChildType;
2728 
2729     /** Return begin of iterator.
2730      * @since GDAL 2.3
2731      */
begin()2732     ChildType** begin() { return oMP.begin(); }
2733     /** Return end of iterator */
end()2734     ChildType** end() { return oMP.end(); }
2735     /** Return begin of iterator.
2736      * @since GDAL 2.3
2737      */
begin()2738     const ChildType* const* begin() const { return oMP.begin(); }
2739     /** Return end of iterator */
end()2740     const ChildType* const* end() const { return oMP.end(); }
2741 
2742     // IWks Interface.
2743     virtual size_t WkbSize() const override;
2744     virtual const char *getGeometryName() const override;
2745     virtual OGRwkbGeometryType getGeometryType() const  override;
2746     virtual OGRErr importFromWkb( const unsigned char *,
2747                                   size_t,
2748                                   OGRwkbVariant,
2749                                   size_t& nBytesConsumedOut ) override;
2750     virtual OGRErr exportToWkb( OGRwkbByteOrder, unsigned char *,
2751                                 OGRwkbVariant=wkbVariantOldOgc )
2752         const override;
2753 
2754 #ifndef DOXYGEN_XML
2755     using OGRGeometry::importFromWkt; /** deprecated */
2756 #endif
2757 
2758     OGRErr importFromWkt( const char ** ) override;
2759 
2760 #ifndef DOXYGEN_XML
2761     using OGRGeometry::exportToWkt;
2762 #endif
2763 
2764     /// Export a polyhedral surface to WKT
2765     /// \param opts  Output options.
2766     /// \param err   Pointer to error code, if desired.
2767     /// \return      WKT representation of the polyhedral surface.
2768     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
2769                                     OGRErr *err = nullptr) const override;
2770 
2771     // IGeometry methods.
2772     virtual int getDimension() const override;
2773 
2774     virtual void empty() override;
2775 
2776     virtual OGRPolyhedralSurface *clone() const override;
2777     virtual void getEnvelope( OGREnvelope * psEnvelope ) const override;
2778     virtual void getEnvelope( OGREnvelope3D * psEnvelope ) const override;
2779 
2780     virtual void flattenTo2D() override;
2781     virtual OGRErr transform( OGRCoordinateTransformation* ) override;
2782     virtual OGRBoolean Equals( const OGRGeometry* ) const override;
2783     virtual double get_Area() const override;
2784     virtual OGRErr PointOnSurface( OGRPoint* ) const override;
2785 
2786     static OGRMultiPolygon* CastToMultiPolygon( OGRPolyhedralSurface* poPS );
2787     virtual OGRBoolean hasCurveGeometry( int bLookForNonLinear = FALSE )
2788         const override;
2789     virtual OGRErr addGeometry( const OGRGeometry * );
2790     OGRErr addGeometryDirectly( OGRGeometry *poNewGeom );
2791     int getNumGeometries() const;
2792     OGRPolygon* getGeometryRef(int i);
2793     const OGRPolygon* getGeometryRef(int i) const;
2794 
2795     virtual OGRBoolean  IsEmpty() const override;
2796     virtual void setCoordinateDimension( int nDimension ) override;
2797     virtual void set3D( OGRBoolean bIs3D ) override;
2798     virtual void setMeasured( OGRBoolean bIsMeasured ) override;
2799     virtual void swapXY() override;
2800     OGRErr removeGeometry( int iIndex, int bDelete = TRUE );
2801 
accept(IOGRGeometryVisitor * visitor)2802     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)2803     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
2804 
2805     virtual void    assignSpatialReference( OGRSpatialReference * poSR ) override;
2806 
2807     OGR_ALLOW_CAST_TO_THIS(PolyhedralSurface)
2808     OGR_ALLOW_UPCAST_TO(Surface)
2809 };
2810 
2811 //! @cond Doxygen_Suppress
2812 /** @see OGRPolyhedralSurface::begin() const */
begin(const OGRPolyhedralSurface * poGeom)2813 inline const OGRPolyhedralSurface::ChildType* const * begin(const OGRPolyhedralSurface* poGeom) { return poGeom->begin(); }
2814 /** @see OGRPolyhedralSurface::end() const */
end(const OGRPolyhedralSurface * poGeom)2815 inline const OGRPolyhedralSurface::ChildType* const * end(const OGRPolyhedralSurface* poGeom) { return poGeom->end(); }
2816 
2817 /** @see OGRPolyhedralSurface::begin() */
begin(OGRPolyhedralSurface * poGeom)2818 inline OGRPolyhedralSurface::ChildType** begin(OGRPolyhedralSurface* poGeom) { return poGeom->begin(); }
2819 /** @see OGRPolyhedralSurface::end() */
end(OGRPolyhedralSurface * poGeom)2820 inline OGRPolyhedralSurface::ChildType** end(OGRPolyhedralSurface* poGeom) { return poGeom->end(); }
2821 //! @endcond
2822 
2823 /************************************************************************/
2824 /*                        OGRTriangulatedSurface                        */
2825 /************************************************************************/
2826 
2827 /**
2828  * TriangulatedSurface class.
2829  *
2830  * @since GDAL 2.2
2831  */
2832 
2833 class CPL_DLL OGRTriangulatedSurface : public OGRPolyhedralSurface
2834 {
2835   protected:
2836 //! @cond Doxygen_Suppress
2837     virtual OGRBoolean         isCompatibleSubType( OGRwkbGeometryType )
2838         const override;
2839     virtual const char*        getSubGeometryName() const override;
2840     virtual OGRwkbGeometryType getSubGeometryType() const override;
2841 
2842     virtual OGRPolyhedralSurfaceCastToMultiPolygon GetCasterToMultiPolygon()
2843         const override;
2844     static OGRMultiPolygon *
2845         CastToMultiPolygonImpl( OGRPolyhedralSurface* poPS );
2846 //! @endcond
2847 
2848   public:
2849     OGRTriangulatedSurface();
2850     OGRTriangulatedSurface( const OGRTriangulatedSurface &other );
2851     ~OGRTriangulatedSurface();
2852 
2853     /** Type of child elements. */
2854     typedef OGRTriangle ChildType;
2855 
2856     /** Return begin of iterator.
2857      * @since GDAL 2.3
2858      */
begin()2859     ChildType** begin() { return reinterpret_cast<ChildType**>(oMP.begin()); }
2860     /** Return end of iterator */
end()2861     ChildType** end() { return reinterpret_cast<ChildType**>(oMP.end()); }
2862     /** Return begin of iterator.
2863      * @since GDAL 2.3
2864      */
begin()2865     const ChildType* const* begin() const { return reinterpret_cast<const ChildType* const*>(oMP.begin()); }
2866     /** Return end of iterator */
end()2867     const ChildType* const* end() const { return reinterpret_cast<const ChildType* const*>(oMP.end()); }
2868 
2869     OGRTriangulatedSurface& operator=( const OGRTriangulatedSurface& other );
2870     virtual const char *getGeometryName() const override;
2871     virtual OGRwkbGeometryType getGeometryType() const override;
2872     virtual OGRTriangulatedSurface *clone() const override;
2873 
2874     /** See OGRPolyhedralSurface::getGeometryRef() */
getGeometryRef(int i)2875     OGRTriangle* getGeometryRef(int i) { return OGRPolyhedralSurface::getGeometryRef(i)->toTriangle(); }
2876     /** See OGRPolyhedralSurface::getGeometryRef() */
getGeometryRef(int i)2877     const OGRTriangle* getGeometryRef(int i) const { return OGRPolyhedralSurface::getGeometryRef(i)->toTriangle(); }
2878 
2879     // IWks Interface.
2880     virtual OGRErr addGeometry( const OGRGeometry * ) override;
2881 
2882     /** Return pointer of this in upper class */
toUpperClass()2883     inline OGRPolyhedralSurface* toUpperClass() { return this; }
2884     /** Return pointer of this in upper class */
toUpperClass()2885     inline const OGRPolyhedralSurface* toUpperClass() const { return this; }
2886 
accept(IOGRGeometryVisitor * visitor)2887     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)2888     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
2889 
2890     static OGRPolyhedralSurface *
2891         CastToPolyhedralSurface( OGRTriangulatedSurface* poTS );
2892 
2893     OGR_ALLOW_CAST_TO_THIS(TriangulatedSurface)
2894     OGR_ALLOW_UPCAST_TO(PolyhedralSurface)
2895 };
2896 
2897 //! @cond Doxygen_Suppress
2898 /** @see OGRTriangulatedSurface::begin() const */
begin(const OGRTriangulatedSurface * poGeom)2899 inline const OGRTriangulatedSurface::ChildType* const * begin(const OGRTriangulatedSurface* poGeom) { return poGeom->begin(); }
2900 /** @see OGRTriangulatedSurface::end() const */
end(const OGRTriangulatedSurface * poGeom)2901 inline const OGRTriangulatedSurface::ChildType* const * end(const OGRTriangulatedSurface* poGeom) { return poGeom->end(); }
2902 
2903 /** @see OGRTriangulatedSurface::begin() */
begin(OGRTriangulatedSurface * poGeom)2904 inline OGRTriangulatedSurface::ChildType** begin(OGRTriangulatedSurface* poGeom) { return poGeom->begin(); }
2905 /** @see OGRTriangulatedSurface::end() */
end(OGRTriangulatedSurface * poGeom)2906 inline OGRTriangulatedSurface::ChildType** end(OGRTriangulatedSurface* poGeom) { return poGeom->end(); }
2907 //! @endcond
2908 
2909 /************************************************************************/
2910 /*                            OGRMultiPoint                             */
2911 /************************************************************************/
2912 
2913 /**
2914  * A collection of OGRPoint.
2915  */
2916 
2917 class CPL_DLL OGRMultiPoint : public OGRGeometryCollection
2918 {
2919   private:
2920     OGRErr  importFromWkt_Bracketed( const char **, int bHasM, int bHasZ );
2921 
2922   protected:
2923     virtual OGRBoolean  isCompatibleSubType( OGRwkbGeometryType )
2924         const override;
2925 
2926   public:
2927     OGRMultiPoint();
2928     OGRMultiPoint(const OGRMultiPoint& other);
2929     ~OGRMultiPoint() override;
2930 
2931     OGRMultiPoint& operator=(const OGRMultiPoint& other);
2932 
2933     /** Type of child elements. */
2934     typedef OGRPoint ChildType;
2935 
2936     /** Return begin of iterator.
2937      * @since GDAL 2.3
2938      */
begin()2939     ChildType** begin() { return reinterpret_cast<ChildType**>(papoGeoms); }
2940     /** Return end of iterator */
end()2941     ChildType** end() { return reinterpret_cast<ChildType**>(papoGeoms + nGeomCount); }
2942     /** Return begin of iterator.
2943      * @since GDAL 2.3
2944      */
begin()2945     const ChildType* const* begin() const { return reinterpret_cast<const ChildType* const*>(papoGeoms); }
2946     /** Return end of iterator */
end()2947     const ChildType* const* end() const { return reinterpret_cast<const ChildType* const*>(papoGeoms + nGeomCount); }
2948 
2949     // IGeometryCollection
2950     /** See OGRGeometryCollection::getGeometryRef() */
getGeometryRef(int i)2951     OGRPoint *getGeometryRef( int i) { return OGRGeometryCollection::getGeometryRef(i)->toPoint(); }
2952     /** See OGRGeometryCollection::getGeometryRef() */
getGeometryRef(int i)2953     const OGRPoint *getGeometryRef( int i ) const { return OGRGeometryCollection::getGeometryRef(i)->toPoint(); }
2954 
2955     // Non-standard (OGRGeometry).
2956     virtual const char *getGeometryName() const override;
2957     virtual OGRwkbGeometryType getGeometryType() const override;
2958     virtual OGRMultiPoint *clone() const override;
2959 
2960 #ifndef DOXYGEN_XML
2961     using OGRGeometry::importFromWkt; /** deprecated */
2962 #endif
2963 
2964     OGRErr importFromWkt( const char ** ) override;
2965 
2966 #ifndef DOXYGEN_XML
2967     using OGRGeometry::exportToWkt;
2968 #endif
2969 
2970     /// Export a multipoint to WKT
2971     /// \param opts  Output options.
2972     /// \param err   Pointer to error code, if desired.
2973     /// \return      WKT representation of the multipoint.
2974     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
2975                                     OGRErr *err = nullptr) const override;
2976 
2977     // IGeometry methods.
2978     virtual int getDimension() const override;
2979 
2980     /** Return pointer of this in upper class */
toUpperClass()2981     inline OGRGeometryCollection* toUpperClass() { return this; }
2982     /** Return pointer of this in upper class */
toUpperClass()2983     inline const OGRGeometryCollection* toUpperClass() const { return this; }
2984 
accept(IOGRGeometryVisitor * visitor)2985     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)2986     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
2987 
2988     // Non-standard.
2989     virtual OGRBoolean hasCurveGeometry( int bLookForNonLinear = FALSE )
2990         const override;
2991 
2992     OGR_ALLOW_CAST_TO_THIS(MultiPoint)
2993     OGR_ALLOW_UPCAST_TO(GeometryCollection)
2994     OGR_FORBID_DOWNCAST_TO_MULTILINESTRING
2995     OGR_FORBID_DOWNCAST_TO_MULTICURVE
2996     OGR_FORBID_DOWNCAST_TO_MULTISURFACE
2997     OGR_FORBID_DOWNCAST_TO_MULTIPOLYGON
2998 };
2999 
3000 //! @cond Doxygen_Suppress
3001 /** @see OGRMultiPoint::begin() const */
begin(const OGRMultiPoint * poGeom)3002 inline const OGRMultiPoint::ChildType* const * begin(const OGRMultiPoint* poGeom) { return poGeom->begin(); }
3003 /** @see OGRMultiPoint::end() const */
end(const OGRMultiPoint * poGeom)3004 inline const OGRMultiPoint::ChildType* const * end(const OGRMultiPoint* poGeom) { return poGeom->end(); }
3005 
3006 /** @see OGRMultiPoint::begin() */
begin(OGRMultiPoint * poGeom)3007 inline OGRMultiPoint::ChildType** begin(OGRMultiPoint* poGeom) { return poGeom->begin(); }
3008 /** @see OGRMultiPoint::end() */
end(OGRMultiPoint * poGeom)3009 inline OGRMultiPoint::ChildType** end(OGRMultiPoint* poGeom) { return poGeom->end(); }
3010 //! @endcond
3011 
3012 /************************************************************************/
3013 /*                          OGRMultiCurve                               */
3014 /************************************************************************/
3015 
3016 /**
3017  * A collection of OGRCurve.
3018  *
3019  * @since GDAL 2.0
3020  */
3021 
3022 class CPL_DLL OGRMultiCurve : public OGRGeometryCollection
3023 {
3024   protected:
3025 //! @cond Doxygen_Suppress
3026     static OGRErr addCurveDirectlyFromWkt( OGRGeometry* poSelf,
3027                                            OGRCurve* poCurve );
3028 //! @endcond
3029     virtual OGRBoolean isCompatibleSubType( OGRwkbGeometryType )
3030         const override;
3031 
3032   public:
3033     OGRMultiCurve();
3034     OGRMultiCurve( const OGRMultiCurve& other );
3035     ~OGRMultiCurve() override;
3036 
3037     OGRMultiCurve& operator=( const OGRMultiCurve& other );
3038 
3039     /** Type of child elements. */
3040     typedef OGRCurve ChildType;
3041 
3042     /** Return begin of iterator.
3043      * @since GDAL 2.3
3044      */
begin()3045     ChildType** begin() { return reinterpret_cast<ChildType**>(papoGeoms); }
3046     /** Return end of iterator */
end()3047     ChildType** end() { return reinterpret_cast<ChildType**>(papoGeoms + nGeomCount); }
3048     /** Return begin of iterator.
3049      * @since GDAL 2.3
3050      */
begin()3051     const ChildType* const* begin() const { return reinterpret_cast<const ChildType* const*>(papoGeoms); }
3052     /** Return end of iterator */
end()3053     const ChildType* const* end() const { return reinterpret_cast<const ChildType* const*>(papoGeoms + nGeomCount); }
3054 
3055     // IGeometryCollection
3056     /** See OGRGeometryCollection::getGeometryRef() */
getGeometryRef(int i)3057     OGRCurve *getGeometryRef( int i) { return OGRGeometryCollection::getGeometryRef(i)->toCurve(); }
3058     /** See OGRGeometryCollection::getGeometryRef() */
getGeometryRef(int i)3059     const OGRCurve *getGeometryRef( int i ) const { return OGRGeometryCollection::getGeometryRef(i)->toCurve(); }
3060 
3061     // Non standard (OGRGeometry).
3062     virtual const char *getGeometryName() const override;
3063     virtual OGRwkbGeometryType getGeometryType() const override;
3064     virtual OGRMultiCurve *clone() const override;
3065 
3066 #ifndef DOXYGEN_XML
3067     using OGRGeometry::importFromWkt; /** deprecated */
3068 #endif
3069 
3070     OGRErr importFromWkt( const char ** ) override;
3071 
3072 #ifndef DOXYGEN_XML
3073     using OGRGeometry::exportToWkt;
3074 #endif
3075 
3076     /// Export a multicurve to WKT
3077     /// \param opts  Output options.
3078     /// \param err   Pointer to error code, if desired.
3079     /// \return      WKT representation of the multicurve.
3080     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
3081                                     OGRErr *err = nullptr) const override;
3082 
3083     // IGeometry methods.
3084     virtual int getDimension() const override;
3085 
3086     // Non-standard.
3087     virtual OGRBoolean hasCurveGeometry( int bLookForNonLinear = FALSE )
3088         const override;
3089 
3090     /** Return pointer of this in upper class */
toUpperClass()3091     inline OGRGeometryCollection* toUpperClass() { return this; }
3092     /** Return pointer of this in upper class */
toUpperClass()3093     inline const OGRGeometryCollection* toUpperClass() const { return this; }
3094 
accept(IOGRGeometryVisitor * visitor)3095     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)3096     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
3097 
3098     static OGRMultiLineString* CastToMultiLineString(OGRMultiCurve* poMC);
3099 
3100     OGR_ALLOW_CAST_TO_THIS(MultiCurve)
3101     OGR_ALLOW_UPCAST_TO(GeometryCollection)
3102     OGR_FORBID_DOWNCAST_TO_MULTIPOINT
3103     OGR_FORBID_DOWNCAST_TO_MULTISURFACE
3104     OGR_FORBID_DOWNCAST_TO_MULTIPOLYGON
3105 };
3106 
3107 //! @cond Doxygen_Suppress
3108 /** @see OGRMultiCurve::begin() const */
begin(const OGRMultiCurve * poGeom)3109 inline const OGRMultiCurve::ChildType* const * begin(const OGRMultiCurve* poGeom) { return poGeom->begin(); }
3110 /** @see OGRMultiCurve::end() const */
end(const OGRMultiCurve * poGeom)3111 inline const OGRMultiCurve::ChildType* const * end(const OGRMultiCurve* poGeom) { return poGeom->end(); }
3112 
3113 /** @see OGRMultiCurve::begin() */
begin(OGRMultiCurve * poGeom)3114 inline OGRMultiCurve::ChildType** begin(OGRMultiCurve* poGeom) { return poGeom->begin(); }
3115 /** @see OGRMultiCurve::end() */
end(OGRMultiCurve * poGeom)3116 inline OGRMultiCurve::ChildType** end(OGRMultiCurve* poGeom) { return poGeom->end(); }
3117 //! @endcond
3118 
3119 /************************************************************************/
3120 /*                          OGRMultiLineString                          */
3121 /************************************************************************/
3122 
3123 /**
3124  * A collection of OGRLineString.
3125  */
3126 
3127 class CPL_DLL OGRMultiLineString : public OGRMultiCurve
3128 {
3129   protected:
3130     virtual OGRBoolean  isCompatibleSubType( OGRwkbGeometryType )
3131         const override;
3132 
3133   public:
3134     OGRMultiLineString();
3135     OGRMultiLineString( const OGRMultiLineString& other );
3136     ~OGRMultiLineString() override;
3137 
3138     OGRMultiLineString& operator=( const OGRMultiLineString& other );
3139 
3140     /** Type of child elements. */
3141     typedef OGRLineString ChildType;
3142 
3143     /** Return begin of iterator.
3144      * @since GDAL 2.3
3145      */
begin()3146     ChildType** begin() { return reinterpret_cast<ChildType**>(papoGeoms); }
3147     /** Return end of iterator */
end()3148     ChildType** end() { return reinterpret_cast<ChildType**>(papoGeoms + nGeomCount); }
3149     /** Return begin of iterator.
3150      * @since GDAL 2.3
3151      */
begin()3152     const ChildType* const* begin() const { return reinterpret_cast<const ChildType* const*>(papoGeoms); }
3153     /** Return end of iterator */
end()3154     const ChildType* const* end() const { return reinterpret_cast<const ChildType* const*>(papoGeoms + nGeomCount); }
3155 
3156     // IGeometryCollection
3157     /** See OGRGeometryCollection::getGeometryRef() */
getGeometryRef(int i)3158     OGRLineString *getGeometryRef( int i) { return OGRGeometryCollection::getGeometryRef(i)->toLineString(); }
3159     /** See OGRGeometryCollection::getGeometryRef() */
getGeometryRef(int i)3160     const OGRLineString *getGeometryRef( int i ) const { return OGRGeometryCollection::getGeometryRef(i)->toLineString(); }
3161 
3162     // Non standard (OGRGeometry).
3163     virtual const char *getGeometryName() const override;
3164     virtual OGRwkbGeometryType getGeometryType() const override;
3165     virtual OGRMultiLineString *clone() const override;
3166 
3167 #ifndef DOXYGEN_XML
3168     using OGRGeometry::exportToWkt;
3169 #endif
3170 
3171     /// Export a multilinestring to WKT
3172     /// \param opts  Output options.
3173     /// \param err   Pointer to error code, if desired.
3174     /// \return      WKT representation of the multilinestring.
3175     virtual std::string exportToWkt(const OGRWktOptions& opts = OGRWktOptions(),
3176                                     OGRErr *err = nullptr) const override;
3177 
3178     // Non standard
3179     virtual OGRBoolean hasCurveGeometry( int bLookForNonLinear = FALSE )
3180         const override;
3181 
3182     /** Return pointer of this in upper class */
toUpperClass()3183     inline OGRGeometryCollection* toUpperClass() { return this; }
3184     /** Return pointer of this in upper class */
toUpperClass()3185     inline const OGRGeometryCollection* toUpperClass() const { return this; }
3186 
accept(IOGRGeometryVisitor * visitor)3187     virtual void accept(IOGRGeometryVisitor* visitor) override { visitor->visit(this); }
accept(IOGRConstGeometryVisitor * visitor)3188     virtual void accept(IOGRConstGeometryVisitor* visitor) const override { visitor->visit(this); }
3189 
3190     static OGRMultiCurve* CastToMultiCurve( OGRMultiLineString* poMLS );
3191 
3192     OGR_ALLOW_CAST_TO_THIS(MultiLineString)
3193     OGR_ALLOW_UPCAST_TO(MultiCurve)
3194     OGR_FORBID_DOWNCAST_TO_MULTIPOINT
3195     OGR_FORBID_DOWNCAST_TO_MULTISURFACE
3196     OGR_FORBID_DOWNCAST_TO_MULTIPOLYGON
3197 };
3198 
3199 //! @cond Doxygen_Suppress
3200 /** @see OGRMultiLineString::begin() const */
begin(const OGRMultiLineString * poGeom)3201 inline const OGRMultiLineString::ChildType* const * begin(const OGRMultiLineString* poGeom) { return poGeom->begin(); }
3202 /** @see OGRMultiLineString::end() const */
end(const OGRMultiLineString * poGeom)3203 inline const OGRMultiLineString::ChildType* const * end(const OGRMultiLineString* poGeom) { return poGeom->end(); }
3204 
3205 /** @see OGRMultiLineString::begin() */
begin(OGRMultiLineString * poGeom)3206 inline OGRMultiLineString::ChildType** begin(OGRMultiLineString* poGeom) { return poGeom->begin(); }
3207 /** @see OGRMultiLineString::end() */
end(OGRMultiLineString * poGeom)3208 inline OGRMultiLineString::ChildType** end(OGRMultiLineString* poGeom) { return poGeom->end(); }
3209 //! @endcond
3210 
3211 /************************************************************************/
3212 /*                          OGRGeometryFactory                          */
3213 /************************************************************************/
3214 
3215 /**
3216  * Create geometry objects from well known text/binary.
3217  */
3218 
3219 class CPL_DLL OGRGeometryFactory
3220 {
3221     static OGRErr createFromFgfInternal( const unsigned char *pabyData,
3222                                          OGRSpatialReference * poSR,
3223                                          OGRGeometry **ppoReturn,
3224                                          int nBytes,
3225                                          int *pnBytesConsumed,
3226                                          int nRecLevel );
3227   public:
3228     static OGRErr createFromWkb( const void *, OGRSpatialReference *,
3229                                  OGRGeometry **, size_t = static_cast<size_t>(-1),
3230                                  OGRwkbVariant=wkbVariantOldOgc );
3231     static OGRErr createFromWkb( const void * pabyData,
3232                                  OGRSpatialReference *,
3233                                  OGRGeometry **,
3234                                  size_t nSize,
3235                                  OGRwkbVariant eVariant,
3236                                  size_t& nBytesConsumedOut );
3237     static OGRErr createFromWkt( const char* , OGRSpatialReference *,
3238                                  OGRGeometry ** );
3239     static OGRErr createFromWkt( const char **, OGRSpatialReference *,
3240                                  OGRGeometry ** );
3241     /** Deprecated.
3242      * @deprecated in GDAL 2.3
3243      */
createFromWkt(char ** ppszInput,OGRSpatialReference * poSRS,OGRGeometry ** ppoGeom)3244     static OGRErr createFromWkt( char ** ppszInput, OGRSpatialReference * poSRS,
3245                                  OGRGeometry ** ppoGeom )
3246                                 CPL_WARN_DEPRECATED("Use createFromWkt(const char**, ...) instead")
3247     {
3248         return createFromWkt( const_cast<const char**>(ppszInput), poSRS, ppoGeom);
3249     }
3250 
3251     static OGRErr createFromFgf( const void*, OGRSpatialReference *,
3252                                  OGRGeometry **, int = -1, int * = nullptr );
3253     static OGRGeometry *createFromGML( const char * );
3254     static OGRGeometry *createFromGEOS( GEOSContextHandle_t hGEOSCtxt,
3255                                         GEOSGeom );
3256     static OGRGeometry *createFromGeoJson( const char *);
3257     static OGRGeometry *createFromGeoJson( const CPLJSONObject &oJSONObject );
3258 
3259     static void   destroyGeometry( OGRGeometry * );
3260     static OGRGeometry *createGeometry( OGRwkbGeometryType );
3261 
3262     static OGRGeometry * forceToPolygon( OGRGeometry * );
3263     static OGRGeometry * forceToLineString( OGRGeometry *,
3264                                             bool bOnlyInOrder = true );
3265     static OGRGeometry * forceToMultiPolygon( OGRGeometry * );
3266     static OGRGeometry * forceToMultiPoint( OGRGeometry * );
3267     static OGRGeometry * forceToMultiLineString( OGRGeometry * );
3268 
3269     static OGRGeometry * forceTo( OGRGeometry* poGeom,
3270                                   OGRwkbGeometryType eTargetType,
3271                                   const char*const* papszOptions = nullptr );
3272 
3273     static OGRGeometry * removeLowerDimensionSubGeoms( const OGRGeometry* poGeom );
3274 
3275     static OGRGeometry * organizePolygons( OGRGeometry **papoPolygons,
3276                                            int nPolygonCount,
3277                                            int *pbResultValidGeometry,
3278                                            const char **papszOptions = nullptr);
3279     static bool haveGEOS();
3280 
3281     /** Opaque class used as argument to transformWithOptions() */
3282     class CPL_DLL TransformWithOptionsCache
3283     {
3284         friend class OGRGeometryFactory;
3285         struct Private;
3286         std::unique_ptr<Private> d;
3287 
3288     public:
3289         TransformWithOptionsCache();
3290         ~TransformWithOptionsCache();
3291     };
3292 
3293     static OGRGeometry* transformWithOptions( const OGRGeometry* poSrcGeom,
3294                                               OGRCoordinateTransformation *poCT,
3295                                               char** papszOptions,
3296                                               const TransformWithOptionsCache& cache = TransformWithOptionsCache() );
3297 
3298     static OGRGeometry*
3299         approximateArcAngles( double dfX, double dfY, double dfZ,
3300                               double dfPrimaryRadius, double dfSecondaryAxis,
3301                               double dfRotation,
3302                               double dfStartAngle, double dfEndAngle,
3303                               double dfMaxAngleStepSizeDegrees,
3304                               const bool bUseMaxGap = false );
3305 
3306     static int GetCurveParameters( double x0, double y0,
3307                                   double x1, double y1,
3308                                   double x2, double y2,
3309                                   double& R, double& cx, double& cy,
3310                                   double& alpha0, double& alpha1,
3311                                   double& alpha2 );
3312     static OGRLineString* curveToLineString(
3313         double x0, double y0, double z0,
3314         double x1, double y1, double z1,
3315         double x2, double y2, double z2,
3316         int bHasZ,
3317         double dfMaxAngleStepSizeDegrees,
3318         const char* const * papszOptions = nullptr );
3319     static OGRCurve* curveFromLineString(
3320         const OGRLineString* poLS,
3321         const char* const * papszOptions = nullptr);
3322 };
3323 
3324 OGRwkbGeometryType CPL_DLL OGRFromOGCGeomType( const char *pszGeomType );
3325 const char CPL_DLL * OGRToOGCGeomType( OGRwkbGeometryType eGeomType );
3326 
3327 //! @cond Doxygen_Suppress
3328 typedef struct _OGRPreparedGeometry OGRPreparedGeometry;
3329 
3330 struct CPL_DLL OGRPreparedGeometryUniquePtrDeleter
3331 {
3332     void operator()(OGRPreparedGeometry*) const;
3333 };
3334 //! @endcond
3335 
3336 /** Unique pointer type for OGRPreparedGeometry.
3337  * @since GDAL 2.3
3338  */
3339 typedef std::unique_ptr<OGRPreparedGeometry, OGRPreparedGeometryUniquePtrDeleter> OGRPreparedGeometryUniquePtr;
3340 
3341 #endif /* ndef OGR_GEOMETRY_H_INCLUDED */
3342