Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix reshape for snapped point with Z #30108

Merged
merged 2 commits into from Jun 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/app/qgsmaptoolreshape.cpp
Expand Up @@ -121,9 +121,11 @@ void QgsMapToolReshape::reshape( QgsVectorLayer *vlayer )
bbox.combineExtentWith( points().at( i ).x(), points().at( i ).y() );
}

QgsLineString reshapeLineString( points() );
if ( QgsWkbTypes::hasZ( vlayer->wkbType() ) )
reshapeLineString.addZValue( defaultZValue() );

QgsPointSequence pts;
QVector<QgsPoint> points;
captureCurve()->points( pts );
QgsLineString reshapeLineString( pts );

//query all the features that intersect bounding box of capture line
QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( bbox ).setNoAttributes() );
Expand All @@ -143,7 +145,7 @@ void QgsMapToolReshape::reshape( QgsVectorLayer *vlayer )
{
// in case of a binding line, we just want to update the line from
// the starting point and not both side
if ( isBinding && !geom.asPolyline().contains( points().first() ) )
if ( isBinding && !geom.asPolyline().contains( pts.constFirst() ) )
continue;

reshapeReturn = geom.reshapeGeometry( reshapeLineString );
Expand Down
171 changes: 151 additions & 20 deletions tests/src/app/testqgsmaptoolreshape.cpp
Expand Up @@ -14,61 +14,191 @@
***************************************************************************/

#include "qgstest.h"
#include "qgsapplication.h"

#include "qgisapp.h"
#include "qgsadvanceddigitizingdockwidget.h"
#include "qgsgeometry.h"
#include "qgsmapcanvas.h"
#include "qgsvectorlayer.h"
#include "qgslinestring.h"
#include "qgsmapcanvassnappingutils.h"
#include "qgssnappingconfig.h"
#include "qgssnappingutils.h"
#include "qgsmaptoolreshape.h"
#include "qgisapp.h"
#include "qgsproject.h"
#include "qgssettings.h"
#include "qgsvectorlayer.h"
#include "qgsmapmouseevent.h"
#include "testqgsmaptoolutils.h"


class TestQgsMapToolReshape : public QObject
/**
* \ingroup UnitTests
* This is a unit test for the vertex tool
*/
class TestQgsMapToolReshape: public QObject
{
Q_OBJECT
public:
TestQgsMapToolReshape() = default;
TestQgsMapToolReshape();

private slots:
void initTestCase(); // will be called before the first testfunction is executed.
void cleanupTestCase(); // will be called after the last testfunction was executed.
void init(); // will be called before each testfunction is executed.
void cleanup(); // will be called after every testfunction.
void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase();// will be called after the last testfunction was executed.

void testReshapeZ();
void reshapeWithBindingLine();

private:
QgisApp *mQgisApp = nullptr;
QgsMapCanvas *mCanvas = nullptr;
QgsMapToolReshape *mCaptureTool = nullptr;
QgsVectorLayer *mLayerLineZ = nullptr;
QgsVectorLayer *mLayerPointZ = nullptr;
QgsVectorLayer *mLayerPolygonZ = nullptr;
};

TestQgsMapToolReshape::TestQgsMapToolReshape() = default;


//runs before all tests
void TestQgsMapToolReshape::initTestCase()
{
qDebug() << "TestMapToolCapture::initTestCase()";
// init QGIS's paths - true means that all path will be inited from prefix
QgsApplication::init();
QgsApplication::initQgis();

// Set up the QgsSettings environment
// Set up the QSettings environment
QCoreApplication::setOrganizationName( QStringLiteral( "QGIS" ) );
QCoreApplication::setOrganizationDomain( QStringLiteral( "qgis.org" ) );
QCoreApplication::setApplicationName( QStringLiteral( "QGIS-TEST" ) );

QgsApplication::showSettings();
mQgisApp = new QgisApp();

mCanvas = new QgsMapCanvas();

// enforce C locale because the tests expect it
// (decimal separators / thousand separators)
QLocale::setDefault( QLocale::c() );
mCanvas->setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:3946" ) ) );

mQgisApp = new QgisApp();
mCanvas->setFrameStyle( QFrame::NoFrame );
mCanvas->resize( 512, 512 );
mCanvas->setExtent( QgsRectangle( 0, 0, 8, 8 ) );
mCanvas->show(); // to make the canvas resize
mCanvas->hide();

// make testing layers
mLayerLineZ = new QgsVectorLayer( QStringLiteral( "LineStringZ?crs=EPSG:3946" ), QStringLiteral( "layer line Z" ), QStringLiteral( "memory" ) );
QVERIFY( mLayerLineZ->isValid() );
QgsProject::instance()->addMapLayers( QList<QgsMapLayer *>() << mLayerLineZ );

mLayerPointZ = new QgsVectorLayer( QStringLiteral( "PointZ?crs=EPSG:3946" ), QStringLiteral( "point Z" ), QStringLiteral( "memory" ) );
QVERIFY( mLayerPointZ->isValid() );
QgsProject::instance()->addMapLayers( QList<QgsMapLayer *>() << mLayerPointZ );

mLayerPolygonZ = new QgsVectorLayer( QStringLiteral( "PolygonZ?crs=EPSG:3946" ), QStringLiteral( "polygon Z" ), QStringLiteral( "memory" ) );
QVERIFY( mLayerPolygonZ->isValid() );
QgsProject::instance()->addMapLayers( QList<QgsMapLayer *>() << mLayerPolygonZ );

mLayerLineZ->startEditing();
QString wkt1 = "LineStringZ (0 0 0, 1 1 0, 1 2 0)";
QString wkt2 = "LineStringZ (2 1 5, 3 3 5)";
QgsFeature f1;
f1.setGeometry( QgsGeometry::fromWkt( wkt1 ) );
QgsFeature f2;
f2.setGeometry( QgsGeometry::fromWkt( wkt2 ) );

QgsFeatureList flist;
flist << f1 << f2;
mLayerLineZ->dataProvider()->addFeatures( flist );
QCOMPARE( mLayerLineZ->featureCount(), ( long )2 );
QCOMPARE( mLayerLineZ->getFeature( 1 ).geometry().asWkt(), wkt1 );
QCOMPARE( mLayerLineZ->getFeature( 2 ).geometry().asWkt(), wkt2 );

mLayerPointZ->startEditing();
QString wkt3 = "PointZ (5 5 5)";
QgsFeature f3;
f3.setGeometry( QgsGeometry::fromWkt( wkt3 ) );
QString wkt4 = "PointZ (6 6 6)";
QgsFeature f4;
f4.setGeometry( QgsGeometry::fromWkt( wkt4 ) );

QgsFeatureList flistPoint;
flistPoint << f3 << f4;
mLayerPointZ->dataProvider()->addFeatures( flistPoint );
QCOMPARE( mLayerPointZ->featureCount(), ( long )2 );
QCOMPARE( mLayerPointZ->getFeature( 1 ).geometry().asWkt(), wkt3 );
QCOMPARE( mLayerPointZ->getFeature( 2 ).geometry().asWkt(), wkt4 );

mLayerPolygonZ->startEditing();
QString wkt5 = "PolygonZ ((7 5 4, 3 2 1, 0 1 2, 7 5 4))";
QgsFeature f5;
f5.setGeometry( QgsGeometry::fromWkt( wkt5 ) );
QgsFeatureList flistPolygon;
flistPolygon << f5;
mLayerPolygonZ->dataProvider()->addFeatures( flistPolygon );
QCOMPARE( mLayerPolygonZ->featureCount(), ( long )1 );
QCOMPARE( mLayerPolygonZ->getFeature( 1 ).geometry().asWkt(), wkt5 );

QgsSnappingConfig cfg = mCanvas->snappingUtils()->config();
cfg.setMode( QgsSnappingConfig::AllLayers );
cfg.setTolerance( 100 );
cfg.setType( QgsSnappingConfig::VertexAndSegment );
cfg.setEnabled( true );
mCanvas->snappingUtils()->setConfig( cfg );

mCanvas->setLayers( QList<QgsMapLayer *>() << mLayerLineZ << mLayerPointZ << mLayerPolygonZ );
mCanvas->setCurrentLayer( mLayerLineZ );

// create the tool
mCaptureTool = new QgsMapToolReshape( mCanvas );
mCanvas->setMapTool( mCaptureTool );

QCOMPARE( mCanvas->mapSettings().outputSize(), QSize( 512, 512 ) );
QCOMPARE( mCanvas->mapSettings().visibleExtent(), QgsRectangle( 0, 0, 8, 8 ) );
}

//runs after all tests
void TestQgsMapToolReshape::cleanupTestCase()
{
delete mCaptureTool;
delete mCanvas;
QgsApplication::exitQgis();
}

void TestQgsMapToolReshape::init()
void TestQgsMapToolReshape::testReshapeZ()
{
}
TestQgsMapToolAdvancedDigitizingUtils utils( mCaptureTool );

// test with default Z value = 333
QgsSettings().setValue( QStringLiteral( "/qgis/digitizing/default_z_value" ), 333 );

QSet<QgsFeatureId> oldFids = utils.existingFeatureIds();

// snap on a linestringz layer
utils.mouseClick( 1, 2, Qt::LeftButton, Qt::KeyboardModifiers(), true );
utils.mouseClick( 2, 1, Qt::LeftButton, Qt::KeyboardModifiers(), true );
utils.mouseClick( 2, 1, Qt::RightButton );

QString wkt = "LineStringZ (0 0 0, 1 1 0, 1 2 0, 2 1 5)";
QCOMPARE( mLayerLineZ->getFeature( 1 ).geometry().asWkt(), wkt );

// snap on a pointz layer
utils.mouseClick( 2, 1, Qt::LeftButton, Qt::KeyboardModifiers(), true );
utils.mouseClick( 5, 5, Qt::LeftButton, Qt::KeyboardModifiers(), true );
utils.mouseClick( 6, 6, Qt::LeftButton, Qt::KeyboardModifiers(), true );
utils.mouseClick( 6, 6, Qt::RightButton );

QString wkt2 = "LineStringZ (0 0 0, 1 1 0, 1 2 0, 2 1 5, 5 5 5, 6 6 6)";
QCOMPARE( mLayerLineZ->getFeature( 1 ).geometry().asWkt(), wkt2 );

// snap on a polygonz layer
utils.mouseClick( 6, 6, Qt::LeftButton, Qt::KeyboardModifiers(), true );
utils.mouseClick( 7, 5, Qt::LeftButton, Qt::KeyboardModifiers(), true );
utils.mouseClick( 3, 2, Qt::LeftButton, Qt::KeyboardModifiers(), true );
utils.mouseClick( 3, 2, Qt::RightButton );

QString wkt3 = "LineStringZ (0 0 0, 1 1 0, 1 2 0, 2 1 5, 5 5 5, 6 6 6, 7 5 4, 3 2 1)";
QCOMPARE( mLayerLineZ->getFeature( 1 ).geometry().asWkt(), wkt3 );
mLayerLineZ->undoStack()->undo();

void TestQgsMapToolReshape::cleanup()
{
}

void TestQgsMapToolReshape::reshapeWithBindingLine()
Expand Down Expand Up @@ -139,5 +269,6 @@ void TestQgsMapToolReshape::reshapeWithBindingLine()
vl->rollBack();
}


QGSTEST_MAIN( TestQgsMapToolReshape )
#include "testqgsmaptoolreshape.moc"