Skip to content

Commit

Permalink
fix edge search in mesh element tool
Browse files Browse the repository at this point in the history
* fix edge search in mesh element tool

* fix QgsMeshLayer::closestEdge()

* add test for hovered elements duing mesh editing

* add test for snapping on mesh element with geographic coordinates
  • Loading branch information
vcloarec committed Oct 14, 2022
1 parent 3eaf823 commit a8e8f97
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/app/mesh/qgsmaptooleditmeshframe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1374,7 +1374,7 @@ void QgsMapToolEditMeshFrame::searchEdge( const QgsPointXY &mapPoint )
const QgsPointXY pt2 = mapVertexXY( iv2 );

QgsPointXY pointOneEdge;
double distance = sqrt( mapPoint.sqrDistToSegment( pt1.x(), pt1.y(), pt2.x(), pt2.y(), pointOneEdge ) );
double distance = sqrt( mapPoint.sqrDistToSegment( pt1.x(), pt1.y(), pt2.x(), pt2.y(), pointOneEdge, 0 ) );
if ( distance < tolerance && distance < minimumDistance && edgeCanBeInteractive( iv1, iv2 ) )
{
mCurrentEdge = {faceIndex, iv2};
Expand Down
2 changes: 1 addition & 1 deletion src/core/mesh/qgsmeshlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ int QgsMeshLayer::closestEdge( const QgsPointXY &point, double searchRadius, Qgs
const QgsMeshVertex &vertex1 = mesh->vertices()[edge.first];
const QgsMeshVertex &vertex2 = mesh->vertices()[edge.second];
QgsPointXY projPoint;
const double sqrDist = point.sqrDistToSegment( vertex1.x(), vertex1.y(), vertex2.x(), vertex2.y(), projPoint );
const double sqrDist = point.sqrDistToSegment( vertex1.x(), vertex1.y(), vertex2.x(), vertex2.y(), projPoint, 0 );
if ( sqrDist < sqrMaxDistFromPoint )
{
selectedIndex = edgeIndex;
Expand Down
57 changes: 49 additions & 8 deletions tests/src/app/testqgsmaptooleditmesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class TestQgsMapToolEditMesh : public QObject
void init(); // will be called before each testfunction is executed.
void cleanup() {} // will be called after every testfunction.

void hoverElements();

void editMesh();

private:
Expand All @@ -41,6 +43,8 @@ class TestQgsMapToolEditMesh : public QObject
QString mDataDir;
std::unique_ptr<QgsMapCanvas> mCanvas;
QgsMapToolEditMeshFrame *mEditMeshMapTool;

std::unique_ptr<QgsMeshLayer> meshLayerSimpleBox;
};


Expand All @@ -52,28 +56,65 @@ void TestQgsMapToolEditMesh::initTestCase()
mQgisApp = new QgisApp();
mDataDir = QString( TEST_DATA_DIR ); //defined in CmakeLists.txt
mDataDir += "/mesh";
}

void TestQgsMapToolEditMesh::init()
{
mCanvas.reset( new QgsMapCanvas() );
mEditMeshMapTool = new QgsMapToolEditMeshFrame( mCanvas.get() );
}

void TestQgsMapToolEditMesh::init()
void TestQgsMapToolEditMesh::hoverElements()
{
QString uri = QString( mDataDir + "/simplebox_clm.nc" );
meshLayerSimpleBox.reset( new QgsMeshLayer( uri, "Simple box", "mdal" ) );
QVERIFY( meshLayerSimpleBox->isValid() );

mCanvas->setLayers( QList<QgsMapLayer *>() << meshLayerSimpleBox.get() );

QgsCoordinateReferenceSystem wgs84Crs;
wgs84Crs.createFromProj( "+proj=longlat +datum=WGS84 +no_defs" );
QVERIFY( wgs84Crs.isValid() );
QVERIFY( meshLayerSimpleBox->crs().isValid() );
mCanvas->setDestinationCrs( wgs84Crs );

QgsCoordinateTransform transform( meshLayerSimpleBox->crs(), mCanvas->mapSettings().destinationCrs(), QgsProject::instance() );
QVERIFY( meshLayerSimpleBox->startFrameEditing( transform ) );

QgsRectangle extent( 3.31351393, 47.97489613, 3.31351792, 47.97508220 );
mCanvas->setExtent( extent );
TestQgsMapToolAdvancedDigitizingUtils tool( mEditMeshMapTool );
mCanvas->setCurrentLayer( meshLayerSimpleBox.get() );
mEditMeshMapTool->mActionDigitizing->trigger();
tool.mouseMove( 3.31376427, 47.97500487 );
QCOMPARE( mEditMeshMapTool->mCurrentFaceIndex, 8 );
QVERIFY( mEditMeshMapTool->mCurrentEdge == QgsMapToolEditMeshFrame::Edge( {-1, -1} ) );
QCOMPARE( mEditMeshMapTool->mCurrentVertexIndex, -1 );

tool.mouseMove( 3.31368247, 47.97500500 );
QCOMPARE( mEditMeshMapTool->mCurrentFaceIndex, 8 );
QVERIFY( mEditMeshMapTool->mCurrentEdge == QgsMapToolEditMeshFrame::Edge( {8, 5} ) );
QCOMPARE( mEditMeshMapTool->mCurrentVertexIndex, -1 );

tool.mouseMove( 3.31368064, 47.97503705 );
QCOMPARE( mEditMeshMapTool->mCurrentFaceIndex, 8 );
QVERIFY( mEditMeshMapTool->mCurrentEdge == QgsMapToolEditMeshFrame::Edge( {8, 5} ) );
QCOMPARE( mEditMeshMapTool->mCurrentVertexIndex, 10 );
}

void TestQgsMapToolEditMesh::editMesh()
{
const QString uri = QString( mDataDir + "/quad_flower.2dm" );
QString uri = QString( mDataDir + "/quad_flower.2dm" );
meshLayerQuadFlower.reset( new QgsMeshLayer( uri, "Quad Flower", "mdal" ) );
QVERIFY( meshLayerQuadFlower );
QVERIFY( meshLayerQuadFlower->isValid() );
QCOMPARE( meshLayerQuadFlower->datasetGroupCount(), 1 );

const QgsCoordinateTransform transform;
meshLayerQuadFlower->startFrameEditing( transform );

mCanvas->setLayers( QList<QgsMapLayer *>() << meshLayerQuadFlower.get() );
}

void TestQgsMapToolEditMesh::editMesh()
{
const double offsetInMapUnits = 15 * mCanvas->mapSettings().mapUnitsPerPixel();

const QgsCoordinateTransform transform;
QVERIFY( meshLayerQuadFlower->meshEditor() );

TestQgsMapToolAdvancedDigitizingUtils tool( mEditMeshMapTool );
Expand Down
43 changes: 42 additions & 1 deletion tests/src/core/testqgsmeshlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1279,7 +1279,7 @@ void TestQgsMeshLayer::test_snap_on_mesh()
{
//1D mesh
mMdal1DLayer->updateTriangularMesh();
const double searchRadius = 10;
double searchRadius = 10;

QgsPointXY snappedPoint;

Expand Down Expand Up @@ -1318,6 +1318,47 @@ void TestQgsMeshLayer::test_snap_on_mesh()
QCOMPARE( snappedPoint, QgsPointXY( 2333.33333333, 2333.333333333 ) );
snappedPoint = mMdalLayer->snapOnElement( QgsMesh::Face, QgsPointXY( 500, 500 ), searchRadius );
QCOMPARE( snappedPoint, QgsPointXY() );

// same test but with coordinates in geographic system with transform coordinates
QgsCoordinateReferenceSystem wgs84Crs;
wgs84Crs.createFromProj( "+proj=longlat +datum=WGS84 +no_defs" );
QVERIFY( wgs84Crs.isValid() );
QgsCoordinateReferenceSystem EPSG32620crs;
EPSG32620crs.createFromProj( "+proj=utm +zone=20 +datum=WGS84 +units=m +no_defs" );

//1D mesh
mMdal1DLayer->setCrs( EPSG32620crs );
QgsCoordinateTransform transform( EPSG32620crs, wgs84Crs, QgsProject::instance() );
mMdal1DLayer->updateTriangularMesh( transform );
searchRadius = 1;
snappedPoint = mMdal1DLayer->snapOnElement( QgsMesh::Vertex, QgsPointXY(), searchRadius );
QCOMPARE( snappedPoint, QgsPointXY() );
snappedPoint = mMdal1DLayer->snapOnElement( QgsMesh::Vertex, transform.transform( QgsPointXY( 1002, 2005 ) ), searchRadius );
QCOMPARE( snappedPoint, transform.transform( QgsPointXY( 1000, 2000 ) ) );
snappedPoint = mMdal1DLayer->snapOnElement( QgsMesh::Edge, transform.transform( QgsPointXY( 1002, 2005 ) ), searchRadius );
QCOMPARE( snappedPoint, transform.transform( QgsPointXY( 1002, 2000 ) ) );
snappedPoint = mMdal1DLayer->snapOnElement( QgsMesh::Edge, transform.transform( QgsPointXY( 998, 2005 ) ), searchRadius );
QCOMPARE( snappedPoint, transform.transform( QgsPointXY( 1000, 2000 ) ) );
snappedPoint = mMdal1DLayer->snapOnElement( QgsMesh::Vertex, transform.transform( QgsPointXY( 2002, 2998 ) ), searchRadius );
QCOMPARE( snappedPoint, transform.transform( QgsPointXY( 2000, 3000 ) ) );

//2D mesh
mMdalLayer->setCrs( EPSG32620crs );
mMdalLayer->updateTriangularMesh( transform );
snappedPoint = mMdalLayer->snapOnElement( QgsMesh::Vertex, QgsPointXY(), searchRadius );
QCOMPARE( snappedPoint, QgsPointXY() );
snappedPoint = mMdalLayer->snapOnElement( QgsMesh::Vertex, QgsPointXY(), searchRadius );
QCOMPARE( snappedPoint, QgsPointXY() );
snappedPoint = mMdalLayer->snapOnElement( QgsMesh::Vertex, transform.transform( QgsPointXY( 1002, 2005 ) ), searchRadius );
QCOMPARE( snappedPoint, transform.transform( QgsPointXY( 1000, 2000 ) ) );
snappedPoint = mMdalLayer->snapOnElement( QgsMesh::Vertex, transform.transform( QgsPointXY( 2002, 2998 ) ), searchRadius );
QCOMPARE( snappedPoint, transform.transform( QgsPointXY( 2000, 3000 ) ) );
snappedPoint = mMdalLayer->snapOnElement( QgsMesh::Face, transform.transform( QgsPointXY( 998, 1998 ) ), searchRadius );
QCOMPARE( snappedPoint, transform.transform( QgsPointXY( 1500, 2500 ) ) );
snappedPoint = mMdalLayer->snapOnElement( QgsMesh::Face, transform.transform( QgsPointXY( 1002, 2001 ) ), searchRadius );
QCOMPARE( snappedPoint, transform.transform( QgsPointXY( 1500, 2500 ) ) );
snappedPoint = mMdalLayer->snapOnElement( QgsMesh::Face, transform.transform( QgsPointXY( 1998, 2998 ) ), searchRadius );
QCOMPARE( snappedPoint, transform.transform( QgsPointXY( 1500, 2500 ) ) );
}

void TestQgsMeshLayer::test_dataset_value_from_layer()
Expand Down

0 comments on commit a8e8f97

Please sign in to comment.