Fixed handling of tolerance for projected layers (#1634).

Patch contributed by Richard Kostecky.


git-svn-id: http://svn.osgeo.org/qgis/trunk@10555 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
wonder 2009-04-13 10:55:56 +00:00
parent ef8a729a47
commit 4f14c52aed
6 changed files with 73 additions and 27 deletions

View File

@ -16,27 +16,26 @@ public:
};
/**
* Static function to get vertex tolerance value from settings
* @param mapUnitsPerPixel number of map units per pixel
* Static function to get vertex tolerance value for a layer.
* The value is read from settings and transformed if necessary.
* @return value of vertex tolerance in map units
*/
static double vertexSearchRadius( double mapUnitsPerPixel );
static double vertexSearchRadius( QgsMapLayer* layer, QgsMapRenderer* renderer );
/**
* Static function to get default tolerance value from settings
* @param mapUnitsPerPixel number of map units per pixel
* Static function to get default tolerance value for a layer.
* The value is read from settings and transformed if necessary.
* @return value of default tolerance in map units
*/
static double defaultTolerance( double mapUnitsPerPixel );
static double defaultTolerance( QgsMapLayer* layer, QgsMapRenderer* renderer );
/**
/**
* Static function to translate tolerance value into current map unit value
* @param tolerace tolerance value to be translated
* @param mapUnitsPerPixel number of map units per pixel
* @param units type of units to be translated
* @return value of tolerance in map units
*/
static double toleranceInMapUnits(double tolerance, double mapUnitsPerPixel, UnitType units = MapUnits);
static double toleranceInMapUnits( double tolerance, QgsMapLayer* layer, QgsMapRenderer* renderer, UnitType units = MapUnits );
};

View File

@ -72,7 +72,7 @@ void QgsMapToolMoveFeature::canvasPressEvent( QMouseEvent * e )
//find first geometry under mouse cursor and store iterator to it
QgsPoint layerCoords = toLayerCoordinates(( QgsMapLayer* )vlayer, e->pos() );
QSettings settings;
double searchRadius = QgsTolerance::vertexSearchRadius( mCanvas->mapUnitsPerPixel() );
double searchRadius = QgsTolerance::vertexSearchRadius( mCanvas->currentLayer(), mCanvas->mapRenderer() );
QgsRectangle selectRect( layerCoords.x() - searchRadius, layerCoords.y() - searchRadius,
layerCoords.x() + searchRadius, layerCoords.y() + searchRadius );

View File

