/src/gdal/ogr/ogrpoint.cpp
Line | Count | Source |
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 | | static int GetEmptyNonEmptyFlag(double x, double y) |
34 | 2.57k | { |
35 | 2.57k | if (std::isnan(x) || std::isnan(y)) |
36 | 528 | return 0; |
37 | 2.04k | return OGRGeometry::OGR_G_NOT_EMPTY_POINT; |
38 | 2.57k | } |
39 | | |
40 | | /************************************************************************/ |
41 | | /* OGRPoint() */ |
42 | | /************************************************************************/ |
43 | | |
44 | | /** |
45 | | * \brief Create an empty point. |
46 | | */ |
47 | | |
48 | 2.58k | OGRPoint::OGRPoint() : x(0.0), y(0.0), z(0.0), m(0.0) |
49 | | |
50 | 2.58k | { |
51 | 2.58k | flags = 0; |
52 | 2.58k | } |
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 | | OGRPoint::OGRPoint(double xIn, double yIn, double zIn) |
66 | 0 | : x(xIn), y(yIn), z(zIn), m(0.0) |
67 | 0 | { |
68 | 0 | flags = GetEmptyNonEmptyFlag(xIn, yIn) | OGR_G_3D; |
69 | 0 | } |
70 | | |
71 | | /************************************************************************/ |
72 | | /* OGRPoint() */ |
73 | | /************************************************************************/ |
74 | | |
75 | | /** |
76 | | * \brief Create a point. |
77 | | * @param xIn x |
78 | | * @param yIn y |
79 | | */ |
80 | | |
81 | 2.57k | OGRPoint::OGRPoint(double xIn, double yIn) : x(xIn), y(yIn), z(0.0), m(0.0) |
82 | 2.57k | { |
83 | 2.57k | flags = GetEmptyNonEmptyFlag(xIn, yIn); |
84 | 2.57k | } |
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 | | OGRPoint::OGRPoint(double xIn, double yIn, double zIn, double mIn) |
99 | 0 | : x(xIn), y(yIn), z(zIn), m(mIn) |
100 | 0 | { |
101 | 0 | flags = GetEmptyNonEmptyFlag(xIn, yIn) | OGR_G_3D | OGR_G_MEASURED; |
102 | 0 | } |
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 | | OGRPoint *OGRPoint::createXYM(double x, double y, double m) |
117 | 0 | { |
118 | 0 | auto p = new OGRPoint(x, y, 0, m); |
119 | 0 | p->flags &= ~OGR_G_3D; |
120 | 0 | return p; |
121 | 0 | } |
122 | | |
123 | | /************************************************************************/ |
124 | | /* OGRPoint( const OGRPoint& ) */ |
125 | | /************************************************************************/ |
126 | | |
127 | | /** |
128 | | * \brief Copy constructor. |
129 | | */ |
130 | | |
131 | 0 | OGRPoint::OGRPoint(const OGRPoint &) = default; |
132 | | |
133 | | /************************************************************************/ |
134 | | /* operator=( const OGRPoint& ) */ |
135 | | /************************************************************************/ |
136 | | |
137 | | /** |
138 | | * \brief Assignment operator. |
139 | | */ |
140 | | |
141 | | OGRPoint &OGRPoint::operator=(const OGRPoint &other) |
142 | 0 | { |
143 | 0 | if (this != &other) |
144 | 0 | { |
145 | | // Slightly more efficient to avoid OGRGeometry::operator=(other); |
146 | | // but do what it does to avoid a call to empty() |
147 | 0 | assignSpatialReference(other.getSpatialReference()); |
148 | 0 | flags = other.flags; |
149 | |
|
150 | 0 | x = other.x; |
151 | 0 | y = other.y; |
152 | 0 | z = other.z; |
153 | 0 | m = other.m; |
154 | 0 | } |
155 | 0 | return *this; |
156 | 0 | } |
157 | | |
158 | | /************************************************************************/ |
159 | | /* clone() */ |
160 | | /* */ |
161 | | /* Make a new object that is a copy of this object. */ |
162 | | /************************************************************************/ |
163 | | |
164 | | OGRPoint *OGRPoint::clone() const |
165 | | |
166 | 0 | { |
167 | 0 | return new (std::nothrow) OGRPoint(*this); |
168 | 0 | } |
169 | | |
170 | | /************************************************************************/ |
171 | | /* empty() */ |
172 | | /************************************************************************/ |
173 | | void OGRPoint::empty() |
174 | | |
175 | 16 | { |
176 | 16 | x = 0.0; |
177 | 16 | y = 0.0; |
178 | 16 | z = 0.0; |
179 | 16 | m = 0.0; |
180 | 16 | flags &= ~OGR_G_NOT_EMPTY_POINT; |
181 | 16 | } |
182 | | |
183 | | /************************************************************************/ |
184 | | /* getDimension() */ |
185 | | /************************************************************************/ |
186 | | |
187 | | int OGRPoint::getDimension() const |
188 | | |
189 | 0 | { |
190 | 0 | return 0; |
191 | 0 | } |
192 | | |
193 | | /************************************************************************/ |
194 | | /* getGeometryType() */ |
195 | | /************************************************************************/ |
196 | | |
197 | | OGRwkbGeometryType OGRPoint::getGeometryType() const |
198 | | |
199 | 9.86k | { |
200 | 9.86k | if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED)) |
201 | 4.59k | return wkbPointZM; |
202 | 5.26k | else if (flags & OGR_G_MEASURED) |
203 | 15 | return wkbPointM; |
204 | 5.25k | else if (flags & OGR_G_3D) |
205 | 4.69k | return wkbPoint25D; |
206 | 561 | else |
207 | 561 | return wkbPoint; |
208 | 9.86k | } |
209 | | |
210 | | /************************************************************************/ |
211 | | /* getGeometryName() */ |
212 | | /************************************************************************/ |
213 | | |
214 | | const char *OGRPoint::getGeometryName() const |
215 | | |
216 | 16 | { |
217 | 16 | return "POINT"; |
218 | 16 | } |
219 | | |
220 | | /************************************************************************/ |
221 | | /* flattenTo2D() */ |
222 | | /************************************************************************/ |
223 | | |
224 | | void OGRPoint::flattenTo2D() |
225 | | |
226 | 0 | { |
227 | 0 | z = 0.0; |
228 | 0 | m = 0.0; |
229 | 0 | flags &= ~OGR_G_3D; |
230 | 0 | setMeasured(FALSE); |
231 | 0 | } |
232 | | |
233 | | /************************************************************************/ |
234 | | /* setCoordinateDimension() */ |
235 | | /************************************************************************/ |
236 | | |
237 | | bool OGRPoint::setCoordinateDimension(int nNewDimension) |
238 | | |
239 | 0 | { |
240 | 0 | if (nNewDimension == 2) |
241 | 0 | flattenTo2D(); |
242 | 0 | else if (nNewDimension == 3) |
243 | 0 | flags |= OGR_G_3D; |
244 | |
|
245 | 0 | setMeasured(FALSE); |
246 | 0 | return true; |
247 | 0 | } |
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 | | size_t OGRPoint::WkbSize() const |
257 | | |
258 | 0 | { |
259 | 0 | if ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED)) |
260 | 0 | return 37; |
261 | 0 | else if ((flags & OGR_G_3D) || (flags & OGR_G_MEASURED)) |
262 | 0 | return 29; |
263 | 0 | else |
264 | 0 | return 21; |
265 | 0 | } |
266 | | |
267 | | /************************************************************************/ |
268 | | /* importFromWkb() */ |
269 | | /* */ |
270 | | /* Initialize from serialized stream in well known binary */ |
271 | | /* format. */ |
272 | | /************************************************************************/ |
273 | | |
274 | | OGRErr OGRPoint::importFromWkb(const unsigned char *pabyData, size_t nSize, |
275 | | OGRwkbVariant eWkbVariant, |
276 | | size_t &nBytesConsumedOut) |
277 | | |
278 | 0 | { |
279 | 0 | nBytesConsumedOut = 0; |
280 | 0 | OGRwkbByteOrder eByteOrder = wkbNDR; |
281 | |
|
282 | 0 | flags = 0; |
283 | 0 | OGRErr eErr = |
284 | 0 | importPreambleFromWkb(pabyData, nSize, eByteOrder, eWkbVariant); |
285 | 0 | pabyData += 5; |
286 | 0 | if (eErr != OGRERR_NONE) |
287 | 0 | return eErr; |
288 | | |
289 | 0 | if (nSize != static_cast<size_t>(-1)) |
290 | 0 | { |
291 | 0 | if ((nSize < 37) && ((flags & OGR_G_3D) && (flags & OGR_G_MEASURED))) |
292 | 0 | return OGRERR_NOT_ENOUGH_DATA; |
293 | 0 | else if ((nSize < 29) && |
294 | 0 | ((flags & OGR_G_3D) || (flags & OGR_G_MEASURED))) |
295 | 0 | return OGRERR_NOT_ENOUGH_DATA; |
296 | 0 | else if (nSize < 21) |
297 | 0 | return OGRERR_NOT_ENOUGH_DATA; |
298 | 0 | } |
299 | | |
300 | 0 | nBytesConsumedOut = 5 + 8 * (2 + ((flags & OGR_G_3D) ? 1 : 0) + |
301 | 0 | ((flags & OGR_G_MEASURED) ? 1 : 0)); |
302 | | |
303 | | /* -------------------------------------------------------------------- */ |
304 | | /* Get the vertex. */ |
305 | | /* -------------------------------------------------------------------- */ |
306 | 0 | memcpy(&x, pabyData, 8); |
307 | 0 | pabyData += 8; |
308 | 0 | memcpy(&y, pabyData, 8); |
309 | 0 | pabyData += 8; |
310 | |
|
311 | 0 | if (OGR_SWAP(eByteOrder)) |
312 | 0 | { |
313 | 0 | CPL_SWAPDOUBLE(&x); |
314 | 0 | CPL_SWAPDOUBLE(&y); |
315 | 0 | } |
316 | |
|
317 | 0 | if (flags & OGR_G_3D) |
318 | 0 | { |
319 | 0 | memcpy(&z, pabyData, 8); |
320 | 0 | pabyData += 8; |
321 | 0 | if (OGR_SWAP(eByteOrder)) |
322 | 0 | CPL_SWAPDOUBLE(&z); |
323 | 0 | } |
324 | 0 | else |
325 | 0 | { |
326 | 0 | z = 0; |
327 | 0 | } |
328 | 0 | if (flags & OGR_G_MEASURED) |
329 | 0 | { |
330 | 0 | memcpy(&m, pabyData, 8); |
331 | | /*pabyData += 8; */ |
332 | 0 | if (OGR_SWAP(eByteOrder)) |
333 | 0 | { |
334 | 0 | CPL_SWAPDOUBLE(&m); |
335 | 0 | } |
336 | 0 | } |
337 | 0 | else |
338 | 0 | { |
339 | 0 | m = 0; |
340 | 0 | } |
341 | | |
342 | | // Detect coordinates are not NaN --> NOT EMPTY. |
343 | 0 | if (!(std::isnan(x) && std::isnan(y))) |
344 | 0 | flags |= OGR_G_NOT_EMPTY_POINT; |
345 | |
|
346 | 0 | return OGRERR_NONE; |
347 | 0 | } |
348 | | |
349 | | /************************************************************************/ |
350 | | /* exportToWkb() */ |
351 | | /* */ |
352 | | /* Build a well known binary representation of this object. */ |
353 | | /************************************************************************/ |
354 | | |
355 | | OGRErr OGRPoint::exportToWkb(unsigned char *pabyData, |
356 | | const OGRwkbExportOptions *psOptions) const |
357 | | |
358 | 0 | { |
359 | 0 | if (!psOptions) |
360 | 0 | { |
361 | 0 | static const OGRwkbExportOptions defaultOptions; |
362 | 0 | psOptions = &defaultOptions; |
363 | 0 | } |
364 | | |
365 | | /* -------------------------------------------------------------------- */ |
366 | | /* Set the byte order. */ |
367 | | /* -------------------------------------------------------------------- */ |
368 | 0 | pabyData[0] = DB2_V72_UNFIX_BYTE_ORDER( |
369 | 0 | static_cast<unsigned char>(psOptions->eByteOrder)); |
370 | 0 | pabyData += 1; |
371 | | |
372 | | /* -------------------------------------------------------------------- */ |
373 | | /* Set the geometry feature type. */ |
374 | | /* -------------------------------------------------------------------- */ |
375 | |
|
376 | 0 | GUInt32 nGType = getGeometryType(); |
377 | |
|
378 | 0 | if (psOptions->eWkbVariant == wkbVariantPostGIS1) |
379 | 0 | { |
380 | 0 | nGType = wkbFlatten(nGType); |
381 | 0 | if (Is3D()) |
382 | | // Explicitly set wkb25DBit. |
383 | 0 | nGType = |
384 | 0 | static_cast<OGRwkbGeometryType>(nGType | wkb25DBitInternalUse); |
385 | 0 | if (IsMeasured()) |
386 | 0 | nGType = static_cast<OGRwkbGeometryType>(nGType | 0x40000000); |
387 | 0 | } |
388 | 0 | else if (psOptions->eWkbVariant == wkbVariantIso) |
389 | 0 | { |
390 | 0 | nGType = getIsoGeometryType(); |
391 | 0 | } |
392 | |
|
393 | 0 | if (psOptions->eByteOrder == wkbNDR) |
394 | 0 | { |
395 | 0 | CPL_LSBPTR32(&nGType); |
396 | 0 | } |
397 | 0 | else |
398 | 0 | { |
399 | 0 | CPL_MSBPTR32(&nGType); |
400 | 0 | } |
401 | |
|
402 | 0 | memcpy(pabyData, &nGType, 4); |
403 | 0 | pabyData += 4; |
404 | | |
405 | | /* -------------------------------------------------------------------- */ |
406 | | /* Copy in the raw data. Swap if needed. */ |
407 | | /* -------------------------------------------------------------------- */ |
408 | |
|
409 | 0 | if (IsEmpty() && psOptions->eWkbVariant == wkbVariantIso) |
410 | 0 | { |
411 | 0 | const double dNan = std::numeric_limits<double>::quiet_NaN(); |
412 | 0 | memcpy(pabyData, &dNan, 8); |
413 | 0 | if (OGR_SWAP(psOptions->eByteOrder)) |
414 | 0 | CPL_SWAPDOUBLE(pabyData); |
415 | 0 | pabyData += 8; |
416 | 0 | memcpy(pabyData, &dNan, 8); |
417 | 0 | if (OGR_SWAP(psOptions->eByteOrder)) |
418 | 0 | CPL_SWAPDOUBLE(pabyData); |
419 | 0 | pabyData += 8; |
420 | 0 | if (flags & OGR_G_3D) |
421 | 0 | { |
422 | 0 | memcpy(pabyData, &dNan, 8); |
423 | 0 | if (OGR_SWAP(psOptions->eByteOrder)) |
424 | 0 | CPL_SWAPDOUBLE(pabyData); |
425 | 0 | pabyData += 8; |
426 | 0 | } |
427 | 0 | if (flags & OGR_G_MEASURED) |
428 | 0 | { |
429 | 0 | memcpy(pabyData, &dNan, 8); |
430 | 0 | if (OGR_SWAP(psOptions->eByteOrder)) |
431 | 0 | CPL_SWAPDOUBLE(pabyData); |
432 | 0 | } |
433 | 0 | } |
434 | 0 | else |
435 | 0 | { |
436 | 0 | memcpy(pabyData, &x, 8); |
437 | 0 | memcpy(pabyData + 8, &y, 8); |
438 | 0 | OGRRoundCoordinatesIEEE754XYValues<0>( |
439 | 0 | psOptions->sPrecision.nXYBitPrecision, pabyData, 1); |
440 | 0 | if (OGR_SWAP(psOptions->eByteOrder)) |
441 | 0 | { |
442 | 0 | CPL_SWAPDOUBLE(pabyData); |
443 | 0 | CPL_SWAPDOUBLE(pabyData + 8); |
444 | 0 | } |
445 | 0 | pabyData += 16; |
446 | 0 | if (flags & OGR_G_3D) |
447 | 0 | { |
448 | 0 | memcpy(pabyData, &z, 8); |
449 | 0 | OGRRoundCoordinatesIEEE754<0>(psOptions->sPrecision.nZBitPrecision, |
450 | 0 | pabyData, 1); |
451 | 0 | if (OGR_SWAP(psOptions->eByteOrder)) |
452 | 0 | CPL_SWAPDOUBLE(pabyData); |
453 | 0 | pabyData += 8; |
454 | 0 | } |
455 | 0 | if (flags & OGR_G_MEASURED) |
456 | 0 | { |
457 | 0 | memcpy(pabyData, &m, 8); |
458 | 0 | OGRRoundCoordinatesIEEE754<0>(psOptions->sPrecision.nMBitPrecision, |
459 | 0 | pabyData, 1); |
460 | 0 | if (OGR_SWAP(psOptions->eByteOrder)) |
461 | 0 | CPL_SWAPDOUBLE(pabyData); |
462 | 0 | } |
463 | 0 | } |
464 | |
|
465 | 0 | return OGRERR_NONE; |
466 | 0 | } |
467 | | |
468 | | /************************************************************************/ |
469 | | /* importFromWkt() */ |
470 | | /* */ |
471 | | /* Instantiate point from well known text format ``POINT */ |
472 | | /* (x,y)''. */ |
473 | | /************************************************************************/ |
474 | | |
475 | | OGRErr OGRPoint::importFromWkt(const char **ppszInput) |
476 | | |
477 | 16 | { |
478 | 16 | int bHasZ = FALSE; |
479 | 16 | int bHasM = FALSE; |
480 | 16 | bool bIsEmpty = false; |
481 | 16 | OGRErr eErr = importPreambleFromWkt(ppszInput, &bHasZ, &bHasM, &bIsEmpty); |
482 | 16 | flags = 0; |
483 | 16 | if (eErr != OGRERR_NONE) |
484 | 1 | return eErr; |
485 | 15 | if (bHasZ) |
486 | 2 | flags |= OGR_G_3D; |
487 | 15 | if (bHasM) |
488 | 11 | flags |= OGR_G_MEASURED; |
489 | 15 | if (bIsEmpty) |
490 | 0 | { |
491 | 0 | return OGRERR_NONE; |
492 | 0 | } |
493 | 15 | else |
494 | 15 | { |
495 | 15 | flags |= OGR_G_NOT_EMPTY_POINT; |
496 | 15 | } |
497 | | |
498 | 15 | const char *pszInput = *ppszInput; |
499 | | |
500 | | /* -------------------------------------------------------------------- */ |
501 | | /* Read the point list which should consist of exactly one point. */ |
502 | | /* -------------------------------------------------------------------- */ |
503 | 15 | OGRRawPoint *poPoints = nullptr; |
504 | 15 | double *padfZ = nullptr; |
505 | 15 | double *padfM = nullptr; |
506 | 15 | int nMaxPoint = 0; |
507 | 15 | int nPoints = 0; |
508 | 15 | int flagsFromInput = flags; |
509 | | |
510 | 15 | pszInput = OGRWktReadPointsM(pszInput, &poPoints, &padfZ, &padfM, |
511 | 15 | &flagsFromInput, &nMaxPoint, &nPoints); |
512 | 15 | if (pszInput == nullptr || nPoints != 1) |
513 | 5 | { |
514 | 5 | CPLFree(poPoints); |
515 | 5 | CPLFree(padfZ); |
516 | 5 | CPLFree(padfM); |
517 | 5 | return OGRERR_CORRUPT_DATA; |
518 | 5 | } |
519 | 10 | if ((flagsFromInput & OGR_G_3D) && !(flags & OGR_G_3D)) |
520 | 0 | { |
521 | 0 | flags |= OGR_G_3D; |
522 | 0 | bHasZ = TRUE; |
523 | 0 | } |
524 | 10 | if ((flagsFromInput & OGR_G_MEASURED) && !(flags & OGR_G_MEASURED)) |
525 | 0 | { |
526 | 0 | flags |= OGR_G_MEASURED; |
527 | 0 | bHasM = TRUE; |
528 | 0 | } |
529 | | |
530 | 10 | x = poPoints[0].x; |
531 | 10 | y = poPoints[0].y; |
532 | | |
533 | 10 | CPLFree(poPoints); |
534 | | |
535 | 10 | if (bHasZ) |
536 | 2 | { |
537 | 2 | if (padfZ != nullptr) |
538 | 2 | z = padfZ[0]; |
539 | 2 | } |
540 | 10 | if (bHasM) |
541 | 8 | { |
542 | 8 | if (padfM != nullptr) |
543 | 8 | m = padfM[0]; |
544 | 8 | } |
545 | | |
546 | 10 | CPLFree(padfZ); |
547 | 10 | CPLFree(padfM); |
548 | | |
549 | 10 | *ppszInput = pszInput; |
550 | | |
551 | 10 | return OGRERR_NONE; |
552 | 15 | } |
553 | | |
554 | | /************************************************************************/ |
555 | | /* exportToWkt() */ |
556 | | /* */ |
557 | | /* Translate this structure into its well known text format */ |
558 | | /* equivalent. */ |
559 | | /************************************************************************/ |
560 | | |
561 | | std::string OGRPoint::exportToWkt(const OGRWktOptions &opts, OGRErr *err) const |
562 | 0 | { |
563 | 0 | std::string wkt = getGeometryName() + wktTypeString(opts.variant); |
564 | 0 | if (IsEmpty()) |
565 | 0 | { |
566 | 0 | wkt += "EMPTY"; |
567 | 0 | } |
568 | 0 | else |
569 | 0 | { |
570 | 0 | wkt += "("; |
571 | |
|
572 | 0 | bool measured = ((opts.variant == wkbVariantIso) && IsMeasured()); |
573 | 0 | wkt += OGRMakeWktCoordinateM(x, y, z, m, Is3D(), measured, opts); |
574 | |
|
575 | 0 | wkt += ")"; |
576 | 0 | } |
577 | |
|
578 | 0 | if (err) |
579 | 0 | *err = OGRERR_NONE; |
580 | 0 | return wkt; |
581 | 0 | } |
582 | | |
583 | | /************************************************************************/ |
584 | | /* getEnvelope() */ |
585 | | /************************************************************************/ |
586 | | |
587 | | void OGRPoint::getEnvelope(OGREnvelope *psEnvelope) const |
588 | | |
589 | 0 | { |
590 | 0 | psEnvelope->MinX = getX(); |
591 | 0 | psEnvelope->MaxX = getX(); |
592 | 0 | psEnvelope->MinY = getY(); |
593 | 0 | psEnvelope->MaxY = getY(); |
594 | 0 | } |
595 | | |
596 | | /************************************************************************/ |
597 | | /* getEnvelope() */ |
598 | | /************************************************************************/ |
599 | | |
600 | | void OGRPoint::getEnvelope(OGREnvelope3D *psEnvelope) const |
601 | | |
602 | 0 | { |
603 | 0 | psEnvelope->MinX = getX(); |
604 | 0 | psEnvelope->MaxX = getX(); |
605 | 0 | psEnvelope->MinY = getY(); |
606 | 0 | psEnvelope->MaxY = getY(); |
607 | 0 | psEnvelope->MinZ = getZ(); |
608 | 0 | psEnvelope->MaxZ = getZ(); |
609 | 0 | } |
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 | | OGRBoolean OGRPoint::Equals(const OGRGeometry *poOther) const |
672 | | |
673 | 0 | { |
674 | 0 | if (poOther == this) |
675 | 0 | return TRUE; |
676 | | |
677 | 0 | if (poOther->getGeometryType() != getGeometryType()) |
678 | 0 | return FALSE; |
679 | | |
680 | 0 | const auto poOPoint = poOther->toPoint(); |
681 | 0 | if (flags != poOPoint->flags) |
682 | 0 | return FALSE; |
683 | | |
684 | 0 | if (IsEmpty()) |
685 | 0 | return TRUE; |
686 | | |
687 | | // Should eventually test the SRS. |
688 | 0 | if (poOPoint->getX() != getX() || poOPoint->getY() != getY() || |
689 | 0 | poOPoint->getZ() != getZ()) |
690 | 0 | return FALSE; |
691 | | |
692 | 0 | return TRUE; |
693 | 0 | } |
694 | | |
695 | | /************************************************************************/ |
696 | | /* transform() */ |
697 | | /************************************************************************/ |
698 | | |
699 | | OGRErr OGRPoint::transform(OGRCoordinateTransformation *poCT) |
700 | | |
701 | 0 | { |
702 | 0 | if (poCT->Transform(1, &x, &y, &z)) |
703 | 0 | { |
704 | 0 | assignSpatialReference(poCT->GetTargetCS()); |
705 | 0 | return OGRERR_NONE; |
706 | 0 | } |
707 | | |
708 | 0 | return OGRERR_FAILURE; |
709 | 0 | } |
710 | | |
711 | | /************************************************************************/ |
712 | | /* swapXY() */ |
713 | | /************************************************************************/ |
714 | | |
715 | | void OGRPoint::swapXY() |
716 | 0 | { |
717 | 0 | std::swap(x, y); |
718 | 0 | } |
719 | | |
720 | | /************************************************************************/ |
721 | | /* Within() */ |
722 | | /************************************************************************/ |
723 | | |
724 | | OGRBoolean OGRPoint::Within(const OGRGeometry *poOtherGeom) const |
725 | | |
726 | 0 | { |
727 | 0 | if (!IsEmpty() && poOtherGeom != nullptr && |
728 | 0 | wkbFlatten(poOtherGeom->getGeometryType()) == wkbCurvePolygon) |
729 | 0 | { |
730 | 0 | const auto poCurve = poOtherGeom->toCurvePolygon(); |
731 | 0 | return poCurve->Contains(this); |
732 | 0 | } |
733 | | |
734 | 0 | return OGRGeometry::Within(poOtherGeom); |
735 | 0 | } |
736 | | |
737 | | /************************************************************************/ |
738 | | /* Intersects() */ |
739 | | /************************************************************************/ |
740 | | |
741 | | OGRBoolean OGRPoint::Intersects(const OGRGeometry *poOtherGeom) const |
742 | | |
743 | 0 | { |
744 | 0 | if (!IsEmpty() && poOtherGeom != nullptr && |
745 | 0 | wkbFlatten(poOtherGeom->getGeometryType()) == wkbCurvePolygon) |
746 | 0 | { |
747 | 0 | const auto poCurve = poOtherGeom->toCurvePolygon(); |
748 | 0 | return poCurve->Intersects(this); |
749 | 0 | } |
750 | | |
751 | 0 | return OGRGeometry::Intersects(poOtherGeom); |
752 | 0 | } |