Cleanups, unit tests

This commit is contained in:
Nyall Dawson 2020-12-02 08:52:10 +10:00
parent c4f2892bbc
commit fc3d61aaea
13 changed files with 331 additions and 35 deletions

View File

@ -75,23 +75,40 @@ Sets the color ramp ``shader`` function used to visualize the attribute.
.. seealso:: :py:func:`colorRampShader`
%End
double min() const;
double minimum() const;
%Docstring
Returns min
%End
void setMin( double value );
%Docstring
Sets min
Returns the minimum value for attributes which will be used by the color ramp shader.
.. seealso:: :py:func:`setMinimum`
.. seealso:: :py:func:`maximum`
%End
double max() const;
void setMinimum( double minimum );
%Docstring
Returns max
Sets the ``minimum`` value for attributes which will be used by the color ramp shader.
.. seealso:: :py:func:`minimum`
.. seealso:: :py:func:`setMaximum`
%End
void setMax( double value );
double maximum() const;
%Docstring
Sets max
Returns the maximum value for attributes which will be used by the color ramp shader.
.. seealso:: :py:func:`setMaximum`
.. seealso:: :py:func:`minimum`
%End
void setMaximum( double maximum );
%Docstring
Sets the ``maximum`` value for attributes which will be used by the color ramp shader.
.. seealso:: :py:func:`maximum`
.. seealso:: :py:func:`setMinimum`
%End
};

View File

@ -135,6 +135,8 @@ Abstract base class for 2d point cloud renderers.
if ( type == QLatin1String( "rgb" ) )
sipType = sipType_QgsPointCloudRgbRenderer;
else if ( type == QLatin1String( "ramp" ) )
sipType = sipType_QgsPointCloudAttributeByRampRenderer;
else
sipType = 0;
%End

View File

