LCOV - code coverage report
Current view: top level - ogr - ogrpoint.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 266 274 97.1 %
Date: 2024-05-03 15:49:35 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             :  * Permission is hereby granted, free of charge, to any person obtaining a
      12             :  * copy of this software and associated documentation files (the "Software"),
      13             :  * to deal in the Software without restriction, including without limitation
      14             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15             :  * and/or sell copies of the Software, and to permit persons to whom the
      16             :  * Software is furnished to do so, subject to the following conditions:
      17             :  *
      18             :  * The above copyright notice and this permission notice shall be included
      19             :  * in all copies or substantial portions of the Software.
      20             :  *
      21             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27             :  * DEALINGS IN THE SOFTWARE.
      28             :  ****************************************************************************/
      29             : 
      30             : #include "cpl_port.h"
      31             : #include "ogr_geometry.h"
      32             : 
      33             : #include <cmath>
      34             : #include <cstdio>
      35             : #include <cstring>
      36             : #include <algorithm>
      37             : #include <limits>
      38             : #include <new>
      39             : 
      40             : #include "cpl_conv.h"
      41             : #include "ogr_core.h"
      42             : #include "ogr_p.h"
      43             : #include "ogr_spatialref.h"
      44             : 
      45             : /************************************************************************/
      46             : /*                         GetEmptyNonEmptyFlag()                       */
      47             : /************************************************************************/
      48             : 
      49      778006 : static int GetEmptyNonEmptyFlag(double x, double y)
      50             : {
      51      778006 :     if (std::isnan(x) || std::isnan(y))
      52          78 :         return 0;
      53      777928 :     return OGRGeometry::OGR_G_NOT_EMPTY_POINT;
      54             : }
      55             : 
      56             : /************************************************************************/
      57             : /*                              OGRPoint()                              */
      58             : /************************************************************************/
      59             : 
      60             : /**
      61             :  * \brief Create an empty point.
      62             :  */
      63             : 
      64      666996 : OGRPoint::OGRPoint() : x(0.0), y(0.0), z(0.0), m(0.0)
      65             : 
      66             : {
      67      666994 :     flags = 0;
      68      666994 : }
      69             : 
      70             : /************************************************************************/
      71             : /*                              OGRPoint()                              */
      72             : /************************************************************************/
      73             : 
      74             : /**
      75             :  * \brief Create a point.
      76             :  * @param xIn x
      77             :  * @param yIn y
      78             :  * @param zIn z
      79             :  */
      80             : 
      81       80066 : OGRPoint::OGRPoint(double xIn, double yIn, double zIn)
      82       80066 :     : x(xIn), y(yIn), z(zIn), m(0.0)
      83             : {
      84       80066 :     flags = GetEmptyNonEmptyFlag(xIn, yIn) | OGR_G_3D;
      85       80066 : }
      86             : 
      87             : /************************************************************************/
      88             : /*                              OGRPoint()                              */
      89             : /************************************************************************/
      90             : 
      91             : /**
      92             :  * \brief Create a point.
      93             :  * @param xIn x
      94             :  * @param yIn y
      95             :  */
      96             : 
      97      697457 : OGRPoint::OGRPoint(double xIn, double yIn) : x(xIn), y(yIn), z(0.0), m(0.0)
      98             : {
      99      697457 :     flags = GetEmptyNonEmptyFlag(xIn, yIn);
     100      697457 : }
     101             : 
     102             : /************************************************************************/
     103             : /*                              OGRPoint()                              */
     104             : /************************************************************************/
     105             : 
     106             : /**
     107             :  * \brief Create a point.
     108             :  * @param xIn x
     109             :  * @param yIn y
     110             :  * @param zIn z
     111             :  * @param mIn m
     112             :  */
     113             : 
     114         483 : OGRPoint::OGRPoint(double xIn, double yIn, double zIn, double mIn)
     115         483 :     : x(xIn), y(yIn), z(zIn), m(mIn)
     116             : {
     117         483 :     flags = GetEmptyNonEmptyFlag(xIn, yIn) | OGR_G_3D | OGR_G_MEASURED;
     118         483 : }
     119             : 
     120             : /************************************************************************/
     121             : /*                             createXYM()                              */
     122             : /************************************************************************/
     123             : 
     124             : /**
     125             :  * \brief Create a XYM point.
     126             :  * @param x x
     127             :  * @param y y
     128             :  * @param m m
     129             :  * @since GDAL 3.1
     130             :  */
     131             : 
     132          88 : OGRPoint *OGRPoint::createXYM(double x, double y, double m)
     133             : {
     134          88 :     auto p = new OGRPoint(x, y, 0, m);
     135          88 :     p->flags &= ~OGR_G_3D;
     136          88 :     return p;
     137             : }
     138             : 
     139             : /************************************************************************/
     140             : /*                       OGRPoint( const OGRPoint& )                    */
     141             : /************************************************************************/
     142             : 
     143             : /**
     144             :  * \brief Copy constructor.
     145             :  *
     146             :  * Note: before GDAL 2.1, only the default implementation of the constructor
     147             :  * existed, which could be unsafe to use.
     148             :  *
     149             :  * @since GDAL 2.1
     150             :  */
     151             : 
     152             : OGRPoint::OGRPoint(const OGRPoint &) = default;
     153             : 
     154             : /************************************************************************/
     155             : /*                             ~OGRPoint()                              */
     156             : /************************************************************************/
     157             : 
     158             : OGRPoint::~OGRPoint() = default;
     159             : 
     160             : /************************************************************************/
     161             : /*                       operator=( const OGRPoint& )                   */
     162             : /************************************************************************/
     163             : 
     164             : /**
     165             :  * \brief Assignment operator.
     166             :  *
     167             :  * Note: before GDAL 2.1, only the default implementation of the operator
     168             :  * existed, which could be unsafe to use.
     169             :  *
     170             :  * @since GDAL 2.1
     171             :  */
     172             : 
     173       18074 : OGRPoint &OGRPoint::operator=(const OGRPoint &other)
     174             : {
     175       18074 :     if (this != &other)
     176             :     {
     177       18073 :         OGRGeometry::operator=(other);
     178             : 
     179       18073 :         x = other.x;
     180       18073 :         y = other.y;
     181       18073 :         z = other.z;
     182       18073 :         m = other.m;
     183             :     }
     184       18074 :     return *this;
     185             : }
     186             : 
     187             : /************************************************************************/
     188             : /*                               clone()                                */
     189             : /*                                                                      */
     190             : /*      Make a new object that is a copy of this object.                */
     191             : /************************************************************************/
     192             : 
     193      256626 : OGRPoint *OGRPoint::clone() const
     194             : 
     195             : {
     196      256626 :     return new (std::nothrow) OGRPoint(*this);
     197             : }
     198             : 
     199             : /************************************************************************/
     200             : /*                               empty()                                */
     201             : /************************************************************************/
     202       98579 : void OGRPoint::empty()
     203             : 
     204             : {
     205       98579 :     x = 0.0;
     206       98579 :     y = 0.0;
     207       98579 :     z = 0.0;
     208       98579 :     m = 0.0;
     209       98579 :     flags &= ~OGR_G_NOT_EMPTY_POINT;
     210       98579 : }
     211             : 
     212             : /************************************************************************/
     213             : /*                            getDimension()                            */
     214             : /************************************************************************/
     215             : 
     216          32 : int OGRPoint::getDimension() const
     217             : 
     218             : {
     219          32 :     return 0;
     220             : }
     221             : 
     222             : /************************************************************************/
     223             : /*                          getGeometryType()                           */
     224             : /************************************************************************/
     225             : 
     226     2135300 : OGRwkbGeometryType OGRPoint::getGeometryType() const
     227             : 
     228             : {
     229     2135300 :     if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED))
     230        8991 :         return wkbPointZM;
     231     2126310 :     else if (flags & OGR_G_MEASURED)
     232         931 :         return wkbPointM;
     233     2125380 :     else if (flags & OGR_G_3D)
     234      178472 :         return wkbPoint25D;
     235             :     else
     236     1946900 :         return wkbPoint;
     237             : }
     238             : 
     239             : /************************************************************************/
     240             : /*                          getGeometryName()                           */
     241             : /************************************************************************/
     242             : 
     243      105967 : const char *OGRPoint::getGeometryName() const
     244             : 
     245             : {
     246      105967 :     return "POINT";
     247             : }
     248             : 
     249             : /************************************************************************/
     250             : /*                            flattenTo2D()                             */
     251             : /************************************************************************/
     252             : 
     253       82708 : void OGRPoint::flattenTo2D()
     254             : 
     255             : {
     256       82708 :     z = 0.0;
     257       82708 :     m = 0.0;
     258       82708 :     flags &= ~OGR_G_3D;
     259       82708 :     setMeasured(FALSE);
     260       82708 : }
     261             : 
     262             : /************************************************************************/
     263             : /*                       setCoordinateDimension()                       */
     264             : /************************************************************************/
     265             : 
     266         882 : void OGRPoint::setCoordinateDimension(int nNewDimension)
     267             : 
     268             : {
     269         882 :     if (nNewDimension == 2)
     270          25 :         flattenTo2D();
     271         857 :     else if (nNewDimension == 3)
     272         857 :         flags |= OGR_G_3D;
     273             : 
     274         882 :     setMeasured(FALSE);
     275         882 : }
     276             : 
     277             : /************************************************************************/
     278             : /*                              WkbSize()                               */
     279             : /*                                                                      */
     280             : /*      Return the size of this object in well known binary             */
     281             : /*      representation including the byte order, and type information.  */
     282             : /************************************************************************/
     283             : 
     284      401291 : size_t OGRPoint::WkbSize() const
     285             : 
     286             : {
     287      401291 :     if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED))
     288        2264 :         return 37;
     289      399027 :     else if ((flags & OGR_G_3D) || (flags & OGR_G_MEASURED))
     290       18416 :         return 29;
     291             :     else
     292      380611 :         return 21;
     293             : }
     294             : 
     295             : /************************************************************************/
     296             : /*                           importFromWkb()                            */
     297             : /*                                                                      */
     298             : /*      Initialize from serialized stream in well known binary          */
     299             : /*      format.                                                         */
     300             : /************************************************************************/
     301             : 
     302       81904 : OGRErr OGRPoint::importFromWkb(const unsigned char *pabyData, size_t nSize,
     303             :                                OGRwkbVariant eWkbVariant,
     304             :                                size_t &nBytesConsumedOut)
     305             : 
     306             : {
     307       81904 :     nBytesConsumedOut = 0;
     308       81904 :     OGRwkbByteOrder eByteOrder = wkbNDR;
     309             : 
     310       81904 :     flags = 0;
     311             :     OGRErr eErr =
     312       81904 :         importPreambleFromWkb(pabyData, nSize, eByteOrder, eWkbVariant);
     313       81904 :     pabyData += 5;
     314       81904 :     if (eErr != OGRERR_NONE)
     315           0 :         return eErr;
     316             : 
     317       81904 :     if (nSize != static_cast<size_t>(-1))
     318             :     {
     319       81902 :         if ((nSize < 37) && ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED)))
     320          85 :             return OGRERR_NOT_ENOUGH_DATA;
     321       81817 :         else if ((nSize < 29) &&
     322       78535 :                  ((flags & OGR_G_3D) || (flags & OGR_G_MEASURED)))
     323           1 :             return OGRERR_NOT_ENOUGH_DATA;
     324       81816 :         else if (nSize < 21)
     325           0 :             return OGRERR_NOT_ENOUGH_DATA;
     326             :     }
     327             : 
     328       81818 :     nBytesConsumedOut = 5 + 8 * (2 + ((flags & OGR_G_3D) ? 1 : 0) +
     329       81818 :                                  ((flags & OGR_G_MEASURED) ? 1 : 0));
     330             : 
     331             :     /* -------------------------------------------------------------------- */
     332             :     /*      Get the vertex.                                                 */
     333             :     /* -------------------------------------------------------------------- */
     334       81818 :     memcpy(&x, pabyData, 8);
     335       81818 :     pabyData += 8;
     336       81818 :     memcpy(&y, pabyData, 8);
     337       81818 :     pabyData += 8;
     338             : 
     339       81818 :     if (OGR_SWAP(eByteOrder))
     340             :     {
     341          76 :         CPL_SWAPDOUBLE(&x);
     342          76 :         CPL_SWAPDOUBLE(&y);
     343             :     }
     344             : 
     345       81818 :     if (flags & OGR_G_3D)
     346             :     {
     347        2945 :         memcpy(&z, pabyData, 8);
     348        2945 :         pabyData += 8;
     349        2945 :         if (OGR_SWAP(eByteOrder))
     350           4 :             CPL_SWAPDOUBLE(&z);
     351             :     }
     352             :     else
     353             :     {
     354       78873 :         z = 0;
     355             :     }
     356       81818 :     if (flags & OGR_G_MEASURED)
     357             :     {
     358        2828 :         memcpy(&m, pabyData, 8);
     359             :         /*pabyData += 8; */
     360        2828 :         if (OGR_SWAP(eByteOrder))
     361             :         {
     362           1 :             CPL_SWAPDOUBLE(&m);
     363             :         }
     364             :     }
     365             :     else
     366             :     {
     367       78990 :         m = 0;
     368             :     }
     369             : 
     370             :     // Detect coordinates are not NaN --> NOT EMPTY.
     371       81818 :     if (!(CPLIsNan(x) && CPLIsNan(y)))
     372       81780 :         flags |= OGR_G_NOT_EMPTY_POINT;
     373             : 
     374       81818 :     return OGRERR_NONE;
     375             : }
     376             : 
     377             : /************************************************************************/
     378             : /*                            exportToWkb()                             */
     379             : /*                                                                      */
     380             : /*      Build a well known binary representation of this object.        */
     381             : /************************************************************************/
     382             : 
     383      398499 : OGRErr OGRPoint::exportToWkb(unsigned char *pabyData,
     384             :                              const OGRwkbExportOptions *psOptions) const
     385             : 
     386             : {
     387      398499 :     if (!psOptions)
     388             :     {
     389             :         static const OGRwkbExportOptions defaultOptions;
     390           0 :         psOptions = &defaultOptions;
     391             :     }
     392             : 
     393             :     /* -------------------------------------------------------------------- */
     394             :     /*      Set the byte order.                                             */
     395             :     /* -------------------------------------------------------------------- */
     396      398499 :     pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER(
     397             :         static_cast<unsigned char>(psOptions->eByteOrder));
     398      398499 :     pabyData += 1;
     399             : 
     400             :     /* -------------------------------------------------------------------- */
     401             :     /*      Set the geometry feature type.                                  */
     402             :     /* -------------------------------------------------------------------- */
     403             : 
     404      398499 :     GUInt32 nGType = getGeometryType();
     405             : 
     406      398499 :     if (psOptions->eWkbVariant == wkbVariantPostGIS1)
     407             :     {
     408         513 :         nGType = wkbFlatten(nGType);
     409         513 :         if (Is3D())
     410             :             // Explicitly set wkb25DBit.
     411           5 :             nGType =
     412           5 :                 static_cast<OGRwkbGeometryType>(nGType | wkb25DBitInternalUse);
     413         513 :         if (IsMeasured())
     414           0 :             nGType = static_cast<OGRwkbGeometryType>(nGType | 0x40000000);
     415             :     }
     416      397986 :     else if (psOptions->eWkbVariant == wkbVariantIso)
     417             :     {
     418      258396 :         nGType = getIsoGeometryType();
     419             :     }
     420             : 
     421      398499 :     if (psOptions->eByteOrder == wkbNDR)
     422             :     {
     423      398482 :         CPL_LSBPTR32(&nGType);
     424             :     }
     425             :     else
     426             :     {
     427          17 :         CPL_MSBPTR32(&nGType);
     428             :     }
     429             : 
     430      398499 :     memcpy(pabyData, &nGType, 4);
     431      398499 :     pabyData += 4;
     432             : 
     433             :     /* -------------------------------------------------------------------- */
     434             :     /*      Copy in the raw data. Swap if needed.                           */
     435             :     /* -------------------------------------------------------------------- */
     436             : 
     437      398499 :     if (IsEmpty() && psOptions->eWkbVariant == wkbVariantIso)
     438             :     {
     439        1032 :         const double dNan = std::numeric_limits<double>::quiet_NaN();
     440        1032 :         memcpy(pabyData, &dNan, 8);
     441        1032 :         if (OGR_SWAP(psOptions->eByteOrder))
     442           0 :             CPL_SWAPDOUBLE(pabyData);
     443        1032 :         pabyData += 8;
     444        1032 :         memcpy(pabyData, &dNan, 8);
     445        1032 :         if (OGR_SWAP(psOptions->eByteOrder))
     446           0 :             CPL_SWAPDOUBLE(pabyData);
     447        1032 :         pabyData += 8;
     448        1032 :         if (flags & OGR_G_3D)
     449             :         {
     450           9 :             memcpy(pabyData, &dNan, 8);
     451           9 :             if (OGR_SWAP(psOptions->eByteOrder))
     452           0 :                 CPL_SWAPDOUBLE(pabyData);
     453           9 :             pabyData += 8;
     454             :         }
     455        1032 :         if (flags & OGR_G_MEASURED)
     456             :         {
     457           8 :             memcpy(pabyData, &dNan, 8);
     458           8 :             if (OGR_SWAP(psOptions->eByteOrder))
     459           0 :                 CPL_SWAPDOUBLE(pabyData);
     460             :         }
     461             :     }
     462             :     else
     463             :     {
     464      397467 :         memcpy(pabyData, &x, 8);
     465      397467 :         memcpy(pabyData + 8, &y, 8);
     466      397467 :         OGRRoundCoordinatesIEEE754XYValues<0>(
     467      397467 :             psOptions->sPrecision.nXYBitPrecision, pabyData, 1);
     468      397467 :         if (OGR_SWAP(psOptions->eByteOrder))
     469             :         {
     470          17 :             CPL_SWAPDOUBLE(pabyData);
     471          17 :             CPL_SWAPDOUBLE(pabyData + 8);
     472             :         }
     473      397467 :         pabyData += 16;
     474      397467 :         if (flags & OGR_G_3D)
     475             :         {
     476       18824 :             memcpy(pabyData, &z, 8);
     477       18824 :             OGRRoundCoordinatesIEEE754<0>(psOptions->sPrecision.nZBitPrecision,
     478             :                                           pabyData, 1);
     479       18824 :             if (OGR_SWAP(psOptions->eByteOrder))
     480           4 :                 CPL_SWAPDOUBLE(pabyData);
     481       18824 :             pabyData += 8;
     482             :         }
     483      397467 :         if (flags & OGR_G_MEASURED)
     484             :         {
     485        1415 :             memcpy(pabyData, &m, 8);
     486        1415 :             OGRRoundCoordinatesIEEE754<0>(psOptions->sPrecision.nMBitPrecision,
     487             :                                           pabyData, 1);
     488        1415 :             if (OGR_SWAP(psOptions->eByteOrder))
     489           1 :                 CPL_SWAPDOUBLE(pabyData);
     490             :         }
     491             :     }
     492             : 
     493      398499 :     return OGRERR_NONE;
     494             : }
     495             : 
     496             : /************************************************************************/
     497             : /*                           importFromWkt()                            */
     498             : /*                                                                      */
     499             : /*      Instantiate point from well known text format ``POINT           */
     500             : /*      (x,y)''.                                                        */
     501             : /************************************************************************/
     502             : 
     503       97491 : OGRErr OGRPoint::importFromWkt(const char **ppszInput)
     504             : 
     505             : {
     506       97491 :     int bHasZ = FALSE;
     507       97491 :     int bHasM = FALSE;
     508       97491 :     bool bIsEmpty = false;
     509       97491 :     OGRErr eErr = importPreambleFromWkt(ppszInput, &bHasZ, &bHasM, &bIsEmpty);
     510       97491 :     flags = 0;
     511       97491 :     if (eErr != OGRERR_NONE)
     512           5 :         return eErr;
     513       97486 :     if (bHasZ)
     514         241 :         flags |= OGR_G_3D;
     515       97486 :     if (bHasM)
     516         189 :         flags |= OGR_G_MEASURED;
     517       97486 :     if (bIsEmpty)
     518             :     {
     519        1073 :         return OGRERR_NONE;
     520             :     }
     521             :     else
     522             :     {
     523       96413 :         flags |= OGR_G_NOT_EMPTY_POINT;
     524             :     }
     525             : 
     526       96413 :     const char *pszInput = *ppszInput;
     527             : 
     528             :     /* -------------------------------------------------------------------- */
     529             :     /*      Read the point list which should consist of exactly one point.  */
     530             :     /* -------------------------------------------------------------------- */
     531       96413 :     OGRRawPoint *poPoints = nullptr;
     532       96413 :     double *padfZ = nullptr;
     533       96413 :     double *padfM = nullptr;
     534       96413 :     int nMaxPoint = 0;
     535       96413 :     int nPoints = 0;
     536       96413 :     int flagsFromInput = flags;
     537             : 
     538       96413 :     pszInput = OGRWktReadPointsM(pszInput, &poPoints, &padfZ, &padfM,
     539             :                                  &flagsFromInput, &nMaxPoint, &nPoints);
     540       96413 :     if (pszInput == nullptr || nPoints != 1)
     541             :     {
     542          15 :         CPLFree(poPoints);
     543          15 :         CPLFree(padfZ);
     544          15 :         CPLFree(padfM);
     545          15 :         return OGRERR_CORRUPT_DATA;
     546             :     }
     547       96398 :     if ((flagsFromInput & OGR_G_3D) && !(flags & OGR_G_3D))
     548             :     {
     549       44291 :         flags |= OGR_G_3D;
     550       44291 :         bHasZ = TRUE;
     551             :     }
     552       96398 :     if ((flagsFromInput & OGR_G_MEASURED) && !(flags & OGR_G_MEASURED))
     553             :     {
     554           4 :         flags |= OGR_G_MEASURED;
     555           4 :         bHasM = TRUE;
     556             :     }
     557             : 
     558       96398 :     x = poPoints[0].x;
     559       96398 :     y = poPoints[0].y;
     560             : 
     561       96398 :     CPLFree(poPoints);
     562             : 
     563       96398 :     if (bHasZ)
     564             :     {
     565       44511 :         if (padfZ != nullptr)
     566       44511 :             z = padfZ[0];
     567             :     }
     568       96398 :     if (bHasM)
     569             :     {
     570         181 :         if (padfM != nullptr)
     571         181 :             m = padfM[0];
     572             :     }
     573             : 
     574       96398 :     CPLFree(padfZ);
     575       96398 :     CPLFree(padfM);
     576             : 
     577       96398 :     *ppszInput = pszInput;
     578             : 
     579       96398 :     return OGRERR_NONE;
     580             : }
     581             : 
     582             : /************************************************************************/
     583             : /*                            exportToWkt()                             */
     584             : /*                                                                      */
     585             : /*      Translate this structure into its well known text format       */
     586             : /*      equivalent.                                                     */
     587             : /************************************************************************/
     588             : 
     589        6136 : std::string OGRPoint::exportToWkt(const OGRWktOptions &opts, OGRErr *err) const
     590             : {
     591        6136 :     std::string wkt = getGeometryName() + wktTypeString(opts.variant);
     592        6136 :     if (IsEmpty())
     593             :     {
     594          41 :         wkt += "EMPTY";
     595             :     }
     596             :     else
     597             :     {
     598        6095 :         wkt += "(";
     599             : 
     600        6095 :         bool measured = ((opts.variant == wkbVariantIso) && IsMeasured());
     601        6095 :         wkt += OGRMakeWktCoordinateM(x, y, z, m, Is3D(), measured, opts);
     602             : 
     603        6095 :         wkt += ")";
     604             :     }
     605             : 
     606        6136 :     if (err)
     607        5907 :         *err = OGRERR_NONE;
     608        6136 :     return wkt;
     609             : }
     610             : 
     611             : /************************************************************************/
     612             : /*                            getEnvelope()                             */
     613             : /************************************************************************/
     614             : 
     615      694500 : void OGRPoint::getEnvelope(OGREnvelope *psEnvelope) const
     616             : 
     617             : {
     618      694500 :     psEnvelope->MinX = getX();
     619      694500 :     psEnvelope->MaxX = getX();
     620      694500 :     psEnvelope->MinY = getY();
     621      694500 :     psEnvelope->MaxY = getY();
     622      694500 : }
     623             : 
     624             : /************************************************************************/
     625             : /*                            getEnvelope()                             */
     626             : /************************************************************************/
     627             : 
     628        5730 : void OGRPoint::getEnvelope(OGREnvelope3D *psEnvelope) const
     629             : 
     630             : {
     631        5730 :     psEnvelope->MinX = getX();
     632        5730 :     psEnvelope->MaxX = getX();
     633        5730 :     psEnvelope->MinY = getY();
     634        5730 :     psEnvelope->MaxY = getY();
     635        5730 :     psEnvelope->MinZ = getZ();
     636        5730 :     psEnvelope->MaxZ = getZ();
     637        5730 : }
     638             : 
     639             : /**
     640             :  * \fn double OGRPoint::getX() const;
     641             :  *
     642             :  * \brief Fetch X coordinate.
     643             :  *
     644             :  * Relates to the SFCOM IPoint::get_X() method.
     645             :  *
     646             :  * @return the X coordinate of this point.
     647             :  */
     648             : 
     649             : /**
     650             :  * \fn double OGRPoint::getY() const;
     651             :  *
     652             :  * \brief Fetch Y coordinate.
     653             :  *
     654             :  * Relates to the SFCOM IPoint::get_Y() method.
     655             :  *
     656             :  * @return the Y coordinate of this point.
     657             :  */
     658             : 
     659             : /**
     660             :  * \fn double OGRPoint::getZ() const;
     661             :  *
     662             :  * \brief Fetch Z coordinate.
     663             :  *
     664             :  * Relates to the SFCOM IPoint::get_Z() method.
     665             :  *
     666             :  * @return the Z coordinate of this point, or zero if it is a 2D point.
     667             :  */
     668             : 
     669             : /**
     670             :  * \fn void OGRPoint::setX( double xIn );
     671             :  *
     672             :  * \brief Assign point X coordinate.
     673             :  *
     674             :  * There is no corresponding SFCOM method.
     675             :  */
     676             : 
     677             : /**
     678             :  * \fn void OGRPoint::setY( double yIn );
     679             :  *
     680             :  * \brief Assign point Y coordinate.
     681             :  *
     682             :  * There is no corresponding SFCOM method.
     683             :  */
     684             : 
     685             : /**
     686             :  * \fn void OGRPoint::setZ( double zIn );
     687             :  *
     688             :  * \brief Assign point Z coordinate.
     689             :  * Calling this method will force the geometry
     690             :  * coordinate dimension to 3D (wkbPoint|wkbZ).
     691             :  *
     692             :  * There is no corresponding SFCOM method.
     693             :  */
     694             : 
     695             : /************************************************************************/
     696             : /*                               Equal()                                */
     697             : /************************************************************************/
     698             : 
     699        7531 : OGRBoolean OGRPoint::Equals(const OGRGeometry *poOther) const
     700             : 
     701             : {
     702        7531 :     if (poOther == this)
     703           4 :         return TRUE;
     704             : 
     705        7527 :     if (poOther->getGeometryType() != getGeometryType())
     706           2 :         return FALSE;
     707             : 
     708        7525 :     const auto poOPoint = poOther->toPoint();
     709        7525 :     if (flags != poOPoint->flags)
     710           2 :         return FALSE;
     711             : 
     712        7523 :     if (IsEmpty())
     713           4 :         return TRUE;
     714             : 
     715             :     // Should eventually test the SRS.
     716       11224 :     if (poOPoint->getX() != getX() || poOPoint->getY() != getY() ||
     717        3705 :         poOPoint->getZ() != getZ())
     718        4550 :         return FALSE;
     719             : 
     720        2969 :     return TRUE;
     721             : }
     722             : 
     723             : /************************************************************************/
     724             : /*                             transform()                              */
     725             : /************************************************************************/
     726             : 
     727       43772 : OGRErr OGRPoint::transform(OGRCoordinateTransformation *poCT)
     728             : 
     729             : {
     730       43772 :     if (poCT->Transform(1, &x, &y, &z))
     731             :     {
     732       43768 :         assignSpatialReference(poCT->GetTargetCS());
     733       43768 :         return OGRERR_NONE;
     734             :     }
     735             : 
     736           4 :     return OGRERR_FAILURE;
     737             : }
     738             : 
     739             : /************************************************************************/
     740             : /*                               swapXY()                               */
     741             : /************************************************************************/
     742             : 
     743         258 : void OGRPoint::swapXY()
     744             : {
     745         258 :     std::swap(x, y);
     746         258 : }
     747             : 
     748             : /************************************************************************/
     749             : /*                               Within()                               */
     750             : /************************************************************************/
     751             : 
     752       15979 : OGRBoolean OGRPoint::Within(const OGRGeometry *poOtherGeom) const
     753             : 
     754             : {
     755       31927 :     if (!IsEmpty() && poOtherGeom != nullptr &&
     756       15948 :         wkbFlatten(poOtherGeom->getGeometryType()) == wkbCurvePolygon)
     757             :     {
     758           5 :         const auto poCurve = poOtherGeom->toCurvePolygon();
     759           5 :         return poCurve->Contains(this);
     760             :     }
     761             : 
     762       15974 :     return OGRGeometry::Within(poOtherGeom);
     763             : }
     764             : 
     765             : /************************************************************************/
     766             : /*                              Intersects()                            */
     767             : /************************************************************************/
     768             : 
     769          24 : OGRBoolean OGRPoint::Intersects(const OGRGeometry *poOtherGeom) const
     770             : 
     771             : {
     772          48 :     if (!IsEmpty() && poOtherGeom != nullptr &&
     773          24 :         wkbFlatten(poOtherGeom->getGeometryType()) == wkbCurvePolygon)
     774             :     {
     775           1 :         const auto poCurve = poOtherGeom->toCurvePolygon();
     776           1 :         return poCurve->Intersects(this);
     777             :     }
     778             : 
     779          23 :     return OGRGeometry::Intersects(poOtherGeom);
     780             : }

Generated by: LCOV version 1.14