mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Add QgsSnapToGridCanvasItem
This commit is contained in:
parent
fff743bed8
commit
1e81e03a18
91
python/gui/auto_generated/qgssnaptogridcanvasitem.sip.in
Normal file
91
python/gui/auto_generated/qgssnaptogridcanvasitem.sip.in
Normal file
@ -0,0 +1,91 @@
|
||||
/************************************************************************
|
||||
* 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 );
|
||||
%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 *
|
||||
************************************************************************/
|
@ -192,6 +192,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
|
||||
|
@ -355,6 +355,7 @@ SET(QGIS_GUI_SRCS
|
||||
qgsshortcutsmanager.cpp
|
||||
qgsslider.cpp
|
||||
qgssnapindicator.cpp
|
||||
qgssnaptogridcanvasitem.cpp
|
||||
qgssublayersdialog.cpp
|
||||
qgssubstitutionlistwidget.cpp
|
||||
qgssqlcomposerdialog.cpp
|
||||
@ -524,6 +525,7 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
qgssearchquerybuilder.h
|
||||
qgsshortcutsmanager.h
|
||||
qgsslider.h
|
||||
qgssnaptogridcanvasitem.h
|
||||
qgssqlcomposerdialog.h
|
||||
qgsstatusbar.h
|
||||
qgssublayersdialog.h
|
||||
|
142
src/gui/qgssnaptogridcanvasitem.cpp
Normal file
142
src/gui/qgssnaptogridcanvasitem.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
#include "qgssnaptogridcanvasitem.h"
|
||||
#include "qgsmapcanvas.h"
|
||||
|
||||
QgsSnapToGridCanvasItem::QgsSnapToGridCanvasItem( QgsMapCanvas *mapCanvas )
|
||||
: QgsMapCanvasItem( mapCanvas )
|
||||
, mGridPen( QPen( QColor( 127, 127, 127, 150 ), 1 ) )
|
||||
, mCurrentPointPen( QPen( QColor( 200, 200, 200, 150 ), 3 ) )
|
||||
{
|
||||
updateMapCanvasCrs();
|
||||
connect( mMapCanvas, &QgsMapCanvas::extentsChanged, this, &QgsSnapToGridCanvasItem::updateZoomFactor );
|
||||
connect( mMapCanvas, &QgsMapCanvas::destinationCrsChanged, this, &QgsSnapToGridCanvasItem::updateMapCanvasCrs );
|
||||
}
|
||||
|
||||
void QgsSnapToGridCanvasItem::paint( QPainter *painter )
|
||||
{
|
||||
painter->save();
|
||||
QgsRectangle mapRect = mMapCanvas->extent();
|
||||
if ( rect() != mapRect )
|
||||
setRect( mapRect );
|
||||
|
||||
painter->setRenderHints( QPainter::Antialiasing );
|
||||
painter->setCompositionMode( QPainter::CompositionMode_Difference );
|
||||
|
||||
if ( mEnabled && mAvailableByZoomFactor )
|
||||
{
|
||||
const QgsRectangle layerExtent = mTransform.transformBoundingBox( mapRect, QgsCoordinateTransform::ReverseTransform );
|
||||
const QgsPointXY layerPt = mTransform.transform( mPoint, QgsCoordinateTransform::ReverseTransform );
|
||||
|
||||
const double gridXMin = std::ceil( layerExtent.xMinimum() / mPrecision ) * mPrecision;
|
||||
const double gridXMax = std::ceil( layerExtent.xMaximum() / mPrecision ) * mPrecision;
|
||||
const double gridYMin = std::ceil( layerExtent.yMinimum() / mPrecision ) * mPrecision;
|
||||
const double gridYMax = std::ceil( layerExtent.yMaximum() / mPrecision ) * mPrecision;
|
||||
|
||||
for ( int x = gridXMin ; x < gridXMax; x += mPrecision )
|
||||
{
|
||||
for ( int y = gridYMin ; y < gridYMax; y += mPrecision )
|
||||
{
|
||||
const QgsPointXY pt = mTransform.transform( x, y );
|
||||
const QPointF canvasPt = toCanvasCoordinates( pt );
|
||||
|
||||
if ( qgsDoubleNear( layerPt.x(), x, mPrecision / 3 ) && qgsDoubleNear( layerPt.y(), y, mPrecision / 3 ) )
|
||||
{
|
||||
painter->setPen( mCurrentPointPen );
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->setPen( mGridPen );
|
||||
}
|
||||
painter->drawLine( canvasPt.x() - 3, canvasPt.y(), canvasPt.x() + 3, canvasPt.y() );
|
||||
painter->drawLine( canvasPt.x(), canvasPt.y() - 3, canvasPt.x(), canvasPt.y() + 3 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QgsPointXY QgsSnapToGridCanvasItem::point() const
|
||||
{
|
||||
return mPoint;
|
||||
}
|
||||
|
||||
void QgsSnapToGridCanvasItem::setPoint( const QgsPointXY &point )
|
||||
{
|
||||
mPoint = point;
|
||||
update();
|
||||
}
|
||||
|
||||
double QgsSnapToGridCanvasItem::precision() const
|
||||
{
|
||||
return mPrecision;
|
||||
}
|
||||
|
||||
void QgsSnapToGridCanvasItem::setPrecision( double precision )
|
||||
{
|
||||
mPrecision = precision;
|
||||
updateZoomFactor();
|
||||
}
|
||||
|
||||
QgsCoordinateReferenceSystem QgsSnapToGridCanvasItem::crs() const
|
||||
{
|
||||
return mTransform.sourceCrs();
|
||||
}
|
||||
|
||||
void QgsSnapToGridCanvasItem::setCrs( const QgsCoordinateReferenceSystem &crs )
|
||||
{
|
||||
mTransform.setSourceCrs( crs );
|
||||
updateZoomFactor();
|
||||
}
|
||||
|
||||
bool QgsSnapToGridCanvasItem::enabled() const
|
||||
{
|
||||
return mEnabled;
|
||||
}
|
||||
|
||||
void QgsSnapToGridCanvasItem::setEnabled( bool enabled )
|
||||
{
|
||||
mEnabled = enabled;
|
||||
update();
|
||||
}
|
||||
|
||||
void QgsSnapToGridCanvasItem::updateMapCanvasCrs()
|
||||
{
|
||||
mTransform.setContext( mMapCanvas->mapSettings().transformContext() );
|
||||
mTransform.setDestinationCrs( mMapCanvas->mapSettings().destinationCrs() );
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void QgsSnapToGridCanvasItem::updateZoomFactor()
|
||||
{
|
||||
if ( !isVisible() )
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
const int threshold = 5;
|
||||
|
||||
const QgsPointXY centerPoint = mMapCanvas->extent().center();
|
||||
const QPointF canvasCenter = toCanvasCoordinates( centerPoint );
|
||||
|
||||
const QgsPointXY pt1 = mMapCanvas->mapSettings().mapToPixel().toMapCoordinates( canvasCenter.x() - threshold, canvasCenter.y() - threshold );
|
||||
const QgsPointXY pt2 = mMapCanvas->mapSettings().mapToPixel().toMapCoordinates( canvasCenter.x() + threshold, canvasCenter.y() + threshold );
|
||||
|
||||
const QgsPointXY layerPt1 = mTransform.transform( pt1, QgsCoordinateTransform::ReverseTransform );
|
||||
const QgsPointXY layerPt2 = mTransform.transform( pt2, QgsCoordinateTransform::ReverseTransform );
|
||||
|
||||
const double dist = layerPt1.distance( layerPt2 );
|
||||
|
||||
if ( dist < mPrecision )
|
||||
mAvailableByZoomFactor = true;
|
||||
else
|
||||
mAvailableByZoomFactor = false;
|
||||
}
|
||||
catch ( QgsCsException &e )
|
||||
{
|
||||
// transform errors?
|
||||
// you've probably got worse problems than the grid with your digitizing operations in the current projection.
|
||||
mAvailableByZoomFactor = false;
|
||||
}
|
||||
}
|
98
src/gui/qgssnaptogridcanvasitem.h
Normal file
98
src/gui/qgssnaptogridcanvasitem.h
Normal file
@ -0,0 +1,98 @@
|
||||
#ifndef QGSSNAPTOGRIDCANVASITEM_H
|
||||
#define QGSSNAPTOGRIDCANVASITEM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QPen>
|
||||
|
||||
#include "qgscoordinatereferencesystem.h"
|
||||
#include "qgsmapcanvasitem.h"
|
||||
#include "qgscoordinatetransform.h"
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
*
|
||||
* Shows a grid on the map canvas given a spatial resolution.
|
||||
*
|
||||
* \since QGIS 3.4
|
||||
*/
|
||||
class GUI_EXPORT QgsSnapToGridCanvasItem : public QObject, public QgsMapCanvasItem
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Will automatically be added to the \a mapCanvas.
|
||||
*/
|
||||
QgsSnapToGridCanvasItem( QgsMapCanvas *mapCanvas );
|
||||
|
||||
void paint( QPainter *painter ) override;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
QgsPointXY point() const;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void setPoint( const QgsPointXY &point );
|
||||
|
||||
/**
|
||||
* The resolution of the grid in map units.
|
||||
* If a crs has been specified it will be in CRS units.
|
||||
*/
|
||||
double precision() const;
|
||||
|
||||
/**
|
||||
* The resolution of the grid in map units.
|
||||
* If a crs has been specified it will be in CRS units.
|
||||
*/
|
||||
void setPrecision( double precision );
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
QgsCoordinateReferenceSystem crs() const;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void setCrs( const QgsCoordinateReferenceSystem &crs );
|
||||
|
||||
/**
|
||||
* Enable this item. It will be hidden if disabled.
|
||||
*/
|
||||
bool enabled() const;
|
||||
|
||||
/**
|
||||
* Enable this item. It will be hidden if disabled.
|
||||
*/
|
||||
void setEnabled( bool enabled );
|
||||
|
||||
private slots:
|
||||
void updateMapCanvasCrs();
|
||||
|
||||
void updateZoomFactor();
|
||||
|
||||
private:
|
||||
QPen mGridPen;
|
||||
QPen mCurrentPointPen;
|
||||
|
||||
bool mEnabled = true;
|
||||
bool mAvailableByZoomFactor = false;
|
||||
|
||||
double mPrecision = 0.0;
|
||||
QgsCoordinateTransform mTransform;
|
||||
QgsPointXY mPoint;
|
||||
};
|
||||
|
||||
#endif // QGSSNAPTOGRIDCANVASITEM_H
|
Loading…
x
Reference in New Issue
Block a user