QgsRectangle QgsCircularString::calculateBoundingBox() const { QgsRectangle bbox; int nPoints = numPoints(); for ( int i = 0; i < ( nPoints - 2 ) ; i += 2 ) { if ( i == 0 ) { bbox = segmentBoundingBox( QgsPointV2( mX[i], mY[i] ), QgsPointV2( mX[i + 1], mY[i + 1] ), QgsPointV2( mX[i + 2], mY[i + 2] ) ); } else { QgsRectangle segmentBox = segmentBoundingBox( QgsPointV2( mX[i], mY[i] ), QgsPointV2( mX[i + 1], mY[i + 1] ), QgsPointV2( mX[i + 2], mY[i + 2] ) ); bbox.combineExtentWith( segmentBox ); } } if ( nPoints > 0 && nPoints % 2 == 0 ) { if ( nPoints == 2 ) { bbox.combineExtentWith( mX[ 0 ], mY[ 0 ] ); } bbox.combineExtentWith( mX[ nPoints - 1 ], mY[ nPoints - 1 ] ); } return bbox; }
//! Generalize the WKB-geometry using the BBOX of the original geometry static QgsGeometry generalizeWkbGeometryByBoundingBox( QgsWkbTypes::Type wkbType, const QgsAbstractGeometry& geometry, const QgsRectangle &envelope ) { unsigned int geometryType = QgsWkbTypes::singleType( QgsWkbTypes::flatType( wkbType ) ); // If the geometry is already minimal skip the generalization int minimumSize = geometryType == QgsWkbTypes::LineString ? 2 : 5; if ( geometry.nCoordinates() <= minimumSize ) { return QgsGeometry( geometry.clone() ); } const double x1 = envelope.xMinimum(); const double y1 = envelope.yMinimum(); const double x2 = envelope.xMaximum(); const double y2 = envelope.yMaximum(); // Write the generalized geometry if ( geometryType == QgsWkbTypes::LineString ) { QgsLineString* lineString = new QgsLineString(); lineString->addVertex( QgsPointV2( x1, y1 ) ); lineString->addVertex( QgsPointV2( x2, y2 ) ); return QgsGeometry( lineString ); } else { return QgsGeometry::fromRect( envelope ); } }
void QgsCircularString::addToPainterPath( QPainterPath &path ) const { int nPoints = numPoints(); if ( nPoints < 1 ) { return; } if ( path.isEmpty() || path.currentPosition() != QPointF( mX[0], mY[0] ) ) { path.moveTo( QPointF( mX[0], mY[0] ) ); } for ( int i = 0; i < ( nPoints - 2 ) ; i += 2 ) { QgsPointSequence pt; segmentize( QgsPointV2( mX[i], mY[i] ), QgsPointV2( mX[i + 1], mY[i + 1] ), QgsPointV2( mX[i + 2], mY[i + 2] ), pt ); for ( int j = 1; j < pt.size(); ++j ) { path.lineTo( pt.at( j ).x(), pt.at( j ).y() ); } //arcTo( path, QPointF( mX[i], mY[i] ), QPointF( mX[i + 1], mY[i + 1] ), QPointF( mX[i + 2], mY[i + 2] ) ); } //if number of points is even, connect to last point with straight line (even though the circular string is not valid) if ( nPoints % 2 == 0 ) { path.lineTo( mX[ nPoints - 1 ], mY[ nPoints - 1 ] ); } }
void QgsMapToolAddCircularString::activate() { if ( mParentTool ) { mParentTool->deleteTempRubberBand(); if ( mPoints.isEmpty() ) { // if the parent tool has a curve, use its last point as the first point in this curve const QgsCompoundCurveV2* compoundCurve = mParentTool->captureCurve(); if ( compoundCurve && compoundCurve->nCurves() > 0 ) { const QgsCurveV2* curve = compoundCurve->curveAt( compoundCurve->nCurves() - 1 ); if ( curve ) { //mParentTool->captureCurve() is in layer coordinates, but we need map coordinates QgsPointV2 endPointLayerCoord = curve->endPoint(); QgsPoint mapPoint = toMapCoordinates( mCanvas->currentLayer(), QgsPoint( endPointLayerCoord.x(), endPointLayerCoord.y() ) ); mPoints.append( QgsPointV2( mapPoint ) ); if ( !mTempRubberBand ) { mTempRubberBand = createGeometryRubberBand(( mode() == CapturePolygon ) ? Qgis::Polygon : Qgis::Line, true ); mTempRubberBand->show(); } QgsCircularStringV2* c = new QgsCircularStringV2(); QgsPointSequenceV2 rubberBandPoints = mPoints; rubberBandPoints.append( QgsPointV2( mapPoint ) ); c->setPoints( rubberBandPoints ); mTempRubberBand->setGeometry( c ); } } } } QgsMapToolCapture::activate(); }
void TestQgsGeometryUtils::testDistanceToVertex() { //test with linestring QgsLineString* outerRing1 = new QgsLineString(); outerRing1->setPoints( QList<QgsPointV2>() << QgsPointV2( 1, 1 ) << QgsPointV2( 1, 2 ) << QgsPointV2( 2, 2 ) << QgsPointV2( 2, 1 ) << QgsPointV2( 1, 1 ) ); QCOMPARE( QgsGeometryUtils::distanceToVertex( *outerRing1, QgsVertexId( 0, 0, 0 ) ), 0.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( *outerRing1, QgsVertexId( 0, 0, 1 ) ), 1.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( *outerRing1, QgsVertexId( 0, 0, 2 ) ), 2.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( *outerRing1, QgsVertexId( 0, 0, 3 ) ), 3.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( *outerRing1, QgsVertexId( 0, 0, 4 ) ), 4.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( *outerRing1, QgsVertexId( 0, 0, 5 ) ), -1.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( *outerRing1, QgsVertexId( 0, 1, 1 ) ), -1.0 ); //test with polygon QgsPolygonV2 polygon1; polygon1.setExteriorRing( outerRing1 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( polygon1, QgsVertexId( 0, 0, 0 ) ), 0.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( polygon1, QgsVertexId( 0, 0, 1 ) ), 1.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( polygon1, QgsVertexId( 0, 0, 2 ) ), 2.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( polygon1, QgsVertexId( 0, 0, 3 ) ), 3.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( polygon1, QgsVertexId( 0, 0, 4 ) ), 4.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( polygon1, QgsVertexId( 0, 0, 5 ) ), -1.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( polygon1, QgsVertexId( 0, 1, 1 ) ), -1.0 ); //test with point QgsPointV2 point( 1, 2 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( point, QgsVertexId( 0, 0, 0 ) ), 0.0 ); QCOMPARE( QgsGeometryUtils::distanceToVertex( point, QgsVertexId( 0, 0, 1 ) ), -1.0 ); }
void QgsMapToolCircularStringRadius::recalculateTempRubberBand( const QgsPoint& mousePosition ) { QList<QgsPointV2> rubberBandPoints; if ( !( mPoints.size() % 2 ) ) { //recalculate midpoint on circle segment QgsPointV2 midPoint; if ( !QgsGeometryUtils::segmentMidPoint( mPoints.at( mPoints.size() - 2 ), mTemporaryEndPoint, midPoint, mRadius, QgsPointV2( mousePosition ) ) ) { return; } mPoints.replace( mPoints.size() - 1, midPoint ); rubberBandPoints.append( mPoints.at( mPoints.size() - 2 ) ); rubberBandPoints.append( mPoints.last() ); rubberBandPoints.append( mTemporaryEndPoint ); } else { rubberBandPoints.append( mPoints.last() ); rubberBandPoints.append( QgsPointV2( mousePosition ) ); } QgsCircularStringV2* cString = new QgsCircularStringV2(); cString->setPoints( rubberBandPoints ); delete mTempRubberBand; mTempRubberBand = createGeometryRubberBand(( mode() == CapturePolygon ) ? QGis::Polygon : QGis::Line, true ); mTempRubberBand->setGeometry( cString ); mTempRubberBand->show(); }
void QgsCircularString::insertVertexBetween( int after, int before, int pointOnCircle ) { double xAfter = mX.at( after ); double yAfter = mY.at( after ); double xBefore = mX.at( before ); double yBefore = mY.at( before ); double xOnCircle = mX.at( pointOnCircle ); double yOnCircle = mY.at( pointOnCircle ); double radius, centerX, centerY; QgsGeometryUtils::circleCenterRadius( QgsPointV2( xAfter, yAfter ), QgsPointV2( xBefore, yBefore ), QgsPointV2( xOnCircle, yOnCircle ), radius, centerX, centerY ); double x = ( xAfter + xBefore ) / 2.0; double y = ( yAfter + yBefore ) / 2.0; QgsPointV2 newVertex = QgsGeometryUtils::pointOnLineWithDistance( QgsPointV2( centerX, centerY ), QgsPointV2( x, y ), radius ); mX.insert( before, newVertex.x() ); mY.insert( before, newVertex.y() ); if ( is3D() ) { mZ.insert( before, ( mZ[after] + mZ[before] ) / 2.0 ); } if ( isMeasure() ) { mM.insert( before, ( mM[after] + mM[before] ) / 2.0 ); } clearCache(); }
double QgsGeometryUtils::circleLength( double x1, double y1, double x2, double y2, double x3, double y3 ) { double centerX, centerY, radius; circleCenterRadius( QgsPointV2( x1, y1 ), QgsPointV2( x2, y2 ), QgsPointV2( x3, y3 ), radius, centerX, centerY ); double length = M_PI / 180.0 * radius * sweepAngle( centerX, centerY, x1, y1, x2, y2, x3, y3 ); if ( length < 0 ) { length = -length; } return length; }
void QgsCircularString::arcTo( QPainterPath &path, QPointF pt1, QPointF pt2, QPointF pt3 ) { double centerX, centerY, radius; QgsGeometryUtils::circleCenterRadius( QgsPointV2( pt1.x(), pt1.y() ), QgsPointV2( pt2.x(), pt2.y() ), QgsPointV2( pt3.x(), pt3.y() ), radius, centerX, centerY ); double p1Angle = QgsGeometryUtils::ccwAngle( pt1.y() - centerY, pt1.x() - centerX ); double sweepAngle = QgsGeometryUtils::sweepAngle( centerX, centerY, pt1.x(), pt1.y(), pt2.x(), pt2.y(), pt3.x(), pt3.y() ); double diameter = 2 * radius; path.arcTo( centerX - radius, centerY - radius, diameter, diameter, p1Angle, sweepAngle ); }
void QgsCircularString::sumUpArea( double &sum ) const { int maxIndex = numPoints() - 1; for ( int i = 0; i < maxIndex; i += 2 ) { QgsPointV2 p1( mX[i], mY[i] ); QgsPointV2 p2( mX[i + 1], mY[i + 1] ); QgsPointV2 p3( mX[i + 2], mY[i + 2] ); //segment is a full circle, p2 is the center point if ( p1 == p3 ) { double r2 = QgsGeometryUtils::sqrDistance2D( p1, p2 ) / 4.0; sum += M_PI * r2; continue; } sum += 0.5 * ( mX[i] * mY[i + 2] - mY[i] * mX[i + 2] ); //calculate area between circle and chord, then sum / subtract from total area double midPointX = ( p1.x() + p3.x() ) / 2.0; double midPointY = ( p1.y() + p3.y() ) / 2.0; double radius, centerX, centerY; QgsGeometryUtils::circleCenterRadius( p1, p2, p3, radius, centerX, centerY ); double d = sqrt( QgsGeometryUtils::sqrDistance2D( QgsPointV2( centerX, centerY ), QgsPointV2( midPointX, midPointY ) ) ); double r2 = radius * radius; if ( d > radius ) { //d cannot be greater than radius, something must be wrong... continue; } bool circlePointLeftOfLine = QgsGeometryUtils::leftOfLine( p2.x(), p2.y(), p1.x(), p1.y(), p3.x(), p3.y() ) < 0; bool centerPointLeftOfLine = QgsGeometryUtils::leftOfLine( centerX, centerY, p1.x(), p1.y(), p3.x(), p3.y() ) < 0; double cov = 0.5 - d * sqrt( r2 - d * d ) / ( M_PI * r2 ) - 1 / M_PI * asin( d / radius ); double circleChordArea = 0; if ( circlePointLeftOfLine == centerPointLeftOfLine ) { circleChordArea = M_PI * r2 * ( 1 - cov ); } else { circleChordArea = M_PI * r2 * cov; } if ( !circlePointLeftOfLine ) { sum += circleChordArea; } else { sum -= circleChordArea; } } }
QgsMapToolCircularStringRadius::QgsMapToolCircularStringRadius( QgsMapToolCapture* parentTool, QgsMapCanvas* canvas, CaptureMode mode ) : QgsMapToolAddCircularString( parentTool, canvas, mode ), mTemporaryEndPoint( QgsPointV2() ), mRadius( 0.0 ), mRadiusSpinBox( nullptr ) { }
QgsPointV2 QgsCircularString::endPoint() const { if ( numPoints() < 1 ) { return QgsPointV2(); } return pointN( numPoints() - 1 ); }
QgsPointV2 QgsAbstractGeometryV2::centroid() const { // http://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon // Pick the first ring of first part for the moment int n = vertexCount( 0, 0 ); if ( n == 1 ) { return vertexAt( QgsVertexId( 0, 0, 0 ) ); } double A = 0.; double Cx = 0.; double Cy = 0.; int i = 0, j = 1; if ( vertexAt( QgsVertexId( 0, 0, 0 ) ) != vertexAt( QgsVertexId( 0, 0, n - 1 ) ) ) { i = n - 1; j = 0; } for ( ; j < n; i = j++ ) { QgsPointV2 vi = vertexAt( QgsVertexId( 0, 0, i ) ); QgsPointV2 vj = vertexAt( QgsVertexId( 0, 0, j ) ); double d = vi.x() * vj.y() - vj.x() * vi.y(); A += d; Cx += ( vi.x() + vj.x() ) * d; Cy += ( vi.y() + vj.y() ) * d; } if ( A < 1E-12 ) { Cx = Cy = 0.; for ( int i = 0; i < n - 1; ++i ) { QgsPointV2 vi = vertexAt( QgsVertexId( 0, 0, i ) ); Cx += vi.x(); Cy += vi.y(); } return QgsPointV2( Cx / ( n - 1 ), Cy / ( n - 1 ) ); } else { return QgsPointV2( Cx / ( 3. * A ), Cy / ( 3. * A ) ); } }
QgsPointV2 QgsCircularString::startPoint() const { if ( numPoints() < 1 ) { return QgsPointV2(); } return pointN( 0 ); }
QgsPointV2 QgsLineStringV2::endPoint() const { if ( numPoints() < 1 ) { return QgsPointV2(); } return pointN( numPoints() - 1 ); }
QgsPointV2 QgsLineStringV2::startPoint() const { if ( numPoints() < 1 ) { return QgsPointV2(); } return pointN( 0 ); }
bool QgsNodeEditorModel::setData( const QModelIndex& index, const QVariant& value, int role ) { if ( !index.isValid() || role != Qt::EditRole ) { return false; } if ( index.row() >= mSelectedFeature->vertexMap().count() ) { return false; } double x = ( index.column() == 0 ? value.toDouble() : mSelectedFeature->vertexMap().at( index.row() )->point().x() ); double y = ( index.column() == 1 ? value.toDouble() : mSelectedFeature->vertexMap().at( index.row() )->point().y() ); if ( index.column() == mRCol ) // radius modified { if ( index.row() == 0 || index.row() >= mSelectedFeature->vertexMap().count() - 1 ) return false; double r = value.toDouble(); double x1 = mSelectedFeature->vertexMap().at( index.row() - 1 )->point().x(); double y1 = mSelectedFeature->vertexMap().at( index.row() - 1 )->point().y(); double x2 = x; double y2 = y; double x3 = mSelectedFeature->vertexMap().at( index.row() + 1 )->point().x(); double y3 = mSelectedFeature->vertexMap().at( index.row() + 1 )->point().y(); QgsPointV2 result; if ( QgsGeometryUtils::segmentMidPoint( QgsPointV2( x1, y1 ), QgsPointV2( x3, y3 ), result, r, QgsPointV2( x2, y2 ) ) ) { x = result.x(); y = result.y(); } } double z = ( index.column() == mZCol ? value.toDouble() : mSelectedFeature->vertexMap().at( index.row() )->point().z() ); double m = ( index.column() == mMCol ? value.toDouble() : mSelectedFeature->vertexMap().at( index.row() )->point().m() ); QgsPointV2 p( QgsWkbTypes::PointZM, x, y, z, m ); mLayer->beginEditCommand( QObject::tr( "Moved vertices" ) ); mLayer->moveVertex( p, mSelectedFeature->featureId(), index.row() ); mLayer->endEditCommand(); mLayer->triggerRepaint(); return false; }
int QgsVectorLayerEditUtils::addPart( const QList<QgsPoint> &points, QgsFeatureId featureId ) { QgsPointSequenceV2 l; for ( QList<QgsPoint>::const_iterator it = points.constBegin(); it != points.constEnd(); ++it ) { l << QgsPointV2( *it ); } return addPart( l, featureId ); }
void TestQgsGeometryUtils::testCircleCenterRadius() { QFETCH( double, x1 ); QFETCH( double, y1 ); QFETCH( double, x2 ); QFETCH( double, y2 ); QFETCH( double, x3 ); QFETCH( double, y3 ); QFETCH( double, expectedRadius ); QFETCH( double, expectedCenterX ); QFETCH( double, expectedCenterY ); double radius, centerX, centerY; QgsGeometryUtils::circleCenterRadius( QgsPointV2( x1, y1 ), QgsPointV2( x2, y2 ), QgsPointV2( x3, y3 ), radius, centerX, centerY ); QVERIFY( qgsDoubleNear( expectedRadius, radius ) ); QVERIFY( qgsDoubleNear( expectedCenterX, centerX ) ); QVERIFY( qgsDoubleNear( expectedCenterY, centerY ) ); }
void TestQgsGeometryUtils::testSegmentMidPoint() { QFETCH( double, pt1x ); QFETCH( double, pt1y ); QFETCH( double, pt2x ); QFETCH( double, pt2y ); QFETCH( double, radius ); QFETCH( bool, left ); QFETCH( double, expectedX ); QFETCH( double, expectedY ); QgsPointV2 midPoint; bool ok = QgsGeometryUtils::segmentMidPoint( QgsPointV2( pt1x, pt1y ), QgsPointV2( pt2x, pt2y ), midPoint, radius, left ); QVERIFY( ok ); QVERIFY( qgsDoubleNear( midPoint.x(), expectedX ) ); QVERIFY( qgsDoubleNear( midPoint.y(), expectedY ) ); }
void QgsMapToolAddCircularString::updateCenterPointRubberBand( const QgsPointV2& pt ) { if ( !mShowCenterPointRubberBand || !mCenterPointRubberBand || mPoints.size() < 2 ) { return; } if (( mPoints.size() ) % 2 != 0 ) { return; } //create circular string QgsCircularStringV2* cs = new QgsCircularStringV2(); QList< QgsPointV2 > csPoints; csPoints.append( mPoints.at( mPoints.size() - 2 ) ); csPoints.append( mPoints.at( mPoints.size() - 1 ) ); csPoints.append( pt ); cs->setPoints( csPoints ); double centerX, centerY; double radius; QgsGeometryUtils::circleCenterRadius( csPoints.at( 0 ), csPoints.at( 1 ), csPoints.at( 2 ), radius, centerX, centerY ); QgsLineStringV2* segment1 = new QgsLineStringV2(); segment1->addVertex( QgsPointV2( centerX, centerY ) ); segment1->addVertex( csPoints.at( 0 ) ); QgsLineStringV2* segment2 = new QgsLineStringV2(); segment2->addVertex( csPoints.at( 2 ) ); segment2->addVertex( QgsPointV2( centerX, centerY ) ); QgsCompoundCurveV2* cc = new QgsCompoundCurveV2(); cc->addCurve( segment1 ); cc->addCurve( cs ); cc->addCurve( segment2 ); QgsCurvePolygonV2* cp = new QgsCurvePolygonV2(); cp->setExteriorRing( cc ); mCenterPointRubberBand->setGeometry( cp ); mCenterPointRubberBand->show(); }
QgsPointV2 QgsLineStringV2::pointN( int i ) const { if ( i < 0 || i >= mX.size() ) { return QgsPointV2(); } double x = mX.at( i ); double y = mY.at( i ); double z = 0; double m = 0; bool hasZ = is3D(); if ( hasZ ) { z = mZ.at( i ); } bool hasM = isMeasure(); if ( hasM ) { m = mM.at( i ); } QgsWKBTypes::Type t = QgsWKBTypes::Point; if ( mWkbType == QgsWKBTypes::LineString25D ) { t = QgsWKBTypes::Point25D; } else if ( hasZ && hasM ) { t = QgsWKBTypes::PointZM; } else if ( hasZ ) { t = QgsWKBTypes::PointZ; } else if ( hasM ) { t = QgsWKBTypes::PointM; } return QgsPointV2( t, x, y, z, m ); }
bool QgsGeometryUtils::segmentMidPoint( const QgsPointV2& p1, const QgsPointV2& p2, QgsPointV2& result, double radius, const QgsPointV2& mousePos ) { QgsPointV2 midPoint(( p1.x() + p2.x() ) / 2.0, ( p1.y() + p2.y() ) / 2.0 ); double midDist = sqrt( sqrDistance2D( p1, midPoint ) ); if ( radius < midDist ) { return false; } double centerMidDist = sqrt( radius * radius - midDist * midDist ); double dist = radius - centerMidDist; double midDx = midPoint.x() - p1.x(); double midDy = midPoint.y() - p1.y(); //get the four possible midpoints QList<QgsPointV2> possibleMidPoints; possibleMidPoints.append( pointOnLineWithDistance( midPoint, QgsPointV2( midPoint.x() - midDy, midPoint.y() + midDx ), dist ) ); possibleMidPoints.append( pointOnLineWithDistance( midPoint, QgsPointV2( midPoint.x() - midDy, midPoint.y() + midDx ), 2 * radius - dist ) ); possibleMidPoints.append( pointOnLineWithDistance( midPoint, QgsPointV2( midPoint.x() + midDy, midPoint.y() - midDx ), dist ) ); possibleMidPoints.append( pointOnLineWithDistance( midPoint, QgsPointV2( midPoint.x() + midDy, midPoint.y() - midDx ), 2 * radius - dist ) ); //take the closest one double minDist = std::numeric_limits<double>::max(); int minDistIndex = -1; for ( int i = 0; i < possibleMidPoints.size(); ++i ) { double currentDist = sqrDistance2D( mousePos, possibleMidPoints.at( i ) ); if ( currentDist < minDist ) { minDistIndex = i; minDist = currentDist; } } if ( minDistIndex == -1 ) { return false; } result = possibleMidPoints.at( minDistIndex ); return true; }
void TestQgsGeometryUtils::testAdjacentVertices() { // test polygon - should wrap around! QgsLineString* closedRing1 = new QgsLineString(); closedRing1->setPoints( QList<QgsPointV2>() << QgsPointV2( 1, 1 ) << QgsPointV2( 1, 2 ) << QgsPointV2( 2, 2 ) << QgsPointV2( 2, 1 ) << QgsPointV2( 1, 1 ) ); QgsPolygonV2 polygon1; polygon1.setExteriorRing( closedRing1 ); QgsVertexId previous; QgsVertexId next; QgsGeometryUtils::adjacentVertices( polygon1, QgsVertexId( 0, 0, 0 ), previous, next ); QCOMPARE( previous, QgsVertexId( 0, 0, 3 ) ); QCOMPARE( next, QgsVertexId( 0, 0, 1 ) ); // test point - both vertices should be invalid QgsPointV2 point( 1, 2 ); QgsGeometryUtils::adjacentVertices( point, QgsVertexId( 0, 0, 0 ), previous, next ); QVERIFY( !previous.isValid() ); QVERIFY( !next.isValid() ); }
int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring, const QgsFeatureIds& targetFeatureIds, QgsFeatureId* modifiedFeatureId ) { QgsLineStringV2* ringLine = new QgsLineStringV2(); QList< QgsPointV2 > ringPoints; QList<QgsPoint>::const_iterator ringIt = ring.constBegin(); for ( ; ringIt != ring.constEnd(); ++ringIt ) { ringPoints.append( QgsPointV2( ringIt->x(), ringIt->y() ) ); } ringLine->setPoints( ringPoints ); return addRing( ringLine, targetFeatureIds, modifiedFeatureId ); }
QgsPointV2 QgsTriangle::inscribedCenter() const { QVector<double> l = lengths(); double x = ( l.at( 0 ) * vertexAt( 2 ).x() + l.at( 1 ) * vertexAt( 0 ).x() + l.at( 2 ) * vertexAt( 1 ).x() ) / perimeter(); double y = ( l.at( 0 ) * vertexAt( 2 ).y() + l.at( 1 ) * vertexAt( 0 ).y() + l.at( 2 ) * vertexAt( 1 ).y() ) / perimeter(); return QgsPointV2( x, y ); }
QgsLineStringV2* QgsGeometryImport::linestringFromPolyline( const QgsPolyline& polyline ) { QgsLineStringV2* line = new QgsLineStringV2(); QList<QgsPointV2> points; QgsPolyline::const_iterator it = polyline.constBegin(); for ( ; it != polyline.constEnd(); ++it ) { points.append( QgsPointV2( it->x(), it->y() ) ); } line->setPoints( points ); return line; }
bool QgsSnapIndex::SegmentSnapItem::getProjection( const QgsPointV2 &p, QgsPointV2 &pProj ) { const QgsPointV2& s1 = idxFrom->point(); const QgsPointV2& s2 = idxTo->point(); double nx = s2.y() - s1.y(); double ny = -( s2.x() - s1.x() ); double t = ( p.x() * ny - p.y() * nx - s1.x() * ny + s1.y() * nx ) / (( s2.x() - s1.x() ) * ny - ( s2.y() - s1.y() ) * nx ); if ( t < 0. || t > 1. ) { return false; } pProj = QgsPointV2( s1.x() + ( s2.x() - s1.x() ) * t, s1.y() + ( s2.y() - s1.y() ) * t ); return true; }
QgsPointV2 QgsGeometryUtils::pointOnLineWithDistance( const QgsPointV2& startPoint, const QgsPointV2& directionPoint, double distance ) { double dx = directionPoint.x() - startPoint.x(); double dy = directionPoint.y() - startPoint.y(); double length = sqrt( dx * dx + dy * dy ); if ( qgsDoubleNear( length, 0.0 ) ) { return startPoint; } double scaleFactor = distance / length; return QgsPointV2( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor ); }
QgsPointV2 QgsLineStringV2::centroid() const { if ( mX.isEmpty() ) return QgsPointV2(); int numPoints = mX.count(); if ( numPoints == 1 ) return QgsPointV2( mX.at( 0 ), mY.at( 0 ) ); double totalLineLength = 0.0; double prevX = mX.at( 0 ); double prevY = mY.at( 0 ); double sumX = 0.0; double sumY = 0.0; for ( int i = 1; i < numPoints ; ++i ) { double currentX = mX.at( i ); double currentY = mY.at( i ); double segmentLength = sqrt( qPow( currentX - prevX, 2.0 ) + qPow( currentY - prevY, 2.0 ) ); if ( qgsDoubleNear( segmentLength, 0.0 ) ) continue; totalLineLength += segmentLength; sumX += segmentLength * 0.5 * ( currentX + prevX ); sumY += segmentLength * 0.5 * ( currentY + prevY ); prevX = currentX; prevY = currentY; } if ( qgsDoubleNear( totalLineLength, 0.0 ) ) return QgsPointV2( mX.at( 0 ), mY.at( 0 ) ); else return QgsPointV2( sumX / totalLineLength, sumY / totalLineLength ); }