mirror of
https://github.com/qgis/QGIS.git
synced 2025-11-22 00:14:55 -05:00
Add QgsMapSettings::computeExtentForScale and QgsMapSettings::computeScaleForExtent
This commit is contained in:
parent
19eaec7436
commit
73c61b6e25
@ -664,6 +664,39 @@ transform rectangle from output CRS to layer's CRS
|
||||
Returns the coordinate transform from layer's CRS to destination CRS
|
||||
|
||||
:return: transform - may be invalid if the transform is not needed
|
||||
%End
|
||||
|
||||
QgsRectangle computeExtentForScale( const QgsPointXY ¢er, double scale ) const;
|
||||
%Docstring
|
||||
Compute the extent such that its ``center`` is at the specified
|
||||
position (mapped to the destinatonCrs) and the zoom factor corresponds
|
||||
to the specified ``scale``
|
||||
|
||||
:param center: the center, in map coordinates
|
||||
:param scale: the desired zoom factor (the x part of 1:x)
|
||||
|
||||
:return: an extent which can be passed to :py:class:`QgsMapCanvas`.setExtent
|
||||
|
||||
.. seealso:: :py:func:`computeScaleForExtent`
|
||||
|
||||
.. versionadded:: 3.22
|
||||
%End
|
||||
|
||||
double computeScaleForExtent( const QgsRectangle &extent ) const;
|
||||
%Docstring
|
||||
Compute the scale that corresponds to the specified ``extent``
|
||||
|
||||
:param extent: the extent, as passed to :py:func:`QgsMapCanvas.setExtent`
|
||||
|
||||
:return: the scale denominator
|
||||
|
||||
.. seealso:: :py:func:`computeExtentForScale`
|
||||
|
||||
.. note::
|
||||
|
||||
This function does not consider any map rotation
|
||||
|
||||
.. versionadded:: 3.22
|
||||
%End
|
||||
|
||||
QgsRectangle fullExtent() const;
|
||||
|
||||
@ -436,6 +436,39 @@ QgsCoordinateTransform QgsMapSettings::layerTransform( const QgsMapLayer *layer
|
||||
return QgsCoordinateTransform( layer->crs(), mDestCRS, mTransformContext );
|
||||
}
|
||||
|
||||
QgsRectangle QgsMapSettings::computeExtentForScale( const QgsPointXY ¢er, double scale ) const
|
||||
{
|
||||
// Output width in inches
|
||||
const double outputWidthInInches = outputSize().width() / outputDpi();
|
||||
|
||||
// Desired visible width (honouring scale)
|
||||
double scaledWidthInInches = outputWidthInInches * scale;
|
||||
|
||||
if ( mapUnits() == QgsUnitTypes::DistanceDegrees )
|
||||
{
|
||||
// Start with some fraction of the current extent around the center
|
||||
double delta = mExtent.width() / 100.;
|
||||
QgsRectangle ext( center.x() - delta, center.y() - delta, center.x() + delta, center.y() + delta );
|
||||
// Get scale at extent, and then scale extent to the desired scale
|
||||
double testScale = mScaleCalculator.calculate( ext, outputSize().width() );
|
||||
ext.scale( scale / testScale );
|
||||
return ext;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Conversion from inches to mapUnits - this is safe to use, because we know here that the map units AREN'T in degrees
|
||||
double conversionFactor = QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceFeet, mapUnits() ) / 12;
|
||||
|
||||
double delta = 0.5 * scaledWidthInInches * conversionFactor;
|
||||
return QgsRectangle( center.x() - delta, center.y() - delta, center.x() + delta, center.y() + delta );
|
||||
}
|
||||
}
|
||||
|
||||
double QgsMapSettings::computeScaleForExtent( const QgsRectangle &extent ) const
|
||||
{
|
||||
return mScaleCalculator.calculate( extent, outputSize().width() );
|
||||
}
|
||||
|
||||
double QgsMapSettings::layerToMapUnits( const QgsMapLayer *layer, const QgsRectangle &referenceExtent ) const
|
||||
{
|
||||
return layerTransform( layer ).scaleFactor( referenceExtent );
|
||||
|
||||
@ -600,6 +600,28 @@ class CORE_EXPORT QgsMapSettings : public QgsTemporalRangeObject
|
||||
*/
|
||||
QgsCoordinateTransform layerTransform( const QgsMapLayer *layer ) const;
|
||||
|
||||
/**
|
||||
* \brief Compute the extent such that its \a center is at the specified
|
||||
* position (mapped to the destinatonCrs) and the zoom factor corresponds
|
||||
* to the specified \a scale
|
||||
* \param center the center, in map coordinates
|
||||
* \param scale the desired zoom factor (the x part of 1:x)
|
||||
* \returns an extent which can be passed to QgsMapCanvas::setExtent
|
||||
* \see computeScaleForExtent()
|
||||
* \since QGIS 3.22
|
||||
*/
|
||||
QgsRectangle computeExtentForScale( const QgsPointXY ¢er, double scale ) const;
|
||||
|
||||
/**
|
||||
* \brief Compute the scale that corresponds to the specified \a extent
|
||||
* \param extent the extent, as passed to \see QgsMapCanvas::setExtent
|
||||
* \returns the scale denominator
|
||||
* \see computeExtentForScale()
|
||||
* \note This function does not consider any map rotation
|
||||
* \since QGIS 3.22
|
||||
*/
|
||||
double computeScaleForExtent( const QgsRectangle &extent ) const;
|
||||
|
||||
//! returns current extent of layer set
|
||||
QgsRectangle fullExtent() const;
|
||||
|
||||
|
||||
@ -62,6 +62,8 @@ class TestQgsMapSettings: public QObject
|
||||
void testRenderedFeatureHandlers();
|
||||
void testCustomRenderingFlags();
|
||||
void testClippingRegions();
|
||||
void testComputeExtentForScale();
|
||||
void testComputeScaleForExtent();
|
||||
|
||||
private:
|
||||
QString toString( const QPolygonF &p, int decimalPlaces = 2 ) const;
|
||||
@ -624,5 +626,37 @@ void TestQgsMapSettings::testClippingRegions()
|
||||
QCOMPARE( settings.clippingRegions().at( 0 ).geometry().asWkt(), QStringLiteral( "Polygon ((10 0, 11 0, 11 1, 10 1, 10 0))" ) ) ;
|
||||
}
|
||||
|
||||
void TestQgsMapSettings::testComputeExtentForScale()
|
||||
{
|
||||
QgsMapSettings settings;
|
||||
settings.setExtent( QgsRectangle( -500., -500., 500., 500. ) ); // Just to ensure settings are valid
|
||||
settings.setDestinationCrs( QgsCoordinateReferenceSystem( "EPSG:3857" ) );
|
||||
|
||||
settings.setOutputSize( QSize( 1000, 1000 ) );
|
||||
|
||||
QgsRectangle rect = settings.computeExtentForScale( QgsPoint( 0, 0 ), 500 );
|
||||
|
||||
// [ output width in inches ] * [scale]
|
||||
double widthInches = settings.outputSize().width() / double( settings.outputDpi() ) * 500;
|
||||
double widthMapUnits = widthInches * QgsUnitTypes::fromUnitToUnitFactor( QgsUnitTypes::DistanceFeet, settings.mapUnits() ) / 12;
|
||||
QGSCOMPARENEARRECTANGLE( rect, QgsRectangle( - 0.5 * widthMapUnits, - 0.5 * widthMapUnits, 0.5 * widthMapUnits, 0.5 * widthMapUnits ), 0.0001 );
|
||||
|
||||
}
|
||||
|
||||
void TestQgsMapSettings::testComputeScaleForExtent()
|
||||
{
|
||||
QgsMapSettings settings;
|
||||
settings.setExtent( QgsRectangle( -500., -500., 500., 500. ) ); // Just to ensure settings are valid
|
||||
settings.setDestinationCrs( QgsCoordinateReferenceSystem( "EPSG:3857" ) );
|
||||
|
||||
settings.setOutputSize( QSize( 1000, 1000 ) );
|
||||
|
||||
double scale = settings.computeScaleForExtent( QgsRectangle( -500., -500., 500., 500. ) );
|
||||
|
||||
double widthInches = 1000 * QgsUnitTypes::fromUnitToUnitFactor( settings.mapUnits(), QgsUnitTypes::DistanceFeet ) * 12;
|
||||
double testScale = widthInches * settings.outputDpi() / double( settings.outputSize().width() );
|
||||
QGSCOMPARENEAR( scale, testScale, 0.001 );
|
||||
}
|
||||
|
||||
QGSTEST_MAIN( TestQgsMapSettings )
|
||||
#include "testqgsmapsettings.moc"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user