24 #include <QStringList> 35 while ( ! geometries.
isEmpty() )
38 if (
const QgsCurveV2* curve = dynamic_cast< const QgsCurveV2* >( g ) )
40 linestrings << static_cast< QgsLineStringV2* >( curve->segmentize() );
44 for (
int i = 0; i < collection->numGeometries(); ++i )
46 geometries.
append( collection->geometryN( i ) );
49 else if (
const QgsCurvePolygonV2* curvePolygon = dynamic_cast< const QgsCurvePolygonV2* >( g ) )
51 if ( curvePolygon->exteriorRing() )
52 linestrings << static_cast< QgsLineStringV2* >( curvePolygon->exteriorRing()->segmentize() );
54 for (
int i = 0; i < curvePolygon->numInteriorRings(); ++i )
56 linestrings << static_cast< QgsLineStringV2* >( curvePolygon->interiorRing( i )->segmentize() );
66 double currentDist = 0;
80 if ( currentDist <= minDist )
82 minDist = currentDist;
83 minDistPoint = vertex;
84 id.part = vertexId.
part;
85 id.ring = vertexId.
ring;
86 id.vertex = vertexId.
vertex;
87 id.type = vertexId.
type;
96 double currentDist = 0;
109 previousVertex = vertex;
112 if ( vertexId ==
id )
125 double currentDist = 0;
135 nextVertex = previousVertex;
140 while ( currentDist < distance && geometry.
nextVertex( nextVertex, point ) )
150 previousVertex = nextVertex;
154 if ( currentDist > distance )
159 previousVertex = nextVertex;
160 previousPoint = point;
170 bool polygonType = ( geom.
dimension() == 2 );
175 if ( coords.
size() <= atVertex.
part )
203 else if ( atVertex.
vertex == 0 )
205 if ( ring.
size() > 1 )
215 if ( polygonType && ring.
size() > 3 )
226 else if ( atVertex.
vertex == ring.
size() - 1 )
246 return ( pt1.
x() - pt2.
x() ) * ( pt1.
x() - pt2.
x() ) + ( pt1.
y() - pt2.
y() ) * ( pt1.
y() - pt2.
y() );
259 double t = (( ptX - x1 ) * dx + ( ptY - y1 ) * dy ) / ( dx * dx + dy * dy );
275 double dist = dx * dx + dy * dy;
290 double d = v.
y() * w.
x() - v.
x() * w.
y();
295 double dx = q1.
x() - p1.
x();
296 double dy = q1.
y() - p1.
y();
297 double k = ( dy * w.
x() - dx * w.
y() ) / d;
309 double wl = w.length();
311 if ( qFuzzyIsNull( vl ) || qFuzzyIsNull( wl ) )
321 double lambdav =
QgsVector( inter.
x() - p1.
x(), inter.
y() - p1.
y() ) * v;
322 if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
325 double lambdaw =
QgsVector( inter.
x() - q1.
x(), inter.
y() - q1.
y() ) * w;
326 if ( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance )
340 for (
int i = 0, j = 1; j < n; i = j++ )
348 int end = i == 0 && isClosed ? n - 1 : n;
349 for (
int k = start, l = start + 1; l < end; k = l++ )
365 intersections.
append( s );
368 return intersections;
377 return f1*f2 - f3*f4;
382 double dx = directionPoint.
x() - startPoint.
x();
383 double dy = directionPoint.
y() - startPoint.
y();
384 double length = sqrt( dx * dx + dy * dy );
391 double scaleFactor = distance / length;
392 return QgsPointV2( startPoint.
x() + dx * scaleFactor, startPoint.
y() + dy * scaleFactor );
397 double angle = atan2( dy, dx ) * 180 /
M_PI;
402 else if ( angle > 360 )
411 double dx21, dy21, dx31, dy31, h21, h31, d;
416 centerX = ( pt1.
x() + pt2.
x() ) / 2.0;
417 centerY = ( pt1.
y() + pt2.
y() ) / 2.0;
418 radius = sqrt( pow( centerX - pt1.
x(), 2.0 ) + pow( centerY - pt1.
y(), 2.0 ) );
423 dx21 = pt2.
x() - pt1.
x();
424 dy21 = pt2.
y() - pt1.
y();
425 dx31 = pt3.
x() - pt1.
x();
426 dy31 = pt3.
y() - pt1.
y();
428 h21 = pow( dx21, 2.0 ) + pow( dy21, 2.0 );
429 h31 = pow( dx31, 2.0 ) + pow( dy31, 2.0 );
432 d = 2 * ( dx21 * dy31 - dx31 * dy21 );
442 centerX = pt1.
x() + ( h21 * dy31 - h31 * dy21 ) / d;
443 centerY = pt1.
y() - ( h21 * dx31 - h31 * dx21 ) / d;
444 radius = sqrt( pow( centerX - pt1.
x(), 2.0 ) + pow( centerY - pt1.
y(), 2.0 ) );
449 if ( angle3 >= angle1 )
451 if ( angle2 > angle1 && angle2 < angle3 )
462 if ( angle2 > angle1 || angle2 < angle3 )
477 if ( angle2 < angle1 )
479 return ( angle <= angle1 && angle >= angle2 );
483 return ( angle <= angle1 || angle >= angle2 );
488 if ( angle2 > angle1 )
490 return ( angle >= angle1 && angle <= angle2 );
494 return ( angle >= angle1 || angle <= angle2 );
507 double centerX, centerY, radius;
509 double length =
M_PI / 180.0 * radius *
sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 );
523 if ( p3Angle >= p1Angle )
525 if ( p2Angle > p1Angle && p2Angle < p3Angle )
527 return( p3Angle - p1Angle );
531 return ( - ( p1Angle + ( 360 - p3Angle ) ) );
536 if ( p2Angle < p1Angle && p2Angle > p3Angle )
538 return( -( p1Angle - p3Angle ) );
542 return( p3Angle + ( 360 - p1Angle ) );
549 QgsPointV2 midPoint(( p1.
x() + p2.
x() ) / 2.0, ( p1.
y() + p2.
y() ) / 2.0 );
551 if ( radius < midDist )
555 double centerMidDist = sqrt( radius * radius - midDist * midDist );
556 double dist = radius - centerMidDist;
558 double midDx = midPoint.
x() - p1.
x();
559 double midDy = midPoint.
y() - p1.
y();
570 int minDistIndex = -1;
571 for (
int i = 0; i < possibleMidPoints.
size(); ++i )
573 double currentDist =
sqrDistance2D( mousePos, possibleMidPoints.
at( i ) );
574 if ( currentDist < minDist )
577 minDist = currentDist;
581 if ( minDistIndex == -1 )
586 result = possibleMidPoints.
at( minDistIndex );
594 double mX, mY, radius;
602 return lineAngle( tangentPoint.
x(), tangentPoint.
y(), mX, mY );
606 return lineAngle( mX, mY, tangentPoint.
x(), tangentPoint.
y() );
612 int dim = 2 + is3D + isMeasure;
614 QStringList coordList = wktCoordinateList.
split(
',', QString::SkipEmptyParts );
619 Q_FOREACH (
const QString& pointCoordinates, coordList )
621 QStringList coordinates = pointCoordinates.
split(
' ', QString::SkipEmptyParts );
622 if ( coordinates.
size() == 3 && !foundZ && !foundM && !is3D && !isMeasure )
628 else if ( coordinates.
size() >= 4 && ( !( is3D || foundZ ) || !( isMeasure || foundM ) ) )
637 Q_FOREACH (
const QString& pointCoordinates, coordList )
639 QStringList coordinates = pointCoordinates.
split(
' ', QString::SkipEmptyParts );
640 if ( coordinates.
size() < dim )
644 double x = coordinates[idx++].toDouble();
645 double y = coordinates[idx++].toDouble();
648 if (( is3D || foundZ ) && coordinates.
length() > idx )
649 z = coordinates[idx++].toDouble();
652 if (( isMeasure || foundM ) && coordinates.
length() > idx )
653 m = coordinates[idx++].toDouble();
656 if ( is3D || foundZ )
658 if ( isMeasure || foundM )
665 if ( isMeasure || foundM )
679 wkb << static_cast<quint32>( points.
size() );
682 wkb << point.
x() << point.
y();
730 if ( strCoordinates.
endsWith( ts ) )
731 strCoordinates.
chop( 1 );
734 return elemCoordinates;
740 elemPosList.
setAttribute(
"srsDimension", is3D ? 3 : 2 );
749 if ( strCoordinates.
endsWith(
' ' ) )
750 strCoordinates.
chop( 1 );
773 double clippedAngle =
angle;
774 if ( clippedAngle >=
M_PI * 2 || clippedAngle <= -2 *
M_PI )
776 clippedAngle = fmod( clippedAngle, 2 *
M_PI );
778 if ( clippedAngle < 0.0 )
780 clippedAngle += 2 *
M_PI;
789 QRegExp cooRegEx(
"^[^\\(]*\\((.*)\\)[^\\)]*$" );
791 return qMakePair( wkbType, contents );
799 for (
int i = 0, n = wkt.
length(); i < n; ++i )
801 if ( wkt[i].isSpace() && level == 0 )
804 if ( wkt[i] ==
',' && level == 0 )
809 block.
prepend( defaultType +
' ' );
817 else if ( wkt[i] ==
')' )
824 block.
prepend( defaultType +
' ' );
832 double at = atan2( y2 - y1, x2 - x1 );
833 double a = -at +
M_PI / 2.0;
856 double clockwiseDiff = 0.0;
859 clockwiseDiff = a2 - a1;
863 clockwiseDiff = a2 + ( 2 *
M_PI - a1 );
865 double counterClockwiseDiff = 2 *
M_PI - clockwiseDiff;
867 double resultAngle = 0;
868 if ( clockwiseDiff <= counterClockwiseDiff )
870 resultAngle = a1 + clockwiseDiff / 2.0;
874 resultAngle = a1 - counterClockwiseDiff / 2.0;
static QgsPointV2 pointOnLineWithDistance(const QgsPointV2 &startPoint, const QgsPointV2 &directionPoint, double distance)
Returns a point a specified distance toward a second point.
QString cap(int nth) const
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) ...
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 (...
static bool circleAngleBetween(double angle, double angle1, double angle2, bool clockwise)
Returns true if, in a circle, angle is between angle1 and angle2.
static bool verticesAtDistance(const QgsAbstractGeometryV2 &geometry, double distance, QgsVertexId &previousVertex, QgsVertexId &nextVertex)
Retrieves the vertices which are before and after the interpolated point at a specified distance alon...
virtual QgsCoordinateSequenceV2 coordinateSequence() const =0
Retrieves the sequence of geometries, rings and nodes.
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)
static double lineAngle(double x1, double y1, double x2, double y2)
Calculates the direction of line joining two points in radians, clockwise from the north direction...
void append(const T &value)
static double distanceToVertex(const QgsAbstractGeometryV2 &geom, const QgsVertexId &id)
Returns the distance along a geometry from its first vertex to the specified vertex.
static double averageAngle(double x1, double y1, double x2, double y2, double x3, double y3)
Angle between two linear segments.
static void pointsToWKB(QgsWkbPtr &wkb, const QgsPointSequenceV2 &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QString & prepend(QChar ch)
static bool lineIntersection(const QgsPointV2 &p1, QgsVector v, const QgsPointV2 &q1, QgsVector w, QgsPointV2 &inter)
Compute the intersection between two lines.
const T & at(int i) const
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.
static QString pointsToJSON(const QgsPointSequenceV2 &points, int precision)
Returns a geoJSON coordinates string.
Abstract base class for all geometries.
static double linePerpendicularAngle(double x1, double y1, double x2, double y2)
Calculates the perpendicular angle to a line joining two points.
static QStringList wktGetChildBlocks(const QString &wkt, const QString &defaultType="")
Parses a WKT string and returns of list of blocks contained in the WKT.
static QgsPointV2 closestVertex(const QgsAbstractGeometryV2 &geom, const QgsPointV2 &pt, QgsVertexId &id)
Returns the closest vertex to a geometry for a specified 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.
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)
double z() const
Returns the point's z-coordinate.
double y() const
Returns the point's y-coordinate.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal.
int indexIn(const QString &str, int offset, CaretMode caretMode) const
static bool circleClockwise(double angle1, double angle2, double angle3)
Returns true if circle is ordered clockwise.
void append(const T &value)
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.
static QString pointsToWKT(const QgsPointSequenceV2 &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
static QList< SelfIntersection > getSelfIntersections(const QgsAbstractGeometryV2 *geom, int part, int ring, double tolerance)
Find self intersections in a polyline.
void setAttribute(const QString &name, const QString &value)
Point geometry type, with support for z-dimension and m-values.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
double x() const
Returns the point's x-coordinate.
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
static void adjacentVertices(const QgsAbstractGeometryV2 &geom, QgsVertexId atVertex, QgsVertexId &beforeVertex, QgsVertexId &afterVertex)
Returns vertices adjacent to a specified vertex within a geometry.
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.
static bool segmentIntersection(const QgsPointV2 &p1, const QgsPointV2 &p2, const QgsPointV2 &q1, const QgsPointV2 &q2, QgsPointV2 &inter, double tolerance)
Compute the intersection between two segments.
virtual bool nextVertex(QgsVertexId &id, QgsPointV2 &vertex) const =0
Returns next vertex id and coordinates.
static double normalizedAngle(double angle)
Ensures that an angle is in the range 0 <= angle < 2 pi.
static QDomElement pointsToGML3(const QgsPointSequenceV2 &points, QDomDocument &doc, int precision, const QString &ns, bool is3D)
Returns a gml::posList DOM element.
double length() const
Returns the length of the vector.
QDomText createTextNode(const QString &value)
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)
A class to represent a vector.
const T & at(int i) const
static bool segmentMidPoint(const QgsPointV2 &p1, const QgsPointV2 &p2, QgsPointV2 &result, double radius, const QgsPointV2 &mousePos)
Calculates midpoint on circle passing through p1 and p2, closest to given coordinate.
static QList< QgsLineStringV2 * > extractLineStrings(const QgsAbstractGeometryV2 *geom)
Returns list of linestrings extracted from the passed geometry.
static QgsPointSequenceV2 pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string.
virtual int vertexCount(int part=0, int ring=0) const =0
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.
virtual int dimension() const =0
Returns the inherent dimension of the geometry.
static double sqrDistToLine(double ptX, double ptY, double x1, double y1, double x2, double y2, double &minDistX, double &minDistY, double epsilon)
Returns the squared distance between a point and a line.
double x() const
Returns the vector's x-component.
static Type parseType(const QString &wktStr)
Attempts to extract the WKB type from a WKT string.
Curve polygon geometry type.
Abstract base class for curved geometry type.
double y() const
Returns the vector's y-component.
double m() const
Returns the point's m value.
static QDomElement pointsToGML2(const QgsPointSequenceV2 &points, QDomDocument &doc, int precision, const QString &ns)
Returns a gml::coordinates DOM element.
virtual QgsPointV2 vertexAt(QgsVertexId id) const =0
Returns the point corresponding to a specified vertex id.