Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Implement raster auto-stretching when updating canvas #3871

Merged
merged 2 commits into from
Dec 16, 2016

Conversation

rouault
Copy link
Contributor

@rouault rouault commented Dec 15, 2016

This commit implements the improvements described at:
https://lists.osgeo.org/pipermail/qgis-developer/2016-September/044393.html

The QgsRasterMinMaxWidget now offers a seetting to specify that the statistics
should be computed each time the canvas extent changes.

Other changes:

  • the content of the QgsRasterMinMaxWidget is now persistant.
  • there is no longer any Load button. The global Apply / OK button of the raster
    properties dialog has this effect.
  • the default "limits" for single band raster is now MinMax and not CumulativeCut
  • the default "limits" can be configured for single band, multi band single byte and
    multi band multi byte
  • "Strech using current extent" honours the "limits" instead of forcing min/max.

@nyalldawson
Copy link
Collaborator

there is no longer any Load button. The global Apply / OK button of the raster
properties dialog has this effect.

Does this also work in the live styling dock?

@nirvn
Copy link
Contributor

nirvn commented Dec 15, 2016

Nice work. How does stretch using current extent work if you only want to take current extent to get min max once ?

Copy link
Collaborator

@nyalldawson nyalldawson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Sounds like a very handy feature to have too. Have you got any more unit tests incoming for this?

@@ -65,6 +66,12 @@ class CORE_EXPORT QgsContrastEnhancement
//! \brief Helper function that returns the minimum possible value for a GDAL data type
static double minimumValuePossible( Qgis::DataType );

//! \brief Return a strign to serialize ContrastEnhancementAlgorithm
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken into account

QSettings mySettings;

QString myKey;
QString myDefault;
QString myDefaultAlg;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the general agreement is that we avoid "my"/"the" prefixes in new code to more closely follow the Qt conventions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken into account

