diff --git a/python/core/core.sip b/python/core/core.sip index 8b782501231..21f850dc4f8 100644 --- a/python/core/core.sip +++ b/python/core/core.sip @@ -64,6 +64,7 @@ %Include qgscoordinatereferencesystem.sip %Include qgssymbol.sip %Include qgssymbologyutils.sip +%Include qgstolerance.sip %Include qgsuniquevaluerenderer.sip %Include qgsvectordataprovider.sip %Include qgsvectorfilewriter.sip diff --git a/python/core/qgssnapper.sip b/python/core/qgssnapper.sip index 021071310f6..49662bd12a5 100644 --- a/python/core/qgssnapper.sip +++ b/python/core/qgssnapper.sip @@ -65,6 +65,8 @@ public: double mTolerance; /**What snapping type to use (snap to segment or to vertex)*/ QgsSnapper::SnappingType mSnapTo; + /**What unit is used for tolerance*/ + QgsTolerance::UnitType mUnitType; }; QgsSnapper(QgsMapRenderer* mapRender); diff --git a/python/core/qgstolerance.sip b/python/core/qgstolerance.sip new file mode 100644 index 00000000000..d706925f17c --- /dev/null +++ b/python/core/qgstolerance.sip @@ -0,0 +1,42 @@ + +class QgsTolerance +{ +%TypeHeaderCode +#include +%End + +public: + /**Type of unit of tolerance value from settings*/ + enum UnitType + { + /**Map unit value*/ + MapUnits, + /**Pixels unit of tolerance*/ + Pixels + }; + + /** + * Static function to get vertex tolerance value from settings + * @param mapUnitsPerPixel number of map units per pixel + * @return value of vertex tolerance in map units + */ + static double vertexSearchRadius( double mapUnitsPerPixel ); + + /** + * Static function to get default tolerance value from settings + * @param mapUnitsPerPixel number of map units per pixel + * @return value of default tolerance in map units + */ + static double defaultTolerance( double mapUnitsPerPixel ); + + /** + * 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); + +}; + diff --git a/src/app/qgsmaptoolmovefeature.cpp b/src/app/qgsmaptoolmovefeature.cpp index f9549f241ab..bf8531d20fe 100644 --- a/src/app/qgsmaptoolmovefeature.cpp +++ b/src/app/qgsmaptoolmovefeature.cpp @@ -21,6 +21,7 @@ #include "qgsrubberband.h" #include "qgsvectordataprovider.h" #include "qgsvectorlayer.h" +#include "qgstolerance.h" #include #include #include @@ -71,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 = settings.value( "/qgis/digitizing/search_radius_vertex_edit", 10 ).toDouble(); + double searchRadius = QgsTolerance::vertexSearchRadius( mCanvas->mapUnitsPerPixel() ); QgsRectangle selectRect( layerCoords.x() - searchRadius, layerCoords.y() - searchRadius, layerCoords.x() + searchRadius, layerCoords.y() + searchRadius ); diff --git a/src/app/qgsoptions.cpp b/src/app/qgsoptions.cpp index c82713d3aed..a7c2571eec8 100644 --- a/src/app/qgsoptions.cpp +++ b/src/app/qgsoptions.cpp @@ -22,6 +22,7 @@ #include "qgisapp.h" #include "qgsgenericprojectionselector.h" #include "qgscoordinatereferencesystem.h" +#include "qgstolerance.h" #include #include @@ -196,6 +197,25 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) : mDefaultSnapModeComboBox->setCurrentIndex( mDefaultSnapModeComboBox->findData( defaultSnapString ) ); mDefaultSnappingToleranceSpinBox->setValue( settings.value( "/qgis/digitizing/default_snapping_tolerance", 0 ).toDouble() ); mSearchRadiusVertexEditSpinBox->setValue( settings.value( "/qgis/digitizing/search_radius_vertex_edit", 10 ).toDouble() ); + int index; + if (settings.value( "/qgis/digitizing/default_snapping_tolerance_unit", 0 ).toInt() == QgsTolerance::MapUnits) + { + index = mDefaultSnappingToleranceComboBox->findText( tr( "map units" ) ); + } + else + { + index = mDefaultSnappingToleranceComboBox->findText( tr( "pixels" ) ); + } + mDefaultSnappingToleranceComboBox->setCurrentIndex( index ); + if (settings.value( "/qgis/digitizing/search_radius_vertex_edit_unit", 0 ).toInt() == QgsTolerance::MapUnits) + { + index = mSearchRadiusVertexEditComboBox->findText( tr( "map units" ) ); + } + else + { + index = mSearchRadiusVertexEditComboBox->findText( tr( "pixels" ) ); + } + mSearchRadiusVertexEditComboBox->setCurrentIndex( settings.value( "/qgis/digitizing/search_radius_vertex_edit_unit", 0 ).toInt() ); //vertex marker mMarkerStyleComboBox->addItem( tr( "Semi transparent circle" ) ); @@ -374,6 +394,11 @@ void QgsOptions::saveOptions() settings.setValue( "/qgis/digitizing/default_snap_mode", defaultSnapModeString ); settings.setValue( "/qgis/digitizing/default_snapping_tolerance", mDefaultSnappingToleranceSpinBox->value() ); settings.setValue( "/qgis/digitizing/search_radius_vertex_edit", mSearchRadiusVertexEditSpinBox->value() ); + settings.setValue( "/qgis/digitizing/default_snapping_tolerance_unit", + (mDefaultSnappingToleranceComboBox->currentIndex() == 0 ? QgsTolerance::MapUnits : QgsTolerance::Pixels ) ); + settings.setValue( "/qgis/digitizing/search_radius_vertex_edit_unit", + (mSearchRadiusVertexEditComboBox->currentIndex() == 0 ? QgsTolerance::MapUnits : QgsTolerance::Pixels ) ); + QString markerComboText = mMarkerStyleComboBox->currentText(); if ( markerComboText == tr( "Semi transparent circle" ) ) diff --git a/src/app/qgsprojectproperties.cpp b/src/app/qgsprojectproperties.cpp index d20a60ce11d..e1f91ba5cd1 100644 --- a/src/app/qgsprojectproperties.cpp +++ b/src/app/qgsprojectproperties.cpp @@ -122,11 +122,13 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa QStringList layerIdList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingList", &ok ); QStringList enabledList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingEnabledList", &ok ); QStringList toleranceList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingToleranceList", &ok ); + QStringList toleranceUnitList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingToleranceUnitList", &ok ); QStringList snapToList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnapToList", &ok ); QStringList::const_iterator idIter = layerIdList.constBegin(); QStringList::const_iterator enabledIter = enabledList.constBegin(); QStringList::const_iterator tolIter = toleranceList.constBegin(); + QStringList::const_iterator tolUnitIter = toleranceUnitList.constBegin(); QStringList::const_iterator snapToIter = snapToList.constBegin(); QgsMapLayer* currentLayer = 0; @@ -160,6 +162,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas* mapCanvas, QWidget *pa newEntry.snapTo = 2; } newEntry.tolerance = tolIter->toDouble(); + newEntry.toleranceUnit = tolUnitIter->toInt(); mSnappingLayerSettings.insert( *idIter, newEntry ); } } @@ -306,11 +309,13 @@ void QgsProjectProperties::apply() QStringList snapToList; QStringList toleranceList; QStringList enabledList; + QStringList toleranceUnitList; for ( layerEntryIt = mSnappingLayerSettings.constBegin(); layerEntryIt != mSnappingLayerSettings.constEnd(); ++layerEntryIt ) { layerIdList << layerEntryIt.key(); toleranceList << QString::number( layerEntryIt->tolerance, 'f' ); + toleranceUnitList << QString::number( (int)layerEntryIt->toleranceUnit ); if ( layerEntryIt->checked ) { enabledList << "enabled"; @@ -338,6 +343,7 @@ void QgsProjectProperties::apply() QgsProject::instance()->writeEntry( "Digitizing", "/LayerSnappingList", layerIdList ); QgsProject::instance()->writeEntry( "Digitizing", "/LayerSnapToList", snapToList ); QgsProject::instance()->writeEntry( "Digitizing", "/LayerSnappingToleranceList", toleranceList ); + QgsProject::instance()->writeEntry( "Digitizing", "/LayerSnappingToleranceUnitList", toleranceUnitList ); QgsProject::instance()->writeEntry( "Digitizing", "/LayerSnappingEnabledList", enabledList ); } diff --git a/src/app/qgssnappingdialog.cpp b/src/app/qgssnappingdialog.cpp index 57940172527..2ada458f108 100644 --- a/src/app/qgssnappingdialog.cpp +++ b/src/app/qgssnappingdialog.cpp @@ -71,6 +71,12 @@ QgsSnappingDialog::QgsSnappingDialog( QgsMapCanvas* canvas, const QMapsetValidator( validator ); mLayerTreeWidget->setItemWidget( newItem, 2, snappingToleranceEdit ); + //snap to vertex/ snap to segment + QComboBox* toleranceUnitsComboBox = new QComboBox( mLayerTreeWidget ); + toleranceUnitsComboBox->insertItem( 0, tr( "map units" ) ); + toleranceUnitsComboBox->insertItem( 1, tr( "pixels" ) ); + mLayerTreeWidget->setItemWidget( newItem, 3, toleranceUnitsComboBox ); + settingIt = settings.find( currentVectorLayer->getLayerID() ); if ( settingIt != settings.constEnd() ) { @@ -89,6 +95,15 @@ QgsSnappingDialog::QgsSnappingDialog( QgsMapCanvas* canvas, const QMapfindText( tr( "to vertex and segment" ) ); } snapToComboBox->setCurrentIndex( index ); + if ( settingIt.value().toleranceUnit == 0 )//map units + { + index = toleranceUnitsComboBox->findText( tr( "map units" ) ); + } + else + { + index = toleranceUnitsComboBox->findText( tr( "pixels" ) ); + } + toleranceUnitsComboBox->setCurrentIndex( index ); if ( settingIt.value().checked ) { newItem->setCheckState( 0, Qt::Checked ); @@ -103,8 +118,9 @@ QgsSnappingDialog::QgsSnappingDialog( QgsMapCanvas* canvas, const QMapresizeColumnToContents( 0 ); - mLayerTreeWidget->setColumnWidth( 1, 300 ); //hardcoded for now + mLayerTreeWidget->setColumnWidth( 1, 200 ); //hardcoded for now mLayerTreeWidget->resizeColumnToContents( 2 ); + mLayerTreeWidget->resizeColumnToContents( 3 ); } } @@ -127,7 +143,9 @@ void QgsSnappingDialog::layerSettings( QMap& settings ) con QString layerId; QString layerName; QString snapToItemText; + QString toleranceItemText; int snapTo; + int toleranceUnit; double tolerance; bool checked = false; @@ -144,6 +162,7 @@ void QgsSnappingDialog::layerSettings( QMap& settings ) con layerId = mLayerIds.at( i ); checked = ( currentItem->checkState( 0 ) == Qt::Checked ); snapToItemText = (( QComboBox* )( mLayerTreeWidget->itemWidget( currentItem, 1 ) ) )->currentText(); + toleranceItemText = (( QComboBox* )( mLayerTreeWidget->itemWidget( currentItem, 3 ) ) )->currentText(); if ( snapToItemText == tr( "to vertex" ) ) { snapTo = 0; @@ -156,10 +175,18 @@ void QgsSnappingDialog::layerSettings( QMap& settings ) con { snapTo = 2; } + if ( toleranceItemText == tr( "map units" ) ) + { + toleranceUnit = 0; + } + else //to vertex and segment + { + toleranceUnit = 1; + } tolerance = (( QLineEdit* )( mLayerTreeWidget->itemWidget( currentItem, 2 ) ) )->text().toDouble(); LayerEntry newEntry; newEntry.checked = checked; newEntry.snapTo = snapTo; newEntry.layerName = layerName; - newEntry.tolerance = tolerance; + newEntry.tolerance = tolerance; newEntry.toleranceUnit = toleranceUnit; settings.insert( layerId, newEntry ); } } diff --git a/src/app/qgssnappingdialog.h b/src/app/qgssnappingdialog.h index f023fd1fa4c..40ec0a34693 100644 --- a/src/app/qgssnappingdialog.h +++ b/src/app/qgssnappingdialog.h @@ -28,6 +28,7 @@ struct LayerEntry int snapTo; //0 = to vertex, 1 = to segment, 2 = to vertex and to segment QString layerName; double tolerance; + int toleranceUnit; }; /**A dialog to enter advanced editing properties, e.g. topological editing, snapping settings diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 1a3d777d1d0..8955bcb35bf 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -43,6 +43,7 @@ SET(QGIS_CORE_SRCS qgssearchtreenode.cpp qgssnapper.cpp qgscoordinatereferencesystem.cpp + qgstolerance.cpp qgsvectordataprovider.cpp qgsvectorfilewriter.cpp qgsvectorlayer.cpp diff --git a/src/core/qgssnapper.cpp b/src/core/qgssnapper.cpp index 81371614f47..a211478bf06 100644 --- a/src/core/qgssnapper.cpp +++ b/src/core/qgssnapper.cpp @@ -56,7 +56,9 @@ int QgsSnapper::snapPoint( const QPoint& startPoint, QList& s { //transform point from map coordinates to layer coordinates layerCoordPoint = mMapRenderer->mapToLayerCoordinates( snapLayerIt->mLayer, mapCoordPoint ); - if ( snapLayerIt->mLayer->snapWithContext( layerCoordPoint, snapLayerIt->mTolerance, + + double tolerance = QgsTolerance::toleranceInMapUnits( snapLayerIt->mTolerance, mMapRenderer->mapUnitsPerPixel(), snapLayerIt->mUnitType ); + if ( snapLayerIt->mLayer->snapWithContext( layerCoordPoint, tolerance, currentResultList, snapLayerIt->mSnapTo ) != 0 ) { //error diff --git a/src/core/qgssnapper.h b/src/core/qgssnapper.h index ab09a55120e..98655689e12 100644 --- a/src/core/qgssnapper.h +++ b/src/core/qgssnapper.h @@ -19,6 +19,7 @@ #define QGSSNAPPER_H #include "qgspoint.h" +#include "qgstolerance.h" #include #include @@ -86,6 +87,8 @@ class CORE_EXPORT QgsSnapper double mTolerance; /**What snapping type to use (snap to segment or to vertex)*/ QgsSnapper::SnappingType mSnapTo; + /**What unit is used for tolerance*/ + QgsTolerance::UnitType mUnitType; }; QgsSnapper( QgsMapRenderer* mapRender ); diff --git a/src/core/qgstolerance.cpp b/src/core/qgstolerance.cpp new file mode 100644 index 00000000000..5b78e7599ff --- /dev/null +++ b/src/core/qgstolerance.cpp @@ -0,0 +1,43 @@ +/*************************************************************************** + qgstolerance.cpp - wrapper for tolerance handling + ---------------------- + begin : March 2009 + copyright : (C) 2009 by Richard Kostecky + email : csf.kostej at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgstolerance.h" +#include + + +double QgsTolerance::toleranceInMapUnits(double tolerance, double mapUnitsPerPixel, UnitType units) +{ + if (units == MapUnits) + { + return tolerance; + } + return tolerance * mapUnitsPerPixel; +} + +double QgsTolerance::vertexSearchRadius( double mapUnitsPerPixel ) +{ + 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); +} + +double QgsTolerance::defaultTolerance( double mapUnitsPerPixel ) +{ + 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); +} diff --git a/src/core/qgstolerance.h b/src/core/qgstolerance.h new file mode 100644 index 00000000000..13e370d5273 --- /dev/null +++ b/src/core/qgstolerance.h @@ -0,0 +1,63 @@ +/*************************************************************************** + qgstolerance.h - wrapper for tolerance handling + ---------------------- + begin : March 2009 + copyright : (C) 2009 by Richard Kostecky + email : csf.kostej at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGSTOLERANCE_H +#define QGSTOLERANCE_H + + +/** \ingroup core + * This is the class is providing tolerance value in map unit values. + * + * \note This class has been added in version 1.1. + */ +class CORE_EXPORT QgsTolerance +{ + + public: + /**Type of unit of tolerance value from settings*/ + enum UnitType + { + /**Map unit value*/ + MapUnits, + /**Pixels unit of tolerance*/ + Pixels + }; + + /** + * Static function to get vertex tolerance value from settings + * @param mapUnitsPerPixel number of map units per pixel + * @return value of vertex tolerance in map units + */ + static double vertexSearchRadius( double mapUnitsPerPixel ); + + /** + * Static function to get default tolerance value from settings + * @param mapUnitsPerPixel number of map units per pixel + * @return value of default tolerance in map units + */ + static double defaultTolerance( double mapUnitsPerPixel ); + + /** + * 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); + +}; + +#endif diff --git a/src/gui/qgsmapcanvassnapper.cpp b/src/gui/qgsmapcanvassnapper.cpp index e81af5483ba..f114ceae9b7 100644 --- a/src/gui/qgsmapcanvassnapper.cpp +++ b/src/gui/qgsmapcanvassnapper.cpp @@ -21,8 +21,10 @@ #include "qgsmaptopixel.h" #include "qgsproject.h" #include "qgsvectorlayer.h" +#include "qgstolerance.h" #include + QgsMapCanvasSnapper::QgsMapCanvasSnapper( QgsMapCanvas* canvas ): mMapCanvas( canvas ), mSnapper( 0 ) { if ( canvas ) @@ -92,13 +94,14 @@ int QgsMapCanvasSnapper::snapToCurrentLayer( const QPoint& p, QListmapUnitsPerPixel()); } else { @@ -149,9 +152,10 @@ int QgsMapCanvasSnapper::snapToBackgroundLayers( const QPoint& p, QListreadListEntry( "Digitizing", "/LayerSnappingEnabledList", &ok ); QStringList toleranceList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingToleranceList", &ok ); + QStringList toleranceUnitList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingToleranceUnitList", &ok ); QStringList snapToList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnapToList", &ok ); - if ( !( layerIdList.size() == enabledList.size() && layerIdList.size() == toleranceList.size() && layerIdList.size() == snapToList.size() ) ) + if ( !( layerIdList.size() == enabledList.size() && layerIdList.size() == toleranceList.size() && layerIdList.size() == toleranceUnitList.size() && layerIdList.size() == snapToList.size() ) ) { return 1; //lists must have the same size, otherwise something is wrong } @@ -168,10 +172,11 @@ int QgsMapCanvasSnapper::snapToBackgroundLayers( const QPoint& p, QListtoDouble(); + snapLayer.mUnitType = (QgsTolerance::UnitType) tolUnitIt->toInt(); //segment or vertex if (( *snapIt ) == "to_vertex" ) @@ -241,8 +247,9 @@ int QgsMapCanvasSnapper::snapToBackgroundLayers( const QPoint& p, QListmapUnitsPerPixel()); + snapLayer.mUnitType = QgsTolerance::MapUnits; snapLayers.append( snapLayer ); } diff --git a/src/ui/qgsoptionsbase.ui b/src/ui/qgsoptionsbase.ui index 44fcda21b46..e96c1d1d8f6 100644 --- a/src/ui/qgsoptionsbase.ui +++ b/src/ui/qgsoptionsbase.ui @@ -659,7 +659,7 @@ - + @@ -729,6 +729,40 @@ + + + + + 0 + 0 + + + + + map units + + + + + pixels + + + + + + + + + map units + + + + + pixels + + + + diff --git a/src/ui/qgssnappingdialogbase.ui b/src/ui/qgssnappingdialogbase.ui index 3e119b2e468..6239742bb01 100644 --- a/src/ui/qgssnappingdialogbase.ui +++ b/src/ui/qgssnappingdialogbase.ui @@ -13,10 +13,22 @@ Snapping options - + 9 - + + 9 + + + 9 + + + 9 + + + 6 + + 6 @@ -36,6 +48,11 @@ Tolerance + + + Units + +