Coverage Report

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