/** \brief Return default contrast enhancemnt settings for that type of raster.
* @note not available in python bindings
*/
bool defaultContrastEnhancementSettings( QgsContrastEnhancement::ContrastEnhancementAlgorithm& myAlgorithm,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be const?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken into account

public:

//! \brief Default cumulative cut lower limit
static const double CUMULATIVE_CUT_LOWER;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about flipping these static consts to static constexpr double?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken into account

@@ -43,8 +44,8 @@ QgsMultiBandColorRendererWidget::QgsMultiBandColorRendererWidget( QgsRasterLayer
layout->setContentsMargins( 0, 0, 0, 0 );
mMinMaxContainerWidget->setLayout( layout );
layout->addWidget( mMinMaxWidget );
connect( mMinMaxWidget, SIGNAL( load( int, double, double, int ) ),
this, SLOT( loadMinMax( int, double, double, int ) ) );
connect( mMinMaxWidget, SIGNAL( load( int, double, double ) ),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use the new style connect here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taken into account

@rouault
Copy link
Contributor Author

rouault commented Dec 15, 2016

Does this also work in the live styling dock?

Good point. It didn't. Fixed

@rouault
Copy link
Contributor Author

rouault commented Dec 15, 2016

Nice work. How does stretch using current extent work if you only want to take current extent to get min max once ?

The "current canvas" extent is only taken into account when you press the Apply button of the dialog or dock widget. This is different from the "updated canvas" choice where each canvas extent change causes recomputation to be done.

@rouault
Copy link
Contributor Author

rouault commented Dec 15, 2016

Have you got any more unit tests incoming for this?

I've added a few tests for the non-UI parts

Copy link
Collaborator

@nyalldawson nyalldawson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good

mpLandsatRasterLayer->refreshContrastEnhancementIfNeeded( mpLandsatRasterLayer->renderer(), newExtent );
QCOMPARE( mpLandsatRasterLayer->renderer()->minMaxOrigin().limits(), QgsRasterMinMaxOrigin::MinMax );
double minVal = dynamic_cast<QgsMultiBandColorRenderer*>( mpLandsatRasterLayer->renderer() )->redContrastEnhancement()->minimumValue();
QVERIFY( fabs( initMinVal - minVal ) < 1e-5 );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use QGSCOMPARENEAR here to get nicer debugging if the test fails

@nirvn
Copy link
Contributor

nirvn commented Dec 16, 2016

@rouault , I can't compile your branch, I get the following make error:

/home/webmaster/dev/cpp/QGIS/src/core/raster/qgsrasterminmaxorigin.cpp: In member function ‘bool QgsRasterMinMaxOrigin::operator==(const QgsRasterMinMaxOrigin&) const’:
/home/webmaster/dev/cpp/QGIS/src/core/raster/qgsrasterminmaxorigin.cpp:43:64: error: ‘fabs’ was not declared in this scope
          fabs( mCumulativeCutLower - other.mCumulativeCutLower ) < 1e-5 &&

@nyalldawson
Copy link
Collaborator

@nirvn try changing it to qAbs

@nirvn
Copy link
Contributor

nirvn commented Dec 16, 2016

@nyalldawson , yeah, done that, waiting for a successful build to report back "all ok" :)

@nirvn
Copy link
Contributor

nirvn commented Dec 16, 2016

@rouault , ok, confirming fabs -> qAbs fixes the build.

Your PR appears to work quite well, good job. You'll need to improve the UI a bit through, as it fails to display properly in the style dock:
untitled

  • Glue accuracy to min /max (i.e. don't use a different grid column there)
  • For extent, either move the radio boxes to three separate rows (that might take too much vertical space), or use a combo box.

I love the updated canvas mode, fantastic job.

@nirvn
Copy link
Contributor

nirvn commented Dec 16, 2016

@rouault , more comments:

  • The singleband pseudocolor renderer has issues on my machine. The rendering takes ages (using a single LANDSAT-8 band), with intense CPU load.
  • The singleband gray UI also needs some fixing to behave well in style dock mode:
    untitled

@nirvn
Copy link
Contributor

nirvn commented Dec 16, 2016

@rouault , also, I noticed the absence of an "updated canvas" mode for the singleband pseudocolor. It'd be great to add that mode too both for consistancy across renderers, as well as practical uses when analyzing LiDAR data, etc.

It'd "simply" require to move the classification code out of UI into the renderer itself. It wasn't possible until recently, when I updated the renderer to store the source color ramp used to create the raster ramp.

This commit implements the improvements described at:
https://lists.osgeo.org/pipermail/qgis-developer/2016-September/044393.html

The QgsRasterMinMaxWidget now offers a seetting to specify that the statistics
should be computed each time the canvas extent changes.

Other changes:
- the content of the QgsRasterMinMaxWidget is now persistant.
- there is no longer any Load button. The global Apply / OK button of the raster
  properties dialog has this effect.
- the default "limits" for single band raster is now MinMax and not CumulativeCut
- the default "limits" can be configured for single band, multi band single byte and
  multi band multi byte
- "Strech using current extent" honours the "limits" instead of forcing min/max.
@rouault
Copy link
Contributor Author

rouault commented Dec 16, 2016

I've fixed :

  • the qAbs issue
  • the UI glitches in style dock mode
  • the 100% CPU (infinite cycle of notifications) effect with the pseudo color renderer when the style dock is enabled
  • added the "Updated canvas" possibility for pseudo color renderer to update the min/max values in the line edit

I don't feel familiar enough with the pseudo color render to do further changes. One thing I didn't do in particular is to auto-classify when the min/max are changed indirectly, because that could break customized classification done by the user (if that would be implemented some care should be taken not to emit the widgetChanged() signal if no changes are done, to avoid infinite notifications)

@rouault rouault merged commit 792873a into qgis:master Dec 16, 2016
@nirvn
Copy link
Contributor

nirvn commented Dec 17, 2016

@rouault , great job.

Re pseudocolor, customization classification == manual edits to the list? I think that should be overwritten if the min max is set to updated extent.

rouault added a commit that referenced this pull request Dec 23, 2016
…nfinite signal notifications.

Fixes #3871 (comment), ie switching between
renderers in the raster layer properties dialog or in the style dock result in non optimal
parameters, so better switch to default parameters that would be the ones used when
adding a layer of the new renderer type to the canvas. This issue already existed in 2.18

Also fixes a potential infinite notification cycle when having both the style dock and
layer properties dialog opened, and applying changes in the layer properties dialog.
(related to #3871).
@rouault
Copy link
Contributor Author

rouault commented Dec 23, 2016

following this set of commits, QGIS fails to renderer a multi band raster using single band gray renderer.

I could reproduce similar behaviour with 2.18 as well. Anyway should be fixed with 645f2c8

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants