Coverage Report

Created: 2026-04-01 06:20

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