void QgsMapMouseEvent::snapPoint() { if ( mSnappingMode == NoSnapping ) return; QgsSnappingUtils* snappingUtils = mMapTool->canvas()->snappingUtils(); QgsSnappingUtils::SnapToMapMode canvasMode = snappingUtils->snapToMapMode(); if ( mSnappingMode == SnapAllLayers ) { int type; double tolerance; QgsTolerance::UnitType unit; snappingUtils->defaultSettings( type, tolerance, unit ); snappingUtils->setSnapToMapMode( QgsSnappingUtils::SnapAllLayers ); snappingUtils->setDefaultSettings( QgsPointLocator::Vertex | QgsPointLocator::Edge, tolerance, unit ); mSnapMatch = snappingUtils->snapToMap( mMapPoint ); snappingUtils->setSnapToMapMode( canvasMode ); snappingUtils->setDefaultSettings( type, tolerance, unit ); } else { mSnapMatch = snappingUtils->snapToMap( mMapPoint ); } mMapPoint = mSnapMatch.isValid() ? mSnapMatch.point() : mOriginalPoint; }
void QgsMapToolOffsetCurve::canvasPressEvent( QMouseEvent* e ) { deleteRubberBandAndGeometry(); mGeometryModified = false; mForceCopy = false; if ( !mCanvas ) { return; } //get selected features or snap to nearest feature if no selection QgsVectorLayer* layer = currentVectorLayer(); if ( !layer ) { notifyNotVectorLayer(); return; } QgsSnappingUtils* snapping = mCanvas->snappingUtils(); // store previous settings int oldType; double oldSearchRadius; QgsTolerance::UnitType oldSearchRadiusUnit; QgsSnappingUtils::SnapToMapMode oldMode = snapping->snapToMapMode(); snapping->defaultSettings( oldType, oldSearchRadius, oldSearchRadiusUnit ); // setup new settings (temporary) QSettings settings; snapping->setSnapToMapMode( QgsSnappingUtils::SnapAllLayers ); snapping->setDefaultSettings( QgsPointLocator::Edge, settings.value( "/Qgis/digitizing/search_radius_vertex_edit", 10 ).toDouble(), ( QgsTolerance::UnitType ) settings.value( "/Qgis/digitizing/search_radius_vertex_edit_unit", QgsTolerance::Pixels ).toInt() ); QgsPointLocator::Match match = snapping->snapToMap( e->pos() ); // restore old settings snapping->setSnapToMapMode( oldMode ); snapping->setDefaultSettings( oldType, oldSearchRadius, oldSearchRadiusUnit ); if ( match.hasEdge() && match.layer() ) { mSourceLayerId = match.layer()->id(); QgsFeature fet; if ( match.layer()->getFeatures( QgsFeatureRequest( match.featureId() ) ).nextFeature( fet ) ) { mForceCopy = ( e->modifiers() & Qt::ControlModifier ); //no geometry modification if ctrl is pressed mOriginalGeometry = createOriginGeometry( match.layer(), match, fet ); mRubberBand = createRubberBand(); if ( mRubberBand ) { mRubberBand->setToGeometry( mOriginalGeometry, layer ); } mModifiedFeature = fet.id(); createDistanceItem(); } } }
QList<QgsPoint> QgsMapMouseEvent::snapSegment( SnappingMode snappingMode, bool* snapped , bool allLayers ) const { QList<QgsPoint> segment; QgsPoint pt1, pt2; // If there's a cached snapping result we use it if ( snappingMode == mSnappingMode && mSnapMatch.hasEdge() ) { mSnapMatch.edgePoints( pt1, pt2 ); segment << pt1 << pt2; } else if ( snappingMode != NoSnapping ) { QgsPointLocator::Match match; if ( snappingMode == SnapProjectConfig && !allLayers ) { // run snapToMap with only segments EdgesOnlyFilter filter; match = mMapCanvas->snappingUtils()->snapToMap( mOriginalMapPoint, &filter ); } else if ( snappingMode == SnapAllLayers || allLayers ) { // run snapToMap with only edges on all layers QgsSnappingUtils* snappingUtils = mMapCanvas->snappingUtils(); QgsSnappingUtils::SnapToMapMode canvasMode = snappingUtils->snapToMapMode(); int type; double tolerance; QgsTolerance::UnitType unit; snappingUtils->defaultSettings( type, tolerance, unit ); snappingUtils->setSnapToMapMode( QgsSnappingUtils::SnapAllLayers ); snappingUtils->setDefaultSettings( QgsPointLocator::Edge, tolerance, unit ); match = snappingUtils->snapToMap( mOriginalMapPoint ); snappingUtils->setSnapToMapMode( canvasMode ); snappingUtils->setDefaultSettings( type, tolerance, unit ); } if ( match.isValid() && match.hasEdge() ) { match.edgePoints( pt1, pt2 ); segment << pt1 << pt2; } } if ( snapped ) { *snapped = segment.count() == 2; } return segment; }
QgsPoint QgsMapMouseEvent::snapPoint( SnappingMode snappingMode ) { // Use cached result if ( mSnappingMode == snappingMode ) return mMapPoint; mSnappingMode = snappingMode; if ( snappingMode == NoSnapping ) { mMapPoint = mOriginalMapPoint; mPixelPoint = pos(); return mMapPoint; } QgsSnappingUtils* snappingUtils = mMapCanvas->snappingUtils(); QgsSnappingUtils::SnapToMapMode canvasMode = snappingUtils->snapToMapMode(); if ( snappingMode == SnapAllLayers ) { int type; double tolerance; QgsTolerance::UnitType unit; snappingUtils->defaultSettings( type, tolerance, unit ); snappingUtils->setSnapToMapMode( QgsSnappingUtils::SnapAllLayers ); snappingUtils->setDefaultSettings( QgsPointLocator::Vertex | QgsPointLocator::Edge, tolerance, unit ); mSnapMatch = snappingUtils->snapToMap( mMapPoint ); snappingUtils->setSnapToMapMode( canvasMode ); snappingUtils->setDefaultSettings( type, tolerance, unit ); } else { mSnapMatch = snappingUtils->snapToMap( mMapPoint ); } if ( mSnapMatch.isValid() ) { mMapPoint = mSnapMatch.point(); mPixelPoint = mapToPixelCoordinates( mMapPoint ); } else { mMapPoint = mOriginalMapPoint; mPixelPoint = pos(); } return mMapPoint; }
void testSnapModeCurrent() { QgsMapSettings mapSettings; mapSettings.setOutputSize( QSize( 100, 100 ) ); mapSettings.setExtent( QgsRectangle( 0, 0, 1, 1 ) ); QVERIFY( mapSettings.hasValidSettings() ); QgsSnappingUtils u; u.setMapSettings( mapSettings ); u.setCurrentLayer( mVL ); // first try with no snapping enabled u.setDefaultSettings( 0, 10, QgsTolerance::Pixels ); QgsPointLocator::Match m0 = u.snapToMap( QPoint( 100, 100 ) ); QVERIFY( !m0.isValid() ); QVERIFY( !m0.hasVertex() ); // now enable snapping u.setDefaultSettings( QgsPointLocator::Vertex | QgsPointLocator::Edge, 10, QgsTolerance::Pixels ); QgsPointLocator::Match m = u.snapToMap( QPoint( 100, 100 ) ); QVERIFY( m.isValid() ); QVERIFY( m.hasVertex() ); QCOMPARE( m.point(), QgsPoint( 1, 0 ) ); QgsPointLocator::Match m2 = u.snapToMap( QPoint( 0, 100 ) ); QVERIFY( !m2.isValid() ); QVERIFY( !m2.hasVertex() ); // do not consider edges in the following test - on 32-bit platforms // result was an edge match very close to (1,0) instead of being exactly (1,0) u.setDefaultSettings( QgsPointLocator::Vertex, 10, QgsTolerance::Pixels ); // test with filtering FilterExcludePoint myFilter( QgsPoint( 1, 0 ) ); QgsPointLocator::Match m3 = u.snapToMap( QPoint( 100, 100 ), &myFilter ); QVERIFY( !m3.isValid() ); }