Coverage Report

Created: 2025-08-28 06:57

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