mirror of
https://github.com/qgis/QGIS.git
synced 2025-11-29 00:06:58 -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`
|
.. seealso:: :py:func:`lockAxisScales`
|
||||||
|
|
||||||
.. versionadded:: 3.32
|
.. 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
|
%End
|
||||||
|
|
||||||
Qgis::DistanceUnit distanceUnit() const;
|
Qgis::DistanceUnit distanceUnit() const;
|
||||||
|
|||||||
@ -235,6 +235,35 @@ Sets whether the distance and elevation scales are locked to each other.
|
|||||||
.. seealso:: :py:func:`lockAxisScales`
|
.. seealso:: :py:func:`lockAxisScales`
|
||||||
|
|
||||||
.. versionadded:: 3.32
|
.. 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
|
%End
|
||||||
|
|
||||||
Qgis::DistanceUnit distanceUnit() const;
|
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
|
// ensures that we always "zoom out" to match horizontal/vertical scales
|
||||||
const double horizontalScale = ( xMaximum - xMinimum ) / mPlotItem->plotArea().width();
|
const double horizontalScale = ( xMaximum - xMinimum ) / mPlotItem->plotArea().width();
|
||||||
const double verticalScale = ( yMaximum - yMinimum ) / mPlotItem->plotArea().height();
|
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;
|
const double deltaHeight = ( yMaximum - yMinimum ) - height;
|
||||||
yMinimum += deltaHeight / 2;
|
yMinimum += deltaHeight / 2;
|
||||||
yMaximum -= deltaHeight / 2;
|
yMaximum -= deltaHeight / 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const double width = verticalScale * mPlotItem->plotArea().width();
|
const double width = verticalScale * mPlotItem->plotArea().width() * mLockedAxisScale;
|
||||||
const double deltaWidth = ( ( xMaximum - xMinimum ) - width );
|
const double deltaWidth = ( ( xMaximum - xMinimum ) - width );
|
||||||
xMinimum += deltaWidth / 2;
|
xMinimum += deltaWidth / 2;
|
||||||
xMaximum -= 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 )
|
QgsPointXY QgsElevationProfileCanvas::snapToPlot( QPoint point )
|
||||||
{
|
{
|
||||||
if ( !mCurrentJob || !mSnappingEnabled )
|
if ( !mCurrentJob || !mSnappingEnabled )
|
||||||
|
|||||||
@ -239,6 +239,29 @@ class GUI_EXPORT QgsElevationProfileCanvas : public QgsPlotCanvas
|
|||||||
*/
|
*/
|
||||||
void setLockAxisScales( bool lock );
|
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.
|
* Returns the distance unit used by the canvas.
|
||||||
*
|
*
|
||||||
@ -340,6 +363,7 @@ class GUI_EXPORT QgsElevationProfileCanvas : public QgsPlotCanvas
|
|||||||
QgsScreenHelper *mScreenHelper = nullptr;
|
QgsScreenHelper *mScreenHelper = nullptr;
|
||||||
|
|
||||||
bool mLockAxisScales = false;
|
bool mLockAxisScales = false;
|
||||||
|
double mLockedAxisScale = 1;
|
||||||
|
|
||||||
QgsCoordinateReferenceSystem mCrs;
|
QgsCoordinateReferenceSystem mCrs;
|
||||||
QgsProject *mProject = nullptr;
|
QgsProject *mProject = nullptr;
|
||||||
|
|||||||
@ -225,6 +225,56 @@ class TestQgsElevationProfileCanvas(QgisTestCase):
|
|||||||
canvas.wheelEvent(wheel_event)
|
canvas.wheelEvent(wheel_event)
|
||||||
self.assertEqual(tool.events[-1].type(), QEvent.Type.Wheel)
|
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__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user