27 #include <QPainterPath>    45   return *otherLine == *
this;
    72   for ( 
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
    85   if ( nPoints > 0 && nPoints % 2 == 0 )
    98   double centerX, centerY, radius;
   121   QgsPointSequenceV2 compassPoints = compassPointsOnSegment( p1Angle, p2Angle, p3Angle, centerX, centerY, radius );
   123   for ( ; cpIt != compassPoints.
constEnd(); ++cpIt )
   125     bbox.combineExtentWith( cpIt->x(), cpIt->y() );
   130 QgsPointSequenceV2 QgsCircularStringV2::compassPointsOnSegment( 
double p1Angle, 
double p2Angle, 
double p3Angle, 
double centerX, 
double centerY, 
double radius )
   134   QgsPointV2 nPoint( centerX, centerY + radius );
   135   QgsPointV2 ePoint( centerX + radius, centerY );
   136   QgsPointV2 sPoint( centerX, centerY - radius );
   137   QgsPointV2 wPoint( centerX - radius, centerY );
   139   if ( p3Angle >= p1Angle )
   141     if ( p2Angle > p1Angle && p2Angle < p3Angle )
   143       if ( p1Angle <= 90 && p3Angle >= 90 )
   145         pointList.
append( nPoint );
   147       if ( p1Angle <= 180 && p3Angle >= 180 )
   149         pointList.
append( wPoint );
   151       if ( p1Angle <= 270 && p3Angle >= 270 )
   153         pointList.
append( sPoint );
   158       pointList.
append( ePoint );
   159       if ( p1Angle >= 90 || p3Angle <= 90 )
   161         pointList.
append( nPoint );
   163       if ( p1Angle >= 180 || p3Angle <= 180 )
   165         pointList.
append( wPoint );
   167       if ( p1Angle >= 270 || p3Angle <= 270 )
   169         pointList.
append( sPoint );
   175     if ( p2Angle < p1Angle && p2Angle > p3Angle )
   177       if ( p1Angle >= 270 && p3Angle <= 270 )
   179         pointList.
append( sPoint );
   181       if ( p1Angle >= 180 && p3Angle <= 180 )
   183         pointList.
append( wPoint );
   185       if ( p1Angle >= 90 && p3Angle <= 90 )
   187         pointList.
append( nPoint );
   192       pointList.
append( ePoint );
   193       if ( p1Angle <= 270 || p3Angle >= 270 )
   195         pointList.
append( sPoint );
   197       if ( p1Angle <= 180 || p3Angle >= 180 )
   199         pointList.
append( wPoint );
   201       if ( p1Angle <= 90 || p3Angle >= 90 )
   203         pointList.
append( nPoint );
   232   for ( 
int i = 0; i < nVertices; ++i )
   265   int size = 
sizeof( char ) + 
sizeof( quint32 ) + 
sizeof( quint32 );
   273   unsigned char* geomPtr = 
new unsigned char[binarySize];
   276   wkb << static_cast<quint32>( 
wkbType() );
   329   for ( 
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
   360   for ( 
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
   362     segmentize( 
pointN( i ), 
pointN( i + 1 ), 
pointN( i + 2 ), points, tolerance, toleranceType );
   371   return qMin( mX.
size(), mY.
size() );
   376   if ( qMin( mX.
size(), mY.
size() ) <= i )
   381   double x = mX.
at( i );
   382   double y = mY.
at( i );
   415   for ( 
int i = 0; i < nPts; ++i )
   425   if ( points.
size() < 1 )
   437   bool hasZ = firstPt.
is3D();
   461   for ( 
int i = 0; i < points.
size(); ++i )
   463     mX[i] = points[i].x();
   464     mY[i] = points[i].y();
   467       mZ[i] = points[i].z();
   471       mM[i] = points[i].m();
   478   bool clockwise = 
false;
   479   int segSide = segmentSide( p1, p3, p2 );
   485   QgsPointV2 circlePoint1 = clockwise ? p3 : p1;
   487   QgsPointV2 circlePoint3 = clockwise ? p1 : p3 ;
   496   if ( circlePoint1 != circlePoint3 && ( radius < 0 || 
qgsDoubleNear( segSide, 0.0 ) ) ) 
   504   double increment = tolerance; 
   507     double halfAngle = acos( -tolerance / radius + 1 );
   508     increment = 2 * halfAngle;
   512   double a1 = atan2( circlePoint1.
y() - centerY, circlePoint1.
x() - centerX );
   513   double a2 = atan2( circlePoint2.
y() - centerY, circlePoint2.
x() - centerX );
   514   double a3 = atan2( circlePoint3.
y() - centerY, circlePoint3.
x() - centerX );
   530   stringPoints.
insert( clockwise ? 0 : stringPoints.
size(), circlePoint1 );
   531   if ( circlePoint2 != circlePoint3 && circlePoint1 != circlePoint2 ) 
   548       if (( addP2 && 
angle > a2 ) )
   550         stringPoints.
insert( clockwise ? 0 : stringPoints.
size(), circlePoint2 );
   554       x = centerX + radius * cos( 
angle );
   555       y = centerY + radius * sin( 
angle );
   557       if ( !hasZ && !hasM )
   565         z = interpolateArc( 
angle, a1, a2, a3, circlePoint1.
z(), circlePoint2.
z(), circlePoint3.
z() );
   569         m = interpolateArc( 
angle, a1, a2, a3, circlePoint1.
m(), circlePoint2.
m(), circlePoint3.
m() );
   572       stringPoints.
insert( clockwise ? 0 : stringPoints.
size(), 
QgsPointV2( pointWkbType, x, y, z, m ) );
   575   stringPoints.
insert( clockwise ? 0 : stringPoints.
size(), circlePoint3 );
   576   points.
append( stringPoints );
   581   double side = (( pt2.
x() - pt1.
x() ) * ( pt3.
y() - pt1.
y() ) - ( pt3.
x() - pt1.
x() ) * ( pt2.
y() - pt1.
y() ) );
   600 double QgsCircularStringV2::interpolateArc( 
double angle, 
double a1, 
double a2, 
double a3, 
double zm1, 
double zm2, 
double zm3 )
 const   606       return zm1 + ( zm2 - zm1 ) * ( 
angle - a1 ) / ( a2 - a1 );
   608       return zm2 + ( zm3 - zm2 ) * ( 
angle - a2 ) / ( a3 - a2 );
   614       return zm1 + ( zm2 - zm1 ) * ( a1 - 
angle ) / ( a1 - a2 );
   616       return zm2 + ( zm3 - zm2 ) * ( a2 - 
angle ) / ( a2 - a3 );
   631   double* zArray = mZ.
data();
   635   bool useDummyZ = !hasZ || !transformZ;
   638     zArray = 
new double[nPoints];
   639     for ( 
int i = 0; i < nPoints; ++i )
   656   for ( 
int i = 0; i < nPoints; ++i )
   659     t.
map( mX.
at( i ), mY.
at( i ), &x, &y );
   666 void QgsCircularStringV2::clip( 
const QgsRectangle& rect )
   685   for ( 
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
   689     for ( 
int j = 1; j < pt.
size(); ++j )
   691       path.
lineTo( pt.
at( j ).x(), pt.
at( j ).y() );
   697   if ( nPoints % 2 == 0 )
   699     path.
lineTo( mX[ nPoints - 1 ], mY[ nPoints - 1 ] );
   705   double centerX, centerY, radius;
   707                                         radius, centerX, centerY );
   712   double diameter = 2 * radius;
   713   path.
arcTo( centerX - radius, centerY - radius, diameter, diameter, p1Angle, sweepAngle );
   739   bool vertexNrEven = ( position.
vertex % 2 == 0 );
   759   mX[position.
vertex] = newPos.
x();
   760   mY[position.
vertex] = newPos.
y();
   763     mZ[position.
vertex] = newPos.
z();
   767     mM[position.
vertex] = newPos.
m();
   781   if ( position.
vertex < 0 || position.
vertex > ( nVertices - 1 ) )
   786   if ( position.
vertex < ( nVertices - 2 ) )
   823   bool minDistLeftOf = 
false;
   825   double currentDist = 0.0;
   828   for ( 
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
   830     currentDist = closestPointOnArc( mX[i], mY[i], mX[i + 1], mY[i + 1], mX[i + 2], mY[i + 2], pt, segmentPt, vertexAfter, leftOf, epsilon );
   831     if ( currentDist < minDist )
   833       minDist = currentDist;
   834       minDistSegmentPoint = segmentPt;
   846   segmentPt = minDistSegmentPoint;
   847   vertexAfter = minDistVertexAfter;
   848   vertexAfter.
part = 0;
   849   vertexAfter.
ring = 0;
   852     *leftOf = minDistLeftOf;
   872   for ( 
int i = 0; i < maxIndex; i += 2 )
   886     sum += 0.5 * ( mX[i] * mY[i+2] - mY[i] * mX[i+2] );
   889     double midPointX = ( p1.
x() + p3.
x() ) / 2.0;
   890     double midPointY = ( p1.
y() + p3.
y() ) / 2.0;
   892     double radius, centerX, centerY;
   896     double r2 = radius * radius;
   907     double cov = 0.5 - d * sqrt( r2 - d * d ) / ( 
M_PI * r2 ) - 1 / 
M_PI * asin( d / radius );
   908     double circleChordArea = 0;
   909     if ( circlePointLeftOfLine == centerPointLeftOfLine )
   911       circleChordArea = 
M_PI * r2 * ( 1 - cov );
   915       circleChordArea = 
M_PI * r2 * cov;
   918     if ( !circlePointLeftOfLine )
   920       sum += circleChordArea;
   924       sum -= circleChordArea;
   929 double QgsCircularStringV2::closestPointOnArc( 
double x1, 
double y1, 
double x2, 
double y2, 
double x3, 
double y3,
   932   double radius, centerX, centerY;
   957     segmentPt = ( distPtPt1 <= distPtPt3 ) ? pt1 : pt3;
   958     vertexAfter.
vertex = ( distPtPt1 <= distPtPt3 ) ? 1 : 2;
   965     segmentPt.
setX( pt.
x() );
   966     segmentPt.
setY( pt.
y() );
   972     *
leftOf = clockwise ? sqrDistance > radius : sqrDistance < radius;
   978 void QgsCircularStringV2::insertVertexBetween( 
int after, 
int before, 
int pointOnCircle )
   980   double xAfter = mX.
at( after );
   981   double yAfter = mY.
at( after );
   982   double xBefore = mX.
at( before );
   983   double yBefore = mY.
at( before );
   984   double xOnCircle = mX.
at( pointOnCircle );
   985   double yOnCircle = mY.
at( pointOnCircle );
   987   double radius, centerX, centerY;
   990   double x = ( xAfter + xBefore ) / 2.0;
   991   double y = ( yAfter + yBefore ) / 2.0;
   994   mX.
insert( before, newVertex.
x() );
   995   mY.
insert( before, newVertex.
y() );
   999     mZ.
insert( before, ( mZ[after] + mZ[before] ) / 2.0 );
  1003     mM.
insert( before, ( mM[after] + mM[before] ) / 2.0 );
  1010   int before = vId.
vertex - 1;
  1012   int after = vId.
vertex + 1;
  1014   if ( vId.
vertex % 2 != 0 ) 
  1048       int vertex1 = vId.
vertex - 2;
  1049       int vertex2 = vId.
vertex - 1;
  1050       int vertex3 = vId.
vertex;
  1053       int vertex4 = vId.
vertex + 1;
  1054       int vertex5 = vId.
vertex + 2;
  1066   std::reverse( copy->mX.
begin(), copy->mX.
end() );
  1067   std::reverse( copy->mY.
begin(), copy->mY.
end() );
  1070     std::reverse( copy->mZ.
begin(), copy->mZ.
end() );
  1074     std::reverse( copy->mM.
begin(), copy->mM.
end() );
  1090   for ( 
int i = 0; i < nPoints; ++i )
  1108   for ( 
int i = 0; i < nPoints; ++i )
 QString wktTypeStr() const
Returns the WKT type string of the geometry. 
 
virtual bool dropMValue() override
Drops any measure values which exist in the geometry. 
 
A rectangle specified with double values. 
 
static QgsPointV2 pointOnLineWithDistance(const QgsPointV2 &startPoint, const QgsPointV2 &directionPoint, double distance)
Returns a point a specified distance toward a second point. 
 
QString asWkt(int precision=17) const override
Returns a WKT representation of the geometry. 
 
QDomElement asGML2(QDomDocument &doc, int precision=17, const QString &ns="gml") const override
Returns a GML2 representation of the geometry. 
 
static double circleTangentDirection(const QgsPointV2 &tangentPoint, const QgsPointV2 &cp1, const QgsPointV2 &cp2, const QgsPointV2 &cp3)
Calculates the direction angle of a circle tangent (clockwise from north in radians) ...
 
virtual QgsRectangle calculateBoundingBox() const override
Default calculator for the minimal bounding box for the geometry. 
 
static QPair< QgsWKBTypes::Type, QString > wktReadBlock(const QString &wkt)
Parses a WKT block of the format "TYPE( contents )" and returns a pair of geometry type to contents (...
 
int wkbSize() const override
Returns the size of the WKB representation of the geometry. 
 
static bool circleAngleBetween(double angle, double angle1, double angle2, bool clockwise)
Returns true if, in a circle, angle is between angle1 and angle2. 
 
QPointF currentPosition() const
 
static double ccwAngle(double dy, double dx)
Returns the counter clockwise angle between a line with components dx, dy and the line with dx > 0 an...
 
virtual QgsLineStringV2 * curveToLine(double tolerance=M_PI_2/90, SegmentationToleranceType toleranceType=MaximumAngle) const override
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
 
QDomNode appendChild(const QDomNode &newChild)
 
void push_back(const T &value)
 
static double averageAngle(double x1, double y1, double x2, double y2, double x3, double y3)
Angle between two linear segments. 
 
static Type addZ(Type type)
Adds the z dimension to a WKB type and returns the new type. 
 
static bool hasM(Type type)
Tests whether a WKB type contains m values. 
 
Circular string geometry type. 
 
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequenceV2 &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }. 
 
virtual bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string. 
 
virtual bool addMValue(double mValue=0) override
Adds a measure to the geometry, initialized to a preset value. 
 
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle...
 
const T & at(int i) const
 
void addToPainterPath(QPainterPath &path) const override
Adds a curve to a painter path. 
 
void insert(int i, const T &value)
 
static void circleCenterRadius(const QgsPointV2 &pt1, const QgsPointV2 &pt2, const QgsPointV2 &pt3, double &radius, double ¢erX, double ¢erY)
Returns radius and center of the circle through pt1, pt2, pt3. 
 
virtual bool operator!=(const QgsCurveV2 &other) const override
 
void moveTo(const QPointF &point)
 
void setX(double x)
Sets the point's x-coordinate. 
 
static double leftOfLine(double x, double y, double x1, double y1, double x2, double y2)
Returns < 0 if point(x/y) is left of the line x1,y1 -> x2,y2. 
 
virtual void clear() override
Clears the geometry, ie reset it to a null geometry. 
 
static double circleLength(double x1, double y1, double x2, double y2, double x3, double y3)
Length of a circular string segment defined by pt1, pt2, pt3. 
 
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform, bool transformZ=false) override
Transforms the geometry using a coordinate transform. 
 
QDomElement createElementNS(const QString &nsURI, const QString &qName)
 
double z() const
Returns the point's z-coordinate. 
 
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension. 
 
double y() const
Returns the point's y-coordinate. 
 
static endian_t endian()
Returns whether this machine uses big or little endian. 
 
virtual bool fromWkb(QgsConstWkbPtr wkb) override
Sets the geometry from a WKB string. 
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference) 
 
void setY(double y)
Sets the point's y-coordinate. 
 
virtual double length() const override
Returns the length of the geometry. 
 
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal. 
 
virtual bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry. 
 
static bool circleClockwise(double angle1, double angle2, double angle3)
Returns true if circle is ordered clockwise. 
 
void append(const T &value)
 
static Type dropZ(Type type)
Drops the z dimension (if present) for a WKB type and returns the new type. 
 
void drawAsPolygon(QPainter &p) const override
Draws the curve as a polygon on the specified QPainter. 
 
static Type addM(Type type)
Adds the m dimension to a WKB type and returns the new type. 
 
virtual void clearCache() const override
Clears any cached parameters associated with the geometry, eg bounding boxes. 
 
static double sqrDistance2D(const QgsPointV2 &pt1, const QgsPointV2 &pt2)
Returns the squared 2D distance between two points. 
 
Utility class for identifying a unique vertex within a geometry. 
 
QDomElement asGML2(QDomDocument &doc, int precision=17, const QString &ns="gml") const override
Returns a GML2 representation of the geometry. 
 
Line string geometry type, with support for z-dimension and m-values. 
 
static QString pointsToWKT(const QgsPointSequenceV2 &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list. 
 
void lineTo(const QPointF &endPoint)
 
void setPoints(const QgsPointSequenceV2 &points)
Resets the line string to match the specified list of points. 
 
bool isMeasure() const
Returns true if the geometry contains m values. 
 
Point geometry type, with support for z-dimension and m-values. 
 
QgsPointV2 pointN(int i) const
Returns the point at index i within the circular string. 
 
bool pointAt(int node, QgsPointV2 &point, QgsVertexId::VertexType &type) const override
Returns the point and vertex id of a point within the curve. 
 
QgsWKBTypes::Type mWkbType
 
void sumUpArea(double &sum) const override
Sums up the area of the curve by iterating over the vertices (shoelace formula). 
 
virtual bool moveVertex(QgsVertexId position, const QgsPointV2 &newPos) override
Moves a vertex within the geometry. 
 
double x() const
Returns the point's x-coordinate. 
 
void setZMTypeFromSubGeometry(const QgsAbstractGeometryV2 *subggeom, QgsWKBTypes::Type baseGeomType)
Updates the geometry type based on whether sub geometries contain z or m values. 
 
static bool angleOnCircle(double angle, double angle1, double angle2, double angle3)
Returns true if an angle is between angle1 and angle3 on a circle described by angle1, angle2 and angle3. 
 
virtual QgsPointV2 startPoint() const override
Returns the starting point of the curve. 
 
double closestSegment(const QgsPointV2 &pt, QgsPointV2 &segmentPt, QgsVertexId &vertexAfter, bool *leftOf, double epsilon) const override
Searches for the closest segment of the geometry to a given point. 
 
QString asJSON(int precision=17) const override
Returns a GeoJSON representation of the geometry. 
 
virtual QgsCircularStringV2 * reversed() const override
Returns a reversed copy of the curve, where the direction of the curve has been flipped. 
 
static QDomElement pointsToGML3(const QgsPointSequenceV2 &points, QDomDocument &doc, int precision, const QString &ns, bool is3D)
Returns a gml::posList DOM element. 
 
unsigned char * asWkb(int &binarySize) const override
Returns a WKB representation of the geometry. 
 
double ANALYSIS_EXPORT angle(Point3D *p1, Point3D *p2, Point3D *p3, Point3D *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored) 
 
virtual bool addZValue(double zValue=0) override
Adds a z-dimension to the geometry, initialized to a preset value. 
 
virtual QgsCircularStringV2 * clone() const override
Clones the geometry by performing a deep copy. 
 
void combineExtentWith(const QgsRectangle &rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
 
void setPoints(const QgsPointSequenceV2 &points)
Sets the circular string's points. 
 
virtual QgsPointV2 endPoint() const override
Returns the end point of the curve. 
 
static Type dropM(Type type)
Drops the m dimension (if present) for a WKB type and returns the new type. 
 
const T & at(int i) const
 
virtual bool dropZValue() override
Drops any z-dimensions which exist in the geometry. 
 
void drawPath(const QPainterPath &path)
 
static QgsPointSequenceV2 pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string. 
 
static double sweepAngle(double centerX, double centerY, double x1, double y1, double x2, double y2, double x3, double y3)
Calculates angle of a circular string part defined by pt1, pt2, pt3. 
 
void insert(int i, const T &value)
 
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry. 
 
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter. 
 
double vertexAngle(QgsVertexId vertex) const override
Returns approximate rotation angle for a vertex. 
 
static Type flatType(Type type)
Returns the flat type for a WKB type. 
 
void points(QgsPointSequenceV2 &pts) const override
Returns a list of points within the curve. 
 
double ANALYSIS_EXPORT leftOf(Point3D *thepoint, Point3D *p1, Point3D *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'. 
 
QgsWKBTypes::Type readHeader() const
 
const_iterator constEnd() const
 
const_iterator constBegin() const
 
Abstract base class for curved geometry type. 
 
QDomElement asGML3(QDomDocument &doc, int precision=17, const QString &ns="gml") const override
Returns a GML3 representation of the geometry. 
 
virtual bool insertVertex(QgsVertexId position, const QgsPointV2 &vertex) override
Inserts a vertex into the geometry. 
 
void arcTo(const QRectF &rectangle, qreal startAngle, qreal sweepLength)
 
double m() const
Returns the point's m value. 
 
QString asJSON(int precision=17) const override
Returns a GeoJSON representation of the geometry. 
 
virtual bool operator==(const QgsCurveV2 &other) const override
 
bool is3D() const
Returns true if the geometry is 3D and contains a z-value. 
 
int numPoints() const override
Returns the number of points in the curve.