Skip to content
Permalink
Browse files

Merge pull request #7711 from m-kuhn/mapToolSnapToGrid

Snap to grid for maptools [FEATURE]
  • Loading branch information
m-kuhn committed Sep 8, 2018
2 parents 0cc9501 + d57c184 commit 32ee71634fe96699964fa86dea98273454f977db
@@ -117,6 +117,15 @@ The unsnapped, real mouse cursor position in pixel coordinates.
Alias to pos()

:return: Mouse position in pixel coordinates
%End

void snapToGrid( double precision, const QgsCoordinateReferenceSystem &crs );
%Docstring
Snaps the mapPoint to a grid with the given ``precision``.
The snapping will be done in the specified ``crs``. If this crs is
different from the mapCanvas crs, it will be reprojected on the fly.

.. versionadded:: 3.4
%End

};
@@ -149,6 +149,22 @@ canvasMoveEvent is triggered and it's not hidden by the cad's
construction mode.

:param e: Mouse events prepared by the cad system
%End

bool snapToLayerGridEnabled() const;
%Docstring
Enables or disables snap to grid of mouse events.
The snapping will occur in the layer's CRS.

.. versionadded:: 3.4
%End

void setSnapToLayerGridEnabled( bool snapToLayerGridEnabled );
%Docstring
Enables or disables snap to grid of mouse events.
The snapping will occur in the layer's CRS.

.. versionadded:: 3.4
%End

};
@@ -0,0 +1,92 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgssnaptogridcanvasitem.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/




class QgsSnapToGridCanvasItem : QObject, QgsMapCanvasItem
{
%Docstring

Shows a grid on the map canvas given a spatial resolution.

.. versionadded:: 3.4
%End

%TypeHeaderCode
#include "qgssnaptogridcanvasitem.h"
%End
public:

QgsSnapToGridCanvasItem( QgsMapCanvas *mapCanvas /TransferThis/ );
%Docstring
Will automatically be added to the ``mapCanvas``.
%End

virtual void paint( QPainter *painter );


QgsPointXY point() const;
%Docstring
A point that will be highlighted on the map canvas.
The point needs to be in map coordinates. The closest point on the
grid will be highlighted.
%End

void setPoint( const QgsPointXY &point );
%Docstring
A point that will be highlighted on the map canvas.
The point needs to be in map coordinates. The closest point on the
grid will be highlighted.
%End

double precision() const;
%Docstring
The resolution of the grid in map units.
If a crs has been specified it will be in CRS units.
%End

void setPrecision( double precision );
%Docstring
The resolution of the grid in map units.
If a crs has been specified it will be in CRS units.
%End

QgsCoordinateReferenceSystem crs() const;
%Docstring
The CRS in which the grid should be calculated.
By default will be an invalid QgsCoordinateReferenceSystem and
as such equal to the CRS of the map canvas.
%End

void setCrs( const QgsCoordinateReferenceSystem &crs );
%Docstring
The CRS in which the grid should be calculated.
By default will be an invalid QgsCoordinateReferenceSystem and
as such equal to the CRS of the map canvas.
%End

bool enabled() const;
%Docstring
Enable this item. It will be hidden if disabled.
%End

void setEnabled( bool enabled );
%Docstring
Enable this item. It will be hidden if disabled.
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgssnaptogridcanvasitem.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -193,6 +193,7 @@
%Include auto_generated/qgssearchquerybuilder.sip
%Include auto_generated/qgsshortcutsmanager.sip
%Include auto_generated/qgsslider.sip
%Include auto_generated/qgssnaptogridcanvasitem.sip
%Include auto_generated/qgsstatusbar.sip
%Include auto_generated/qgssublayersdialog.sip
%Include auto_generated/qgssubstitutionlistwidget.sip
@@ -27,6 +27,7 @@ QgsMapToolSplitFeatures::QgsMapToolSplitFeatures( QgsMapCanvas *canvas )
: QgsMapToolCapture( canvas, QgisApp::instance()->cadDockWidget(), QgsMapToolCapture::CaptureLine )
{
mToolName = tr( "Split features" );
setSnapToLayerGridEnabled( false );
}

void QgsMapToolSplitFeatures::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
@@ -27,6 +27,7 @@ QgsMapToolSplitParts::QgsMapToolSplitParts( QgsMapCanvas *canvas )
: QgsMapToolCapture( canvas, QgisApp::instance()->cadDockWidget(), QgsMapToolCapture::CaptureLine )
{
mToolName = tr( "Split parts" );
setSnapToLayerGridEnabled( false );
}

void QgsMapToolSplitParts::cadCanvasReleaseEvent( QgsMapMouseEvent *e )
@@ -47,7 +47,7 @@ bool QgsVectorLayerEditUtils::insertVertex( double x, double y, QgsFeatureId atF

geometry.insertVertex( x, y, beforeVertex );

mLayer->editBuffer()->changeGeometry( atFeatureId, geometry );
mLayer->changeGeometry( atFeatureId, geometry );
return true;
}

@@ -64,7 +64,7 @@ bool QgsVectorLayerEditUtils::insertVertex( const QgsPoint &point, QgsFeatureId

geometry.insertVertex( point, beforeVertex );

mLayer->editBuffer()->changeGeometry( atFeatureId, geometry );
mLayer->changeGeometry( atFeatureId, geometry );
return true;
}

@@ -87,7 +87,7 @@ bool QgsVectorLayerEditUtils::moveVertex( const QgsPoint &p, QgsFeatureId atFeat

geometry.moveVertex( p, atVertex );

mLayer->editBuffer()->changeGeometry( atFeatureId, geometry );
mLayer->changeGeometry( atFeatureId, geometry );
return true;
}

@@ -112,7 +112,7 @@ QgsVectorLayer::EditResult QgsVectorLayerEditUtils::deleteVertex( QgsFeatureId f
geometry.set( nullptr );
}

mLayer->editBuffer()->changeGeometry( featureId, geometry );
mLayer->changeGeometry( featureId, geometry );
return !geometry.isNull() ? QgsVectorLayer::Success : QgsVectorLayer::EmptyGeometry;
}

