18 #include <QStringList>
23 double currentDist = 0;
36 if ( currentDist <= minDist )
38 minDist = currentDist;
39 minDistPoint = vertex;
40 id.part = vertexId.
part;
41 id.ring = vertexId.
ring;
42 id.vertex = vertexId.
vertex;
51 bool polygonType = ( geom.
dimension() == 2 );
56 if ( coords.
size() <= atVertex.
part )
79 else if ( atVertex.
vertex == 0 )
82 if ( polygonType && ring.
size() > 3 )
107 return ( pt1.
x() - pt2.
x() ) * ( pt1.
x() - pt2.
x() ) + ( pt1.
y() - pt2.
y() ) * ( pt1.
y() - pt2.
y() );
114 double ny = -( x2 - x1 );
117 t = ( ptX * ny - ptY * nx - x1 * ny + y1 * nx ) / (( x2 - x1 ) * ny - ( y2 - y1 ) * nx );
131 minDistX = x1 + t * ( x2 - x1 );
132 minDistY = y1 + t * ( y2 - y1 );
135 double dist = ( minDistX - ptX ) * ( minDistX - ptX ) + ( minDistY - ptY ) * ( minDistY - ptY );
150 double d = v.
y() * w.
x() - v.
x() * w.
y();
155 double dx = q1.
x() - p1.
x();
156 double dy = q1.
y() - p1.
y();
157 double k = ( dy * w.
x() - dx * w.
y() ) / d;
169 double wl = w.length();
171 if ( qFuzzyIsNull( vl ) || qFuzzyIsNull( wl ) )
181 double lambdav =
QgsVector( inter.
x() - p1.
x(), inter.
y() - p1.
y() ) * v;
182 if ( lambdav < 0. + tolerance || lambdav > vl - tolerance )
185 double lambdaw =
QgsVector( inter.
x() - q1.
x(), inter.
y() - q1.
y() ) * w;
186 if ( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance )
200 for (
int i = 0, j = 1; j < n; i = j++ )
208 int end = i == 0 && isClosed ? n - 1 : n;
209 for (
int k = start, l = start + 1; l < end; k = l++ )
225 intersections.
append( s );
228 return intersections;
237 return f1*f2 - f3*f4;
242 double dx = directionPoint.
x() - startPoint.
x();
243 double dy = directionPoint.
y() - startPoint.
y();
244 double length = sqrt( dx * dx + dy * dy );
251 double scaleFactor = distance / length;
252 return QgsPointV2( startPoint.
x() + dx * scaleFactor, startPoint.
y() + dy * scaleFactor );
257 double angle = atan2( dy, dx ) * 180 /
M_PI;
262 else if ( angle > 360 )
271 double temp, bc, cd, det;
278 radius = sqrt( pow( pt2.
x() - pt1.
x(), 2.0 ) + pow( pt2.
y() - pt1.
y(), 2.0 ) );
282 temp = pt2.
x() * pt2.
x() + pt2.
y() * pt2.
y();
283 bc = ( pt1.
x() * pt1.
x() + pt1.
y() * pt1.
y() - temp ) / 2.0;
284 cd = ( temp - pt3.
x() * pt3.
x() - pt3.
y() * pt3.
y() ) / 2.0;
285 det = ( pt1.
x() - pt2.
x() ) * ( pt2.
y() - pt3.
y() ) - ( pt2.
x() - pt3.
x() ) * ( pt1.
y() - pt2.
y() );
295 centerX = ( bc * ( pt2.
y() - pt3.
y() ) - cd * ( pt1.
y() - pt2.
y() ) ) * det;
296 centerY = (( pt1.
x() - pt2.
x() ) * cd - ( pt2.
x() - pt3.
x() ) * bc ) * det;
297 radius = sqrt(( centerX - pt1.
x() ) * ( centerX - pt1.
x() ) + ( centerY - pt1.
y() ) * ( centerY - pt1.
y() ) );
302 if ( angle3 >= angle1 )
304 if ( angle2 > angle1 && angle2 < angle3 )
315 if ( angle2 > angle1 || angle2 < angle3 )
330 if ( angle2 < angle1 )
332 return ( angle <= angle1 && angle >= angle2 );
336 return ( angle <= angle1 || angle >= angle2 );
341 if ( angle2 > angle1 )
343 return ( angle >= angle1 && angle <= angle2 );
347 return ( angle >= angle1 || angle <= angle2 );
360 double centerX, centerY, radius;
362 double length =
M_PI / 180.0 * radius *
sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 );
376 if ( p3Angle >= p1Angle )
378 if ( p2Angle > p1Angle && p2Angle < p3Angle )
380 return( p3Angle - p1Angle );
384 return ( - ( p1Angle + ( 360 - p3Angle ) ) );
389 if ( p2Angle < p1Angle && p2Angle > p3Angle )
391 return( -( p1Angle - p3Angle ) );
395 return( p3Angle + ( 360 - p1Angle ) );
402 QgsPointV2 midPoint(( p1.
x() + p2.
x() ) / 2.0, ( p1.
y() + p2.
y() ) / 2.0 );
404 if ( radius < midDist )
408 double centerMidDist = sqrt( radius * radius - midDist * midDist );
409 double dist = radius - centerMidDist;
411 double midDx = midPoint.
x() - p1.
x();
412 double midDy = midPoint.
y() - p1.
y();
423 int minDistIndex = -1;
424 for (
int i = 0; i < possibleMidPoints.
size(); ++i )
426 double currentDist =
sqrDistance2D( mousePos, possibleMidPoints.
at( i ) );
427 if ( currentDist < minDist )
430 minDist = currentDist;
434 if ( minDistIndex == -1 )
439 result = possibleMidPoints.
at( minDistIndex );
447 double mX, mY, radius;
455 return lineAngle( tangentPoint.
x(), tangentPoint.
y(), mX, mY );
459 return lineAngle( mX, mY, tangentPoint.
x(), tangentPoint.
y() );
465 int dim = 2 + is3D + isMeasure;
467 QStringList coordList = wktCoordinateList.
split(
",", QString::SkipEmptyParts );
472 Q_FOREACH (
const QString& pointCoordinates, coordList )
474 QStringList coordinates = pointCoordinates.
split(
" ", QString::SkipEmptyParts );
475 if ( coordinates.
size() == 3 && !foundZ && !foundM && !is3D && !isMeasure )
481 else if ( coordinates.
size() >= 4 && ( !( is3D || foundZ ) || !( isMeasure || foundM ) ) )
490 Q_FOREACH (
const QString& pointCoordinates, coordList )
492 QStringList coordinates = pointCoordinates.
split(
" ", QString::SkipEmptyParts );
493 if ( coordinates.
size() < dim )
497 double x = coordinates[idx++].toDouble();
498 double y = coordinates[idx++].toDouble();
501 if (( is3D || foundZ ) && coordinates.
length() >= idx )
502 z = coordinates[idx++].toDouble();
505 if (( isMeasure || foundM ) && coordinates.
length() >= idx )
506 m = coordinates[idx++].toDouble();
509 if ( is3D || foundZ )
511 if ( isMeasure || foundM )
518 if ( isMeasure || foundM )
532 wkb << static_cast<quint32>( points.
size() );
535 wkb << point.
x() << point.
y();
575 if ( strCoordinates.
endsWith(
" " ) )
576 strCoordinates.
chop( 1 );
579 return elemCoordinates;
585 elemPosList.
setAttribute(
"srsDimension", is3D ? 3 : 2 );
594 if ( strCoordinates.
endsWith(
" " ) )
595 strCoordinates.
chop( 1 );
620 QRegExp cooRegEx(
"^[^\\(]*\\((.*)\\)[^\\)]*$" );
622 return qMakePair( wkbType, contents );
630 for (
int i = 0, n = wkt.
length(); i < n; ++i )
632 if ( wkt[i].isSpace() && level == 0 )
635 if ( wkt[i] ==
',' && level == 0 )
640 block.
prepend( defaultType +
" " );
648 else if ( wkt[i] ==
')' )
655 block.
prepend( defaultType +
" " );
663 double at = atan2( y2 - y1, x2 - x1 );
664 double a = -at +
M_PI / 2.0;
697 double clockwiseDiff = 0.0;
700 clockwiseDiff = a2 - a1;
704 clockwiseDiff = a2 + ( 2 *
M_PI - a1 );
706 double counterClockwiseDiff = 2 *
M_PI - clockwiseDiff;
708 double resultAngle = 0;
709 if ( clockwiseDiff <= counterClockwiseDiff )
711 resultAngle = a1 + clockwiseDiff / 2.0;
715 resultAngle = a1 - counterClockwiseDiff / 2.0;
718 if ( resultAngle >= 2 *
M_PI )
720 resultAngle -= 2 *
M_PI;
722 else if ( resultAngle < 0 )
724 resultAngle = 2 *
M_PI - resultAngle;
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 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 direction of line (clockwise from north direction) in radians.
static double averageAngle(double x1, double y1, double x2, double y2, double x3, double y3)
Angle between two linear segments.
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QString & prepend(QChar ch)
static QString pointsToWKT(const QList< QgsPointV2 > &points, int precision, bool is3D, bool isMeasure)
Returns a WKT coordinate list.
const T & at(int i) const
static QString pointsToJSON(const QList< QgsPointV2 > &points, int precision)
Returns a geoJSON coordinates string.
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.
static double linePerpendicularAngle(double x1, double y1, double x2, double y2)
Calculates angle perpendicular to line.
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)
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 void adjacentVertices(const QgsAbstractGeometryV2 &geom, const QgsVertexId &atVertex, QgsVertexId &beforeVertex, QgsVertexId &afterVertex)
Returns vertices adjacent to a specified vertex within a geometry.
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 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)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
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.
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.
static QDomElement pointsToGML3(const QList< QgsPointV2 > &points, QDomDocument &doc, int precision, const QString &ns, bool is3D)
Returns a gml::posList DOM element.
virtual QgsPointV2 vertexAt(const QgsVertexId &id) const =0
Returns the point corresponding to a specified vertex id.
QString qgsDoubleToString(const double &a, const int &precision=17)
static bool lineIntersection(const QgsPointV2 &p1, const QgsVector &v, const QgsPointV2 &q1, const QgsVector &w, QgsPointV2 &inter)
Compute the intersection between two lines.
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.
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 QList< QgsPointV2 > pointsFromWKT(const QString &wktCoordinateList, bool is3D, bool isMeasure)
Returns a list of points contained in a WKT string.
virtual void coordinateSequence(QList< QList< QList< QgsPointV2 > > > &coord) const =0
Retrieves the sequence of geometries, rings and nodes.
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)
static void pointsToWKB(QgsWkbPtr &wkb, const QList< QgsPointV2 > &points, bool is3D, bool isMeasure)
Returns a LinearRing { uint32 numPoints; Point points[numPoints]; }.
static QDomElement pointsToGML2(const QList< QgsPointV2 > &points, QDomDocument &doc, int precision, const QString &ns)
Returns a gml::coordinates DOM element.