27 #include <QPainterPath>
57 for (
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
74 double centerX, centerY, radius;
97 QList<QgsPointV2> compassPoints = compassPointsOnSegment( p1Angle, p2Angle, p3Angle, centerX, centerY, radius );
99 for ( ; cpIt != compassPoints.
constEnd(); ++cpIt )
101 bbox.combineExtentWith( cpIt->x(), cpIt->y() );
106 QList<QgsPointV2> QgsCircularStringV2::compassPointsOnSegment(
double p1Angle,
double p2Angle,
double p3Angle,
double centerX,
double centerY,
double radius )
110 QgsPointV2 nPoint( centerX, centerY + radius );
111 QgsPointV2 ePoint( centerX + radius, centerY );
112 QgsPointV2 sPoint( centerX, centerY - radius );
113 QgsPointV2 wPoint( centerX - radius, centerY );
115 if ( p3Angle >= p1Angle )
117 if ( p2Angle > p1Angle && p2Angle < p3Angle )
119 if ( p1Angle <= 90 && p3Angle >= 90 )
121 pointList.
append( nPoint );
123 if ( p1Angle <= 180 && p3Angle >= 180 )
125 pointList.
append( wPoint );
127 if ( p1Angle <= 270 && p3Angle >= 270 )
129 pointList.
append( sPoint );
134 pointList.
append( ePoint );
135 if ( p1Angle >= 90 || p3Angle <= 90 )
137 pointList.
append( nPoint );
139 if ( p1Angle >= 180 || p3Angle <= 180 )
141 pointList.
append( wPoint );
143 if ( p1Angle >= 270 || p3Angle <= 270 )
145 pointList.
append( sPoint );
151 if ( p2Angle < p1Angle && p2Angle > p3Angle )
153 if ( p1Angle >= 270 && p3Angle <= 270 )
155 pointList.
append( sPoint );
157 if ( p1Angle >= 180 && p3Angle <= 180 )
159 pointList.
append( wPoint );
161 if ( p1Angle >= 90 && p3Angle <= 90 )
163 pointList.
append( nPoint );
168 pointList.
append( ePoint );
169 if ( p1Angle <= 270 || p3Angle >= 270 )
171 pointList.
append( sPoint );
173 if ( p1Angle <= 180 || p3Angle >= 180 )
175 pointList.
append( wPoint );
177 if ( p1Angle <= 90 || p3Angle >= 90 )
179 pointList.
append( nPoint );
210 for (
int i = 0; i < nVertices; ++i )
243 int size =
sizeof( char ) +
sizeof( quint32 ) +
sizeof( quint32 );
251 unsigned char* geomPtr =
new unsigned char[binarySize];
254 wkb << static_cast<quint32>(
wkbType() );
307 for (
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
338 for (
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
349 return qMin( mX.
size(), mY.
size() );
354 if ( qMin( mX.
size(), mY.
size() ) <= i )
359 double x = mX.
at( i );
360 double y = mY.
at( i );
393 for (
int i = 0; i < nPts; ++i )
401 if ( points.
size() < 1 )
409 bool hasZ = firstPt.
is3D();
433 for (
int i = 0; i < points.
size(); ++i )
435 mX[i] = points[i].x();
436 mY[i] = points[i].y();
439 mZ[i] = points[i].z();
443 mM[i] = points[i].m();
455 int segSide = segmentSide( p1, p3, p2 );
465 bool clockwise =
false;
471 double increment = fabs(
M_PI_2 / 90 );
474 double a1 = atan2( p1.
y() - centerY, p1.
x() - centerX );
475 double a2 = atan2( p2.
y() - centerY, p2.
x() - centerX );
476 double a3 = atan2( p3.
y() - centerY, p3.
x() - centerX );
504 if ( p2 != p3 && p1 != p2 )
508 x = centerX + radius * cos(
angle );
509 y = centerY + radius * sin(
angle );
511 if ( !hasZ && !hasM )
519 z = interpolateArc(
angle, a1, a2, a3, p1.
z(), p2.
z(), p3.
z() );
523 m = interpolateArc(
angle, a1, a2, a3, p1.
m(), p2.
m(), p3.
m() );
534 double side = (( pt2.
x() - pt1.
x() ) * ( pt3.
y() - pt1.
y() ) - ( pt3.
x() - pt1.
x() ) * ( pt2.
y() - pt1.
y() ) );
553 double QgsCircularStringV2::interpolateArc(
double angle,
double a1,
double a2,
double a3,
double zm1,
double zm2,
double zm3 )
const
559 return zm1 + ( zm2 - zm1 ) * ( angle - a1 ) / ( a2 - a1 );
561 return zm2 + ( zm3 - zm2 ) * ( angle - a2 ) / ( a3 - a2 );
567 return zm1 + ( zm2 - zm1 ) * ( a1 - angle ) / ( a1 - a2 );
569 return zm2 + ( zm3 - zm2 ) * ( a2 - angle ) / ( a2 - a3 );
582 double* zArray = mZ.
data();
588 zArray =
new double[nPoints];
589 for (
int i = 0; i < nPoints; ++i )
604 for (
int i = 0; i < nPoints; ++i )
608 t.
map( mX[i], mY[i], &x, &y );
609 mX[i] = x; mY[i] = y;
611 t.
map( mX[i], mY[i], &mX[i], &mY[i] );
617 void QgsCircularStringV2::clip(
const QgsRectangle& rect )
636 for (
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
640 for (
int j = 1; j < pt.
size(); ++j )
642 path.
lineTo( pt.
at( j ).x(), pt.
at( j ).y() );
650 double centerX, centerY, radius;
652 radius, centerX, centerY );
657 double diameter = 2 * radius;
658 path.
arcTo( centerX - radius, centerY - radius, diameter, diameter, p1Angle, sweepAngle );
684 bool vertexNrEven = ( position.
vertex % 2 == 0 );
703 mX[position.
vertex] = newPos.
x();
704 mY[position.
vertex] = newPos.
y();
707 mZ[position.
vertex] = newPos.
z();
711 mM[position.
vertex] = newPos.
m();
724 if ( position.
vertex < 1 || position.
vertex > ( nVertices - 2 ) )
729 if ( position.
vertex < ( nVertices - 2 ) )
764 bool minDistLeftOf =
false;
766 double currentDist = 0.0;
769 for (
int i = 0; i < ( nPoints - 2 ) ; i += 2 )
771 currentDist = closestPointOnArc( mX[i], mY[i], mX[i + 1], mY[i + 1], mX[i + 2], mY[i + 2], pt, segmentPt, vertexAfter, leftOf, epsilon );
772 if ( currentDist < minDist )
774 minDist = currentDist;
775 minDistSegmentPoint = segmentPt;
784 segmentPt = minDistSegmentPoint;
785 vertexAfter = minDistVertexAfter;
786 vertexAfter.
part = 0; vertexAfter.
ring = 0;
789 *leftOf = minDistLeftOf;
809 for (
int i = 0; i < maxIndex; i += 2 )
823 sum += 0.5 * ( mX[i] * mY[i+2] - mY[i] * mX[i+2] );
826 double midPointX = ( p1.
x() + p3.
x() ) / 2.0;
827 double midPointY = ( p1.
y() + p3.
y() ) / 2.0;
829 double radius, centerX, centerY;
833 double r2 = radius * radius;
844 double cov = 0.5 - d * sqrt( r2 - d * d ) / (
M_PI * r2 ) - 1 /
M_PI * asin( d / radius );
845 double circleChordArea = 0;
846 if ( circlePointLeftOfLine == centerPointLeftOfLine )
848 circleChordArea =
M_PI * r2 * ( 1 - cov );
852 circleChordArea =
M_PI * r2 * cov;
855 if ( !circlePointLeftOfLine )
857 sum += circleChordArea;
861 sum -= circleChordArea;
866 double QgsCircularStringV2::closestPointOnArc(
double x1,
double y1,
double x2,
double y2,
double x3,
double y3,
869 double radius, centerX, centerY;
894 segmentPt = ( distPtPt1 <= distPtPt3 ) ? pt1 : pt3;
895 vertexAfter.
vertex = ( distPtPt1 <= distPtPt3 ) ? 1 : 2;
902 segmentPt.
setX( pt.
x() );
903 segmentPt.
setY( pt.
y() );
909 *leftOf = clockwise ? sqrDistance > radius : sqrDistance < radius;
915 void QgsCircularStringV2::insertVertexBetween(
int after,
int before,
int pointOnCircle )
917 double xAfter = mX[after];
918 double yAfter = mY[after];
919 double xBefore = mX[before];
920 double yBefore = mY[before];
921 double xOnCircle = mX[ pointOnCircle ];
922 double yOnCircle = mY[ pointOnCircle ];
924 double radius, centerX, centerY;
927 double x = ( xAfter + xBefore ) / 2.0;
928 double y = ( yAfter + yBefore ) / 2.0;
931 mX.
insert( before, newVertex.
x() );
932 mY.
insert( before, newVertex.
y() );
936 mZ.
insert( before, ( mZ[after] + mZ[before] ) / 2.0 );
940 mM.
insert( before, ( mM[after] + mM[before] ) / 2.0 );
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.
virtual QgsRectangle calculateBoundingBox() const override
Calculates 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.
virtual bool fromWkb(const unsigned char *wkb) override
Sets the geometry from a WKB string.
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)
void push_back(const T &value)
virtual QgsAbstractGeometryV2 * clone() const override
Clones the geometry by performing a deep copy.
virtual bool fromWkt(const QString &wkt) override
Sets the geometry from a WKT string.
const T & at(int i) const
static QString pointsToWKT(const QList< QgsPointV2 > &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
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.
Abstract base class for all geometries.
void moveTo(const QPointF &point)
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.
QDomElement createElementNS(const QString &nsURI, const QString &qName)
static endian_t endian()
Returns whether this machine uses big or little endian.
QString wktTypeStr() const
Returns the WKT type string of the geometry.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
virtual double length() const override
Returns the length (or perimeter for area geometries) of the geometry.
QgsPointV2 pointN(int i) const
Returns the point at index i within the circular string.
QgsWKBTypes::Type readHeader() const
static Type flatType(Type type)
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)
void drawAsPolygon(QPainter &p) const override
Draws the curve as a polygon on the specified QPainter.
void setPoints(const QList< QgsPointV2 > &points)
Sets the circular string's points.
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.
QDomElement asGML2(QDomDocument &doc, int precision=17, const QString &ns="gml") const override
Returns a GML2 representation of the geometry.
Line string geometry type.
void lineTo(const QPointF &endPoint)
QgsWKBTypes::Type mWkbType
void sumUpArea(double &sum) const override
Calculates the area of the curve.
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 bool deleteVertex(const QgsVertexId &position) override
Deletes a vertex within the geometry.
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)
static QDomElement pointsToGML3(const QList< QgsPointV2 > &points, QDomDocument &doc, int precision, const QString &ns, bool is3D)
Returns a gml::posList DOM element.
virtual bool insertVertex(const QgsVertexId &position, const QgsPointV2 &vertex) override
Inserts a vertex into the geometry.
virtual bool moveVertex(const QgsVertexId &position, const QgsPointV2 &newPos) override
Moves a vertex within the geometry.
virtual QgsPointV2 endPoint() const override
Returns the end point of the curve.
const T & at(int i) const
bool pointAt(int i, QgsPointV2 &vertex, QgsVertexId::VertexType &type) const override
Returns the point and vertex id of a point within the curve.
void points(QList< QgsPointV2 > &pts) const override
Returns a list of points within the curve.
void drawPath(const QPainterPath &path)
void setPoints(const QList< QgsPointV2 > &points)
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 transform(const QgsCoordinateTransform &ct) override
Transforms the geometry using a coordinate transform.
QgsAbstractGeometryV2 * segmentize() const override
Returns a version of the geometry without curves.
void draw(QPainter &p) const override
Draws the geometry using the specified QPainter.
static QList< QgsPointV2 > pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string.
QgsRectangle mBoundingBox
static Type parseType(const QString &wktStr)
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.
static void pointsToWKB(QgsWkbPtr &wkb, const QList< QgsPointV2 > &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
void arcTo(const QRectF &rectangle, qreal startAngle, qreal sweepLength)
QString asJSON(int precision=17) const override
Returns a GeoJSON representation of the geometry.
int numPoints() const override
Returns the number of points in the curve.