Wednesday, December 4, 2013

Ubuntu Precise, QGIS, GRASS and r.denoise

If you are interested in making your own shaded relief in QGIS, you may want to know about a GRASS module called r.denoise.

r.denoise (as explained more at length here), removes the random noise from a digital elevation model. As a result, when you generate a shaded relief image from the DEM it doesn't show as many small texture features.

Shaded relief of a portion of Canadian topographic map 093L14 (Smithers) generated with GRASS's module r.shaded.relief. At left, shaded relief from regular CDED DEM, and, at right, from CDED DEM denoised with r.denoise. Denoising parameters in this case were 5 iterations at a tolerance of 0.93.
The trick is that, although under Ubuntu Precise it's easy to install QGIS and GRASS (packages qgis and qgis-plugin-grass), r.denoise is not a standard module in GRASS. It's an addon. There are many wonderful GRASS addons (see a list here), but installing a GRASS addon when you did not compile GRASS yourself (i.e., you installed it through a precompiled package, as one tends to do under Ubuntu), requires a few extra steps. It can be done, however!

I recently struggled through installing r.denoise, and I was unable to find complete instructions on the web, so I thought I would explain here how I did it.

I'll assume that you are running Ubuntu Precise, and that you already have QGIS 2 and the GRASS plugin installed, and that you know how to use them.

Preparation

There are four things you will need before you can install r.denoise:
  • package grass-dev (which will in turn require package grass)
  • package subversion
  • the mdenoise utility
  • a patch in a makefile that comes as part of grass-dev (apparently you will not need this if you have grass version >=6.4.2, but at this point Ubuntu has 6.4.1)
Phase 1: The packages grass-dev and subversion you can install through the synaptic package manager.

Phase 2: To install mdenoise,
  1. go to the Cardiff University site on the Filtering and Processing of Irregular Meshes with Uncertainties  and downlaod mdsource.zip
  2. unzip it into a temporary folder, e.g., on your desktop
  3. open a terminal in that folder and compile mdenoise with:
  4. $ g++ -o mdenoise mdenoise.cpp triangle.c
  5. move (as root or using sudo)  the new file that appears, "mdenoise," into /usr/bin:
$ sudo mv mdenoise /usr/bin/

Phase 3: to patch Platform.make file in /usr/lib/grass64/include/Make, run the following command:

$ sudo sed -i -e 's+^\(GRASS_HOME[ ]*=\) /build/.*+\1 ${INST_DIR}+' \
-e 's+^\(RUN_GISBASE[ ]*=\) /build/.*+\1 ${INST_DIR}+' \
/usr/lib/grass64/include/Make/Platform.make
 
OK, now you're ready to install the addon r.denoise.

Installing r.denoise itself

1. Start QGIS and make sure the GRASS plugin in loaded. If you haven't already discovered it, the GRASS menu is under the "Plugins" menu.

2. Open a GRASS mapset, so that the GRASS toolbox will be available: Plugins>GRASS>Open mapset, or the corresponding button on the GRASS toolbar. (If you need to create a GRASS mapset first, a set of getting-started-with-GRASS instructions are here.)

3. Open the GRASS Tools: Plugins>GRASS>Open GRASS Tools, or the corresponding button on the GRASS toolbar.

4. Open a GRASS shell. You can find this at the top of the Modules Tree ("Modules Tree " tab), or search for it ("shell") on the Modules List tab. A GRASS shell opens as a fourth tab in the GRASS window. In this shell window, Ctrl-Shift-C and Ctrl-Shft-V act as Copy and Paste, just as in a regular terminal window.

5. In the GRASS shell, type:
$ g.extension extension=r.denoise svnurl=http://svn.osgeo.org/grass/grass-addons/grass6/
This will launch a process of downloading the source code for the addon via subversion, compiling it, and then installing the executable.

Unfortunately, if you're like me, you will get this:

Fetching from GRASS-Addons SVN (be patient)...
A    r.denoise/description.html
A    r.denoise/r.denoise
A    r.denoise/Makefile
 U   r.denoise
