Coverage Report

Created: 2025-11-16 06:25

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