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 )
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();
483 int segSide = segmentSide( p1, p3, p2 );
485 if ( p1 != p3 && ( radius < 0 ||
qgsDoubleNear( segSide, 0.0 ) ) )
493 bool clockwise =
false;
499 double increment = fabs(
M_PI_2 / 90 );
502 double a1 = atan2( p1.
y() - centerY, p1.
x() - centerX );
503 double a2 = atan2( p2.
y() - centerY, p2.
x() - centerX );
504 double a3 = atan2( p3.
y() - centerY, p3.
x() - centerX );
532 if ( p2 != p3 && p1 != p2 )
542 x = centerX + radius * cos(
angle );
543 y = centerY + radius * sin(
angle );
545 if ( !hasZ && !hasM )
553 z = interpolateArc(
angle, a1, a2, a3, p1.
z(), p2.
z(), p3.
z() );
557 m = interpolateArc(
angle, a1, a2, a3, p1.
m(), p2.
m(), p3.
m() );
568 double side = (( pt2.
x() - pt1.
x() ) * ( pt3.
y() - pt1.
y() ) - ( pt3.
x() - pt1.
x() ) * ( pt2.
y() - pt1.
y() ) );
587 double QgsCircularStringV2::interpolateArc(
double angle,
double a1,
double a2,
double a3,
double zm1,
double zm2,
double zm3 )
const 593 return zm1 + ( zm2 - zm1 ) * (
angle - a1 ) / ( a2 - a1 );
595 return zm2 + ( zm3 - zm2 ) * (
angle - a2 ) / ( a3 - a2 );
601 return zm1 + ( zm2 - zm1 ) * ( a1 -
angle ) / ( a1 - a2 );
603 return zm2 + ( zm3 - zm2 ) * ( a2 -
angle ) / ( a2 - a3 );
618 double* zArray = mZ.
data();
624 zArray =
new double[nPoints];
625 for (
int i = 0; i < nPoints; ++i )
642 for (
int i = 0; i < nPoints; ++i )
645 t.
map( mX.
at( i ), mY.
at( i ), &x, &y );
652 void QgsCircularStringV2::clip(
const QgsRectangle& rect )
671 for (
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
675 for (
int j = 1; j < pt.
size(); ++j )
677 path.
lineTo( pt.
at( j ).x(), pt.
at( j ).y() );
683 if ( nPoints % 2 == 0 )
685 path.
lineTo( mX[ nPoints - 1 ], mY[ nPoints - 1 ] );
691 double centerX, centerY, radius;
693 radius, centerX, centerY );
698 double diameter = 2 * radius;
699 path.
arcTo( centerX - radius, centerY - radius, diameter, diameter, p1Angle, sweepAngle );
725 bool vertexNrEven = ( position.
vertex % 2 == 0 );
745 mX[position.
vertex] = newPos.
x();
746 mY[position.
vertex] = newPos.
y();
749 mZ[position.
vertex] = newPos.
z();
753 mM[position.
vertex] = newPos.
m();
766 if ( position.
vertex < 1 || position.
vertex > ( nVertices - 2 ) )
771 if ( position.
vertex < ( nVertices - 2 ) )
808 bool minDistLeftOf =
false;
810 double currentDist = 0.0;
813 for (
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
815 currentDist = closestPointOnArc( mX[i], mY[i], mX[i + 1], mY[i + 1], mX[i + 2], mY[i + 2], pt, segmentPt, vertexAfter, leftOf, epsilon );
816 if ( currentDist < minDist )
818 minDist = currentDist;
819 minDistSegmentPoint = segmentPt;
828 segmentPt = minDistSegmentPoint;
829 vertexAfter = minDistVertexAfter;
830 vertexAfter.
part = 0;
831 vertexAfter.
ring = 0;
834 *leftOf = minDistLeftOf;
854 for (
int i = 0; i < maxIndex; i += 2 )
868 sum += 0.5 * ( mX[i] * mY[i+2] - mY[i] * mX[i+2] );
871 double midPointX = ( p1.
x() + p3.
x() ) / 2.0;
872 double midPointY = ( p1.
y() + p3.
y() ) / 2.0;
874 double radius, centerX, centerY;
878 double r2 = radius * radius;
889 double cov = 0.5 - d * sqrt( r2 - d * d ) / (
M_PI * r2 ) - 1 /
M_PI * asin( d / radius );
890 double circleChordArea = 0;
891 if ( circlePointLeftOfLine == centerPointLeftOfLine )
893 circleChordArea =
M_PI * r2 * ( 1 - cov );
897 circleChordArea =
M_PI * r2 * cov;
900 if ( !circlePointLeftOfLine )
902 sum += circleChordArea;
906 sum -= circleChordArea;
911 double QgsCircularStringV2::closestPointOnArc(
double x1,
double y1,
double x2,
double y2,
double x3,
double y3,
914 double radius, centerX, centerY;
939 segmentPt = ( distPtPt1 <= distPtPt3 ) ? pt1 : pt3;
940 vertexAfter.
vertex = ( distPtPt1 <= distPtPt3 ) ? 1 : 2;
947 segmentPt.
setX( pt.
x() );
948 segmentPt.
setY( pt.
y() );
954 *
leftOf = clockwise ? sqrDistance > radius : sqrDistance < radius;
960 void QgsCircularStringV2::insertVertexBetween(
int after,
int before,
int pointOnCircle )
962 double xAfter = mX.
at( after );
963 double yAfter = mY.
at( after );
964 double xBefore = mX.
at( before );
965 double yBefore = mY.
at( before );
966 double xOnCircle = mX.
at( pointOnCircle );
967 double yOnCircle = mY.
at( pointOnCircle );
969 double radius, centerX, centerY;
972 double x = ( xAfter + xBefore ) / 2.0;
973 double y = ( yAfter + yBefore ) / 2.0;
976 mX.
insert( before, newVertex.
x() );
977 mY.
insert( before, newVertex.
y() );
981 mZ.
insert( before, ( mZ[after] + mZ[before] ) / 2.0 );
985 mM.
insert( before, ( mM[after] + mM[before] ) / 2.0 );
992 int before = vId.
vertex - 1;
994 int after = vId.
vertex + 1;
996 if ( vId.
vertex % 2 != 0 )
1030 int vertex1 = vId.
vertex - 2;
1031 int vertex2 = vId.
vertex - 1;
1032 int vertex3 = vId.
vertex;
1035 int vertex4 = vId.
vertex + 1;
1036 int vertex5 = vId.
vertex + 2;
1048 std::reverse( copy->mX.
begin(), copy->mX.
end() );
1049 std::reverse( copy->mY.
begin(), copy->mY.
end() );
1052 std::reverse( copy->mZ.
begin(), copy->mZ.
end() );
1056 std::reverse( copy->mM.
begin(), copy->mM.
end() );
1072 for (
int i = 0; i < nPoints; ++i )
1090 for (
int i = 0; i < nPoints; ++i )
virtual bool dropMValue() override
Drops any measure values which exist in the geometry.
QgsWKBTypes::Type wkbType() const
Returns the WKB type of 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...
QDomNode appendChild(const QDomNode &newChild)
double x() const
Returns the point's x-coordinate.
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.
const T & at(int i) const
virtual QgsLineStringV2 * curveToLine() const override
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
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.
QgsCurveV2 * segmentize() const override
Returns a geometry without curves.
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.
QDomElement createElementNS(const QString &nsURI, const QString &qName)
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
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.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
void setY(double y)
Sets the point's y-coordinate.
virtual double length() const override
Returns the length of the geometry.
QgsPointV2 pointN(int i) const
Returns the point at index i within the circular string.
double y() const
Returns the point's y-coordinate.
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal.
QgsWKBTypes::Type readHeader() const
virtual bool deleteVertex(QgsVertexId position) override
Deletes a vertex within the geometry.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
static bool circleClockwise(double angle1, double angle2, double angle3)
Returns true if circle is ordered clockwise.
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
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.
bool isMeasure() const
Returns true if the geometry contains m values.
double z() const
Returns the point's z-coordinate.
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.
Point geometry type, with support for z-dimension and m-values.
bool pointAt(int node, QgsPointV2 &point, QgsVertexId::VertexType &type) const override
Returns the point and vertex id of a point within the curve.
void transform(const QgsCoordinateTransform &ct, QgsCoordinateTransform::TransformDirection d=QgsCoordinateTransform::ForwardTransform) override
Transforms the geometry using a coordinate transform.
QgsWKBTypes::Type mWkbType
void sumUpArea(double &sum) const override
Calculates the area of the curve.
virtual bool moveVertex(QgsVertexId position, const QgsPointV2 &newPos) override
Moves a vertex within the geometry.
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.
virtual QString geometryType() const override
Returns a unique string representing the geometry type.
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 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 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.
double m() const
Returns the point's m value.
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.
static Type parseType(const QString &wktStr)
Attempts to extract the WKB type from a WKT string.
double ANALYSIS_EXPORT leftOf(Point3D *thepoint, Point3D *p1, Point3D *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'.
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)
QString asJSON(int precision=17) const override
Returns a GeoJSON representation of the geometry.
virtual bool operator==(const QgsCurveV2 &other) const override
int numPoints() const override
Returns the number of points in the curve.