double QgsLineString::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const { double sqrDist = std::numeric_limits<double>::max(); double testDist = 0; double segmentPtX, segmentPtY; int size = mX.size(); if ( size == 0 || size == 1 ) { vertexAfter = QgsVertexId( 0, 0, 0 ); return -1; } for ( int i = 1; i < size; ++i ) { double prevX = mX.at( i - 1 ); double prevY = mY.at( i - 1 ); double currentX = mX.at( i ); double currentY = mY.at( i ); testDist = QgsGeometryUtils::sqrDistToLine( pt.x(), pt.y(), prevX, prevY, currentX, currentY, segmentPtX, segmentPtY, epsilon ); if ( testDist < sqrDist ) { sqrDist = testDist; segmentPt.setX( segmentPtX ); segmentPt.setY( segmentPtY ); if ( leftOf ) { *leftOf = ( QgsGeometryUtils::leftOfLine( pt.x(), pt.y(), prevX, prevY, currentX, currentY ) < 0 ); } vertexAfter.part = 0; vertexAfter.ring = 0; vertexAfter.vertex = i; } } return sqrDist; }
bool QgsCurve::isClosed() const { if ( numPoints() == 0 ) return false; //don't consider M-coordinates when testing closedness QgsPointV2 start = startPoint(); QgsPointV2 end = endPoint(); return ( qgsDoubleNear( start.x(), end.x(), 1E-8 ) && qgsDoubleNear( start.y(), end.y(), 1E-8 ) && qgsDoubleNear( start.z(), end.z(), 1E-8 ) ); }
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 ); }
bool QgsGeometryUtils::segmentIntersection( const QgsPointV2 &p1, const QgsPointV2 &p2, const QgsPointV2 &q1, const QgsPointV2 &q2, QgsPointV2 &inter, double tolerance ) { QgsVector v( p2.x() - p1.x(), p2.y() - p1.y() ); QgsVector w( q2.x() - q1.x(), q2.y() - q1.y() ); double vl = v.length(); double wl = w.length(); if ( qFuzzyIsNull( vl ) || qFuzzyIsNull( wl ) ) { return false; } v = v / vl; w = w / wl; if ( !QgsGeometryUtils::lineIntersection( p1, v, q1, w, inter ) ) return false; double lambdav = QgsVector( inter.x() - p1.x(), inter.y() - p1.y() ) * v; if ( lambdav < 0. + tolerance || lambdav > vl - tolerance ) return false; double lambdaw = QgsVector( inter.x() - q1.x(), inter.y() - q1.y() ) * w; if ( lambdaw < 0. + tolerance || lambdaw >= wl - tolerance ) return false; return true; }
bool QgsGeometryUtils::lineIntersection( const QgsPointV2& p1, const QgsVector& v, const QgsPointV2& q1, const QgsVector& w, QgsPointV2& inter ) { double d = v.y() * w.x() - v.x() * w.y(); if ( d == 0 ) return false; double dx = q1.x() - p1.x(); double dy = q1.y() - p1.y(); double k = ( dy * w.x() - dx * w.y() ) / d; inter = QgsPointV2( p1.x() + v.x() * k, p1.y() + v.y() * k ); return true; }
double QgsCircularString::closestPointOnArc( double x1, double y1, double x2, double y2, double x3, double y3, const QgsPointV2 &pt, QgsPointV2 &segmentPt, QgsVertexId &vertexAfter, bool *leftOf, double epsilon ) { double radius, centerX, centerY; QgsPointV2 pt1( x1, y1 ); QgsPointV2 pt2( x2, y2 ); QgsPointV2 pt3( x3, y3 ); QgsGeometryUtils::circleCenterRadius( pt1, pt2, pt3, radius, centerX, centerY ); double angle = QgsGeometryUtils::ccwAngle( pt.y() - centerY, pt.x() - centerX ); double angle1 = QgsGeometryUtils::ccwAngle( pt1.y() - centerY, pt1.x() - centerX ); double angle2 = QgsGeometryUtils::ccwAngle( pt2.y() - centerY, pt2.x() - centerX ); double angle3 = QgsGeometryUtils::ccwAngle( pt3.y() - centerY, pt3.x() - centerX ); bool clockwise = QgsGeometryUtils::circleClockwise( angle1, angle2, angle3 ); if ( QgsGeometryUtils::angleOnCircle( angle, angle1, angle2, angle3 ) ) { //get point on line center -> pt with distance radius segmentPt = QgsGeometryUtils::pointOnLineWithDistance( QgsPointV2( centerX, centerY ), pt, radius ); //vertexAfter vertexAfter.vertex = QgsGeometryUtils::circleAngleBetween( angle, angle1, angle2, clockwise ) ? 1 : 2; } else { double distPtPt1 = QgsGeometryUtils::sqrDistance2D( pt, pt1 ); double distPtPt3 = QgsGeometryUtils::sqrDistance2D( pt, pt3 ); segmentPt = ( distPtPt1 <= distPtPt3 ) ? pt1 : pt3; vertexAfter.vertex = ( distPtPt1 <= distPtPt3 ) ? 1 : 2; } double sqrDistance = QgsGeometryUtils::sqrDistance2D( segmentPt, pt ); //prevent rounding errors if the point is directly on the segment if ( qgsDoubleNear( sqrDistance, 0.0, epsilon ) ) { segmentPt.setX( pt.x() ); segmentPt.setY( pt.y() ); sqrDistance = 0.0; } if ( leftOf ) { *leftOf = clockwise ? sqrDistance > radius : sqrDistance < radius; } return sqrDistance; }
bool QgsLineStringV2::insertVertex( const QgsVertexId& position, const QgsPointV2& vertex ) { if ( position.vertex < 0 || position.vertex > mX.size() ) { return false; } if ( mWkbType == QgsWKBTypes::Unknown || mX.isEmpty() ) { setZMTypeFromSubGeometry( &vertex, QgsWKBTypes::LineString ); } mX.insert( position.vertex, vertex.x() ); mY.insert( position.vertex, vertex.y() ); if ( is3D() ) { mZ.insert( position.vertex, vertex.z() ); } if ( isMeasure() ) { mM.insert( position.vertex, vertex.m() ); } mBoundingBox = QgsRectangle(); //set bounding box invalid return true; }
QgsTriangle::QgsTriangle( const QgsPointV2 &p1, const QgsPointV2 &p2, const QgsPointV2 &p3 ) { mWkbType = QgsWkbTypes::Triangle; if ( !validateGeom( p1, p2, p3 ) ) { return; } QVector< double > x; x << p1.x() << p2.x() << p3.x(); QVector< double > y; y << p1.y() << p2.y() << p3.y(); QgsLineString *ext = new QgsLineString( x, y ); setExteriorRing( ext ); }
double QgsLineStringV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const { double sqrDist = std::numeric_limits<double>::max(); double testDist = 0; double segmentPtX, segmentPtY; int size = mCoords.size(); for ( int i = 1; i < size; ++i ) { const QPointF& prev = mCoords.at( i - 1 ); const QPointF& currentPt = mCoords.at( i ); testDist = QgsGeometryUtils::sqrDistToLine( pt.x(), pt.y(), prev.x(), prev.y(), currentPt.x(), currentPt.y(), segmentPtX, segmentPtY, epsilon ); if ( testDist < sqrDist ) { sqrDist = testDist; segmentPt.setX( segmentPtX ); segmentPt.setY( segmentPtY ); if ( leftOf ) { *leftOf = ( QgsGeometryUtils::leftOfLine( segmentPtX, segmentPtY, prev.x(), prev.y(), pt.x(), pt.y() ) < 0 ); } vertexAfter.part = 0; vertexAfter.ring = 0; vertexAfter.vertex = i; } } return sqrDist; }
bool QgsCircularString::insertVertex( QgsVertexId position, const QgsPointV2 &vertex ) { if ( position.vertex > mX.size() || position.vertex < 1 ) { return false; } mX.insert( position.vertex, vertex.x() ); mY.insert( position.vertex, vertex.y() ); if ( is3D() ) { mZ.insert( position.vertex, vertex.z() ); } if ( isMeasure() ) { mM.insert( position.vertex, vertex.m() ); } bool vertexNrEven = ( position.vertex % 2 == 0 ); if ( vertexNrEven ) { insertVertexBetween( position.vertex - 2, position.vertex - 1, position.vertex ); } else { insertVertexBetween( position.vertex, position.vertex + 1, position.vertex - 1 ); } clearCache(); //set bounding box invalid return true; }
QgsRectangle QgsAbstractGeometry::calculateBoundingBox() const { double xmin = std::numeric_limits<double>::max(); double ymin = std::numeric_limits<double>::max(); double xmax = -std::numeric_limits<double>::max(); double ymax = -std::numeric_limits<double>::max(); QgsVertexId id; QgsPointV2 vertex; double x, y; while ( nextVertex( id, vertex ) ) { x = vertex.x(); y = vertex.y(); if ( x < xmin ) xmin = x; if ( x > xmax ) xmax = x; if ( y < ymin ) ymin = y; if ( y > ymax ) ymax = y; } return QgsRectangle( xmin, ymin, xmax, ymax ); }
void QgsMapToolCapture::canvasMapMoveEvent( QgsMapMouseEvent * e ) { bool snapped = e->isSnapped(); QgsPoint point = e->mapPoint(); if ( !snapped ) { delete mSnappingMarker; mSnappingMarker = 0; } else { if ( !mSnappingMarker ) { mSnappingMarker = new QgsVertexMarker( mCanvas ); mSnappingMarker->setIconType( QgsVertexMarker::ICON_CROSS ); mSnappingMarker->setColor( Qt::magenta ); mSnappingMarker->setPenWidth( 3 ); } mSnappingMarker->setCenter( point ); } if ( !mTempRubberBand && mCaptureCurve.numPoints() > 0 ) { mTempRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line, true ); QgsPointV2 pt = mCaptureCurve.endPoint(); mTempRubberBand->addPoint( QgsPoint( pt.x(), pt.y() ) ); mTempRubberBand->addPoint( point ); } if ( mCaptureMode != CapturePoint && mTempRubberBand && mCapturing ) { mTempRubberBand->movePoint( point ); } } // mouseMoveEvent
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(); }
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 QgsSelectedFeature::moveSelectedVertexes( QgsVector v ) { int nUpdates = 0; Q_FOREACH ( QgsVertexEntry *entry, mVertexMap ) { if ( entry->isSelected() ) nUpdates++; } if ( nUpdates == 0 ) return; mVlayer->beginEditCommand( QObject::tr( "Moved vertices" ) ); int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 ); beginGeometryChange(); QMultiMap<double, QgsSnappingResult> currentResultList; for ( int i = mVertexMap.size() - 1; i > -1 && nUpdates > 0; i-- ) { QgsVertexEntry *entry = mVertexMap.value( i, nullptr ); if ( !entry || !entry->isSelected() ) continue; if ( topologicalEditing ) { // snap from current vertex currentResultList.clear(); mVlayer->snapWithContext( entry->pointV1(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex ); } // only last update should trigger the geometry update // as vertex selection gets lost on the update if ( --nUpdates == 0 ) endGeometryChange(); QgsPointV2 p = entry->point(); p.setX( p.x() + v.x() ); p.setY( p.y() + v.y() ); mVlayer->moveVertex( p, mFeatureId, i ); if ( topologicalEditing ) { QMultiMap<double, QgsSnappingResult>::iterator resultIt = currentResultList.begin(); for ( ; resultIt != currentResultList.end(); ++resultIt ) { // move all other if ( mFeatureId != resultIt.value().snappedAtGeometry ) mVlayer->moveVertex( p, resultIt.value().snappedAtGeometry, resultIt.value().snappedVertexNr ); } } } if ( nUpdates > 0 ) endGeometryChange(); mVlayer->endEditCommand(); }
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 ) ); } }
double QgsGeometryUtils::circleTangentDirection( const QgsPointV2& tangentPoint, const QgsPointV2& cp1, const QgsPointV2& cp2, const QgsPointV2& cp3 ) { //calculate circle midpoint double mX, mY, radius; circleCenterRadius( cp1, cp2, cp3, radius, mX, mY ); double p1Angle = QgsGeometryUtils::ccwAngle( cp1.y() - mY, cp1.x() - mX ); double p2Angle = QgsGeometryUtils::ccwAngle( cp2.y() - mY, cp2.x() - mX ); double p3Angle = QgsGeometryUtils::ccwAngle( cp3.y() - mY, cp3.x() - mX ); if ( circleClockwise( p1Angle, p2Angle, p3Angle ) ) { return lineAngle( tangentPoint.x(), tangentPoint.y(), mX, mY ); } else { return lineAngle( mX, mY, tangentPoint.x(), tangentPoint.y() ); } }
/** * Calculate the area of a triangle in 3d space */ static double triarea3d( const QgsPointV2 &P1, const QgsPointV2 &P2, const QgsPointV2 &P3 ) { //LWDEBUG( 2, "Entered triarea3d" ); double ax, bx, ay, by, az, bz, cx, cy, cz, area; ax = P1.x() - P2.x(); bx = P3.x() - P2.x(); ay = P1.y() - P2.y(); by = P3.y() - P2.y(); az = P1.z() - P2.z(); bz = P3.z() - P2.z(); cx = ay * bz - az * by; cy = az * bx - ax * bz; cz = ax * by - ay * bx; area = qAbs( 0.5 * ( sqrt( cx * cx + cy * cy + cz * cz ) ) ); return area; }
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; }
int QgsCircularString::segmentSide( const QgsPointV2 &pt1, const QgsPointV2 &pt3, const QgsPointV2 &pt2 ) const { double side = ( ( pt2.x() - pt1.x() ) * ( pt3.y() - pt1.y() ) - ( pt3.x() - pt1.x() ) * ( pt2.y() - pt1.y() ) ); if ( side == 0.0 ) { return 0; } else { if ( side < 0 ) { return -1; } if ( side > 0 ) { return 1; } return 0; } }
QgsRectangle QgsCircularString::segmentBoundingBox( const QgsPointV2 &pt1, const QgsPointV2 &pt2, const QgsPointV2 &pt3 ) { double centerX, centerY, radius; QgsGeometryUtils::circleCenterRadius( pt1, pt2, pt3, radius, centerX, centerY ); double p1Angle = QgsGeometryUtils::ccwAngle( pt1.y() - centerY, pt1.x() - centerX ); if ( p1Angle > 360 ) { p1Angle -= 360; } double p2Angle = QgsGeometryUtils::ccwAngle( pt2.y() - centerY, pt2.x() - centerX ); if ( p2Angle > 360 ) { p2Angle -= 360; } double p3Angle = QgsGeometryUtils::ccwAngle( pt3.y() - centerY, pt3.x() - centerX ); if ( p3Angle > 360 ) { p3Angle -= 360; } //start point, end point and compass points in between can be on bounding box QgsRectangle bbox( pt1.x(), pt1.y(), pt1.x(), pt1.y() ); bbox.combineExtentWith( pt3.x(), pt3.y() ); QgsPointSequence compassPoints = compassPointsOnSegment( p1Angle, p2Angle, p3Angle, centerX, centerY, radius ); QgsPointSequence::const_iterator cpIt = compassPoints.constBegin(); for ( ; cpIt != compassPoints.constEnd(); ++cpIt ) { bbox.combineExtentWith( cpIt->x(), cpIt->y() ); } return bbox; }
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; }
bool QgsLineStringV2::insertVertex( const QgsVertexId& position, const QgsPointV2& vertex ) { if ( position.vertex < 0 || position.vertex > mCoords.size() ) { return false; } mCoords.insert( position.vertex, QPointF( vertex.x(), vertex.y() ) ); if ( is3D() ) { mZ.insert( position.vertex, vertex.z() ); } if ( isMeasure() ) { mM.insert( position.vertex, vertex.m() ); } return true; }
void QgsLineStringV2::addVertex( const QgsPointV2& pt ) { if ( mWkbType == QgsWKBTypes::Unknown ) { setZMTypeFromSubGeometry( &pt, QgsWKBTypes::LineString ); } mCoords.append( QPointF( pt.x(), pt.y() ) ); if ( is3D() ) { mZ.append( pt.z() ); } if ( isMeasure() ) { mM.append( pt.m() ); } }
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; }
void QgsLineStringV2::addVertex( const QgsPointV2& pt ) { if ( mWkbType == QgsWKBTypes::Unknown ) { setZMTypeFromSubGeometry( &pt, QgsWKBTypes::LineString ); } mCoords.append( QPointF( pt.x(), pt.y() ) ); if ( is3D() ) { mZ.append( pt.z() ); } if ( isMeasure() ) { mM.append( pt.m() ); } mBoundingBox = QgsRectangle(); //set bounding box invalid so it needs to be recalculated next time }
bool QgsLineStringV2::insertVertex( const QgsVertexId& position, const QgsPointV2& vertex ) { if ( position.vertex < 0 || position.vertex >= mCoords.size() ) { return false; } mCoords.insert( position.vertex, QPointF( vertex.x(), vertex.y() ) ); if ( is3D() ) { mZ.insert( position.vertex, vertex.z() ); } if ( isMeasure() ) { mM.insert( position.vertex, vertex.m() ); } mBoundingBox = QgsRectangle(); //set bounding box invalid so it needs to be recalculated next time return true; }
int QgsMapToolCapture::addCurve( QgsCurveV2* c ) { if ( !c ) { return 1; } if ( !mRubberBand ) { mRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line ); } QgsLineStringV2* lineString = c->curveToLine(); QList<QgsPointV2> linePoints; lineString->points( linePoints ); delete lineString; QList<QgsPointV2>::const_iterator ptIt = linePoints.constBegin(); for ( ; ptIt != linePoints.constEnd(); ++ptIt ) { mRubberBand->addPoint( QgsPoint( ptIt->x(), ptIt->y() ) ); } if ( !mTempRubberBand ) { mTempRubberBand = createRubberBand( mCaptureMode == CapturePolygon ? QGis::Polygon : QGis::Line, true ); } else { mTempRubberBand->reset(); } QgsPointV2 endPt = c->endPoint(); mTempRubberBand->addPoint( QgsPoint( endPt.x(), endPt.y() ) ); //add last point of c //transform back to layer CRS in case map CRS and layer CRS are different QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ); const QgsCoordinateTransform* ct = mCanvas->mapSettings().layerTransform( vlayer ); if ( ct ) { c->transform( *ct, QgsCoordinateTransform::ReverseTransform ); } mCaptureCurve.addCurve( c ); return 0; }
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 QgsLineStringV2::addVertex( const QgsPointV2& pt ) { if ( mWkbType == QgsWKBTypes::Unknown || mX.isEmpty() ) { setZMTypeFromSubGeometry( &pt, QgsWKBTypes::LineString ); } mX.append( pt.x() ); mY.append( pt.y() ); if ( is3D() ) { mZ.append( pt.z() ); } if ( isMeasure() ) { mM.append( pt.m() ); } mBoundingBox = QgsRectangle(); //set bounding box invalid }