LCOV - code coverage report
Current view: top level - ogr - ogr_geometry.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 554 560 98.9 %
Date: 2024-11-21 22:18:42 Functions: 301 308 97.7 %

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

Generated by: LCOV version 1.14