LCOV - code coverage report
Current view: top level - ogr - ogr_geometry.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 558 564 98.9 %
Date: 2025-05-09 19:18:34 Functions: 303 310 97.7 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  Classes for manipulating simple features that is not specific
       5             :  *           to a particular interface technology.
       6             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 1999, Frank Warmerdam
      10             :  * Copyright (c) 2008-2014, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * SPDX-License-Identifier: MIT
      13             :  ****************************************************************************/
      14             : 
      15             : #ifndef OGR_GEOMETRY_H_INCLUDED
      16             : #define OGR_GEOMETRY_H_INCLUDED
      17             : 
      18             : #include "cpl_conv.h"
      19             : #include "cpl_json.h"
      20             : #include "gdal_fwd.h"
      21             : #include "ogr_core.h"
      22             : #include "ogr_geomcoordinateprecision.h"
      23             : #include "ogr_spatialref.h"
      24             : 
      25             : #include <climits>
      26             : #include <cmath>
      27             : #include <memory>
      28             : #include <utility>
      29             : 
      30             : /**
      31             :  * \file ogr_geometry.h
      32             :  *
      33             :  * Simple feature geometry classes.
      34             :  */
      35             : 
      36             : /// WKT Output formatting options.
      37             : enum class OGRWktFormat
      38             : {
      39             :     F,       ///< F-type formatting.
      40             :     G,       ///< G-type formatting.
      41             :     Default  ///< Format as F when abs(value) < 1, otherwise as G.
      42             : };
      43             : 
      44             : /// Options for formatting WKT output
      45             : struct CPL_DLL OGRWktOptions
      46             : {
      47             :   public:
      48             :     /// Type of WKT output to produce.
      49             :     OGRwkbVariant variant = wkbVariantOldOgc;
      50             :     /// Precision of output for X,Y coordinates.  Interpretation depends on \c format.
      51             :     int xyPrecision;
      52             :     /// Precision of output for Z coordinates.  Interpretation depends on \c format.
      53             :     int zPrecision;
      54             :     /// Precision of output for M coordinates.  Interpretation depends on \c format.
      55             :     int mPrecision;
      56             :     /// Whether GDAL-special rounding should be applied.
      57             :     bool round;
      58             :     /// Formatting type.
      59             :     OGRWktFormat format = OGRWktFormat::Default;
      60             : 
      61             :     /// Constructor.
      62       11087 :     OGRWktOptions()
      63       22174 :         : xyPrecision(getDefaultPrecision()), zPrecision(xyPrecision),
      64       11087 :           mPrecision(zPrecision), round(getDefaultRound())
      65             :     {
      66       11087 :     }
      67             : 
      68             :     /// Constructor.
      69       24336 :     OGRWktOptions(int xyPrecisionIn, bool roundIn)
      70       24336 :         : xyPrecision(xyPrecisionIn), zPrecision(xyPrecision),
      71       24336 :           mPrecision(zPrecision), round(roundIn)
      72             :     {
      73       24336 :     }
      74             : 
      75             :     /// Copy constructor
      76             :     OGRWktOptions(const OGRWktOptions &) = default;
      77             : 
      78             :     /// Return default precision
      79             :     static int getDefaultPrecision();
      80             : 
      81             :     /// Return default rounding mode.
      82             :     static bool getDefaultRound();
      83             : };
      84             : 
      85             : /**
      86             :  * Simple container for a position.
      87             :  */
      88             : class OGRRawPoint
      89             : {
      90             :   public:
      91             :     /** Constructor */
      92         473 :     OGRRawPoint() : x(0.0), y(0.0)
      93             :     {
      94         473 :     }
      95             : 
      96             :     /** Constructor */
      97          80 :     OGRRawPoint(double xIn, double yIn) : x(xIn), y(yIn)
      98             :     {
      99          80 :     }
     100             : 
     101             :     /** x */
     102             :     double x;
     103             :     /** y */
     104             :     double y;
     105             : };
     106             : 
     107             : /** GEOS geometry type */
     108             : typedef struct GEOSGeom_t *GEOSGeom;
     109             : /** GEOS context handle type */
     110             : typedef struct GEOSContextHandle_HS *GEOSContextHandle_t;
     111             : /** SFCGAL geometry type */
     112             : typedef void sfcgal_geometry_t;
     113             : 
     114             : class OGRPoint;
     115             : class OGRCurve;
     116             : class OGRCompoundCurve;
     117             : class OGRSimpleCurve;
     118             : class OGRLinearRing;
     119             : class OGRLineString;
     120             : class OGRCircularString;
     121             : class OGRSurface;
     122             : class OGRCurvePolygon;
     123             : class OGRPolygon;
     124             : class OGRMultiPoint;
     125             : class OGRMultiSurface;
     126             : class OGRMultiPolygon;
     127             : class OGRMultiCurve;
     128             : class OGRMultiLineString;
     129             : class OGRGeometryCollection;
     130             : class OGRTriangle;
     131             : class OGRPolyhedralSurface;
     132             : class OGRTriangulatedSurface;
     133             : 
     134             : //! @cond Doxygen_Suppress
     135             : typedef OGRLineString *(*OGRCurveCasterToLineString)(OGRCurve *);
     136             : typedef OGRLinearRing *(*OGRCurveCasterToLinearRing)(OGRCurve *);
     137             : 
     138             : typedef OGRPolygon *(*OGRSurfaceCasterToPolygon)(OGRSurface *);
     139             : typedef OGRCurvePolygon *(*OGRSurfaceCasterToCurvePolygon)(OGRSurface *);
     140             : typedef OGRMultiPolygon *(*OGRPolyhedralSurfaceCastToMultiPolygon)(
     141             :     OGRPolyhedralSurface *);
     142             : 
     143             : //! @endcond
     144             : 
     145             : /** OGRGeometry visitor interface.
     146             :  * @since GDAL 2.3
     147             :  */
     148             : class CPL_DLL IOGRGeometryVisitor
     149             : {
     150             :   public:
     151             :     /** Destructor/ */
     152          86 :     virtual ~IOGRGeometryVisitor() = default;
     153             : 
     154             :     /** Visit OGRPoint. */
     155             :     virtual void visit(OGRPoint *) = 0;
     156             :     /** Visit OGRLineString. */
     157             :     virtual void visit(OGRLineString *) = 0;
     158             :     /** Visit OGRLinearRing. */
     159             :     virtual void visit(OGRLinearRing *) = 0;
     160             :     /** Visit OGRPolygon. */
     161             :     virtual void visit(OGRPolygon *) = 0;
     162             :     /** Visit OGRMultiPoint. */
     163             :     virtual void visit(OGRMultiPoint *) = 0;
     164             :     /** Visit OGRMultiLineString. */
     165             :     virtual void visit(OGRMultiLineString *) = 0;
     166             :     /** Visit OGRMultiPolygon. */
     167             :     virtual void visit(OGRMultiPolygon *) = 0;
     168             :     /** Visit OGRGeometryCollection. */
     169             :     virtual void visit(OGRGeometryCollection *) = 0;
     170             :     /** Visit OGRCircularString. */
     171             :     virtual void visit(OGRCircularString *) = 0;
     172             :     /** Visit OGRCompoundCurve. */
     173             :     virtual void visit(OGRCompoundCurve *) = 0;
     174             :     /** Visit OGRCurvePolygon. */
     175             :     virtual void visit(OGRCurvePolygon *) = 0;
     176             :     /** Visit OGRMultiCurve. */
     177             :     virtual void visit(OGRMultiCurve *) = 0;
     178             :     /** Visit OGRMultiSurface. */
     179             :     virtual void visit(OGRMultiSurface *) = 0;
     180             :     /** Visit OGRTriangle. */
     181             :     virtual void visit(OGRTriangle *) = 0;
     182             :     /** Visit OGRPolyhedralSurface. */
     183             :     virtual void visit(OGRPolyhedralSurface *) = 0;
     184             :     /** Visit OGRTriangulatedSurface. */
     185             :     virtual void visit(OGRTriangulatedSurface *) = 0;
     186             : };
     187             : 
     188             : /** OGRGeometry visitor default implementation.
     189             :  *
     190             :  * This default implementation will recurse down to calling
     191             :  * visit(OGRPoint*) on each point.
     192             :  *
     193             :  * @since GDAL 2.3
     194             :  */
     195             : class CPL_DLL OGRDefaultGeometryVisitor : public IOGRGeometryVisitor
     196             : {
     197             :     void _visit(OGRSimpleCurve *poGeom);
     198             : 
     199             :   public:
     200           0 :     void visit(OGRPoint *) override
     201             :     {
     202           0 :     }
     203             : 
     204             :     void visit(OGRLineString *) override;
     205             :     void visit(OGRLinearRing *) override;
     206             :     void visit(OGRPolygon *) override;
     207             :     void visit(OGRMultiPoint *) override;
     208             :     void visit(OGRMultiLineString *) override;
     209             :     void visit(OGRMultiPolygon *) override;
     210             :     void visit(OGRGeometryCollection *) override;
     211             :     void visit(OGRCircularString *) override;
     212             :     void visit(OGRCompoundCurve *) override;
     213             :     void visit(OGRCurvePolygon *) override;
     214             :     void visit(OGRMultiCurve *) override;
     215             :     void visit(OGRMultiSurface *) override;
     216             :     void visit(OGRTriangle *) override;
     217             :     void visit(OGRPolyhedralSurface *) override;
     218             :     void visit(OGRTriangulatedSurface *) override;
     219             : };
     220             : 
     221             : /** OGRGeometry visitor interface.
     222             :  * @since GDAL 2.3
     223             :  */
     224             : class CPL_DLL IOGRConstGeometryVisitor
     225             : {
     226             :   public:
     227             :     /** Destructor/ */
     228         291 :     virtual ~IOGRConstGeometryVisitor() = default;
     229             : 
     230             :     /** Visit OGRPoint. */
     231             :     virtual void visit(const OGRPoint *) = 0;
     232             :     /** Visit OGRLineString. */
     233             :     virtual void visit(const OGRLineString *) = 0;
     234             :     /** Visit OGRLinearRing. */
     235             :     virtual void visit(const OGRLinearRing *) = 0;
     236             :     /** Visit OGRPolygon. */
     237             :     virtual void visit(const OGRPolygon *) = 0;
     238             :     /** Visit OGRMultiPoint. */
     239             :     virtual void visit(const OGRMultiPoint *) = 0;
     240             :     /** Visit OGRMultiLineString. */
     241             :     virtual void visit(const OGRMultiLineString *) = 0;
     242             :     /** Visit OGRMultiPolygon. */
     243             :     virtual void visit(const OGRMultiPolygon *) = 0;
     244             :     /** Visit OGRGeometryCollection. */
     245             :     virtual void visit(const OGRGeometryCollection *) = 0;
     246             :     /** Visit OGRCircularString. */
     247             :     virtual void visit(const OGRCircularString *) = 0;
     248             :     /** Visit OGRCompoundCurve. */
     249             :     virtual void visit(const OGRCompoundCurve *) = 0;
     250             :     /** Visit OGRCurvePolygon. */
     251             :     virtual void visit(const OGRCurvePolygon *) = 0;
     252             :     /** Visit OGRMultiCurve. */
     253             :     virtual void visit(const OGRMultiCurve *) = 0;
     254             :     /** Visit OGRMultiSurface. */
     255             :     virtual void visit(const OGRMultiSurface *) = 0;
     256             :     /** Visit OGRTriangle. */
     257             :     virtual void visit(const OGRTriangle *) = 0;
     258             :     /** Visit OGRPolyhedralSurface. */
     259             :     virtual void visit(const OGRPolyhedralSurface *) = 0;
     260             :     /** Visit OGRTriangulatedSurface. */
     261             :     virtual void visit(const OGRTriangulatedSurface *) = 0;
     262             : };
     263             : 
     264             : /** OGRGeometry visitor default implementation.
     265             :  *
     266             :  * This default implementation will recurse down to calling
     267             :  * visit(const OGRPoint*) on each point.
     268             :  *
     269             :  * @since GDAL 2.3
     270             :  */
     271             : class CPL_DLL OGRDefaultConstGeometryVisitor : public IOGRConstGeometryVisitor
     272             : {
     273             :     void _visit(const OGRSimpleCurve *poGeom);
     274             : 
     275             :   public:
     276           0 :     void visit(const OGRPoint *) override
     277             :     {
     278           0 :     }
     279             : 
     280             :     void visit(const OGRLineString *) override;
     281             :     void visit(const OGRLinearRing *) override;
     282             :     void visit(const OGRPolygon *) override;
     283             :     void visit(const OGRMultiPoint *) override;
     284             :     void visit(const OGRMultiLineString *) override;
     285             :     void visit(const OGRMultiPolygon *) override;
     286             :     void visit(const OGRGeometryCollection *) override;
     287             :     void visit(const OGRCircularString *) override;
     288             :     void visit(const OGRCompoundCurve *) override;
     289             :     void visit(const OGRCurvePolygon *) override;
     290             :     void visit(const OGRMultiCurve *) override;
     291             :     void visit(const OGRMultiSurface *) override;
     292             :     void visit(const OGRTriangle *) override;
     293             :     void visit(const OGRPolyhedralSurface *) override;
     294             :     void visit(const OGRTriangulatedSurface *) override;
     295             : };
     296             : 
     297             : /************************************************************************/
     298             : /*                  OGRGeomCoordinateBinaryPrecision                    */
     299             : /************************************************************************/
     300             : 
     301             : /** Geometry coordinate precision for a binary representation.
     302             :  *
     303             :  * @since GDAL 3.9
     304             :  */
     305             : struct CPL_DLL OGRGeomCoordinateBinaryPrecision
     306             : {
     307             :     int nXYBitPrecision =
     308             :         INT_MIN; /**< Number of bits needed to achieved XY precision. Typically
     309             :                     computed with SetFromResolution() */
     310             :     int nZBitPrecision =
     311             :         INT_MIN; /**< Number of bits needed to achieved Z precision. Typically
     312             :                     computed with SetFromResolution() */
     313             :     int nMBitPrecision =
     314             :         INT_MIN; /**< Number of bits needed to achieved M precision. Typically
     315             :                     computed with SetFromResolution() */
     316             : 
     317             :     void SetFrom(const OGRGeomCoordinatePrecision &);
     318             : };
     319             : 
     320             : /************************************************************************/
     321             : /*                           OGRwkbExportOptions                        */
     322             : /************************************************************************/
     323             : 
     324             : /** WKB export options.
     325             :  *
     326             :  * @since GDAL 3.9
     327             :  */
     328             : struct CPL_DLL OGRwkbExportOptions
     329             : {
     330             :     OGRwkbByteOrder eByteOrder = wkbNDR;           /**< Byte order */
     331             :     OGRwkbVariant eWkbVariant = wkbVariantOldOgc;  /**< WKB variant. */
     332             :     OGRGeomCoordinateBinaryPrecision sPrecision{}; /**< Binary precision. */
     333             : };
     334             : 
     335             : /************************************************************************/
     336             : /*                             OGRGeometry                              */
     337             : /************************************************************************/
     338             : 
     339             : /**
     340             :  * Abstract base class for all geometry classes.
     341             :  *
     342             :  * Some spatial analysis methods require that OGR is built on the GEOS library
     343             :  * to work properly. The precise meaning of methods that describe spatial
     344             :  * relationships between geometries is described in the SFCOM, or other simple
     345             :  * features interface specifications, like "OpenGISĀ® Implementation
     346             :  * Specification for Geographic information - Simple feature access - Part 1:
     347             :  * Common architecture":
     348             :  * <a href="http://www.opengeospatial.org/standards/sfa">OGC 06-103r4</a>
     349             :  *
     350             :  * In GDAL 2.0, the hierarchy of classes has been extended with
     351             :  * <a href="https://portal.opengeospatial.org/files/?artifact_id=32024">
     352             :  * (working draft) ISO SQL/MM Part 3 (ISO/IEC 13249-3)</a> curve geometries :
     353             :  * CIRCULARSTRING (OGRCircularString), COMPOUNDCURVE (OGRCompoundCurve),
     354             :  * CURVEPOLYGON (OGRCurvePolygon), MULTICURVE (OGRMultiCurve) and
     355             :  * MULTISURFACE (OGRMultiSurface).
     356             :  *
     357             :  */
     358             : 
     359    10526400 : class CPL_DLL OGRGeometry
     360             : {
     361             :   private:
     362             :     const OGRSpatialReference *poSRS = nullptr;  // may be NULL
     363             : 
     364             :   protected:
     365             :     //! @cond Doxygen_Suppress
     366             :     friend class OGRCurveCollection;
     367             : 
     368             :     unsigned int flags = 0;
     369             : 
     370             :     OGRErr importPreambleFromWkt(const char **ppszInput, int *pbHasZ,
     371             :                                  int *pbHasM, bool *pbIsEmpty);
     372             :     OGRErr importCurveCollectionFromWkt(
     373             :         const char **ppszInput, int bAllowEmptyComponent, int bAllowLineString,
     374             :         int bAllowCurve, int bAllowCompoundCurve,
     375             :         OGRErr (*pfnAddCurveDirectly)(OGRGeometry *poSelf, OGRCurve *poCurve));
     376             :     OGRErr importPreambleFromWkb(const unsigned char *pabyData, size_t nSize,
     377             :                                  OGRwkbByteOrder &eByteOrder,
     378             :                                  OGRwkbVariant eWkbVariant);
     379             :     OGRErr importPreambleOfCollectionFromWkb(const unsigned char *pabyData,
     380             :                                              size_t &nSize, size_t &nDataOffset,
     381             :                                              OGRwkbByteOrder &eByteOrder,
     382             :                                              size_t nMinSubGeomSize,
     383             :                                              int &nGeomCount,
     384             :                                              OGRwkbVariant eWkbVariant);
     385             :     OGRErr PointOnSurfaceInternal(OGRPoint *poPoint) const;
     386             :     OGRBoolean IsSFCGALCompatible() const;
     387             : 
     388             :     void HomogenizeDimensionalityWith(OGRGeometry *poOtherGeom);
     389             :     std::string wktTypeString(OGRwkbVariant variant) const;
     390             : 
     391             :     //! @endcond
     392             : 
     393             :   public:
     394             :     /************************************************************************/
     395             :     /*                   Bit flags for OGRGeometry                          */
     396             :     /*          The OGR_G_NOT_EMPTY_POINT is used *only* for points.        */
     397             :     /*          Do not use these outside of the core.                       */
     398             :     /*          Use Is3D, IsMeasured, set3D, and setMeasured instead        */
     399             :     /************************************************************************/
     400             : 
     401             :     //! @cond Doxygen_Suppress
     402             :     static const unsigned int OGR_G_NOT_EMPTY_POINT = 0x1;
     403             :     static const unsigned int OGR_G_3D = 0x2;
     404             :     static const unsigned int OGR_G_MEASURED = 0x4;
     405             :     //! @endcond
     406             : 
     407             :     OGRGeometry();
     408             :     OGRGeometry(const OGRGeometry &other);
     409             :     OGRGeometry(OGRGeometry &&other);
     410             :     virtual ~OGRGeometry();
     411             : 
     412             :     OGRGeometry &operator=(const OGRGeometry &other);
     413             :     OGRGeometry &operator=(OGRGeometry &&other);
     414             : 
     415             :     /** Returns if two geometries are equal. */
     416             :     bool operator==(const OGRGeometry &other) const
     417             :     {
     418             :         return CPL_TO_BOOL(Equals(&other));
     419             :     }
     420             : 
     421             :     /** Returns if two geometries are different. */
     422        1149 :     bool operator!=(const OGRGeometry &other) const
     423             :     {
     424        1149 :         return !CPL_TO_BOOL(Equals(&other));
     425             :     }
     426             : 
     427             :     // Standard IGeometry.
     428             :     virtual int getDimension() const = 0;
     429             :     virtual int getCoordinateDimension() const;
     430             :     int CoordinateDimension() const;
     431             :     virtual OGRBoolean IsEmpty() const = 0;
     432             :     virtual OGRBoolean IsValid() const;
     433             :     virtual OGRGeometry *MakeValid(CSLConstList papszOptions = nullptr) const;
     434             :     virtual OGRGeometry *Normalize() const;
     435             :     virtual OGRBoolean IsSimple() const;
     436             : 
     437             :     /*! Returns whether the geometry has a Z component. */
     438    20661254 :     OGRBoolean Is3D() const
     439             :     {
     440    20661254 :         return (flags & OGR_G_3D) != 0;
     441             :     }
     442             : 
     443             :     /*! Returns whether the geometry has a M component. */
     444    14812560 :     OGRBoolean IsMeasured() const
     445             :     {
     446    14812560 :         return (flags & OGR_G_MEASURED) != 0;
     447             :     }
     448             : 
     449             :     virtual OGRBoolean IsRing() const;
     450             :     virtual void empty() = 0;
     451             :     virtual OGRGeometry *clone() const CPL_WARN_UNUSED_RESULT = 0;
     452             :     virtual void getEnvelope(OGREnvelope *psEnvelope) const = 0;
     453             :     virtual void getEnvelope(OGREnvelope3D *psEnvelope) const = 0;
     454             : 
     455             :     // IWks Interface.
     456             :     virtual size_t WkbSize() const = 0;
     457             :     OGRErr importFromWkb(const GByte *, size_t = static_cast<size_t>(-1),
     458             :                          OGRwkbVariant = wkbVariantOldOgc);
     459             :     virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
     460             :                                  size_t &nBytesConsumedOut) = 0;
     461             :     OGRErr exportToWkb(OGRwkbByteOrder, unsigned char *,
     462             :                        OGRwkbVariant = wkbVariantOldOgc) const;
     463             :     virtual OGRErr exportToWkb(unsigned char *,
     464             :                                const OGRwkbExportOptions * = nullptr) const = 0;
     465             :     virtual OGRErr importFromWkt(const char **ppszInput) = 0;
     466             : 
     467             : #ifndef DOXYGEN_XML
     468             :     /** Deprecated.
     469             :      * @deprecated in GDAL 2.3
     470             :      */
     471             :     OGRErr importFromWkt(char **ppszInput)
     472             :         /*! @cond Doxygen_Suppress */
     473             :         CPL_WARN_DEPRECATED("Use importFromWkt(const char**) instead")
     474             :     /*! @endcond */
     475             :     {
     476             :         return importFromWkt(const_cast<const char **>(ppszInput));
     477             :     }
     478             : #endif
     479             : 
     480             :     OGRErr exportToWkt(char **ppszDstText,
     481             :                        OGRwkbVariant = wkbVariantOldOgc) const;
     482             : 
     483             :     /// Export a WKT geometry.
     484             :     /// \param opts  Output options.
     485             :     /// \param err   Pointer to error code, if desired.
     486             :     /// \return  WKT string representing this geometry.
     487             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
     488             :                                     OGRErr *err = nullptr) const = 0;
     489             : 
     490             :     // Non-standard.
     491             :     virtual OGRwkbGeometryType getGeometryType() const = 0;
     492             :     OGRwkbGeometryType getIsoGeometryType() const;
     493             :     virtual const char *getGeometryName() const = 0;
     494             :     void dumpReadable(FILE *, const char * = nullptr,
     495             :                       CSLConstList papszOptions = nullptr) const;
     496             :     std::string dumpReadable(const char * = nullptr,
     497             :                              CSLConstList papszOptions = nullptr) const;
     498             :     virtual void flattenTo2D() = 0;
     499             :     virtual char *exportToGML(const char *const *papszOptions = nullptr) const;
     500             :     virtual char *exportToKML() const;
     501             :     virtual char *exportToJson(CSLConstList papszOptions = nullptr) const;
     502             : 
     503             :     /** Accept a visitor. */
     504             :     virtual void accept(IOGRGeometryVisitor *visitor) = 0;
     505             : 
     506             :     /** Accept a visitor. */
     507             :     virtual void accept(IOGRConstGeometryVisitor *visitor) const = 0;
     508             : 
     509             :     static GEOSContextHandle_t createGEOSContext();
     510             :     static void freeGEOSContext(GEOSContextHandle_t hGEOSCtxt);
     511             :     GEOSGeom
     512             :     exportToGEOS(GEOSContextHandle_t hGEOSCtxt,
     513             :                  bool bRemoveEmptyParts = false) const CPL_WARN_UNUSED_RESULT;
     514             :     virtual OGRBoolean hasCurveGeometry(int bLookForNonLinear = FALSE) const;
     515             :     virtual OGRGeometry *getCurveGeometry(
     516             :         const char *const *papszOptions = nullptr) const CPL_WARN_UNUSED_RESULT;
     517             :     virtual OGRGeometry *getLinearGeometry(
     518             :         double dfMaxAngleStepSizeDegrees = 0,
     519             :         const char *const *papszOptions = nullptr) const CPL_WARN_UNUSED_RESULT;
     520             : 
     521             :     void roundCoordinates(const OGRGeomCoordinatePrecision &sPrecision);
     522             :     void
     523             :     roundCoordinatesIEEE754(const OGRGeomCoordinateBinaryPrecision &options);
     524             : 
     525             :     // SFCGAL interfacing methods.
     526             :     //! @cond Doxygen_Suppress
     527             :     static sfcgal_geometry_t *OGRexportToSFCGAL(const OGRGeometry *poGeom);
     528             :     static OGRGeometry *SFCGALexportToOGR(const sfcgal_geometry_t *_geometry);
     529             :     //! @endcond
     530             :     virtual void closeRings();
     531             : 
     532             :     virtual bool setCoordinateDimension(int nDimension);
     533             :     virtual bool set3D(OGRBoolean bIs3D);
     534             :     virtual bool setMeasured(OGRBoolean bIsMeasured);
     535             : 
     536             :     virtual void assignSpatialReference(const OGRSpatialReference *poSR);
     537             : 
     538     1930644 :     const OGRSpatialReference *getSpatialReference(void) const
     539             :     {
     540     1930644 :         return poSRS;
     541             :     }
     542             : 
     543             :     virtual OGRErr transform(OGRCoordinateTransformation *poCT) = 0;
     544             :     OGRErr transformTo(const OGRSpatialReference *poSR);
     545             : 
     546             :     virtual bool segmentize(double dfMaxLength);
     547             : 
     548             :     // ISpatialRelation
     549             :     virtual OGRBoolean Intersects(const OGRGeometry *) const;
     550             :     virtual OGRBoolean Equals(const OGRGeometry *) const = 0;
     551             :     virtual OGRBoolean Disjoint(const OGRGeometry *) const;
     552             :     virtual OGRBoolean Touches(const OGRGeometry *) const;
     553             :     virtual OGRBoolean Crosses(const OGRGeometry *) const;
     554             :     virtual OGRBoolean Within(const OGRGeometry *) const;
     555             :     virtual OGRBoolean Contains(const OGRGeometry *) const;
     556             :     virtual OGRBoolean Overlaps(const OGRGeometry *) const;
     557             :     //    virtual OGRBoolean  Relate( const OGRGeometry *, const char * ) const;
     558             :     //    virtual OGRGeometry *LocateAlong( double mValue ) const;
     559             :     //    virtual OGRGeometry *LocateBetween( double mStart, double mEnd )
     560             :     //    const;
     561             : 
     562             :     virtual OGRGeometry *Boundary() const CPL_WARN_UNUSED_RESULT;
     563             :     virtual double Distance(const OGRGeometry *) const;
     564             :     virtual OGRGeometry *ConvexHull() const CPL_WARN_UNUSED_RESULT;
     565             :     virtual OGRGeometry *
     566             :     ConcaveHull(double dfRatio, bool bAllowHoles) const CPL_WARN_UNUSED_RESULT;
     567             :     virtual OGRGeometry *
     568             :     Buffer(double dfDist, int nQuadSegs = 30) const CPL_WARN_UNUSED_RESULT;
     569             :     virtual OGRGeometry *
     570             :     BufferEx(double dfDistance,
     571             :              CSLConstList papszOptions) const CPL_WARN_UNUSED_RESULT;
     572             :     virtual OGRGeometry *
     573             :     Intersection(const OGRGeometry *) const CPL_WARN_UNUSED_RESULT;
     574             :     virtual OGRGeometry *
     575             :     Union(const OGRGeometry *) const CPL_WARN_UNUSED_RESULT;
     576             :     virtual OGRGeometry *UnionCascaded() const CPL_WARN_UNUSED_RESULT;
     577             :     OGRGeometry *UnaryUnion() const CPL_WARN_UNUSED_RESULT;
     578             :     virtual OGRGeometry *
     579             :     Difference(const OGRGeometry *) const CPL_WARN_UNUSED_RESULT;
     580             :     virtual OGRGeometry *
     581             :     SymDifference(const OGRGeometry *) const CPL_WARN_UNUSED_RESULT;
     582             :     virtual OGRErr Centroid(OGRPoint *poPoint) const;
     583             :     virtual OGRGeometry *
     584             :     Simplify(double dTolerance) const CPL_WARN_UNUSED_RESULT;
     585             :     OGRGeometry *
     586             :     SimplifyPreserveTopology(double dTolerance) const CPL_WARN_UNUSED_RESULT;
     587             :     virtual OGRGeometry *
     588             :     DelaunayTriangulation(double dfTolerance,
     589             :                           int bOnlyEdges) const CPL_WARN_UNUSED_RESULT;
     590             : 
     591             :     virtual OGRGeometry *Polygonize() const CPL_WARN_UNUSED_RESULT;
     592             :     virtual OGRGeometry *BuildArea() const CPL_WARN_UNUSED_RESULT;
     593             : 
     594             :     virtual double Distance3D(const OGRGeometry *poOtherGeom) const;
     595             : 
     596             :     OGRGeometry *SetPrecision(double dfGridSize, int nFlags) const;
     597             : 
     598             :     virtual bool hasEmptyParts() const;
     599             :     virtual void removeEmptyParts();
     600             : 
     601             :     //! @cond Doxygen_Suppress
     602             :     // backward compatibility to non-standard method names.
     603             :     OGRBoolean Intersect(OGRGeometry *) const
     604             :         CPL_WARN_DEPRECATED("Non standard method. "
     605             :                             "Use Intersects() instead");
     606             :     OGRBoolean Equal(OGRGeometry *) const
     607             :         CPL_WARN_DEPRECATED("Non standard method. "
     608             :                             "Use Equals() instead");
     609             :     OGRGeometry *SymmetricDifference(const OGRGeometry *) const
     610             :         CPL_WARN_DEPRECATED("Non standard method. "
     611             :                             "Use SymDifference() instead");
     612             :     OGRGeometry *getBoundary() const
     613             :         CPL_WARN_DEPRECATED("Non standard method. "
     614             :                             "Use Boundary() instead");
     615             :     //! @endcond
     616             : 
     617             :     //! @cond Doxygen_Suppress
     618             :     // Special HACK for DB2 7.2 support
     619             :     static int bGenerate_DB2_V72_BYTE_ORDER;
     620             :     //! @endcond
     621             : 
     622             :     virtual void swapXY();
     623             : 
     624             :     bool IsRectangle() const;
     625             : 
     626             :     //! @cond Doxygen_Suppress
     627             :     static OGRGeometry *CastToIdentity(OGRGeometry *poGeom)
     628             :     {
     629             :         return poGeom;
     630             :     }
     631             : 
     632             :     static OGRGeometry *CastToError(OGRGeometry *poGeom);
     633             : 
     634             :     //! @endcond
     635             : 
     636             :     /** Convert a OGRGeometry* to a OGRGeometryH.
     637             :      * @since GDAL 2.3
     638             :      */
     639      463016 :     static inline OGRGeometryH ToHandle(OGRGeometry *poGeom)
     640             :     {
     641      463016 :         return reinterpret_cast<OGRGeometryH>(poGeom);
     642             :     }
     643             : 
     644             :     /** Convert a OGRGeometryH to a OGRGeometry*.
     645             :      * @since GDAL 2.3
     646             :      */
     647     1785567 :     static inline OGRGeometry *FromHandle(OGRGeometryH hGeom)
     648             :     {
     649     1785567 :         return reinterpret_cast<OGRGeometry *>(hGeom);
     650             :     }
     651             : 
     652             :     /** Down-cast to OGRPoint*.
     653             :      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbPoint.
     654             :      * @since GDAL 2.3
     655             :      */
     656      187452 :     inline OGRPoint *toPoint()
     657             :     {
     658      187452 :         return cpl::down_cast<OGRPoint *>(this);
     659             :     }
     660             : 
     661             :     /** Down-cast to OGRPoint*.
     662             :      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbPoint.
     663             :      * @since GDAL 2.3
     664             :      */
     665       59187 :     inline const OGRPoint *toPoint() const
     666             :     {
     667       59187 :         return cpl::down_cast<const OGRPoint *>(this);
     668             :     }
     669             : 
     670             :     /** Down-cast to OGRCurve*.
     671             :      * Implies prior checking that OGR_GT_IsSubClass(getGeometryType(),
     672             :      * wkbCurve).
     673             :      * @since GDAL 2.3
     674             :      */
     675       11340 :     inline OGRCurve *toCurve()
     676             :     {
     677       11340 :         return cpl::down_cast<OGRCurve *>(this);
     678             :     }
     679             : 
     680             :     /** Down-cast to OGRCurve*.
     681             :      * Implies prior checking that OGR_GT_IsSubClass(getGeometryType(),
     682             :      * wkbCurve).
     683             :      * @since GDAL 2.3
     684             :      */
     685          59 :     inline const OGRCurve *toCurve() const
     686             :     {
     687          59 :         return cpl::down_cast<const OGRCurve *>(this);
     688             :     }
     689             : 
     690             :     /** Down-cast to OGRSimpleCurve*.
     691             :      * Implies prior checking that getGeometryType() is wkbLineString,
     692             :      * wkbCircularString or a derived type.
     693             :      * @since GDAL 2.3
     694             :      */
     695      400607 :     inline OGRSimpleCurve *toSimpleCurve()
     696             :     {
     697      400607 :         return cpl::down_cast<OGRSimpleCurve *>(this);
     698             :     }
     699             : 
     700             :     /** Down-cast to OGRSimpleCurve*.
     701             :      * Implies prior checking that getGeometryType() is wkbLineString,
     702             :      * wkbCircularString or a derived type.
     703             :      * @since GDAL 2.3
     704             :      */
     705       48031 :     inline const OGRSimpleCurve *toSimpleCurve() const
     706             :     {
     707       48031 :         return cpl::down_cast<const OGRSimpleCurve *>(this);
     708             :     }
     709             : 
     710             :     /** Down-cast to OGRLineString*.
     711             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     712             :      * wkbLineString.
     713             :      * @since GDAL 2.3
     714             :      */
     715       35076 :     inline OGRLineString *toLineString()
     716             :     {
     717       35076 :         return cpl::down_cast<OGRLineString *>(this);
     718             :     }
     719             : 
     720             :     /** Down-cast to OGRLineString*.
     721             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     722             :      * wkbLineString.
     723             :      * @since GDAL 2.3
     724             :      */
     725        9505 :     inline const OGRLineString *toLineString() const
     726             :     {
     727        9505 :         return cpl::down_cast<const OGRLineString *>(this);
     728             :     }
     729             : 
     730             :     /** Down-cast to OGRLinearRing*.
     731             :      * Implies prior checking that EQUAL(getGeometryName(), "LINEARRING").
     732             :      * @since GDAL 2.3
     733             :      */
     734      260313 :     inline OGRLinearRing *toLinearRing()
     735             :     {
     736      260313 :         return cpl::down_cast<OGRLinearRing *>(this);
     737             :     }
     738             : 
     739             :     /** Down-cast to OGRLinearRing*.
     740             :      * Implies prior checking that EQUAL(getGeometryName(), "LINEARRING").
     741             :      * @since GDAL 2.3
     742             :      */
     743         169 :     inline const OGRLinearRing *toLinearRing() const
     744             :     {
     745         169 :         return cpl::down_cast<const OGRLinearRing *>(this);
     746             :     }
     747             : 
     748             :     /** Down-cast to OGRCircularString*.
     749             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     750             :      * wkbCircularString.
     751             :      * @since GDAL 2.3
     752             :      */
     753           3 :     inline OGRCircularString *toCircularString()
     754             :     {
     755           3 :         return cpl::down_cast<OGRCircularString *>(this);
     756             :     }
     757             : 
     758             :     /** Down-cast to OGRCircularString*.
     759             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     760             :      * wkbCircularString.
     761             :      * @since GDAL 2.3
     762             :      */
     763          44 :     inline const OGRCircularString *toCircularString() const
     764             :     {
     765          44 :         return cpl::down_cast<const OGRCircularString *>(this);
     766             :     }
     767             : 
     768             :     /** Down-cast to OGRCompoundCurve*.
     769             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     770             :      * wkbCompoundCurve.
     771             :      * @since GDAL 2.3
     772             :      */
     773        2720 :     inline OGRCompoundCurve *toCompoundCurve()
     774             :     {
     775        2720 :         return cpl::down_cast<OGRCompoundCurve *>(this);
     776             :     }
     777             : 
     778             :     /** Down-cast to OGRCompoundCurve*.
     779             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     780             :      * wkbCompoundCurve.
     781             :      * @since GDAL 2.3
     782             :      */
     783         890 :     inline const OGRCompoundCurve *toCompoundCurve() const
     784             :     {
     785         890 :         return cpl::down_cast<const OGRCompoundCurve *>(this);
     786             :     }
     787             : 
     788             :     /** Down-cast to OGRSurface*.
     789             :      * Implies prior checking that OGR_GT_IsSubClass(getGeometryType(),
     790             :      * wkbSurface).
     791             :      * @since GDAL 2.3
     792             :      */
     793        1577 :     inline OGRSurface *toSurface()
     794             :     {
     795        1577 :         return cpl::down_cast<OGRSurface *>(this);
     796             :     }
     797             : 
     798             :     /** Down-cast to OGRSurface*.
     799             :      * Implies prior checking that OGR_GT_IsSubClass(getGeometryType(),
     800             :      * wkbSurface).
     801             :      * @since GDAL 2.3
     802             :      */
     803          99 :     inline const OGRSurface *toSurface() const
     804             :     {
     805          99 :         return cpl::down_cast<const OGRSurface *>(this);
     806             :     }
     807             : 
     808             :     /** Down-cast to OGRPolygon*.
     809             :      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbPolygon
     810             :      * or wkbTriangle.
     811             :      * @since GDAL 2.3
     812             :      */
     813       56539 :     inline OGRPolygon *toPolygon()
     814             :     {
     815       56539 :         return cpl::down_cast<OGRPolygon *>(this);
     816             :     }
     817             : 
     818             :     /** Down-cast to OGRPolygon*.
     819             :      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbPolygon
     820             :      * or wkbTriangle.
     821             :      * @since GDAL 2.3
     822             :      */
     823      239711 :     inline const OGRPolygon *toPolygon() const
     824             :     {
     825      239711 :         return cpl::down_cast<const OGRPolygon *>(this);
     826             :     }
     827             : 
     828             :     /** Down-cast to OGRTriangle*.
     829             :      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbTriangle.
     830             :      * @since GDAL 2.3
     831             :      */
     832       52121 :     inline OGRTriangle *toTriangle()
     833             :     {
     834       52121 :         return cpl::down_cast<OGRTriangle *>(this);
     835             :     }
     836             : 
     837             :     /** Down-cast to OGRTriangle*.
     838             :      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbTriangle.
     839             :      * @since GDAL 2.3
     840             :      */
     841           2 :     inline const OGRTriangle *toTriangle() const
     842             :     {
     843           2 :         return cpl::down_cast<const OGRTriangle *>(this);
     844             :     }
     845             : 
     846             :     /** Down-cast to OGRCurvePolygon*.
     847             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     848             :      * wkbCurvePolygon or wkbPolygon or wkbTriangle.
     849             :      * @since GDAL 2.3
     850             :      */
     851       68110 :     inline OGRCurvePolygon *toCurvePolygon()
     852             :     {
     853       68110 :         return cpl::down_cast<OGRCurvePolygon *>(this);
     854             :     }
     855             : 
     856             :     /** Down-cast to OGRCurvePolygon*.
     857             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     858             :      * wkbCurvePolygon or wkbPolygon or wkbTriangle.
     859             :      * @since GDAL 2.3
     860             :      */
     861       42658 :     inline const OGRCurvePolygon *toCurvePolygon() const
     862             :     {
     863       42658 :         return cpl::down_cast<const OGRCurvePolygon *>(this);
     864             :     }
     865             : 
     866             :     /** Down-cast to OGRGeometryCollection*.
     867             :      * Implies prior checking that OGR_GT_IsSubClass(getGeometryType(),
     868             :      * wkbGeometryCollection).
     869             :      * @since GDAL 2.3
     870             :      */
     871        9790 :     inline OGRGeometryCollection *toGeometryCollection()
     872             :     {
     873        9790 :         return cpl::down_cast<OGRGeometryCollection *>(this);
     874             :     }
     875             : 
     876             :     /** Down-cast to OGRGeometryCollection*.
     877             :      * Implies prior checking that OGR_GT_IsSubClass(getGeometryType(),
     878             :      * wkbGeometryCollection).
     879             :      * @since GDAL 2.3
     880             :      */
     881        6241 :     inline const OGRGeometryCollection *toGeometryCollection() const
     882             :     {
     883        6241 :         return cpl::down_cast<const OGRGeometryCollection *>(this);
     884             :     }
     885             : 
     886             :     /** Down-cast to OGRMultiPoint*.
     887             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     888             :      * wkbMultiPoint.
     889             :      * @since GDAL 2.3
     890             :      */
     891         169 :     inline OGRMultiPoint *toMultiPoint()
     892             :     {
     893         169 :         return cpl::down_cast<OGRMultiPoint *>(this);
     894             :     }
     895             : 
     896             :     /** Down-cast to OGRMultiPoint*.
     897             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     898             :      * wkbMultiPoint.
     899             :      * @since GDAL 2.3
     900             :      */
     901         183 :     inline const OGRMultiPoint *toMultiPoint() const
     902             :     {
     903         183 :         return cpl::down_cast<const OGRMultiPoint *>(this);
     904             :     }
     905             : 
     906             :     /** Down-cast to OGRMultiLineString*.
     907             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     908             :      * wkbMultiLineString.
     909             :      * @since GDAL 2.3
     910             :      */
     911         179 :     inline OGRMultiLineString *toMultiLineString()
     912             :     {
     913         179 :         return cpl::down_cast<OGRMultiLineString *>(this);
     914             :     }
     915             : 
     916             :     /** Down-cast to OGRMultiLineString*.
     917             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     918             :      * wkbMultiLineString.
     919             :      * @since GDAL 2.3
     920             :      */
     921         122 :     inline const OGRMultiLineString *toMultiLineString() const
     922             :     {
     923         122 :         return cpl::down_cast<const OGRMultiLineString *>(this);
     924             :     }
     925             : 
     926             :     /** Down-cast to OGRMultiPolygon*.
     927             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     928             :      * wkbMultiPolygon.
     929             :      * @since GDAL 2.3
     930             :      */
     931         533 :     inline OGRMultiPolygon *toMultiPolygon()
     932             :     {
     933         533 :         return cpl::down_cast<OGRMultiPolygon *>(this);
     934             :     }
     935             : 
     936             :     /** Down-cast to OGRMultiPolygon*.
     937             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     938             :      * wkbMultiPolygon.
     939             :      * @since GDAL 2.3
     940             :      */
     941       66546 :     inline const OGRMultiPolygon *toMultiPolygon() const
     942             :     {
     943       66546 :         return cpl::down_cast<const OGRMultiPolygon *>(this);
     944             :     }
     945             : 
     946             :     /** Down-cast to OGRMultiCurve*.
     947             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     948             :      * wkbMultiCurve and derived types.
     949             :      * @since GDAL 2.3
     950             :      */
     951        1033 :     inline OGRMultiCurve *toMultiCurve()
     952             :     {
     953        1033 :         return cpl::down_cast<OGRMultiCurve *>(this);
     954             :     }
     955             : 
     956             :     /** Down-cast to OGRMultiCurve*.
     957             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     958             :      * wkbMultiCurve and derived types.
     959             :      * @since GDAL 2.3
     960             :      */
     961          41 :     inline const OGRMultiCurve *toMultiCurve() const
     962             :     {
     963          41 :         return cpl::down_cast<const OGRMultiCurve *>(this);
     964             :     }
     965             : 
     966             :     /** Down-cast to OGRMultiSurface*.
     967             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     968             :      * wkbMultiSurface and derived types.
     969             :      * @since GDAL 2.3
     970             :      */
     971          13 :     inline OGRMultiSurface *toMultiSurface()
     972             :     {
     973          13 :         return cpl::down_cast<OGRMultiSurface *>(this);
     974             :     }
     975             : 
     976             :     /** Down-cast to OGRMultiSurface*.
     977             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     978             :      * wkbMultiSurface and derived types.
     979             :      * @since GDAL 2.3
     980             :      */
     981         100 :     inline const OGRMultiSurface *toMultiSurface() const
     982             :     {
     983         100 :         return cpl::down_cast<const OGRMultiSurface *>(this);
     984             :     }
     985             : 
     986             :     /** Down-cast to OGRPolyhedralSurface*.
     987             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     988             :      * wkbPolyhedralSurface or wkbTIN.
     989             :      * @since GDAL 2.3
     990             :      */
     991        1234 :     inline OGRPolyhedralSurface *toPolyhedralSurface()
     992             :     {
     993        1234 :         return cpl::down_cast<OGRPolyhedralSurface *>(this);
     994             :     }
     995             : 
     996             :     /** Down-cast to OGRPolyhedralSurface*.
     997             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
     998             :      * wkbPolyhedralSurface or wkbTIN.
     999             :      * @since GDAL 2.3
    1000             :      */
    1001        5766 :     inline const OGRPolyhedralSurface *toPolyhedralSurface() const
    1002             :     {
    1003        5766 :         return cpl::down_cast<const OGRPolyhedralSurface *>(this);
    1004             :     }
    1005             : 
    1006             :     /** Down-cast to OGRTriangulatedSurface*.
    1007             :      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbTIN.
    1008             :      * @since GDAL 2.3
    1009             :      */
    1010           4 :     inline OGRTriangulatedSurface *toTriangulatedSurface()
    1011             :     {
    1012           4 :         return cpl::down_cast<OGRTriangulatedSurface *>(this);
    1013             :     }
    1014             : 
    1015             :     /** Down-cast to OGRTriangulatedSurface*.
    1016             :      * Implies prior checking that wkbFlatten(getGeometryType()) == wkbTIN.
    1017             :      * @since GDAL 2.3
    1018             :      */
    1019           2 :     inline const OGRTriangulatedSurface *toTriangulatedSurface() const
    1020             :     {
    1021           2 :         return cpl::down_cast<const OGRTriangulatedSurface *>(this);
    1022             :     }
    1023             : };
    1024             : 
    1025             : //! @cond Doxygen_Suppress
    1026             : struct CPL_DLL OGRGeometryUniquePtrDeleter
    1027             : {
    1028             :     void operator()(OGRGeometry *) const;
    1029             : };
    1030             : 
    1031             : //! @endcond
    1032             : 
    1033             : /** Unique pointer type for OGRGeometry.
    1034             :  * @since GDAL 2.3
    1035             :  */
    1036             : typedef std::unique_ptr<OGRGeometry, OGRGeometryUniquePtrDeleter>
    1037             :     OGRGeometryUniquePtr;
    1038             : 
    1039             : //! @cond Doxygen_Suppress
    1040             : #define OGR_FORBID_DOWNCAST_TO(name)                                           \
    1041             :     inline OGR##name *to##name() = delete;                                     \
    1042             :     inline const OGR##name *to##name() const = delete;
    1043             : 
    1044             : #define OGR_FORBID_DOWNCAST_TO_POINT OGR_FORBID_DOWNCAST_TO(Point)
    1045             : #define OGR_FORBID_DOWNCAST_TO_CURVE OGR_FORBID_DOWNCAST_TO(Curve)
    1046             : #define OGR_FORBID_DOWNCAST_TO_SIMPLE_CURVE OGR_FORBID_DOWNCAST_TO(SimpleCurve)
    1047             : #define OGR_FORBID_DOWNCAST_TO_LINESTRING OGR_FORBID_DOWNCAST_TO(LineString)
    1048             : #define OGR_FORBID_DOWNCAST_TO_LINEARRING OGR_FORBID_DOWNCAST_TO(LinearRing)
    1049             : #define OGR_FORBID_DOWNCAST_TO_CIRCULARSTRING                                  \
    1050             :     OGR_FORBID_DOWNCAST_TO(CircularString)
    1051             : #define OGR_FORBID_DOWNCAST_TO_COMPOUNDCURVE                                   \
    1052             :     OGR_FORBID_DOWNCAST_TO(CompoundCurve)
    1053             : #define OGR_FORBID_DOWNCAST_TO_SURFACE OGR_FORBID_DOWNCAST_TO(Surface)
    1054             : #define OGR_FORBID_DOWNCAST_TO_CURVEPOLYGON OGR_FORBID_DOWNCAST_TO(CurvePolygon)
    1055             : #define OGR_FORBID_DOWNCAST_TO_POLYGON OGR_FORBID_DOWNCAST_TO(Polygon)
    1056             : #define OGR_FORBID_DOWNCAST_TO_TRIANGLE OGR_FORBID_DOWNCAST_TO(Triangle)
    1057             : #define OGR_FORBID_DOWNCAST_TO_MULTIPOINT OGR_FORBID_DOWNCAST_TO(MultiPoint)
    1058             : #define OGR_FORBID_DOWNCAST_TO_MULTICURVE OGR_FORBID_DOWNCAST_TO(MultiCurve)
    1059             : #define OGR_FORBID_DOWNCAST_TO_MULTILINESTRING                                 \
    1060             :     OGR_FORBID_DOWNCAST_TO(MultiLineString)
    1061             : #define OGR_FORBID_DOWNCAST_TO_MULTISURFACE OGR_FORBID_DOWNCAST_TO(MultiSurface)
    1062             : #define OGR_FORBID_DOWNCAST_TO_MULTIPOLYGON OGR_FORBID_DOWNCAST_TO(MultiPolygon)
    1063             : #define OGR_FORBID_DOWNCAST_TO_GEOMETRYCOLLECTION                              \
    1064             :     OGR_FORBID_DOWNCAST_TO(GeometryCollection)
    1065             : #define OGR_FORBID_DOWNCAST_TO_POLYHEDRALSURFACE                               \
    1066             :     OGR_FORBID_DOWNCAST_TO(PolyhedralSurface)
    1067             : #define OGR_FORBID_DOWNCAST_TO_TIN OGR_FORBID_DOWNCAST_TO(TriangulatedSurface)
    1068             : 
    1069             : #define OGR_ALLOW_UPCAST_TO(name)                                              \
    1070             :     inline OGR##name *to##name()                                               \
    1071             :     {                                                                          \
    1072             :         return this;                                                           \
    1073             :     }                                                                          \
    1074             :     inline const OGR##name *to##name() const                                   \
    1075             :     {                                                                          \
    1076             :         return this;                                                           \
    1077             :     }
    1078             : 
    1079             : #ifndef SUPPRESS_OGR_ALLOW_CAST_TO_THIS_WARNING
    1080             : #define CAST_TO_THIS_WARNING CPL_WARN_DEPRECATED("Casting to this is useless")
    1081             : #else
    1082             : #define CAST_TO_THIS_WARNING
    1083             : #endif
    1084             : 
    1085             : #define OGR_ALLOW_CAST_TO_THIS(name)                                           \
    1086             :     inline OGR##name *to##name() CAST_TO_THIS_WARNING                          \
    1087             :     {                                                                          \
    1088             :         return this;                                                           \
    1089             :     }                                                                          \
    1090             :     inline const OGR##name *to##name() const CAST_TO_THIS_WARNING              \
    1091             :     {                                                                          \
    1092             :         return this;                                                           \
    1093             :     }
    1094             : 
    1095             : #define OGR_FORBID_DOWNCAST_TO_ALL_CURVES                                      \
    1096             :     OGR_FORBID_DOWNCAST_TO_CURVE                                               \
    1097             :     OGR_FORBID_DOWNCAST_TO_SIMPLE_CURVE                                        \
    1098             :     OGR_FORBID_DOWNCAST_TO_LINESTRING                                          \
    1099             :     OGR_FORBID_DOWNCAST_TO_LINEARRING                                          \
    1100             :     OGR_FORBID_DOWNCAST_TO_CIRCULARSTRING                                      \
    1101             :     OGR_FORBID_DOWNCAST_TO_COMPOUNDCURVE
    1102             : 
    1103             : #define OGR_FORBID_DOWNCAST_TO_ALL_SURFACES                                    \
    1104             :     OGR_FORBID_DOWNCAST_TO_SURFACE                                             \
    1105             :     OGR_FORBID_DOWNCAST_TO_CURVEPOLYGON                                        \
    1106             :     OGR_FORBID_DOWNCAST_TO_POLYGON                                             \
    1107             :     OGR_FORBID_DOWNCAST_TO_TRIANGLE                                            \
    1108             :     OGR_FORBID_DOWNCAST_TO_POLYHEDRALSURFACE                                   \
    1109             :     OGR_FORBID_DOWNCAST_TO_TIN
    1110             : 
    1111             : #define OGR_FORBID_DOWNCAST_TO_ALL_SINGLES                                     \
    1112             :     OGR_FORBID_DOWNCAST_TO_POINT                                               \
    1113             :     OGR_FORBID_DOWNCAST_TO_ALL_CURVES                                          \
    1114             :     OGR_FORBID_DOWNCAST_TO_ALL_SURFACES
    1115             : 
    1116             : #define OGR_FORBID_DOWNCAST_TO_ALL_MULTI                                       \
    1117             :     OGR_FORBID_DOWNCAST_TO_GEOMETRYCOLLECTION                                  \
    1118             :     OGR_FORBID_DOWNCAST_TO_MULTIPOINT                                          \
    1119             :     OGR_FORBID_DOWNCAST_TO_MULTICURVE                                          \
    1120             :     OGR_FORBID_DOWNCAST_TO_MULTILINESTRING                                     \
    1121             :     OGR_FORBID_DOWNCAST_TO_MULTISURFACE                                        \
    1122             :     OGR_FORBID_DOWNCAST_TO_MULTIPOLYGON
    1123             : 
    1124             : //! @endcond
    1125             : 
    1126             : /************************************************************************/
    1127             : /*                               OGRPoint                               */
    1128             : /************************************************************************/
    1129             : 
    1130             : /**
    1131             :  * Point class.
    1132             :  *
    1133             :  * Implements SFCOM IPoint methods.
    1134             :  */
    1135             : 
    1136      332287 : class CPL_DLL OGRPoint : public OGRGeometry
    1137             : {
    1138             :     double x;
    1139             :     double y;
    1140             :     double z;
    1141             :     double m;
    1142             : 
    1143             :   public:
    1144             :     OGRPoint();
    1145             :     OGRPoint(double x, double y);
    1146             :     OGRPoint(double x, double y, double z);
    1147             :     OGRPoint(double x, double y, double z, double m);
    1148             :     OGRPoint(const OGRPoint &other);
    1149             :     /** Move constructor */
    1150      112128 :     OGRPoint(OGRPoint &&other) = default;
    1151             :     static OGRPoint *createXYM(double x, double y, double m);
    1152             : 
    1153             :     OGRPoint &operator=(const OGRPoint &other);
    1154             :     /** Move assignment operator */
    1155             :     OGRPoint &operator=(OGRPoint &&other) = default;
    1156             : 
    1157             :     // IWks Interface
    1158             :     size_t WkbSize() const override;
    1159             :     OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
    1160             :                          size_t &nBytesConsumedOut) override;
    1161             :     OGRErr exportToWkb(unsigned char *,
    1162             :                        const OGRwkbExportOptions * = nullptr) const override;
    1163             : 
    1164             : #ifndef DOXYGEN_XML
    1165             :     using OGRGeometry::importFromWkt; /** deprecated */
    1166             : #endif
    1167             : 
    1168             :     OGRErr importFromWkt(const char **) override;
    1169             : 
    1170             : #ifndef DOXYGEN_XML
    1171             :     using OGRGeometry::exportToWkt;
    1172             : #endif
    1173             : 
    1174             :     /// Export a point to WKT
    1175             :     /// \param opts  Output options.
    1176             :     /// \param err   Pointer to error code, if desired.
    1177             :     /// \return  WKT string representing this point.
    1178             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    1179             :                                     OGRErr *err = nullptr) const override;
    1180             : 
    1181             :     // IGeometry
    1182             :     virtual int getDimension() const override;
    1183             :     virtual OGRPoint *clone() const override;
    1184             :     virtual void empty() override;
    1185             :     virtual void getEnvelope(OGREnvelope *psEnvelope) const override;
    1186             :     virtual void getEnvelope(OGREnvelope3D *psEnvelope) const override;
    1187             : 
    1188     4276348 :     virtual OGRBoolean IsEmpty() const override
    1189             :     {
    1190     4276348 :         return !(flags & OGR_G_NOT_EMPTY_POINT);
    1191             :     }
    1192             : 
    1193             :     // IPoint
    1194             :     /** Return x */
    1195    13253436 :     double getX() const
    1196             :     {
    1197    13253436 :         return x;
    1198             :     }
    1199             : 
    1200             :     /** Return y */
    1201    13001277 :     double getY() const
    1202             :     {
    1203    13001277 :         return y;
    1204             :     }
    1205             : 
    1206             :     /** Return z */
    1207     5228967 :     double getZ() const
    1208             :     {
    1209     5228967 :         return z;
    1210             :     }
    1211             : 
    1212             :     /** Return m */
    1213         925 :     double getM() const
    1214             :     {
    1215         925 :         return m;
    1216             :     }
    1217             : 
    1218             :     // Non standard
    1219             :     virtual bool setCoordinateDimension(int nDimension) override;
    1220             : 
    1221             :     /** Set x
    1222             :      * @param xIn x
    1223             :      */
    1224     1973623 :     void setX(double xIn)
    1225             :     {
    1226     1973623 :         x = xIn;
    1227     1973623 :         if (std::isnan(x) || std::isnan(y))
    1228           5 :             flags &= ~OGR_G_NOT_EMPTY_POINT;
    1229             :         else
    1230     1973622 :             flags |= OGR_G_NOT_EMPTY_POINT;
    1231     1973623 :     }
    1232             : 
    1233             :     /** Set y
    1234             :      * @param yIn y
    1235             :      */
    1236     1973561 :     void setY(double yIn)
    1237             :     {
    1238     1973561 :         y = yIn;
    1239     1973561 :         if (std::isnan(x) || std::isnan(y))
    1240           7 :             flags &= ~OGR_G_NOT_EMPTY_POINT;
    1241             :         else
    1242     1973548 :             flags |= OGR_G_NOT_EMPTY_POINT;
    1243     1973561 :     }
    1244             : 
    1245             :     /** Set z
    1246             :      * @param zIn z
    1247             :      */
    1248       49055 :     void setZ(double zIn)
    1249             :     {
    1250       49055 :         z = zIn;
    1251       49055 :         flags |= OGR_G_3D;
    1252       49055 :     }
    1253             : 
    1254             :     /** Set m
    1255             :      * @param mIn m
    1256             :      */
    1257       28671 :     void setM(double mIn)
    1258             :     {
    1259       28671 :         m = mIn;
    1260       28671 :         flags |= OGR_G_MEASURED;
    1261       28671 :     }
    1262             : 
    1263             :     // ISpatialRelation
    1264             :     virtual OGRBoolean Equals(const OGRGeometry *) const override;
    1265             :     virtual OGRBoolean Intersects(const OGRGeometry *) const override;
    1266             :     virtual OGRBoolean Within(const OGRGeometry *) const override;
    1267             : 
    1268             :     // Non standard from OGRGeometry
    1269             :     virtual const char *getGeometryName() const override;
    1270             :     virtual OGRwkbGeometryType getGeometryType() const override;
    1271             :     virtual OGRErr transform(OGRCoordinateTransformation *poCT) override;
    1272             :     virtual void flattenTo2D() override;
    1273             : 
    1274        1150 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    1275             :     {
    1276        1150 :         visitor->visit(this);
    1277        1150 :     }
    1278             : 
    1279       67890 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    1280             :     {
    1281       67890 :         visitor->visit(this);
    1282       67890 :     }
    1283             : 
    1284             :     virtual void swapXY() override;
    1285             : 
    1286             :     OGR_ALLOW_CAST_TO_THIS(Point)
    1287             :     OGR_FORBID_DOWNCAST_TO_ALL_CURVES
    1288             :     OGR_FORBID_DOWNCAST_TO_ALL_SURFACES
    1289             :     OGR_FORBID_DOWNCAST_TO_ALL_MULTI
    1290             : };
    1291             : 
    1292             : /************************************************************************/
    1293             : /*                            OGRPointIterator                          */
    1294             : /************************************************************************/
    1295             : 
    1296             : /**
    1297             :  * Interface for a point iterator.
    1298             :  *
    1299             :  * @since GDAL 2.0
    1300             :  */
    1301             : 
    1302         256 : class CPL_DLL OGRPointIterator
    1303             : {
    1304             :   public:
    1305             :     virtual ~OGRPointIterator();
    1306             :     virtual OGRBoolean getNextPoint(OGRPoint *p) = 0;
    1307             : 
    1308             :     static void destroy(OGRPointIterator *);
    1309             : };
    1310             : 
    1311             : /************************************************************************/
    1312             : /*                               OGRCurve                               */
    1313             : /************************************************************************/
    1314             : 
    1315             : /**
    1316             :  * Abstract curve base class for OGRLineString, OGRCircularString and
    1317             :  * OGRCompoundCurve
    1318             :  */
    1319             : 
    1320           8 : class CPL_DLL OGRCurve : public OGRGeometry
    1321             : {
    1322             :   protected:
    1323             :     //! @cond Doxygen_Suppress
    1324     3429597 :     OGRCurve() = default;
    1325      301723 :     OGRCurve(const OGRCurve &other) = default;
    1326           4 :     OGRCurve(OGRCurve &&other) = default;
    1327             : 
    1328             :     virtual OGRCurveCasterToLineString GetCasterToLineString() const = 0;
    1329             :     virtual OGRCurveCasterToLinearRing GetCasterToLinearRing() const = 0;
    1330             : 
    1331             :     friend class OGRCurvePolygon;
    1332             :     friend class OGRCompoundCurve;
    1333             :     //! @endcond
    1334             :     virtual int ContainsPoint(const OGRPoint *p) const;
    1335             :     virtual int IntersectsPoint(const OGRPoint *p) const;
    1336             :     virtual double get_AreaOfCurveSegments() const = 0;
    1337             : 
    1338             :   private:
    1339          38 :     class CPL_DLL ConstIterator
    1340             :     {
    1341             :         struct Private;
    1342             :         std::unique_ptr<Private> m_poPrivate;
    1343             : 
    1344             :       public:
    1345             :         ConstIterator(const OGRCurve *poSelf, bool bStart);
    1346             :         ConstIterator(ConstIterator &&oOther) noexcept;
    1347             :         ConstIterator &operator=(ConstIterator &&oOther);
    1348             :         ~ConstIterator();
    1349             :         const OGRPoint &operator*() const;
    1350             :         ConstIterator &operator++();
    1351             :         bool operator!=(const ConstIterator &it) const;
    1352             :     };
    1353             : 
    1354             :     friend inline ConstIterator begin(const OGRCurve *);
    1355             :     friend inline ConstIterator end(const OGRCurve *);
    1356             : 
    1357             :   public:
    1358             :     //! @cond Doxygen_Suppress
    1359             :     OGRCurve &operator=(const OGRCurve &other);
    1360             :     OGRCurve &operator=(OGRCurve &&other) = default;
    1361             :     //! @endcond
    1362             : 
    1363             :     /** Type of child elements. */
    1364             :     typedef OGRPoint ChildType;
    1365             : 
    1366             :     /** Return begin of a point iterator.
    1367             :      *
    1368             :      * Using this iterator for standard range-based loops is safe, but
    1369             :      * due to implementation limitations, you shouldn't try to access
    1370             :      * (dereference) more than one iterator step at a time, since you will get
    1371             :      * a reference to the same OGRPoint& object.
    1372             :      * @since GDAL 2.3
    1373             :      */
    1374             :     ConstIterator begin() const;
    1375             :     /** Return end of a point iterator. */
    1376             :     ConstIterator end() const;
    1377             : 
    1378             :     // IGeometry
    1379             :     virtual OGRCurve *clone() const override = 0;
    1380             : 
    1381             :     // ICurve methods
    1382             :     virtual double get_Length() const = 0;
    1383             :     virtual void StartPoint(OGRPoint *) const = 0;
    1384             :     virtual void EndPoint(OGRPoint *) const = 0;
    1385             :     virtual int get_IsClosed() const;
    1386             :     virtual void Value(double, OGRPoint *) const = 0;
    1387             :     virtual OGRLineString *
    1388             :     CurveToLine(double dfMaxAngleStepSizeDegrees = 0,
    1389             :                 const char *const *papszOptions = nullptr) const = 0;
    1390             :     virtual int getDimension() const override;
    1391             : 
    1392             :     // non standard
    1393             :     virtual int getNumPoints() const = 0;
    1394             :     virtual OGRPointIterator *getPointIterator() const = 0;
    1395             :     virtual OGRBoolean IsConvex() const;
    1396             :     virtual double get_Area() const = 0;
    1397             :     virtual double get_GeodesicArea(
    1398             :         const OGRSpatialReference *poSRSOverride = nullptr) const = 0;
    1399             :     virtual double get_GeodesicLength(
    1400             :         const OGRSpatialReference *poSRSOverride = nullptr) const = 0;
    1401             :     virtual int isClockwise() const;
    1402             :     virtual void reversePoints() = 0;
    1403             : 
    1404             :     /** Down-cast to OGRSimpleCurve*.
    1405             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
    1406             :      * wkbLineString or wkbCircularString. */
    1407         488 :     inline OGRSimpleCurve *toSimpleCurve()
    1408             :     {
    1409         488 :         return cpl::down_cast<OGRSimpleCurve *>(this);
    1410             :     }
    1411             : 
    1412             :     /** Down-cast to OGRSimpleCurve*.
    1413             :      * Implies prior checking that wkbFlatten(getGeometryType()) ==
    1414             :      * wkbLineString or wkbCircularString. */
    1415             :     inline const OGRSimpleCurve *toSimpleCurve() const
    1416             :     {
    1417             :         return cpl::down_cast<const OGRSimpleCurve *>(this);
    1418             :     }
    1419             : 
    1420             :     static OGRCompoundCurve *CastToCompoundCurve(OGRCurve *puCurve);
    1421             :     static OGRLineString *CastToLineString(OGRCurve *poCurve);
    1422             :     static OGRLinearRing *CastToLinearRing(OGRCurve *poCurve);
    1423             : 
    1424             :     OGR_FORBID_DOWNCAST_TO_POINT
    1425             :     OGR_ALLOW_CAST_TO_THIS(Curve)
    1426             :     OGR_FORBID_DOWNCAST_TO_ALL_SURFACES
    1427             :     OGR_FORBID_DOWNCAST_TO_ALL_MULTI
    1428             : };
    1429             : 
    1430             : //! @cond Doxygen_Suppress
    1431             : /** @see OGRCurve::begin() const */
    1432           8 : inline OGRCurve::ConstIterator begin(const OGRCurve *poCurve)
    1433             : {
    1434           8 :     return poCurve->begin();
    1435             : }
    1436             : 
    1437             : /** @see OGRCurve::end() const */
    1438           8 : inline OGRCurve::ConstIterator end(const OGRCurve *poCurve)
    1439             : {
    1440           8 :     return poCurve->end();
    1441             : }
    1442             : 
    1443             : //! @endcond
    1444             : 
    1445             : /************************************************************************/
    1446             : /*                           OGRIteratedPoint                           */
    1447             : /************************************************************************/
    1448             : 
    1449             : /*!
    1450             :  Implementation detail of OGRSimpleCurve::Iterator.
    1451             : 
    1452             :  This class is a simple wrapper over OGRPoint, which shouldn't be directly
    1453             :  referenced by the user other than trough auto&& in an iteator
    1454             :  over a OGRSimpleCurve.
    1455             : 
    1456             :  Typical usage pattern is:
    1457             :  \verbatim
    1458             :  for (auto&& p: line)
    1459             :  {
    1460             :     p.setZ(100);
    1461             :  }
    1462             :  \endverbatim
    1463             : 
    1464             :  The lifetime of this object is coupled to the one of the curve on which it
    1465             :  was returned. It is thus also illegal to modify it once the curve has been
    1466             :  deleted.
    1467             : 
    1468             :  @since GDAL 3.6
    1469             :  */
    1470             : class CPL_DLL OGRIteratedPoint : public OGRPoint
    1471             : {
    1472             :   private:
    1473             :     friend class OGRSimpleCurve;
    1474             : 
    1475             :     OGRSimpleCurve *m_poCurve = nullptr;
    1476             :     int m_nPos = 0;
    1477             : 
    1478         478 :     OGRIteratedPoint() = default;
    1479             : 
    1480             :     CPL_DISALLOW_COPY_ASSIGN(OGRIteratedPoint)
    1481             : 
    1482             :   public:
    1483             :     /** Set x
    1484             :      * @param xIn x
    1485             :      */
    1486             :     void setX(double xIn);
    1487             :     /** Set y
    1488             :      * @param yIn y
    1489             :      */
    1490             :     void setY(double yIn);
    1491             :     /** Set z
    1492             :      * @param zIn z
    1493             :      */
    1494             :     void setZ(double zIn);
    1495             :     /** Set m
    1496             :      * @param mIn m
    1497             :      */
    1498             :     void setM(double mIn);
    1499             : };
    1500             : 
    1501             : /************************************************************************/
    1502             : /*                             OGRSimpleCurve                           */
    1503             : /************************************************************************/
    1504             : 
    1505             : /**
    1506             :  * Abstract curve base class for OGRLineString and OGRCircularString
    1507             :  *
    1508             :  * Note: this class does not exist in SQL/MM standard and exists for
    1509             :  * implementation convenience.
    1510             :  *
    1511             :  * @since GDAL 2.0
    1512             :  */
    1513             : 
    1514             : class CPL_DLL OGRSimpleCurve : public OGRCurve
    1515             : {
    1516             :   protected:
    1517             :     //! @cond Doxygen_Suppress
    1518             :     friend class OGRGeometry;
    1519             : 
    1520             :     int nPointCount = 0;
    1521             :     int m_nPointCapacity = 0;
    1522             :     OGRRawPoint *paoPoints = nullptr;
    1523             :     double *padfZ = nullptr;
    1524             :     double *padfM = nullptr;
    1525             : 
    1526             :     bool Make3D();
    1527             :     void Make2D();
    1528             :     void RemoveM();
    1529             :     bool AddM();
    1530             : 
    1531             :     OGRErr importFromWKTListOnly(const char **ppszInput, int bHasZ, int bHasM,
    1532             :                                  OGRRawPoint *&paoPointsIn, int &nMaxPoints,
    1533             :                                  double *&padfZIn);
    1534             :     //! @endcond
    1535             : 
    1536             :     virtual double get_LinearArea() const;
    1537             : 
    1538             :     /** Constructor */
    1539     3426938 :     OGRSimpleCurve() = default;
    1540             : 
    1541             :     OGRSimpleCurve(const OGRSimpleCurve &other);
    1542             : 
    1543             :     OGRSimpleCurve(OGRSimpleCurve &&other);
    1544             : 
    1545             :   private:
    1546             :     class CPL_DLL Iterator
    1547             :     {
    1548             :         struct Private;
    1549             :         std::unique_ptr<Private> m_poPrivate;
    1550             :         void update();
    1551             : 
    1552             :       public:
    1553             :         Iterator(OGRSimpleCurve *poSelf, int nPos);
    1554             :         Iterator(Iterator &&oOther) noexcept;  // declared but not defined.
    1555             :                                                // Needed for gcc 5.4 at least
    1556             :         ~Iterator();
    1557             :         OGRIteratedPoint &operator*();
    1558             :         Iterator &operator++();
    1559             :         bool operator!=(const Iterator &it) const;
    1560             :     };
    1561             : 
    1562             :     friend inline Iterator begin(OGRSimpleCurve *);
    1563             :     friend inline Iterator end(OGRSimpleCurve *);
    1564             : 
    1565         250 :     class CPL_DLL ConstIterator
    1566             :     {
    1567             :         struct Private;
    1568             :         std::unique_ptr<Private> m_poPrivate;
    1569             : 
    1570             :       public:
    1571             :         ConstIterator(const OGRSimpleCurve *poSelf, int nPos);
    1572             :         ConstIterator(
    1573             :             ConstIterator &&oOther) noexcept;  // declared but not defined.
    1574             :                                                // Needed for gcc 5.4 at least
    1575             :         ~ConstIterator();
    1576             :         const OGRPoint &operator*() const;
    1577             :         ConstIterator &operator++();
    1578             :         bool operator!=(const ConstIterator &it) const;
    1579             :     };
    1580             : 
    1581             :     friend inline ConstIterator begin(const OGRSimpleCurve *);
    1582             :     friend inline ConstIterator end(const OGRSimpleCurve *);
    1583             : 
    1584             :   public:
    1585             :     ~OGRSimpleCurve() override;
    1586             : 
    1587             :     OGRSimpleCurve &operator=(const OGRSimpleCurve &other);
    1588             : 
    1589             :     OGRSimpleCurve &operator=(OGRSimpleCurve &&other);
    1590             : 
    1591             :     /** Type of child elements. */
    1592             :     typedef OGRPoint ChildType;
    1593             : 
    1594             :     /** Return begin of point iterator.
    1595             :      *
    1596             :      * Using this iterator for standard range-based loops is safe, but
    1597             :      * due to implementation limitations, you shouldn't try to access
    1598             :      * (dereference) more than one iterator step at a time, since you will get
    1599             :      * a reference to the same OGRPoint& object.
    1600             :      * @since GDAL 2.3
    1601             :      */
    1602             :     Iterator begin();
    1603             :     /** Return end of point iterator. */
    1604             :     Iterator end();
    1605             :     /** Return begin of point iterator.
    1606             :      *
    1607             :      * Using this iterator for standard range-based loops is safe, but
    1608             :      * due to implementation limitations, you shouldn't try to access
    1609             :      * (dereference) more than one iterator step at a time, since you will get
    1610             :      * a reference to the same OGRPoint& object.
    1611             :      * @since GDAL 2.3
    1612             :      */
    1613             :     ConstIterator begin() const;
    1614             :     /** Return end of point iterator. */
    1615             :     ConstIterator end() const;
    1616             : 
    1617             :     // IWks Interface.
    1618             :     virtual size_t WkbSize() const override;
    1619             :     virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
    1620             :                                  size_t &nBytesConsumedOut) override;
    1621             :     virtual OGRErr
    1622             :     exportToWkb(unsigned char *,
    1623             :                 const OGRwkbExportOptions * = nullptr) const override;
    1624             : 
    1625             : #ifndef DOXYGEN_XML
    1626             :     using OGRGeometry::importFromWkt; /** deprecated */
    1627             : #endif
    1628             : 
    1629             :     OGRErr importFromWkt(const char **) override;
    1630             : 
    1631             : #ifndef DOXYGEN_XML
    1632             :     using OGRGeometry::exportToWkt;
    1633             : #endif
    1634             : 
    1635             :     /// Export a simple curve to WKT
    1636             :     /// \param opts  Output options.
    1637             :     /// \param err   Pointer to error code, if desired.
    1638             :     /// \return  WKT string representing this simple curve.
    1639             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    1640             :                                     OGRErr *err = nullptr) const override;
    1641             : 
    1642             :     // IGeometry interface.
    1643             :     virtual void empty() override;
    1644             :     virtual void getEnvelope(OGREnvelope *psEnvelope) const override;
    1645             :     virtual void getEnvelope(OGREnvelope3D *psEnvelope) const override;
    1646             :     virtual OGRBoolean IsEmpty() const override;
    1647             :     virtual OGRSimpleCurve *clone() const override = 0;
    1648             : 
    1649             :     // ICurve methods.
    1650             :     virtual double get_Length() const override;
    1651             :     virtual void StartPoint(OGRPoint *) const override;
    1652             :     virtual void EndPoint(OGRPoint *) const override;
    1653             :     virtual void Value(double, OGRPoint *) const override;
    1654             :     virtual double Project(const OGRPoint *) const;
    1655             :     virtual OGRLineString *getSubLine(double, double, int) const;
    1656             : 
    1657             :     // ILineString methods.
    1658    10297810 :     virtual int getNumPoints() const override
    1659             :     {
    1660    10297810 :         return nPointCount;
    1661             :     }
    1662             : 
    1663             :     void getPoint(int, OGRPoint *) const;
    1664             : 
    1665     4596767 :     double getX(int i) const
    1666             :     {
    1667     4596767 :         return paoPoints[i].x;
    1668             :     }
    1669             : 
    1670     4330031 :     double getY(int i) const
    1671             :     {
    1672     4330031 :         return paoPoints[i].y;
    1673             :     }
    1674             : 
    1675             :     double getZ(int i) const;
    1676             :     double getM(int i) const;
    1677             : 
    1678             :     // ISpatialRelation
    1679             :     virtual OGRBoolean Equals(const OGRGeometry *) const override;
    1680             : 
    1681             :     // non standard.
    1682             :     virtual bool setCoordinateDimension(int nDimension) override;
    1683             :     virtual bool set3D(OGRBoolean bIs3D) override;
    1684             :     virtual bool setMeasured(OGRBoolean bIsMeasured) override;
    1685             :     bool setNumPoints(int nNewPointCount, int bZeroizeNewContent = TRUE);
    1686             :     bool setPoint(int, OGRPoint *);
    1687             :     bool setPoint(int, double, double);
    1688             :     bool setZ(int, double);
    1689             :     bool setM(int, double);
    1690             :     bool setPoint(int, double, double, double);
    1691             :     bool setPointM(int, double, double, double);
    1692             :     bool setPoint(int, double, double, double, double);
    1693             :     bool setPoints(int, const OGRRawPoint *, const double * = nullptr);
    1694             :     bool setPointsM(int, const OGRRawPoint *, const double *);
    1695             :     bool setPoints(int, const OGRRawPoint *, const double *, const double *);
    1696             :     bool setPoints(int, const double *padfX, const double *padfY,
    1697             :                    const double *padfZIn = nullptr);
    1698             :     bool setPointsM(int, const double *padfX, const double *padfY,
    1699             :                     const double *padfMIn = nullptr);
    1700             :     bool setPoints(int, const double *padfX, const double *padfY,
    1701             :                    const double *padfZIn, const double *padfMIn);
    1702             :     bool addPoint(const OGRPoint *);
    1703             :     bool addPoint(double, double);
    1704             :     bool addPoint(double, double, double);
    1705             :     bool addPointM(double, double, double);
    1706             :     bool addPoint(double, double, double, double);
    1707             : 
    1708             :     bool removePoint(int);
    1709             : 
    1710             :     void getPoints(OGRRawPoint *, double * = nullptr) const;
    1711             :     void getPoints(void *pabyX, int nXStride, void *pabyY, int nYStride,
    1712             :                    void *pabyZ = nullptr, int nZStride = 0,
    1713             :                    void *pabyM = nullptr, int nMStride = 0) const;
    1714             : 
    1715             :     void addSubLineString(const OGRLineString *, int nStartVertex = 0,
    1716             :                           int nEndVertex = -1);
    1717             :     void reversePoints() override;
    1718             :     virtual OGRPointIterator *getPointIterator() const override;
    1719             : 
    1720             :     // non-standard from OGRGeometry
    1721             :     virtual OGRErr transform(OGRCoordinateTransformation *poCT) override;
    1722             :     virtual void flattenTo2D() override;
    1723             :     virtual bool segmentize(double dfMaxLength) override;
    1724             : 
    1725             :     virtual void swapXY() override;
    1726             : 
    1727           3 :     OGR_ALLOW_UPCAST_TO(Curve)
    1728             :     OGR_ALLOW_CAST_TO_THIS(SimpleCurve)
    1729             : };
    1730             : 
    1731             : //! @cond Doxygen_Suppress
    1732             : /** @see OGRSimpleCurve::begin() */
    1733           5 : inline OGRSimpleCurve::Iterator begin(OGRSimpleCurve *poCurve)
    1734             : {
    1735           5 :     return poCurve->begin();
    1736             : }
    1737             : 
    1738             : /** @see OGRSimpleCurve::end() */
    1739           5 : inline OGRSimpleCurve::Iterator end(OGRSimpleCurve *poCurve)
    1740             : {
    1741           5 :     return poCurve->end();
    1742             : }
    1743             : 
    1744             : /** @see OGRSimpleCurve::begin() const */
    1745           5 : inline OGRSimpleCurve::ConstIterator begin(const OGRSimpleCurve *poCurve)
    1746             : {
    1747           5 :     return poCurve->begin();
    1748             : }
    1749             : 
    1750             : /** @see OGRSimpleCurve::end() const */
    1751           5 : inline OGRSimpleCurve::ConstIterator end(const OGRSimpleCurve *poCurve)
    1752             : {
    1753           5 :     return poCurve->end();
    1754             : }
    1755             : 
    1756             : //! @endcond
    1757             : 
    1758             : /************************************************************************/
    1759             : /*                            OGRLineString                             */
    1760             : /************************************************************************/
    1761             : 
    1762             : /**
    1763             :  * Concrete representation of a multi-vertex line.
    1764             :  *
    1765             :  * Note: for implementation convenience, we make it inherit from OGRSimpleCurve
    1766             :  * whereas SFSQL and SQL/MM only make it inherits from OGRCurve.
    1767             :  */
    1768             : 
    1769      301053 : class CPL_DLL OGRLineString : public OGRSimpleCurve
    1770             : {
    1771             :     // cppcheck-suppress unusedPrivateFunction
    1772             :     static OGRLinearRing *CasterToLinearRing(OGRCurve *poCurve);
    1773             : 
    1774             :   protected:
    1775             :     //! @cond Doxygen_Suppress
    1776             :     static OGRLineString *TransferMembersAndDestroy(OGRLineString *poSrc,
    1777             :                                                     OGRLineString *poDst);
    1778             : 
    1779             :     virtual OGRCurveCasterToLineString GetCasterToLineString() const override;
    1780             :     virtual OGRCurveCasterToLinearRing GetCasterToLinearRing() const override;
    1781             : 
    1782             :     virtual double get_AreaOfCurveSegments() const override;
    1783             :     //! @endcond
    1784             : 
    1785             :     static OGRLinearRing *CastToLinearRing(OGRLineString *poLS);
    1786             : 
    1787             :   public:
    1788             :     /** Create an empty line string. */
    1789     3419814 :     OGRLineString() = default;
    1790             :     OGRLineString(const OGRLineString &other);
    1791             :     OGRLineString(OGRLineString &&other);
    1792             : 
    1793             :     OGRLineString &operator=(const OGRLineString &other);
    1794             :     OGRLineString &operator=(OGRLineString &&other);
    1795             : 
    1796             :     virtual OGRLineString *clone() const override;
    1797             :     virtual OGRLineString *
    1798             :     CurveToLine(double dfMaxAngleStepSizeDegrees = 0,
    1799             :                 const char *const *papszOptions = nullptr) const override;
    1800             :     virtual OGRGeometry *
    1801             :     getCurveGeometry(const char *const *papszOptions = nullptr) const override;
    1802             :     virtual double get_Area() const override;
    1803             :     virtual double get_GeodesicArea(
    1804             :         const OGRSpatialReference *poSRSOverride = nullptr) const override;
    1805             :     virtual double get_GeodesicLength(
    1806             :         const OGRSpatialReference *poSRSOverride = nullptr) const override;
    1807             : 
    1808             :     // Non-standard from OGRGeometry.
    1809             :     virtual OGRwkbGeometryType getGeometryType() const override;
    1810             :     virtual const char *getGeometryName() const override;
    1811             :     virtual int isClockwise() const override;
    1812             : 
    1813             :     /** Return pointer of this in upper class */
    1814             :     inline OGRSimpleCurve *toUpperClass()
    1815             :     {
    1816             :         return this;
    1817             :     }
    1818             : 
    1819             :     /** Return pointer of this in upper class */
    1820             :     inline const OGRSimpleCurve *toUpperClass() const
    1821             :     {
    1822             :         return this;
    1823             :     }
    1824             : 
    1825          24 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    1826             :     {
    1827          24 :         visitor->visit(this);
    1828          24 :     }
    1829             : 
    1830          11 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    1831             :     {
    1832          11 :         visitor->visit(this);
    1833          11 :     }
    1834             : 
    1835           2 :     OGR_ALLOW_UPCAST_TO(SimpleCurve)
    1836             :     OGR_ALLOW_CAST_TO_THIS(LineString)
    1837             : };
    1838             : 
    1839             : /************************************************************************/
    1840             : /*                            OGRLinearRing                             */
    1841             : /************************************************************************/
    1842             : 
    1843             : /**
    1844             :  * Concrete representation of a closed ring.
    1845             :  *
    1846             :  * This class is functionally equivalent to an OGRLineString, but has a
    1847             :  * separate identity to maintain alignment with the OpenGIS simple feature
    1848             :  * data model.  It exists to serve as a component of an OGRPolygon.
    1849             :  *
    1850             :  * The OGRLinearRing has no corresponding free standing well known binary
    1851             :  * representation, so importFromWkb() and exportToWkb() will not actually
    1852             :  * work.  There is a non-standard GDAL WKT representation though.
    1853             :  *
    1854             :  * Because OGRLinearRing is not a "proper" free standing simple features
    1855             :  * object, it cannot be directly used on a feature via SetGeometry(), and
    1856             :  * cannot generally be used with GEOS for operations like Intersects().
    1857             :  * Instead the polygon should be used, or the OGRLinearRing should be
    1858             :  * converted to an OGRLineString for such operations.
    1859             :  *
    1860             :  * Note: this class exists in SFSQL 1.2, but not in ISO SQL/MM Part 3.
    1861             :  */
    1862             : 
    1863           6 : class CPL_DLL OGRLinearRing : public OGRLineString
    1864             : {
    1865             :     static OGRLineString *CasterToLineString(OGRCurve *poCurve);
    1866             : 
    1867             :     // IWks Interface - Note this isn't really a first class object
    1868             :     // for the purposes of WKB form.  These methods always fail since this
    1869             :     // object can't be serialized on its own.
    1870             :     virtual size_t WkbSize() const override;
    1871             :     virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
    1872             :                                  size_t &nBytesConsumedOut) override;
    1873             :     OGRErr exportToWkb(unsigned char *,
    1874             :                        const OGRwkbExportOptions * = nullptr) const override;
    1875             : 
    1876             :   protected:
    1877             :     //! @cond Doxygen_Suppress
    1878             :     friend class OGRPolygon;
    1879             :     friend class OGRTriangle;
    1880             : 
    1881             :     // These are not IWks compatible ... just a convenience for OGRPolygon.
    1882             :     virtual size_t _WkbSize(int _flags) const;
    1883             :     virtual OGRErr _importFromWkb(OGRwkbByteOrder, int _flags,
    1884             :                                   const unsigned char *, size_t,
    1885             :                                   size_t &nBytesConsumedOut);
    1886             :     virtual OGRErr _exportToWkb(int _flags, unsigned char *,
    1887             :                                 const OGRwkbExportOptions *) const;
    1888             : 
    1889             :     virtual OGRCurveCasterToLineString GetCasterToLineString() const override;
    1890             :     virtual OGRCurveCasterToLinearRing GetCasterToLinearRing() const override;
    1891             :     //! @endcond
    1892             : 
    1893             :     static OGRLineString *CastToLineString(OGRLinearRing *poLR);
    1894             : 
    1895             :   public:
    1896             :     /** Constructor */
    1897     3069316 :     OGRLinearRing() = default;
    1898             :     OGRLinearRing(const OGRLinearRing &other);
    1899             :     /** Move constructor*/
    1900           1 :     OGRLinearRing(OGRLinearRing &&other) = default;
    1901             :     explicit OGRLinearRing(const OGRLinearRing *);
    1902             : 
    1903             :     OGRLinearRing &operator=(const OGRLinearRing &other);
    1904             :     /** Move assignment operator */
    1905             :     OGRLinearRing &operator=(OGRLinearRing &&other) = default;
    1906             : 
    1907             :     // Non standard.
    1908             :     virtual const char *getGeometryName() const override;
    1909             :     virtual OGRLinearRing *clone() const override;
    1910             : 
    1911             :     //! @cond Doxygen_Suppress
    1912             :     void reverseWindingOrder()
    1913             :         CPL_WARN_DEPRECATED("Use reversePoints() instead");
    1914             :     //! @endcond
    1915             : 
    1916             :     virtual void closeRings() override;
    1917             :     OGRBoolean isPointInRing(const OGRPoint *pt,
    1918             :                              int bTestEnvelope = TRUE) const;
    1919             :     OGRBoolean isPointOnRingBoundary(const OGRPoint *pt,
    1920             :                                      int bTestEnvelope = TRUE) const;
    1921             :     virtual OGRErr transform(OGRCoordinateTransformation *poCT) override;
    1922             : 
    1923             :     /** Return pointer of this in upper class */
    1924          80 :     inline OGRLineString *toUpperClass()
    1925             :     {
    1926          80 :         return this;
    1927             :     }
    1928             : 
    1929             :     /** Return pointer of this in upper class */
    1930          99 :     inline const OGRLineString *toUpperClass() const
    1931             :     {
    1932          99 :         return this;
    1933             :     }
    1934             : 
    1935          80 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    1936             :     {
    1937          80 :         visitor->visit(this);
    1938          80 :     }
    1939             : 
    1940          99 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    1941             :     {
    1942          99 :         visitor->visit(this);
    1943          99 :     }
    1944             : 
    1945             :     OGR_ALLOW_UPCAST_TO(LineString)
    1946             :     OGR_ALLOW_CAST_TO_THIS(LinearRing)
    1947             : };
    1948             : 
    1949             : /************************************************************************/
    1950             : /*                         OGRCircularString                            */
    1951             : /************************************************************************/
    1952             : 
    1953             : /**
    1954             :  * Concrete representation of a circular string, that is to say a curve made
    1955             :  * of one or several arc circles.
    1956             :  *
    1957             :  * Note: for implementation convenience, we make it inherit from OGRSimpleCurve
    1958             :  * whereas SQL/MM only makes it inherits from OGRCurve.
    1959             :  *
    1960             :  * Compatibility: ISO SQL/MM Part 3.
    1961             :  *
    1962             :  * @since GDAL 2.0
    1963             :  */
    1964             : 
    1965         412 : class CPL_DLL OGRCircularString : public OGRSimpleCurve
    1966             : {
    1967             :   private:
    1968             :     void ExtendEnvelopeWithCircular(OGREnvelope *psEnvelope) const;
    1969             :     OGRBoolean IsValidFast() const;
    1970             :     int IsFullCircle(double &cx, double &cy, double &square_R) const;
    1971             : 
    1972             :   protected:
    1973             :     //! @cond Doxygen_Suppress
    1974             :     virtual OGRCurveCasterToLineString GetCasterToLineString() const override;
    1975             :     virtual OGRCurveCasterToLinearRing GetCasterToLinearRing() const override;
    1976             :     virtual int IntersectsPoint(const OGRPoint *p) const override;
    1977             :     virtual int ContainsPoint(const OGRPoint *p) const override;
    1978             :     virtual double get_AreaOfCurveSegments() const override;
    1979             :     //! @endcond
    1980             : 
    1981             :   public:
    1982             :     /** Create an empty circular string. */
    1983        7128 :     OGRCircularString() = default;
    1984             : 
    1985             :     OGRCircularString(const OGRCircularString &other);
    1986             :     /** Move constructor */
    1987           1 :     OGRCircularString(OGRCircularString &&other) = default;
    1988             : 
    1989             :     OGRCircularString &operator=(const OGRCircularString &other);
    1990             :     /** Move assignment operator */
    1991             :     OGRCircularString &operator=(OGRCircularString &&other) = default;
    1992             : 
    1993             :     // IWks Interface.
    1994             :     virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
    1995             :                                  size_t &nBytesConsumedOut) override;
    1996             :     OGRErr exportToWkb(unsigned char *,
    1997             :                        const OGRwkbExportOptions * = nullptr) const override;
    1998             : 
    1999             : #ifndef DOXYGEN_XML
    2000             :     using OGRGeometry::importFromWkt; /** deprecated */
    2001             : #endif
    2002             : 
    2003             :     OGRErr importFromWkt(const char **) override;
    2004             : 
    2005             : #ifndef DOXYGEN_XML
    2006             :     using OGRGeometry::exportToWkt;
    2007             : #endif
    2008             : 
    2009             :     /// Export a circular string to WKT
    2010             :     /// \param opts  Output options.
    2011             :     /// \param err   Pointer to error code, if desired.
    2012             :     /// \return  WKT string representing this circular string.
    2013             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    2014             :                                     OGRErr *err = nullptr) const override;
    2015             : 
    2016             :     // IGeometry interface.
    2017             :     virtual OGRBoolean IsValid() const override;
    2018             :     virtual void getEnvelope(OGREnvelope *psEnvelope) const override;
    2019             :     virtual void getEnvelope(OGREnvelope3D *psEnvelope) const override;
    2020             :     virtual OGRCircularString *clone() const override;
    2021             : 
    2022             :     // ICurve methods.
    2023             :     virtual double get_Length() const override;
    2024             :     virtual OGRLineString *
    2025             :     CurveToLine(double dfMaxAngleStepSizeDegrees = 0,
    2026             :                 const char *const *papszOptions = nullptr) const override;
    2027             :     virtual void Value(double, OGRPoint *) const override;
    2028             :     virtual double get_Area() const override;
    2029             :     virtual double get_GeodesicArea(
    2030             :         const OGRSpatialReference *poSRSOverride = nullptr) const override;
    2031             :     virtual double get_GeodesicLength(
    2032             :         const OGRSpatialReference *poSRSOverride = nullptr) const override;
    2033             : 
    2034             :     // Non-standard from OGRGeometry.
    2035             :     virtual OGRwkbGeometryType getGeometryType() const override;
    2036             :     virtual const char *getGeometryName() const override;
    2037             :     virtual bool segmentize(double dfMaxLength) override;
    2038             :     virtual OGRBoolean
    2039             :     hasCurveGeometry(int bLookForNonLinear = FALSE) const override;
    2040             :     virtual OGRGeometry *
    2041             :     getLinearGeometry(double dfMaxAngleStepSizeDegrees = 0,
    2042             :                       const char *const *papszOptions = nullptr) const override;
    2043             : 
    2044             :     /** Return pointer of this in upper class */
    2045             :     inline OGRSimpleCurve *toUpperClass()
    2046             :     {
    2047             :         return this;
    2048             :     }
    2049             : 
    2050             :     /** Return pointer of this in upper class */
    2051             :     inline const OGRSimpleCurve *toUpperClass() const
    2052             :     {
    2053             :         return this;
    2054             :     }
    2055             : 
    2056           1 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    2057             :     {
    2058           1 :         visitor->visit(this);
    2059           1 :     }
    2060             : 
    2061           6 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    2062             :     {
    2063           6 :         visitor->visit(this);
    2064           6 :     }
    2065             : 
    2066           1 :     OGR_ALLOW_UPCAST_TO(SimpleCurve)
    2067             :     OGR_ALLOW_CAST_TO_THIS(CircularString)
    2068             : };
    2069             : 
    2070             : /************************************************************************/
    2071             : /*                           OGRCurveCollection                         */
    2072             : /************************************************************************/
    2073             : 
    2074             : /**
    2075             :  * Utility class to store a collection of curves. Used as a member of
    2076             :  * OGRCompoundCurve and OGRCurvePolygon.
    2077             :  *
    2078             :  * This class is only exported because of linking issues. It should never
    2079             :  * be directly used.
    2080             :  *
    2081             :  * @since GDAL 2.0
    2082             :  */
    2083             : 
    2084             : //! @cond Doxygen_Suppress
    2085             : class CPL_DLL OGRCurveCollection
    2086             : {
    2087             :   protected:
    2088             :     friend class OGRCompoundCurve;
    2089             :     friend class OGRCurvePolygon;
    2090             :     friend class OGRPolygon;
    2091             :     friend class OGRTriangle;
    2092             : 
    2093             :     int nCurveCount = 0;
    2094             :     OGRCurve **papoCurves = nullptr;
    2095             : 
    2096             :   public:
    2097     1513958 :     OGRCurveCollection() = default;
    2098             :     OGRCurveCollection(const OGRCurveCollection &other);
    2099             :     OGRCurveCollection(OGRCurveCollection &&other);
    2100             :     ~OGRCurveCollection();
    2101             : 
    2102             :     OGRCurveCollection &operator=(const OGRCurveCollection &other);
    2103             :     OGRCurveCollection &operator=(OGRCurveCollection &&other);
    2104             : 
    2105             :     /** Type of child elements. */
    2106             :     typedef OGRCurve ChildType;
    2107             : 
    2108             :     /** Return begin of curve iterator.
    2109             :      * @since GDAL 2.3
    2110             :      */
    2111     6260400 :     OGRCurve **begin()
    2112             :     {
    2113     6260400 :         return papoCurves;
    2114             :     }
    2115             : 
    2116             :     /** Return end of curve iterator. */
    2117     6260390 :     OGRCurve **end()
    2118             :     {
    2119     6260390 :         return papoCurves + nCurveCount;
    2120             :     }
    2121             : 
    2122             :     /** Return begin of curve iterator.
    2123             :      * @since GDAL 2.3
    2124             :      */
    2125     1805238 :     const OGRCurve *const *begin() const
    2126             :     {
    2127     1805238 :         return papoCurves;
    2128             :     }
    2129             : 
    2130             :     /** Return end of curve iterator. */
    2131     1805208 :     const OGRCurve *const *end() const
    2132             :     {
    2133     1805208 :         return papoCurves + nCurveCount;
    2134             :     }
    2135             : 
    2136             :     void empty(OGRGeometry *poGeom);
    2137             :     OGRBoolean IsEmpty() const;
    2138             :     void getEnvelope(OGREnvelope *psEnvelope) const;
    2139             :     void getEnvelope(OGREnvelope3D *psEnvelope) const;
    2140             : 
    2141             :     OGRErr addCurveDirectly(OGRGeometry *poGeom, OGRCurve *poCurve,
    2142             :                             int bNeedRealloc);
    2143             :     size_t WkbSize() const;
    2144             :     OGRErr importPreambleFromWkb(OGRGeometry *poGeom,
    2145             :                                  const unsigned char *pabyData, size_t &nSize,
    2146             :                                  size_t &nDataOffset,
    2147             :                                  OGRwkbByteOrder &eByteOrder,
    2148             :                                  size_t nMinSubGeomSize,
    2149             :                                  OGRwkbVariant eWkbVariant);
    2150             :     OGRErr
    2151             :     importBodyFromWkb(OGRGeometry *poGeom, const unsigned char *pabyData,
    2152             :                       size_t nSize, bool bAcceptCompoundCurve,
    2153             :                       OGRErr (*pfnAddCurveDirectlyFromWkb)(OGRGeometry *poGeom,
    2154             :                                                            OGRCurve *poCurve),
    2155             :                       OGRwkbVariant eWkbVariant, size_t &nBytesConsumedOut);
    2156             :     std::string exportToWkt(const OGRGeometry *geom, const OGRWktOptions &opts,
    2157             :                             OGRErr *err) const;
    2158             :     OGRErr exportToWkb(const OGRGeometry *poGeom, unsigned char *,
    2159             :                        const OGRwkbExportOptions * = nullptr) const;
    2160             :     OGRBoolean Equals(const OGRCurveCollection *poOCC) const;
    2161             :     bool setCoordinateDimension(OGRGeometry *poGeom, int nNewDimension);
    2162             :     bool set3D(OGRGeometry *poGeom, OGRBoolean bIs3D);
    2163             :     bool setMeasured(OGRGeometry *poGeom, OGRBoolean bIsMeasured);
    2164             :     void assignSpatialReference(OGRGeometry *poGeom,
    2165             :                                 const OGRSpatialReference *poSR);
    2166             :     int getNumCurves() const;
    2167             :     OGRCurve *getCurve(int);
    2168             :     const OGRCurve *getCurve(int) const;
    2169             :     OGRCurve *stealCurve(int);
    2170             : 
    2171             :     OGRErr removeCurve(int iIndex, bool bDelete = true);
    2172             : 
    2173             :     bool hasEmptyParts() const;
    2174             :     void removeEmptyParts();
    2175             : 
    2176             :     void reversePoints();
    2177             : 
    2178             :     OGRErr transform(OGRGeometry *poGeom, OGRCoordinateTransformation *poCT);
    2179             :     void flattenTo2D(OGRGeometry *poGeom);
    2180             :     bool segmentize(double dfMaxLength);
    2181             :     void swapXY();
    2182             :     OGRBoolean hasCurveGeometry(int bLookForNonLinear) const;
    2183             : };
    2184             : 
    2185             : //! @endcond
    2186             : 
    2187             : /************************************************************************/
    2188             : /*                            OGRCompoundCurve                          */
    2189             : /************************************************************************/
    2190             : 
    2191             : /**
    2192             :  * Concrete representation of a compound curve, made of curves: OGRLineString
    2193             :  * and OGRCircularString. Each curve is connected by its first point to
    2194             :  * the last point of the previous curve.
    2195             :  *
    2196             :  * Compatibility: ISO SQL/MM Part 3.
    2197             :  *
    2198             :  * @since GDAL 2.0
    2199             :  */
    2200             : 
    2201         264 : class CPL_DLL OGRCompoundCurve : public OGRCurve
    2202             : {
    2203             :   private:
    2204             :     OGRCurveCollection oCC{};
    2205             : 
    2206             :     OGRErr addCurveDirectlyInternal(OGRCurve *poCurve, double dfToleranceEps,
    2207             :                                     int bNeedRealloc);
    2208             :     static OGRErr addCurveDirectlyFromWkt(OGRGeometry *poSelf,
    2209             :                                           OGRCurve *poCurve);
    2210             :     static OGRErr addCurveDirectlyFromWkb(OGRGeometry *poSelf,
    2211             :                                           OGRCurve *poCurve);
    2212             :     OGRLineString *CurveToLineInternal(double dfMaxAngleStepSizeDegrees,
    2213             :                                        const char *const *papszOptions,
    2214             :                                        int bIsLinearRing) const;
    2215             :     // cppcheck-suppress unusedPrivateFunction
    2216             :     static OGRLineString *CasterToLineString(OGRCurve *poCurve);
    2217             :     // cppcheck-suppress unusedPrivateFunction
    2218             :     static OGRLinearRing *CasterToLinearRing(OGRCurve *poCurve);
    2219             : 
    2220             :   protected:
    2221             :     //! @cond Doxygen_Suppress
    2222             :     static OGRLineString *CastToLineString(OGRCompoundCurve *poCC);
    2223             :     static OGRLinearRing *CastToLinearRing(OGRCompoundCurve *poCC);
    2224             : 
    2225             :     virtual OGRCurveCasterToLineString GetCasterToLineString() const override;
    2226             :     virtual OGRCurveCasterToLinearRing GetCasterToLinearRing() const override;
    2227             :     //! @endcond
    2228             : 
    2229             :   public:
    2230             :     /** Create an empty compound curve. */
    2231        2658 :     OGRCompoundCurve() = default;
    2232             : 
    2233             :     OGRCompoundCurve(const OGRCompoundCurve &other);
    2234             :     /** Move constructor */
    2235           1 :     OGRCompoundCurve(OGRCompoundCurve &&other) = default;
    2236             : 
    2237             :     OGRCompoundCurve &operator=(const OGRCompoundCurve &other);
    2238             :     /** Move assignment operator */
    2239             :     OGRCompoundCurve &operator=(OGRCompoundCurve &&other) = default;
    2240             : 
    2241             :     /** Type of child elements. */
    2242             :     typedef OGRCurve ChildType;
    2243             : 
    2244             :     /** Return begin of curve iterator.
    2245             :      * @since GDAL 2.3
    2246             :      */
    2247          15 :     ChildType **begin()
    2248             :     {
    2249          15 :         return oCC.begin();
    2250             :     }
    2251             : 
    2252             :     /** Return end of curve iterator. */
    2253          15 :     ChildType **end()
    2254             :     {
    2255          15 :         return oCC.end();
    2256             :     }
    2257             : 
    2258             :     /** Return begin of curve iterator.
    2259             :      * @since GDAL 2.3
    2260             :      */
    2261          20 :     const ChildType *const *begin() const
    2262             :     {
    2263          20 :         return oCC.begin();
    2264             :     }
    2265             : 
    2266             :     /** Return end of curve iterator. */
    2267          20 :     const ChildType *const *end() const
    2268             :     {
    2269          20 :         return oCC.end();
    2270             :     }
    2271             : 
    2272             :     // IWks Interface
    2273             :     virtual size_t WkbSize() const override;
    2274             :     virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
    2275             :                                  size_t &nBytesConsumedOut) override;
    2276             :     OGRErr exportToWkb(unsigned char *,
    2277             :                        const OGRwkbExportOptions * = nullptr) const override;
    2278             : 
    2279             : #ifndef DOXYGEN_XML
    2280             :     using OGRGeometry::importFromWkt; /** deprecated */
    2281             : #endif
    2282             : 
    2283             :     OGRErr importFromWkt(const char **) override;
    2284             : 
    2285             : #ifndef DOXYGEN_XML
    2286             :     using OGRGeometry::exportToWkt;
    2287             : #endif
    2288             : 
    2289             :     /// Export a compound curve to WKT
    2290             :     /// \param opts  Output options.
    2291             :     /// \param err   Pointer to error code, if desired.
    2292             :     /// \return      WKT representation of the compound curve.
    2293             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    2294             :                                     OGRErr *err = nullptr) const override;
    2295             : 
    2296             :     // IGeometry interface.
    2297             :     virtual OGRCompoundCurve *clone() const override;
    2298             :     virtual void empty() override;
    2299             :     virtual void getEnvelope(OGREnvelope *psEnvelope) const override;
    2300             :     virtual void getEnvelope(OGREnvelope3D *psEnvelope) const override;
    2301             :     virtual OGRBoolean IsEmpty() const override;
    2302             : 
    2303             :     // ICurve methods.
    2304             :     virtual double get_Length() const override;
    2305             :     virtual void StartPoint(OGRPoint *) const override;
    2306             :     virtual void EndPoint(OGRPoint *) const override;
    2307             :     virtual void Value(double, OGRPoint *) const override;
    2308             :     virtual OGRLineString *
    2309             :     CurveToLine(double dfMaxAngleStepSizeDegrees = 0,
    2310             :                 const char *const *papszOptions = nullptr) const override;
    2311             : 
    2312             :     virtual int getNumPoints() const override;
    2313             :     virtual double get_AreaOfCurveSegments() const override;
    2314             :     virtual double get_Area() const override;
    2315             :     virtual double get_GeodesicArea(
    2316             :         const OGRSpatialReference *poSRSOverride = nullptr) const override;
    2317             :     virtual double get_GeodesicLength(
    2318             :         const OGRSpatialReference *poSRSOverride = nullptr) const override;
    2319             : 
    2320             :     // ISpatialRelation.
    2321             :     virtual OGRBoolean Equals(const OGRGeometry *) const override;
    2322             : 
    2323             :     // ICompoundCurve method.
    2324             :     int getNumCurves() const;
    2325             :     OGRCurve *getCurve(int);
    2326             :     const OGRCurve *getCurve(int) const;
    2327             : 
    2328             :     // Non-standard.
    2329             :     virtual bool setCoordinateDimension(int nDimension) override;
    2330             :     virtual bool set3D(OGRBoolean bIs3D) override;
    2331             :     virtual bool setMeasured(OGRBoolean bIsMeasured) override;
    2332             : 
    2333             :     virtual void
    2334             :     assignSpatialReference(const OGRSpatialReference *poSR) override;
    2335             : 
    2336             :     /** Default relative tolerance to assume that the end of the previous curve
    2337             :      * is equal to the start of the next one.
    2338             :      */
    2339             :     static constexpr double DEFAULT_TOLERANCE_EPSILON = 1e-14;
    2340             : 
    2341             :     OGRErr addCurve(const OGRCurve *,
    2342             :                     double dfToleranceEps = DEFAULT_TOLERANCE_EPSILON);
    2343             :     OGRErr addCurveDirectly(OGRCurve *,
    2344             :                             double dfToleranceEps = DEFAULT_TOLERANCE_EPSILON);
    2345             :     OGRErr addCurve(std::unique_ptr<OGRCurve>,
    2346             :                     double dfToleranceEps = DEFAULT_TOLERANCE_EPSILON);
    2347             :     OGRCurve *stealCurve(int);
    2348             :     virtual OGRPointIterator *getPointIterator() const override;
    2349             :     void reversePoints() override;
    2350             : 
    2351             :     // Non-standard from OGRGeometry.
    2352             :     virtual OGRwkbGeometryType getGeometryType() const override;
    2353             :     virtual const char *getGeometryName() const override;
    2354             :     virtual OGRErr transform(OGRCoordinateTransformation *poCT) override;
    2355             :     virtual void flattenTo2D() override;
    2356             :     virtual bool segmentize(double dfMaxLength) override;
    2357             :     virtual OGRBoolean
    2358             :     hasCurveGeometry(int bLookForNonLinear = FALSE) const override;
    2359             :     virtual OGRGeometry *
    2360             :     getLinearGeometry(double dfMaxAngleStepSizeDegrees = 0,
    2361             :                       const char *const *papszOptions = nullptr) const override;
    2362             : 
    2363           1 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    2364             :     {
    2365           1 :         visitor->visit(this);
    2366           1 :     }
    2367             : 
    2368           3 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    2369             :     {
    2370           3 :         visitor->visit(this);
    2371           3 :     }
    2372             : 
    2373             :     virtual void swapXY() override;
    2374             : 
    2375             :     bool hasEmptyParts() const override;
    2376             :     void removeEmptyParts() override;
    2377             : 
    2378           1 :     OGR_ALLOW_UPCAST_TO(Curve)
    2379             :     OGR_ALLOW_CAST_TO_THIS(CompoundCurve)
    2380             : };
    2381             : 
    2382             : //! @cond Doxygen_Suppress
    2383             : /** @see OGRCompoundCurve::begin() const */
    2384             : inline const OGRCompoundCurve::ChildType *const *
    2385           3 : begin(const OGRCompoundCurve *poCurve)
    2386             : {
    2387           3 :     return poCurve->begin();
    2388             : }
    2389             : 
    2390             : /** @see OGRCompoundCurve::end() const */
    2391             : inline const OGRCompoundCurve::ChildType *const *
    2392           3 : end(const OGRCompoundCurve *poCurve)
    2393             : {
    2394           3 :     return poCurve->end();
    2395             : }
    2396             : 
    2397             : /** @see OGRCompoundCurve::begin() */
    2398          14 : inline OGRCompoundCurve::ChildType **begin(OGRCompoundCurve *poCurve)
    2399             : {
    2400          14 :     return poCurve->begin();
    2401             : }
    2402             : 
    2403             : /** @see OGRCompoundCurve::end() */
    2404          14 : inline OGRCompoundCurve::ChildType **end(OGRCompoundCurve *poCurve)
    2405             : {
    2406          14 :     return poCurve->end();
    2407             : }
    2408             : 
    2409             : //! @endcond
    2410             : 
    2411             : /************************************************************************/
    2412             : /*                              OGRSurface                              */
    2413             : /************************************************************************/
    2414             : 
    2415             : /**
    2416             :  * Abstract base class for 2 dimensional objects like polygons or curve
    2417             :  * polygons.
    2418             :  */
    2419             : 
    2420             : class CPL_DLL OGRSurface : public OGRGeometry
    2421             : {
    2422             :   protected:
    2423             :     //! @cond Doxygen_Suppress
    2424             :     virtual OGRSurfaceCasterToPolygon GetCasterToPolygon() const = 0;
    2425             :     virtual OGRSurfaceCasterToCurvePolygon GetCasterToCurvePolygon() const = 0;
    2426             :     //! @endcond
    2427             : 
    2428             :   public:
    2429             :     virtual double get_Area() const = 0;
    2430             :     virtual double get_GeodesicArea(
    2431             :         const OGRSpatialReference *poSRSOverride = nullptr) const = 0;
    2432             :     virtual double get_Length() const = 0;
    2433             :     virtual double get_GeodesicLength(
    2434             :         const OGRSpatialReference *poSRSOverride = nullptr) const = 0;
    2435             : 
    2436           0 :     virtual OGRErr PointOnSurface(OGRPoint *poPoint) const
    2437             :     {
    2438           0 :         return PointOnSurfaceInternal(poPoint);
    2439             :     }
    2440             : 
    2441             :     virtual OGRSurface *clone() const override = 0;
    2442             : 
    2443             :     //! @cond Doxygen_Suppress
    2444             :     static OGRPolygon *CastToPolygon(OGRSurface *poSurface);
    2445             :     static OGRCurvePolygon *CastToCurvePolygon(OGRSurface *poSurface);
    2446             :     //! @endcond
    2447             : 
    2448             :     OGR_FORBID_DOWNCAST_TO_POINT
    2449             :     OGR_FORBID_DOWNCAST_TO_ALL_CURVES
    2450             :     OGR_ALLOW_CAST_TO_THIS(Surface)
    2451             :     OGR_FORBID_DOWNCAST_TO_ALL_MULTI
    2452             : };
    2453             : 
    2454             : /************************************************************************/
    2455             : /*                          OGRCurvePolygon                             */
    2456             : /************************************************************************/
    2457             : 
    2458             : /**
    2459             :  * Concrete class representing curve polygons.
    2460             :  *
    2461             :  * Note that curve polygons consist of one outer (curve) ring, and zero or
    2462             :  * more inner rings.  A curve polygon cannot represent disconnected
    2463             :  * regions (such as multiple islands in a political body).  The
    2464             :  * OGRMultiSurface must be used for this.
    2465             :  *
    2466             :  * Compatibility: ISO SQL/MM Part 3.
    2467             :  *
    2468             :  * @since GDAL 2.0
    2469             :  */
    2470             : 
    2471     1549106 : class CPL_DLL OGRCurvePolygon : public OGRSurface
    2472             : {
    2473             :     static OGRPolygon *CasterToPolygon(OGRSurface *poSurface);
    2474             : 
    2475             :   private:
    2476             :     OGRBoolean IntersectsPoint(const OGRPoint *p) const;
    2477             :     OGRBoolean ContainsPoint(const OGRPoint *p) const;
    2478             : 
    2479             :     virtual bool isRingCorrectType(const OGRCurve *poRing) const;
    2480             : 
    2481             :     virtual bool checkRing(const OGRCurve *poNewRing) const;
    2482             :     OGRErr addRingDirectlyInternal(OGRCurve *poCurve, int bNeedRealloc);
    2483             :     static OGRErr addCurveDirectlyFromWkt(OGRGeometry *poSelf,
    2484             :                                           OGRCurve *poCurve);
    2485             :     static OGRErr addCurveDirectlyFromWkb(OGRGeometry *poSelf,
    2486             :                                           OGRCurve *poCurve);
    2487             : 
    2488             :   protected:
    2489             :     //! @cond Doxygen_Suppress
    2490             :     friend class OGRPolygon;
    2491             :     friend class OGRTriangle;
    2492             :     OGRCurveCollection oCC{};
    2493             : 
    2494             :     virtual OGRSurfaceCasterToPolygon GetCasterToPolygon() const override;
    2495             :     virtual OGRSurfaceCasterToCurvePolygon
    2496             :     GetCasterToCurvePolygon() const override;
    2497             : 
    2498             :     //! @endcond
    2499             : 
    2500             :     static OGRPolygon *CastToPolygon(OGRCurvePolygon *poCP);
    2501             : 
    2502             :   public:
    2503             :     /** Create an empty curve polygon. */
    2504     1511304 :     OGRCurvePolygon() = default;
    2505             : 
    2506             :     OGRCurvePolygon(const OGRCurvePolygon &);
    2507             :     /** Move constructor */
    2508           3 :     OGRCurvePolygon(OGRCurvePolygon &&) = default;
    2509             : 
    2510             :     OGRCurvePolygon &operator=(const OGRCurvePolygon &other);
    2511             :     /** Move assignment operator */
    2512             :     OGRCurvePolygon &operator=(OGRCurvePolygon &&other) = default;
    2513             : 
    2514             :     /** Type of child elements. */
    2515             :     typedef OGRCurve ChildType;
    2516             : 
    2517             :     /** Return begin of curve iterator.
    2518             :      * @since GDAL 2.3
    2519             :      */
    2520         101 :     ChildType **begin()
    2521             :     {
    2522         101 :         return oCC.begin();
    2523             :     }
    2524             : 
    2525             :     /** Return end of curve iterator. */
    2526         101 :     ChildType **end()
    2527             :     {
    2528         101 :         return oCC.end();
    2529             :     }
    2530             : 
    2531             :     /** Return begin of curve iterator.
    2532             :      * @since GDAL 2.3
    2533             :      */
    2534         148 :     const ChildType *const *begin() const
    2535             :     {
    2536         148 :         return oCC.begin();
    2537             :     }
    2538             : 
    2539             :     /** Return end of curve iterator. */
    2540         148 :     const ChildType *const *end() const
    2541             :     {
    2542         148 :         return oCC.end();
    2543             :     }
    2544             : 
    2545             :     // Non standard (OGRGeometry).
    2546             :     virtual const char *getGeometryName() const override;
    2547             :     virtual OGRwkbGeometryType getGeometryType() const override;
    2548             :     virtual OGRCurvePolygon *clone() const override;
    2549             :     virtual void empty() override;
    2550             :     virtual OGRErr transform(OGRCoordinateTransformation *poCT) override;
    2551             :     virtual void flattenTo2D() override;
    2552             :     virtual OGRBoolean IsEmpty() const override;
    2553             :     virtual bool segmentize(double dfMaxLength) override;
    2554             :     virtual OGRBoolean
    2555             :     hasCurveGeometry(int bLookForNonLinear = FALSE) const override;
    2556             :     virtual OGRGeometry *
    2557             :     getLinearGeometry(double dfMaxAngleStepSizeDegrees = 0,
    2558             :                       const char *const *papszOptions = nullptr) const override;
    2559             :     virtual double get_GeodesicArea(
    2560             :         const OGRSpatialReference *poSRSOverride = nullptr) const override;
    2561             :     virtual double get_GeodesicLength(
    2562             :         const OGRSpatialReference *poSRSOverride = nullptr) const override;
    2563             : 
    2564             :     // ISurface Interface
    2565             :     virtual double get_Area() const override;
    2566             : 
    2567             :     virtual double get_Length() const override;
    2568             : 
    2569             :     // IWks Interface
    2570             :     virtual size_t WkbSize() const override;
    2571             :     virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
    2572             :                                  size_t &nBytesConsumedOut) override;
    2573             :     OGRErr exportToWkb(unsigned char *,
    2574             :                        const OGRwkbExportOptions * = nullptr) const override;
    2575             : 
    2576             : #ifndef DOXYGEN_XML
    2577             :     using OGRGeometry::importFromWkt; /** deprecated */
    2578             : #endif
    2579             : 
    2580             :     OGRErr importFromWkt(const char **) override;
    2581             : 
    2582             : #ifndef DOXYGEN_XML
    2583             :     using OGRGeometry::exportToWkt;
    2584             : #endif
    2585             : 
    2586             :     /// Export a curve polygon to WKT
    2587             :     /// \param opts  Output options.
    2588             :     /// \param err   Pointer to error code, if desired.
    2589             :     /// \return      WKT representation of the curve polygon.
    2590             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    2591             :                                     OGRErr *err = nullptr) const override;
    2592             : 
    2593             :     // IGeometry
    2594             :     virtual int getDimension() const override;
    2595             :     virtual void getEnvelope(OGREnvelope *psEnvelope) const override;
    2596             :     virtual void getEnvelope(OGREnvelope3D *psEnvelope) const override;
    2597             : 
    2598             :     // ICurvePolygon
    2599             :     virtual OGRPolygon *
    2600             :     CurvePolyToPoly(double dfMaxAngleStepSizeDegrees = 0,
    2601             :                     const char *const *papszOptions = nullptr) const;
    2602             : 
    2603             :     // ISpatialRelation
    2604             :     virtual OGRBoolean Equals(const OGRGeometry *) const override;
    2605             :     virtual OGRBoolean Intersects(const OGRGeometry *) const override;
    2606             :     virtual OGRBoolean Contains(const OGRGeometry *) const override;
    2607             : 
    2608             :     // Non standard
    2609             :     virtual bool setCoordinateDimension(int nDimension) override;
    2610             :     virtual bool set3D(OGRBoolean bIs3D) override;
    2611             :     virtual bool setMeasured(OGRBoolean bIsMeasured) override;
    2612             : 
    2613             :     virtual void
    2614             :     assignSpatialReference(const OGRSpatialReference *poSR) override;
    2615             : 
    2616             :     virtual OGRErr addRing(const OGRCurve *);
    2617             :     virtual OGRErr addRingDirectly(OGRCurve *);
    2618             :     OGRErr addRing(std::unique_ptr<OGRCurve>);
    2619             : 
    2620             :     OGRCurve *getExteriorRingCurve();
    2621             :     const OGRCurve *getExteriorRingCurve() const;
    2622             :     int getNumInteriorRings() const;
    2623             :     OGRCurve *getInteriorRingCurve(int);
    2624             :     const OGRCurve *getInteriorRingCurve(int) const;
    2625             : 
    2626             :     OGRCurve *stealExteriorRingCurve();
    2627             : 
    2628             :     OGRErr removeRing(int iIndex, bool bDelete = true);
    2629             : 
    2630           1 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    2631             :     {
    2632           1 :         visitor->visit(this);
    2633           1 :     }
    2634             : 
    2635           3 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    2636             :     {
    2637           3 :         visitor->visit(this);
    2638           3 :     }
    2639             : 
    2640             :     virtual void swapXY() override;
    2641             : 
    2642             :     bool hasEmptyParts() const override;
    2643             :     void removeEmptyParts() override;
    2644             : 
    2645           8 :     OGR_ALLOW_UPCAST_TO(Surface)
    2646             :     OGR_ALLOW_CAST_TO_THIS(CurvePolygon)
    2647             : };
    2648             : 
    2649             : //! @cond Doxygen_Suppress
    2650             : /** @see OGRCurvePolygon::begin() const */
    2651             : inline const OGRCurvePolygon::ChildType *const *
    2652           2 : begin(const OGRCurvePolygon *poGeom)
    2653             : {
    2654           2 :     return poGeom->begin();
    2655             : }
    2656             : 
    2657             : /** @see OGRCurvePolygon::end() const */
    2658             : inline const OGRCurvePolygon::ChildType *const *
    2659           2 : end(const OGRCurvePolygon *poGeom)
    2660             : {
    2661           2 :     return poGeom->end();
    2662             : }
    2663             : 
    2664             : /** @see OGRCurvePolygon::begin() */
    2665           2 : inline OGRCurvePolygon::ChildType **begin(OGRCurvePolygon *poGeom)
    2666             : {
    2667           2 :     return poGeom->begin();
    2668             : }
    2669             : 
    2670             : /** @see OGRCurvePolygon::end() */
    2671           2 : inline OGRCurvePolygon::ChildType **end(OGRCurvePolygon *poGeom)
    2672             : {
    2673           2 :     return poGeom->end();
    2674             : }
    2675             : 
    2676             : //! @endcond
    2677             : 
    2678             : /************************************************************************/
    2679             : /*                              OGRPolygon                              */
    2680             : /************************************************************************/
    2681             : 
    2682             : /**
    2683             :  * Concrete class representing polygons.
    2684             :  *
    2685             :  * Note that the OpenGIS simple features polygons consist of one outer ring
    2686             :  * (linearring), and zero or more inner rings.  A polygon cannot represent
    2687             :  * disconnected regions (such as multiple islands in a political body).  The
    2688             :  * OGRMultiPolygon must be used for this.
    2689             :  */
    2690             : 
    2691     1548844 : class CPL_DLL OGRPolygon : public OGRCurvePolygon
    2692             : {
    2693             :     static OGRCurvePolygon *CasterToCurvePolygon(OGRSurface *poSurface);
    2694             : 
    2695             :   protected:
    2696             :     //! @cond Doxygen_Suppress
    2697             :     friend class OGRMultiSurface;
    2698             :     friend class OGRPolyhedralSurface;
    2699             :     friend class OGRTriangulatedSurface;
    2700             : 
    2701             :     virtual bool isRingCorrectType(const OGRCurve *poRing) const override;
    2702             : 
    2703             :     virtual bool checkRing(const OGRCurve *poNewRing) const override;
    2704             :     virtual OGRErr importFromWKTListOnly(const char **ppszInput, int bHasZ,
    2705             :                                          int bHasM, OGRRawPoint *&paoPoints,
    2706             :                                          int &nMaxPoints, double *&padfZ);
    2707             : 
    2708             :     static OGRCurvePolygon *CastToCurvePolygon(OGRPolygon *poPoly);
    2709             : 
    2710             :     virtual OGRSurfaceCasterToPolygon GetCasterToPolygon() const override;
    2711             :     virtual OGRSurfaceCasterToCurvePolygon
    2712             :     GetCasterToCurvePolygon() const override;
    2713             :     //! @endcond
    2714             : 
    2715             :   public:
    2716             :     /** Create an empty polygon. */
    2717     1510656 :     OGRPolygon() = default;
    2718             : 
    2719             :     OGRPolygon(double x1, double y1, double x2, double y2);
    2720             : 
    2721             :     explicit OGRPolygon(const OGREnvelope &envelope);
    2722             : 
    2723             :     OGRPolygon(const OGRPolygon &other);
    2724             :     /** Move constructor */
    2725           2 :     OGRPolygon(OGRPolygon &&other) = default;
    2726             : 
    2727             :     OGRPolygon &operator=(const OGRPolygon &other);
    2728             :     /** Move assignment operator */
    2729             :     OGRPolygon &operator=(OGRPolygon &&other) = default;
    2730             : 
    2731             :     /** Type of child elements. */
    2732             :     typedef OGRLinearRing ChildType;
    2733             : 
    2734             :     /** Return begin of iterator.
    2735             :      * @since GDAL 2.3
    2736             :      */
    2737        1360 :     ChildType **begin()
    2738             :     {
    2739        1360 :         return reinterpret_cast<ChildType **>(oCC.begin());
    2740             :     }
    2741             : 
    2742             :     /** Return end of iterator */
    2743        1360 :     ChildType **end()
    2744             :     {
    2745        1360 :         return reinterpret_cast<ChildType **>(oCC.end());
    2746             :     }
    2747             : 
    2748             :     /** Return begin of iterator.
    2749             :      * @since GDAL 2.3
    2750             :      */
    2751     1237045 :     const ChildType *const *begin() const
    2752             :     {
    2753     1237045 :         return reinterpret_cast<const ChildType *const *>(oCC.begin());
    2754             :     }
    2755             : 
    2756             :     /** Return end of iterator */
    2757     1236985 :     const ChildType *const *end() const
    2758             :     {
    2759     1236985 :         return reinterpret_cast<const ChildType *const *>(oCC.end());
    2760             :     }
    2761             : 
    2762             :     // Non-standard (OGRGeometry).
    2763             :     virtual const char *getGeometryName() const override;
    2764             :     virtual OGRwkbGeometryType getGeometryType() const override;
    2765             :     virtual OGRPolygon *clone() const override;
    2766             :     virtual OGRBoolean
    2767             :     hasCurveGeometry(int bLookForNonLinear = FALSE) const override;
    2768             :     virtual OGRGeometry *
    2769             :     getCurveGeometry(const char *const *papszOptions = nullptr) const override;
    2770             :     virtual OGRGeometry *
    2771             :     getLinearGeometry(double dfMaxAngleStepSizeDegrees = 0,
    2772             :                       const char *const *papszOptions = nullptr) const override;
    2773             : 
    2774             :     // IWks Interface.
    2775             :     virtual size_t WkbSize() const override;
    2776             :     virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
    2777             :                                  size_t &nBytesConsumedOut) override;
    2778             :     OGRErr exportToWkb(unsigned char *,
    2779             :                        const OGRwkbExportOptions * = nullptr) const override;
    2780             : 
    2781             : #ifndef DOXYGEN_XML
    2782             :     using OGRGeometry::importFromWkt; /** deprecated */
    2783             : #endif
    2784             : 
    2785             :     OGRErr importFromWkt(const char **) override;
    2786             : 
    2787             : #ifndef DOXYGEN_XML
    2788             :     using OGRGeometry::exportToWkt;
    2789             : #endif
    2790             : 
    2791             :     /// Export a polygon to WKT
    2792             :     /// \param opts  Output options.
    2793             :     /// \param err   Pointer to error code, if desired.
    2794             :     /// \return      WKT representation of the polygon.
    2795             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    2796             :                                     OGRErr *err = nullptr) const override;
    2797             : 
    2798             :     // ICurvePolygon.
    2799             :     virtual OGRPolygon *
    2800             :     CurvePolyToPoly(double dfMaxAngleStepSizeDegrees = 0,
    2801             :                     const char *const *papszOptions = nullptr) const override;
    2802             : 
    2803             :     OGRLinearRing *getExteriorRing();
    2804             :     const OGRLinearRing *getExteriorRing() const;
    2805             :     virtual OGRLinearRing *getInteriorRing(int);
    2806             :     virtual const OGRLinearRing *getInteriorRing(int) const;
    2807             : 
    2808             :     OGRLinearRing *stealExteriorRing();
    2809             :     virtual OGRLinearRing *stealInteriorRing(int);
    2810             : 
    2811             :     OGRBoolean IsPointOnSurface(const OGRPoint *) const;
    2812             : 
    2813             :     /** Return pointer of this in upper class */
    2814          77 :     inline OGRCurvePolygon *toUpperClass()
    2815             :     {
    2816          77 :         return this;
    2817             :     }
    2818             : 
    2819             :     /** Return pointer of this in upper class */
    2820          98 :     inline const OGRCurvePolygon *toUpperClass() const
    2821             :     {
    2822          98 :         return this;
    2823             :     }
    2824             : 
    2825          75 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    2826             :     {
    2827          75 :         visitor->visit(this);
    2828          75 :     }
    2829             : 
    2830          96 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    2831             :     {
    2832          96 :         visitor->visit(this);
    2833          96 :     }
    2834             : 
    2835             :     virtual void closeRings() override;
    2836             : 
    2837           2 :     OGR_ALLOW_UPCAST_TO(CurvePolygon)
    2838             :     OGR_ALLOW_CAST_TO_THIS(Polygon)
    2839             : };
    2840             : 
    2841             : //! @cond Doxygen_Suppress
    2842             : /** @see OGRPolygon::begin() const */
    2843       14625 : inline const OGRPolygon::ChildType *const *begin(const OGRPolygon *poGeom)
    2844             : {
    2845       14625 :     return poGeom->begin();
    2846             : }
    2847             : 
    2848             : /** @see OGRPolygon::end() const */
    2849       14625 : inline const OGRPolygon::ChildType *const *end(const OGRPolygon *poGeom)
    2850             : {
    2851       14625 :     return poGeom->end();
    2852             : }
    2853             : 
    2854             : /** @see OGRPolygon::begin() */
    2855          52 : inline OGRPolygon::ChildType **begin(OGRPolygon *poGeom)
    2856             : {
    2857          52 :     return poGeom->begin();
    2858             : }
    2859             : 
    2860             : /** @see OGRPolygon::end() */
    2861          52 : inline OGRPolygon::ChildType **end(OGRPolygon *poGeom)
    2862             : {
    2863          52 :     return poGeom->end();
    2864             : }
    2865             : 
    2866             : //! @endcond
    2867             : 
    2868             : /************************************************************************/
    2869             : /*                              OGRTriangle                             */
    2870             : /************************************************************************/
    2871             : 
    2872             : /**
    2873             :  * Triangle class.
    2874             :  *
    2875             :  * @since GDAL 2.2
    2876             :  */
    2877             : 
    2878     1295552 : class CPL_DLL OGRTriangle : public OGRPolygon
    2879             : {
    2880             :   private:
    2881             :     // cppcheck-suppress unusedPrivateFunction
    2882             :     static OGRPolygon *CasterToPolygon(OGRSurface *poSurface);
    2883             :     bool quickValidityCheck() const;
    2884             : 
    2885             :   protected:
    2886             :     //! @cond Doxygen_Suppress
    2887             :     virtual OGRSurfaceCasterToPolygon GetCasterToPolygon() const override;
    2888             :     virtual OGRErr importFromWKTListOnly(const char **ppszInput, int bHasZ,
    2889             :                                          int bHasM, OGRRawPoint *&paoPoints,
    2890             :                                          int &nMaxPoints,
    2891             :                                          double *&padfZ) override;
    2892             :     //! @endcond
    2893             : 
    2894             :   public:
    2895             :     /** Constructor. */
    2896       14586 :     OGRTriangle() = default;
    2897             :     OGRTriangle(const OGRPoint &p, const OGRPoint &q, const OGRPoint &r);
    2898             :     OGRTriangle(const OGRTriangle &other);
    2899             :     /** Move constructor */
    2900           1 :     OGRTriangle(OGRTriangle &&other) = default;
    2901             :     OGRTriangle(const OGRPolygon &other, OGRErr &eErr);
    2902             :     OGRTriangle &operator=(const OGRTriangle &other);
    2903             :     /** Move assignment operator */
    2904             :     OGRTriangle &operator=(OGRTriangle &&other) = default;
    2905             : 
    2906             :     virtual const char *getGeometryName() const override;
    2907             :     virtual OGRwkbGeometryType getGeometryType() const override;
    2908             :     virtual OGRTriangle *clone() const override;
    2909             : 
    2910             :     // IWks Interface.
    2911             :     virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
    2912             :                                  size_t &nBytesConsumedOut) override;
    2913             : 
    2914             :     // New methods rewritten from OGRPolygon/OGRCurvePolygon/OGRGeometry.
    2915             :     virtual OGRErr addRingDirectly(OGRCurve *poNewRing) override;
    2916             : 
    2917             :     /** Return pointer of this in upper class */
    2918           2 :     inline OGRPolygon *toUpperClass()
    2919             :     {
    2920           2 :         return this;
    2921             :     }
    2922             : 
    2923             :     /** Return pointer of this in upper class */
    2924           2 :     inline const OGRPolygon *toUpperClass() const
    2925             :     {
    2926           2 :         return this;
    2927             :     }
    2928             : 
    2929           2 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    2930             :     {
    2931           2 :         visitor->visit(this);
    2932           2 :     }
    2933             : 
    2934           2 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    2935             :     {
    2936           2 :         visitor->visit(this);
    2937           2 :     }
    2938             : 
    2939             :     //! @cond Doxygen_Suppress
    2940             :     static OGRGeometry *CastToPolygon(OGRGeometry *poGeom);
    2941             :     //! @endcond
    2942             : 
    2943           1 :     OGR_ALLOW_UPCAST_TO(Polygon)
    2944             :     OGR_ALLOW_CAST_TO_THIS(Triangle)
    2945             : };
    2946             : 
    2947             : /************************************************************************/
    2948             : /*                        OGRGeometryCollection                         */
    2949             : /************************************************************************/
    2950             : 
    2951             : /**
    2952             :  * A collection of 1 or more geometry objects.
    2953             :  *
    2954             :  * All geometries must share a common spatial reference system, and
    2955             :  * Subclasses may impose additional restrictions on the contents.
    2956             :  */
    2957             : 
    2958             : class CPL_DLL OGRGeometryCollection : public OGRGeometry
    2959             : {
    2960             :     OGRErr importFromWktInternal(const char **ppszInput, int nRecLevel);
    2961             : 
    2962             :   protected:
    2963             :     //! @cond Doxygen_Suppress
    2964             :     int nGeomCount = 0;
    2965             :     OGRGeometry **papoGeoms = nullptr;
    2966             : 
    2967             :     std::string
    2968             :     exportToWktInternal(const OGRWktOptions &opts, OGRErr *err,
    2969             :                         const std::string &exclude = std::string()) const;
    2970             :     static OGRGeometryCollection *
    2971             :     TransferMembersAndDestroy(OGRGeometryCollection *poSrc,
    2972             :                               OGRGeometryCollection *poDst);
    2973             : 
    2974             :     OGRErr importFromWkbInternal(const unsigned char *pabyData, size_t nSize,
    2975             :                                  int nRecLevel, OGRwkbVariant,
    2976             :                                  size_t &nBytesConsumedOut);
    2977             :     //! @endcond
    2978             :     virtual OGRBoolean isCompatibleSubType(OGRwkbGeometryType) const;
    2979             : 
    2980             :   public:
    2981             :     /** Create an empty geometry collection. */
    2982      117249 :     OGRGeometryCollection() = default;
    2983             : 
    2984             :     OGRGeometryCollection(const OGRGeometryCollection &other);
    2985             :     OGRGeometryCollection(OGRGeometryCollection &&other);
    2986             :     ~OGRGeometryCollection() override;
    2987             : 
    2988             :     OGRGeometryCollection &operator=(const OGRGeometryCollection &other);
    2989             :     OGRGeometryCollection &operator=(OGRGeometryCollection &&other);
    2990             : 
    2991             :     /** Type of child elements. */
    2992             :     typedef OGRGeometry ChildType;
    2993             : 
    2994             :     /** Return begin of sub-geometry iterator.
    2995             :      * @since GDAL 2.3
    2996             :      */
    2997      390657 :     ChildType **begin()
    2998             :     {
    2999      390657 :         return papoGeoms;
    3000             :     }
    3001             : 
    3002             :     /** Return end of sub-geometry iterator. */
    3003      390646 :     ChildType **end()
    3004             :     {
    3005      390646 :         return papoGeoms + nGeomCount;
    3006             :     }
    3007             : 
    3008             :     /** Return begin of sub-geometry iterator.
    3009             :      * @since GDAL 2.3
    3010             :      */
    3011      144981 :     const ChildType *const *begin() const
    3012             :     {
    3013      144981 :         return papoGeoms;
    3014             :     }
    3015             : 
    3016             :     /** Return end of sub-geometry iterator. */
    3017      144945 :     const ChildType *const *end() const
    3018             :     {
    3019      144945 :         return papoGeoms + nGeomCount;
    3020             :     }
    3021             : 
    3022             :     // Non standard (OGRGeometry).
    3023             :     virtual const char *getGeometryName() const override;
    3024             :     virtual OGRwkbGeometryType getGeometryType() const override;
    3025             :     virtual OGRGeometryCollection *clone() const override;
    3026             :     virtual void empty() override;
    3027             :     virtual OGRErr transform(OGRCoordinateTransformation *poCT) override;
    3028             :     virtual void flattenTo2D() override;
    3029             :     virtual OGRBoolean IsEmpty() const override;
    3030             :     virtual bool segmentize(double dfMaxLength) override;
    3031             :     virtual OGRBoolean
    3032             :     hasCurveGeometry(int bLookForNonLinear = FALSE) const override;
    3033             :     virtual OGRGeometry *
    3034             :     getCurveGeometry(const char *const *papszOptions = nullptr) const override;
    3035             :     virtual OGRGeometry *
    3036             :     getLinearGeometry(double dfMaxAngleStepSizeDegrees = 0,
    3037             :                       const char *const *papszOptions = nullptr) const override;
    3038             :     virtual double
    3039             :     get_GeodesicArea(const OGRSpatialReference *poSRSOverride = nullptr) const;
    3040             :     virtual double get_GeodesicLength(
    3041             :         const OGRSpatialReference *poSRSOverride = nullptr) const;
    3042             : 
    3043             :     // IWks Interface
    3044             :     virtual size_t WkbSize() const override;
    3045             :     virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
    3046             :                                  size_t &nBytesConsumedOut) override;
    3047             :     OGRErr exportToWkb(unsigned char *,
    3048             :                        const OGRwkbExportOptions * = nullptr) const override;
    3049             : 
    3050             : #ifndef DOXYGEN_XML
    3051             :     using OGRGeometry::importFromWkt; /** deprecated */
    3052             : #endif
    3053             : 
    3054             :     OGRErr importFromWkt(const char **) override;
    3055             : 
    3056             : #ifndef DOXYGEN_XML
    3057             :     using OGRGeometry::exportToWkt;
    3058             : #endif
    3059             : 
    3060             :     /// Export a geometry collection to WKT
    3061             :     /// \param opts  Output options.
    3062             :     /// \param err   Pointer to error code, if desired.
    3063             :     /// \return      WKT representation of the geometry collection.
    3064             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    3065             :                                     OGRErr *err = nullptr) const override;
    3066             : 
    3067             :     virtual double get_Length() const;
    3068             :     virtual double get_Area() const;
    3069             : 
    3070             :     // IGeometry methods
    3071             :     virtual int getDimension() const override;
    3072             :     virtual void getEnvelope(OGREnvelope *psEnvelope) const override;
    3073             :     virtual void getEnvelope(OGREnvelope3D *psEnvelope) const override;
    3074             : 
    3075             :     // IGeometryCollection
    3076             :     int getNumGeometries() const;
    3077             :     OGRGeometry *getGeometryRef(int);
    3078             :     const OGRGeometry *getGeometryRef(int) const;
    3079             : 
    3080             :     // ISpatialRelation
    3081             :     virtual OGRBoolean Equals(const OGRGeometry *) const override;
    3082             : 
    3083             :     // Non standard
    3084             :     virtual bool setCoordinateDimension(int nDimension) override;
    3085             :     virtual bool set3D(OGRBoolean bIs3D) override;
    3086             :     virtual bool setMeasured(OGRBoolean bIsMeasured) override;
    3087             :     virtual OGRErr addGeometry(const OGRGeometry *);
    3088             :     virtual OGRErr addGeometryDirectly(OGRGeometry *);
    3089             :     OGRErr addGeometry(std::unique_ptr<OGRGeometry> geom);
    3090             :     virtual OGRErr removeGeometry(int iIndex, int bDelete = TRUE);
    3091             :     std::unique_ptr<OGRGeometry> stealGeometry(int iIndex);
    3092             : 
    3093             :     bool hasEmptyParts() const override;
    3094             :     void removeEmptyParts() override;
    3095             : 
    3096             :     virtual void
    3097             :     assignSpatialReference(const OGRSpatialReference *poSR) override;
    3098             : 
    3099             :     void closeRings() override;
    3100             : 
    3101             :     virtual void swapXY() override;
    3102             : 
    3103           1 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    3104             :     {
    3105           1 :         visitor->visit(this);
    3106           1 :     }
    3107             : 
    3108           1 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    3109             :     {
    3110           1 :         visitor->visit(this);
    3111           1 :     }
    3112             : 
    3113             :     static OGRGeometryCollection *
    3114             :     CastToGeometryCollection(OGRGeometryCollection *poSrc);
    3115             : 
    3116             :     OGR_FORBID_DOWNCAST_TO_POINT
    3117             :     OGR_FORBID_DOWNCAST_TO_ALL_CURVES
    3118             :     OGR_FORBID_DOWNCAST_TO_ALL_SURFACES
    3119             :     OGR_ALLOW_CAST_TO_THIS(GeometryCollection)
    3120             : };
    3121             : 
    3122             : //! @cond Doxygen_Suppress
    3123             : /** @see OGRGeometryCollection::begin() const */
    3124             : inline const OGRGeometryCollection::ChildType *const *
    3125        1362 : begin(const OGRGeometryCollection *poGeom)
    3126             : {
    3127        1362 :     return poGeom->begin();
    3128             : }
    3129             : 
    3130             : /** @see OGRGeometryCollection::end() const */
    3131             : inline const OGRGeometryCollection::ChildType *const *
    3132        1309 : end(const OGRGeometryCollection *poGeom)
    3133             : {
    3134        1309 :     return poGeom->end();
    3135             : }
    3136             : 
    3137             : /** @see OGRGeometryCollection::begin() */
    3138         565 : inline OGRGeometryCollection::ChildType **begin(OGRGeometryCollection *poGeom)
    3139             : {
    3140         565 :     return poGeom->begin();
    3141             : }
    3142             : 
    3143             : /** @see OGRGeometryCollection::end() */
    3144         565 : inline OGRGeometryCollection::ChildType **end(OGRGeometryCollection *poGeom)
    3145             : {
    3146         565 :     return poGeom->end();
    3147             : }
    3148             : 
    3149             : //! @endcond
    3150             : 
    3151             : /************************************************************************/
    3152             : /*                          OGRMultiSurface                             */
    3153             : /************************************************************************/
    3154             : 
    3155             : /**
    3156             :  * A collection of non-overlapping OGRSurface.
    3157             :  *
    3158             :  * @since GDAL 2.0
    3159             :  */
    3160             : 
    3161       16927 : class CPL_DLL OGRMultiSurface : public OGRGeometryCollection
    3162             : {
    3163             :   protected:
    3164             :     virtual OGRBoolean isCompatibleSubType(OGRwkbGeometryType) const override;
    3165             : 
    3166             :   public:
    3167             :     /** Create an empty multi surface collection. */
    3168       78368 :     OGRMultiSurface() = default;
    3169             : 
    3170             :     OGRMultiSurface(const OGRMultiSurface &other);
    3171             :     /** Move constructor */
    3172           4 :     OGRMultiSurface(OGRMultiSurface &&other) = default;
    3173             : 
    3174             :     OGRMultiSurface &operator=(const OGRMultiSurface &other);
    3175             :     /** Move assignment operator */
    3176             :     OGRMultiSurface &operator=(OGRMultiSurface &&other) = default;
    3177             : 
    3178             :     /** Type of child elements. */
    3179             :     typedef OGRSurface ChildType;
    3180             : 
    3181             :     /** Return begin of iterator.
    3182             :      * @since GDAL 2.3
    3183             :      */
    3184          64 :     ChildType **begin()
    3185             :     {
    3186          64 :         return reinterpret_cast<ChildType **>(papoGeoms);
    3187             :     }
    3188             : 
    3189             :     /** Return end of iterator */
    3190          64 :     ChildType **end()
    3191             :     {
    3192          64 :         return reinterpret_cast<ChildType **>(papoGeoms + nGeomCount);
    3193             :     }
    3194             : 
    3195             :     /** Return begin of iterator.
    3196             :      * @since GDAL 2.3
    3197             :      */
    3198          94 :     const ChildType *const *begin() const
    3199             :     {
    3200          94 :         return reinterpret_cast<const ChildType *const *>(papoGeoms);
    3201             :     }
    3202             : 
    3203             :     /** Return end of iterator */
    3204          94 :     const ChildType *const *end() const
    3205             :     {
    3206          94 :         return reinterpret_cast<const ChildType *const *>(papoGeoms +
    3207          94 :                                                           nGeomCount);
    3208             :     }
    3209             : 
    3210             :     // Non standard (OGRGeometry).
    3211             :     virtual const char *getGeometryName() const override;
    3212             :     virtual OGRwkbGeometryType getGeometryType() const override;
    3213             :     virtual OGRMultiSurface *clone() const override;
    3214             : 
    3215             : #ifndef DOXYGEN_XML
    3216             :     using OGRGeometry::importFromWkt; /** deprecated */
    3217             : #endif
    3218             : 
    3219             :     OGRErr importFromWkt(const char **) override;
    3220             : 
    3221             : #ifndef DOXYGEN_XML
    3222             :     using OGRGeometry::exportToWkt;
    3223             : #endif
    3224             : 
    3225             :     /// Export a geometry collection to WKT
    3226             :     /// \param opts  Output options.
    3227             :     /// \param err   Pointer to error code, if desired.
    3228             :     /// \return      WKT representation of the geometry collection.
    3229             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    3230             :                                     OGRErr *err = nullptr) const override;
    3231             : 
    3232             :     // IMultiSurface methods
    3233             :     virtual OGRErr PointOnSurface(OGRPoint *poPoint) const;
    3234             : 
    3235             :     // IGeometry methods
    3236             :     virtual int getDimension() const override;
    3237             : 
    3238             :     // IGeometryCollection
    3239             :     /** See OGRGeometryCollection::getGeometryRef() */
    3240           8 :     OGRSurface *getGeometryRef(int i)
    3241             :     {
    3242           8 :         return OGRGeometryCollection::getGeometryRef(i)->toSurface();
    3243             :     }
    3244             : 
    3245             :     /** See OGRGeometryCollection::getGeometryRef() */
    3246             :     const OGRSurface *getGeometryRef(int i) const
    3247             :     {
    3248             :         return OGRGeometryCollection::getGeometryRef(i)->toSurface();
    3249             :     }
    3250             : 
    3251             :     // Non standard
    3252             :     virtual OGRBoolean
    3253             :     hasCurveGeometry(int bLookForNonLinear = FALSE) const override;
    3254             : 
    3255             :     /** Return pointer of this in upper class */
    3256           1 :     inline OGRGeometryCollection *toUpperClass()
    3257             :     {
    3258           1 :         return this;
    3259             :     }
    3260             : 
    3261             :     /** Return pointer of this in upper class */
    3262           1 :     inline const OGRGeometryCollection *toUpperClass() const
    3263             :     {
    3264           1 :         return this;
    3265             :     }
    3266             : 
    3267           1 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    3268             :     {
    3269           1 :         visitor->visit(this);
    3270           1 :     }
    3271             : 
    3272           1 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    3273             :     {
    3274           1 :         visitor->visit(this);
    3275           1 :     }
    3276             : 
    3277             :     static OGRMultiPolygon *CastToMultiPolygon(OGRMultiSurface *poMS);
    3278             : 
    3279             :     OGR_ALLOW_CAST_TO_THIS(MultiSurface)
    3280           2 :     OGR_ALLOW_UPCAST_TO(GeometryCollection)
    3281             :     OGR_FORBID_DOWNCAST_TO_MULTIPOINT
    3282             :     OGR_FORBID_DOWNCAST_TO_MULTILINESTRING
    3283             :     OGR_FORBID_DOWNCAST_TO_MULTICURVE
    3284             : };
    3285             : 
    3286             : //! @cond Doxygen_Suppress
    3287             : /** @see OGRMultiSurface::begin() const */
    3288             : inline const OGRMultiSurface::ChildType *const *
    3289           2 : begin(const OGRMultiSurface *poGeom)
    3290             : {
    3291           2 :     return poGeom->begin();
    3292             : }
    3293             : 
    3294             : /** @see OGRMultiSurface::end() const */
    3295             : inline const OGRMultiSurface::ChildType *const *
    3296           2 : end(const OGRMultiSurface *poGeom)
    3297             : {
    3298           2 :     return poGeom->end();
    3299             : }
    3300             : 
    3301             : /** @see OGRMultiSurface::begin() */
    3302           2 : inline OGRMultiSurface::ChildType **begin(OGRMultiSurface *poGeom)
    3303             : {
    3304           2 :     return poGeom->begin();
    3305             : }
    3306             : 
    3307             : /** @see OGRMultiSurface::end() */
    3308           2 : inline OGRMultiSurface::ChildType **end(OGRMultiSurface *poGeom)
    3309             : {
    3310           2 :     return poGeom->end();
    3311             : }
    3312             : 
    3313             : //! @endcond
    3314             : 
    3315             : /************************************************************************/
    3316             : /*                           OGRMultiPolygon                            */
    3317             : /************************************************************************/
    3318             : 
    3319             : /**
    3320             :  * A collection of non-overlapping OGRPolygon.
    3321             :  */
    3322             : 
    3323       16793 : class CPL_DLL OGRMultiPolygon : public OGRMultiSurface
    3324             : {
    3325             :   protected:
    3326             :     virtual OGRBoolean isCompatibleSubType(OGRwkbGeometryType) const override;
    3327             :     friend class OGRPolyhedralSurface;
    3328             :     friend class OGRTriangulatedSurface;
    3329             : 
    3330             :   private:
    3331             :     //! @cond Doxygen_Suppress
    3332             :     OGRErr _addGeometryWithExpectedSubGeometryType(
    3333             :         const OGRGeometry *poNewGeom, OGRwkbGeometryType eSubGeometryType);
    3334             :     OGRErr _addGeometryDirectlyWithExpectedSubGeometryType(
    3335             :         OGRGeometry *poNewGeom, OGRwkbGeometryType eSubGeometryType);
    3336             :     //! @endcond
    3337             : 
    3338             :   public:
    3339             :     /** Create an empty multi polygon collection. */
    3340       76906 :     OGRMultiPolygon() = default;
    3341             : 
    3342             :     OGRMultiPolygon(const OGRMultiPolygon &other);
    3343             :     /** Move constructor */
    3344           3 :     OGRMultiPolygon(OGRMultiPolygon &&other) = default;
    3345             : 
    3346             :     OGRMultiPolygon &operator=(const OGRMultiPolygon &other);
    3347             :     /** Move assignment operator */
    3348             :     OGRMultiPolygon &operator=(OGRMultiPolygon &&other) = default;
    3349             : 
    3350             :     /** Type of child elements. */
    3351             :     typedef OGRPolygon ChildType;
    3352             : 
    3353             :     /** Return begin of iterator.
    3354             :      * @since GDAL 2.3
    3355             :      */
    3356        1211 :     ChildType **begin()
    3357             :     {
    3358        1211 :         return reinterpret_cast<ChildType **>(papoGeoms);
    3359             :     }
    3360             : 
    3361             :     /** Return end of iterator */
    3362        1211 :     ChildType **end()
    3363             :     {
    3364        1211 :         return reinterpret_cast<ChildType **>(papoGeoms + nGeomCount);
    3365             :     }
    3366             : 
    3367             :     /** Return begin of iterator.
    3368             :      * @since GDAL 2.3
    3369             :      */
    3370       19791 :     const ChildType *const *begin() const
    3371             :     {
    3372       19791 :         return reinterpret_cast<const ChildType *const *>(papoGeoms);
    3373             :     }
    3374             : 
    3375             :     /** Return end of iterator */
    3376       19791 :     const ChildType *const *end() const
    3377             :     {
    3378       19791 :         return reinterpret_cast<const ChildType *const *>(papoGeoms +
    3379       19791 :                                                           nGeomCount);
    3380             :     }
    3381             : 
    3382             :     // IGeometryCollection
    3383             :     /** See OGRGeometryCollection::getGeometryRef() */
    3384         426 :     OGRPolygon *getGeometryRef(int i)
    3385             :     {
    3386         426 :         return OGRGeometryCollection::getGeometryRef(i)->toPolygon();
    3387             :     }
    3388             : 
    3389             :     /** See OGRGeometryCollection::getGeometryRef() */
    3390      165176 :     const OGRPolygon *getGeometryRef(int i) const
    3391             :     {
    3392      165176 :         return OGRGeometryCollection::getGeometryRef(i)->toPolygon();
    3393             :     }
    3394             : 
    3395             :     // Non-standard (OGRGeometry).
    3396             :     virtual const char *getGeometryName() const override;
    3397             :     virtual OGRwkbGeometryType getGeometryType() const override;
    3398             :     virtual OGRMultiPolygon *clone() const override;
    3399             : 
    3400             : #ifndef DOXYGEN_XML
    3401             :     using OGRGeometry::exportToWkt;
    3402             : #endif
    3403             : 
    3404             :     virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
    3405             :                                  size_t &nBytesConsumedOut) override;
    3406             : 
    3407             :     /// Export a multipolygon to WKT
    3408             :     /// \param opts  Output options.
    3409             :     /// \param err   Pointer to error code, if desired.
    3410             :     /// \return      WKT representation of the multipolygon.
    3411             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    3412             :                                     OGRErr *err = nullptr) const override;
    3413             : 
    3414             :     // Non standard
    3415             :     virtual OGRBoolean
    3416             :     hasCurveGeometry(int bLookForNonLinear = FALSE) const override;
    3417             : 
    3418             :     /** Return pointer of this in upper class */
    3419          14 :     inline OGRGeometryCollection *toUpperClass()
    3420             :     {
    3421          14 :         return this;
    3422             :     }
    3423             : 
    3424             :     /** Return pointer of this in upper class */
    3425           1 :     inline const OGRGeometryCollection *toUpperClass() const
    3426             :     {
    3427           1 :         return this;
    3428             :     }
    3429             : 
    3430          14 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    3431             :     {
    3432          14 :         visitor->visit(this);
    3433          14 :     }
    3434             : 
    3435           1 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    3436             :     {
    3437           1 :         visitor->visit(this);
    3438           1 :     }
    3439             : 
    3440             :     static OGRMultiSurface *CastToMultiSurface(OGRMultiPolygon *poMP);
    3441             : 
    3442             :     OGR_ALLOW_CAST_TO_THIS(MultiPolygon)
    3443           1 :     OGR_ALLOW_UPCAST_TO(MultiSurface)
    3444             : };
    3445             : 
    3446             : //! @cond Doxygen_Suppress
    3447             : /** @see OGRMultiPolygon::begin() const */
    3448             : inline const OGRMultiPolygon::ChildType *const *
    3449          65 : begin(const OGRMultiPolygon *poGeom)
    3450             : {
    3451          65 :     return poGeom->begin();
    3452             : }
    3453             : 
    3454             : /** @see OGRMultiPolygon::end() const */
    3455             : inline const OGRMultiPolygon::ChildType *const *
    3456          65 : end(const OGRMultiPolygon *poGeom)
    3457             : {
    3458          65 :     return poGeom->end();
    3459             : }
    3460             : 
    3461             : /** @see OGRMultiPolygon::begin() */
    3462          13 : inline OGRMultiPolygon::ChildType **begin(OGRMultiPolygon *poGeom)
    3463             : {
    3464          13 :     return poGeom->begin();
    3465             : }
    3466             : 
    3467             : /** @see OGRMultiPolygon::end() */
    3468          13 : inline OGRMultiPolygon::ChildType **end(OGRMultiPolygon *poGeom)
    3469             : {
    3470          13 :     return poGeom->end();
    3471             : }
    3472             : 
    3473             : //! @endcond
    3474             : 
    3475             : /************************************************************************/
    3476             : /*                         OGRPolyhedralSurface                         */
    3477             : /************************************************************************/
    3478             : 
    3479             : /**
    3480             :  * PolyhedralSurface class.
    3481             :  *
    3482             :  * @since GDAL 2.2
    3483             :  */
    3484             : 
    3485          47 : class CPL_DLL OGRPolyhedralSurface : public OGRSurface
    3486             : {
    3487             :   protected:
    3488             :     //! @cond Doxygen_Suppress
    3489             :     friend class OGRTriangulatedSurface;
    3490             :     OGRMultiPolygon oMP{};
    3491             :     virtual OGRSurfaceCasterToPolygon GetCasterToPolygon() const override;
    3492             :     virtual OGRSurfaceCasterToCurvePolygon
    3493             :     GetCasterToCurvePolygon() const override;
    3494             :     virtual OGRBoolean isCompatibleSubType(OGRwkbGeometryType) const;
    3495             :     virtual const char *getSubGeometryName() const;
    3496             :     virtual OGRwkbGeometryType getSubGeometryType() const;
    3497             :     std::string exportToWktInternal(const OGRWktOptions &opts,
    3498             :                                     OGRErr *err) const;
    3499             : 
    3500             :     virtual OGRPolyhedralSurfaceCastToMultiPolygon
    3501             :     GetCasterToMultiPolygon() const;
    3502             :     static OGRMultiPolygon *CastToMultiPolygonImpl(OGRPolyhedralSurface *poPS);
    3503             :     //! @endcond
    3504             : 
    3505             :   public:
    3506             :     /** Create an empty PolyhedralSurface */
    3507       49948 :     OGRPolyhedralSurface() = default;
    3508             : 
    3509             :     OGRPolyhedralSurface(const OGRPolyhedralSurface &other);
    3510             :     /** Move constructor */
    3511           2 :     OGRPolyhedralSurface(OGRPolyhedralSurface &&other) = default;
    3512             : 
    3513             :     OGRPolyhedralSurface &operator=(const OGRPolyhedralSurface &other);
    3514             :     /** Move assignment operator */
    3515             :     OGRPolyhedralSurface &operator=(OGRPolyhedralSurface &&other) = default;
    3516             : 
    3517             :     /** Type of child elements. */
    3518             :     typedef OGRPolygon ChildType;
    3519             : 
    3520             :     /** Return begin of iterator.
    3521             :      * @since GDAL 2.3
    3522             :      */
    3523         986 :     ChildType **begin()
    3524             :     {
    3525         986 :         return oMP.begin();
    3526             :     }
    3527             : 
    3528             :     /** Return end of iterator */
    3529         986 :     ChildType **end()
    3530             :     {
    3531         986 :         return oMP.end();
    3532             :     }
    3533             : 
    3534             :     /** Return begin of iterator.
    3535             :      * @since GDAL 2.3
    3536             :      */
    3537       18100 :     const ChildType *const *begin() const
    3538             :     {
    3539       18100 :         return oMP.begin();
    3540             :     }
    3541             : 
    3542             :     /** Return end of iterator */
    3543       18100 :     const ChildType *const *end() const
    3544             :     {
    3545       18100 :         return oMP.end();
    3546             :     }
    3547             : 
    3548             :     // IWks Interface.
    3549             :     virtual size_t WkbSize() const override;
    3550             :     virtual const char *getGeometryName() const override;
    3551             :     virtual OGRwkbGeometryType getGeometryType() const override;
    3552             :     virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
    3553             :                                  size_t &nBytesConsumedOut) override;
    3554             :     OGRErr exportToWkb(unsigned char *,
    3555             :                        const OGRwkbExportOptions * = nullptr) const override;
    3556             : 
    3557             : #ifndef DOXYGEN_XML
    3558             :     using OGRGeometry::importFromWkt; /** deprecated */
    3559             : #endif
    3560             : 
    3561             :     OGRErr importFromWkt(const char **) override;
    3562             : 
    3563             : #ifndef DOXYGEN_XML
    3564             :     using OGRGeometry::exportToWkt;
    3565             : #endif
    3566             : 
    3567             :     /// Export a polyhedral surface to WKT
    3568             :     /// \param opts  Output options.
    3569             :     /// \param err   Pointer to error code, if desired.
    3570             :     /// \return      WKT representation of the polyhedral surface.
    3571             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    3572             :                                     OGRErr *err = nullptr) const override;
    3573             : 
    3574             :     // IGeometry methods.
    3575             :     virtual int getDimension() const override;
    3576             : 
    3577             :     virtual void empty() override;
    3578             : 
    3579             :     virtual OGRPolyhedralSurface *clone() const override;
    3580             :     virtual void getEnvelope(OGREnvelope *psEnvelope) const override;
    3581             :     virtual void getEnvelope(OGREnvelope3D *psEnvelope) const override;
    3582             : 
    3583             :     virtual void flattenTo2D() override;
    3584             :     virtual OGRErr transform(OGRCoordinateTransformation *) override;
    3585             :     virtual OGRBoolean Equals(const OGRGeometry *) const override;
    3586             :     virtual double get_Area() const override;
    3587             :     virtual double get_GeodesicArea(
    3588             :         const OGRSpatialReference *poSRSOverride = nullptr) const override;
    3589             :     virtual double get_Length() const override;
    3590             :     virtual double get_GeodesicLength(
    3591             :         const OGRSpatialReference *poSRSOverride = nullptr) const override;
    3592             : 
    3593             :     virtual OGRErr PointOnSurface(OGRPoint *) const override;
    3594             : 
    3595             :     static OGRMultiPolygon *CastToMultiPolygon(OGRPolyhedralSurface *poPS);
    3596             :     virtual OGRBoolean
    3597             :     hasCurveGeometry(int bLookForNonLinear = FALSE) const override;
    3598             :     virtual OGRErr addGeometry(const OGRGeometry *);
    3599             :     OGRErr addGeometryDirectly(OGRGeometry *poNewGeom);
    3600             :     OGRErr addGeometry(std::unique_ptr<OGRGeometry> poNewGeom);
    3601             : 
    3602             :     int getNumGeometries() const;
    3603             :     OGRPolygon *getGeometryRef(int i);
    3604             :     const OGRPolygon *getGeometryRef(int i) const;
    3605             : 
    3606             :     virtual OGRBoolean IsEmpty() const override;
    3607             :     virtual bool setCoordinateDimension(int nDimension) override;
    3608             :     virtual bool set3D(OGRBoolean bIs3D) override;
    3609             :     virtual bool setMeasured(OGRBoolean bIsMeasured) override;
    3610             :     virtual void swapXY() override;
    3611             :     OGRErr removeGeometry(int iIndex, int bDelete = TRUE);
    3612             : 
    3613             :     bool hasEmptyParts() const override;
    3614             :     void removeEmptyParts() override;
    3615             : 
    3616           1 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    3617             :     {
    3618           1 :         visitor->visit(this);
    3619           1 :     }
    3620             : 
    3621           1 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    3622             :     {
    3623           1 :         visitor->visit(this);
    3624           1 :     }
    3625             : 
    3626             :     virtual void
    3627             :     assignSpatialReference(const OGRSpatialReference *poSR) override;
    3628             : 
    3629             :     OGR_ALLOW_CAST_TO_THIS(PolyhedralSurface)
    3630           2 :     OGR_ALLOW_UPCAST_TO(Surface)
    3631             : };
    3632             : 
    3633             : //! @cond Doxygen_Suppress
    3634             : /** @see OGRPolyhedralSurface::begin() const */
    3635             : inline const OGRPolyhedralSurface::ChildType *const *
    3636           2 : begin(const OGRPolyhedralSurface *poGeom)
    3637             : {
    3638           2 :     return poGeom->begin();
    3639             : }
    3640             : 
    3641             : /** @see OGRPolyhedralSurface::end() const */
    3642             : inline const OGRPolyhedralSurface::ChildType *const *
    3643           2 : end(const OGRPolyhedralSurface *poGeom)
    3644             : {
    3645           2 :     return poGeom->end();
    3646             : }
    3647             : 
    3648             : /** @see OGRPolyhedralSurface::begin() */
    3649           2 : inline OGRPolyhedralSurface::ChildType **begin(OGRPolyhedralSurface *poGeom)
    3650             : {
    3651           2 :     return poGeom->begin();
    3652             : }
    3653             : 
    3654             : /** @see OGRPolyhedralSurface::end() */
    3655           2 : inline OGRPolyhedralSurface::ChildType **end(OGRPolyhedralSurface *poGeom)
    3656             : {
    3657           2 :     return poGeom->end();
    3658             : }
    3659             : 
    3660             : //! @endcond
    3661             : 
    3662             : /************************************************************************/
    3663             : /*                        OGRTriangulatedSurface                        */
    3664             : /************************************************************************/
    3665             : 
    3666             : /**
    3667             :  * TriangulatedSurface class.
    3668             :  *
    3669             :  * @since GDAL 2.2
    3670             :  */
    3671             : 
    3672           2 : class CPL_DLL OGRTriangulatedSurface : public OGRPolyhedralSurface
    3673             : {
    3674             :   protected:
    3675             :     //! @cond Doxygen_Suppress
    3676             :     virtual OGRBoolean isCompatibleSubType(OGRwkbGeometryType) const override;
    3677             :     virtual const char *getSubGeometryName() const override;
    3678             :     virtual OGRwkbGeometryType getSubGeometryType() const override;
    3679             : 
    3680             :     virtual OGRPolyhedralSurfaceCastToMultiPolygon
    3681             :     GetCasterToMultiPolygon() const override;
    3682             :     static OGRMultiPolygon *CastToMultiPolygonImpl(OGRPolyhedralSurface *poPS);
    3683             :     //! @endcond
    3684             : 
    3685             :   public:
    3686             :     /** Constructor */
    3687       41287 :     OGRTriangulatedSurface() = default;
    3688             : 
    3689             :     OGRTriangulatedSurface(const OGRTriangulatedSurface &other);
    3690             :     /** Move constructor */
    3691           1 :     OGRTriangulatedSurface(OGRTriangulatedSurface &&other) = default;
    3692             : 
    3693             :     OGRTriangulatedSurface &operator=(const OGRTriangulatedSurface &other);
    3694             :     /** Move assignment operator */
    3695             :     OGRTriangulatedSurface &operator=(OGRTriangulatedSurface &&other) = default;
    3696             : 
    3697             :     /** Type of child elements. */
    3698             :     typedef OGRTriangle ChildType;
    3699             : 
    3700             :     /** Return begin of iterator.
    3701             :      * @since GDAL 2.3
    3702             :      */
    3703           3 :     ChildType **begin()
    3704             :     {
    3705           3 :         return reinterpret_cast<ChildType **>(oMP.begin());
    3706             :     }
    3707             : 
    3708             :     /** Return end of iterator */
    3709           3 :     ChildType **end()
    3710             :     {
    3711           3 :         return reinterpret_cast<ChildType **>(oMP.end());
    3712             :     }
    3713             : 
    3714             :     /** Return begin of iterator.
    3715             :      * @since GDAL 2.3
    3716             :      */
    3717           3 :     const ChildType *const *begin() const
    3718             :     {
    3719           3 :         return reinterpret_cast<const ChildType *const *>(oMP.begin());
    3720             :     }
    3721             : 
    3722             :     /** Return end of iterator */
    3723           3 :     const ChildType *const *end() const
    3724             :     {
    3725           3 :         return reinterpret_cast<const ChildType *const *>(oMP.end());
    3726             :     }
    3727             : 
    3728             :     virtual const char *getGeometryName() const override;
    3729             :     virtual OGRwkbGeometryType getGeometryType() const override;
    3730             :     virtual OGRTriangulatedSurface *clone() const override;
    3731             : 
    3732             :     /** See OGRPolyhedralSurface::getGeometryRef() */
    3733             :     OGRTriangle *getGeometryRef(int i)
    3734             :     {
    3735             :         return OGRPolyhedralSurface::getGeometryRef(i)->toTriangle();
    3736             :     }
    3737             : 
    3738             :     /** See OGRPolyhedralSurface::getGeometryRef() */
    3739           1 :     const OGRTriangle *getGeometryRef(int i) const
    3740             :     {
    3741           1 :         return OGRPolyhedralSurface::getGeometryRef(i)->toTriangle();
    3742             :     }
    3743             : 
    3744             :     // IWks Interface.
    3745             :     virtual OGRErr addGeometry(const OGRGeometry *) override;
    3746             : 
    3747             : #ifndef DOXYGEN_XML
    3748             :     using OGRPolyhedralSurface::addGeometry;
    3749             : #endif
    3750             : 
    3751             :     /** Return pointer of this in upper class */
    3752           1 :     inline OGRPolyhedralSurface *toUpperClass()
    3753             :     {
    3754           1 :         return this;
    3755             :     }
    3756             : 
    3757             :     /** Return pointer of this in upper class */
    3758           1 :     inline const OGRPolyhedralSurface *toUpperClass() const
    3759             :     {
    3760           1 :         return this;
    3761             :     }
    3762             : 
    3763           1 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    3764             :     {
    3765           1 :         visitor->visit(this);
    3766           1 :     }
    3767             : 
    3768           1 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    3769             :     {
    3770           1 :         visitor->visit(this);
    3771           1 :     }
    3772             : 
    3773             :     static OGRPolyhedralSurface *
    3774             :     CastToPolyhedralSurface(OGRTriangulatedSurface *poTS);
    3775             : 
    3776             :     OGR_ALLOW_CAST_TO_THIS(TriangulatedSurface)
    3777           1 :     OGR_ALLOW_UPCAST_TO(PolyhedralSurface)
    3778             : };
    3779             : 
    3780             : //! @cond Doxygen_Suppress
    3781             : /** @see OGRTriangulatedSurface::begin() const */
    3782             : inline const OGRTriangulatedSurface::ChildType *const *
    3783           2 : begin(const OGRTriangulatedSurface *poGeom)
    3784             : {
    3785           2 :     return poGeom->begin();
    3786             : }
    3787             : 
    3788             : /** @see OGRTriangulatedSurface::end() const */
    3789             : inline const OGRTriangulatedSurface::ChildType *const *
    3790           2 : end(const OGRTriangulatedSurface *poGeom)
    3791             : {
    3792           2 :     return poGeom->end();
    3793             : }
    3794             : 
    3795             : /** @see OGRTriangulatedSurface::begin() */
    3796           2 : inline OGRTriangulatedSurface::ChildType **begin(OGRTriangulatedSurface *poGeom)
    3797             : {
    3798           2 :     return poGeom->begin();
    3799             : }
    3800             : 
    3801             : /** @see OGRTriangulatedSurface::end() */
    3802           2 : inline OGRTriangulatedSurface::ChildType **end(OGRTriangulatedSurface *poGeom)
    3803             : {
    3804           2 :     return poGeom->end();
    3805             : }
    3806             : 
    3807             : //! @endcond
    3808             : 
    3809             : /************************************************************************/
    3810             : /*                            OGRMultiPoint                             */
    3811             : /************************************************************************/
    3812             : 
    3813             : /**
    3814             :  * A collection of OGRPoint.
    3815             :  */
    3816             : 
    3817         670 : class CPL_DLL OGRMultiPoint : public OGRGeometryCollection
    3818             : {
    3819             :   private:
    3820             :     OGRErr importFromWkt_Bracketed(const char **, int bHasM, int bHasZ);
    3821             : 
    3822             :   protected:
    3823             :     virtual OGRBoolean isCompatibleSubType(OGRwkbGeometryType) const override;
    3824             : 
    3825             :   public:
    3826             :     /** Create an empty multi point collection. */
    3827        4285 :     OGRMultiPoint() = default;
    3828             : 
    3829             :     OGRMultiPoint(const OGRMultiPoint &other);
    3830             :     /** Move constructor */
    3831           1 :     OGRMultiPoint(OGRMultiPoint &&other) = default;
    3832             : 
    3833             :     OGRMultiPoint &operator=(const OGRMultiPoint &other);
    3834             :     /** Move assignment operator */
    3835             :     OGRMultiPoint &operator=(OGRMultiPoint &&other) = default;
    3836             : 
    3837             :     /** Type of child elements. */
    3838             :     typedef OGRPoint ChildType;
    3839             : 
    3840             :     /** Return begin of iterator.
    3841             :      * @since GDAL 2.3
    3842             :      */
    3843         140 :     ChildType **begin()
    3844             :     {
    3845         140 :         return reinterpret_cast<ChildType **>(papoGeoms);
    3846             :     }
    3847             : 
    3848             :     /** Return end of iterator */
    3849         140 :     ChildType **end()
    3850             :     {
    3851         140 :         return reinterpret_cast<ChildType **>(papoGeoms + nGeomCount);
    3852             :     }
    3853             : 
    3854             :     /** Return begin of iterator.
    3855             :      * @since GDAL 2.3
    3856             :      */
    3857         298 :     const ChildType *const *begin() const
    3858             :     {
    3859         298 :         return reinterpret_cast<const ChildType *const *>(papoGeoms);
    3860             :     }
    3861             : 
    3862             :     /** Return end of iterator */
    3863         298 :     const ChildType *const *end() const
    3864             :     {
    3865         298 :         return reinterpret_cast<const ChildType *const *>(papoGeoms +
    3866         298 :                                                           nGeomCount);
    3867             :     }
    3868             : 
    3869             :     // IGeometryCollection
    3870             :     /** See OGRGeometryCollection::getGeometryRef() */
    3871        1002 :     OGRPoint *getGeometryRef(int i)
    3872             :     {
    3873        1002 :         return OGRGeometryCollection::getGeometryRef(i)->toPoint();
    3874             :     }
    3875             : 
    3876             :     /** See OGRGeometryCollection::getGeometryRef() */
    3877         248 :     const OGRPoint *getGeometryRef(int i) const
    3878             :     {
    3879         248 :         return OGRGeometryCollection::getGeometryRef(i)->toPoint();
    3880             :     }
    3881             : 
    3882             :     // Non-standard (OGRGeometry).
    3883             :     virtual const char *getGeometryName() const override;
    3884             :     virtual OGRwkbGeometryType getGeometryType() const override;
    3885             :     virtual OGRMultiPoint *clone() const override;
    3886             : 
    3887             : #ifndef DOXYGEN_XML
    3888             :     using OGRGeometry::importFromWkt; /** deprecated */
    3889             : #endif
    3890             : 
    3891             :     OGRErr importFromWkt(const char **) override;
    3892             : 
    3893             : #ifndef DOXYGEN_XML
    3894             :     using OGRGeometry::exportToWkt;
    3895             : #endif
    3896             : 
    3897             :     /// Export a multipoint to WKT
    3898             :     /// \param opts  Output options.
    3899             :     /// \param err   Pointer to error code, if desired.
    3900             :     /// \return      WKT representation of the multipoint.
    3901             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    3902             :                                     OGRErr *err = nullptr) const override;
    3903             : 
    3904             :     // IGeometry methods.
    3905             :     virtual int getDimension() const override;
    3906             : 
    3907             :     /** Return pointer of this in upper class */
    3908           1 :     inline OGRGeometryCollection *toUpperClass()
    3909             :     {
    3910           1 :         return this;
    3911             :     }
    3912             : 
    3913             :     /** Return pointer of this in upper class */
    3914          40 :     inline const OGRGeometryCollection *toUpperClass() const
    3915             :     {
    3916          40 :         return this;
    3917             :     }
    3918             : 
    3919           1 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    3920             :     {
    3921           1 :         visitor->visit(this);
    3922           1 :     }
    3923             : 
    3924          40 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    3925             :     {
    3926          40 :         visitor->visit(this);
    3927          40 :     }
    3928             : 
    3929             :     // Non-standard.
    3930             :     virtual OGRBoolean
    3931             :     hasCurveGeometry(int bLookForNonLinear = FALSE) const override;
    3932             : 
    3933             :     OGR_ALLOW_CAST_TO_THIS(MultiPoint)
    3934           1 :     OGR_ALLOW_UPCAST_TO(GeometryCollection)
    3935             :     OGR_FORBID_DOWNCAST_TO_MULTILINESTRING
    3936             :     OGR_FORBID_DOWNCAST_TO_MULTICURVE
    3937             :     OGR_FORBID_DOWNCAST_TO_MULTISURFACE
    3938             :     OGR_FORBID_DOWNCAST_TO_MULTIPOLYGON
    3939             : };
    3940             : 
    3941             : //! @cond Doxygen_Suppress
    3942             : /** @see OGRMultiPoint::begin() const */
    3943         211 : inline const OGRMultiPoint::ChildType *const *begin(const OGRMultiPoint *poGeom)
    3944             : {
    3945         211 :     return poGeom->begin();
    3946             : }
    3947             : 
    3948             : /** @see OGRMultiPoint::end() const */
    3949         211 : inline const OGRMultiPoint::ChildType *const *end(const OGRMultiPoint *poGeom)
    3950             : {
    3951         211 :     return poGeom->end();
    3952             : }
    3953             : 
    3954             : /** @see OGRMultiPoint::begin() */
    3955           2 : inline OGRMultiPoint::ChildType **begin(OGRMultiPoint *poGeom)
    3956             : {
    3957           2 :     return poGeom->begin();
    3958             : }
    3959             : 
    3960             : /** @see OGRMultiPoint::end() */
    3961           2 : inline OGRMultiPoint::ChildType **end(OGRMultiPoint *poGeom)
    3962             : {
    3963           2 :     return poGeom->end();
    3964             : }
    3965             : 
    3966             : //! @endcond
    3967             : 
    3968             : /************************************************************************/
    3969             : /*                          OGRMultiCurve                               */
    3970             : /************************************************************************/
    3971             : 
    3972             : /**
    3973             :  * A collection of OGRCurve.
    3974             :  *
    3975             :  * @since GDAL 2.0
    3976             :  */
    3977             : 
    3978       16454 : class CPL_DLL OGRMultiCurve : public OGRGeometryCollection
    3979             : {
    3980             :   protected:
    3981             :     //! @cond Doxygen_Suppress
    3982             :     static OGRErr addCurveDirectlyFromWkt(OGRGeometry *poSelf,
    3983             :                                           OGRCurve *poCurve);
    3984             :     //! @endcond
    3985             :     virtual OGRBoolean isCompatibleSubType(OGRwkbGeometryType) const override;
    3986             : 
    3987             :   public:
    3988             :     /** Create an empty multi curve collection. */
    3989       29397 :     OGRMultiCurve() = default;
    3990             : 
    3991             :     OGRMultiCurve(const OGRMultiCurve &other);
    3992             :     /** Move constructor */
    3993           2 :     OGRMultiCurve(OGRMultiCurve &&other) = default;
    3994             : 
    3995             :     OGRMultiCurve &operator=(const OGRMultiCurve &other);
    3996             :     /** Move assignment operator */
    3997             :     OGRMultiCurve &operator=(OGRMultiCurve &&other) = default;
    3998             : 
    3999             :     /** Type of child elements. */
    4000             :     typedef OGRCurve ChildType;
    4001             : 
    4002             :     /** Return begin of iterator.
    4003             :      * @since GDAL 2.3
    4004             :      */
    4005          64 :     ChildType **begin()
    4006             :     {
    4007          64 :         return reinterpret_cast<ChildType **>(papoGeoms);
    4008             :     }
    4009             : 
    4010             :     /** Return end of iterator */
    4011          64 :     ChildType **end()
    4012             :     {
    4013          64 :         return reinterpret_cast<ChildType **>(papoGeoms + nGeomCount);
    4014             :     }
    4015             : 
    4016             :     /** Return begin of iterator.
    4017             :      * @since GDAL 2.3
    4018             :      */
    4019          37 :     const ChildType *const *begin() const
    4020             :     {
    4021          37 :         return reinterpret_cast<const ChildType *const *>(papoGeoms);
    4022             :     }
    4023             : 
    4024             :     /** Return end of iterator */
    4025          37 :     const ChildType *const *end() const
    4026             :     {
    4027          37 :         return reinterpret_cast<const ChildType *const *>(papoGeoms +
    4028          37 :                                                           nGeomCount);
    4029             :     }
    4030             : 
    4031             :     // IGeometryCollection
    4032             :     /** See OGRGeometryCollection::getGeometryRef() */
    4033             :     OGRCurve *getGeometryRef(int i)
    4034             :     {
    4035             :         return OGRGeometryCollection::getGeometryRef(i)->toCurve();
    4036             :     }
    4037             : 
    4038             :     /** See OGRGeometryCollection::getGeometryRef() */
    4039             :     const OGRCurve *getGeometryRef(int i) const
    4040             :     {
    4041             :         return OGRGeometryCollection::getGeometryRef(i)->toCurve();
    4042             :     }
    4043             : 
    4044             :     // Non standard (OGRGeometry).
    4045             :     virtual const char *getGeometryName() const override;
    4046             :     virtual OGRwkbGeometryType getGeometryType() const override;
    4047             :     virtual OGRMultiCurve *clone() const override;
    4048             : 
    4049             : #ifndef DOXYGEN_XML
    4050             :     using OGRGeometry::importFromWkt; /** deprecated */
    4051             : #endif
    4052             : 
    4053             :     OGRErr importFromWkt(const char **) override;
    4054             : 
    4055             : #ifndef DOXYGEN_XML
    4056             :     using OGRGeometry::exportToWkt;
    4057             : #endif
    4058             : 
    4059             :     /// Export a multicurve to WKT
    4060             :     /// \param opts  Output options.
    4061             :     /// \param err   Pointer to error code, if desired.
    4062             :     /// \return      WKT representation of the multicurve.
    4063             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    4064             :                                     OGRErr *err = nullptr) const override;
    4065             : 
    4066             :     // IGeometry methods.
    4067             :     virtual int getDimension() const override;
    4068             : 
    4069             :     // Non-standard.
    4070             :     virtual OGRBoolean
    4071             :     hasCurveGeometry(int bLookForNonLinear = FALSE) const override;
    4072             : 
    4073             :     /** Return pointer of this in upper class */
    4074           1 :     inline OGRGeometryCollection *toUpperClass()
    4075             :     {
    4076           1 :         return this;
    4077             :     }
    4078             : 
    4079             :     /** Return pointer of this in upper class */
    4080           1 :     inline const OGRGeometryCollection *toUpperClass() const
    4081             :     {
    4082           1 :         return this;
    4083             :     }
    4084             : 
    4085           1 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    4086             :     {
    4087           1 :         visitor->visit(this);
    4088           1 :     }
    4089             : 
    4090           1 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    4091             :     {
    4092           1 :         visitor->visit(this);
    4093           1 :     }
    4094             : 
    4095             :     static OGRMultiLineString *CastToMultiLineString(OGRMultiCurve *poMC);
    4096             : 
    4097             :     OGR_ALLOW_CAST_TO_THIS(MultiCurve)
    4098           2 :     OGR_ALLOW_UPCAST_TO(GeometryCollection)
    4099             :     OGR_FORBID_DOWNCAST_TO_MULTIPOINT
    4100             :     OGR_FORBID_DOWNCAST_TO_MULTISURFACE
    4101             :     OGR_FORBID_DOWNCAST_TO_MULTIPOLYGON
    4102             : };
    4103             : 
    4104             : //! @cond Doxygen_Suppress
    4105             : /** @see OGRMultiCurve::begin() const */
    4106           2 : inline const OGRMultiCurve::ChildType *const *begin(const OGRMultiCurve *poGeom)
    4107             : {
    4108           2 :     return poGeom->begin();
    4109             : }
    4110             : 
    4111             : /** @see OGRMultiCurve::end() const */
    4112           2 : inline const OGRMultiCurve::ChildType *const *end(const OGRMultiCurve *poGeom)
    4113             : {
    4114           2 :     return poGeom->end();
    4115             : }
    4116             : 
    4117             : /** @see OGRMultiCurve::begin() */
    4118          21 : inline OGRMultiCurve::ChildType **begin(OGRMultiCurve *poGeom)
    4119             : {
    4120          21 :     return poGeom->begin();
    4121             : }
    4122             : 
    4123             : /** @see OGRMultiCurve::end() */
    4124          21 : inline OGRMultiCurve::ChildType **end(OGRMultiCurve *poGeom)
    4125             : {
    4126          21 :     return poGeom->end();
    4127             : }
    4128             : 
    4129             : //! @endcond
    4130             : 
    4131             : /************************************************************************/
    4132             : /*                          OGRMultiLineString                          */
    4133             : /************************************************************************/
    4134             : 
    4135             : /**
    4136             :  * A collection of OGRLineString.
    4137             :  */
    4138             : 
    4139       16293 : class CPL_DLL OGRMultiLineString : public OGRMultiCurve
    4140             : {
    4141             :   protected:
    4142             :     virtual OGRBoolean isCompatibleSubType(OGRwkbGeometryType) const override;
    4143             : 
    4144             :   public:
    4145             :     /** Create an empty multi line string collection. */
    4146       27966 :     OGRMultiLineString() = default;
    4147             : 
    4148             :     OGRMultiLineString(const OGRMultiLineString &other);
    4149             :     /** Move constructor */
    4150           1 :     OGRMultiLineString(OGRMultiLineString &&other) = default;
    4151             : 
    4152             :     OGRMultiLineString &operator=(const OGRMultiLineString &other);
    4153             :     /** Move assignment operator */
    4154             :     OGRMultiLineString &operator=(OGRMultiLineString &&other) = default;
    4155             : 
    4156             :     /** Type of child elements. */
    4157             :     typedef OGRLineString ChildType;
    4158             : 
    4159             :     /** Return begin of iterator.
    4160             :      * @since GDAL 2.3
    4161             :      */
    4162         124 :     ChildType **begin()
    4163             :     {
    4164         124 :         return reinterpret_cast<ChildType **>(papoGeoms);
    4165             :     }
    4166             : 
    4167             :     /** Return end of iterator */
    4168         124 :     ChildType **end()
    4169             :     {
    4170         124 :         return reinterpret_cast<ChildType **>(papoGeoms + nGeomCount);
    4171             :     }
    4172             : 
    4173             :     /** Return begin of iterator.
    4174             :      * @since GDAL 2.3
    4175             :      */
    4176        8841 :     const ChildType *const *begin() const
    4177             :     {
    4178        8841 :         return reinterpret_cast<const ChildType *const *>(papoGeoms);
    4179             :     }
    4180             : 
    4181             :     /** Return end of iterator */
    4182        8841 :     const ChildType *const *end() const
    4183             :     {
    4184        8841 :         return reinterpret_cast<const ChildType *const *>(papoGeoms +
    4185        8841 :                                                           nGeomCount);
    4186             :     }
    4187             : 
    4188             :     // IGeometryCollection
    4189             :     /** See OGRGeometryCollection::getGeometryRef() */
    4190       26936 :     OGRLineString *getGeometryRef(int i)
    4191             :     {
    4192       26936 :         return OGRGeometryCollection::getGeometryRef(i)->toLineString();
    4193             :     }
    4194             : 
    4195             :     /** See OGRGeometryCollection::getGeometryRef() */
    4196          65 :     const OGRLineString *getGeometryRef(int i) const
    4197             :     {
    4198          65 :         return OGRGeometryCollection::getGeometryRef(i)->toLineString();
    4199             :     }
    4200             : 
    4201             :     // Non standard (OGRGeometry).
    4202             :     virtual const char *getGeometryName() const override;
    4203             :     virtual OGRwkbGeometryType getGeometryType() const override;
    4204             :     virtual OGRMultiLineString *clone() const override;
    4205             : 
    4206             : #ifndef DOXYGEN_XML
    4207             :     using OGRGeometry::exportToWkt;
    4208             : #endif
    4209             : 
    4210             :     virtual OGRErr importFromWkb(const unsigned char *, size_t, OGRwkbVariant,
    4211             :                                  size_t &nBytesConsumedOut) override;
    4212             : 
    4213             :     /// Export a multilinestring to WKT
    4214             :     /// \param opts  Output options.
    4215             :     /// \param err   Pointer to error code, if desired.
    4216             :     /// \return      WKT representation of the multilinestring.
    4217             :     virtual std::string exportToWkt(const OGRWktOptions &opts = OGRWktOptions(),
    4218             :                                     OGRErr *err = nullptr) const override;
    4219             : 
    4220             :     // Non standard
    4221             :     virtual OGRBoolean
    4222             :     hasCurveGeometry(int bLookForNonLinear = FALSE) const override;
    4223             : 
    4224             :     /** Return pointer of this in upper class */
    4225           8 :     inline OGRGeometryCollection *toUpperClass()
    4226             :     {
    4227           8 :         return this;
    4228             :     }
    4229             : 
    4230             :     /** Return pointer of this in upper class */
    4231           1 :     inline const OGRGeometryCollection *toUpperClass() const
    4232             :     {
    4233           1 :         return this;
    4234             :     }
    4235             : 
    4236           8 :     virtual void accept(IOGRGeometryVisitor *visitor) override
    4237             :     {
    4238           8 :         visitor->visit(this);
    4239           8 :     }
    4240             : 
    4241           1 :     virtual void accept(IOGRConstGeometryVisitor *visitor) const override
    4242             :     {
    4243           1 :         visitor->visit(this);
    4244           1 :     }
    4245             : 
    4246             :     static OGRMultiCurve *CastToMultiCurve(OGRMultiLineString *poMLS);
    4247             : 
    4248             :     OGR_ALLOW_CAST_TO_THIS(MultiLineString)
    4249           1 :     OGR_ALLOW_UPCAST_TO(MultiCurve)
    4250             :     OGR_FORBID_DOWNCAST_TO_MULTIPOINT
    4251             :     OGR_FORBID_DOWNCAST_TO_MULTISURFACE
    4252             :     OGR_FORBID_DOWNCAST_TO_MULTIPOLYGON
    4253             : };
    4254             : 
    4255             : //! @cond Doxygen_Suppress
    4256             : /** @see OGRMultiLineString::begin() const */
    4257             : inline const OGRMultiLineString::ChildType *const *
    4258        8811 : begin(const OGRMultiLineString *poGeom)
    4259             : {
    4260        8811 :     return poGeom->begin();
    4261             : }
    4262             : 
    4263             : /** @see OGRMultiLineString::end() const */
    4264             : inline const OGRMultiLineString::ChildType *const *
    4265        8811 : end(const OGRMultiLineString *poGeom)
    4266             : {
    4267        8811 :     return poGeom->end();
    4268             : }
    4269             : 
    4270             : /** @see OGRMultiLineString::begin() */
    4271           2 : inline OGRMultiLineString::ChildType **begin(OGRMultiLineString *poGeom)
    4272             : {
    4273           2 :     return poGeom->begin();
    4274             : }
    4275             : 
    4276             : /** @see OGRMultiLineString::end() */
    4277           2 : inline OGRMultiLineString::ChildType **end(OGRMultiLineString *poGeom)
    4278             : {
    4279           2 :     return poGeom->end();
    4280             : }
    4281             : 
    4282             : //! @endcond
    4283             : 
    4284             : /************************************************************************/
    4285             : /*                          OGRGeometryFactory                          */
    4286             : /************************************************************************/
    4287             : 
    4288             : /**
    4289             :  * Create geometry objects from well known text/binary.
    4290             :  */
    4291             : 
    4292             : class CPL_DLL OGRGeometryFactory
    4293             : {
    4294             :     static OGRErr createFromFgfInternal(const unsigned char *pabyData,
    4295             :                                         OGRSpatialReference *poSR,
    4296             :                                         OGRGeometry **ppoReturn, int nBytes,
    4297             :                                         int *pnBytesConsumed, int nRecLevel);
    4298             : 
    4299             :   public:
    4300             :     static OGRErr createFromWkb(const void *, const OGRSpatialReference *,
    4301             :                                 OGRGeometry **,
    4302             :                                 size_t = static_cast<size_t>(-1),
    4303             :                                 OGRwkbVariant = wkbVariantOldOgc);
    4304             :     static OGRErr createFromWkb(const void *pabyData,
    4305             :                                 const OGRSpatialReference *, OGRGeometry **,
    4306             :                                 size_t nSize, OGRwkbVariant eVariant,
    4307             :                                 size_t &nBytesConsumedOut);
    4308             :     static OGRErr createFromWkt(const char *, const OGRSpatialReference *,
    4309             :                                 OGRGeometry **);
    4310             :     static OGRErr createFromWkt(const char **, const OGRSpatialReference *,
    4311             :                                 OGRGeometry **);
    4312             :     static std::pair<std::unique_ptr<OGRGeometry>, OGRErr>
    4313             :     createFromWkt(const char *, const OGRSpatialReference * = nullptr);
    4314             : 
    4315             :     /** Deprecated.
    4316             :      * @deprecated in GDAL 2.3
    4317             :      */
    4318             :     static OGRErr createFromWkt(char **ppszInput,
    4319             :                                 const OGRSpatialReference *poSRS,
    4320             :                                 OGRGeometry **ppoGeom)
    4321             :         CPL_WARN_DEPRECATED("Use createFromWkt(const char**, ...) instead")
    4322             :     {
    4323             :         return createFromWkt(const_cast<const char **>(ppszInput), poSRS,
    4324             :                              ppoGeom);
    4325             :     }
    4326             : 
    4327             :     static OGRErr createFromFgf(const void *, OGRSpatialReference *,
    4328             :                                 OGRGeometry **, int = -1, int * = nullptr);
    4329             :     static OGRGeometry *createFromGML(const char *);
    4330             :     static OGRGeometry *createFromGEOS(GEOSContextHandle_t hGEOSCtxt, GEOSGeom);
    4331             :     static OGRGeometry *createFromGeoJson(const char *, int = -1);
    4332             :     static OGRGeometry *createFromGeoJson(const CPLJSONObject &oJSONObject);
    4333             : 
    4334             :     static void destroyGeometry(OGRGeometry *);
    4335             :     static OGRGeometry *createGeometry(OGRwkbGeometryType);
    4336             : 
    4337             :     static OGRGeometry *forceToPolygon(OGRGeometry *);
    4338             :     static OGRGeometry *forceToLineString(OGRGeometry *,
    4339             :                                           bool bOnlyInOrder = true);
    4340             :     static OGRGeometry *forceToMultiPolygon(OGRGeometry *);
    4341             :     static OGRGeometry *forceToMultiPoint(OGRGeometry *);
    4342             :     static OGRGeometry *forceToMultiLineString(OGRGeometry *);
    4343             : 
    4344             :     static OGRGeometry *forceTo(OGRGeometry *poGeom,
    4345             :                                 OGRwkbGeometryType eTargetType,
    4346             :                                 const char *const *papszOptions = nullptr);
    4347             : 
    4348             :     static OGRGeometry *removeLowerDimensionSubGeoms(const OGRGeometry *poGeom);
    4349             : 
    4350             :     static OGRGeometry *organizePolygons(OGRGeometry **papoPolygons,
    4351             :                                          int nPolygonCount,
    4352             :                                          int *pbResultValidGeometry,
    4353             :                                          const char **papszOptions = nullptr);
    4354             :     static bool haveGEOS();
    4355             : 
    4356             :     /** Opaque class used as argument to transformWithOptions() */
    4357             :     class CPL_DLL TransformWithOptionsCache
    4358             :     {
    4359             :         friend class OGRGeometryFactory;
    4360             :         struct Private;
    4361             :         std::unique_ptr<Private> d;
    4362             : 
    4363             :       public:
    4364             :         TransformWithOptionsCache();
    4365             :         ~TransformWithOptionsCache();
    4366             :     };
    4367             : 
    4368             :     //! @cond Doxygen_Suppress
    4369             :     static bool isTransformWithOptionsRegularTransform(
    4370             :         const OGRSpatialReference *poSourceCRS,
    4371             :         const OGRSpatialReference *poTargetCRS, CSLConstList papszOptions);
    4372             :     //! @endcond
    4373             : 
    4374             :     static OGRGeometry *transformWithOptions(
    4375             :         const OGRGeometry *poSrcGeom, OGRCoordinateTransformation *poCT,
    4376             :         char **papszOptions,
    4377             :         const TransformWithOptionsCache &cache = TransformWithOptionsCache());
    4378             : 
    4379             :     static double GetDefaultArcStepSize();
    4380             : 
    4381             :     static OGRGeometry *
    4382             :     approximateArcAngles(double dfX, double dfY, double dfZ,
    4383             :                          double dfPrimaryRadius, double dfSecondaryAxis,
    4384             :                          double dfRotation, double dfStartAngle,
    4385             :                          double dfEndAngle, double dfMaxAngleStepSizeDegrees,
    4386             :                          const bool bUseMaxGap = false);
    4387             : 
    4388             :     static int GetCurveParameters(double x0, double y0, double x1, double y1,
    4389             :                                   double x2, double y2, double &R, double &cx,
    4390             :                                   double &cy, double &alpha0, double &alpha1,
    4391             :                                   double &alpha2);
    4392             :     static OGRLineString *
    4393             :     curveToLineString(double x0, double y0, double z0, double x1, double y1,
    4394             :                       double z1, double x2, double y2, double z2, int bHasZ,
    4395             :                       double dfMaxAngleStepSizeDegrees,
    4396             :                       const char *const *papszOptions = nullptr);
    4397             :     static OGRCurve *
    4398             :     curveFromLineString(const OGRLineString *poLS,
    4399             :                         const char *const *papszOptions = nullptr);
    4400             : };
    4401             : 
    4402             : OGRwkbGeometryType CPL_DLL OGRFromOGCGeomType(const char *pszGeomType);
    4403             : const char CPL_DLL *OGRToOGCGeomType(OGRwkbGeometryType eGeomType,
    4404             :                                      bool bCamelCase = false,
    4405             :                                      bool bAddZM = false,
    4406             :                                      bool bSpaceBeforeZM = false);
    4407             : 
    4408             : //! @cond Doxygen_Suppress
    4409             : typedef struct _OGRPreparedGeometry OGRPreparedGeometry;
    4410             : 
    4411             : struct CPL_DLL OGRPreparedGeometryUniquePtrDeleter
    4412             : {
    4413             :     void operator()(OGRPreparedGeometry *) const;
    4414             : };
    4415             : 
    4416             : //! @endcond
    4417             : 
    4418             : /** Unique pointer type for OGRPreparedGeometry.
    4419             :  * @since GDAL 2.3
    4420             :  */
    4421             : typedef std::unique_ptr<OGRPreparedGeometry,
    4422             :                         OGRPreparedGeometryUniquePtrDeleter>
    4423             :     OGRPreparedGeometryUniquePtr;
    4424             : 
    4425             : #endif /* ndef OGR_GEOMETRY_H_INCLUDED */

Generated by: LCOV version 1.14