Monthly Archives: February 2017

Today I wanna share a solution for a problem we faced during the implementation of a tool for our QGIS plugin, DsgTools. The tool in question captures the signal featureAdded to get access to the newly created features for a particular QgsVectorLayer and change their attributes.

But, during our code testing we found a major problem. During the edition, when the undo button was pressed QGIS crashed big time!

By studing the link above and some other related, we have discovered that our function connected to featureAdded was messing things up, but why? Sure, we have learned some “kludges” or like some might say “McGyver Programming Stunts” to solve the problem, but what is the magic that happens when a user finishes adding a feature in QGIS? We need to understand that in order to code in an elegant way!

First of all, featureAdded() is triggered:

self.iface.actionAddFeature().trigger()

This triggers QgsMapToolAddFeature::addFeature which does the following

Ok, on one hand I want to manipulate feature’s attributes when they are added, but on the other hand, if I try to do so, I’ll mess up the undo stack. How should we proceed? What if I only peep while QGIS does its magic and then I barge in and do my own stuff? So I have to have one slot connected to featureAdded signal just to let me know which features should I visit on the editBuffer and another slot connected to editCommandEnded signal, so that I am sure that the undoStack is properly built allowing me to revisit the added features to change its attributes.

Lets consider that I want to perform a pan-sharpening using this following images:

Radar image

Classified image

Using Orfeo toolbox I can achieve the following results: (Bayes, LMVM and RCS respectively)

Bayes algorithm

LMVM algorithm

RCS algorithm

Looking at the results made by Orfeo we can choose the RCS output as the best looking pan-sharpened image. In my opinion, it seems to get more details of that part of the land surrounded by water on top of the image, don’t you agree?

Now, the other 2, Bayes and LMVM outputs don’t look quite good in my humble opinion. The Bayes output delivered almost no change and the LMVM output seems a bit blurred.

Considering this, you can try to perform a pan-sharpening operation using HSV fusion, but this is not available neither in QGIS (natively) nor in Orfeo toolbox.

So, having that in mind, my co-workers and I decided to develop a script to perform pan-sharpening using HSV fusion. The result of our work is available as a tool in our QGIS plugin called DSG Tools (https://plugins.qgis.org/plugins/DsgTools/). In another another opportunity I will explain more about DSG Tools.

DSG Tools is a QGIS plugin developed by the Geographic Service at Brazilian Army. It was developed to make it possible to acquire vector data in QGIS in accordance to the Brazilian Geospatial Vector Data Structure, but besides that, DSG Tools provides a considerable toolbox that allow among other things, perform pan-sharpening using HSV fusion.

The script we made can be installed into QGIS’ toolbox and it will be available in a group called DSG as we can see next:

Well, starting the script and setting its parameters (remember to superimpose the images prior the fusion – Orfeo has a tool for this) we can achieve the following result:

In my opinion, the pan-sharpened image generated by our HSV fusion script seems very close to the real terrain. Let’s now compare Orfeo’s RCS output and our HSV fusion output side by side:

RCS algorithm

HSV fusion by DSG Tools

Which one would you choose? I would choose the HSV fusion… But remember, this is just my opinion…

Maybe you’ve already needed to perform a decision tree classification in some point in your GIS life. You might have used ENVI’s decision tree to do the job, right? But, what about QGIS? Can we achieve the same results using QGIS processing? Definitely yes!!!

Today I’ll gonna show how this can be simple.

Imagine you want to classify this image:

Using this one to help filter the land cover:

On ENVI, this can be done with a decision tree like this one (one of my co-workers made it):

Ok, we can see that the decision tree uses several conditions to discover what pixels it should classify in a specific class. This conditions are translated to GRASS using this:

if(x,a,b) a if x not zero, b otherwise

Where “x” is a condition to be followed.

So, to classify water (let’s say pixel value 0) to a class with value 5 and classify everything else to 255 we need to make this expression if(x,5,255), where x is the condition (e.g. image==0).

Quite easy, right?

Moving forward, with more levels (like in the decision tree above), we need to use nested if conditions (i.e if conditions inside another if condition).

So, the next step is to open the processing toolbox in QGIS and search for r.mapcalculator to open the following dialog:

We can choose several images (A, B, and so on…). In my case, I’ll choose Raster Layer A and Raster Layer B (the first two images in this article). Inside the formula I’ll insert my nested if conditions taken from my decision tree, as follows:

With this set, I just need to to click on “Run” and wait for my classified image. By the way, the process is quite fast thanks to GRASS…

As we can see, the results are identical (another point for QGIS and GRASS for the awesome results they deliver together!!!). Below, on the right side we have the QGIS’ result and on the left side we have ENVI’s result (I made a small subset to make it easier to check both results).