00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "qgsmapcanvassnapper.h"
00019 #include "qgsmapcanvas.h"
00020 #include "qgsmaplayerregistry.h"
00021 #include "qgsmaptopixel.h"
00022 #include "qgsproject.h"
00023 #include "qgsvectorlayer.h"
00024 #include "qgstolerance.h"
00025 #include <QSettings>
00026
00027
00028 QgsMapCanvasSnapper::QgsMapCanvasSnapper( QgsMapCanvas* canvas ): mMapCanvas( canvas ), mSnapper( 0 )
00029 {
00030 if ( canvas )
00031 {
00032 QgsMapRenderer* canvasRender = canvas->mapRenderer();
00033 if ( canvasRender )
00034 {
00035 mSnapper = new QgsSnapper( canvasRender );
00036 }
00037 }
00038 }
00039
00040 QgsMapCanvasSnapper::QgsMapCanvasSnapper(): mMapCanvas( 0 ), mSnapper( 0 )
00041 {
00042
00043 }
00044
00045 QgsMapCanvasSnapper::~QgsMapCanvasSnapper()
00046 {
00047 delete mSnapper;
00048 }
00049
00050 void QgsMapCanvasSnapper::setMapCanvas( QgsMapCanvas* canvas )
00051 {
00052 mMapCanvas = canvas;
00053 delete mSnapper;
00054 if ( mMapCanvas )
00055 {
00056 mSnapper = new QgsSnapper( canvas->mapRenderer() );
00057 }
00058 else
00059 {
00060 mSnapper = 0;
00061 }
00062 }
00063
00064 int QgsMapCanvasSnapper::snapToCurrentLayer( const QPoint& p, QList<QgsSnappingResult>& results, QgsSnapper::SnappingType snap_to, double snappingTol, const QList<QgsPoint>& excludePoints )
00065 {
00066 results.clear();
00067
00068 if ( mSnapper && mMapCanvas )
00069 {
00070
00071
00072 int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
00073 if ( topologicalEditing == 0 )
00074 {
00075 mSnapper->setSnapMode( QgsSnapper::SnapWithOneResult );
00076 }
00077 else
00078 {
00079 mSnapper->setSnapMode( QgsSnapper::SnapWithResultsForSamePosition );
00080 }
00081
00082
00083 QgsMapLayer* currentLayer = mMapCanvas->currentLayer();
00084 if ( !currentLayer )
00085 {
00086 return 2;
00087 }
00088 QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( currentLayer );
00089 if ( !vlayer )
00090 {
00091 return 3;
00092 }
00093
00094 QgsSnapper::SnapLayer snapLayer;
00095 snapLayer.mLayer = vlayer;
00096 snapLayer.mSnapTo = snap_to;
00097 snapLayer.mUnitType = QgsTolerance::MapUnits;
00098
00099 QSettings settings;
00100
00101 if ( snappingTol < 0 )
00102 {
00103
00104 snapLayer.mTolerance = QgsTolerance::vertexSearchRadius( vlayer, mMapCanvas->mapRenderer() );
00105 }
00106 else
00107 {
00108 snapLayer.mTolerance = snappingTol;
00109 }
00110
00111 QList<QgsSnapper::SnapLayer> snapLayers;
00112 snapLayers.append( snapLayer );
00113 mSnapper->setSnapLayers( snapLayers );
00114
00115 if ( mSnapper->snapPoint( p, results, excludePoints ) != 0 )
00116 {
00117 return 4;
00118 }
00119
00120 return 0;
00121 }
00122 else
00123 {
00124 return 1;
00125 }
00126 }
00127
00128 int QgsMapCanvasSnapper::snapToBackgroundLayers( const QPoint& p, QList<QgsSnappingResult>& results, const QList<QgsPoint>& excludePoints )
00129 {
00130 results.clear();
00131
00132 if ( mSnapper )
00133 {
00134
00135 int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );
00136 if ( topologicalEditing == 0 )
00137 {
00138 mSnapper->setSnapMode( QgsSnapper::SnapWithOneResult );
00139 }
00140 else
00141 {
00142 mSnapper->setSnapMode( QgsSnapper::SnapWithResultsForSamePosition );
00143 }
00144
00145
00146 bool ok;
00147 bool snappingDefinedInProject = true;
00148 QStringList layerIdList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingList", &ok );
00149 if ( !ok )
00150 {
00151 snappingDefinedInProject = false;
00152 }
00153 QStringList enabledList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingEnabledList", &ok );
00154 QStringList toleranceList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingToleranceList", &ok );
00155 QStringList toleranceUnitList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnappingToleranceUnitList", &ok );
00156 QStringList snapToList = QgsProject::instance()->readListEntry( "Digitizing", "/LayerSnapToList", &ok );
00157
00158 if ( !( layerIdList.size() == enabledList.size() && layerIdList.size() == toleranceList.size() && layerIdList.size() == toleranceUnitList.size() && layerIdList.size() == snapToList.size() ) )
00159 {
00160 return 1;
00161 }
00162
00163 QList<QgsSnapper::SnapLayer> snapLayers;
00164 QgsSnapper::SnapLayer snapLayer;
00165
00166
00167 if ( snappingDefinedInProject )
00168 {
00169
00170 QgsMapLayer* layer = 0;
00171 QgsVectorLayer* vlayer = 0;
00172
00173 QStringList::const_iterator layerIt = layerIdList.constBegin();
00174 QStringList::const_iterator tolIt = toleranceList.constBegin();
00175 QStringList::const_iterator tolUnitIt = toleranceUnitList.constBegin();
00176 QStringList::const_iterator snapIt = snapToList.constBegin();
00177 QStringList::const_iterator enabledIt = enabledList.constBegin();
00178
00179 for ( ; layerIt != layerIdList.constEnd(); ++layerIt, ++tolIt, ++tolUnitIt, ++snapIt, ++enabledIt )
00180 {
00181 if (( *enabledIt ) != "enabled" )
00182 {
00183 continue;
00184 }
00185
00186
00187 layer = QgsMapLayerRegistry::instance()->mapLayer( *layerIt );
00188 if ( layer == NULL )
00189 continue;
00190 vlayer = qobject_cast<QgsVectorLayer *>( layer );
00191 if ( vlayer == NULL )
00192 continue;
00193
00194 snapLayer.mLayer = vlayer;
00195
00196
00197 snapLayer.mTolerance = tolIt->toDouble();
00198 snapLayer.mUnitType = ( QgsTolerance::UnitType ) tolUnitIt->toInt();
00199
00200
00201 if (( *snapIt ) == "to_vertex" )
00202 {
00203 snapLayer.mSnapTo = QgsSnapper::SnapToVertex;
00204 }
00205 else if (( *snapIt ) == "to_segment" )
00206 {
00207 snapLayer.mSnapTo = QgsSnapper::SnapToSegment;
00208 }
00209 else
00210 {
00211 snapLayer.mSnapTo = QgsSnapper::SnapToVertexAndSegment;
00212 }
00213
00214 snapLayers.append( snapLayer );
00215 }
00216 }
00217 else
00218 {
00219 QgsMapLayer* currentLayer = mMapCanvas->currentLayer();
00220 if ( !currentLayer )
00221 {
00222 return 2;
00223 }
00224
00225 QgsVectorLayer* currentVectorLayer = qobject_cast<QgsVectorLayer *>( currentLayer );
00226 if ( !currentVectorLayer )
00227 {
00228 return 3;
00229 }
00230
00231 snapLayer.mLayer = currentVectorLayer;
00232 QSettings settings;
00233
00234
00235 QString defaultSnapString = settings.value( "/qgis/digitizing/default_snap_mode", "to vertex" ).toString();
00236 if ( defaultSnapString == "to segment" )
00237 {
00238 snapLayer.mSnapTo = QgsSnapper::SnapToSegment;
00239 }
00240 else if ( defaultSnapString == "to vertex and segment" )
00241 {
00242 snapLayer.mSnapTo = QgsSnapper::SnapToVertexAndSegment;
00243 }
00244 else
00245 {
00246 snapLayer.mSnapTo = QgsSnapper::SnapToVertex;
00247 }
00248
00249
00250 snapLayer.mTolerance = QgsTolerance::defaultTolerance( currentVectorLayer, mMapCanvas->mapRenderer() );
00251 snapLayer.mUnitType = QgsTolerance::MapUnits;
00252
00253 snapLayers.append( snapLayer );
00254 }
00255
00256 mSnapper->setSnapLayers( snapLayers );
00257
00258 if ( mSnapper->snapPoint( p, results, excludePoints ) != 0 )
00259 {
00260 return 4;
00261 }
00262 return 0;
00263 }
00264 else
00265 {
00266 return 5;
00267 }
00268 }