@ -143,8 +143,8 @@ QgsPointCloudRenderer *QgsPointCloudAttributeByRampRenderer::create( QDomElement
QDomElement elemShader = element.firstChildElement( QStringLiteral( "colorrampshader" ) );
r->mColorRampShader.readXml( elemShader );
r->setMin( element.attribute( QStringLiteral( "min" ), QStringLiteral( "0" ) ).toDouble() );
r->setMax( element.attribute( QStringLiteral( "max" ), QStringLiteral( "100" ) ).toDouble() );
r->setMinimum( element.attribute( QStringLiteral( "min" ), QStringLiteral( "0" ) ).toDouble() );
r->setMaximum( element.attribute( QStringLiteral( "max" ), QStringLiteral( "100" ) ).toDouble() );
r->restoreCommonProperties( element, context );
@ -208,22 +208,22 @@ void QgsPointCloudAttributeByRampRenderer::setColorRampShader( const QgsColorRam
mColorRampShader = shader;
}
double QgsPointCloudAttributeByRampRenderer::min() const
double QgsPointCloudAttributeByRampRenderer::minimum() const
{
return mMin;
}
void QgsPointCloudAttributeByRampRenderer::setMin( double value )
void QgsPointCloudAttributeByRampRenderer::setMinimum( double minimum )
{
mMin = value;
mMin = minimum;
}
double QgsPointCloudAttributeByRampRenderer::max() const
double QgsPointCloudAttributeByRampRenderer::maximum() const
{
return mMax;
}
void QgsPointCloudAttributeByRampRenderer::setMax( double value )
void QgsPointCloudAttributeByRampRenderer::setMaximum( double value )
{
mMax = value;
}

View File

@ -79,16 +79,37 @@ class CORE_EXPORT QgsPointCloudAttributeByRampRenderer : public QgsPointCloudRen
*/
void setColorRampShader( const QgsColorRampShader &shader );
//! Returns min
double min() const;
//! Sets min
void setMin( double value );
/**
* Returns the minimum value for attributes which will be used by the color ramp shader.
*
* \see setMinimum()
* \see maximum()
*/
double minimum() const;
//! Returns max
double max() const;
/**
* Sets the \a minimum value for attributes which will be used by the color ramp shader.
*
* \see minimum()
* \see setMaximum()
*/
void setMinimum( double minimum );
//! Sets max
void setMax( double value );
/**
* Returns the maximum value for attributes which will be used by the color ramp shader.
*
* \see setMaximum()
* \see minimum()
*/
double maximum() const;
/**
* Sets the \a maximum value for attributes which will be used by the color ramp shader.
*
* \see maximum()
* \see setMinimum()
*/
void setMaximum( double maximum );
private:

View File

@ -204,6 +204,8 @@ class CORE_EXPORT QgsPointCloudRenderer
if ( type == QLatin1String( "rgb" ) )
sipType = sipType_QgsPointCloudRgbRenderer;
else if ( type == QLatin1String( "ramp" ) )
sipType = sipType_QgsPointCloudAttributeByRampRenderer;
else
sipType = 0;
SIP_END

View File

@ -63,8 +63,8 @@ QgsPointCloudRenderer *QgsPointCloudAttributeByRampRendererWidget::renderer()
std::unique_ptr< QgsPointCloudAttributeByRampRenderer > renderer = qgis::make_unique< QgsPointCloudAttributeByRampRenderer >();
renderer->setAttribute( mAttributeComboBox->currentAttribute() );
renderer->setMin( mMinSpin->value() );
renderer->setMax( mMaxSpin->value() );
renderer->setMinimum( mMinSpin->value() );
renderer->setMaximum( mMaxSpin->value() );
renderer->setColorRampShader( mScalarColorRampShaderWidget->shader() );
@ -90,11 +90,11 @@ void QgsPointCloudAttributeByRampRendererWidget::setFromRenderer( const QgsPoint
{
mAttributeComboBox->setAttribute( mbcr->attribute() );
mMinSpin->setValue( mbcr->min() );
mMaxSpin->setValue( mbcr->max() );
mMinSpin->setValue( mbcr->minimum() );
mMaxSpin->setValue( mbcr->maximum() );
whileBlocking( mScalarColorRampShaderWidget )->setFromShader( mbcr->colorRampShader() );
whileBlocking( mScalarColorRampShaderWidget )->setMinimumMaximum( mbcr->min(), mbcr->max() );
whileBlocking( mScalarColorRampShaderWidget )->setMinimumMaximum( mbcr->minimum(), mbcr->maximum() );
}
else
{

View File

@ -206,6 +206,7 @@ ADD_PYTHON_TEST(PyQgsPanelWidget test_qgspanelwidget.py)
ADD_PYTHON_TEST(PyQgsPanelWidgetStack test_qgspanelwidgetstack.py)
ADD_PYTHON_TEST(PyQgsPathResolver test_qgspathresolver.py)
ADD_PYTHON_TEST(PyQgsPoint test_qgspoint.py)
ADD_PYTHON_TEST(PyQgsPointCloudAttributeByRampRenderer test_qgspointcloudattributebyramprenderer.py)
ADD_PYTHON_TEST(PyQgsPointCloudAttributeComboBox test_qgspointcloudattributecombobox.py)
ADD_PYTHON_TEST(PyQgsPointCloudAttributeModel test_qgspointcloudattributemodel.py)
ADD_PYTHON_TEST(PyQgsPointCloudRgbRenderer test_qgspointcloudrgbrenderer.py)

View File

@ -0,0 +1,258 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for QgsPointCloudAttributeByRampRenderer
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Nyall Dawson'
__date__ = '09/11/2020'
__copyright__ = 'Copyright 2020, The QGIS Project'
import qgis # NOQA
from qgis.core import (
QgsProviderRegistry,
QgsPointCloudLayer,
QgsPointCloudAttributeByRampRenderer,
QgsReadWriteContext,
QgsRenderContext,
QgsPointCloudRenderContext,
QgsVector3D,
QgsMultiRenderChecker,
QgsMapSettings,
QgsRectangle,
QgsUnitTypes,
QgsMapUnitScale,
QgsCoordinateReferenceSystem,
QgsDoubleRange,
QgsColorRampShader,
QgsStyle
)
from qgis.PyQt.QtCore import QDir, QSize
from qgis.PyQt.QtGui import QPainter
from qgis.PyQt.QtXml import QDomDocument
from qgis.testing import start_app, unittest
from utilities import unitTestDataPath
start_app()
class TestQgsPointCloudAttributeByRampRenderer(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.report = "<h1>Python QgsPointCloudAttributeByRampRenderer Tests</h1>\n"
@classmethod
def tearDownClass(cls):
report_file_path = "%s/qgistest.html" % QDir.tempPath()
with open(report_file_path, 'a') as report_file:
report_file.write(cls.report)
def testBasic(self):
renderer = QgsPointCloudAttributeByRampRenderer()
renderer.setAttribute('attr')
self.assertEqual(renderer.attribute(), 'attr')
renderer.setMinimum(5)
self.assertEqual(renderer.minimum(), 5)
renderer.setMaximum(15)
self.assertEqual(renderer.maximum(), 15)
ramp = QgsStyle.defaultStyle().colorRamp("Viridis")
shader = QgsColorRampShader(20, 30, ramp)
renderer.setColorRampShader(shader)
self.assertEqual(renderer.colorRampShader().minimumValue(), 20)
self.assertEqual(renderer.colorRampShader().maximumValue(), 30)
renderer.setMaximumScreenError(18)
renderer.setMaximumScreenErrorUnit(QgsUnitTypes.RenderInches)
renderer.setPointSize(13)
renderer.setPointSizeUnit(QgsUnitTypes.RenderPoints)
renderer.setPointSizeMapUnitScale(QgsMapUnitScale(1000, 2000))
rr = renderer.clone()
self.assertEqual(rr.maximumScreenError(), 18)
self.assertEqual(rr.maximumScreenErrorUnit(), QgsUnitTypes.RenderInches)
self.assertEqual(rr.pointSize(), 13)
self.assertEqual(rr.pointSizeUnit(), QgsUnitTypes.RenderPoints)
self.assertEqual(rr.pointSizeMapUnitScale().minScale, 1000)
self.assertEqual(rr.pointSizeMapUnitScale().maxScale, 2000)
self.assertEqual(rr.attribute(), 'attr')
self.assertEqual(rr.minimum(), 5)
self.assertEqual(rr.maximum(), 15)
self.assertEqual(rr.colorRampShader().minimumValue(), 20)
self.assertEqual(rr.colorRampShader().maximumValue(), 30)
self.assertEqual(rr.colorRampShader().sourceColorRamp().color1(),
renderer.colorRampShader().sourceColorRamp().color1())
self.assertEqual(rr.colorRampShader().sourceColorRamp().color2(),
renderer.colorRampShader().sourceColorRamp().color2())
doc = QDomDocument("testdoc")
elem = renderer.save(doc, QgsReadWriteContext())
r2 = QgsPointCloudAttributeByRampRenderer.create(elem, QgsReadWriteContext())
self.assertEqual(r2.maximumScreenError(), 18)
self.assertEqual(r2.maximumScreenErrorUnit(), QgsUnitTypes.RenderInches)
self.assertEqual(r2.pointSize(), 13)
self.assertEqual(r2.pointSizeUnit(), QgsUnitTypes.RenderPoints)
self.assertEqual(r2.pointSizeMapUnitScale().minScale, 1000)
self.assertEqual(r2.pointSizeMapUnitScale().maxScale, 2000)
self.assertEqual(r2.attribute(), 'attr')
self.assertEqual(r2.minimum(), 5)
self.assertEqual(r2.maximum(), 15)
self.assertEqual(r2.colorRampShader().minimumValue(), 20)
self.assertEqual(r2.colorRampShader().maximumValue(), 30)
self.assertEqual(r2.colorRampShader().sourceColorRamp().color1(),
renderer.colorRampShader().sourceColorRamp().color1())
self.assertEqual(r2.colorRampShader().sourceColorRamp().color2(),
renderer.colorRampShader().sourceColorRamp().color2())
def testUsedAttributes(self):
renderer = QgsPointCloudAttributeByRampRenderer()
renderer.setAttribute('attr')
rc = QgsRenderContext()
prc = QgsPointCloudRenderContext(rc, QgsVector3D(), QgsVector3D())
self.assertEqual(renderer.usedAttributes(prc), {'attr'})
@unittest.skipIf('ept' not in QgsProviderRegistry.instance().providerList(), 'EPT provider not available')
def testRender(self):
layer = QgsPointCloudLayer(unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept')
self.assertTrue(layer.isValid())
renderer = QgsPointCloudAttributeByRampRenderer()
renderer.setAttribute('Intensity')
renderer.setMinimum(200)
renderer.setMaximum(1000)
ramp = QgsStyle.defaultStyle().colorRamp("Viridis")
shader = QgsColorRampShader(200, 1000, ramp)
shader.classifyColorRamp()
renderer.setColorRampShader(shader)
layer.setRenderer(renderer)
layer.renderer().setPointSize(2)
layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMillimeters)
mapsettings = QgsMapSettings()
mapsettings.setOutputSize(QSize(400, 400))
mapsettings.setOutputDpi(96)
mapsettings.setDestinationCrs(layer.crs())
mapsettings.setExtent(QgsRectangle(498061, 7050991, 498069, 7050999))
mapsettings.setLayers([layer])
renderchecker = QgsMultiRenderChecker()
renderchecker.setMapSettings(mapsettings)
renderchecker.setControlPathPrefix('pointcloudrenderer')
renderchecker.setControlName('expected_ramp_render')
result = renderchecker.runTest('expected_ramp_render')
TestQgsPointCloudAttributeByRampRenderer.report += renderchecker.report()
self.assertTrue(result)
@unittest.skipIf('ept' not in QgsProviderRegistry.instance().providerList(), 'EPT provider not available')
def testRenderCrsTransform(self):
layer = QgsPointCloudLayer(unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept')
self.assertTrue(layer.isValid())
renderer = QgsPointCloudAttributeByRampRenderer()
renderer.setAttribute('Intensity')
renderer.setMinimum(200)
renderer.setMaximum(1000)
ramp = QgsStyle.defaultStyle().colorRamp("Viridis")
shader = QgsColorRampShader(200, 1000, ramp)
shader.classifyColorRamp()
renderer.setColorRampShader(shader)
layer.setRenderer(renderer)
layer.renderer().setPointSize(2)
layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMillimeters)
mapsettings = QgsMapSettings()
mapsettings.setOutputSize(QSize(400, 400))
mapsettings.setOutputDpi(96)
mapsettings.setDestinationCrs(QgsCoordinateReferenceSystem('EPSG:4326'))
mapsettings.setExtent(QgsRectangle(152.980508492, -26.662023491, 152.980586020, -26.662071137))
mapsettings.setLayers([layer])
renderchecker = QgsMultiRenderChecker()
renderchecker.setMapSettings(mapsettings)
renderchecker.setControlPathPrefix('pointcloudrenderer')
renderchecker.setControlName('expected_ramp_render_crs_transform')
result = renderchecker.runTest('expected_ramp_render_crs_transform')
TestQgsPointCloudAttributeByRampRenderer.report += renderchecker.report()
self.assertTrue(result)
@unittest.skipIf('ept' not in QgsProviderRegistry.instance().providerList(), 'EPT provider not available')
def testRenderPointSize(self):
layer = QgsPointCloudLayer(unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept')
self.assertTrue(layer.isValid())
renderer = QgsPointCloudAttributeByRampRenderer()
renderer.setAttribute('Intensity')
renderer.setMinimum(200)
renderer.setMaximum(1000)
ramp = QgsStyle.defaultStyle().colorRamp("Viridis")
shader = QgsColorRampShader(200, 1000, ramp)
shader.classifyColorRamp()
renderer.setColorRampShader(shader)
layer.setRenderer(renderer)
layer.renderer().setPointSize(.15)
layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMapUnits)
mapsettings = QgsMapSettings()
mapsettings.setOutputSize(QSize(400, 400))
mapsettings.setOutputDpi(96)
mapsettings.setDestinationCrs(layer.crs())
mapsettings.setExtent(QgsRectangle(498061, 7050991, 498069, 7050999))
mapsettings.setLayers([layer])
renderchecker = QgsMultiRenderChecker()
renderchecker.setMapSettings(mapsettings)
renderchecker.setControlPathPrefix('pointcloudrenderer')
renderchecker.setControlName('expected_ramp_pointsize')
result = renderchecker.runTest('expected_ramp_pointsize')
TestQgsPointCloudAttributeByRampRenderer.report += renderchecker.report()
self.assertTrue(result)
@unittest.skipIf('ept' not in QgsProviderRegistry.instance().providerList(), 'EPT provider not available')
def testRenderZRange(self):
layer = QgsPointCloudLayer(unitTestDataPath() + '/point_clouds/ept/sunshine-coast/ept.json', 'test', 'ept')
self.assertTrue(layer.isValid())
renderer = QgsPointCloudAttributeByRampRenderer()
renderer.setAttribute('Intensity')
renderer.setMinimum(200)
renderer.setMaximum(1000)
ramp = QgsStyle.defaultStyle().colorRamp("Viridis")
shader = QgsColorRampShader(200, 1000, ramp)
shader.classifyColorRamp()
renderer.setColorRampShader(shader)
layer.setRenderer(renderer)
layer.renderer().setPointSize(2)
layer.renderer().setPointSizeUnit(QgsUnitTypes.RenderMillimeters)
mapsettings = QgsMapSettings()
mapsettings.setOutputSize(QSize(400, 400))
mapsettings.setOutputDpi(96)
mapsettings.setDestinationCrs(layer.crs())
mapsettings.setExtent(QgsRectangle(498061, 7050991, 498069, 7050999))
mapsettings.setLayers([layer])
mapsettings.setZRange(QgsDoubleRange(74.7, 75))
renderchecker = QgsMultiRenderChecker()
renderchecker.setMapSettings(mapsettings)
renderchecker.setControlPathPrefix('pointcloudrenderer')
renderchecker.setControlName('expected_ramp_zfilter')
result = renderchecker.runTest('expected_ramp_zfilter')
TestQgsPointCloudAttributeByRampRenderer.report += renderchecker.report()
self.assertTrue(result)
if __name__ == '__main__':
unittest.main()

View File

@ -149,11 +149,6 @@ class TestQgsPointCloudRgbRenderer(unittest.TestCase):
self.assertEqual(renderer.usedAttributes(prc), {'r', 'g', 'b'})
# if context is filtering by z, we also need the z attribute
rc.setZRange(QgsDoubleRange(1, 10))
prc = QgsPointCloudRenderContext(rc, QgsVector3D(), QgsVector3D())
self.assertEqual(renderer.usedAttributes(prc), {'r', 'g', 'b', 'Z'})
@unittest.skipIf('ept' not in QgsProviderRegistry.instance().providerList(), 'EPT provider not available')
def testRender(self):
layer = QgsPointCloudLayer(unitTestDataPath() + '/point_clouds/ept/rgb/ept.json', 'test', 'ept')

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB