Skip to content

Commit 6aff4e9

Browse files
author
wonder
committed
Fixed handling of tolerance for projected layers (#1634).
Patch contributed by Richard Kostecky. git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@10555 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 411dace commit 6aff4e9

6 files changed

+73
-27
lines changed

python/core/qgstolerance.sip

+8-9
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,26 @@ public:
1616
};
1717

1818
/**
19-
* Static function to get vertex tolerance value from settings
20-
* @param mapUnitsPerPixel number of map units per pixel
19+
* Static function to get vertex tolerance value for a layer.
20+
* The value is read from settings and transformed if necessary.
2121
* @return value of vertex tolerance in map units
2222
*/
23-
static double vertexSearchRadius( double mapUnitsPerPixel );
23+
static double vertexSearchRadius( QgsMapLayer* layer, QgsMapRenderer* renderer );
2424

2525
/**
26-
* Static function to get default tolerance value from settings
27-
* @param mapUnitsPerPixel number of map units per pixel
26+
* Static function to get default tolerance value for a layer.
27+
* The value is read from settings and transformed if necessary.
2828
* @return value of default tolerance in map units
2929
*/
30-
static double defaultTolerance( double mapUnitsPerPixel );
30+
static double defaultTolerance( QgsMapLayer* layer, QgsMapRenderer* renderer );
3131

32-
/**
32+
/**
3333
* Static function to translate tolerance value into current map unit value
3434
* @param tolerace tolerance value to be translated
35-
* @param mapUnitsPerPixel number of map units per pixel
3635
* @param units type of units to be translated
3736
* @return value of tolerance in map units
3837
*/
39-
static double toleranceInMapUnits(double tolerance, double mapUnitsPerPixel, UnitType units = MapUnits);
38+
static double toleranceInMapUnits( double tolerance, QgsMapLayer* layer, QgsMapRenderer* renderer, UnitType units = MapUnits );
4039

4140
};
4241

src/app/qgsmaptoolmovefeature.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void QgsMapToolMoveFeature::canvasPressEvent( QMouseEvent * e )
7272
//find first geometry under mouse cursor and store iterator to it
7373
QgsPoint layerCoords = toLayerCoordinates(( QgsMapLayer* )vlayer, e->pos() );
7474
QSettings settings;
75-
double searchRadius = QgsTolerance::vertexSearchRadius( mCanvas->mapUnitsPerPixel() );
75+
double searchRadius = QgsTolerance::vertexSearchRadius( mCanvas->currentLayer(), mCanvas->mapRenderer() );
7676
QgsRectangle selectRect( layerCoords.x() - searchRadius, layerCoords.y() - searchRadius,
7777
layerCoords.x() + searchRadius, layerCoords.y() + searchRadius );
7878

