Skip to content

Commit bae6d56

Browse files
committedJul 17, 2017
consider datum transformation when pasting features (fixes #16846)
1 parent bcc8e90 commit bae6d56

File tree

7 files changed

+42
-8
lines changed

7 files changed

+42
-8
lines changed
 

‎doc/api_break.dox

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,7 @@ QgsDatumTransformStore {#qgis_api_break_3_0_QgsDatumTransformStore}
960960

961961
- transformation() now returns a QgsCoordinateTransform object, not a pointer. An invalid QgsCoordinateTransform will
962962
be returned in place of a null pointer.
963+
- transformation() also optional source and destination authid parameters
963964

964965

965966
QgsDiagram {#qgis_api_break_3_0_QgsDiagram}

‎python/core/qgsdatumtransformstore.sip

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,13 @@ class QgsDatumTransformStore
3636
:rtype: bool
3737
%End
3838

39-
QgsCoordinateTransform transformation( const QgsMapLayer *layer ) const;
39+
QgsCoordinateTransform transformation( const QgsMapLayer *layer, QString srcAuthId = QString(), QString dstAuthId = QString() ) const;
4040
%Docstring
4141
Will return transform from layer's CRS to current destination CRS.
42-
Will emit datumTransformInfoRequested signal if the layer has no entry.
4342
:return: transformation associated with layer, or an invalid QgsCoordinateTransform
4443
if no transform is associated with the layer
44+
\param srcAuthId source CRS (defaults to layer crs)
45+
\param dstAuthId destination CRS (defaults to store's crs)
4546
:rtype: QgsCoordinateTransform
4647
%End
4748

‎python/gui/qgsmapcanvas.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,7 @@ called when panning is in action, reset indicates end of panning
853853

854854

855855

856+
856857
void updateDatumTransformEntries();
857858
%Docstring
858859
Make sure the datum transform store is properly populated

‎src/app/qgsclipboard.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#include "qgsogrutils.h"
3737
#include "qgsjsonutils.h"
3838
#include "qgssettings.h"
39+
#include "qgisapp.h"
40+
#include "qgsmapcanvas.h"
3941

4042
QgsClipboard::QgsClipboard()
4143
: QObject()
@@ -59,6 +61,9 @@ void QgsClipboard::replaceWithCopyOf( QgsVectorLayer *src )
5961
mFeatureFields = src->fields();
6062
mFeatureClipboard = src->selectedFeatures();
6163
mCRS = src->crs();
64+
layerDestroyed();
65+
mSrcLayer = src;
66+
connect( mSrcLayer, &QObject::destroyed, this, &QgsClipboard::layerDestroyed );
6267

6368
QgsDebugMsg( "replaced QGis clipboard." );
6469

@@ -73,11 +78,19 @@ void QgsClipboard::replaceWithCopyOf( QgsFeatureStore &featureStore )
7378
mFeatureFields = featureStore.fields();
7479
mFeatureClipboard = featureStore.features();
7580
mCRS = featureStore.crs();
81+
disconnect( mSrcLayer, &QObject::destroyed, this, &QgsClipboard::layerDestroyed );
82+
mSrcLayer = nullptr;
7683
setSystemClipboard();
7784
mUseSystemClipboard = false;
7885
emit changed();
7986
}
8087

88+
void QgsClipboard::layerDestroyed()
Code has comments. Press enter to view.
89+
{
90+
disconnect( mSrcLayer, &QObject::destroyed, this, &QgsClipboard::layerDestroyed );
91+
mSrcLayer = nullptr;
92+
}
93+
8194
QString QgsClipboard::generateClipboardText() const
8295
{
8396
QgsSettings settings;
@@ -264,7 +277,17 @@ bool QgsClipboard::isEmpty() const
264277
QgsFeatureList QgsClipboard::transformedCopyOf( const QgsCoordinateReferenceSystem &destCRS, const QgsFields &fields ) const
265278
{
266279
QgsFeatureList featureList = copyOf( fields );
267-
QgsCoordinateTransform ct( crs(), destCRS );
280+
281+
QgsCoordinateTransform ct;
282+
if ( mSrcLayer )
283+
{
284+
QgisApp::instance()->mapCanvas()->getDatumTransformInfo( mSrcLayer, crs().authid(), destCRS.authid() );
285+
ct = QgisApp::instance()->mapCanvas()->mapSettings().datumTransformStore().transformation( mSrcLayer, crs().authid(), destCRS.authid() );
286+
}
287+
else
288+
{
289+
ct = QgsCoordinateTransform( crs(), destCRS );
290+
}
268291

269292
QgsDebugMsg( "transforming clipboard." );
270293
for ( QgsFeatureList::iterator iter = featureList.begin(); iter != featureList.end(); ++iter )

‎src/app/qgsclipboard.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ class APP_EXPORT QgsClipboard : public QObject
148148
//! Emitted when content changed
149149
void changed();
150150

151+
private slots:
152+
//! source layer destroyed
153+
void layerDestroyed();
154+
151155
private:
152156

153157
/**
@@ -180,6 +184,7 @@ class APP_EXPORT QgsClipboard : public QObject
180184
QgsFeatureList mFeatureClipboard;
181185
QgsFields mFeatureFields;
182186
QgsCoordinateReferenceSystem mCRS;
187+
QgsVectorLayer *mSrcLayer = nullptr;
183188

184189
//! True when the data from the system clipboard should be read
185190
bool mUseSystemClipboard;

‎src/core/qgsdatumtransformstore.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,15 @@ bool QgsDatumTransformStore::hasEntryForLayer( QgsMapLayer *layer ) const
5050
return mEntries.contains( layer->id() );
5151
}
5252

53-
QgsCoordinateTransform QgsDatumTransformStore::transformation( const QgsMapLayer *layer ) const
53+
QgsCoordinateTransform QgsDatumTransformStore::transformation( const QgsMapLayer *layer, QString srcAuthId, QString dstAuthId ) const
5454
{
5555
if ( !layer )
5656
return QgsCoordinateTransform();
5757

58-
QString srcAuthId = layer->crs().authid();
59-
QString dstAuthId = mDestCRS.authid();
58+
if ( srcAuthId.isEmpty() )
59+
srcAuthId = layer->crs().authid();
60+
if ( dstAuthId.isEmpty() )
61+
dstAuthId = mDestCRS.authid();
6062

6163
if ( srcAuthId == dstAuthId )
6264
{

‎src/core/qgsdatumtransformstore.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,12 @@ class CORE_EXPORT QgsDatumTransformStore
4545

4646
/**
4747
* Will return transform from layer's CRS to current destination CRS.
48-
* Will emit datumTransformInfoRequested signal if the layer has no entry.
4948
* \returns transformation associated with layer, or an invalid QgsCoordinateTransform
5049
* if no transform is associated with the layer
50+
* \param srcAuthId source CRS (defaults to layer crs)
51+
* \param dstAuthId destination CRS (defaults to store's crs)
5152
*/
52-
QgsCoordinateTransform transformation( const QgsMapLayer *layer ) const;
53+
QgsCoordinateTransform transformation( const QgsMapLayer *layer, QString srcAuthId = QString(), QString dstAuthId = QString() ) const;
5354

5455
void readXml( const QDomNode &parentNode );
5556

7 commit comments

Comments
 (7)

3nids commented on Jul 18, 2017

@3nids
Member

@jef-n any chance to backport this to 2.18 ?

3nids commented on Jul 18, 2017

@3nids
Member

this issue is even a bit broader....
taking the example of the issue (canvas in epsg 2056, layer in 21781 with custom datum transform)
if you use the select map tool and try to select features on the 21781 layer, the map tool does not respect the transformation either....

3nids commented on Jul 18, 2017

@3nids
Member

3nids commented on Jul 19, 2017

@3nids
Member

snapping is also affected....

nyalldawson commented on Jul 19, 2017

@nyalldawson
Collaborator

@3nids actually the issue is everywhere. IMO datum transforms need a total rethink and rewrite - the current approach just isn't working.

3nids commented on Jul 20, 2017

@3nids
Member

@nyalldawson do you have something in mind already? I think this is a major concern in Switzerland for the upcoming months/years, and I guess it'll be easier to fix this before 3.0.

andreasneumann commented on Jul 20, 2017

@andreasneumann
Member

I agree. Datum transformations are currently quite important in Switzerland. Some cantons already migrated everything, others are in transition or will do the migration soon.

Please sign in to comment.