Checked out revision 58345.
Compiling ...
mkdir -p /usr/lib/grass64/bin.x86_64-pc-linux-gnu
mkdir: cannot create directory `/usr/lib/grass64/bin.x86_64-pc-linux-gnu': Permission denied
make: *** [/usr/lib/grass64/bin.x86_64-pc-linux-gnu] Error 1
ERROR: Compilation failed, sorry. Please check above error messages.

In short, GRASS does not have permission to create this directory it wants (/usr/lib/grass64/bin.x86_64-pc-linux-gnu). I tried a number of workarounds. Running GRASS as root does not help. Attempting to 'sudo' this g.extension command does not work. Finally, I simply created the directory myself from within the GRASS shell by typing:

 $ sudo mkdir /usr/lib/grass64/bin.x86_64-pc-linux-gnu

I know this looks an ugly and desperate act, but it leads to success just down the road, so bear with me.


Note that all I had to do was copy the mkdir line from the output above (with Ctrl-Shift-C), paste it in as the next command (Ctrl-Shift-V), hit the Home key to jump to the front of the command line, type 'sudo' and hit Enter.

Now run the g.extension command again (tap up-arrow until it reappears as you entered it before), and get a similar error for another directory it can't create:

Fetching from GRASS-Addons SVN (be patient)...
A    r.denoise/description.html
A    r.denoise/r.denoise
A    r.denoise/Makefile
 U   r.denoise
Checked out revision 58345.
Compiling ...
mkdir -p /usr/lib/grass64/dist.x86_64-pc-linux-gnu/include/grass
mkdir: cannot create directory `/usr/lib/grass64/dist.x86_64-pc-linux-gnu': Permission denied
make: *** [/usr/lib/grass64/dist.x86_64-pc-linux-gnu/include/grass] Error 1
ERROR: Compilation failed, sorry. Please check above error messages.

Repeat the process of creating the new subdir by hand.

$ sudo mkdir -p /usr/lib/grass64/dist.x86_64-pc-linux-gnu/include/grass

However, this time change the permissions to world-writeable on this new subdir. g.extension is going to want to create six more sub-directories under it, so this will save you significant time:
$ sudo chmod -R 777 /usr/lib/grass64/dist.x86_64-pc-linux-gnu/

Running the g.extension command a third time you will now get a long output:

Fetching from GRASS-Addons SVN (be patient)...
A    r.denoise/description.html
A    r.denoise/r.denoise
A    r.denoise/Makefile
 U   r.denoise
Checked out revision 58345.
Compiling ...
mkdir -p /usr/lib/grass64/dist.x86_64-pc-linux-gnu/lib
mkdir -p /usr/lib/grass64/dist.x86_64-pc-linux-gnu/bin
mkdir -p /usr/lib/grass64/dist.x86_64-pc-linux-gnu/etc
mkdir -p /usr/lib/grass64/dist.x86_64-pc-linux-gnu/driver
mkdir -p /usr/lib/grass64/dist.x86_64-pc-linux-gnu/driver/db
mkdir -p /usr/lib/grass64/dist.x86_64-pc-linux-gnu/fonts
if [ ! -d /usr/lib/grass64/dist.x86_64-pc-linux-gnu/scripts ]; then mkdir -p /usr/lib/grass64/dist.x86_64-pc-linux-gnu/scripts; fi
/usr/bin/install -c  r.denoise /usr/lib/grass64/dist.x86_64-pc-linux-gnu/scripts/r.denoise
make htmlscript scriptstrings
[...and a whole lot of other stuff, including errors...]

This is good news: your script has been created and it's at /usr/lib/grass64/dist.x86_64-pc-linux-gnu/scripts/r.denoise. (Note: we're not going to get the documentation for the module. That's what all the final errors are about. Haven't been able to solve this part yet.)


As a final step, it's up to you (using sudo) to move it to /usr/lib/grass64/scripts:

$ sudo mv /usr/lib/grass64/dist.x86_64-pc-linux-gnu/scripts/r.denoise /usr/lib/grass64/scripts/

Make sure it's executable, and if it's not you can make it that way with

$ sudo chmod +x /usr/lib/grass64/scripts/r.denoise

r.denoise is now accessible to you through the GRASS shell by typing:
$ r.denoise

It'll open a nice little GUI and let you get started denoising.


One final note, probably unnecessary to seasoned GRASS users. When r.denoise asks you for a raster input map, you can pick from the current mapset using the dropdown. It'll insert the name of the map with an @ sign and then the mapset name, something like "mymap@mymapset". But when it asks for "Denoised raster output map," put in a new filename without the "@mymapset".

Happy denoising!