LCOV - code coverage report
Current view: top level - ogr - ogrpoint.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 271 275 98.5 %
Date: 2025-11-04 19:10:06 Functions: 26 26 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  OpenGIS Simple Features Reference Implementation
       4             :  * Purpose:  The Point geometry class.
       5             :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 1999, Frank Warmerdam
       9             :  * Copyright (c) 2008-2011, Even Rouault <even dot rouault at spatialys.com>
      10             :  *
      11             :  * SPDX-License-Identifier: MIT
      12             :  ****************************************************************************/
      13             : 
      14             : #include "cpl_port.h"
      15             : #include "ogr_geometry.h"
      16             : 
      17             : #include <cmath>
      18             : #include <cstdio>
      19             : #include <cstring>
      20             : #include <algorithm>
      21             : #include <limits>
      22             : #include <new>
      23             : 
      24             : #include "cpl_conv.h"
      25             : #include "ogr_core.h"
      26             : #include "ogr_p.h"
      27             : #include "ogr_spatialref.h"
      28             : 
      29             : /************************************************************************/
      30             : /*                         GetEmptyNonEmptyFlag()                       */
      31             : /************************************************************************/
      32             : 
      33     4642890 : static int GetEmptyNonEmptyFlag(double x, double y)
      34             : {
      35     4642890 :     if (std::isnan(x) || std::isnan(y))
      36          94 :         return 0;
      37     4642800 :     return OGRGeometry::OGR_G_NOT_EMPTY_POINT;
      38             : }
      39             : 
      40             : /************************************************************************/
      41             : /*                              OGRPoint()                              */
      42             : /************************************************************************/
      43             : 
      44             : /**
      45             :  * \brief Create an empty point.
      46             :  */
      47             : 
      48      946701 : OGRPoint::OGRPoint() : x(0.0), y(0.0), z(0.0), m(0.0)
      49             : 
      50             : {
      51      946697 :     flags = 0;
      52      946697 : }
      53             : 
      54             : /************************************************************************/
      55             : /*                              OGRPoint()                              */
      56             : /************************************************************************/
      57             : 
      58             : /**
      59             :  * \brief Create a point.
      60             :  * @param xIn x
      61             :  * @param yIn y
      62             :  * @param zIn z
      63             :  */
      64             : 
      65     3911580 : OGRPoint::OGRPoint(double xIn, double yIn, double zIn)
      66     3911580 :     : x(xIn), y(yIn), z(zIn), m(0.0)
      67             : {
      68     3911580 :     flags = GetEmptyNonEmptyFlag(xIn, yIn) | OGR_G_3D;
      69     3911580 : }
      70             : 
      71             : /************************************************************************/
      72             : /*                              OGRPoint()                              */
      73             : /************************************************************************/
      74             : 
      75             : /**
      76             :  * \brief Create a point.
      77             :  * @param xIn x
      78             :  * @param yIn y
      79             :  */
      80             : 
      81      730819 : OGRPoint::OGRPoint(double xIn, double yIn) : x(xIn), y(yIn), z(0.0), m(0.0)
      82             : {
      83      730819 :     flags = GetEmptyNonEmptyFlag(xIn, yIn);
      84      730819 : }
      85             : 
      86             : /************************************************************************/
      87             : /*                              OGRPoint()                              */
      88             : /************************************************************************/
      89             : 
      90             : /**
      91             :  * \brief Create a point.
      92             :  * @param xIn x
      93             :  * @param yIn y
      94             :  * @param zIn z
      95             :  * @param mIn m
      96             :  */
      97             : 
      98         493 : OGRPoint::OGRPoint(double xIn, double yIn, double zIn, double mIn)
      99         493 :     : x(xIn), y(yIn), z(zIn), m(mIn)
     100             : {
     101         493 :     flags = GetEmptyNonEmptyFlag(xIn, yIn) | OGR_G_3D | OGR_G_MEASURED;
     102         493 : }
     103             : 
     104             : /************************************************************************/
     105             : /*                             createXYM()                              */
     106             : /************************************************************************/
     107             : 
     108             : /**
     109             :  * \brief Create a XYM point.
     110             :  * @param x x
     111             :  * @param y y
     112             :  * @param m m
     113             :  * @since GDAL 3.1
     114             :  */
     115             : 
     116          91 : OGRPoint *OGRPoint::createXYM(double x, double y, double m)
     117             : {
     118          91 :     auto p = new OGRPoint(x, y, 0, m);
     119          91 :     p->flags &= ~OGR_G_3D;
     120          91 :     return p;
     121             : }
     122             : 
     123             : /************************************************************************/
     124             : /*                       OGRPoint( const OGRPoint& )                    */
     125             : /************************************************************************/
     126             : 
     127             : /**
     128             :  * \brief Copy constructor.
     129             :  */
     130             : 
     131             : OGRPoint::OGRPoint(const OGRPoint &) = default;
     132             : 
     133             : /************************************************************************/
     134             : /*                       operator=( const OGRPoint& )                   */
     135             : /************************************************************************/
     136             : 
     137             : /**
     138             :  * \brief Assignment operator.
     139             :  */
     140             : 
     141       23774 : OGRPoint &OGRPoint::operator=(const OGRPoint &other)
     142             : {
     143       23774 :     if (this != &other)
     144             :     {
     145             :         // Slightly more efficient to avoid OGRGeometry::operator=(other);
     146             :         // but do what it does to avoid a call to empty()
     147       23773 :         assignSpatialReference(other.getSpatialReference());
     148       23773 :         flags = other.flags;
     149             : 
     150       23773 :         x = other.x;
     151       23773 :         y = other.y;
     152       23773 :         z = other.z;
     153       23773 :         m = other.m;
     154             :     }
     155       23774 :     return *this;
     156             : }
     157             : 
     158             : /************************************************************************/
     159             : /*                               clone()                                */
     160             : /*                                                                      */
     161             : /*      Make a new object that is a copy of this object.                */
     162             : /************************************************************************/
     163             : 
     164      267501 : OGRPoint *OGRPoint::clone() const
     165             : 
     166             : {
     167      267501 :     return new (std::nothrow) OGRPoint(*this);
     168             : }
     169             : 
     170             : /************************************************************************/
     171             : /*                               empty()                                */
     172             : /************************************************************************/
     173       97356 : void OGRPoint::empty()
     174             : 
     175             : {
     176       97356 :     x = 0.0;
     177       97356 :     y = 0.0;
     178       97356 :     z = 0.0;
     179       97356 :     m = 0.0;
     180       97356 :     flags &= ~OGR_G_NOT_EMPTY_POINT;
     181       97356 : }
     182             : 
     183             : /************************************************************************/
     184             : /*                            getDimension()                            */
     185             : /************************************************************************/
     186             : 
     187          45 : int OGRPoint::getDimension() const
     188             : 
     189             : {
     190          45 :     return 0;
     191             : }
     192             : 
     193             : /************************************************************************/
     194             : /*                          getGeometryType()                           */
     195             : /************************************************************************/
     196             : 
     197     2328730 : OGRwkbGeometryType OGRPoint::getGeometryType() const
     198             : 
     199             : {
     200     2328730 :     if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED))
     201        9266 :         return wkbPointZM;
     202     2319460 :     else if (flags & OGR_G_MEASURED)
     203        1114 :         return wkbPointM;
     204     2318350 :     else if (flags & OGR_G_3D)
     205      197697 :         return wkbPoint25D;
     206             :     else
     207     2120650 :         return wkbPoint;
     208             : }
     209             : 
     210             : /************************************************************************/
     211             : /*                          getGeometryName()                           */
     212             : /************************************************************************/
     213             : 
     214      106804 : const char *OGRPoint::getGeometryName() const
     215             : 
     216             : {
     217      106804 :     return "POINT";
     218             : }
     219             : 
     220             : /************************************************************************/
     221             : /*                            flattenTo2D()                             */
     222             : /************************************************************************/
     223             : 
     224       93922 : void OGRPoint::flattenTo2D()
     225             : 
     226             : {
     227       93922 :     z = 0.0;
     228       93922 :     m = 0.0;
     229       93922 :     flags &= ~OGR_G_3D;
     230       93922 :     setMeasured(FALSE);
     231       93922 : }
     232             : 
     233             : /************************************************************************/
     234             : /*                       setCoordinateDimension()                       */
     235             : /************************************************************************/
     236             : 
     237         922 : bool OGRPoint::setCoordinateDimension(int nNewDimension)
     238             : 
     239             : {
     240         922 :     if (nNewDimension == 2)
     241          17 :         flattenTo2D();
     242         905 :     else if (nNewDimension == 3)
     243         905 :         flags |= OGR_G_3D;
     244             : 
     245         922 :     setMeasured(FALSE);
     246         922 :     return true;
     247             : }
     248             : 
     249             : /************************************************************************/
     250             : /*                              WkbSize()                               */
     251             : /*                                                                      */
     252             : /*      Return the size of this object in well known binary             */
     253             : /*      representation including the byte order, and type information.  */
     254             : /************************************************************************/
     255             : 
     256      426607 : size_t OGRPoint::WkbSize() const
     257             : 
     258             : {
     259      426607 :     if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED))
     260        2410 :         return 37;
     261      424197 :     else if ((flags & OGR_G_3D) || (flags & OGR_G_MEASURED))
     262       19395 :         return 29;
     263             :     else
     264      404802 :         return 21;
     265             : }
     266             : 
     267             : /************************************************************************/
     268             : /*                           importFromWkb()                            */
     269             : /*                                                                      */
     270             : /*      Initialize from serialized stream in well known binary          */
     271             : /*      format.                                                         */
     272             : /************************************************************************/
     273             : 
     274       82743 : OGRErr OGRPoint::importFromWkb(const unsigned char *pabyData, size_t nSize,
     275             :                                OGRwkbVariant eWkbVariant,
     276             :                                size_t &nBytesConsumedOut)
     277             : 
     278             : {
     279       82743 :     nBytesConsumedOut = 0;
     280       82743 :     OGRwkbByteOrder eByteOrder = wkbNDR;
     281             : 
     282       82743 :     flags = 0;
     283             :     OGRErr eErr =
     284       82743 :         importPreambleFromWkb(pabyData, nSize, eByteOrder, eWkbVariant);
     285       82743 :     pabyData += 5;
     286       82743 :     if (eErr != OGRERR_NONE)
     287           0 :         return eErr;
     288             : 
     289       82743 :     if (nSize != static_cast<size_t>(-1))
     290             :     {
     291       82741 :         if ((nSize < 37) && ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED)))
     292          85 :             return OGRERR_NOT_ENOUGH_DATA;
     293       82656 :         else if ((nSize < 29) &&
     294       79324 :                  ((flags & OGR_G_3D) || (flags & OGR_G_MEASURED)))
     295           1 :             return OGRERR_NOT_ENOUGH_DATA;
     296       82655 :         else if (nSize < 21)
     297           0 :             return OGRERR_NOT_ENOUGH_DATA;
     298             :     }
     299             : 
     300       82657 :     nBytesConsumedOut = 5 + 8 * (2 + ((flags & OGR_G_3D) ? 1 : 0) +
     301       82657 :                                  ((flags & OGR_G_MEASURED) ? 1 : 0));
     302             : 
     303             :     /* -------------------------------------------------------------------- */
     304             :     /*      Get the vertex.                                                 */
     305             :     /* -------------------------------------------------------------------- */
     306       82657 :     memcpy(&x, pabyData, 8);
     307       82657 :     pabyData += 8;
     308       82657 :     memcpy(&y, pabyData, 8);
     309       82657 :     pabyData += 8;
     310             : 
     311       82657 :     if (OGR_SWAP(eByteOrder))
     312             :     {
     313         166 :         CPL_SWAPDOUBLE(&x);
     314         166 :         CPL_SWAPDOUBLE(&y);
     315             :     }
     316             : 
     317       82657 :     if (flags & OGR_G_3D)
     318             :     {
     319        2956 :         memcpy(&z, pabyData, 8);
     320        2956 :         pabyData += 8;
     321        2956 :         if (OGR_SWAP(eByteOrder))
     322          10 :             CPL_SWAPDOUBLE(&z);
     323             :     }
     324             :     else
     325             :     {
     326       79701 :         z = 0;
     327             :     }
     328       82657 :     if (flags & OGR_G_MEASURED)
     329             :     {
     330        2837 :         memcpy(&m, pabyData, 8);
     331             :         /*pabyData += 8; */
     332        2837 :         if (OGR_SWAP(eByteOrder))
     333             :         {
     334           5 :             CPL_SWAPDOUBLE(&m);
     335             :         }
     336             :     }
     337             :     else
     338             :     {
     339       79820 :         m = 0;
     340             :     }
     341             : 
     342             :     // Detect coordinates are not NaN --> NOT EMPTY.
     343       82657 :     if (!(std::isnan(x) && std::isnan(y)))
     344       82611 :         flags |= OGR_G_NOT_EMPTY_POINT;
     345             : 
     346       82657 :     return OGRERR_NONE;
     347             : }
     348             : 
     349             : /************************************************************************/
     350             : /*                            exportToWkb()                             */
     351             : /*                                                                      */
     352             : /*      Build a well known binary representation of this object.        */
     353             : /************************************************************************/
     354             : 
     355      412757 : OGRErr OGRPoint::exportToWkb(unsigned char *pabyData,
     356             :                              const OGRwkbExportOptions *psOptions) const
     357             : 
     358             : {
     359      412757 :     if (!psOptions)
     360             :     {
     361             :         static const OGRwkbExportOptions defaultOptions;
     362           0 :         psOptions = &defaultOptions;
     363             :     }
     364             : 
     365             :     /* -------------------------------------------------------------------- */
     366             :     /*      Set the byte order.                                             */
     367             :     /* -------------------------------------------------------------------- */
     368      412757 :     pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER(
     369             :         static_cast<unsigned char>(psOptions->eByteOrder));
     370      412757 :     pabyData += 1;
     371             : 
     372             :     /* -------------------------------------------------------------------- */
     373             :     /*      Set the geometry feature type.                                  */
     374             :     /* -------------------------------------------------------------------- */
     375             : 
     376      412757 :     GUInt32 nGType = getGeometryType();
     377             : 
     378      412757 :     if (psOptions->eWkbVariant == wkbVariantPostGIS1)
     379             :     {
     380         514 :         nGType = wkbFlatten(nGType);
     381         514 :         if (Is3D())
     382             :             // Explicitly set wkb25DBit.
     383           5 :             nGType =
     384           5 :                 static_cast<OGRwkbGeometryType>(nGType | wkb25DBitInternalUse);
     385         514 :         if (IsMeasured())
     386           0 :             nGType = static_cast<OGRwkbGeometryType>(nGType | 0x40000000);
     387             :     }
     388      412243 :     else if (psOptions->eWkbVariant == wkbVariantIso)
     389             :     {
     390      406318 :         nGType = getIsoGeometryType();
     391             :     }
     392             : 
     393      412757 :     if (psOptions->eByteOrder == wkbNDR)
     394             :     {
     395      412730 :         CPL_LSBPTR32(&nGType);
     396             :     }
     397             :     else
     398             :     {
     399          27 :         CPL_MSBPTR32(&nGType);
     400             :     }
     401             : 
     402      412757 :     memcpy(pabyData, &nGType, 4);
     403      412757 :     pabyData += 4;
     404             : 
     405             :     /* -------------------------------------------------------------------- */
     406             :     /*      Copy in the raw data. Swap if needed.                           */
     407             :     /* -------------------------------------------------------------------- */
     408             : 
     409      412757 :     if (IsEmpty() && psOptions->eWkbVariant == wkbVariantIso)
     410             :     {
     411        1140 :         const double dNan = std::numeric_limits<double>::quiet_NaN();
     412        1140 :         memcpy(pabyData, &dNan, 8);
     413        1140 :         if (OGR_SWAP(psOptions->eByteOrder))
     414           4 :             CPL_SWAPDOUBLE(pabyData);
     415        1140 :         pabyData += 8;
     416        1140 :         memcpy(pabyData, &dNan, 8);
     417        1140 :         if (OGR_SWAP(psOptions->eByteOrder))
     418           4 :             CPL_SWAPDOUBLE(pabyData);
     419        1140 :         pabyData += 8;
     420        1140 :         if (flags & OGR_G_3D)
     421             :         {
     422          61 :             memcpy(pabyData, &dNan, 8);
     423          61 :             if (OGR_SWAP(psOptions->eByteOrder))
     424           2 :                 CPL_SWAPDOUBLE(pabyData);
     425          61 :             pabyData += 8;
     426             :         }
     427        1140 :         if (flags & OGR_G_MEASURED)
     428             :         {
     429          20 :             memcpy(pabyData, &dNan, 8);
     430          20 :             if (OGR_SWAP(psOptions->eByteOrder))
     431           2 :                 CPL_SWAPDOUBLE(pabyData);
     432             :         }
     433             :     }
     434             :     else
     435             :     {
     436      411617 :         memcpy(pabyData, &x, 8);
     437      411617 :         memcpy(pabyData + 8, &y, 8);
     438      411617 :         OGRRoundCoordinatesIEEE754XYValues<0>(
     439      411617 :             psOptions->sPrecision.nXYBitPrecision, pabyData, 1);
     440      411617 :         if (OGR_SWAP(psOptions->eByteOrder))
     441             :         {
     442          23 :             CPL_SWAPDOUBLE(pabyData);
     443          23 :             CPL_SWAPDOUBLE(pabyData + 8);
     444             :         }
     445      411617 :         pabyData += 16;
     446      411617 :         if (flags & OGR_G_3D)
     447             :         {
     448       19419 :             memcpy(pabyData, &z, 8);
     449       19419 :             OGRRoundCoordinatesIEEE754<0>(psOptions->sPrecision.nZBitPrecision,
     450             :                                           pabyData, 1);
     451       19419 :             if (OGR_SWAP(psOptions->eByteOrder))
     452           8 :                 CPL_SWAPDOUBLE(pabyData);
     453       19419 :             pabyData += 8;
     454             :         }
     455      411617 :         if (flags & OGR_G_MEASURED)
     456             :         {
     457        1563 :             memcpy(pabyData, &m, 8);
     458        1563 :             OGRRoundCoordinatesIEEE754<0>(psOptions->sPrecision.nMBitPrecision,
     459             :                                           pabyData, 1);
     460        1563 :             if (OGR_SWAP(psOptions->eByteOrder))
     461           3 :                 CPL_SWAPDOUBLE(pabyData);
     462             :         }
     463             :     }
     464             : 
     465      412757 :     return OGRERR_NONE;
     466             : }
     467             : 
     468             : /************************************************************************/
     469             : /*                           importFromWkt()                            */
     470             : /*                                                                      */
     471             : /*      Instantiate point from well known text format ``POINT           */
     472             : /*      (x,y)''.                                                        */
     473             : /************************************************************************/
     474             : 
     475       97333 : OGRErr OGRPoint::importFromWkt(const char **ppszInput)
     476             : 
     477             : {
     478       97333 :     int bHasZ = FALSE;
     479       97333 :     int bHasM = FALSE;
     480       97333 :     bool bIsEmpty = false;
     481       97333 :     OGRErr eErr = importPreambleFromWkt(ppszInput, &bHasZ, &bHasM, &bIsEmpty);
     482       97333 :     flags = 0;
     483       97333 :     if (eErr != OGRERR_NONE)
     484           6 :         return eErr;
     485       97327 :     if (bHasZ)
     486         716 :         flags |= OGR_G_3D;
     487       97327 :     if (bHasM)
     488         223 :         flags |= OGR_G_MEASURED;
     489       97327 :     if (bIsEmpty)
     490             :     {
     491        1099 :         return OGRERR_NONE;
     492             :     }
     493             :     else
     494             :     {
     495       96228 :         flags |= OGR_G_NOT_EMPTY_POINT;
     496             :     }
     497             : 
     498       96228 :     const char *pszInput = *ppszInput;
     499             : 
     500             :     /* -------------------------------------------------------------------- */
     501             :     /*      Read the point list which should consist of exactly one point.  */
     502             :     /* -------------------------------------------------------------------- */
     503       96228 :     OGRRawPoint *poPoints = nullptr;
     504       96228 :     double *padfZ = nullptr;
     505       96228 :     double *padfM = nullptr;
     506       96228 :     int nMaxPoint = 0;
     507       96228 :     int nPoints = 0;
     508       96228 :     int flagsFromInput = flags;
     509             : 
     510       96228 :     pszInput = OGRWktReadPointsM(pszInput, &poPoints, &padfZ, &padfM,
     511             :                                  &flagsFromInput, &nMaxPoint, &nPoints);
     512       96228 :     if (pszInput == nullptr || nPoints != 1)
     513             :     {
     514          16 :         CPLFree(poPoints);
     515          16 :         CPLFree(padfZ);
     516          16 :         CPLFree(padfM);
     517          16 :         return OGRERR_CORRUPT_DATA;
     518             :     }
     519       96212 :     if ((flagsFromInput & OGR_G_3D) && !(flags & OGR_G_3D))
     520             :     {
     521       44269 :         flags |= OGR_G_3D;
     522       44269 :         bHasZ = TRUE;
     523             :     }
     524       96212 :     if ((flagsFromInput & OGR_G_MEASURED) && !(flags & OGR_G_MEASURED))
     525             :     {
     526           4 :         flags |= OGR_G_MEASURED;
     527           4 :         bHasM = TRUE;
     528             :     }
     529             : 
     530       96212 :     x = poPoints[0].x;
     531       96212 :     y = poPoints[0].y;
     532             : 
     533       96212 :     CPLFree(poPoints);
     534             : 
     535       96212 :     if (bHasZ)
     536             :     {
     537       44952 :         if (padfZ != nullptr)
     538       44952 :             z = padfZ[0];
     539             :     }
     540       96212 :     if (bHasM)
     541             :     {
     542         204 :         if (padfM != nullptr)
     543         204 :             m = padfM[0];
     544             :     }
     545             : 
     546       96212 :     CPLFree(padfZ);
     547       96212 :     CPLFree(padfM);
     548             : 
     549       96212 :     *ppszInput = pszInput;
     550             : 
     551       96212 :     return OGRERR_NONE;
     552             : }
     553             : 
     554             : /************************************************************************/
     555             : /*                            exportToWkt()                             */
     556             : /*                                                                      */
     557             : /*      Translate this structure into its well known text format       */
     558             : /*      equivalent.                                                     */
     559             : /************************************************************************/
     560             : 
     561        6367 : std::string OGRPoint::exportToWkt(const OGRWktOptions &opts, OGRErr *err) const
     562             : {
     563        6367 :     std::string wkt = getGeometryName() + wktTypeString(opts.variant);
     564        6367 :     if (IsEmpty())
     565             :     {
     566          67 :         wkt += "EMPTY";
     567             :     }
     568             :     else
     569             :     {
     570        6300 :         wkt += "(";
     571             : 
     572        6300 :         bool measured = ((opts.variant == wkbVariantIso) && IsMeasured());
     573        6300 :         wkt += OGRMakeWktCoordinateM(x, y, z, m, Is3D(), measured, opts);
     574             : 
     575        6300 :         wkt += ")";
     576             :     }
     577             : 
     578        6367 :     if (err)
     579        6122 :         *err = OGRERR_NONE;
     580        6367 :     return wkt;
     581             : }
     582             : 
     583             : /************************************************************************/
     584             : /*                            getEnvelope()                             */
     585             : /************************************************************************/
     586             : 
     587      731593 : void OGRPoint::getEnvelope(OGREnvelope *psEnvelope) const
     588             : 
     589             : {
     590      731593 :     psEnvelope->MinX = getX();
     591      731593 :     psEnvelope->MaxX = getX();
     592      731593 :     psEnvelope->MinY = getY();
     593      731593 :     psEnvelope->MaxY = getY();
     594      731593 : }
     595             : 
     596             : /************************************************************************/
     597             : /*                            getEnvelope()                             */
     598             : /************************************************************************/
     599             : 
     600        5852 : void OGRPoint::getEnvelope(OGREnvelope3D *psEnvelope) const
     601             : 
     602             : {
     603        5852 :     psEnvelope->MinX = getX();
     604        5852 :     psEnvelope->MaxX = getX();
     605        5852 :     psEnvelope->MinY = getY();
     606        5852 :     psEnvelope->MaxY = getY();
     607        5852 :     psEnvelope->MinZ = getZ();
     608        5852 :     psEnvelope->MaxZ = getZ();
     609        5852 : }
     610             : 
     611             : /**
     612             :  * \fn double OGRPoint::getX() const;
     613             :  *
     614             :  * \brief Fetch X coordinate.
     615             :  *
     616             :  * Relates to the SFCOM IPoint::get_X() method.
     617             :  *
     618             :  * @return the X coordinate of this point.
     619             :  */
     620             : 
     621             : /**
     622             :  * \fn double OGRPoint::getY() const;
     623             :  *
     624             :  * \brief Fetch Y coordinate.
     625             :  *
     626             :  * Relates to the SFCOM IPoint::get_Y() method.
     627             :  *
     628             :  * @return the Y coordinate of this point.
     629             :  */
     630             : 
     631             : /**
     632             :  * \fn double OGRPoint::getZ() const;
     633             :  *
     634             :  * \brief Fetch Z coordinate.
     635             :  *
     636             :  * Relates to the SFCOM IPoint::get_Z() method.
     637             :  *
     638             :  * @return the Z coordinate of this point, or zero if it is a 2D point.
     639             :  */
     640             : 
     641             : /**
     642             :  * \fn void OGRPoint::setX( double xIn );
     643             :  *
     644             :  * \brief Assign point X coordinate.
     645             :  *
     646             :  * There is no corresponding SFCOM method.
     647             :  */
     648             : 
     649             : /**
     650             :  * \fn void OGRPoint::setY( double yIn );
     651             :  *
     652             :  * \brief Assign point Y coordinate.
     653             :  *
     654             :  * There is no corresponding SFCOM method.
     655             :  */
     656             : 
     657             : /**
     658             :  * \fn void OGRPoint::setZ( double zIn );
     659             :  *
     660             :  * \brief Assign point Z coordinate.
     661             :  * Calling this method will force the geometry
     662             :  * coordinate dimension to 3D (wkbPoint|wkbZ).
     663             :  *
     664             :  * There is no corresponding SFCOM method.
     665             :  */
     666             : 
     667             : /************************************************************************/
     668             : /*                               Equal()                                */
     669             : /************************************************************************/
     670             : 
     671        7432 : OGRBoolean OGRPoint::Equals(const OGRGeometry *poOther) const
     672             : 
     673             : {
     674        7432 :     if (poOther == this)
     675           4 :         return TRUE;
     676             : 
     677        7428 :     if (poOther->getGeometryType() != getGeometryType())
     678           3 :         return FALSE;
     679             : 
     680        7425 :     const auto poOPoint = poOther->toPoint();
     681        7425 :     if (flags != poOPoint->flags)
     682           2 :         return FALSE;
     683             : 
     684        7423 :     if (IsEmpty())
     685           5 :         return TRUE;
     686             : 
     687             :     // Should eventually test the SRS.
     688       11177 :     if (poOPoint->getX() != getX() || poOPoint->getY() != getY() ||
     689        3759 :         poOPoint->getZ() != getZ())
     690        4395 :         return FALSE;
     691             : 
     692        3023 :     return TRUE;
     693             : }
     694             : 
     695             : /************************************************************************/
     696             : /*                             transform()                              */
     697             : /************************************************************************/
     698             : 
     699        3952 : OGRErr OGRPoint::transform(OGRCoordinateTransformation *poCT)
     700             : 
     701             : {
     702        3952 :     if (poCT->Transform(1, &x, &y, &z))
     703             :     {
     704        3948 :         assignSpatialReference(poCT->GetTargetCS());
     705        3948 :         return OGRERR_NONE;
     706             :     }
     707             : 
     708           4 :     return OGRERR_FAILURE;
     709             : }
     710             : 
     711             : /************************************************************************/
     712             : /*                               swapXY()                               */
     713             : /************************************************************************/
     714             : 
     715         271 : void OGRPoint::swapXY()
     716             : {
     717         271 :     std::swap(x, y);
     718         271 : }
     719             : 
     720             : /************************************************************************/
     721             : /*                               Within()                               */
     722             : /************************************************************************/
     723             : 
     724       16283 : OGRBoolean OGRPoint::Within(const OGRGeometry *poOtherGeom) const
     725             : 
     726             : {
     727       32519 :     if (!IsEmpty() && poOtherGeom != nullptr &&
     728       16236 :         wkbFlatten(poOtherGeom->getGeometryType()) == wkbCurvePolygon)
     729             :     {
     730           5 :         const auto poCurve = poOtherGeom->toCurvePolygon();
     731           5 :         return poCurve->Contains(this);
     732             :     }
     733             : 
     734       16278 :     return OGRGeometry::Within(poOtherGeom);
     735             : }
     736             : 
     737             : /************************************************************************/
     738             : /*                              Intersects()                            */
     739             : /************************************************************************/
     740             : 
     741          24 : OGRBoolean OGRPoint::Intersects(const OGRGeometry *poOtherGeom) const
     742             : 
     743             : {
     744          48 :     if (!IsEmpty() && poOtherGeom != nullptr &&
     745          24 :         wkbFlatten(poOtherGeom->getGeometryType()) == wkbCurvePolygon)
     746             :     {
     747           1 :         const auto poCurve = poOtherGeom->toCurvePolygon();
     748           1 :         return poCurve->Intersects(this);
     749             :     }
     750             : 
     751          23 :     return OGRGeometry::Intersects(poOtherGeom);
     752             : }

Generated by: LCOV version 1.14