[GRASS-user] randomize the position of a raster map

Hi all,

I have a landcover maps, and I need to randomize the position of them, keeping all the pixels on the new raster map.

Is there a command that can do this within GRASS?

best

···

Miltinho - mcr@rc.unesp.br
Laboratório de Ecologia Espacial e Conservação - LEEC
Depto de Ecologia - UNESP - Rio Claro
Av. 24A, 1515- Bela Vista
13506-900 Rio Claro, SP, Brasil

Fone: +55 19 3526-9647 (office) 19 3526-9680 (lab)
Cel: 19 9853-3220 / 19 9853-5430

Depto Ecologia http://ib.rc.unesp.br/#!/departamentos/ecologia/
PG ECO & BIODIV http://ib.rc.unesp.br/#!/departamentos/ecologia/pos-graduacao-em-ecologia-e-biodiversidade/

CV http://buscatextual.cnpq.br/buscatextual/visualizacv.do?id=K4792988H6&mostrarNroCitacoesISI=true&mostrarNroCitacoesScopus=true

Google citations http://scholar.google.com/citations?user=OWX_2eAAAAAJ

On 08/12/14 18:26, Milton Ribeiro wrote:

Hi all,

I have a landcover maps, and I need to randomize the position of them,
keeping all the pixels on the new raster map.

IIUC, you actually want to randomize the categories of pixels where categories are land covers and there is a constraint that you want to keep the same number of pixels per category. Is that correct ?

Is there a command that can do this within GRASS?

You could use r.random following a procedure something like this:

create a raster (mymask) where all cells are non-null

for each category of land cover,
  get cat and percentage of cover of that cat (e.g. via r.stats)
  run r.random, using cover=mymask and n=percentage of cover
  modify mymask so that the cells attributed in the previous run of r.random get set to null to make them unavailable in the next run

There is just one issue: the cover option in r.random provokes a check if the randomly selected cell is in the cover area or not. If not, it is not used, but no replacement is found, so if you use cover= the percentage value in n= is not respected... Ideally this should be corrected to while cell number X is not within the cover, find a new cell. See [1] for an old discussion about this.

