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