mirror of
https://github.com/qgis/QGIS.git
synced 2025-11-22 00:14:55 -05:00
[api] Set specific distance:elevation ratio for elevation profile canvas
This commit is contained in:
parent
19d87693db
commit
d919d8f776
@ -235,6 +235,35 @@ Sets whether the distance and elevation scales are locked to each other.
|
||||
.. seealso:: :py:func:`lockAxisScales`
|
||||
|
||||
.. versionadded:: 3.32
|
||||
%End
|
||||
|
||||
double axisScaleRatio() const;
|
||||
%Docstring
|
||||
Returns the current ratio of horizontal (distance) to vertical
|
||||
(elevation) scale for the plot.
|
||||
|
||||
.. seealso:: :py:func:`setAxisScaleRatio`
|
||||
|
||||
.. versionadded:: 4.0
|
||||
%End
|
||||
|
||||
void setAxisScaleRatio( double scale );
|
||||
%Docstring
|
||||
Sets the ratio of horizontal (distance) to vertical (elevation) scale
|
||||
for the plot.
|
||||
|
||||
E.g. a ``scale`` of 3 indicates a ratio of 3:1 for distance vs
|
||||
elevation, whereas a scale of 0.3333 indicates a ratio of 1:3 for
|
||||
distance vs elevation.
|
||||
|
||||
This will immediately update the visible plot area to match the
|
||||
specified scale.
|
||||
|
||||
.. seealso:: :py:func:`axisScaleRatio`
|
||||
|
||||
.. seealso:: :py:func:`setLockAxisScales`
|
||||
|
||||
.. versionadded:: 4.0
|
||||
%End
|
||||
|
||||
Qgis::DistanceUnit distanceUnit() const;
|
||||
|
||||
@ -235,6 +235,35 @@ Sets whether the distance and elevation scales are locked to each other.
|
||||
.. seealso:: :py:func:`lockAxisScales`
|
||||
|
||||
.. versionadded:: 3.32
|
||||
%End
|
||||
|
||||
double axisScaleRatio() const;
|
||||
%Docstring
|
||||
Returns the current ratio of horizontal (distance) to vertical
|
||||
(elevation) scale for the plot.
|
||||
|
||||
.. seealso:: :py:func:`setAxisScaleRatio`
|
||||
|
||||
.. versionadded:: 4.0
|
||||
%End
|
||||
|
||||
void setAxisScaleRatio( double scale );
|
||||
%Docstring
|
||||
Sets the ratio of horizontal (distance) to vertical (elevation) scale
|
||||
for the plot.
|
||||
|
||||
E.g. a ``scale`` of 3 indicates a ratio of 3:1 for distance vs
|
||||
elevation, whereas a scale of 0.3333 indicates a ratio of 1:3 for
|
||||
distance vs elevation.
|
||||
|
||||
This will immediately update the visible plot area to match the
|
||||
specified scale.
|
||||
|
||||
.. seealso:: :py:func:`axisScaleRatio`
|
||||
|
||||
.. seealso:: :py:func:`setLockAxisScales`
|
||||
|
||||
.. versionadded:: 4.0
|
||||
%End
|
||||
|
||||
Qgis::DistanceUnit distanceUnit() const;
|
||||
|
||||
@ -605,16 +605,19 @@ void QgsElevationProfileCanvas::adjustRangeForAxisScaleLock( double &xMinimum, d
|
||||
// ensures that we always "zoom out" to match horizontal/vertical scales
|
||||
const double horizontalScale = ( xMaximum - xMinimum ) / mPlotItem->plotArea().width();
|
||||
const double verticalScale = ( yMaximum - yMinimum ) / mPlotItem->plotArea().height();
|
||||
if ( horizontalScale > verticalScale )
|
||||
|
||||
const double currentRatio = horizontalScale / verticalScale;
|
||||
|
||||
if ( currentRatio <= mLockedAxisScale )
|
||||
{
|
||||
const double height = horizontalScale * mPlotItem->plotArea().height();
|
||||
const double height = horizontalScale * mPlotItem->plotArea().height() / mLockedAxisScale;
|
||||
const double deltaHeight = ( yMaximum - yMinimum ) - height;
|
||||
yMinimum += deltaHeight / 2;
|
||||
yMaximum -= deltaHeight / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
const double width = verticalScale * mPlotItem->plotArea().width();
|
||||
const double width = verticalScale * mPlotItem->plotArea().width() * mLockedAxisScale;
|
||||
const double deltaWidth = ( ( xMaximum - xMinimum ) - width );
|
||||
xMinimum += deltaWidth / 2;
|
||||
xMaximum -= deltaWidth / 2;
|
||||
@ -700,6 +703,32 @@ void QgsElevationProfileCanvas::setLockAxisScales( bool lock )
|
||||
}
|
||||
}
|
||||
|
||||
double QgsElevationProfileCanvas::axisScaleRatio() const
|
||||
{
|
||||
const double horizontalScale = ( mPlotItem->xMaximum() - mPlotItem->xMinimum() ) * mPlotItem->mXScaleFactor / mPlotItem->plotArea().width();
|
||||
const double verticalScale = ( mPlotItem->yMaximum() - mPlotItem->yMinimum() ) / mPlotItem->plotArea().height();
|
||||
return horizontalScale / verticalScale;
|
||||
}
|
||||
|
||||
void QgsElevationProfileCanvas::setAxisScaleRatio( double scale )
|
||||
{
|
||||
mLockedAxisScale = scale;
|
||||
|
||||
double xMinimum = mPlotItem->xMinimum() * mPlotItem->mXScaleFactor;
|
||||
double xMaximum = mPlotItem->xMaximum() * mPlotItem->mXScaleFactor;
|
||||
double yMinimum = mPlotItem->yMinimum();
|
||||
double yMaximum = mPlotItem->yMaximum();
|
||||
adjustRangeForAxisScaleLock( xMinimum, xMaximum, yMinimum, yMaximum );
|
||||
mPlotItem->setXMinimum( xMinimum / mPlotItem->mXScaleFactor );
|
||||
mPlotItem->setXMaximum( xMaximum / mPlotItem->mXScaleFactor );
|
||||
mPlotItem->setYMinimum( yMinimum );
|
||||
mPlotItem->setYMaximum( yMaximum );
|
||||
|
||||
refineResults();
|
||||
mPlotItem->updatePlot();
|
||||
emit plotAreaChanged();
|
||||
}
|
||||
|
||||
QgsPointXY QgsElevationProfileCanvas::snapToPlot( QPoint point )
|
||||
{
|
||||
if ( !mCurrentJob || !mSnappingEnabled )
|
||||
|
||||
@ -239,6 +239,29 @@ class GUI_EXPORT QgsElevationProfileCanvas : public QgsPlotCanvas
|
||||
*/
|
||||
void setLockAxisScales( bool lock );
|
||||
|
||||
/**
|
||||
* Returns the current ratio of horizontal (distance) to vertical (elevation) scale
|
||||
* for the plot.
|
||||
*
|
||||
* \see setAxisScaleRatio()
|
||||
* \since QGIS 4.0
|
||||
*/
|
||||
double axisScaleRatio() const;
|
||||
|
||||
/**
|
||||
* Sets the ratio of horizontal (distance) to vertical (elevation) scale for the plot.
|
||||
*
|
||||
* E.g. a \a scale of 3 indicates a ratio of 3:1 for distance vs elevation, whereas a scale
|
||||
* of 0.3333 indicates a ratio of 1:3 for distance vs elevation.
|
||||
*
|
||||
* This will immediately update the visible plot area to match the specified scale.
|
||||
*
|
||||
* \see axisScaleRatio()
|
||||
* \see setLockAxisScales()
|
||||
* \since QGIS 4.0
|
||||
*/
|
||||
void setAxisScaleRatio( double scale );
|
||||
|
||||
/**
|
||||
* Returns the distance unit used by the canvas.
|
||||
*
|
||||
@ -340,6 +363,7 @@ class GUI_EXPORT QgsElevationProfileCanvas : public QgsPlotCanvas
|
||||
QgsScreenHelper *mScreenHelper = nullptr;
|
||||
|
||||
bool mLockAxisScales = false;
|
||||
double mLockedAxisScale = 1;
|
||||
|
||||
QgsCoordinateReferenceSystem mCrs;
|
||||
QgsProject *mProject = nullptr;
|
||||
|
||||
@ -225,6 +225,56 @@ class TestQgsElevationProfileCanvas(QgisTestCase):
|
||||
canvas.wheelEvent(wheel_event)
|
||||
self.assertEqual(tool.events[-1].type(), QEvent.Type.Wheel)
|
||||
|
||||
def test_ratio(self):
|
||||
"""
|
||||
Test axis scale ratio logic
|
||||
"""
|
||||
canvas = QgsElevationProfileCanvas()
|
||||
canvas.setCrs(QgsCoordinateReferenceSystem("EPSG:4326"))
|
||||
canvas.setFrameStyle(0)
|
||||
# make a 2:1 canvas, to make the maths easier!
|
||||
canvas.resize(800, 400)
|
||||
canvas.setProject(QgsProject.instance())
|
||||
canvas.show()
|
||||
self.assertEqual(canvas.width(), 800)
|
||||
self.assertEqual(canvas.height(), 400)
|
||||
|
||||
canvas.setVisiblePlotRange(100, 200, 50, 150)
|
||||
# showing 100m distance, 100m elevation
|
||||
# distance:elevation ratio is 1:2, as canvas is twice as wide as high
|
||||
self.assertAlmostEqual(canvas.axisScaleRatio(), 0.5, 1)
|
||||
|
||||
canvas.setVisiblePlotRange(100, 300, 50, 150)
|
||||
# showing 200m distance, 100m elevation
|
||||
# distance:elevation ratio is 1:1, as canvas is twice as wide as high
|
||||
self.assertAlmostEqual(canvas.axisScaleRatio(), 1.0, 1)
|
||||
|
||||
canvas.setVisiblePlotRange(100, 500, 50, 150)
|
||||
# showing 400m distance, 100m elevation
|
||||
# distance:elevation ratio is 2:1, as canvas is twice as wide as high
|
||||
self.assertAlmostEqual(canvas.axisScaleRatio(), 2.0, delta=0.1)
|
||||
|
||||
canvas.setAxisScaleRatio(0.5)
|
||||
self.assertAlmostEqual(canvas.axisScaleRatio(), 0.5, 1)
|
||||
self.assertAlmostEqual(canvas.visibleDistanceRange().lower(), 248.024, 1)
|
||||
self.assertAlmostEqual(canvas.visibleDistanceRange().upper(), 351.976, 1)
|
||||
self.assertAlmostEqual(canvas.visibleElevationRange().lower(), 50.0, 1)
|
||||
self.assertAlmostEqual(canvas.visibleElevationRange().upper(), 150.0, 1)
|
||||
|
||||
canvas.setAxisScaleRatio(1.0)
|
||||
self.assertAlmostEqual(canvas.axisScaleRatio(), 1.0, 1)
|
||||
self.assertAlmostEqual(canvas.visibleDistanceRange().lower(), 248.024, 1)
|
||||
self.assertAlmostEqual(canvas.visibleDistanceRange().upper(), 351.976, 1)
|
||||
self.assertAlmostEqual(canvas.visibleElevationRange().lower(), 75.0, 1)
|
||||
self.assertAlmostEqual(canvas.visibleElevationRange().upper(), 125.0, 1)
|
||||
|
||||
canvas.setAxisScaleRatio(2.0)
|
||||
self.assertAlmostEqual(canvas.axisScaleRatio(), 2.0, 1)
|
||||
self.assertAlmostEqual(canvas.visibleDistanceRange().lower(), 248.024, 1)
|
||||
self.assertAlmostEqual(canvas.visibleDistanceRange().upper(), 351.976, 1)
|
||||
self.assertAlmostEqual(canvas.visibleElevationRange().lower(), 87.5, 1)
|
||||
self.assertAlmostEqual(canvas.visibleElevationRange().upper(), 112.5, 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user