src/core/qgssnapper.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ int QgsSnapper::snapPoint( const QPoint& startPoint, QList<QgsSnappingResult>& s
5757
//transform point from map coordinates to layer coordinates
5858
layerCoordPoint = mMapRenderer->mapToLayerCoordinates( snapLayerIt->mLayer, mapCoordPoint );
5959

60-
double tolerance = QgsTolerance::toleranceInMapUnits( snapLayerIt->mTolerance, mMapRenderer->mapUnitsPerPixel(), snapLayerIt->mUnitType );
60+
double tolerance = QgsTolerance::toleranceInMapUnits( snapLayerIt->mTolerance, snapLayerIt->mLayer, mMapRenderer, snapLayerIt->mUnitType );
6161
if ( snapLayerIt->mLayer->snapWithContext( layerCoordPoint, tolerance,
6262
currentResultList, snapLayerIt->mSnapTo ) != 0 )
6363
{

src/core/qgstolerance.cpp

+46-5
Original file line numberDiff line numberDiff line change
@@ -15,29 +15,70 @@
1515

1616
#include "qgstolerance.h"
1717
#include <QSettings>
18+
#include <QPoint>
19+
#include <math.h>
1820

1921

20-
double QgsTolerance::toleranceInMapUnits( double tolerance, double mapUnitsPerPixel, UnitType units )
22+
23+
double QgsTolerance::toleranceInMapUnits( double tolerance, QgsMapLayer* layer, QgsMapRenderer* renderer, UnitType units )
2124
{
2225
if ( units == MapUnits )
2326
{
2427
return tolerance;
2528
}
29+
double mapUnitsPerPixel = computeMapUnitPerPixel( layer, renderer );
2630
return tolerance * mapUnitsPerPixel;
2731
}
2832

29-
double QgsTolerance::vertexSearchRadius( double mapUnitsPerPixel )
33+
34+
double QgsTolerance::vertexSearchRadius( QgsMapLayer* layer, QgsMapRenderer* renderer )
3035
{
3136
QSettings settings;
3237
double tolerance = settings.value( "/qgis/digitizing/search_radius_vertex_edit", 10 ).toDouble();
3338
UnitType units = ( QgsTolerance::UnitType ) settings.value( "/qgis/digitizing/search_radius_vertex_edit_unit", 0 ).toInt();
34-
return toleranceInMapUnits( tolerance, mapUnitsPerPixel, units );
39+
return toleranceInMapUnits( tolerance, layer, renderer, units );
3540
}
3641

37-
double QgsTolerance::defaultTolerance( double mapUnitsPerPixel )
42+
43+
double QgsTolerance::defaultTolerance( QgsMapLayer* layer, QgsMapRenderer* renderer )
3844
{
3945
QSettings settings;
4046
double tolerance = settings.value( "/qgis/digitizing/default_snapping_tolerance", 0 ).toDouble();
4147
UnitType units = ( QgsTolerance::UnitType ) settings.value( "/qgis/digitizing/default_snapping_tolerance_unit", 0 ).toInt();
42-
return toleranceInMapUnits( tolerance, mapUnitsPerPixel, units );
48+
return toleranceInMapUnits( tolerance, layer, renderer, units );
49+
}
50+
51+
52+
double QgsTolerance::computeMapUnitPerPixel( QgsMapLayer* layer, QgsMapRenderer* renderer )
53+
{
54+
if ( ! renderer->hasCrsTransformEnabled() )
55+
{
56+
// if the on-the-fly projections are not enabled, layer units pre pixel are the same as map units per pixel
57+
return renderer->mapUnitsPerPixel();
58+
}
59+
60+
// the layer is projected. Find out how many pixels are in one map unit - either horizontal and vertical direction
61+
// this check might not work correctly in some cases
62+
// (on a large area the pixels projected around "0,0" can have different properties from the actual point)
63+
QgsPoint p1 = toLayerCoordinates(layer, renderer, QPoint(0,1));
64+
QgsPoint p2 = toLayerCoordinates(layer, renderer, QPoint(0,2));
65+
QgsPoint p3 = toLayerCoordinates(layer, renderer, QPoint(1,0));
66+
QgsPoint p4 = toLayerCoordinates(layer, renderer, QPoint(2,0));
67+
double x = p1.sqrDist(p2);
68+
double y = p3.sqrDist(p4);
69+
if (x > y)
70+
{
71+
return sqrt(x);
72+
}
73+
else
74+
{
75+
return sqrt(y);
76+
}
77+
}
78+
79+
80+
QgsPoint QgsTolerance::toLayerCoordinates( QgsMapLayer* layer, QgsMapRenderer* renderer, const QPoint& point )
81+
{
82+
QgsPoint pt = renderer->coordinateTransform()->toMapCoordinates( point );
83+
return renderer->mapToLayerCoordinates( layer, pt );
4384
}

src/core/qgstolerance.h

+15-9
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515

1616
#ifndef QGSTOLERANCE_H
1717
#define QGSTOLERANCE_H
18-
18+
#include "qgsmaptopixel.h"
19+
#include "qgsmaprenderer.h"
20+
#include "qgsmaplayer.h"
21+
#include "qgspoint.h"
1922

2023
/** \ingroup core
2124
* This is the class is providing tolerance value in map unit values.
@@ -36,27 +39,30 @@ class CORE_EXPORT QgsTolerance
3639
};
3740

3841
/**
39-
* Static function to get vertex tolerance value from settings
40-
* @param mapUnitsPerPixel number of map units per pixel
42+
* Static function to get vertex tolerance value for a layer.
43+
* The value is read from settings and transformed if necessary.
4144
* @return value of vertex tolerance in map units
4245
*/
43-
static double vertexSearchRadius( double mapUnitsPerPixel );
46+
static double vertexSearchRadius( QgsMapLayer* layer, QgsMapRenderer* renderer );
4447

4548
/**
46-
* Static function to get default tolerance value from settings
47-
* @param mapUnitsPerPixel number of map units per pixel
49+
* Static function to get default tolerance value for a layer.
50+
* The value is read from settings and transformed if necessary.
4851
* @return value of default tolerance in map units
4952
*/
50-
static double defaultTolerance( double mapUnitsPerPixel );
53+
static double defaultTolerance( QgsMapLayer* layer, QgsMapRenderer* renderer );
5154

5255
/**
5356
* Static function to translate tolerance value into current map unit value
5457
* @param tolerace tolerance value to be translated
55-
* @param mapUnitsPerPixel number of map units per pixel
5658
* @param units type of units to be translated
5759
* @return value of tolerance in map units
5860
*/
59-
static double toleranceInMapUnits( double tolerance, double mapUnitsPerPixel, UnitType units = MapUnits );
61+
static double toleranceInMapUnits( double tolerance, QgsMapLayer* layer, QgsMapRenderer* renderer, UnitType units = MapUnits );
62+
63+
private:
64+
static double computeMapUnitPerPixel( QgsMapLayer* layer, QgsMapRenderer* renderer );
65+
static QgsPoint toLayerCoordinates( QgsMapLayer* layer, QgsMapRenderer* renderer, const QPoint& point );
6066

6167
};
6268

src/gui/qgsmapcanvassnapper.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ int QgsMapCanvasSnapper::snapToCurrentLayer( const QPoint& p, QList<QgsSnappingR
101101
if ( snappingTol < 0 )
102102
{
103103
//use search tolerance for vertex editing
104-
snapLayer.mTolerance = QgsTolerance::vertexSearchRadius( mMapCanvas->mapUnitsPerPixel() );
104+
snapLayer.mTolerance = QgsTolerance::vertexSearchRadius( vlayer, mMapCanvas->mapRenderer() );
105105
}
106106
else
107107
{
@@ -248,7 +248,7 @@ int QgsMapCanvasSnapper::snapToBackgroundLayers( const QPoint& p, QList<QgsSnapp
248248
}
249249

250250
//default snapping tolerance (returned in map units)
251-
snapLayer.mTolerance = QgsTolerance::defaultTolerance( mMapCanvas->mapUnitsPerPixel() );
251+
snapLayer.mTolerance = QgsTolerance::defaultTolerance( currentVectorLayer, mMapCanvas->mapRenderer() );
252252
snapLayer.mUnitType = QgsTolerance::MapUnits;
253253

254254
snapLayers.append( snapLayer );

0 commit comments

Comments
 (0)