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;
95 bool polygonType = ( geom.
dimension() == 2 );
100 if ( coords.
size() <= atVertex.
part )
128 else if ( atVertex.
vertex == 0 )
133 if ( polygonType && ring.
size() > 3 )
144 else if ( atVertex.
vertex == ring.
size() - 1 )
164 return ( pt1.
x() - pt2.
x() ) * ( pt1.
x() - pt2.
x() ) + ( pt1.
y() - pt2.
y() ) * ( pt1.
y() - pt2.
y() );
171 double ny = -( x2 - x1 );
174 t = ( ptX * ny - ptY * nx - x1 * ny + y1 * nx ) / (( x2 - x1 ) * ny - ( y2 - y1 ) * nx );
188 minDistX = x1 + t * ( x2 - x1 );
189 minDistY = y1 + t * ( y2 - y1 );
192 double dist = ( minDistX - ptX ) * ( minDistX - ptX ) + ( minDistY - ptY ) * ( minDistY - ptY );
207 double d = v.
y() * w.
x() - v.
x() * w.
y();
212 double dx = q1.
x() - p1.
x();
213 double dy = q1.
y() - p1.
y();
214 double k = ( dy * w.
x() - dx * w.
y() ) / d;
226 double wl = w.length();
228 if ( qFuzzyIsNull( vl ) || qFuzzyIsNull( wl ) )
238 double lambdav =
QgsVector( inter.
x() - p1.
x(), inter.
y() - p1.
y() ) * v;
239 if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
242 double lambdaw =
QgsVector( inter.
x() - q1.
x(), inter.
y() - q1.
y() ) * w;
243 if ( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance )
257 for (
int i = 0, j = 1; j < n; i = j++ )
265 int end = i == 0 && isClosed ? n - 1 : n;
266 for (
int k = start, l = start + 1; l < end; k = l++ )
282 intersections.
append( s );
285 return intersections;
294 return f1*f2 - f3*f4;
299 double dx = directionPoint.
x() - startPoint.
x();
300 double dy = directionPoint.
y() - startPoint.
y();
301 double length = sqrt( dx * dx + dy * dy );
308 double scaleFactor = distance / length;
309 return QgsPointV2( startPoint.
x() + dx * scaleFactor, startPoint.
y() + dy * scaleFactor );
314 double angle = atan2( dy, dx ) * 180 /
M_PI;
319 else if ( angle > 360 )
328 double dx21, dy21, dx31, dy31, h21, h31, d;
335 radius = sqrt( pow( pt2.
x() - pt1.
x(), 2.0 ) + pow( pt2.
y() - pt1.
y(), 2.0 ) );
340 dx21 = pt2.
x() - pt1.
x();
341 dy21 = pt2.
y() - pt1.
y();
342 dx31 = pt3.
x() - pt1.
x();
343 dy31 = pt3.
y() - pt1.
y();
345 h21 = pow( dx21, 2.0 ) + pow( dy21, 2.0 );
346 h31 = pow( dx31, 2.0 ) + pow( dy31, 2.0 );
349 d = 2 * ( dx21 * dy31 - dx31 * dy21 );
359 centerX = pt1.
x() + ( h21 * dy31 - h31 * dy21 ) / d;
360 centerY = pt1.
y() - ( h21 * dx31 - h31 * dx21 ) / d;
361 radius = sqrt( pow( centerX - pt1.
x(), 2.0 ) + pow( centerY - pt1.
y(), 2.0 ) );
366 if ( angle3 >= angle1 )
368 if ( angle2 > angle1 && angle2 < angle3 )
379 if ( angle2 > angle1 || angle2 < angle3 )
394 if ( angle2 < angle1 )
396 return ( angle <= angle1 && angle >= angle2 );
400 return ( angle <= angle1 || angle >= angle2 );
405 if ( angle2 > angle1 )
407 return ( angle >= angle1 && angle <= angle2 );
411 return ( angle >= angle1 || angle <= angle2 );
424 double centerX, centerY, radius;
426 double length =
M_PI / 180.0 * radius *
sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 );
440 if ( p3Angle >= p1Angle )
442 if ( p2Angle > p1Angle && p2Angle < p3Angle )
444 return( p3Angle - p1Angle );
448 return ( - ( p1Angle + ( 360 - p3Angle ) ) );
453 if ( p2Angle < p1Angle && p2Angle > p3Angle )
455 return( -( p1Angle - p3Angle ) );
459 return( p3Angle + ( 360 - p1Angle ) );
466 QgsPointV2 midPoint(( p1.
x() + p2.
x() ) / 2.0, ( p1.
y() + p2.
y() ) / 2.0 );
468 if ( radius < midDist )
472 double centerMidDist = sqrt( radius * radius - midDist * midDist );
473 double dist = radius - centerMidDist;
475 double midDx = midPoint.
x() - p1.
x();
476 double midDy = midPoint.
y() - p1.
y();
487 int minDistIndex = -1;
488 for (
int i = 0; i < possibleMidPoints.
size(); ++i )
490 double currentDist =
sqrDistance2D( mousePos, possibleMidPoints.
at( i ) );
491 if ( currentDist < minDist )
494 minDist = currentDist;
498 if ( minDistIndex == -1 )
503 result = possibleMidPoints.
at( minDistIndex );
511 double mX, mY, radius;
519 return lineAngle( tangentPoint.
x(), tangentPoint.
y(), mX, mY );
523 return lineAngle( mX, mY, tangentPoint.
x(), tangentPoint.
y() );
529 int dim = 2 + is3D + isMeasure;
531 QStringList coordList = wktCoordinateList.
split(
',', QString::SkipEmptyParts );
536 Q_FOREACH (
const QString& pointCoordinates, coordList )
538 QStringList coordinates = pointCoordinates.
split(
' ', QString::SkipEmptyParts );
539 if ( coordinates.
size() == 3 && !foundZ && !foundM && !is3D && !isMeasure )
545 else if ( coordinates.
size() >= 4 && ( !( is3D || foundZ ) || !( isMeasure || foundM ) ) )
554 Q_FOREACH (
const QString& pointCoordinates, coordList )
556 QStringList coordinates = pointCoordinates.
split(
' ', QString::SkipEmptyParts );
557 if ( coordinates.
size() < dim )
561 double x = coordinates[idx++].toDouble();
562 double y = coordinates[idx++].toDouble();
565 if (( is3D || foundZ ) && coordinates.
length() > idx )
566 z = coordinates[idx++].toDouble();
569 if (( isMeasure || foundM ) && coordinates.
length() > idx )
570 m = coordinates[idx++].toDouble();
573 if ( is3D || foundZ )
575 if ( isMeasure || foundM )
582 if ( isMeasure || foundM )
596 wkb << static_cast<quint32>( points.
size() );
599 wkb << point.
x() << point.
y();
639 if ( strCoordinates.
endsWith(
' ' ) )
640 strCoordinates.
chop( 1 );
643 return elemCoordinates;
649 elemPosList.
setAttribute(
"srsDimension", is3D ? 3 : 2 );
658 if ( strCoordinates.
endsWith(
' ' ) )
659 strCoordinates.
chop( 1 );
682 double clippedAngle =
angle;
683 if ( clippedAngle >=
M_PI * 2 || clippedAngle <= -2 *
M_PI )
685 clippedAngle = fmod( clippedAngle, 2 *
M_PI );
687 if ( clippedAngle < 0.0 )
689 clippedAngle += 2 *
M_PI;
698 QRegExp cooRegEx(
"^[^\\(]*\\((.*)\\)[^\\)]*$" );
700 return qMakePair( wkbType, contents );
708 for (
int i = 0, n = wkt.
length(); i < n; ++i )
710 if ( wkt[i].isSpace() && level == 0 )
713 if ( wkt[i] ==
',' && level == 0 )
718 block.
prepend( defaultType +
' ' );
726 else if ( wkt[i] ==
')' )
733 block.
prepend( defaultType +
' ' );
741 double at = atan2( y2 - y1, x2 - x1 );
742 double a = -at +
M_PI / 2.0;
765 double clockwiseDiff = 0.0;
768 clockwiseDiff = a2 - a1;
772 clockwiseDiff = a2 + ( 2 *
M_PI - a1 );
774 double counterClockwiseDiff = 2 *
M_PI - clockwiseDiff;
776 double resultAngle = 0;
777 if ( clockwiseDiff <= counterClockwiseDiff )
779 resultAngle = a1 + clockwiseDiff / 2.0;
783 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.
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 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)
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)
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.
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.
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 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.