QGIS API Documentation  2.11.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 <QSettings>
18 #include <QPoint>
19 #include <cmath>
20 
21 
22 // return ratio [mu/lu] between map units and layer units
23 // this is of course only an approximation
24 double _ratioMU2LU( const QgsMapSettings& mapSettings, QgsMapLayer* layer )
25 {
26  double distMU = mapSettings.mapUnitsPerPixel();
27  QgsPoint ptMapCenterMU = mapSettings.visibleExtent().center();
28  QgsPoint ptMapCenterRightMU( ptMapCenterMU.x() + distMU, ptMapCenterMU.y() );
29  QgsPoint ptMapCenterLU = mapSettings.mapToLayerCoordinates( layer, ptMapCenterMU );
30  QgsPoint ptMapCenterRightLU = mapSettings.mapToLayerCoordinates( layer, ptMapCenterRightMU );
31  double distLU = sqrt( ptMapCenterLU.sqrDist( ptMapCenterRightLU ) );
32  double ratio = distMU / distLU;
33  return ratio;
34 }
35 
36 double QgsTolerance::toleranceInProjectUnits( double tolerance, QgsMapLayer* layer, const QgsMapSettings& mapSettings, QgsTolerance::UnitType units )
37 {
38  // converts to map units
39  if ( units == ProjectUnits )
40  return tolerance;
41  else if ( units == Pixels )
42  return tolerance * mapSettings.mapUnitsPerPixel();
43  else // units == LayerUnits
44  {
45  // [mu] = [lu] * [mu/lu]
46  return tolerance * _ratioMU2LU( mapSettings, layer );
47  }
48 }
49 
50 
51 double QgsTolerance::toleranceInMapUnits( double tolerance, QgsMapLayer *layer, const QgsMapSettings& mapSettings, QgsTolerance::UnitType units )
52 {
53  // converts to layer units
54  if ( units == LayerUnits )
55  {
56  return tolerance;
57  }
58  else if ( units == Pixels )
59  {
60  double layerUnitsPerPixel = computeMapUnitPerPixel( layer, mapSettings );
61  return tolerance * layerUnitsPerPixel;
62  }
63  else // ProjectUnits
64  {
65  // [lu] = [mu] / [mu/lu]
66  return tolerance / _ratioMU2LU( mapSettings, layer );
67  }
68 }
69 
70 double QgsTolerance::toleranceInMapUnits( double tolerance, QgsMapLayer* layer, QgsMapRenderer* renderer, UnitType units )
71 {
72  return toleranceInMapUnits( tolerance, layer, renderer->mapSettings(), units );
73 }
74 
76 {
77  QSettings settings;
78  double tolerance = settings.value( "/qgis/digitizing/search_radius_vertex_edit", 10 ).toDouble();
79  UnitType units = ( QgsTolerance::UnitType ) settings.value( "/qgis/digitizing/search_radius_vertex_edit_unit", QgsTolerance::Pixels ).toInt();
80  if ( units == LayerUnits )
81  units = ProjectUnits;
82  return toleranceInProjectUnits( tolerance, 0, mapSettings, units );
83 }
84 
85 double QgsTolerance::vertexSearchRadius( QgsMapLayer *layer, const QgsMapSettings &mapSettings )
86 {
87  QSettings settings;
88  double tolerance = settings.value( "/qgis/digitizing/search_radius_vertex_edit", 10 ).toDouble();
89  UnitType units = ( QgsTolerance::UnitType ) settings.value( "/qgis/digitizing/search_radius_vertex_edit_unit", QgsTolerance::Pixels ).toInt();
90  return toleranceInMapUnits( tolerance, layer, mapSettings, units );
91 }
92 
94 {
95  return vertexSearchRadius( layer, renderer->mapSettings() );
96 }
97 
98 double QgsTolerance::defaultTolerance( QgsMapLayer *layer, const QgsMapSettings& mapSettings )
99 {
100  QSettings settings;
101  double tolerance = settings.value( "/qgis/digitizing/default_snapping_tolerance", 0 ).toDouble();
102  UnitType units = ( QgsTolerance::UnitType ) settings.value( "/qgis/digitizing/default_snapping_tolerance_unit", ProjectUnits ).toInt();
103  return toleranceInMapUnits( tolerance, layer, mapSettings, units );
104 }
105 
106 
108 {
109  return defaultTolerance( layer, renderer->mapSettings() );
110 }
111 
112 
113 double QgsTolerance::computeMapUnitPerPixel( QgsMapLayer* layer, const QgsMapSettings& mapSettings )
114 {
115  if ( ! mapSettings.hasCrsTransformEnabled() )
116  {
117  // if the on-the-fly projections are not enabled, layer units pre pixel are the same as map units per pixel
118  return mapSettings.mapUnitsPerPixel();
119  }
120 
121  // the layer is projected. Find out how many pixels are in one map unit - either horizontal and vertical direction
122  // this check might not work correctly in some cases
123  // (on a large area the pixels projected around "0,0" can have different properties from the actual point)
124  QgsPoint p1 = toLayerCoordinates( layer, mapSettings, QPoint( 0, 1 ) );
125  QgsPoint p2 = toLayerCoordinates( layer, mapSettings, QPoint( 0, 2 ) );
126  QgsPoint p3 = toLayerCoordinates( layer, mapSettings, QPoint( 1, 0 ) );
127  QgsPoint p4 = toLayerCoordinates( layer, mapSettings, QPoint( 2, 0 ) );
128  double x = p1.sqrDist( p2 );
129  double y = p3.sqrDist( p4 );
130  if ( x > y )
131  {
132  return sqrt( x );
133  }
134  else
135  {
136  return sqrt( y );
137  }
138 }
139 
140 
141 QgsPoint QgsTolerance::toLayerCoordinates( QgsMapLayer* layer, const QgsMapSettings& mapSettings, const QPoint& point )
142 {
143  QgsPoint pt = mapSettings.mapToPixel().toMapCoordinates( point );
144  return mapSettings.mapToLayerCoordinates( layer, pt );
145 }
const QgsMapSettings & mapSettings()
bridge to QgsMapSettings
Base class for all map layer types.
Definition: qgsmaplayer.h:49
Pixels unit of tolerance.
Definition: qgstolerance.h:40
QgsRectangle visibleExtent() const
Return the actual extent derived from requested extent that takes takes output image size into accoun...
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
const QgsMapToPixel & mapToPixel() const
Map (project) units.
Definition: qgstolerance.h:42
A non GUI class for rendering a map layer set onto a QPainter.
static double toleranceInMapUnits(double tolerance, QgsMapLayer *layer, const QgsMapSettings &mapSettings, UnitType units=LayerUnits)
Static function to translate tolerance value into layer units.
QgsPoint mapToLayerCoordinates(QgsMapLayer *theLayer, QgsPoint point) const
transform point coordinates from output CRS to layer's CRS
double sqrDist(double x, double y) const
Returns the squared distance between this point and x,y.
Definition: qgspoint.cpp:345
double x() const
Get the x value of the point.
Definition: qgspoint.h:126
The QgsMapSettings class contains configuration for rendering of the map.
int toInt(bool *ok) const
double mapUnitsPerPixel() const
Return the distance in geographical coordinates that equals to one pixel in the map.
static double defaultTolerance(QgsMapLayer *layer, const QgsMapSettings &mapSettings)
Static function to get default tolerance value for a layer.
A class to represent a point.
Definition: qgspoint.h:63
QgsPoint toMapCoordinates(int x, int y) const
static double vertexSearchRadius(const QgsMapSettings &mapSettings)
Static function to get vertex tolerance value.
QVariant value(const QString &key, const QVariant &defaultValue) const
static double toleranceInProjectUnits(double tolerance, QgsMapLayer *layer, const QgsMapSettings &mapSettings, QgsTolerance::UnitType units)
Static function to translate tolerance value into map units.
Layer unit value.
Definition: qgstolerance.h:38
double y() const
Get the y value of the point.
Definition: qgspoint.h:134
double _ratioMU2LU(const QgsMapSettings &mapSettings, QgsMapLayer *layer)
double toDouble(bool *ok) const
UnitType
Type of unit of tolerance value from settings.
Definition: qgstolerance.h:33
QgsPoint center() const
Center point of the rectangle.
Definition: qgsrectangle.h:212