Skip to content
Permalink
Browse files
- QgsSnapper: use one list of QgsSnapper::SnapLayer structs rather th…
…an three separate lists

- PyQGIS: finished QgsSnapper binding, added QgsMapCanvasSnapper


git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@9657 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
wonder committed Nov 17, 2008
1 parent 977ada1 commit 08fdf7af9b09f491b8f786d48c13899c11a7e5d1
Showing with 104 additions and 69 deletions.
  1. +11 −3 python/core/qgssnapper.sip
  2. +1 −0 python/gui/gui.sip
  3. +45 −0 python/gui/qgsmapcanvassnapper.sip
  4. +10 −28 src/core/qgssnapper.cpp
  5. +13 −10 src/core/qgssnapper.h
  6. +24 −28 src/gui/qgsmapcanvassnapper.cpp
@@ -57,6 +57,16 @@ public:
SnapWithResultsWithinTolerances
};

struct SnapLayer
{
/**The layer to which snapping is applied*/
QgsVectorLayer* mLayer;
/**The snapping tolerances for the layers, always in source coordinate systems of the layer*/
double mTolerance;
/**What snapping type to use (snap to segment or to vertex)*/
QgsSnapper::SnappingType mSnapTo;
};

QgsSnapper(QgsMapRenderer* mapRender);
~QgsSnapper();
/**Does the snapping operation
@@ -66,9 +76,7 @@ public:
int snapPoint(const QPoint& startPoint, QList<QgsSnappingResult>& snappingResult, const QList<QgsPoint>& excludeList);

//setters
void setLayersToSnap(const QList<QgsVectorLayer*>& layerList);
void setTolerances(const QList<double>& toleranceList);
// TODO wrap void setSnapToList(const QList<QgsSnapper::SnappingType>& snapToList);
void setSnapLayers( const QList<QgsSnapper::SnapLayer>& snapLayers );
void setSnapMode(QgsSnapper::SnappingMode snapMode);

};
@@ -14,6 +14,7 @@
%Include qgsmapcanvas.sip
%Include qgsmapcanvasitem.sip
%Include qgsmapcanvasmap.sip
%Include qgsmapcanvassnapper.sip
%Include qgsmaptool.sip
%Include qgsmaptoolemitpoint.sip
%Include qgsmaptoolpan.sip
@@ -0,0 +1,45 @@

/** \ingroup gui
* This class reads the snapping properties from the current project and
* configures a QgsSnapper to perform the snapping.
* Snapping can be done to the active layer (usefull for selecting a vertex to
* manipulate) or to background layers
*/
class QgsMapCanvasSnapper
{
%TypeHeaderCode
#include <qgsmapcanvassnapper.h>
%End
public:
/**Constructor
@param canvas the map canvas to snap to*/
QgsMapCanvasSnapper( QgsMapCanvas* canvas );

QgsMapCanvasSnapper();

~QgsMapCanvasSnapper();

/**Does a snap to the current layer. Uses snap mode
QgsSnapper::SnapWithResultsForSamePosition if topological editing is enabled
and QgsSnapper::SnapWithOneResult_BY_SEGMENT if not. As this method is usually used to
find vertices/segments for editing operations, it uses the search radius for vertex
editing from the qgis options.
@param p start point of the snap (in pixel coordinates)
@param results list to which the results are appended
@param snap_to snap to vertex or to segment
@param snappingTol snapping tolerance. -1 means that the search radius for vertex edits is taken
@param excludePoints a list with (map coordinate) points that should be excluded in the snapping result. Useful e.g. for vertex moves where a vertex should not be snapped to its original position*/
int snapToCurrentLayer( const QPoint& p, QList<QgsSnappingResult>& results, QgsSnapper::SnappingType snap_to, double snappingTol = -1, const QList<QgsPoint>& excludePoints = QList<QgsPoint>() );
/**Snaps to the background layers. This method is usefull to align the features of the
edited layers to those of other layers (as described in the project properties).
Uses snap mode QgsSnapper::SnapWithOneResult. Therefore, only the
closest result is returned.
@param p start point of the snap (in pixel coordinates)
@param result snapped point
@param excludePoints a list with (map coordinate) points that should be excluded in the snapping result. Useful e.g. for vertex moves where a vertex should not be snapped to its original position
@return 0 in case of success*/
int snapToBackgroundLayers( const QPoint& p, QList<QgsSnappingResult>& results, const QList<QgsPoint>& excludePoints = QList<QgsPoint>() );

void setMapCanvas( QgsMapCanvas* canvas );

};
@@ -43,16 +43,6 @@ int QgsSnapper::snapPoint( const QPoint& startPoint, QList<QgsSnappingResult>& s
{
snappingResult.clear();

//list must have the same length
if ( !( mLayersToSnap.size() == mSnappingTolerances.size() && mLayersToSnap.size() == mSnapToList.size() ) )
{
return 1;
}

QList<QgsVectorLayer*>::iterator layerIt = mLayersToSnap.begin();
QList<double>::const_iterator toleranceIt = mSnappingTolerances.constBegin();
QList<QgsSnapper::SnappingType>::const_iterator snapToIt = mSnapToList.constBegin();

QMultiMap<double, QgsSnappingResult> snappingResultList;//all snapping results
QMultiMap<double, QgsSnappingResult> currentResultList; //snapping results of examined layer

@@ -61,12 +51,13 @@ int QgsSnapper::snapPoint( const QPoint& startPoint, QList<QgsSnappingResult>& s
QgsPoint layerCoordPoint; //start point in layer coordinates
QgsSnappingResult newResult;


for ( ; layerIt != mLayersToSnap.end(); ++layerIt, ++toleranceIt, ++snapToIt )
QList<QgsSnapper::SnapLayer>::iterator snapLayerIt;
for (snapLayerIt = mSnapLayers.begin(); snapLayerIt != mSnapLayers.end(); ++snapLayerIt )
{
//transform point from map coordinates to layer coordinates
layerCoordPoint = mMapRenderer->mapToLayerCoordinates( *layerIt, mapCoordPoint );
if (( *layerIt )->snapWithContext( layerCoordPoint, *toleranceIt, currentResultList, *snapToIt ) != 0 )
layerCoordPoint = mMapRenderer->mapToLayerCoordinates( snapLayerIt->mLayer, mapCoordPoint );
if ( snapLayerIt->mLayer->snapWithContext( layerCoordPoint, snapLayerIt->mTolerance,
currentResultList, snapLayerIt->mSnapTo ) != 0 )
{
//error
}
@@ -78,9 +69,9 @@ int QgsSnapper::snapPoint( const QPoint& startPoint, QList<QgsSnappingResult>& s
//for each snapping result: transform start point, snap point and other points into map coordinates to find out distance
//store results in snapping result list
newResult = currentResultIt.value();
newResult.snappedVertex = mMapRenderer->layerToMapCoordinates( *layerIt, currentResultIt.value().snappedVertex );
newResult.beforeVertex = mMapRenderer->layerToMapCoordinates( *layerIt, currentResultIt.value().beforeVertex );
newResult.afterVertex = mMapRenderer->layerToMapCoordinates( *layerIt, currentResultIt.value().afterVertex );
newResult.snappedVertex = mMapRenderer->layerToMapCoordinates( snapLayerIt->mLayer, currentResultIt.value().snappedVertex );
newResult.beforeVertex = mMapRenderer->layerToMapCoordinates( snapLayerIt->mLayer, currentResultIt.value().beforeVertex );
newResult.afterVertex = mMapRenderer->layerToMapCoordinates( snapLayerIt->mLayer, currentResultIt.value().afterVertex );
snappingResultList.insert( sqrt( newResult.snappedVertex.sqrDist( mapCoordPoint ) ), newResult );
}
}
@@ -128,20 +119,11 @@ int QgsSnapper::snapPoint( const QPoint& startPoint, QList<QgsSnappingResult>& s
return 0;
}

void QgsSnapper::setLayersToSnap( const QList<QgsVectorLayer*>& layerList )
void QgsSnapper::setSnapLayers( const QList<QgsSnapper::SnapLayer>& snapLayers )
{
mLayersToSnap = layerList;
mSnapLayers = snapLayers;
}

void QgsSnapper::setTolerances( const QList<double>& toleranceList )
{
mSnappingTolerances = toleranceList;
}

void QgsSnapper::setSnapToList( const QList<QgsSnapper::SnappingType>& snapToList )
{
mSnapToList = snapToList;
}

void QgsSnapper::setSnapMode( QgsSnapper::SnappingMode snapMode )
{
@@ -78,6 +78,16 @@ class CORE_EXPORT QgsSnapper
SnapWithResultsWithinTolerances
};

struct SnapLayer
{
/**The layer to which snapping is applied*/
QgsVectorLayer* mLayer;
/**The snapping tolerances for the layers, always in source coordinate systems of the layer*/
double mTolerance;
/**What snapping type to use (snap to segment or to vertex)*/
QgsSnapper::SnappingType mSnapTo;
};

QgsSnapper( QgsMapRenderer* mapRender );
~QgsSnapper();
/**Does the snapping operation
@@ -88,9 +98,7 @@ class CORE_EXPORT QgsSnapper
int snapPoint( const QPoint& startPoint, QList<QgsSnappingResult>& snappingResult, const QList<QgsPoint>& excludePoints = QList<QgsPoint>() );

//setters
void setLayersToSnap( const QList<QgsVectorLayer*>& layerList );
void setTolerances( const QList<double>& toleranceList );
void setSnapToList( const QList<QgsSnapper::SnappingType>& snapToList );
void setSnapLayers( const QList<QgsSnapper::SnapLayer>& snapLayers );
void setSnapMode( QgsSnapper::SnappingMode snapMode );

private:
@@ -105,13 +113,8 @@ class CORE_EXPORT QgsSnapper
QgsMapRenderer* mMapRenderer;
/**Snap mode to apply*/
QgsSnapper::SnappingMode mSnapMode;
/**The layers to which snapping is applied*/
QList<QgsVectorLayer*> mLayersToSnap;
/**The snapping tolerances for the layers. The order must correspond to the layer list.
Note that the tolerances are always in source coordinate systems of the layers*/
QList<double> mSnappingTolerances;
/**List if snap to segment of to vertex. The order must correspond to the layer list*/
QList<QgsSnapper::SnappingType> mSnapToList;
/**List of layers to which snapping is applied*/
QList<QgsSnapper::SnapLayer> mSnapLayers;
};

#endif
@@ -89,29 +89,25 @@ int QgsMapCanvasSnapper::snapToCurrentLayer( const QPoint& p, QList<QgsSnappingR
return 3;
}

QList<QgsVectorLayer*> layerList;
QList<double> toleranceList;
QList<QgsSnapper::SnappingType> snapToList;

layerList.push_back( vlayer );
snapToList.push_back( snap_to );
QgsSnapper::SnapLayer snapLayer;
snapLayer.mLayer = vlayer;
snapLayer.mSnapTo = snap_to;

QSettings settings;

if ( snappingTol < 0 )
{
//use search tolerance for vertex editing
toleranceList.push_back( settings.value( "/qgis/digitizing/search_radius_vertex_edit", 50 ).toDouble() );
snapLayer.mTolerance = settings.value( "/qgis/digitizing/search_radius_vertex_edit", 50 ).toDouble();
}
else
{
toleranceList.push_back( snappingTol );
snapLayer.mTolerance = snappingTol;
}


mSnapper->setLayersToSnap( layerList );
mSnapper->setTolerances( toleranceList );
mSnapper->setSnapToList( snapToList );
QList<QgsSnapper::SnapLayer> snapLayers;
snapLayers.append( snapLayer );
mSnapper->setSnapLayers( snapLayers );

if ( mSnapper->snapPoint( p, results, excludePoints ) != 0 )
{
@@ -160,9 +156,8 @@ int QgsMapCanvasSnapper::snapToBackgroundLayers( const QPoint& p, QList<QgsSnapp
return 1; //lists must have the same size, otherwise something is wrong
}

QList<QgsVectorLayer*> vectorLayerList;
QList<double> toleranceDoubleList;
QList<QgsSnapper::SnappingType> snapTo;
QList<QgsSnapper::SnapLayer> snapLayers;
QgsSnapper::SnapLayer snapLayer;

//Use snapping information from the project
if ( snappingDefinedInProject )
@@ -190,27 +185,28 @@ int QgsMapCanvasSnapper::snapToBackgroundLayers( const QPoint& p, QList<QgsSnapp
vlayer = dynamic_cast<QgsVectorLayer*>( layer );
if ( vlayer )
{
vectorLayerList.push_back( vlayer );
snapLayer.mLayer = vlayer;
}
}

//tolerance
toleranceDoubleList.push_back( tolIt->toDouble() );
snapLayer.mTolerance = tolIt->toDouble();

//segment or vertex
if (( *snapIt ) == "to_vertex" )
{
snapTo.push_back( QgsSnapper::SnapToVertex );
snapLayer.mSnapTo = QgsSnapper::SnapToVertex;
}
else if (( *snapIt ) == "to_segment" )
{
snapTo.push_back( QgsSnapper::SnapToSegment );
snapLayer.mSnapTo = QgsSnapper::SnapToSegment;
}
else //to vertex and segment
{
snapTo.push_back( QgsSnapper::SnapToVertexAndSegment );
snapLayer.mSnapTo = QgsSnapper::SnapToVertexAndSegment;
}

snapLayers.append(snapLayer);
}
}
else //nothing in project. Use default snapping tolerance to vertex of current layer
@@ -227,31 +223,31 @@ int QgsMapCanvasSnapper::snapToBackgroundLayers( const QPoint& p, QList<QgsSnapp
return 3;
}

vectorLayerList.push_back( currentVectorLayer );
snapLayer.mLayer = currentVectorLayer;
QSettings settings;

//default snap mode
QString defaultSnapString = settings.value( "/qgis/digitizing/default_snap_mode", "to vertex" ).toString();
if ( defaultSnapString == "to segment" )
{
snapTo.push_back( QgsSnapper::SnapToSegment );
snapLayer.mSnapTo = QgsSnapper::SnapToSegment;
}
else if ( defaultSnapString == "to vertex and segment" )
{
snapTo.push_back( QgsSnapper::SnapToVertexAndSegment );
snapLayer.mSnapTo = QgsSnapper::SnapToVertexAndSegment;
}
else
{
snapTo.push_back( QgsSnapper::SnapToVertex );
snapLayer.mSnapTo = QgsSnapper::SnapToVertex;
}

//default snapping tolerance
toleranceDoubleList.push_back( settings.value( "/qgis/digitizing/default_snapping_tolerance", 0 ).toDouble() );
snapLayer.mTolerance = settings.value( "/qgis/digitizing/default_snapping_tolerance", 0 ).toDouble();

snapLayers.append(snapLayer);
}

mSnapper->setLayersToSnap( vectorLayerList );
mSnapper->setTolerances( toleranceDoubleList );
mSnapper->setSnapToList( snapTo );
mSnapper->setSnapLayers( snapLayers );

if ( mSnapper->snapPoint( p, results, excludePoints ) != 0 )
{

0 comments on commit 08fdf7a

Please sign in to comment.