Skip to content
Permalink
Browse files
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
  • Loading branch information
wonder committed Apr 13, 2009
1 parent 411dace commit 6aff4e96400f700bbbb1e303d2758dab33601666
Showing with 73 additions and 27 deletions.
  1. +8 −9 python/core/qgstolerance.sip
  2. +1 −1 src/app/qgsmaptoolmovefeature.cpp
  3. +1 −1 src/core/qgssnapper.cpp
  4. +46 −5 src/core/qgstolerance.cpp
  5. +15 −9 src/core/qgstolerance.h
  6. +2 −2 src/gui/qgsmapcanvassnapper.cpp
@@ -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 );

};

@@ -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 );

@@ -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 )
{
@@ -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 );
}
@@ -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 );

};

@@ -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 );

0 comments on commit 6aff4e9

Please sign in to comment.