@ -57,7 +57,7 @@ int QgsSnapper::snapPoint( const QPoint& startPoint, QList<QgsSnappingResult>& s
//transform point from map coordinates to layer coordinates
layerCoordPoint = mMapRenderer->mapToLayerCoordinates( snapLayerIt->mLayer, mapCoordPoint );
double tolerance = QgsTolerance::toleranceInMapUnits( snapLayerIt->mTolerance, mMapRenderer->mapUnitsPerPixel(), snapLayerIt->mUnitType );
double tolerance = QgsTolerance::toleranceInMapUnits( snapLayerIt->mTolerance, snapLayerIt->mLayer, mMapRenderer, snapLayerIt->mUnitType );
if ( snapLayerIt->mLayer->snapWithContext( layerCoordPoint, tolerance,
currentResultList, snapLayerIt->mSnapTo ) != 0 )
{

View File

@ -15,29 +15,70 @@
#include "qgstolerance.h"
#include <QSettings>
#include <QPoint>
#include <math.h>
double QgsTolerance::toleranceInMapUnits( double tolerance, double mapUnitsPerPixel, UnitType units )
double QgsTolerance::toleranceInMapUnits( double tolerance, QgsMapLayer* layer, QgsMapRenderer* renderer, UnitType units )
{
if ( units == MapUnits )
{
return tolerance;
}
double mapUnitsPerPixel = computeMapUnitPerPixel( layer, renderer );
return tolerance * mapUnitsPerPixel;
}
double QgsTolerance::vertexSearchRadius( double mapUnitsPerPixel )
double QgsTolerance::vertexSearchRadius( QgsMapLayer* layer, QgsMapRenderer* renderer )
{
QSettings settings;
double tolerance = settings.value( "/qgis/digitizing/search_radius_vertex_edit", 10 ).toDouble();
UnitType units = ( QgsTolerance::UnitType ) settings.value( "/qgis/digitizing/search_radius_vertex_edit_unit", 0 ).toInt();
return toleranceInMapUnits( tolerance, mapUnitsPerPixel, units );
return toleranceInMapUnits( tolerance, layer, renderer, units );
}
double QgsTolerance::defaultTolerance( double mapUnitsPerPixel )
double QgsTolerance::defaultTolerance( QgsMapLayer* layer, QgsMapRenderer* renderer )
{
QSettings settings;
double tolerance = settings.value( "/qgis/digitizing/default_snapping_tolerance", 0 ).toDouble();
UnitType units = ( QgsTolerance::UnitType ) settings.value( "/qgis/digitizing/default_snapping_tolerance_unit", 0 ).toInt();
return toleranceInMapUnits( tolerance, mapUnitsPerPixel, units );
return toleranceInMapUnits( tolerance, layer, renderer, units );
}
double QgsTolerance::computeMapUnitPerPixel( QgsMapLayer* layer, QgsMapRenderer* renderer )
{
if ( ! renderer->hasCrsTransformEnabled() )
{
// if the on-the-fly projections are not enabled, layer units pre pixel are the same as map units per pixel
return renderer->mapUnitsPerPixel();
}
// the layer is projected. Find out how many pixels are in one map unit - either horizontal and vertical direction
// this check might not work correctly in some cases
// (on a large area the pixels projected around "0,0" can have different properties from the actual point)
QgsPoint p1 = toLayerCoordinates(layer, renderer, QPoint(0,1));
QgsPoint p2 = toLayerCoordinates(layer, renderer, QPoint(0,2));
QgsPoint p3 = toLayerCoordinates(layer, renderer, QPoint(1,0));
QgsPoint p4 = toLayerCoordinates(layer, renderer, QPoint(2,0));
double x = p1.sqrDist(p2);
double y = p3.sqrDist(p4);
if (x > y)
{
return sqrt(x);
}
else
{
return sqrt(y);
}
}
QgsPoint QgsTolerance::toLayerCoordinates( QgsMapLayer* layer, QgsMapRenderer* renderer, const QPoint& point )
{
QgsPoint pt = renderer->coordinateTransform()->toMapCoordinates( point );
return renderer->mapToLayerCoordinates( layer, pt );
}

View File

@ -15,7 +15,10 @@
#ifndef QGSTOLERANCE_H
#define QGSTOLERANCE_H
#include "qgsmaptopixel.h"
#include "qgsmaprenderer.h"
#include "qgsmaplayer.h"
#include "qgspoint.h"
/** \ingroup core
* This is the class is providing tolerance value in map unit values.
@ -36,27 +39,30 @@ class CORE_EXPORT QgsTolerance
};
/**
* Static function to get vertex tolerance value from settings
* @param mapUnitsPerPixel number of map units per pixel
* Static function to get vertex tolerance value for a layer.
* The value is read from settings and transformed if necessary.
* @return value of vertex tolerance in map units
*/
static double vertexSearchRadius( double mapUnitsPerPixel );
static double vertexSearchRadius( QgsMapLayer* layer, QgsMapRenderer* renderer );
/**
* Static function to get default tolerance value from settings
* @param mapUnitsPerPixel number of map units per pixel
* Static function to get default tolerance value for a layer.
* The value is read from settings and transformed if necessary.
* @return value of default tolerance in map units
*/
static double defaultTolerance( double mapUnitsPerPixel );
static double defaultTolerance( QgsMapLayer* layer, QgsMapRenderer* renderer );
/**
* Static function to translate tolerance value into current map unit value
* @param tolerace tolerance value to be translated
* @param mapUnitsPerPixel number of map units per pixel
* @param units type of units to be translated
* @return value of tolerance in map units
*/
static double toleranceInMapUnits( double tolerance, double mapUnitsPerPixel, UnitType units = MapUnits );
static double toleranceInMapUnits( double tolerance, QgsMapLayer* layer, QgsMapRenderer* renderer, UnitType units = MapUnits );
private:
static double computeMapUnitPerPixel( QgsMapLayer* layer, QgsMapRenderer* renderer );
static QgsPoint toLayerCoordinates( QgsMapLayer* layer, QgsMapRenderer* renderer, const QPoint& point );
};

View File

@ -101,7 +101,7 @@ int QgsMapCanvasSnapper::snapToCurrentLayer( const QPoint& p, QList<QgsSnappingR
if ( snappingTol < 0 )
{
//use search tolerance for vertex editing
snapLayer.mTolerance = QgsTolerance::vertexSearchRadius( mMapCanvas->mapUnitsPerPixel() );
snapLayer.mTolerance = QgsTolerance::vertexSearchRadius( vlayer, mMapCanvas->mapRenderer() );
}
else
{
@ -248,7 +248,7 @@ int QgsMapCanvasSnapper::snapToBackgroundLayers( const QPoint& p, QList<QgsSnapp
}
//default snapping tolerance (returned in map units)
snapLayer.mTolerance = QgsTolerance::defaultTolerance( mMapCanvas->mapUnitsPerPixel() );
snapLayer.mTolerance = QgsTolerance::defaultTolerance( currentVectorLayer, mMapCanvas->mapRenderer() );
snapLayer.mUnitType = QgsTolerance::MapUnits;
snapLayers.append( snapLayer );