QGIS API Documentation 4.1.0-Master (3fcefe620d1)
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 if ( numPoints() < 1 )
305 {
306 return QgsPoint();
307 }
308 return pointN( 0 );
309}
310
312{
313 if ( numPoints() < 1 )
314 {
315 return QgsPoint();
316 }
317 return pointN( numPoints() - 1 );
318}
319
320void QgsSimpleCurve::filterVertices( const std::function<bool( const QgsPoint & )> &filter )
321{
322 bool hasZ = is3D();
323 bool hasM = isMeasure();
324 int size = mX.size();
325
326 double *srcX = mX.data();
327 double *srcY = mY.data();
328 double *srcM = hasM ? mM.data() : nullptr;
329 double *srcZ = hasZ ? mZ.data() : nullptr;
330
331 double *destX = srcX;
332 double *destY = srcY;
333 double *destM = srcM;
334 double *destZ = srcZ;
335
336 int filteredPoints = 0;
337 for ( int i = 0; i < size; ++i )
338 {
339 double x = *srcX++;
340 double y = *srcY++;
341 double z = hasZ ? *srcZ++ : std::numeric_limits<double>::quiet_NaN();
342 double m = hasM ? *srcM++ : std::numeric_limits<double>::quiet_NaN();
343
344 if ( filter( QgsPoint( x, y, z, m ) ) )
345 {
346 filteredPoints++;
347 *destX++ = x;
348 *destY++ = y;
349 if ( hasM )
350 *destM++ = m;
351 if ( hasZ )
352 *destZ++ = z;
353 }
354 }
355
356 mX.resize( filteredPoints );
357 mY.resize( filteredPoints );
358 if ( hasZ )
359 mZ.resize( filteredPoints );
360 if ( hasM )
361 mM.resize( filteredPoints );
362
363 clearCache();
364}
365
366void QgsSimpleCurve::transformVertices( const std::function<QgsPoint( const QgsPoint & )> &transform )
367{
368 bool hasZ = is3D();
369 bool hasM = isMeasure();
370 int size = mX.size();
371
372 double *srcX = mX.data();
373 double *srcY = mY.data();
374 double *srcM = hasM ? mM.data() : nullptr;
375 double *srcZ = hasZ ? mZ.data() : nullptr;
376
377 for ( int i = 0; i < size; ++i )
378 {
379 double x = *srcX;
380 double y = *srcY;
381 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
382 double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
383 QgsPoint res = transform( QgsPoint( x, y, z, m ) );
384 *srcX++ = res.x();
385 *srcY++ = res.y();
386 if ( hasM )
387 *srcM++ = res.m();
388 if ( hasZ )
389 *srcZ++ = res.z();
390 }
391 clearCache();
392}
393
394bool QgsSimpleCurve::moveVertex( QgsVertexId position, const QgsPoint &newPos )
395{
396 if ( position.vertex < 0 || position.vertex >= mX.size() )
397 {
398 return false;
399 }
400
401 mX[position.vertex] = newPos.x();
402 mY[position.vertex] = newPos.y();
403 if ( is3D() && newPos.is3D() )
404 {
405 mZ[position.vertex] = newPos.z();
406 }
407 if ( isMeasure() && newPos.isMeasure() )
408 {
409 mM[position.vertex] = newPos.m();
410 }
411 clearCache(); //set bounding box invalid
412 return true;
413}
414
416{
417 QgsSimpleCurve *copy = qgis::down_cast<QgsSimpleCurve *>( clone() );
418 std::reverse( copy->mX.begin(), copy->mX.end() );
419 std::reverse( copy->mY.begin(), copy->mY.end() );
420 if ( is3D() )
421 {
422 std::reverse( copy->mZ.begin(), copy->mZ.end() );
423 }
424 if ( isMeasure() )
425 {
426 std::reverse( copy->mM.begin(), copy->mM.end() );
427 }
428
430 return copy;
431}
432
434{
435 const QgsSimpleCurve *otherCurve = qgsgeometry_cast<const QgsSimpleCurve *>( other );
436 if ( !otherCurve )
437 return -1;
438
439 const int size = mX.size();
440 const int otherSize = otherCurve->mX.size();
441 if ( size > otherSize )
442 {
443 return 1;
444 }
445 else if ( size < otherSize )
446 {
447 return -1;
448 }
449
450 if ( is3D() && !otherCurve->is3D() )
451 return 1;
452 else if ( !is3D() && otherCurve->is3D() )
453 return -1;
454 const bool considerZ = is3D();
455
456 if ( isMeasure() && !otherCurve->isMeasure() )
457 return 1;
458 else if ( !isMeasure() && otherCurve->isMeasure() )
459 return -1;
460 const bool considerM = isMeasure();
461
462 for ( int i = 0; i < size; i++ )
463 {
464 const double x = mX[i];
465 const double otherX = otherCurve->mX[i];
466 if ( x < otherX )
467 {
468 return -1;
469 }
470 else if ( x > otherX )
471 {
472 return 1;
473 }
474
475 const double y = mY[i];
476 const double otherY = otherCurve->mY[i];
477 if ( y < otherY )
478 {
479 return -1;
480 }
481 else if ( y > otherY )
482 {
483 return 1;
484 }
485
486 if ( considerZ )
487 {
488 const double z = mZ[i];
489 const double otherZ = otherCurve->mZ[i];
490
491 if ( z < otherZ )
492 {
493 return -1;
494 }
495 else if ( z > otherZ )
496 {
497 return 1;
498 }
499 }
500
501 if ( considerM )
502 {
503 const double m = mM[i];
504 const double otherM = otherCurve->mM[i];
505
506 if ( m < otherM )
507 {
508 return -1;
509 }
510 else if ( m > otherM )
511 {
512 return 1;
513 }
514 }
515 }
516 return 0;
517}
518
520 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
521) const
522{
523 const bool useZ = is3D();
524 const bool useM = isMeasure();
525
526 const int size = mX.size();
527 if ( size == 0 )
528 return;
529
530 index = std::clamp( index, 0, size - 1 );
531
532 const int part1Size = index + 1;
533 x1.resize( part1Size );
534 y1.resize( part1Size );
535 z1.resize( useZ ? part1Size : 0 );
536 m1.resize( useM ? part1Size : 0 );
537
538 const double *sourceX = mX.constData();
539 const double *sourceY = mY.constData();
540 const double *sourceZ = useZ ? mZ.constData() : nullptr;
541 const double *sourceM = useM ? mM.constData() : nullptr;
542
543 double *destX = x1.data();
544 double *destY = y1.data();
545 double *destZ = useZ ? z1.data() : nullptr;
546 double *destM = useM ? m1.data() : nullptr;
547
548 std::copy( sourceX, sourceX + part1Size, destX );
549 std::copy( sourceY, sourceY + part1Size, destY );
550 if ( useZ )
551 std::copy( sourceZ, sourceZ + part1Size, destZ );
552 if ( useM )
553 std::copy( sourceM, sourceM + part1Size, destM );
554
555 const int part2Size = size - index;
556 x2.resize( part2Size );
557 y2.resize( part2Size );
558 z2.resize( useZ ? part2Size : 0 );
559 m2.resize( useM ? part2Size : 0 );
560
561 if ( part2Size < 2 )
562 return;
563
564 destX = x2.data();
565 destY = y2.data();
566 destZ = useZ ? z2.data() : nullptr;
567 destM = useM ? m2.data() : nullptr;
568 std::copy( sourceX + index, sourceX + size, destX );
569 std::copy( sourceY + index, sourceY + size, destY );
570 if ( useZ )
571 std::copy( sourceZ + index, sourceZ + size, destZ );
572 if ( useM )
573 std::copy( sourceM + index, sourceM + size, destM );
574
575 return;
576}
577
579{
580 if ( !curve || curve->isEmpty() || QgsWkbTypes::flatType( mWkbType ) != QgsWkbTypes::flatType( curve->wkbType() ) )
581 {
582 return;
583 }
584
585 if ( numPoints() < 1 )
586 {
588 }
589
590 // do not store duplicate points
591 if ( numPoints() > 0
592 && curve->numPoints() > 0
593 && qgsDoubleNear( endPoint().x(), curve->startPoint().x() )
594 && qgsDoubleNear( endPoint().y(), curve->startPoint().y() )
595 && ( !is3D() || !curve->is3D() || qgsDoubleNear( endPoint().z(), curve->startPoint().z() ) )
596 && ( !isMeasure() || !curve->isMeasure() || qgsDoubleNear( endPoint().m(), curve->startPoint().m() ) ) )
597 {
598 mX.pop_back();
599 mY.pop_back();
600
601 if ( is3D() && curve->is3D() )
602 {
603 mZ.pop_back();
604 }
605 if ( isMeasure() && curve->isMeasure() )
606 {
607 mM.pop_back();
608 }
609 }
610
611 mX += curve->mX;
612 mY += curve->mY;
613
614 if ( is3D() )
615 {
616 if ( curve->is3D() )
617 {
618 mZ += curve->mZ;
619 }
620 else
621 {
622 // if append line does not have z coordinates, fill with NaN to match number of points in final line
623 mZ.insert( mZ.count(), mX.size() - mZ.size(), std::numeric_limits<double>::quiet_NaN() );
624 }
625 }
626
627 if ( isMeasure() )
628 {
629 if ( curve->isMeasure() )
630 {
631 mM += curve->mM;
632 }
633 else
634 {
635 // if append line does not have m values, fill with NaN to match number of points in final line
636 mM.insert( mM.count(), mX.size() - mM.size(), std::numeric_limits<double>::quiet_NaN() );
637 }
638 }
639
640 clearCache(); //set bounding box invalid
641}
642
644{
645 pts.clear();
646 int nPoints = numPoints();
647 pts.reserve( nPoints );
648 for ( int i = 0; i < nPoints; ++i )
649 {
650 pts.push_back( pointN( i ) );
651 }
652}
653
655{
656 if ( points.isEmpty() )
657 {
658 clear();
659 return;
660 }
661
662 clearCache(); //set bounding box invalid
663
664 //get wkb type from first point
665 const QgsPoint &firstPt = points.at( 0 );
666 bool hasZ = firstPt.is3D();
667 bool hasM = firstPt.isMeasure();
668
670
671 mX.resize( points.size() );
672 mY.resize( points.size() );
673 if ( hasZ )
674 {
675 mZ.resize( points.size() );
676 }
677 else
678 {
679 mZ.clear();
680 }
681 if ( hasM )
682 {
683 mM.resize( points.size() );
684 }
685 else
686 {
687 mM.clear();
688 }
689
690 for ( int i = 0; i < points.size(); ++i )
691 {
692 mX[i] = points.at( i ).x();
693 mY[i] = points.at( i ).y();
694 if ( hasZ )
695 {
696 double z = points.at( i ).z();
697 mZ[i] = std::isnan( z ) ? 0 : z;
698 }
699 if ( hasM )
700 {
701 double m = points.at( i ).m();
702 mM[i] = std::isnan( m ) ? 0 : m;
703 }
704 }
705}
706
707void QgsSimpleCurve::scroll( int index )
708{
709 const int size = mX.size();
710 if ( index < 1 || index >= size - 1 )
711 return;
712
713 const bool useZ = is3D();
714 const bool useM = isMeasure();
715
716 QVector<double> newX( size );
717 QVector<double> newY( size );
718 QVector<double> newZ( useZ ? size : 0 );
719 QVector<double> newM( useM ? size : 0 );
720 auto it = std::copy( mX.constBegin() + index, mX.constEnd() - 1, newX.begin() );
721 it = std::copy( mX.constBegin(), mX.constBegin() + index, it );
722 *it = *newX.constBegin();
723 mX = std::move( newX );
724
725 it = std::copy( mY.constBegin() + index, mY.constEnd() - 1, newY.begin() );
726 it = std::copy( mY.constBegin(), mY.constBegin() + index, it );
727 *it = *newY.constBegin();
728 mY = std::move( newY );
729 if ( useZ )
730 {
731 it = std::copy( mZ.constBegin() + index, mZ.constEnd() - 1, newZ.begin() );
732 it = std::copy( mZ.constBegin(), mZ.constBegin() + index, it );
733 *it = *newZ.constBegin();
734 mZ = std::move( newZ );
735 }
736 if ( useM )
737 {
738 it = std::copy( mM.constBegin() + index, mM.constEnd() - 1, newM.begin() );
739 it = std::copy( mM.constBegin(), mM.constBegin() + index, it );
740 *it = *newM.constBegin();
741 mM = std::move( newM );
742 }
743}
744
746{
747 std::swap( mX, mY );
748 clearCache();
749}
750
752{
753 return mX.isEmpty();
754}
755
756
758{
759 if ( !transformer )
760 return false;
761
762 bool hasZ = is3D();
763 bool hasM = isMeasure();
764 int size = mX.size();
765
766 double *srcX = mX.data();
767 double *srcY = mY.data();
768 double *srcM = hasM ? mM.data() : nullptr;
769 double *srcZ = hasZ ? mZ.data() : nullptr;
770
771 bool res = true;
772 for ( int i = 0; i < size; ++i )
773 {
774 double x = *srcX;
775 double y = *srcY;
776 double z = hasZ ? *srcZ : std::numeric_limits<double>::quiet_NaN();
777 double m = hasM ? *srcM : std::numeric_limits<double>::quiet_NaN();
778 if ( !transformer->transformPoint( x, y, z, m ) )
779 {
780 res = false;
781 break;
782 }
783
784 *srcX++ = x;
785 *srcY++ = y;
786 if ( hasM )
787 *srcM++ = m;
788 if ( hasZ )
789 *srcZ++ = z;
790
791 if ( feedback && feedback->isCanceled() )
792 {
793 res = false;
794 break;
795 }
796 }
797 clearCache();
798 return res;
799}
800
802{
803 double *zArray = nullptr;
804 bool hasZ = is3D();
805 int nPoints = numPoints();
806
807 // it's possible that transformCoords will throw an exception - so we need to use
808 // a smart pointer for the dummy z values in order to ensure that they always get cleaned up
809 std::unique_ptr< double[] > dummyZ;
810 if ( !hasZ || !transformZ )
811 {
812 dummyZ = std::make_unique<double[]>( nPoints );
813 zArray = dummyZ.get();
814 }
815 else
816 {
817 zArray = mZ.data();
818 }
819 ct.transformCoords( nPoints, mX.data(), mY.data(), zArray, d );
820 clearCache();
821}
822
823void QgsSimpleCurve::transform( const QTransform &t, double zTranslate, double zScale, double mTranslate, double mScale )
824{
825 int nPoints = numPoints();
826 bool hasZ = is3D();
827 bool hasM = isMeasure();
828 double *x = mX.data();
829 double *y = mY.data();
830 double *z = hasZ ? mZ.data() : nullptr;
831 double *m = hasM ? mM.data() : nullptr;
832 for ( int i = 0; i < nPoints; ++i )
833 {
834 double xOut, yOut;
835 t.map( *x, *y, &xOut, &yOut );
836 *x++ = xOut;
837 *y++ = yOut;
838 if ( hasZ )
839 {
840 *z = *z * zScale + zTranslate;
841 z++;
842 }
843 if ( hasM )
844 {
845 *m = *m * mScale + mTranslate;
846 m++;
847 }
848 }
849 clearCache();
850}
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:294
@ LineString25D
LineString25D.
Definition qgis.h:362
@ Point
Point.
Definition qgis.h:296
@ Unknown
Unknown.
Definition qgis.h:295
@ PointM
PointM.
Definition qgis.h:329
@ PointZ
PointZ.
Definition qgis.h:313
@ Point25D
Point25D.
Definition qgis.h:361
@ PointZM
PointZM.
Definition qgis.h:345
@ LineStringZ
LineStringZ.
Definition qgis.h:314
TransformDirection
Indicates the direction (forward or inverse) of a transform.
Definition qgis.h:2832
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:406
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.
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:7340
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.