@@ -159,7 +159,7 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::addRing( QgsCurve *ring, c
if ( addRingReturnCode == 0 )
if ( addRingReturnCode == QgsGeometry::Success )
{
mLayer->editBuffer()->changeGeometry( f.id(), g );
mLayer->changeGeometry( f.id(), g );
if ( modifiedFeatureId )
*modifiedFeatureId = f.id();

@@ -212,7 +212,7 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::addPart( const QgsPointSeq
//convert back to single part if required by layer
geometry.convertToSingleType();
}
mLayer->editBuffer()->changeGeometry( featureId, geometry );
mLayer->changeGeometry( featureId, geometry );
}
return errorCode;
}
@@ -247,7 +247,7 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::addPart( QgsCurve *ring, Q
//convert back to single part if required by layer
geometry.convertToSingleType();
}
mLayer->editBuffer()->changeGeometry( featureId, geometry );
mLayer->changeGeometry( featureId, geometry );
}
return errorCode;
}
@@ -267,7 +267,7 @@ int QgsVectorLayerEditUtils::translateFeature( QgsFeatureId featureId, double dx
int errorCode = geometry.translate( dx, dy );
if ( errorCode == 0 )
{
mLayer->editBuffer()->changeGeometry( featureId, geometry );
mLayer->changeGeometry( featureId, geometry );
}
return errorCode;
}
@@ -348,13 +348,13 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitFeatures( const QVect
if ( splitFunctionReturn == QgsGeometry::OperationResult::Success )
{
//change this geometry
mLayer->editBuffer()->changeGeometry( feat.id(), featureGeom );
mLayer->changeGeometry( feat.id(), featureGeom );

//insert new features
for ( int i = 0; i < newGeometries.size(); ++i )
{
QgsFeature f = QgsVectorLayerUtils::createFeature( mLayer, newGeometries.at( i ), feat.attributes().toMap() );
mLayer->editBuffer()->addFeature( f );
mLayer->addFeature( f );
}

if ( topologicalEditing )
@@ -470,7 +470,7 @@ QgsGeometry::OperationResult QgsVectorLayerEditUtils::splitParts( const QVector<

if ( !addPartRet )
{
mLayer->editBuffer()->changeGeometry( feat.id(), featureGeom );
mLayer->changeGeometry( feat.id(), featureGeom );
}

if ( topologicalEditing )
@@ -358,6 +358,7 @@ SET(QGIS_GUI_SRCS
qgsshortcutsmanager.cpp
qgsslider.cpp
qgssnapindicator.cpp
qgssnaptogridcanvasitem.cpp
qgssublayersdialog.cpp
qgssubstitutionlistwidget.cpp
qgssqlcomposerdialog.cpp
@@ -527,6 +528,7 @@ SET(QGIS_GUI_MOC_HDRS
qgssearchquerybuilder.h
qgsshortcutsmanager.h
qgsslider.h
qgssnaptogridcanvasitem.h
qgssqlcomposerdialog.h
qgsstatusbar.h
qgssublayersdialog.h
@@ -71,6 +71,30 @@ void QgsMapMouseEvent::setMapPoint( const QgsPointXY &point )
mPixelPoint = mapToPixelCoordinates( point );
}

void QgsMapMouseEvent::snapToGrid( double precision, const QgsCoordinateReferenceSystem &crs )
{
if ( precision <= 0 )
return;

try
{
QgsCoordinateTransform ct( mMapCanvas->mapSettings().destinationCrs(), crs, mMapCanvas->mapSettings().transformContext() );

QgsPointXY pt = ct.transform( mMapPoint );

pt.setX( std::round( pt.x() / precision ) * precision );
pt.setY( std::round( pt.y() / precision ) * precision );

pt = ct.transform( pt, QgsCoordinateTransform::ReverseTransform );

setMapPoint( pt );
}
catch ( QgsCsException &e )
{
Q_UNUSED( e )
}
}

QPoint QgsMapMouseEvent::mapToPixelCoordinates( const QgsPointXY &point )
{
double x = point.x(), y = point.y();
@@ -126,6 +126,15 @@ class GUI_EXPORT QgsMapMouseEvent : public QMouseEvent
*/
QPoint originalPixelPoint() const { return pos(); }

/**
* Snaps the mapPoint to a grid with the given \a precision.
* The snapping will be done in the specified \a crs. If this crs is
* different from the mapCanvas crs, it will be reprojected on the fly.
*
* \since QGIS 3.4
*/
void snapToGrid( double precision, const QgsCoordinateReferenceSystem &crs );

private:

QPoint mapToPixelCoordinates( const QgsPointXY &point );

2 comments on commit 32ee716

@lajunek

This comment has been minimized.

Copy link

@lajunek lajunek replied Mar 8, 2019

@m-kuhn can you please describe the new feature for documentation 3.4 with more detail?

@m-kuhn

This comment has been minimized.

Copy link
Member Author

@m-kuhn m-kuhn replied Mar 8, 2019

Hi @lajunek
on the top of this page you find a link to #7711

image

Is that enough for you or do you need more?

Please sign in to comment.
You can’t perform that action at this time.