mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-17 00:09:36 -04:00
Display the limit as an infinite line
This commit is contained in:
parent
aedb0a8286
commit
da99ccf0d3
@ -48,6 +48,7 @@ QgsMapToolTrimExtendFeature::QgsMapToolTrimExtendFeature( QgsMapCanvas *canvas )
|
||||
: QgsMapToolEdit( canvas )
|
||||
{
|
||||
mToolName = tr( "Trim/Extend feature" );
|
||||
connect( mCanvas, &QgsMapCanvas::extentsChanged, this, &QgsMapToolTrimExtendFeature::extendLimit );
|
||||
}
|
||||
|
||||
static bool getPoints( const QgsPointLocator::Match &match, QgsPoint &p1, QgsPoint &p2 )
|
||||
@ -89,15 +90,19 @@ void QgsMapToolTrimExtendFeature::canvasMoveEvent( QgsMapMouseEvent *e )
|
||||
|
||||
QgsPointXY p1, p2;
|
||||
match.edgePoints( p1, p2 );
|
||||
|
||||
mLimitLayer = match.layer();
|
||||
mRubberBandLimit.reset( createRubberBand( Qgis::GeometryType::Line ) );
|
||||
mRubberBandLimitExtend.reset( createRubberBand( Qgis::GeometryType::Line ) );
|
||||
mRubberBandLimitExtend->setLineStyle( Qt::DotLine );
|
||||
mRubberBandLimit->addPoint( p1 );
|
||||
mRubberBandLimit->addPoint( p2 );
|
||||
mRubberBandLimit->show();
|
||||
extendLimit();
|
||||
}
|
||||
else if ( mRubberBandLimit )
|
||||
{
|
||||
mRubberBandLimit->hide();
|
||||
mRubberBandLimitExtend.reset();
|
||||
}
|
||||
break;
|
||||
case StepExtend:
|
||||
@ -198,8 +203,10 @@ void QgsMapToolTrimExtendFeature::canvasMoveEvent( QgsMapMouseEvent *e )
|
||||
if ( mIsModified )
|
||||
{
|
||||
mGeom.removeDuplicateNodes();
|
||||
mRubberBandExtend->setToGeometry( mGeom, mVlayer );
|
||||
// Densify by count to better display the intersection when layer crs != map crs
|
||||
mRubberBandExtend->setToGeometry( mGeom.densifyByCount( 10 ), mVlayer );
|
||||
mRubberBandExtend->show();
|
||||
extendLimit();
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -294,6 +301,69 @@ void QgsMapToolTrimExtendFeature::keyPressEvent( QKeyEvent *e )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QgsMapToolTrimExtendFeature::extendLimit()
|
||||
{
|
||||
if ( !mRubberBandLimitExtend )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsVectorLayer *refLayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() );
|
||||
refLayer = refLayer ? refLayer : mVlayer ? mVlayer
|
||||
: mLimitLayer;
|
||||
|
||||
// Compute intersection between the line that extends the limit segment and the
|
||||
// edges of the map canvas
|
||||
QgsPointXY p1 = toLayerCoordinates( refLayer, *mRubberBandLimit->getPoint( 0, 0 ) );
|
||||
QgsPointXY p2 = toLayerCoordinates( refLayer, *mRubberBandLimit->getPoint( 0, 1 ) );
|
||||
QgsPoint canvasTopLeft = QgsPoint( toLayerCoordinates( refLayer, QPoint( 0, 0 ) ) );
|
||||
QgsPoint canvasTopRight = QgsPoint( toLayerCoordinates( refLayer, QPoint( mCanvas->width(), 0 ) ) );
|
||||
QgsPoint canvasBottomLeft = QgsPoint( toLayerCoordinates( refLayer, QPoint( 0, mCanvas->height() ) ) );
|
||||
QgsPoint canvasBottomRight = QgsPoint( toLayerCoordinates( refLayer, QPoint( mCanvas->width(), mCanvas->height() ) ) );
|
||||
|
||||
QList<QgsPointXY> points;
|
||||
points << p1 << p2;
|
||||
|
||||
QgsPoint intersection;
|
||||
if ( QgsGeometryUtils::lineIntersection( QgsPoint( p1 ), QgsPoint( p2 ) - QgsPoint( p1 ), canvasTopLeft, canvasTopRight - canvasTopLeft, intersection ) )
|
||||
{
|
||||
points << QgsPointXY( intersection );
|
||||
}
|
||||
if ( QgsGeometryUtils::lineIntersection( QgsPoint( p1 ), QgsPoint( p2 ) - QgsPoint( p1 ), canvasTopRight, canvasBottomRight - canvasTopRight, intersection ) )
|
||||
{
|
||||
points << QgsPointXY( intersection );
|
||||
}
|
||||
if ( QgsGeometryUtils::lineIntersection( QgsPoint( p1 ), QgsPoint( p2 ) - QgsPoint( p1 ), canvasBottomRight, canvasBottomLeft - canvasBottomRight, intersection ) )
|
||||
{
|
||||
points << QgsPointXY( intersection );
|
||||
}
|
||||
if ( QgsGeometryUtils::lineIntersection( QgsPoint( p1 ), QgsPoint( p2 ) - QgsPoint( p1 ), canvasBottomLeft, canvasTopLeft - canvasBottomLeft, intersection ) )
|
||||
{
|
||||
points << QgsPointXY( intersection );
|
||||
}
|
||||
|
||||
// Reorder the points by x/y coordinates
|
||||
std::sort( points.begin(), points.end(), []( const QgsPointXY &a, const QgsPointXY &b ) -> bool {
|
||||
if ( a.x() == b.x() )
|
||||
return a.y() < b.y();
|
||||
return a.x() < b.x();
|
||||
} );
|
||||
|
||||
// Keep only the closest intersection points from the original points
|
||||
const int p1Idx = points.indexOf( p1 );
|
||||
const int p2Idx = points.indexOf( p2 );
|
||||
const int first = std::max( 0, std::min( p1Idx, p2Idx ) - 1 );
|
||||
const int last = std::min( points.size() - 1, std::max( p1Idx, p2Idx ) + 1 );
|
||||
const QgsPolylineXY polyline = points.mid( first, last - first + 1 ).toVector();
|
||||
|
||||
// Densify the polyline to display a more accurate prediction when layer crs != canvas crs
|
||||
QgsGeometry geom = QgsGeometry::fromPolylineXY( polyline ).densifyByCount( 10 );
|
||||
|
||||
mRubberBandLimitExtend->setToGeometry( geom, refLayer );
|
||||
mRubberBandLimitExtend->show();
|
||||
}
|
||||
|
||||
void QgsMapToolTrimExtendFeature::deactivate()
|
||||
{
|
||||
mStep = StepLimit;
|
||||
@ -302,6 +372,7 @@ void QgsMapToolTrimExtendFeature::deactivate()
|
||||
mIsIntersection = false;
|
||||
mSegmentIntersects = false;
|
||||
mRubberBandLimit.reset();
|
||||
mRubberBandLimitExtend.reset();
|
||||
mRubberBandExtend.reset();
|
||||
mRubberBandIntersection.reset();
|
||||
QgsMapTool::deactivate();
|
||||
|
@ -38,9 +38,15 @@ class APP_EXPORT QgsMapToolTrimExtendFeature : public QgsMapToolEdit
|
||||
//! called when map tool is being deactivated
|
||||
void deactivate() override;
|
||||
|
||||
private slots:
|
||||
// Recompute the extended limit
|
||||
void extendLimit();
|
||||
|
||||
private:
|
||||
//! Rubberband that shows the limit
|
||||
//! Rubberband that highlights the limit segment
|
||||
std::unique_ptr<QgsRubberBand> mRubberBandLimit;
|
||||
//! Rubberband that extends the limit segment
|
||||
std::unique_ptr<QgsRubberBand> mRubberBandLimitExtend;
|
||||
//! Rubberband that shows the feature being extended
|
||||
std::unique_ptr<QgsRubberBand> mRubberBandExtend;
|
||||
//! Rubberband that shows the intersection point
|
||||
|
Loading…
x
Reference in New Issue
Block a user