Skip to content

Commit

Permalink
Merge pull request #9294 from lbartoletti/bugfix_21390_pointZ_snapping
Browse files Browse the repository at this point in the history
Fix Z snapping for point.
  • Loading branch information
m-kuhn authored Mar 25, 2019
2 parents e5f0522 + 0cb0e38 commit 9327834
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 23 deletions.
28 changes: 19 additions & 9 deletions src/app/qgsmaptooldigitizefeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,31 @@ void QgsMapToolDigitizeFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
return;
}

QgsPointXY savePoint; //point in layer coordinates
QgsPoint savePoint; //point in layer coordinates
bool isMatchPointZ = false;
try
{
QgsPoint fetchPoint;
int res;
res = fetchLayerPoint( e->mapPointMatch(), fetchPoint );
if ( QgsWkbTypes::hasZ( fetchPoint.wkbType() ) )
isMatchPointZ = true;

if ( res == 0 )
{
savePoint = QgsPointXY( fetchPoint.x(), fetchPoint.y() );
if ( isMatchPointZ )
savePoint = fetchPoint;
else
savePoint = QgsPoint( fetchPoint.x(), fetchPoint.y() );
}
else
{
savePoint = toLayerCoordinates( vlayer, e->mapPoint() );
QgsPointXY layerPoint = toLayerCoordinates( vlayer, e->mapPoint() );
if ( isMatchPointZ )
savePoint = QgsPoint( QgsWkbTypes::PointZ, layerPoint.x(), layerPoint.y(), fetchPoint.z() );
else
savePoint = QgsPoint( layerPoint.x(), layerPoint.y() );
}
QgsDebugMsg( "savePoint = " + savePoint.toString() );
}
catch ( QgsCsException &cse )
{
Expand All @@ -171,11 +181,11 @@ void QgsMapToolDigitizeFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
QgsGeometry g;
if ( layerWKBType == QgsWkbTypes::Point )
{
g = QgsGeometry::fromPointXY( savePoint );
g = QgsGeometry( qgis::make_unique<QgsPoint>( savePoint ) );
}
else if ( !QgsWkbTypes::isMultiType( layerWKBType ) && QgsWkbTypes::hasZ( layerWKBType ) )
{
g = QgsGeometry( new QgsPoint( QgsWkbTypes::PointZ, savePoint.x(), savePoint.y(), defaultZValue() ) );
g = QgsGeometry( qgis::make_unique<QgsPoint>( savePoint.x(), savePoint.y(), isMatchPointZ ? savePoint.z() : defaultZValue() ) );
}
else if ( QgsWkbTypes::isMultiType( layerWKBType ) && !QgsWkbTypes::hasZ( layerWKBType ) )
{
Expand All @@ -184,13 +194,13 @@ void QgsMapToolDigitizeFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
else if ( QgsWkbTypes::isMultiType( layerWKBType ) && QgsWkbTypes::hasZ( layerWKBType ) )
{
QgsMultiPoint *mp = new QgsMultiPoint();
mp->addGeometry( new QgsPoint( QgsWkbTypes::PointZ, savePoint.x(), savePoint.y(), defaultZValue() ) );
g = QgsGeometry( mp );
mp->addGeometry( new QgsPoint( QgsWkbTypes::PointZ, savePoint.x(), savePoint.y(), isMatchPointZ ? savePoint.z() : defaultZValue() ) );
g.set( mp );
}
else
{
// if layer supports more types (mCheckGeometryType is false)
g = QgsGeometry::fromPointXY( savePoint );
g = QgsGeometry( qgis::make_unique<QgsPoint>( savePoint ) );
}

if ( QgsWkbTypes::hasM( layerWKBType ) )
Expand Down
3 changes: 2 additions & 1 deletion tests/src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,8 @@ ADD_QGIS_TEST(qgisappclipboard testqgisappclipboard.cpp)
ADD_QGIS_TEST(attributetabletest testqgsattributetable.cpp)
ADD_QGIS_TEST(applocatorfilters testqgsapplocatorfilters.cpp)
ADD_QGIS_TEST(fieldcalculatortest testqgsfieldcalculator.cpp)
ADD_QGIS_TEST(maptooladdfeature testqgsmaptooladdfeature.cpp)
ADD_QGIS_TEST(maptooladdfeatureline testqgsmaptooladdfeatureline.cpp)
ADD_QGIS_TEST(maptooladdfeaturepoint testqgsmaptooladdfeaturepoint.cpp)
ADD_QGIS_TEST(maptoolidentifyaction testqgsmaptoolidentifyaction.cpp)
ADD_QGIS_TEST(maptoolselect testqgsmaptoolselect.cpp)
ADD_QGIS_TEST(maptoolreshape testqgsmaptoolreshape.cpp)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/***************************************************************************
testqgsmaptooladdfeature.cpp
testqgsmaptooladdfeatureline.cpp
----------------------
Date : October 2017
Copyright : (C) 2017 by Martin Dobias
Expand Down Expand Up @@ -53,11 +53,11 @@ namespace QTest
* \ingroup UnitTests
* This is a unit test for the vertex tool
*/
class TestQgsMapToolAddFeature : public QObject
class TestQgsMapToolAddFeatureLine : public QObject
{
Q_OBJECT
public:
TestQgsMapToolAddFeature();
TestQgsMapToolAddFeatureLine();

private slots:
void initTestCase();// will be called before the first testfunction is executed.
Expand All @@ -81,11 +81,11 @@ class TestQgsMapToolAddFeature : public QObject
QgsFeatureId mFidLineF1 = 0;
};

TestQgsMapToolAddFeature::TestQgsMapToolAddFeature() = default;
TestQgsMapToolAddFeatureLine::TestQgsMapToolAddFeatureLine() = default;


//runs before all tests
void TestQgsMapToolAddFeature::initTestCase()
void TestQgsMapToolAddFeatureLine::initTestCase()
{
qDebug() << "TestMapToolCapture::initTestCase()";
// init QGIS's paths - true means that all path will be inited from prefix
Expand Down Expand Up @@ -177,14 +177,14 @@ void TestQgsMapToolAddFeature::initTestCase()
}

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

void TestQgsMapToolAddFeature::testNoTracing()
void TestQgsMapToolAddFeatureLine::testNoTracing()
{
TestQgsMapToolAdvancedDigitizingUtils utils( mCaptureTool );

Expand All @@ -205,7 +205,7 @@ void TestQgsMapToolAddFeature::testNoTracing()
QCOMPARE( mLayerLine->undoStack()->index(), 1 );
}

void TestQgsMapToolAddFeature::testTracing()
void TestQgsMapToolAddFeatureLine::testTracing()
{
TestQgsMapToolAdvancedDigitizingUtils utils( mCaptureTool );

Expand Down Expand Up @@ -250,7 +250,7 @@ void TestQgsMapToolAddFeature::testTracing()
mEnableTracingAction->setChecked( false );
}

void TestQgsMapToolAddFeature::testTracingWithOffset()
void TestQgsMapToolAddFeatureLine::testTracingWithOffset()
{
TestQgsMapToolAdvancedDigitizingUtils utils( mCaptureTool );

Expand Down Expand Up @@ -328,7 +328,7 @@ void TestQgsMapToolAddFeature::testTracingWithOffset()
mEnableTracingAction->setChecked( false );
}

void TestQgsMapToolAddFeature::testZ()
void TestQgsMapToolAddFeatureLine::testZ()
{
TestQgsMapToolAdvancedDigitizingUtils utils( mCaptureTool );

Expand Down Expand Up @@ -369,7 +369,7 @@ void TestQgsMapToolAddFeature::testZ()
mCanvas->setCurrentLayer( mLayerLine );
}

void TestQgsMapToolAddFeature::testZMSnapping()
void TestQgsMapToolAddFeatureLine::testZMSnapping()
{
TestQgsMapToolAdvancedDigitizingUtils utils( mCaptureTool );

Expand Down Expand Up @@ -397,5 +397,5 @@ void TestQgsMapToolAddFeature::testZMSnapping()
mCanvas->snappingUtils()->setConfig( cfg );
}

QGSTEST_MAIN( TestQgsMapToolAddFeature )
#include "testqgsmaptooladdfeature.moc"
QGSTEST_MAIN( TestQgsMapToolAddFeatureLine )
#include "testqgsmaptooladdfeatureline.moc"
168 changes: 168 additions & 0 deletions tests/src/app/testqgsmaptooladdfeaturepoint.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/***************************************************************************
testqgsmaptooladdfeaturepoint.cpp
----------------------
Date : October 2017
Copyright : (C) 2017 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgstest.h"

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


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

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 testPointZ();

private:
QgisApp *mQgisApp = nullptr;
QgsMapCanvas *mCanvas = nullptr;
QgsMapToolAddFeature *mCaptureTool = nullptr;
QgsVectorLayer *mLayerPointZSnap = nullptr;
QgsVectorLayer *mLayerPointZ = nullptr;
};

TestQgsMapToolAddFeaturePoint::TestQgsMapToolAddFeaturePoint() = default;


//runs before all tests
void TestQgsMapToolAddFeaturePoint::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 QSettings environment
QCoreApplication::setOrganizationName( QStringLiteral( "QGIS" ) );
QCoreApplication::setOrganizationDomain( QStringLiteral( "qgis.org" ) );
QCoreApplication::setApplicationName( QStringLiteral( "QGIS-TEST" ) );

mQgisApp = new QgisApp();

mCanvas = new QgsMapCanvas();

mCanvas->setDestinationCrs( QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:27700" ) ) );

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
mLayerPointZ = new QgsVectorLayer( QStringLiteral( "PointZ?crs=EPSG:27700" ), QStringLiteral( "layer point Z" ), QStringLiteral( "memory" ) );
QVERIFY( mLayerPointZ->isValid() );
QgsProject::instance()->addMapLayers( QList<QgsMapLayer *>() << mLayerPointZ );

mLayerPointZ->startEditing();
QgsFeature pointFZ;
QString pointWktZ = "PointZ(7 7 4)";
pointFZ.setGeometry( QgsGeometry::fromWkt( pointWktZ ) );

mLayerPointZ->addFeature( pointFZ );
QCOMPARE( mLayerPointZ->featureCount(), ( long )1 );

// make layer for snapping
mLayerPointZSnap = new QgsVectorLayer( QStringLiteral( "PointZ?crs=EPSG:27700" ), QStringLiteral( "Snap point" ), QStringLiteral( "memory" ) );
QVERIFY( mLayerPointZSnap->isValid() );
QgsProject::instance()->addMapLayers( QList<QgsMapLayer *>() << mLayerPointZSnap );

mLayerPointZSnap->startEditing();
QgsFeature pointF;
QString pointWktZSnap = "PointZ(6 6 3)";
pointF.setGeometry( QgsGeometry::fromWkt( pointWktZSnap ) );

mLayerPointZSnap->addFeature( pointF );
QCOMPARE( mLayerPointZSnap->featureCount(), ( long )1 );

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 *>() << mLayerPointZ << mLayerPointZSnap );
mCanvas->setCurrentLayer( mLayerPointZ );

// create the tool
mCaptureTool = new QgsMapToolAddFeature( mCanvas, /*mAdvancedDigitizingDockWidget, */ QgsMapToolCapture::CapturePoint );
mCanvas->setMapTool( mCaptureTool );

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

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

void TestQgsMapToolAddFeaturePoint::testPointZ()
{
TestQgsMapToolAdvancedDigitizingUtils utils( mCaptureTool );

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

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

utils.mouseClick( 4, 0, Qt::LeftButton, Qt::KeyboardModifiers(), true );
QgsFeatureId newFid = utils.newFeatureId( oldFids );

QCOMPARE( mLayerPointZ->featureCount(), ( long )2 );

QString wkt = "PointZ (4 0 333)";
QCOMPARE( mLayerPointZ->getFeature( newFid ).geometry().asWkt(), wkt );

mLayerPointZ->undoStack()->undo();

oldFids = utils.existingFeatureIds();
utils.mouseClick( 6, 6, Qt::LeftButton, Qt::KeyboardModifiers(), true );
newFid = utils.newFeatureId( oldFids );

wkt = "PointZ (6 6 3)";
QCOMPARE( mLayerPointZ->getFeature( newFid ).geometry().asWkt(), wkt );

mLayerPointZ->undoStack()->undo();
}

QGSTEST_MAIN( TestQgsMapToolAddFeaturePoint )
#include "testqgsmaptooladdfeaturepoint.moc"

0 comments on commit 9327834

Please sign in to comment.