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