LCOV - code coverage report
Current view: top level - ogr - ogr_geometry.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 522 528 98.9 %
Date: 2024-05-03 15:49:35 Functions: 300 308 97.4 %

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

Generated by: LCOV version 1.14