void QgsMapToolCircularStringRadius::recalculateTempRubberBand( const QgsPointXY &mousePosition ) { QgsPointSequence rubberBandPoints; if ( !( mPoints.size() % 2 ) ) { //recalculate midpoint on circle segment QgsPoint midPoint; if ( !QgsGeometryUtils::segmentMidPoint( mPoints.at( mPoints.size() - 2 ), mTemporaryEndPoint, midPoint, mRadius, QgsPoint( 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( mapPoint( mousePosition ) ); } QgsCircularString *cString = new QgsCircularString(); cString->setPoints( rubberBandPoints ); delete mTempRubberBand; mTempRubberBand = createGeometryRubberBand( mLayerType, true ); mTempRubberBand->setGeometry( cString ); mTempRubberBand->show(); }
void QgsMapToolCircularStringCurvePoint::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) { QgsPointV2 mapPoint( e->mapPoint() ); if ( e->button() == Qt::LeftButton ) { mPoints.append( mapPoint ); if ( !mCenterPointRubberBand && mShowCenterPointRubberBand ) { createCenterPointRubberBand(); } if ( !mPoints.isEmpty() ) { if ( !mTempRubberBand ) { mTempRubberBand = createGeometryRubberBand( ( mode() == CapturePolygon ) ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, true ); mTempRubberBand->show(); } QgsCircularString *c = new QgsCircularString(); QgsPointSequence rubberBandPoints = mPoints.mid( mPoints.size() - 1 - ( mPoints.size() + 1 ) % 2 ); rubberBandPoints.append( mapPoint ); c->setPoints( rubberBandPoints ); mTempRubberBand->setGeometry( c ); } if ( mPoints.size() > 1 && mPoints.size() % 2 ) { if ( !mRubberBand ) { mRubberBand = createGeometryRubberBand( ( mode() == CapturePolygon ) ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry ); mRubberBand->show(); } QgsCircularString *c = new QgsCircularString(); QgsPointSequence rubberBandPoints = mPoints; rubberBandPoints.append( mapPoint ); c->setPoints( rubberBandPoints ); mRubberBand->setGeometry( c ); removeCenterPointRubberBand(); } } else if ( e->button() == Qt::RightButton ) { deactivate(); if ( mParentTool ) { mParentTool->canvasReleaseEvent( e ); } } }
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 QgsCompoundCurve *compoundCurve = mParentTool->captureCurve(); if ( compoundCurve && compoundCurve->nCurves() > 0 ) { const QgsCurve *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 ) ? QgsWkbTypes::PolygonGeometry : QgsWkbTypes::LineGeometry, true ); mTempRubberBand->show(); } QgsCircularString *c = new QgsCircularString(); QgsPointSequence rubberBandPoints = mPoints; rubberBandPoints.append( QgsPointV2( mapPoint ) ); c->setPoints( rubberBandPoints ); mTempRubberBand->setGeometry( c ); } } } } QgsMapToolCapture::activate(); }
void QgsMapToolAddCircularString::updateCenterPointRubberBand( const QgsPointV2 &pt ) { if ( !mShowCenterPointRubberBand || !mCenterPointRubberBand || mPoints.size() < 2 ) { return; } if ( ( mPoints.size() ) % 2 != 0 ) { return; } //create circular string QgsCircularString *cs = new QgsCircularString(); QgsPointSequence csPoints; csPoints.append( mPoints.at( mPoints.size() - 2 ) ); csPoints.append( mPoints.at( mPoints.size() - 1 ) ); csPoints.append( pt ); cs->setPoints( csPoints ); QgsPointV2 center; double radius; QgsGeometryUtils::circleCenterRadius( csPoints.at( 0 ), csPoints.at( 1 ), csPoints.at( 2 ), radius, center.rx(), center.ry() ); QgsLineString *segment1 = new QgsLineString(); segment1->addVertex( center ); segment1->addVertex( csPoints.at( 0 ) ); QgsLineString *segment2 = new QgsLineString(); segment2->addVertex( csPoints.at( 2 ) ); segment2->addVertex( center ); QgsCompoundCurve *cc = new QgsCompoundCurve(); cc->addCurve( segment1 ); cc->addCurve( cs ); cc->addCurve( segment2 ); QgsCurvePolygon *cp = new QgsCurvePolygon(); cp->setExteriorRing( cc ); mCenterPointRubberBand->setGeometry( cp ); mCenterPointRubberBand->show(); }
int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring, const QgsFeatureIds& targetFeatureIds, QgsFeatureId* modifiedFeatureId ) { QgsLineString* ringLine = new QgsLineString(); QgsPointSequence 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 ); }
void QgsCompoundCurve::points( QgsPointSequence &pts ) const { pts.clear(); if ( mCurves.empty() ) { return; } mCurves[0]->points( pts ); for ( int i = 1; i < mCurves.size(); ++i ) { QgsPointSequence pList; mCurves[i]->points( pList ); pList.removeFirst(); //first vertex already added in previous line pts.append( pList ); } }
QgsCircularString *QgsCircle::toCircularString( bool oriented ) const { std::unique_ptr<QgsCircularString> circString( new QgsCircularString() ); QgsPointSequence points; QVector<QgsPoint> quad; if ( oriented ) { quad = quadrant(); } else { quad = northQuadrant(); } quad.append( quad.at( 0 ) ); for ( QVector<QgsPoint>::const_iterator it = quad.constBegin(); it != quad.constEnd(); ++it ) { points.append( *it ); } circString->setPoints( points ); return circString.release(); }
void QgsCircularString::segmentize( const QgsPointV2 &p1, const QgsPointV2 &p2, const QgsPointV2 &p3, QgsPointSequence &points, double tolerance, SegmentationToleranceType toleranceType ) const { bool clockwise = false; int segSide = segmentSide( p1, p3, p2 ); if ( segSide == -1 ) { clockwise = true; } QgsPointV2 circlePoint1 = clockwise ? p3 : p1; QgsPointV2 circlePoint2 = p2; QgsPointV2 circlePoint3 = clockwise ? p1 : p3 ; //adapted code from postgis double radius = 0; double centerX = 0; double centerY = 0; QgsGeometryUtils::circleCenterRadius( circlePoint1, circlePoint2, circlePoint3, radius, centerX, centerY ); if ( circlePoint1 != circlePoint3 && ( radius < 0 || qgsDoubleNear( segSide, 0.0 ) ) ) //points are colinear { points.append( p1 ); points.append( p2 ); points.append( p3 ); return; } double increment = tolerance; //one segment per degree if ( toleranceType == QgsAbstractGeometry::MaximumDifference ) { double halfAngle = acos( -tolerance / radius + 1 ); increment = 2 * halfAngle; } //angles of pt1, pt2, pt3 double a1 = atan2( circlePoint1.y() - centerY, circlePoint1.x() - centerX ); double a2 = atan2( circlePoint2.y() - centerY, circlePoint2.x() - centerX ); double a3 = atan2( circlePoint3.y() - centerY, circlePoint3.x() - centerX ); /* Adjust a3 up so we can increment from a1 to a3 cleanly */ if ( a3 <= a1 ) a3 += 2.0 * M_PI; if ( a2 < a1 ) a2 += 2.0 * M_PI; bool hasZ = is3D(); bool hasM = isMeasure(); double x, y; double z = 0; double m = 0; QList<QgsPointV2> stringPoints; stringPoints.insert( clockwise ? 0 : stringPoints.size(), circlePoint1 ); if ( circlePoint2 != circlePoint3 && circlePoint1 != circlePoint2 ) //draw straight line segment if two points have the same position { QgsWkbTypes::Type pointWkbType = QgsWkbTypes::Point; if ( hasZ ) pointWkbType = QgsWkbTypes::addZ( pointWkbType ); if ( hasM ) pointWkbType = QgsWkbTypes::addM( pointWkbType ); //make sure the curve point p2 is part of the segmentized vertices. But only if p1 != p3 bool addP2 = true; if ( qgsDoubleNear( circlePoint1.x(), circlePoint3.x() ) && qgsDoubleNear( circlePoint1.y(), circlePoint3.y() ) ) { addP2 = false; } for ( double angle = a1 + increment; angle < a3; angle += increment ) { if ( ( addP2 && angle > a2 ) ) { stringPoints.insert( clockwise ? 0 : stringPoints.size(), circlePoint2 ); addP2 = false; } x = centerX + radius * cos( angle ); y = centerY + radius * sin( angle ); if ( !hasZ && !hasM ) { stringPoints.insert( clockwise ? 0 : stringPoints.size(), QgsPointV2( x, y ) ); continue; } if ( hasZ ) { z = interpolateArc( angle, a1, a2, a3, circlePoint1.z(), circlePoint2.z(), circlePoint3.z() ); } if ( hasM ) { m = interpolateArc( angle, a1, a2, a3, circlePoint1.m(), circlePoint2.m(), circlePoint3.m() ); } stringPoints.insert( clockwise ? 0 : stringPoints.size(), QgsPointV2( pointWkbType, x, y, z, m ) ); } } stringPoints.insert( clockwise ? 0 : stringPoints.size(), circlePoint3 ); points.append( stringPoints ); }
QgsPointSequence QgsCircularString::compassPointsOnSegment( double p1Angle, double p2Angle, double p3Angle, double centerX, double centerY, double radius ) { QgsPointSequence pointList; QgsPointV2 nPoint( centerX, centerY + radius ); QgsPointV2 ePoint( centerX + radius, centerY ); QgsPointV2 sPoint( centerX, centerY - radius ); QgsPointV2 wPoint( centerX - radius, centerY ); if ( p3Angle >= p1Angle ) { if ( p2Angle > p1Angle && p2Angle < p3Angle ) { if ( p1Angle <= 90 && p3Angle >= 90 ) { pointList.append( nPoint ); } if ( p1Angle <= 180 && p3Angle >= 180 ) { pointList.append( wPoint ); } if ( p1Angle <= 270 && p3Angle >= 270 ) { pointList.append( sPoint ); } } else { pointList.append( ePoint ); if ( p1Angle >= 90 || p3Angle <= 90 ) { pointList.append( nPoint ); } if ( p1Angle >= 180 || p3Angle <= 180 ) { pointList.append( wPoint ); } if ( p1Angle >= 270 || p3Angle <= 270 ) { pointList.append( sPoint ); } } } else { if ( p2Angle < p1Angle && p2Angle > p3Angle ) { if ( p1Angle >= 270 && p3Angle <= 270 ) { pointList.append( sPoint ); } if ( p1Angle >= 180 && p3Angle <= 180 ) { pointList.append( wPoint ); } if ( p1Angle >= 90 && p3Angle <= 90 ) { pointList.append( nPoint ); } } else { pointList.append( ePoint ); if ( p1Angle <= 270 || p3Angle >= 270 ) { pointList.append( sPoint ); } if ( p1Angle <= 180 || p3Angle >= 180 ) { pointList.append( wPoint ); } if ( p1Angle <= 90 || p3Angle >= 90 ) { pointList.append( nPoint ); } } } return pointList; }