Skip to content

Commit

Permalink
other approach
Browse files Browse the repository at this point in the history
  • Loading branch information
vcloarec authored and lbartoletti committed Oct 1, 2021
1 parent 2fb69d0 commit 812bbf9
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 44 deletions.
3 changes: 2 additions & 1 deletion python/core/auto_generated/qgspointlocator.sip.in
Expand Up @@ -195,10 +195,11 @@ The id of the feature to which the snapped geometry belongs.
Only for a valid edge match - obtain endpoints of the edge
%End

QgsPoint interpolatedPoint( const QgsCoordinateReferenceSystem &projectCrs, const QgsMapLayer *sourceLayer ) const;
QgsPoint interpolatedPoint( const QgsCoordinateReferenceSystem &destinationCrs ) const;
%Docstring
Convenient method to return a point on an edge with linear
interpolation of the Z value.
The parameter ``destinationCrs`` depends of where the instance of this Match is created (geom.cache: layer CRS, map canvas snapper: dest CRS)

.. versionadded:: 3.10
%End
Expand Down
2 changes: 1 addition & 1 deletion src/app/mesh/qgsmaptooleditmeshframe.cpp
Expand Up @@ -2574,7 +2574,7 @@ void QgsMapToolEditMeshFrame::addVertex(
zValue = currentZValue();
else if ( mapPointMatch.isValid() )
{
QgsPoint layerPoint = mapPointMatch.interpolatedPoint( QgsProject::instance()->crs(), mCurrentLayer );
QgsPoint layerPoint = mapPointMatch.interpolatedPoint( mCanvas->mapSettings().destinationCrs() );
zValue = layerPoint.z();
}
else if ( mCurrentFaceIndex != -1 ) //we are on a face -->interpolate the z value
Expand Down
60 changes: 47 additions & 13 deletions src/app/vertextool/qgsvertextool.cpp
Expand Up @@ -2094,16 +2094,56 @@ void QgsVertexTool::stopDragging()

QgsPoint QgsVertexTool::matchToLayerPoint( const QgsVectorLayer *destLayer, const QgsPointXY &mapPoint, const QgsPointLocator::Match *match )
{
// try to use point coordinates in the original CRS if it is the same
if ( match && match->hasVertex() && match->layer() && match->layer()->crs() == destLayer->crs() )
if ( match->layer() )
{
QgsFeature f;
QgsFeatureIterator fi = match->layer()->getFeatures( QgsFeatureRequest( match->featureId() ).setNoAttributes() );
if ( fi.nextFeature( f ) )
return f.geometry().vertexAt( match->vertexIndex() );
switch ( match->type() )
{
case QgsPointLocator::Vertex:
case QgsPointLocator::LineEndpoint:
case QgsPointLocator::All:
{
// use point coordinates of the layer
QgsFeature f;
QgsFeatureIterator fi = match->layer()->getFeatures( QgsFeatureRequest( match->featureId() ).setNoAttributes() );
if ( fi.nextFeature( f ) )
{
QgsPoint layerPoint = f.geometry().vertexAt( match->vertexIndex() );
if ( match->layer()->crs() == destLayer->crs() )
{
return layerPoint;
}
else
{
QgsCoordinateTransform transform( match->layer()->crs(), destLayer->crs(), mCanvas->mapSettings().transformContext() );
if ( transform.isValid() )
{
try
{
layerPoint.transform( transform );
return layerPoint;
}
catch ( QgsCsException & )
{
QgsDebugMsg( QStringLiteral( "transformation to layer coordinate failed" ) );
}
}
return layerPoint;
}
}
}
break;
case QgsPointLocator::Edge:
case QgsPointLocator::MiddleOfSegment:
return toLayerCoordinates( destLayer, match->interpolatedPoint( mCanvas->mapSettings().destinationCrs() ) );
break;
case QgsPointLocator::Invalid:
case QgsPointLocator::Area:
case QgsPointLocator::Centroid:
break;
}
}

// fall back to reprojection of the map point to layer point if they are not the same CRS
// fall back to reprojection of the map point to layer point
return QgsPoint( toLayerCoordinates( destLayer, mapPoint ) );
}

Expand Down Expand Up @@ -2133,12 +2173,6 @@ void QgsVertexTool::moveVertex( const QgsPointXY &mapPoint, const QgsPointLocato

QgsPoint layerPoint = matchToLayerPoint( dragLayer, mapPoint, mapPointMatch );

// needed to get Z value
if ( mapPointMatch && mapPointMatch->layer() && QgsWkbTypes::hasZ( mapPointMatch->layer()->wkbType() ) && ( mapPointMatch->hasEdge() || mapPointMatch->hasMiddleSegment() ) )
{
layerPoint = mapPointMatch->interpolatedPoint( QgsProject::instance()->crs(), dragLayer );
}

QgsVertexId vid;
if ( !geom.vertexIdFromVertexNr( dragVertexId, vid ) )
{
Expand Down
66 changes: 37 additions & 29 deletions src/core/qgspointlocator.h
Expand Up @@ -261,42 +261,50 @@ class CORE_EXPORT QgsPointLocator : public QObject
/**
* Convenient method to return a point on an edge with linear
* interpolation of the Z value.
* The parameter \a destinationCrs depends of where the instance of this Match is created (geom.cache: layer CRS, map canvas snapper: dest CRS)
* \since 3.10
*/
QgsPoint interpolatedPoint( const QgsCoordinateReferenceSystem &projectCrs, const QgsMapLayer *sourceLayer ) const
QgsPoint interpolatedPoint( const QgsCoordinateReferenceSystem &destinationCrs ) const
{
QgsPoint point;
QgsPoint snappedPoint( mPoint );
const QgsGeometry geom = mLayer->getGeometry( mFid );
try
{
if ( mLayer )
snappedPoint.transform( QgsCoordinateTransform( projectCrs, mLayer->crs(), mLayer->transformContext() ) );
}
catch ( QgsCsException &cse )
{
Q_UNUSED( cse )
QgsDebugMsg( QStringLiteral( "transformation to layer coordinate failed" ) );
return QgsPoint();
}

if ( !( geom.isNull() || geom.isEmpty() ) )
if ( mLayer )
{
const QgsLineString line( geom.vertexAt( mVertexIndex ), geom.vertexAt( mVertexIndex + 1 ) );
point = QgsGeometryUtils::closestPoint( line, snappedPoint );
}
// (re)Transform layerPoint to vlayer crs
try
{
if ( sourceLayer )
point.transform( QgsCoordinateTransform( mLayer->crs(), sourceLayer->crs(), sourceLayer->transformContext() ) );
}
catch ( QgsCsException &cse )
{
Q_UNUSED( cse )
QgsDebugMsg( QStringLiteral( "transformation to layer coordinate failed" ) );
return QgsPoint();
QgsPointXY snappedPoint( mPoint );
const QgsGeometry geom = mLayer->getGeometry( mFid );
QgsCoordinateTransform transform( destinationCrs, mLayer->crs(), mLayer->transformContext() );
if ( transform.isValid() )
{
try
{
snappedPoint = transform.transform( snappedPoint );
}
catch ( QgsCsException & )
{
QgsDebugMsg( QStringLiteral( "transformation to layer coordinate failed" ) );
}
}

if ( !( geom.isNull() || geom.isEmpty() ) )
{
const QgsLineString line( geom.vertexAt( mVertexIndex ), geom.vertexAt( mVertexIndex + 1 ) );
point = QgsGeometryUtils::closestPoint( line, QgsPoint( snappedPoint ) );
}


if ( transform.isValid() )
{
try
{
point.transform( transform, QgsCoordinateTransform::ReverseTransform );
}
catch ( QgsCsException & )
{
QgsDebugMsg( QStringLiteral( "transformation to destination coordinate failed" ) );
}
}
}

return point;
}

Expand Down

0 comments on commit 812bbf9

Please sign in to comment.