Skip to content
Permalink
Browse files
Merge pull request #42966 from uclaros/scale-with-crs
Fix scale tool when map and layer have different crs
  • Loading branch information
nyalldawson committed Apr 27, 2021
2 parents 729792d + 88a78dc commit fc51887aa41ae2b52ca23d07da6f135b632123b6
Showing with 42 additions and 8 deletions.
  1. +12 −8 src/app/qgsmaptoolscalefeature.cpp
  2. +30 −0 tests/src/app/testqgsmaptoolscalefeature.cpp
@@ -244,6 +244,8 @@ void QgsMapToolScaleFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
if ( minDistance == std::numeric_limits<double>::max() )
{
emit messageEmitted( tr( "Could not find a nearby feature in the current layer." ) );
if ( mAutoSetAnchorPoint )
mAnchorPoint.reset();
return;
}

@@ -317,15 +319,16 @@ void QgsMapToolScaleFeature::updateRubberband( double scale )
{
mScaling = scale;

QTransform t;
t.translate( mFeatureCenterMapCoords.x(), mFeatureCenterMapCoords.y() );
t.scale( mScaling, mScaling );
t.translate( -mFeatureCenterMapCoords.x(), -mFeatureCenterMapCoords.y() );

QgsVectorLayer *vlayer = currentVectorLayer();
if ( !vlayer )
return;

QgsPointXY layerCoords = toLayerCoordinates( vlayer, mFeatureCenterMapCoords );
QTransform t;
t.translate( layerCoords.x(), layerCoords.y() );
t.scale( mScaling, mScaling );
t.translate( -layerCoords.x(), -layerCoords.y() );

mRubberBand->reset( vlayer->geometryType() );
for ( const QgsGeometry &originalGeometry : mOriginalGeometries )
{
@@ -355,10 +358,11 @@ void QgsMapToolScaleFeature::applyScaling( double scale )

vlayer->beginEditCommand( tr( "Features Scaled" ) );

QgsPointXY layerCoords = toLayerCoordinates( vlayer, mFeatureCenterMapCoords );
QTransform t;
t.translate( mFeatureCenterMapCoords.x(), mFeatureCenterMapCoords.y() );
t.translate( layerCoords.x(), layerCoords.y() );
t.scale( mScaling, mScaling );
t.translate( -mFeatureCenterMapCoords.x(), -mFeatureCenterMapCoords.y() );
t.translate( -layerCoords.x(), -layerCoords.y() );

for ( QgsFeatureId id : std::as_const( mScaledFeatures ) )
{
@@ -407,7 +411,7 @@ void QgsMapToolScaleFeature::activate()
if ( vlayer->selectedFeatureCount() > 0 )
{
mExtent = vlayer->boundingBoxOfSelected();
mFeatureCenterMapCoords = mExtent.center();
mFeatureCenterMapCoords = toMapCoordinates( vlayer, mExtent.center() );

mAnchorPoint = std::make_unique<QgsVertexMarker>( mCanvas );
mAnchorPoint->setIconType( QgsVertexMarker::ICON_CROSS );
@@ -49,6 +49,7 @@ class TestQgsMapToolScaleFeature: public QObject
void testScaleFeatureWithAnchorSetAfterStart();
void testScaleSelectedFeatures();
void testScaleFeatureManualAnchorSnapping();
void testScaleFeatureDifferentCrs();

private:
QgisApp *mQgisApp = nullptr;
@@ -261,6 +262,35 @@ void TestQgsMapToolScaleFeature::testScaleFeatureManualAnchorSnapping()
cfg.setTolerance( tolerance );
cfg.setUnits( units );
mCanvas->snappingUtils()->setConfig( cfg );

// remove manual anchor point via right click
utils.mouseClick( 10, 25, Qt::RightButton, Qt::KeyboardModifiers(), true );
}

void TestQgsMapToolScaleFeature::testScaleFeatureDifferentCrs()
{
mCanvas->setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) );
TestQgsMapToolUtils utils( mScaleTool );

//scale up
utils.mouseClick( -8.82187821744550682, 2.0909475540607434, Qt::LeftButton, Qt::KeyboardModifiers(), true );
utils.mouseMove( -8.82188215592444536, 2.09095048559432861 );
utils.mouseClick( -8.82188215592444536, 2.09095048559432861, Qt::LeftButton, Qt::KeyboardModifiers(), true );

QCOMPARE( mLayerBase->getFeature( 1 ).geometry().asWkt( 2 ), QStringLiteral( "Polygon ((-2.5 -2.5, -2.5 -0.5, -0.5 -0.5, -0.5 -2.5, -2.5 -2.5))" ) );
QCOMPARE( mLayerBase->getFeature( 2 ).geometry().asWkt( 2 ), QStringLiteral( "Polygon ((1.1 0.8, 1.1 5, 2.1 5, 2.1 0.8, 1.1 0.8))" ) );

//scale down
utils.mouseClick( -8.82185881943214234, 2.09096315856551129, Qt::LeftButton, Qt::KeyboardModifiers(), true );
utils.mouseMove( -8.82185818217576667, 2.09097065484482636 );
utils.mouseClick( -8.82185818217576667, 2.09097065484482636, Qt::LeftButton, Qt::KeyboardModifiers(), true );

QCOMPARE( mLayerBase->getFeature( 1 ).geometry().asWkt( 2 ), QStringLiteral( "Polygon ((-2.5 -2.5, -2.5 -0.5, -0.5 -0.5, -0.5 -2.5, -2.5 -2.5))" ) );
QCOMPARE( mLayerBase->getFeature( 2 ).geometry().asWkt( 2 ), QStringLiteral( "Polygon ((1.35 1.84, 1.35 3.96, 1.85 3.96, 1.85 1.84, 1.35 1.84))" ) );

mLayerBase->undoStack()->undo();
mLayerBase->undoStack()->undo();
mCanvas->setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) );
}

QGSTEST_MAIN( TestQgsMapToolScaleFeature )

0 comments on commit fc51887

Please sign in to comment.