QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgstolerance.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgstolerance.cpp - wrapper for tolerance handling
3 ----------------------
4 begin : March 2009
5 copyright : (C) 2009 by Richard Kostecky
6 email : csf.kostej at gmail dot com
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15
16#include "qgstolerance.h"
17#include "qgsmapsettings.h"
19#include "qgspointxy.h"
20
21#include <QPoint>
22#include <cmath>
23
24
25// return ratio [mu/lu] between map units and layer units
26// this is of course only an approximation
27double _ratioMU2LU( const QgsMapSettings &mapSettings, QgsMapLayer *layer )
28{
29 const double distMU = mapSettings.mapUnitsPerPixel();
30 const QgsPointXY ptMapCenterMU = mapSettings.visibleExtent().center();
31 const QgsPointXY ptMapCenterRightMU( ptMapCenterMU.x() + distMU, ptMapCenterMU.y() );
32 const QgsPointXY ptMapCenterLU = mapSettings.mapToLayerCoordinates( layer, ptMapCenterMU );
33 const QgsPointXY ptMapCenterRightLU = mapSettings.mapToLayerCoordinates( layer, ptMapCenterRightMU );
34 const double distLU = std::sqrt( ptMapCenterLU.sqrDist( ptMapCenterRightLU ) );
35 const double ratio = distMU / distLU;
36 return ratio;
37}
38
39double QgsTolerance::toleranceInProjectUnits( double tolerance, QgsMapLayer *layer, const QgsMapSettings &mapSettings, QgsTolerance::UnitType units )
40{
41 // converts to map units
42 if ( units == ProjectUnits )
43 return tolerance;
44 else if ( units == Pixels )
45 return tolerance * mapSettings.mapUnitsPerPixel();
46 else // units == LayerUnits
47 {
48 // [mu] = [lu] * [mu/lu]
49 return tolerance * _ratioMU2LU( mapSettings, layer );
50 }
51}
52
53
54double QgsTolerance::toleranceInMapUnits( double tolerance, QgsMapLayer *layer, const QgsMapSettings &mapSettings, QgsTolerance::UnitType units )
55{
56 // converts to layer units
57 if ( units == LayerUnits )
58 {
59 return tolerance;
60 }
61 else if ( units == Pixels )
62 {
63 const double layerUnitsPerPixel = computeMapUnitPerPixel( layer, mapSettings );
64 return tolerance * layerUnitsPerPixel;
65 }
66 else // ProjectUnits
67 {
68 // [lu] = [mu] / [mu/lu]
69 return tolerance / _ratioMU2LU( mapSettings, layer );
70 }
71}
72
74{
77 if ( units == LayerUnits )
78 units = ProjectUnits;
79 return toleranceInProjectUnits( tolerance, nullptr, mapSettings, units );
80}
81
83{
86 return toleranceInMapUnits( tolerance, layer, mapSettings, units );
87}
88
89double QgsTolerance::defaultTolerance( QgsMapLayer *layer, const QgsMapSettings &mapSettings )
90{
93 return toleranceInMapUnits( tolerance, layer, mapSettings, units );
94}
95
96
97double QgsTolerance::computeMapUnitPerPixel( QgsMapLayer *layer, const QgsMapSettings &mapSettings )
98{
99 // the layer is projected. Find out how many pixels are in one map unit - either horizontal and vertical direction
100 // this check might not work correctly in some cases
101 // (on a large area the pixels projected around "0,0" can have different properties from the actual point)
102 const QgsPointXY p1 = toLayerCoordinates( layer, mapSettings, QPoint( 0, 1 ) );
103 const QgsPointXY p2 = toLayerCoordinates( layer, mapSettings, QPoint( 0, 2 ) );
104 const QgsPointXY p3 = toLayerCoordinates( layer, mapSettings, QPoint( 1, 0 ) );
105 const QgsPointXY p4 = toLayerCoordinates( layer, mapSettings, QPoint( 2, 0 ) );
106 const double x = p1.sqrDist( p2 );
107 const double y = p3.sqrDist( p4 );
108 if ( x > y )
109 {
110 return std::sqrt( x );
111 }
112 else
113 {
114 return std::sqrt( y );
115 }
116}
117
118
119QgsPointXY QgsTolerance::toLayerCoordinates( QgsMapLayer *layer, const QgsMapSettings &mapSettings, QPoint point )
120{
121 const QgsPointXY pt = mapSettings.mapToPixel().toMapCoordinates( point );
122 return mapSettings.mapToLayerCoordinates( layer, pt );
123}
Base class for all map layer types.
Definition: qgsmaplayer.h:73
The QgsMapSettings class contains configuration for rendering of the map.
const QgsMapToPixel & mapToPixel() const
double mapUnitsPerPixel() const
Returns the distance in geographical coordinates that equals to one pixel in the map.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
QgsPointXY toMapCoordinates(int x, int y) const
Transforms device coordinates to map (world) coordinates.
A class to represent a 2D point.
Definition: qgspointxy.h:59
double sqrDist(double x, double y) const SIP_HOLDGIL
Returns the squared distance between this point a specified x, y coordinate.
Definition: qgspointxy.h:190
double y
Definition: qgspointxy.h:63
Q_GADGET double x
Definition: qgspointxy.h:62
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Definition: qgsrectangle.h:251
T value(const QString &dynamicKeyPart=QString()) const
Returns settings value.
static const QgsSettingsEntryDouble settingsDigitizingDefaultSnappingTolerance
Settings entry digitizing default snapping tolerance.
static const QgsSettingsEntryEnumFlag< QgsTolerance::UnitType > settingsDigitizingSearchRadiusVertexEditUnit
Settings entry digitizing search radius vertex edit unit.
static const QgsSettingsEntryEnumFlag< QgsTolerance::UnitType > settingsDigitizingDefaultSnappingToleranceUnit
Settings entry digitizing default snapping tolerance unit.
static const QgsSettingsEntryDouble settingsDigitizingSearchRadiusVertexEdit
Settings entry digitizing search radius vertex edit.
static double toleranceInMapUnits(double tolerance, QgsMapLayer *layer, const QgsMapSettings &mapSettings, UnitType units=LayerUnits)
Static function to translate tolerance value into layer units.
static double vertexSearchRadius(const QgsMapSettings &mapSettings)
Static function to get vertex tolerance value.
static double defaultTolerance(QgsMapLayer *layer, const QgsMapSettings &mapSettings)
Static function to get default tolerance value for a layer.
static double toleranceInProjectUnits(double tolerance, QgsMapLayer *layer, const QgsMapSettings &mapSettings, QgsTolerance::UnitType units)
Static function to translate tolerance value into map units.
UnitType
Type of unit of tolerance value from settings.
Definition: qgstolerance.h:42
@ ProjectUnits
Map (project) units. Added in 2.8.
Definition: qgstolerance.h:48
@ Pixels
Pixels unit of tolerance.
Definition: qgstolerance.h:46
@ LayerUnits
Layer unit value.
Definition: qgstolerance.h:44
double _ratioMU2LU(const QgsMapSettings &mapSettings, QgsMapLayer *layer)