QGIS API Documentation 4.3.0-Master (0ad0cdb9438)
Loading...
Searching...
No Matches
qgssimplecurve.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgssimplecurve.h
3 ------------
4 begin : May 2026
5 copyright : (C) 2014 by Marco Hugentobler
6 (C) 2026 by Germán Carrillo
7 email : marco at sourcepole dot ch
8 german at opengis dot ch
9 ***************************************************************************/
10
11/***************************************************************************
12 * *
13 * This program is free software; you can redistribute it and/or modify *
14 * it under the terms of the GNU General Public License as published by *
15 * the Free Software Foundation; either version 2 of the License, or *
16 * (at your option) any later version. *
17 * *
18 ***************************************************************************/
19
20#include "qgssimplecurve.h"
21
22#include "qgsapplication.h"
24#include "qgsfeedback.h"
26#include "qgsgeometryutils.h"
27
28#include <QString>
29
30using namespace Qt::StringLiterals;
31
33{
34 int binarySize = sizeof( char ) + sizeof( quint32 ) + sizeof( quint32 );
35 binarySize += numPoints() * ( 2 + is3D() + isMeasure() ) * sizeof( double );
36 return binarySize;
37}
38
39QByteArray QgsSimpleCurve::asWkb( WkbFlags flags ) const
40{
41 QByteArray wkbArray;
42 wkbArray.resize( QgsSimpleCurve::wkbSize( flags ) );
43 QgsWkbPtr wkb( wkbArray );
44 wkb << static_cast<char>( QgsApplication::endian() );
45 wkb << static_cast<quint32>( wkbType() );
47 points( pts );
48 QgsGeometryUtils::pointsToWKB( wkb, pts, is3D(), isMeasure(), flags );
49 return wkbArray;
50}
51
52QString QgsSimpleCurve::asWkt( int precision ) const
53{
54 QString wkt = wktTypeStr() + ' ';
55
56 if ( isEmpty() )
57 wkt += "EMPTY"_L1;
58 else
59 {
61 points( pts );
62 wkt += QgsGeometryUtils::pointsToWKT( pts, precision, is3D(), isMeasure() );
63 }
64 return wkt;
65}
66
68{
69 if ( !wkbPtr )
70 {
71 return false;
72 }
73
74 Qgis::WkbType type = wkbPtr.readHeader();
76 {
77 return false;
78 }
79 mWkbType = type;
80 importVerticesFromWkb( wkbPtr );
81 return true;
82}
83
85{
86 bool hasZ = is3D();
87 bool hasM = isMeasure();
88 int nVertices = 0;
89 wkb >> nVertices;
90 mX.resize( nVertices );
91 mY.resize( nVertices );
92 hasZ ? mZ.resize( nVertices ) : mZ.clear();
93 hasM ? mM.resize( nVertices ) : mM.clear();
94 double *x = mX.data();
95 double *y = mY.data();
96 double *m = hasM ? mM.data() : nullptr;
97 double *z = hasZ ? mZ.data() : nullptr;
98 for ( int i = 0; i < nVertices; ++i )
99 {
100 wkb >> *x++;
101 wkb >> *y++;
102 if ( hasZ )
103 {
104 wkb >> *z++;
105 }
106 if ( hasM )
107 {
108 wkb >> *m++;
109 }
110 }
111 clearCache(); //set bounding box invalid
112}
113
114bool QgsSimpleCurve::fromWkt( const QString &wkt )
115{
116 clear();
117
118 QPair<Qgis::WkbType, QString> parts = QgsGeometryUtils::wktReadBlock( wkt );
119
121 return false;
122 mWkbType = parts.first;
123
124 parts.second = parts.second.remove( '(' ).remove( ')' );
125 QString secondWithoutParentheses = parts.second;
126 secondWithoutParentheses = secondWithoutParentheses.simplified().remove( ' ' );
127 if ( ( parts.second.compare( "EMPTY"_L1, Qt::CaseInsensitive ) == 0 ) || secondWithoutParentheses.isEmpty() )
128 return true;
129
131 // There is a non number in the coordinates sequence
132 // LineString ( A b, 1 2)
133 if ( points.isEmpty() )
134 return false;
135
136 setPoints( points );
137 return true;
138}
139
141{
142 mX.clear();
143 mY.clear();
144 mZ.clear();
145 mM.clear();
146 clearCache();
147}
148
150{
151 if ( i < 0 || i >= mX.size() )
152 {
153 return QgsPoint();
154 }
155
156 double x = mX.at( i );
157 double y = mY.at( i );
158 double z = std::numeric_limits<double>::quiet_NaN(); // TODO: QgsCircularString had 0 here!
159 double m = std::numeric_limits<double>::quiet_NaN(); // TODO: QgsCircularString had 0 here!
160
161 bool hasZ = is3D();
162 if ( hasZ )
163 {
164 z = mZ.at( i );
165 }
166 bool hasM = isMeasure();
167 if ( hasM )
168 {
169 m = mM.at( i );
170 }
171
174 {
176 }
177 else if ( hasZ && hasM )
178 {
180 }
181 else if ( hasZ )
182 {
184 }
185 else if ( hasM )
186 {
188 }
189 return QgsPoint( t, x, y, z, m );
190}
191
193{
194 return mX.size();
195}
196
198{
199 return mX.size();
200}
201
202bool QgsSimpleCurve::addMValue( double mValue )
203{
205 return false;
206
207 clearCache();
209
210 mM.clear();
211 int nPoints = numPoints();
212 mM.reserve( nPoints );
213 for ( int i = 0; i < nPoints; ++i )
214 {
215 mM << mValue;
216 }
217 return true;
218}
219
220bool QgsSimpleCurve::addZValue( double zValue )
221{
223 return false;
224
225 clearCache();
227 {
229 return true;
230 }
231
233
234 mZ.clear();
235 int nPoints = numPoints();
236 mZ.reserve( nPoints );
237 for ( int i = 0; i < nPoints; ++i )
238 {
239 mZ << zValue;
240 }
241 return true;
242}
243
245{
246 if ( !isMeasure() )
247 return false;
248
249 clearCache();
251 mM.clear();
252 return true;
253}
254
256{
257 if ( !is3D() )
258 return false;
259
260 clearCache();
261
263 mZ.clear();
264 return true;
265}
266
267double QgsSimpleCurve::xAt( int index ) const
268{
269 if ( index >= 0 && index < mX.size() )
270 return mX.at( index );
271 else
272 return 0.0;
273}
274
275double QgsSimpleCurve::yAt( int index ) const
276{
277 if ( index >= 0 && index < mY.size() )
278 return mY.at( index );
279 else
280 return 0.0;
281}
282
283void QgsSimpleCurve::setXAt( int index, double x )
284{
285 if ( index >= 0 && index < mX.size() )
286 mX[index] = x;
287 clearCache();
288}
289
290void QgsSimpleCurve::setYAt( int index, double y )
291{
292 if ( index >= 0 && index < mY.size() )
293 mY[index] = y;
294 clearCache();
295}
296
298{
299 return 1;
300}
301
303{
304 return true;
305}
306
308{
309 if ( numPoints() < 1 )
310 {
311 return QgsPoint();
312 }
313 return pointN( 0 );
314}
315
317{
318 if ( numPoints() < 1 )
319 {
320 return QgsPoint();
321 }
322 return pointN( numPoints() - 1 );
323}
324
325void QgsSimpleCurve::filterVertices( const std::function<bool( const QgsPoint & )> &filter )
326{
327 bool hasZ = is3D();
328 bool hasM = isMeasure();
329 int size = mX.size();
330
331 double *srcX = mX.data();
332 double *srcY = mY.data();
333 double *srcM = hasM ? mM.data() : nullptr;
334 double *srcZ = hasZ ? mZ.data() : nullptr;
335
336 double *destX = srcX;
337 double *destY = srcY;
338 double *destM = srcM;
339 double *destZ = srcZ;
340
341 int filteredPoints = 0;
342 for ( int i = 0; i < size; ++i )
343 {
344 double x = *srcX++;
345 double y = *srcY++;
346 double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN();
347 double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN();
348
349 if ( filter( QgsPoint( x, y, z, m ) ) )
350 {
351 filteredPoints++;
352 *destX++ = x;
353 *destY++ = y;
354 if ( hasM )
355 *destM++ = m;
356 if ( hasZ )
357 *destZ++ = z;
358 }
359 }
360
361 mX.resize( filteredPoints );
362 mY.resize( filteredPoints );
363 if ( hasZ )
364 mZ.resize( filteredPoints );
365 if ( hasM )
366 mM.resize( filteredPoints );
367
368 clearCache();
369}
370
371void QgsSimpleCurve::transformVertices( const std::function<QgsPoint( const QgsPoint & )> &transform )
372{
373 bool hasZ = is3D();
374 bool hasM = isMeasure();
375 int size = mX.size();
376
377 double *srcX = mX.data();
378 double *srcY = mY.data();
379 double *srcM = hasM ? mM.data() : nullptr;
380 double *srcZ = hasZ ? mZ.data() : nullptr;
381
382 for ( int i = 0; i < size; ++i )
383 {
384 double x = *srcX;
385 double y = *srcY;
386 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
387 double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
388 QgsPoint res = transform( QgsPoint( x, y, z, m ) );
389 *srcX++ = res.x();
390 *srcY++ = res.y();
391 if ( hasM )
392 *srcM++ = res.m();
393 if ( hasZ )
394 *srcZ++ = res.z();
395 }
396 clearCache();
397}
398
399bool QgsSimpleCurve::moveVertex( QgsVertexId position, const QgsPoint &newPos )
400{
401 if ( position.vertex < 0 || position.vertex >= mX.size() )
402 {
403 return false;
404 }
405
406 mX[position.vertex] = newPos.x();
407 mY[position.vertex] = newPos.y();
408 if ( is3D() && newPos.is3D() )
409 {
410 mZ[position.vertex] = newPos.z();
411 }
412 if ( isMeasure() && newPos.isMeasure() )
413 {
414 mM[position.vertex] = newPos.m();
415 }
416 clearCache(); //set bounding box invalid
417 return true;
418}
419
421{
422 QgsSimpleCurve *copy = qgis::down_cast<QgsSimpleCurve *>( clone() );
423 std::reverse( copy->mX.begin(), copy->mX.end() );
424 std::reverse( copy->mY.begin(), copy->mY.end() );
425 if ( is3D() )
426 {
427 std::reverse( copy->mZ.begin(), copy->mZ.end() );
428 }
429 if ( isMeasure() )
430 {
431 std::reverse( copy->mM.begin(), copy->mM.end() );
432 }
433
435 return copy;
436}
437
439{
440 const QgsSimpleCurve *otherCurve = qgsgeometry_cast<const QgsSimpleCurve *>( other );
441 if ( !otherCurve )
442 return -1;
443
444 const int size = mX.size();
445 const int otherSize = otherCurve->mX.size();
446 if ( size > otherSize )
447 {
448 return 1;
449 }
450 else if ( size < otherSize )
451 {
452 return -1;
453 }
454
455 if ( is3D() && !otherCurve->is3D() )
456 return 1;
457 else if ( !is3D() && otherCurve->is3D() )
458 return -1;
459 const bool considerZ = is3D();
460
461 if ( isMeasure() && !otherCurve->isMeasure() )
462 return 1;
463 else if ( !isMeasure() && otherCurve->isMeasure() )
464 return -1;
465 const bool considerM = isMeasure();
466
467 for ( int i = 0; i < size; i++ )
468 {
469 const double x = mX[i];
470 const double otherX = otherCurve->mX[i];
471 if ( x < otherX )
472 {
473 return -1;
474 }
475 else if ( x > otherX )
476 {
477 return 1;
478 }
479
480 const double y = mY[i];
481 const double otherY = otherCurve->mY[i];
482 if ( y < otherY )
483 {
484 return -1;
485 }
486 else if ( y > otherY )
487 {
488 return 1;
489 }
490
491 if ( considerZ )
492 {
493 const double z = mZ[i];
494 const double otherZ = otherCurve->mZ[i];
495
496 if ( z < otherZ )
497 {
498 return -1;
499 }
500 else if ( z > otherZ )
501 {
502 return 1;
503 }
504 }
505
506 if ( considerM )
507 {
508 const double m = mM[i];
509 const double otherM = otherCurve->mM[i];
510
511 if ( m < otherM )
512 {
513 return -1;
514 }
515 else if ( m > otherM )
516 {
517 return 1;
518 }
519 }
520 }
521 return 0;
522}
523
525 int index, QVector< double > &x1, QVector< double > &y1, QVector< double > &z1, QVector< double > &m1, QVector< double > &x2, QVector< double > &y2, QVector< double > &z2, QVector< double > &m2
526) const
527{
528 const bool useZ = is3D();
529 const bool useM = isMeasure();
530
531 const int size = mX.size();
532 if ( size == 0 )
533 return;
534
535 index = std::clamp( index, 0, size - 1 );
536
537 const int part1Size = index + 1;
538 x1.resize( part1Size );
539 y1.resize( part1Size );
540 z1.resize( useZ ? part1Size : 0 );
541 m1.resize( useM ? part1Size : 0 );
542
543 const double *sourceX = mX.constData();
544 const double *sourceY = mY.constData();
545 const double *sourceZ = useZ ? mZ.constData() : nullptr;
546 const double *sourceM = useM ? mM.constData() : nullptr;
547
548 double *destX = x1.data();
549 double *destY = y1.data();
550 double *destZ = useZ ? z1.data() : nullptr;
551 double *destM = useM ? m1.data() : nullptr;
552
553 std::copy( sourceX, sourceX + part1Size, destX );
554 std::copy( sourceY, sourceY + part1Size, destY );
555 if ( useZ )
556 std::copy( sourceZ, sourceZ + part1Size, destZ );
557 if ( useM )
558 std::copy( sourceM, sourceM + part1Size, destM );
559
560 const int part2Size = size - index;
561 x2.resize( part2Size );
562 y2.resize( part2Size );
563 z2.resize( useZ ? part2Size : 0 );
564 m2.resize( useM ? part2Size : 0 );
565
566 if ( part2Size < 2 )
567 return;
568
569 destX = x2.data();
570 destY = y2.data();
571 destZ = useZ ? z2.data() : nullptr;
572 destM = useM ? m2.data() : nullptr;
573 std::copy( sourceX + index, sourceX + size, destX );
574 std::copy( sourceY + index, sourceY + size, destY );
575 if ( useZ )
576 std::copy( sourceZ + index, sourceZ + size, destZ );
577 if ( useM )
578 std::copy( sourceM + index, sourceM + size, destM );
579
580 return;
581}
582
584{
585 if ( !curve || curve->isEmpty() || QgsWkbTypes::flatType( mWkbType ) != QgsWkbTypes::flatType( curve->wkbType() ) )
586 {
587 return;
588 }
589
590 if ( numPoints() < 1 )
591 {
593 }
594
595 // do not store duplicate points
596 if ( numPoints() > 0
597 && curve->numPoints() > 0
598 && qgsDoubleNear( endPoint().x(), curve->startPoint().x() )
599 && qgsDoubleNear( endPoint().y(), curve->startPoint().y() )
600 && ( !is3D() || !curve->is3D() || qgsDoubleNear( endPoint().z(), curve->startPoint().z() ) )
601 && ( !isMeasure() || !curve->isMeasure() || qgsDoubleNear( endPoint().m(), curve->startPoint().m() ) ) )
602 {
603 mX.pop_back();
604 mY.pop_back();
605
606 if ( is3D() && curve->is3D() )
607 {
608 mZ.pop_back();
609 }
610 if ( isMeasure() && curve->isMeasure() )
611 {
612 mM.pop_back();
613 }
614 }
615
616 mX += curve->mX;
617 mY += curve->mY;
618
619 if ( is3D() )
620 {
621 if ( curve->is3D() )
622 {
623 mZ += curve->mZ;
624 }
625 else
626 {
627 // if append line does not have z coordinates, fill with NaN to match number of points in final line
628 mZ.insert( mZ.count(), mX.size() - mZ.size(), std::numeric_limits<double>::quiet_NaN() );
629 }
630 }
631
632 if ( isMeasure() )
633 {
634 if ( curve->isMeasure() )
635 {
636 mM += curve->mM;
637 }
638 else
639 {
640 // if append line does not have m values, fill with NaN to match number of points in final line
641 mM.insert( mM.count(), mX.size() - mM.size(), std::numeric_limits<double>::quiet_NaN() );
642 }
643 }
644
645 clearCache(); //set bounding box invalid
646}
647
649{
650 pts.clear();
651 int nPoints = numPoints();
652 pts.reserve( nPoints );
653 for ( int i = 0; i < nPoints; ++i )
654 {
655 pts.push_back( pointN( i ) );
656 }
657}
658
660{
661 if ( points.isEmpty() )
662 {
663 clear();
664 return;
665 }
666
667 clearCache(); //set bounding box invalid
668
669 //get wkb type from first point
670 const QgsPoint &firstPt = points.at( 0 );
671 bool hasZ = firstPt.is3D();
672 bool hasM = firstPt.isMeasure();
673
675
676 mX.resize( points.size() );
677 mY.resize( points.size() );
678 if ( hasZ )
679 {
680 mZ.resize( points.size() );
681 }
682 else
683 {
684 mZ.clear();
685 }
686 if ( hasM )
687 {
688 mM.resize( points.size() );
689 }
690 else
691 {
692 mM.clear();
693 }
694
695 for ( int i = 0; i < points.size(); ++i )
696 {
697 mX[i] = points.at( i ).x();
698 mY[i] = points.at( i ).y();
699 if ( hasZ )
700 {
701 double z = points.at( i ).z();
702 mZ[i] = std::isnan( z ) ? 0 : z;
703 }
704 if ( hasM )
705 {
706 double m = points.at( i ).m();
707 mM[i] = std::isnan( m ) ? 0 : m;
708 }
709 }
710}
711
712void QgsSimpleCurve::scroll( int index )
713{
714 const int size = mX.size();
715 if ( index < 1 || index >= size - 1 )
716 return;
717
718 const bool useZ = is3D();
719 const bool useM = isMeasure();
720
721 QVector<double> newX( size );
722 QVector<double> newY( size );
723 QVector<double> newZ( useZ ? size : 0 );
724 QVector<double> newM( useM ? size : 0 );
725 auto it = std::copy( mX.constBegin() + index, mX.constEnd() - 1, newX.begin() );
726 it = std::copy( mX.constBegin(), mX.constBegin() + index, it );
727 *it = *newX.constBegin();
728 mX = std::move( newX );
729
730 it = std::copy( mY.constBegin() + index, mY.constEnd() - 1, newY.begin() );
731 it = std::copy( mY.constBegin(), mY.constBegin() + index, it );
732 *it = *newY.constBegin();
733 mY = std::move( newY );
734 if ( useZ )
735 {
736 it = std::copy( mZ.constBegin() + index, mZ.constEnd() - 1, newZ.begin() );
737 it = std::copy( mZ.constBegin(), mZ.constBegin() + index, it );
738 *it = *newZ.constBegin();
739 mZ = std::move( newZ );
740 }
741 if ( useM )
742 {
743 it = std::copy( mM.constBegin() + index, mM.constEnd() - 1, newM.begin() );
744 it = std::copy( mM.constBegin(), mM.constBegin() + index, it );
745 *it = *newM.constBegin();
746 mM = std::move( newM );
747 }
748}
749
751{
752 std::swap( mX, mY );
753 clearCache();
754}
755
757{
758 return mX.isEmpty();
759}
760
761
763{
764 if ( !transformer )
765 return false;
766
767 bool hasZ = is3D();
768 bool hasM = isMeasure();
769 int size = mX.size();
770
771 double *srcX = mX.data();
772 double *srcY = mY.data();
773 double *srcM = hasM ? mM.data() : nullptr;
774 double *srcZ = hasZ ? mZ.data() : nullptr;
775
776 bool res = true;
777 for ( int i = 0; i < size; ++i )
778 {
779 double x = *srcX;
780 double y = *srcY;
781 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
782 double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
783 if ( !transformer->transformPoint( x, y, z, m ) )
784 {
785 res = false;
786 break;
787 }
788
789 *srcX++ = x;
790 *srcY++ = y;
791 if ( hasM )
792 *srcM++ = m;
793 if ( hasZ )
794 *srcZ++ = z;
795
796 if ( feedback && feedback->isCanceled() )
797 {
798 res = false;
799 break;
800 }
801 }
802 clearCache();
803 return res;
804}
805
807{
808 double *zArray = nullptr;
809 bool hasZ = is3D();
810 int nPoints = numPoints();
811
812 // it's possible that transformCoords will throw an exception - so we need to use
813 // a smart pointer for the dummy z values in order to ensure that they always get cleaned up
814 std::unique_ptr< double[] > dummyZ;
815 if ( !hasZ || !transformZ )
816 {
817 dummyZ = std::make_unique<double[]>( nPoints );
818 zArray = dummyZ.get();
819 }
820 else
821 {
822 zArray = mZ.data();
823 }
824 ct.transformCoords( nPoints, mX.data(), mY.data(), zArray, d );
825 clearCache();
826}
827
828void QgsSimpleCurve::transform( const QTransform &t, double zTranslate, double zScale, double mTranslate, double mScale )
829{
830 int nPoints = numPoints();
831 bool hasZ = is3D();
832 bool hasM = isMeasure();
833 double *x = mX.data();
834 double *y = mY.data();
835 double *z = hasZ ? mZ.data() : nullptr;
836 double *m = hasM ? mM.data() : nullptr;
837 for ( int i = 0; i < nPoints; ++i )
838 {
839 double xOut, yOut;
840 t.map( *x, *y, &xOut, &yOut );
841 *x++ = xOut;
842 *y++ = yOut;
843 if ( hasZ )
844 {
845 *z = *z * zScale + zTranslate;
846 z++;
847 }
848 if ( hasM )
849 {
850 *m = *m * mScale + mTranslate;
851 m++;
852 }
853 }
854 clearCache();
855}
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:314
@ LineString25D
LineString25D.
Definition qgis.h:382
@ Point
Point.
Definition qgis.h:316
@ Unknown
Unknown.
Definition qgis.h:315
@ PointM
PointM.
Definition qgis.h:349
@ PointZ
PointZ.
Definition qgis.h:333
@ Point25D
Point25D.
Definition qgis.h:381
@ PointZM
PointZM.
Definition qgis.h:365
@ LineStringZ
LineStringZ.
Definition qgis.h:334
TransformDirection
Indicates the direction (forward or inverse) of a transform.
Definition qgis.h:2882
An abstract base class for classes which transform geometries by transforming input points to output ...
virtual bool transformPoint(double &x, double &y, double &z, double &m)=0
Transforms the point defined by the coordinates (x, y, z) and the specified m value.
bool isMeasure() const
Returns true if the geometry contains m values.
QFlags< WkbFlag > WkbFlags
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
Qgis::WkbType wkbType() const
Returns the WKB type of the geometry.
void setZMTypeFromSubGeometry(const QgsAbstractGeometry *subggeom, Qgis::WkbType baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values.
QgsAbstractGeometry()=default
QgsGeometryConstPartIterator parts() const
Returns Java-style iterator for traversal of parts of the geometry.
static endian_t endian()
Returns whether this machine uses big or little endian.
A const WKB pointer.
Definition qgswkbptr.h:211
Qgis::WkbType readHeader() const
readHeader
Definition qgswkbptr.cpp:60
Handles coordinate transforms between two coordinate systems.
void transformCoords(int numPoint, double *x, double *y, double *z, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward) const
Transform an array of coordinates to the destination CRS.
void clearCache() const override
Clears any cached parameters associated with the geometry, e.g., bounding boxes.
Definition qgscurve.cpp:298
QgsCurve * clone() const override=0
Clones the geometry by performing a deep copy.
double mSummedUpArea
Definition qgscurve.h:413
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition qgsfeedback.h:44
bool isCanceled() const
Tells whether the operation has been canceled already.
Definition qgsfeedback.h:56
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequence &points, bool is3D, bool isMeasure, QgsAbstractGeometry::WkbFlags flags)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
static QPair< Qgis::WkbType, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
static QgsPointSequence pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string.
static QString pointsToWKT(const QgsPointSequence &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:53
double z
Definition qgspoint.h:58
double x
Definition qgspoint.h:56
double m
Definition qgspoint.h:59
double y
Definition qgspoint.h:57
double yAt(int index) const override
Returns the y-coordinate of the specified node in the line string.
bool dropZValue() override
Drops any z-dimensions which exist in the geometry.
void setYAt(int index, double y)
Sets the y-coordinate of the specified node in the simple curve.
bool dropMValue() override
Drops any measure values which exist in the geometry.
QVector< double > mM
bool moveVertex(QgsVertexId position, const QgsPoint &newPos) override
Moves a vertex within the geometry.
int numPoints() const override
Returns the number of points in the curve.
int wkbSize(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Returns the length of the QByteArray returned by asWkb().
void transformVertices(const std::function< QgsPoint(const QgsPoint &) > &transform) override
Transforms the vertices from the geometry in place, applying the transform function to every vertex.
bool isEmpty() const override
Returns true if the geometry is empty.
QByteArray asWkb(QgsAbstractGeometry::WkbFlags flags=QgsAbstractGeometry::WkbFlags()) const override
Returns a WKB representation of the geometry.
int compareToSameClass(const QgsAbstractGeometry *other) const final
Compares to an other geometry of the same class, and returns a integer for sorting of the two geometr...
int nCoordinates() const override
Returns the number of nodes contained in the geometry.
void splitCurveAtVertexProtected(int index, QVector< double > &x1, QVector< double > &y1, QVector< double > &z1, QVector< double > &m1, QVector< double > &x2, QVector< double > &y2, QVector< double > &z2, QVector< double > &m2) const
Returns coordinate vectors for the split curves.
bool transform(QgsAbstractGeometryTransformer *transformer, QgsFeedback *feedback=nullptr) override
Transforms the vertices from the geometry in place, using the specified geometry transformer object.
QgsSimpleCurve()=default
double xAt(int index) const override
Returns the x-coordinate of the specified node in the line string.
void points(QgsPointSequence &pts) const override
Returns a list of points within the curve.
void setXAt(int index, double x)
Sets the x-coordinate of the specified node in the simple curve.
void clear() override
Clears the geometry, ie reset it to a null geometry.
QVector< double > mZ
bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value.
bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
QgsPoint startPoint() const override
Returns the starting point of the curve.
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry.
bool fromWkb(QgsConstWkbPtr &wkb) override
Sets the geometry from a WKB string.
bool isSimpleCurve() const override
This method returns true for classes that can be cast to the QgsSimpleCurve class.
int dimension() const override
Returns the inherent dimension of the geometry.
void filterVertices(const std::function< bool(const QgsPoint &) > &filter) override
Filters the vertices from the geometry in place, removing any which do not return true for the filter...
void setPoints(const QgsPointSequence &points)
Resets the simple curve to match the specified list of points.
QgsPoint endPoint() const override
Returns the end point of the curve.
QgsPoint pointN(int i) const
Returns the specified point from inside the simple curve.
QVector< double > mX
void scroll(int firstVertexIndex) final
Scrolls the curve vertices so that they start with the vertex at the given index.
void importVerticesFromWkb(const QgsConstWkbPtr &wkb)
Imports vertices from wkb geometry representation.
QgsSimpleCurve * reversed() const override
Returns a reversed copy of the curve, where the direction of the curve has been flipped.
QVector< double > mY
bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value.
void append(const QgsSimpleCurve *curve)
Appends the contents of another simple curve to the end of this simple curve.
void swapXy() override
Swaps the x and y coordinates from the geometry.
WKB pointer handler.
Definition qgswkbptr.h:47
static Qgis::WkbType dropM(Qgis::WkbType type)
Drops the m dimension (if present) for a WKB type and returns the new type.
static Qgis::WkbType dropZ(Qgis::WkbType type)
Drops the z dimension (if present) for a WKB type and returns the new type.
static Qgis::WkbType addM(Qgis::WkbType type)
Adds the m dimension to a WKB type and returns the new type.
static Qgis::WkbType addZ(Qgis::WkbType type)
Adds the z dimension to a WKB type and returns the new type.
static Q_INVOKABLE bool hasZ(Qgis::WkbType type)
Tests whether a WKB type contains the z-dimension.
static Q_INVOKABLE bool hasM(Qgis::WkbType type)
Tests whether a WKB type contains m values.
static Qgis::WkbType flatType(Qgis::WkbType type)
Returns the flat type for a WKB type.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference).
Definition qgis.h:7743
T qgsgeometry_cast(QgsAbstractGeometry *geom)
QVector< QgsPoint > QgsPointSequence
Utility class for identifying a unique vertex within a geometry.
Definition qgsvertexid.h:35
int vertex
Vertex number.