Coverage Report

Created: 2025-06-22 06:59

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