Skip to content

Commit

Permalink
Merge pull request #7844 from m-kuhn/conversionFactor
Browse files Browse the repository at this point in the history
QgsCoordinateTransform::scaleFactor()
  • Loading branch information
m-kuhn committed Sep 11, 2018
2 parents d65bd5f + cf82c13 commit fae9256
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 8 deletions.
11 changes: 11 additions & 0 deletions python/core/auto_generated/qgscoordinatetransform.sip.in
Expand Up @@ -356,6 +356,17 @@ This should be called whenever the srs database has
been modified in order to ensure that outdated CRS transforms are not created.

.. versionadded:: 3.0
%End

double scaleFactor( const QgsRectangle &referenceExtent ) const;
%Docstring
Computes an *estimated* conversion factor between source and destination units:

sourceUnits * scaleFactor = destinationUnits

:param referenceExtent: A reference extent based on which to perform the computation

.. versionadded:: 3.4
%End

};
Expand Down
11 changes: 11 additions & 0 deletions src/core/qgscoordinatetransform.cpp
Expand Up @@ -798,3 +798,14 @@ void QgsCoordinateTransform::invalidateCache()
sTransforms.clear();
sCacheLock.unlock();
}

double QgsCoordinateTransform::scaleFactor( const QgsRectangle &ReferenceExtent ) const
{
QgsPointXY source1( ReferenceExtent.xMinimum(), ReferenceExtent.yMinimum() );
QgsPointXY source2( ReferenceExtent.xMaximum(), ReferenceExtent.yMaximum() );
double distSourceUnits = std::sqrt( source1.sqrDist( source2 ) );
QgsPointXY dest1 = transform( source1 );
QgsPointXY dest2 = transform( source2 );
double distDestUnits = std::sqrt( dest1.sqrDist( dest2 ) );
return distDestUnits / distSourceUnits;
}
11 changes: 11 additions & 0 deletions src/core/qgscoordinatetransform.h
Expand Up @@ -405,6 +405,17 @@ class CORE_EXPORT QgsCoordinateTransform
*/
static void invalidateCache();

/**
* Computes an *estimated* conversion factor between source and destination units:
*
* sourceUnits * scaleFactor = destinationUnits
*
* \param referenceExtent A reference extent based on which to perform the computation
*
* \since QGIS 3.4
*/
double scaleFactor( const QgsRectangle &referenceExtent ) const;

private:

mutable QExplicitlySharedDataPointer<QgsCoordinateTransformPrivate> d;
Expand Down
9 changes: 1 addition & 8 deletions src/core/qgsmapsettings.cpp
Expand Up @@ -396,14 +396,7 @@ QgsCoordinateTransform QgsMapSettings::layerTransform( const QgsMapLayer *layer

double QgsMapSettings::layerToMapUnits( const QgsMapLayer *layer, const QgsRectangle &referenceExtent ) const
{
QgsRectangle extent = referenceExtent.isEmpty() ? layer->extent() : referenceExtent;
QgsPointXY l1( extent.xMinimum(), extent.yMinimum() );
QgsPointXY l2( extent.xMaximum(), extent.yMaximum() );
double distLayerUnits = std::sqrt( l1.sqrDist( l2 ) );
QgsPointXY m1 = layerToMapCoordinates( layer, l1 );
QgsPointXY m2 = layerToMapCoordinates( layer, l2 );
double distMapUnits = std::sqrt( m1.sqrDist( m2 ) );
return distMapUnits / distLayerUnits;
return layerTransform( layer ).scaleFactor( referenceExtent );
}


Expand Down
38 changes: 38 additions & 0 deletions tests/src/core/testqgscoordinatetransform.cpp
Expand Up @@ -36,6 +36,8 @@ class TestQgsCoordinateTransform: public QObject
void isValid();
void isShortCircuited();
void contextShared();
void scaleFactor();
void scaleFactor_data();

private:

Expand Down Expand Up @@ -213,6 +215,42 @@ void TestQgsCoordinateTransform::contextShared()
QCOMPARE( copy2.sourceDestinationDatumTransforms(), expected );
}

void TestQgsCoordinateTransform::scaleFactor()
{
QFETCH( QgsCoordinateReferenceSystem, sourceCrs );
QFETCH( QgsCoordinateReferenceSystem, destCrs );
QFETCH( QgsRectangle, rect );
QFETCH( double, factor );

QgsCoordinateTransform ct( sourceCrs, destCrs, QgsProject::instance() );

// qDebug() << QString::number(ct.scaleFactor( rect ), 'g', 17) ;
QVERIFY( qgsDoubleNear( ct.scaleFactor( rect ), factor ) );
}

void TestQgsCoordinateTransform::scaleFactor_data()
{
QTest::addColumn<QgsCoordinateReferenceSystem>( "sourceCrs" );
QTest::addColumn<QgsCoordinateReferenceSystem>( "destCrs" );
QTest::addColumn<QgsRectangle>( "rect" );
QTest::addColumn<double>( "factor" );

QTest::newRow( "Different map units" )
<< QgsCoordinateReferenceSystem::fromEpsgId( 2056 )
<< QgsCoordinateReferenceSystem::fromEpsgId( 4326 )
<< QgsRectangle( 2550000, 1200000, 2550100, 1200100 )
<< 1.1223316038381985e-5;
QTest::newRow( "Same map units" )
<< QgsCoordinateReferenceSystem::fromEpsgId( 2056 )
<< QgsCoordinateReferenceSystem::fromEpsgId( 21781 )
<< QgsRectangle( 2550000, 1200000, 2550100, 1200100 )
<< 1.0000000000248837;
QTest::newRow( "Same CRS" )
<< QgsCoordinateReferenceSystem::fromEpsgId( 2056 )
<< QgsCoordinateReferenceSystem::fromEpsgId( 2056 )
<< QgsRectangle( 2550000, 1200000, 2550100, 1200100 )
<< 1.0;
}

void TestQgsCoordinateTransform::transformBoundingBox()
{
Expand Down

0 comments on commit fae9256

Please sign in to comment.