[GRASSLIST:2923] Re: Puzzling mapcalc command

SWlab swlab at cornell.edu
Fri Mar 12 12:28:01 EST 2004


[Thursday 11 March 2004 21:14] From Glynn Clements
> SWlab wrote:
> > I want to compute some maps with mapcalc (GRASS53 v2004/03.. on a SuSE
> > box). Depending on the way I parse the info to the command I have results
> > or none

> Actually, I'm slightly surprised that r.mapcalc actually made it to
> the last line without reporting an error. In retrospect, I can see
> why; however, r.mapcalc should probably be changed to prohibit certain
> aspects of the above. In particular, it should probably prohibit using
> an identifier on the LHS of an assignment after it has occurred
> elsewhere.

Glynn, thanks a lot for your enlighting answer. For a bit more background:
I'm porting a set of bash scripts to perl. The bash scripts were basically a 
succession of calls to "r.mapcalc": maps were then evaluated at once, and 
everything worked fine. Except of course that I kept on calling "r.mapcalc", 
and I assume that there should be some initialization each time I call the 
command (I don't speak C, so the sources are not really meaningful to me).

So I thought it'd be quicker (and more elegant) to put all my calls into one 
big string, and call mapcalc just once (with the small function below). Fatal 
mistake as you explained it so well... It seems that a workaround would be to 
create shortr command lines, making sure the maps are created before using 
them...

Is there any alternative to "r.mapcalc" to create/modify rasters in scripts ? 
I thought about using PDLs in Perl, but the interaction with GRASS has to be 
optimized to be really useful (I started using r.in.ascii/r.out.ascii to 
read/write GRASS maps to/from PDLs, but the process is a bit too long...). Of 
course, not talking C is a handicap, and I'm not really keen on using  
FORTRAN either... Any idea would be welcomed.

Thanks  alot




# A Perl call to mapcalc ########################
sub rmapcalc() {
    my $command=shift;
    for ($command) {
        s/ +//g;            # Strips multiple spaces
        s/(?<!\n)\n//g;     # Suppress NL in middle of a line
    };
    croak "ERROR: cannot fork: $!" unless defined(my $pid=open(GRASS,"|-"));
    my $tmpfile=".tmpsmdr";
    if($pid){
        print GRASS "$command\nexit\n";
        close(GRASS) or do { print "\nERROR with 'r.mapcalc' :\n";
                             print "$command\nexit\n";
                             open(X,"<$tmpfile") or die "Can't find 
$tmpfile:$!";
                             while(<X>){print $_};
                             croak "Exit...";
                            };
        unlink($tmpfile); }
    else {
        exec("r.mapcalc 2>$tmpfile") or
            croak "ERROR: can't execute 'r.mapcalc': $!";
    };
    return;
};

-- 
Soil & Water Laboratory
Dept. of Biological & Environmental Engineering
Cornell University
ITHACA, NY 14853
Tel: (607)255.2463




More information about the grass-user mailing list