mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Respect transform context in point locator
This commit is contained in:
parent
8f15cdf680
commit
b904731259
@ -2002,7 +2002,8 @@ QgsPointLocator {#qgis_api_break_3_0_QgsPointLocator}
|
||||
---------------
|
||||
|
||||
- The constructor now takes a reference rather than a pointer to a CRS. This has no effect on PyQGIS code, but c++
|
||||
plugins calling this method will need to be updated.
|
||||
plugins calling this method will need to be updated. The constructor now requires a QgsCoordinateTransformContext argument
|
||||
when a destination crs is specified.
|
||||
- The destCRS parameter in the constructor has been renamed to destinationCrs.
|
||||
- destCRS() has been renamed to destinationCrs()
|
||||
- destinationCrs() now returns a copy instead of a reference to the CRS. This has no effect on PyQGIS code, but c++
|
||||
|
@ -30,12 +30,15 @@ Works with one layer.
|
||||
public:
|
||||
|
||||
explicit QgsPointLocator( QgsVectorLayer *layer, const QgsCoordinateReferenceSystem &destinationCrs = QgsCoordinateReferenceSystem(),
|
||||
const QgsCoordinateTransformContext &transformContext = QgsCoordinateTransformContext(),
|
||||
const QgsRectangle *extent = 0 );
|
||||
%Docstring
|
||||
Construct point locator for a ``layer``.
|
||||
|
||||
If a valid QgsCoordinateReferenceSystem is passed for ``destinationCrs`` then the locator will
|
||||
do the searches on data reprojected to the given CRS.
|
||||
do the searches on data reprojected to the given CRS. For accurate reprojection it is important
|
||||
to set the correct ``transformContext`` if a ``destinationCrs`` is specified. This is usually taken
|
||||
from the current :py:func:`QgsProject.transformContext()`
|
||||
|
||||
If ``extent`` is not null, the locator will index only a subset of the layer which falls within that extent.
|
||||
%End
|
||||
|
@ -181,6 +181,11 @@ Called when starting to index - can be overridden and e.g. progress dialog can b
|
||||
virtual void prepareIndexProgress( int index );
|
||||
%Docstring
|
||||
Called when finished indexing a layer. When index == count the indexing is complete
|
||||
%End
|
||||
|
||||
void clearAllLocators();
|
||||
%Docstring
|
||||
Deletes all existing locators (e.g. when destination CRS has changed and we need to reindex)
|
||||
%End
|
||||
|
||||
};
|
||||
|
@ -620,15 +620,13 @@ class QgsPointLocator_DumpTree : public SpatialIndex::IQueryStrategy
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
QgsPointLocator::QgsPointLocator( QgsVectorLayer *layer, const QgsCoordinateReferenceSystem &destCRS, const QgsRectangle *extent )
|
||||
QgsPointLocator::QgsPointLocator( QgsVectorLayer *layer, const QgsCoordinateReferenceSystem &destCRS, const QgsCoordinateTransformContext &transformContext, const QgsRectangle *extent )
|
||||
: mIsEmptyLayer( false )
|
||||
, mLayer( layer )
|
||||
{
|
||||
if ( destCRS.isValid() )
|
||||
{
|
||||
Q_NOWARN_DEPRECATED_PUSH
|
||||
mTransform = QgsCoordinateTransform( layer->crs(), destCRS );
|
||||
Q_NOWARN_DEPRECATED_POP
|
||||
mTransform = QgsCoordinateTransform( layer->crs(), destCRS, transformContext );
|
||||
}
|
||||
|
||||
setExtent( extent );
|
||||
|
@ -55,12 +55,15 @@ class CORE_EXPORT QgsPointLocator : public QObject
|
||||
/**
|
||||
* Construct point locator for a \a layer.
|
||||
*
|
||||
* If a valid QgsCoordinateReferenceSystem is passed for \a destinationCrs then the locator will
|
||||
* do the searches on data reprojected to the given CRS.
|
||||
* If a valid QgsCoordinateReferenceSystem is passed for \a destinationCrs then the locator will
|
||||
* do the searches on data reprojected to the given CRS. For accurate reprojection it is important
|
||||
* to set the correct \a transformContext if a \a destinationCrs is specified. This is usually taken
|
||||
* from the current QgsProject::transformContext().
|
||||
*
|
||||
* If \a extent is not null, the locator will index only a subset of the layer which falls within that extent.
|
||||
* If \a extent is not null, the locator will index only a subset of the layer which falls within that extent.
|
||||
*/
|
||||
explicit QgsPointLocator( QgsVectorLayer *layer, const QgsCoordinateReferenceSystem &destinationCrs = QgsCoordinateReferenceSystem(),
|
||||
const QgsCoordinateTransformContext &transformContext = QgsCoordinateTransformContext(),
|
||||
const QgsRectangle *extent = nullptr );
|
||||
|
||||
~QgsPointLocator() override;
|
||||
|
@ -39,7 +39,7 @@ QgsPointLocator *QgsSnappingUtils::locatorForLayer( QgsVectorLayer *vl )
|
||||
|
||||
if ( !mLocators.contains( vl ) )
|
||||
{
|
||||
QgsPointLocator *vlpl = new QgsPointLocator( vl, destinationCrs() );
|
||||
QgsPointLocator *vlpl = new QgsPointLocator( vl, destinationCrs(), mMapSettings.transformContext() );
|
||||
mLocators.insert( vl, vlpl );
|
||||
}
|
||||
return mLocators.value( vl );
|
||||
@ -72,7 +72,7 @@ QgsPointLocator *QgsSnappingUtils::temporaryLocatorForLayer( QgsVectorLayer *vl,
|
||||
|
||||
QgsRectangle rect( pointMap.x() - tolerance, pointMap.y() - tolerance,
|
||||
pointMap.x() + tolerance, pointMap.y() + tolerance );
|
||||
QgsPointLocator *vlpl = new QgsPointLocator( vl, destinationCrs(), &rect );
|
||||
QgsPointLocator *vlpl = new QgsPointLocator( vl, destinationCrs(), mMapSettings.transformContext(), &rect );
|
||||
mTemporaryLocators.insert( vl, vlpl );
|
||||
return mTemporaryLocators.value( vl );
|
||||
}
|
||||
|
@ -184,14 +184,14 @@ class CORE_EXPORT QgsSnappingUtils : public QObject
|
||||
//! Called when finished indexing a layer. When index == count the indexing is complete
|
||||
virtual void prepareIndexProgress( int index ) { Q_UNUSED( index ); }
|
||||
|
||||
//! Deletes all existing locators (e.g. when destination CRS has changed and we need to reindex)
|
||||
void clearAllLocators();
|
||||
|
||||
private:
|
||||
void onIndividualLayerSettingsChanged( const QHash<QgsVectorLayer *, QgsSnappingConfig::IndividualLayerSettings> &layerSettings );
|
||||
//! Get destination CRS from map settings, or an invalid CRS if projections are disabled
|
||||
QgsCoordinateReferenceSystem destinationCrs() const;
|
||||
|
||||
//! delete all existing locators (e.g. when destination CRS has changed and we need to reindex)
|
||||
void clearAllLocators();
|
||||
|
||||
//! return a locator (temporary or not) according to the indexing strategy
|
||||
QgsPointLocator *locatorForLayerUsingStrategy( QgsVectorLayer *vl, const QgsPointXY &pointMap, double tolerance );
|
||||
//! return a temporary locator with index only for a small area (will be replaced by another one on next request)
|
||||
|
@ -29,6 +29,7 @@ QgsMapCanvasSnappingUtils::QgsMapCanvasSnappingUtils( QgsMapCanvas *canvas, QObj
|
||||
connect( canvas, &QgsMapCanvas::destinationCrsChanged, this, &QgsMapCanvasSnappingUtils::canvasMapSettingsChanged );
|
||||
connect( canvas, &QgsMapCanvas::layersChanged, this, &QgsMapCanvasSnappingUtils::canvasMapSettingsChanged );
|
||||
connect( canvas, &QgsMapCanvas::currentLayerChanged, this, &QgsMapCanvasSnappingUtils::canvasCurrentLayerChanged );
|
||||
connect( canvas, &QgsMapCanvas::transformContextChanged, this, &QgsMapCanvasSnappingUtils::canvasTransformContextChanged );
|
||||
canvasMapSettingsChanged();
|
||||
canvasCurrentLayerChanged();
|
||||
}
|
||||
@ -38,6 +39,13 @@ void QgsMapCanvasSnappingUtils::canvasMapSettingsChanged()
|
||||
setMapSettings( mCanvas->mapSettings() );
|
||||
}
|
||||
|
||||
void QgsMapCanvasSnappingUtils::canvasTransformContextChanged()
|
||||
{
|
||||
// can't trust any of our previous locators, as we don't know exactly how datum transform changes would affect these
|
||||
clearAllLocators();
|
||||
setMapSettings( mCanvas->mapSettings() );
|
||||
}
|
||||
|
||||
void QgsMapCanvasSnappingUtils::canvasCurrentLayerChanged()
|
||||
{
|
||||
setCurrentLayer( qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ) );
|
||||
|
@ -40,6 +40,7 @@ class GUI_EXPORT QgsMapCanvasSnappingUtils : public QgsSnappingUtils
|
||||
|
||||
private slots:
|
||||
void canvasMapSettingsChanged();
|
||||
void canvasTransformContextChanged();
|
||||
void canvasCurrentLayerChanged();
|
||||
|
||||
private:
|
||||
|
@ -248,13 +248,13 @@ class TestQgsPointLocator : public QObject
|
||||
void testExtent()
|
||||
{
|
||||
QgsRectangle bbox1( 10, 10, 11, 11 ); // out of layer's bounds
|
||||
QgsPointLocator loc1( mVL, QgsCoordinateReferenceSystem(), &bbox1 );
|
||||
QgsPointLocator loc1( mVL, QgsCoordinateReferenceSystem(), QgsCoordinateTransformContext(), &bbox1 );
|
||||
|
||||
QgsPointLocator::Match m1 = loc1.nearestVertex( QgsPointXY( 2, 2 ), 999 );
|
||||
QVERIFY( !m1.isValid() );
|
||||
|
||||
QgsRectangle bbox2( 0, 0, 1, 1 ); // in layer's bounds
|
||||
QgsPointLocator loc2( mVL, QgsCoordinateReferenceSystem(), &bbox2 );
|
||||
QgsPointLocator loc2( mVL, QgsCoordinateReferenceSystem(), QgsCoordinateTransformContext(), &bbox2 );
|
||||
|
||||
QgsPointLocator::Match m2 = loc2.nearestVertex( QgsPointXY( 2, 2 ), 999 );
|
||||
QVERIFY( m2.isValid() );
|
||||
@ -270,7 +270,7 @@ class TestQgsPointLocator : public QObject
|
||||
flist << ff;
|
||||
vlNullGeom->dataProvider()->addFeatures( flist );
|
||||
|
||||
QgsPointLocator loc( vlNullGeom, QgsCoordinateReferenceSystem(), nullptr );
|
||||
QgsPointLocator loc( vlNullGeom, QgsCoordinateReferenceSystem(), QgsCoordinateTransformContext(), nullptr );
|
||||
|
||||
QgsPointLocator::Match m1 = loc.nearestVertex( QgsPointXY( 2, 2 ), std::numeric_limits<double>::max() );
|
||||
QVERIFY( !m1.isValid() );
|
||||
@ -292,7 +292,7 @@ class TestQgsPointLocator : public QObject
|
||||
flist << ff;
|
||||
vlEmptyGeom->dataProvider()->addFeatures( flist );
|
||||
|
||||
QgsPointLocator loc( vlEmptyGeom, QgsCoordinateReferenceSystem(), nullptr );
|
||||
QgsPointLocator loc( vlEmptyGeom, QgsCoordinateReferenceSystem(), QgsCoordinateTransformContext(), nullptr );
|
||||
|
||||
QgsPointLocator::Match m1 = loc.nearestVertex( QgsPointXY( 2, 2 ), std::numeric_limits<double>::max() );
|
||||
QVERIFY( !m1.isValid() );
|
||||
|
Loading…
x
Reference in New Issue
Block a user