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 4503080 : static int GetEmptyNonEmptyFlag(double x, double y)
34 : {
35 4503080 : if (std::isnan(x) || std::isnan(y))
36 94 : return 0;
37 4502980 : return OGRGeometry::OGR_G_NOT_EMPTY_POINT;
38 : }
39 :
40 : /************************************************************************/
41 : /* OGRPoint() */
42 : /************************************************************************/
43 :
44 : /**
45 : * \brief Create an empty point.
46 : */
47 :
48 924134 : OGRPoint::OGRPoint() : x(0.0), y(0.0), z(0.0), m(0.0)
49 :
50 : {
51 924125 : flags = 0;
52 924125 : }
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 3809450 : OGRPoint::OGRPoint(double xIn, double yIn, double zIn)
66 3809450 : : x(xIn), y(yIn), z(zIn), m(0.0)
67 : {
68 3809450 : flags = GetEmptyNonEmptyFlag(xIn, yIn) | OGR_G_3D;
69 3809450 : }
70 :
71 : /************************************************************************/
72 : /* OGRPoint() */
73 : /************************************************************************/
74 :
75 : /**
76 : * \brief Create a point.
77 : * @param xIn x
78 : * @param yIn y
79 : */
80 :
81 693141 : OGRPoint::OGRPoint(double xIn, double yIn) : x(xIn), y(yIn), z(0.0), m(0.0)
82 : {
83 693141 : flags = GetEmptyNonEmptyFlag(xIn, yIn);
84 693141 : }
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 483 : OGRPoint::OGRPoint(double xIn, double yIn, double zIn, double mIn)
99 483 : : x(xIn), y(yIn), z(zIn), m(mIn)
100 : {
101 483 : flags = GetEmptyNonEmptyFlag(xIn, yIn) | OGR_G_3D | OGR_G_MEASURED;
102 483 : }
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 88 : OGRPoint *OGRPoint::createXYM(double x, double y, double m)
117 : {
118 88 : auto p = new OGRPoint(x, y, 0, m);
119 88 : p->flags &= ~OGR_G_3D;
120 88 : return p;
121 : }
122 :
123 : /************************************************************************/
124 : /* OGRPoint( const OGRPoint& ) */
125 : /************************************************************************/
126 :
127 : /**
128 : * \brief Copy constructor.
129 : *
130 : * Note: before GDAL 2.1, only the default implementation of the constructor
131 : * existed, which could be unsafe to use.
132 : *
133 : * @since GDAL 2.1
134 : */
135 :
136 : OGRPoint::OGRPoint(const OGRPoint &) = default;
137 :
138 : /************************************************************************/
139 : /* operator=( const OGRPoint& ) */
140 : /************************************************************************/
141 :
142 : /**
143 : * \brief Assignment operator.
144 : *
145 : * Note: before GDAL 2.1, only the default implementation of the operator
146 : * existed, which could be unsafe to use.
147 : *
148 : * @since GDAL 2.1
149 : */
150 :
151 21834 : OGRPoint &OGRPoint::operator=(const OGRPoint &other)
152 : {
153 21834 : if (this != &other)
154 : {
155 : // Slightly more efficient to avoid OGRGeometry::operator=(other);
156 : // but do what it does to avoid a call to empty()
157 21833 : assignSpatialReference(other.getSpatialReference());
158 21833 : flags = other.flags;
159 :
160 21833 : x = other.x;
161 21833 : y = other.y;
162 21833 : z = other.z;
163 21833 : m = other.m;
164 : }
165 21834 : return *this;
166 : }
167 :
168 : /************************************************************************/
169 : /* clone() */
170 : /* */
171 : /* Make a new object that is a copy of this object. */
172 : /************************************************************************/
173 :
174 247039 : OGRPoint *OGRPoint::clone() const
175 :
176 : {
177 247039 : return new (std::nothrow) OGRPoint(*this);
178 : }
179 :
180 : /************************************************************************/
181 : /* empty() */
182 : /************************************************************************/
183 97760 : void OGRPoint::empty()
184 :
185 : {
186 97760 : x = 0.0;
187 97760 : y = 0.0;
188 97760 : z = 0.0;
189 97760 : m = 0.0;
190 97760 : flags &= ~OGR_G_NOT_EMPTY_POINT;
191 97760 : }
192 :
193 : /************************************************************************/
194 : /* getDimension() */
195 : /************************************************************************/
196 :
197 22 : int OGRPoint::getDimension() const
198 :
199 : {
200 22 : return 0;
201 : }
202 :
203 : /************************************************************************/
204 : /* getGeometryType() */
205 : /************************************************************************/
206 :
207 2142190 : OGRwkbGeometryType OGRPoint::getGeometryType() const
208 :
209 : {
210 2142190 : if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED))
211 9026 : return wkbPointZM;
212 2133160 : else if (flags & OGR_G_MEASURED)
213 946 : return wkbPointM;
214 2132220 : else if (flags & OGR_G_3D)
215 180543 : return wkbPoint25D;
216 : else
217 1951670 : return wkbPoint;
218 : }
219 :
220 : /************************************************************************/
221 : /* getGeometryName() */
222 : /************************************************************************/
223 :
224 106996 : const char *OGRPoint::getGeometryName() const
225 :
226 : {
227 106996 : return "POINT";
228 : }
229 :
230 : /************************************************************************/
231 : /* flattenTo2D() */
232 : /************************************************************************/
233 :
234 92014 : void OGRPoint::flattenTo2D()
235 :
236 : {
237 92014 : z = 0.0;
238 92014 : m = 0.0;
239 92014 : flags &= ~OGR_G_3D;
240 92014 : setMeasured(FALSE);
241 92014 : }
242 :
243 : /************************************************************************/
244 : /* setCoordinateDimension() */
245 : /************************************************************************/
246 :
247 884 : bool OGRPoint::setCoordinateDimension(int nNewDimension)
248 :
249 : {
250 884 : if (nNewDimension == 2)
251 27 : flattenTo2D();
252 857 : else if (nNewDimension == 3)
253 857 : flags |= OGR_G_3D;
254 :
255 884 : setMeasured(FALSE);
256 884 : return true;
257 : }
258 :
259 : /************************************************************************/
260 : /* WkbSize() */
261 : /* */
262 : /* Return the size of this object in well known binary */
263 : /* representation including the byte order, and type information. */
264 : /************************************************************************/
265 :
266 402883 : size_t OGRPoint::WkbSize() const
267 :
268 : {
269 402883 : if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED))
270 2268 : return 37;
271 400615 : else if ((flags & OGR_G_3D) || (flags & OGR_G_MEASURED))
272 19180 : return 29;
273 : else
274 381435 : return 21;
275 : }
276 :
277 : /************************************************************************/
278 : /* importFromWkb() */
279 : /* */
280 : /* Initialize from serialized stream in well known binary */
281 : /* format. */
282 : /************************************************************************/
283 :
284 82581 : OGRErr OGRPoint::importFromWkb(const unsigned char *pabyData, size_t nSize,
285 : OGRwkbVariant eWkbVariant,
286 : size_t &nBytesConsumedOut)
287 :
288 : {
289 82581 : nBytesConsumedOut = 0;
290 82581 : OGRwkbByteOrder eByteOrder = wkbNDR;
291 :
292 82581 : flags = 0;
293 : OGRErr eErr =
294 82581 : importPreambleFromWkb(pabyData, nSize, eByteOrder, eWkbVariant);
295 82581 : pabyData += 5;
296 82581 : if (eErr != OGRERR_NONE)
297 0 : return eErr;
298 :
299 82581 : if (nSize != static_cast<size_t>(-1))
300 : {
301 82579 : if ((nSize < 37) && ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED)))
302 85 : return OGRERR_NOT_ENOUGH_DATA;
303 82494 : else if ((nSize < 29) &&
304 79170 : ((flags & OGR_G_3D) || (flags & OGR_G_MEASURED)))
305 1 : return OGRERR_NOT_ENOUGH_DATA;
306 82493 : else if (nSize < 21)
307 0 : return OGRERR_NOT_ENOUGH_DATA;
308 : }
309 :
310 82495 : nBytesConsumedOut = 5 + 8 * (2 + ((flags & OGR_G_3D) ? 1 : 0) +
311 82495 : ((flags & OGR_G_MEASURED) ? 1 : 0));
312 :
313 : /* -------------------------------------------------------------------- */
314 : /* Get the vertex. */
315 : /* -------------------------------------------------------------------- */
316 82495 : memcpy(&x, pabyData, 8);
317 82495 : pabyData += 8;
318 82495 : memcpy(&y, pabyData, 8);
319 82495 : pabyData += 8;
320 :
321 82495 : if (OGR_SWAP(eByteOrder))
322 : {
323 160 : CPL_SWAPDOUBLE(&x);
324 160 : CPL_SWAPDOUBLE(&y);
325 : }
326 :
327 82495 : if (flags & OGR_G_3D)
328 : {
329 2955 : memcpy(&z, pabyData, 8);
330 2955 : pabyData += 8;
331 2955 : if (OGR_SWAP(eByteOrder))
332 10 : CPL_SWAPDOUBLE(&z);
333 : }
334 : else
335 : {
336 79540 : z = 0;
337 : }
338 82495 : if (flags & OGR_G_MEASURED)
339 : {
340 2836 : memcpy(&m, pabyData, 8);
341 : /*pabyData += 8; */
342 2836 : if (OGR_SWAP(eByteOrder))
343 : {
344 5 : CPL_SWAPDOUBLE(&m);
345 : }
346 : }
347 : else
348 : {
349 79659 : m = 0;
350 : }
351 :
352 : // Detect coordinates are not NaN --> NOT EMPTY.
353 82495 : if (!(std::isnan(x) && std::isnan(y)))
354 82449 : flags |= OGR_G_NOT_EMPTY_POINT;
355 :
356 82495 : return OGRERR_NONE;
357 : }
358 :
359 : /************************************************************************/
360 : /* exportToWkb() */
361 : /* */
362 : /* Build a well known binary representation of this object. */
363 : /************************************************************************/
364 :
365 399597 : OGRErr OGRPoint::exportToWkb(unsigned char *pabyData,
366 : const OGRwkbExportOptions *psOptions) const
367 :
368 : {
369 399597 : if (!psOptions)
370 : {
371 : static const OGRwkbExportOptions defaultOptions;
372 0 : psOptions = &defaultOptions;
373 : }
374 :
375 : /* -------------------------------------------------------------------- */
376 : /* Set the byte order. */
377 : /* -------------------------------------------------------------------- */
378 399597 : pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER(
379 : static_cast<unsigned char>(psOptions->eByteOrder));
380 399597 : pabyData += 1;
381 :
382 : /* -------------------------------------------------------------------- */
383 : /* Set the geometry feature type. */
384 : /* -------------------------------------------------------------------- */
385 :
386 399597 : GUInt32 nGType = getGeometryType();
387 :
388 399597 : if (psOptions->eWkbVariant == wkbVariantPostGIS1)
389 : {
390 514 : nGType = wkbFlatten(nGType);
391 514 : if (Is3D())
392 : // Explicitly set wkb25DBit.
393 5 : nGType =
394 5 : static_cast<OGRwkbGeometryType>(nGType | wkb25DBitInternalUse);
395 514 : if (IsMeasured())
396 0 : nGType = static_cast<OGRwkbGeometryType>(nGType | 0x40000000);
397 : }
398 399083 : else if (psOptions->eWkbVariant == wkbVariantIso)
399 : {
400 258455 : nGType = getIsoGeometryType();
401 : }
402 :
403 399597 : if (psOptions->eByteOrder == wkbNDR)
404 : {
405 399570 : CPL_LSBPTR32(&nGType);
406 : }
407 : else
408 : {
409 27 : CPL_MSBPTR32(&nGType);
410 : }
411 :
412 399597 : memcpy(pabyData, &nGType, 4);
413 399597 : pabyData += 4;
414 :
415 : /* -------------------------------------------------------------------- */
416 : /* Copy in the raw data. Swap if needed. */
417 : /* -------------------------------------------------------------------- */
418 :
419 399597 : if (IsEmpty() && psOptions->eWkbVariant == wkbVariantIso)
420 : {
421 1040 : const double dNan = std::numeric_limits<double>::quiet_NaN();
422 1040 : memcpy(pabyData, &dNan, 8);
423 1040 : if (OGR_SWAP(psOptions->eByteOrder))
424 4 : CPL_SWAPDOUBLE(pabyData);
425 1040 : pabyData += 8;
426 1040 : memcpy(pabyData, &dNan, 8);
427 1040 : if (OGR_SWAP(psOptions->eByteOrder))
428 4 : CPL_SWAPDOUBLE(pabyData);
429 1040 : pabyData += 8;
430 1040 : if (flags & OGR_G_3D)
431 : {
432 13 : memcpy(pabyData, &dNan, 8);
433 13 : if (OGR_SWAP(psOptions->eByteOrder))
434 2 : CPL_SWAPDOUBLE(pabyData);
435 13 : pabyData += 8;
436 : }
437 1040 : if (flags & OGR_G_MEASURED)
438 : {
439 12 : memcpy(pabyData, &dNan, 8);
440 12 : if (OGR_SWAP(psOptions->eByteOrder))
441 2 : CPL_SWAPDOUBLE(pabyData);
442 : }
443 : }
444 : else
445 : {
446 398557 : memcpy(pabyData, &x, 8);
447 398557 : memcpy(pabyData + 8, &y, 8);
448 398557 : OGRRoundCoordinatesIEEE754XYValues<0>(
449 398557 : psOptions->sPrecision.nXYBitPrecision, pabyData, 1);
450 398557 : if (OGR_SWAP(psOptions->eByteOrder))
451 : {
452 23 : CPL_SWAPDOUBLE(pabyData);
453 23 : CPL_SWAPDOUBLE(pabyData + 8);
454 : }
455 398557 : pabyData += 16;
456 398557 : if (flags & OGR_G_3D)
457 : {
458 19338 : memcpy(pabyData, &z, 8);
459 19338 : OGRRoundCoordinatesIEEE754<0>(psOptions->sPrecision.nZBitPrecision,
460 : pabyData, 1);
461 19338 : if (OGR_SWAP(psOptions->eByteOrder))
462 8 : CPL_SWAPDOUBLE(pabyData);
463 19338 : pabyData += 8;
464 : }
465 398557 : if (flags & OGR_G_MEASURED)
466 : {
467 1419 : memcpy(pabyData, &m, 8);
468 1419 : OGRRoundCoordinatesIEEE754<0>(psOptions->sPrecision.nMBitPrecision,
469 : pabyData, 1);
470 1419 : if (OGR_SWAP(psOptions->eByteOrder))
471 3 : CPL_SWAPDOUBLE(pabyData);
472 : }
473 : }
474 :
475 399597 : return OGRERR_NONE;
476 : }
477 :
478 : /************************************************************************/
479 : /* importFromWkt() */
480 : /* */
481 : /* Instantiate point from well known text format ``POINT */
482 : /* (x,y)''. */
483 : /************************************************************************/
484 :
485 97737 : OGRErr OGRPoint::importFromWkt(const char **ppszInput)
486 :
487 : {
488 97737 : int bHasZ = FALSE;
489 97737 : int bHasM = FALSE;
490 97737 : bool bIsEmpty = false;
491 97737 : OGRErr eErr = importPreambleFromWkt(ppszInput, &bHasZ, &bHasM, &bIsEmpty);
492 97737 : flags = 0;
493 97737 : if (eErr != OGRERR_NONE)
494 6 : return eErr;
495 97731 : if (bHasZ)
496 274 : flags |= OGR_G_3D;
497 97731 : if (bHasM)
498 213 : flags |= OGR_G_MEASURED;
499 97731 : if (bIsEmpty)
500 : {
501 1098 : return OGRERR_NONE;
502 : }
503 : else
504 : {
505 96633 : flags |= OGR_G_NOT_EMPTY_POINT;
506 : }
507 :
508 96633 : const char *pszInput = *ppszInput;
509 :
510 : /* -------------------------------------------------------------------- */
511 : /* Read the point list which should consist of exactly one point. */
512 : /* -------------------------------------------------------------------- */
513 96633 : OGRRawPoint *poPoints = nullptr;
514 96633 : double *padfZ = nullptr;
515 96633 : double *padfM = nullptr;
516 96633 : int nMaxPoint = 0;
517 96633 : int nPoints = 0;
518 96633 : int flagsFromInput = flags;
519 :
520 96633 : pszInput = OGRWktReadPointsM(pszInput, &poPoints, &padfZ, &padfM,
521 : &flagsFromInput, &nMaxPoint, &nPoints);
522 96633 : if (pszInput == nullptr || nPoints != 1)
523 : {
524 16 : CPLFree(poPoints);
525 16 : CPLFree(padfZ);
526 16 : CPLFree(padfM);
527 16 : return OGRERR_CORRUPT_DATA;
528 : }
529 96617 : if ((flagsFromInput & OGR_G_3D) && !(flags & OGR_G_3D))
530 : {
531 44295 : flags |= OGR_G_3D;
532 44295 : bHasZ = TRUE;
533 : }
534 96617 : if ((flagsFromInput & OGR_G_MEASURED) && !(flags & OGR_G_MEASURED))
535 : {
536 4 : flags |= OGR_G_MEASURED;
537 4 : bHasM = TRUE;
538 : }
539 :
540 96617 : x = poPoints[0].x;
541 96617 : y = poPoints[0].y;
542 :
543 96617 : CPLFree(poPoints);
544 :
545 96617 : if (bHasZ)
546 : {
547 44537 : if (padfZ != nullptr)
548 44537 : z = padfZ[0];
549 : }
550 96617 : if (bHasM)
551 : {
552 195 : if (padfM != nullptr)
553 195 : m = padfM[0];
554 : }
555 :
556 96617 : CPLFree(padfZ);
557 96617 : CPLFree(padfM);
558 :
559 96617 : *ppszInput = pszInput;
560 :
561 96617 : return OGRERR_NONE;
562 : }
563 :
564 : /************************************************************************/
565 : /* exportToWkt() */
566 : /* */
567 : /* Translate this structure into its well known text format */
568 : /* equivalent. */
569 : /************************************************************************/
570 :
571 6238 : std::string OGRPoint::exportToWkt(const OGRWktOptions &opts, OGRErr *err) const
572 : {
573 6238 : std::string wkt = getGeometryName() + wktTypeString(opts.variant);
574 6238 : if (IsEmpty())
575 : {
576 66 : wkt += "EMPTY";
577 : }
578 : else
579 : {
580 6172 : wkt += "(";
581 :
582 6172 : bool measured = ((opts.variant == wkbVariantIso) && IsMeasured());
583 6172 : wkt += OGRMakeWktCoordinateM(x, y, z, m, Is3D(), measured, opts);
584 :
585 6172 : wkt += ")";
586 : }
587 :
588 6238 : if (err)
589 6009 : *err = OGRERR_NONE;
590 6238 : return wkt;
591 : }
592 :
593 : /************************************************************************/
594 : /* getEnvelope() */
595 : /************************************************************************/
596 :
597 685045 : void OGRPoint::getEnvelope(OGREnvelope *psEnvelope) const
598 :
599 : {
600 685045 : psEnvelope->MinX = getX();
601 685045 : psEnvelope->MaxX = getX();
602 685045 : psEnvelope->MinY = getY();
603 685045 : psEnvelope->MaxY = getY();
604 685045 : }
605 :
606 : /************************************************************************/
607 : /* getEnvelope() */
608 : /************************************************************************/
609 :
610 5982 : void OGRPoint::getEnvelope(OGREnvelope3D *psEnvelope) const
611 :
612 : {
613 5982 : psEnvelope->MinX = getX();
614 5982 : psEnvelope->MaxX = getX();
615 5982 : psEnvelope->MinY = getY();
616 5982 : psEnvelope->MaxY = getY();
617 5982 : psEnvelope->MinZ = getZ();
618 5982 : psEnvelope->MaxZ = getZ();
619 5982 : }
620 :
621 : /**
622 : * \fn double OGRPoint::getX() const;
623 : *
624 : * \brief Fetch X coordinate.
625 : *
626 : * Relates to the SFCOM IPoint::get_X() method.
627 : *
628 : * @return the X coordinate of this point.
629 : */
630 :
631 : /**
632 : * \fn double OGRPoint::getY() const;
633 : *
634 : * \brief Fetch Y coordinate.
635 : *
636 : * Relates to the SFCOM IPoint::get_Y() method.
637 : *
638 : * @return the Y coordinate of this point.
639 : */
640 :
641 : /**
642 : * \fn double OGRPoint::getZ() const;
643 : *
644 : * \brief Fetch Z coordinate.
645 : *
646 : * Relates to the SFCOM IPoint::get_Z() method.
647 : *
648 : * @return the Z coordinate of this point, or zero if it is a 2D point.
649 : */
650 :
651 : /**
652 : * \fn void OGRPoint::setX( double xIn );
653 : *
654 : * \brief Assign point X coordinate.
655 : *
656 : * There is no corresponding SFCOM method.
657 : */
658 :
659 : /**
660 : * \fn void OGRPoint::setY( double yIn );
661 : *
662 : * \brief Assign point Y coordinate.
663 : *
664 : * There is no corresponding SFCOM method.
665 : */
666 :
667 : /**
668 : * \fn void OGRPoint::setZ( double zIn );
669 : *
670 : * \brief Assign point Z coordinate.
671 : * Calling this method will force the geometry
672 : * coordinate dimension to 3D (wkbPoint|wkbZ).
673 : *
674 : * There is no corresponding SFCOM method.
675 : */
676 :
677 : /************************************************************************/
678 : /* Equal() */
679 : /************************************************************************/
680 :
681 7621 : OGRBoolean OGRPoint::Equals(const OGRGeometry *poOther) const
682 :
683 : {
684 7621 : if (poOther == this)
685 4 : return TRUE;
686 :
687 7617 : if (poOther->getGeometryType() != getGeometryType())
688 2 : return FALSE;
689 :
690 7615 : const auto poOPoint = poOther->toPoint();
691 7615 : if (flags != poOPoint->flags)
692 2 : return FALSE;
693 :
694 7613 : if (IsEmpty())
695 4 : return TRUE;
696 :
697 : // Should eventually test the SRS.
698 11394 : if (poOPoint->getX() != getX() || poOPoint->getY() != getY() ||
699 3785 : poOPoint->getZ() != getZ())
700 4560 : return FALSE;
701 :
702 3049 : return TRUE;
703 : }
704 :
705 : /************************************************************************/
706 : /* transform() */
707 : /************************************************************************/
708 :
709 3750 : OGRErr OGRPoint::transform(OGRCoordinateTransformation *poCT)
710 :
711 : {
712 3750 : if (poCT->Transform(1, &x, &y, &z))
713 : {
714 3746 : assignSpatialReference(poCT->GetTargetCS());
715 3746 : return OGRERR_NONE;
716 : }
717 :
718 4 : return OGRERR_FAILURE;
719 : }
720 :
721 : /************************************************************************/
722 : /* swapXY() */
723 : /************************************************************************/
724 :
725 258 : void OGRPoint::swapXY()
726 : {
727 258 : std::swap(x, y);
728 258 : }
729 :
730 : /************************************************************************/
731 : /* Within() */
732 : /************************************************************************/
733 :
734 16237 : OGRBoolean OGRPoint::Within(const OGRGeometry *poOtherGeom) const
735 :
736 : {
737 32427 : if (!IsEmpty() && poOtherGeom != nullptr &&
738 16190 : wkbFlatten(poOtherGeom->getGeometryType()) == wkbCurvePolygon)
739 : {
740 5 : const auto poCurve = poOtherGeom->toCurvePolygon();
741 5 : return poCurve->Contains(this);
742 : }
743 :
744 16232 : return OGRGeometry::Within(poOtherGeom);
745 : }
746 :
747 : /************************************************************************/
748 : /* Intersects() */
749 : /************************************************************************/
750 :
751 24 : OGRBoolean OGRPoint::Intersects(const OGRGeometry *poOtherGeom) const
752 :
753 : {
754 48 : if (!IsEmpty() && poOtherGeom != nullptr &&
755 24 : wkbFlatten(poOtherGeom->getGeometryType()) == wkbCurvePolygon)
756 : {
757 1 : const auto poCurve = poOtherGeom->toCurvePolygon();
758 1 : return poCurve->Intersects(this);
759 : }
760 :
761 23 : return OGRGeometry::Intersects(poOtherGeom);
762 : }
|