Skip to content
Permalink
Browse files

Merge pull request #7844 from m-kuhn/conversionFactor

QgsCoordinateTransform::scaleFactor()
  • Loading branch information
m-kuhn committed Sep 11, 2018
2 parents d65bd5f + cf82c13 commit fae9256a41318c665a052232932f7ec175ca6bc6
@@ -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

};
@@ -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;
}
@@ -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;
@@ -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 );
}


@@ -36,6 +36,8 @@ class TestQgsCoordinateTransform: public QObject
void isValid();
void isShortCircuited();
void contextShared();
void scaleFactor();
void scaleFactor_data();

private:

@@ -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()
{

0 comments on commit fae9256

Please sign in to comment.
You can’t perform that action at this time.