Attached is a bash script that tries to work around this issue and works more or less for me (at least with the "landuse dataset in the simplified NC dataset). Certainly not perfect, but maybe you can build on that.

Another option might be something like this:

Knowing that:

r.stats -ncp landuse --quiet
1 73077 29.31%
2 2137 0.86%
3 25518 10.24%
4 16829 6.75%
5 126265 50.64%
6 5303 2.13%
7 194 0.08%

use the random generator in r.mapcalc

r.mapcalc "eval(random = rand(0.0,1.0)); landuse_randomized_mapcalc = if(random<=0.2931,1, if(random>0.2931 && random <=0.3017,2,if(random>0.3017 && random <=0.4041, 3, if(random>0.4041 && random<=0.4716, 4, if(random > 0.4716 && random <=0.9780, 5, if(random>0.9780 && random <=0.9993, 5, 6))))))" --o

The result is not perfect in terms of cell counts, but close:

r.stats -ncp landuse_randomized_mapcalc --quiet
1 73402 29.46%
2 2061 0.83%
3 25215 10.12%
4 16982 6.82%
5 131484 52.78%
6 180 0.07%

Moritz

[1] https://trac.osgeo.org/grass/ticket/1082
  

(attachments)

randomize_raster_categories.sh (773 Bytes)

Hi Moritz,

I like your tips… I will try this.

Thanks!

milton

···

2014-12-09 12:55 GMT-02:00 Moritz Lennert <mlennert@club.worldonline.be>:

On 08/12/14 18:26, Milton Ribeiro wrote:

Hi all,

I have a landcover maps, and I need to randomize the position of them,
keeping all the pixels on the new raster map.

IIUC, you actually want to randomize the categories of pixels where categories are land covers and there is a constraint that you want to keep the same number of pixels per category. Is that correct ?

Is there a command that can do this within GRASS?

You could use r.random following a procedure something like this:

create a raster (mymask) where all cells are non-null

for each category of land cover,
get cat and percentage of cover of that cat (e.g. via r.stats)
run r.random, using cover=mymask and n=percentage of cover
modify mymask so that the cells attributed in the previous run of r.random get set to null to make them unavailable in the next run

There is just one issue: the cover option in r.random provokes a check if the randomly selected cell is in the cover area or not. If not, it is not used, but no replacement is found, so if you use cover= the percentage value in n= is not respected… Ideally this should be corrected to while cell number X is not within the cover, find a new cell. See [1] for an old discussion about this.

Attached is a bash script that tries to work around this issue and works more or less for me (at least with the "landuse dataset in the simplified NC dataset). Certainly not perfect, but maybe you can build on that.

Another option might be something like this:

Knowing that:

r.stats -ncp landuse --quiet
1 73077 29.31%
2 2137 0.86%
3 25518 10.24%
4 16829 6.75%
5 126265 50.64%
6 5303 2.13%
7 194 0.08%

use the random generator in r.mapcalc

r.mapcalc “eval(random = rand(0.0,1.0)); landuse_randomized_mapcalc = if(random<=0.2931,1, if(random>0.2931 && random <=0.3017,2,if(random>0.3017 && random <=0.4041, 3, if(random>0.4041 && random<=0.4716, 4, if(random > 0.4716 && random <=0.9780, 5, if(random>0.9780 && random <=0.9993, 5, 6))))))” --o

The result is not perfect in terms of cell counts, but close:

r.stats -ncp landuse_randomized_mapcalc --quiet
1 73402 29.46%
2 2061 0.83%
3 25215 10.12%
4 16982 6.82%
5 131484 52.78%
6 180 0.07%

Moritz

[1] https://trac.osgeo.org/grass/ticket/1082

Miltinho - mcr@rc.unesp.br
Laboratório de Ecologia Espacial e Conservação - LEEC
Depto de Ecologia - UNESP - Rio Claro
Av. 24A, 1515- Bela Vista
13506-900 Rio Claro, SP, Brasil

Fone: +55 19 3526-9647 (office) 19 3526-9680 (lab)
Cel: 19 9853-3220 / 19 9853-5430

Depto Ecologia http://ib.rc.unesp.br/#!/departamentos/ecologia/
PG ECO & BIODIV http://ib.rc.unesp.br/#!/departamentos/ecologia/pos-graduacao-em-ecologia-e-biodiversidade/

CV http://buscatextual.cnpq.br/buscatextual/visualizacv.do?id=K4792988H6&mostrarNroCitacoesISI=true&mostrarNroCitacoesScopus=true

Google citations http://scholar.google.com/citations?user=OWX_2eAAAAAJ

Nice suggestions Moritz. Another alternative to accomplish this is to combine r.surf.random and r.recode (instead of recode, one can also use r.reclass). I haven’t tried it, but this might be faster for large maps or with many categories?

r.surf.random flags=i, output=LUCrandom min=0 max=10000
r.recode input=LUCrandom output=LUCrandom2 << EOF
0:2931:1
2932:3017:2
3018:4041:3
4042:4716:4
4717:9780:5
9781:9993:6
9994:10000:7
EOF

···

On Tue, Dec 9, 2014 at 3:55 PM, Moritz Lennert <mlennert@club.worldonline.be> wrote:

On 08/12/14 18:26, Milton Ribeiro wrote:

Hi all,

I have a landcover maps, and I need to randomize the position of them,
keeping all the pixels on the new raster map.

IIUC, you actually want to randomize the categories of pixels where categories are land covers and there is a constraint that you want to keep the same number of pixels per category. Is that correct ?

Is there a command that can do this within GRASS?

You could use r.random following a procedure something like this:

create a raster (mymask) where all cells are non-null

for each category of land cover,
get cat and percentage of cover of that cat (e.g. via r.stats)
run r.random, using cover=mymask and n=percentage of cover
modify mymask so that the cells attributed in the previous run of r.random get set to null to make them unavailable in the next run

There is just one issue: the cover option in r.random provokes a check if the randomly selected cell is in the cover area or not. If not, it is not used, but no replacement is found, so if you use cover= the percentage value in n= is not respected… Ideally this should be corrected to while cell number X is not within the cover, find a new cell. See [1] for an old discussion about this.

Attached is a bash script that tries to work around this issue and works more or less for me (at least with the "landuse dataset in the simplified NC dataset). Certainly not perfect, but maybe you can build on that.

Another option might be something like this:

Knowing that:

r.stats -ncp landuse --quiet
1 73077 29.31%
2 2137 0.86%
3 25518 10.24%
4 16829 6.75%
5 126265 50.64%
6 5303 2.13%
7 194 0.08%

use the random generator in r.mapcalc

r.mapcalc “eval(random = rand(0.0,1.0)); landuse_randomized_mapcalc = if(random<=0.2931,1, if(random>0.2931 && random <=0.3017,2,if(random>0.3017 && random <=0.4041, 3, if(random>0.4041 && random<=0.4716, 4, if(random > 0.4716 && random <=0.9780, 5, if(random>0.9780 && random <=0.9993, 5, 6))))))” --o

The result is not perfect in terms of cell counts, but close:

r.stats -ncp landuse_randomized_mapcalc --quiet
1 73402 29.46%
2 2061 0.83%
3 25215 10.12%
4 16982 6.82%
5 131484 52.78%
6 180 0.07%

Moritz

[1] https://trac.osgeo.org/grass/ticket/1082


grass-user mailing list
grass-user@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/grass-user