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 : }
|