Coverage Report

Created: 2026-07-25 06:50

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