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
|
Returns the coordinate transform from layer's CRS to destination CRS
|
||||||
|
|
||||||
:return: transform - may be invalid if the transform is not needed
|
: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
|
%End
|
||||||
|
|
||||||
QgsRectangle fullExtent() const;
|
QgsRectangle fullExtent() const;
|
||||||
|
|||||||
@ -436,6 +436,39 @@ QgsCoordinateTransform QgsMapSettings::layerTransform( const QgsMapLayer *layer
|
|||||||
return QgsCoordinateTransform( layer->crs(), mDestCRS, mTransformContext );
|
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
|
double QgsMapSettings::layerToMapUnits( const QgsMapLayer *layer, const QgsRectangle &referenceExtent ) const
|
||||||
{
|
{
|
||||||
return layerTransform( layer ).scaleFactor( referenceExtent );
|
return layerTransform( layer ).scaleFactor( referenceExtent );
|
||||||
|
|||||||
@ -600,6 +600,28 @@ class CORE_EXPORT QgsMapSettings : public QgsTemporalRangeObject
|
|||||||
*/
|
*/
|
||||||
QgsCoordinateTransform layerTransform( const QgsMapLayer *layer ) const;
|
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
|
//! returns current extent of layer set
|
||||||
QgsRectangle fullExtent() const;
|
QgsRectangle fullExtent() const;
|
||||||
|
|
||||||
|
|||||||
@ -62,6 +62,8 @@ class TestQgsMapSettings: public QObject
|
|||||||
void testRenderedFeatureHandlers();
|
void testRenderedFeatureHandlers();
|
||||||
void testCustomRenderingFlags();
|
void testCustomRenderingFlags();
|
||||||
void testClippingRegions();
|
void testClippingRegions();
|
||||||
|
void testComputeExtentForScale();
|
||||||
|
void testComputeScaleForExtent();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString toString( const QPolygonF &p, int decimalPlaces = 2 ) const;
|
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))" ) ) ;
|
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 )
|
QGSTEST_MAIN( TestQgsMapSettings )
|
||||||
#include "testqgsmapsettings.moc"
|
#include "testqgsmapsettings.moc"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user