rsbivand / rgrass

Interpreted interface between the GRASS geographical information system and R
https://rsbivand.github.io/rgrass/
24 stars 8 forks source link

initGRASS home-parameter does not work in Windows (GISRC-environment) #5

Closed raff-k closed 2 years ago

raff-k commented 5 years ago

I am using the Cran-Version rgrass7_0.1-12. Under Windows I discoverd that the GISRC-environment is all the time stored as "junk"-file in the current working directory, even when the home-path is explicitly set. Moreover, the path to the junk-file is not properly set in the system-environment. Instead of the complete path, only "junk" is written (see Sys.getenv("GISRC")). This causes troubles when one is changing the working directory but still executing GRASS GIS operations.

By debugging, I discover, that at the beginning the path is properly set by Sys.setenv(GISRC = paste(Sys.getenv("HOME"), "\\.grassrc7", sep = "")). However, subsequently the information is overwritten by fn_gisrc <- "junk"followed by Sys.setenv(GISRC = fn_gisrc). Here, junk is automatically written to the current working directory (cat("GISDBASE:", getwd(), "\n", file = Sys.getenv("GISRC"))).

In the following a hopefully reproducible code to demonstrate the issue:

# ONLY IN WINDOWS

# load packages
if(!require("pacman")) install.packages("pacman")
pacman::p_load(rgrass7, sf, raster, link2GI, RQGIS)

# get a raster file from RQGIS package
dtm <- RQGIS::dem

# get pathes of GRASS GIS installation (can take a while)
# link2GI::findGRASS()

# this should be adapted according to version
my_default_GRASS7 <- c("C:/OSGeo4W64/","grass76","osgeo4W") # here GRASS GIS 7.6 (Windows)
my_default_GRASS7_path <- link2GI::paramGRASSw(my_default_GRASS7, FALSE)$gisbase_GRASS

# get start path of working directory
path.StartWD <- getwd()

# check if already a junk-file exists, and delete it if TRUE
if(file.exists(file.path(path.StartWD, "junk"))){
  cat("junk-file existed ... \n")
  file.remove(file.path(path.StartWD, "junk"))
} else {
  cat("junk-file do not exist ... \n")
}

# init GRASS GIS now via link2GI to set all necessairy pathes correctly
link2GI::linkGRASS7(x = dtm, 
                    default_GRASS7 = my_default_GRASS7, 
                    quiet = FALSE)

# Testing if junk file exist
file.exists(file.path(getwd(), "junk")) # [1] TRUE
file.exists(file.path(path.StartWD, "junk")) # [1] TRUE

# Test if rgrass7 can be executed
# ... this should deliver some result
rgrass7::gmeta()

# Let's create a new directory and change to it ...
path.TestChange <- file.path(getwd(), "Test_Change")
dir.create(path = path.TestChange, recursive = TRUE)

# ... change to path
setwd(path.TestChange)

# ... now we test again if rgrass7 can be executed
rgrass7::gmeta() # probably some warnings

# Warning messages:
#   1: In system(syscmd, intern = intern, ignore.stderr = ignore.stderr,  :
#                  running command 'g.region.exe -g -3' had status 1
#                2: In system(syscmd, intern = intern, ignore.stderr = ignore.stderr,  :
#                               running command 'g.proj.exe -j -f' had status 1

# let's init grass gis now via rgrass7::initGRASS()
rgrass7::initGRASS(gisBase = my_default_GRASS7_path, 
                   home = file.path(tempdir()), 
                   override=TRUE)

# let's check if home-file exists
file.exists(file.path(tempdir(), ".grassrc7")) # [1] FALSE
read.table(file = file.path(tempdir(), ".grassrc7")) # ... cannot open file

# ... it is not existing since junk file was automatically set to current working directory:
Sys.getenv("GISRC")
file.exists(file.path(getwd(), "junk")) # [1] TRUE

read.table(file = file.path(getwd(), "junk"))
# V1                                             V2
# 1      GISDBASE: C:/Users/TEST/AppData/Local/Temp/RtmpcRDllD
# 2 LOCATION_NAME:                               file305821664147
# 3        MAPSET:                                file30583764682
# 4     GRASS_GUI:                                           text

# now we have two junk files...
# ... one in path.TestChange
# ... one in path.StartWD

# check gmeta() in start directory
setwd(path.StartWD)
rgrass7::gmeta()

# gisdbase    C:/Users/TEST/AppData/Local/Temp/RtmpI1xUx8 
# location    file201426e36517 
# mapset      PERMANENT 
# rows        117 
# columns     117 
# north       8935384 
# south       8931775 
# west        794599.1 
# east        798208.6 
# nsres       30.85 
# ewres       30.85 
# projection  +proj=utm +south +no_defs +zone=17 +a=6378137 +rf=298.257223563 +towgs84=0,0,0,0,0,0,0 +to_meter=1

# check gmeta() in test directory
setwd(path.TestChange)
rgrass7::gmeta()

# gisdbase    C:/Users/TEST/AppData/Local/Temp/RtmpI1xUx8 
# location    file20143a7f3327 
# mapset      file201466c53e1c 
# rows        1 
# columns     1 
# north       1 
# south       0 
# west        0 
# east        1 
# nsres       1 
# ewres       1 
# projection  NA 

# Let's create a second directory and change to it ...
path.TestChange_2 <- file.path(path.StartWD, "Test_Change_2")
dir.create(path = path.TestChange_2, recursive = TRUE)
setwd(path.TestChange_2)

# gmeta() should output warnings again ....
rgrass7::gmeta()

# now set the complete path of the junk-file into the environment variable
Sys.setenv("GISRC" = file.path(path.StartWD, "junk")) # check first
Sys.getenv("GISRC") # check: should be a complete path now

# gmeta() should work again
rgrass7::gmeta()

# gisdbase    C:/Users/TEST/AppData/Local/Temp/RtmpI1xUx8 
# location    file201426e36517 
# mapset      PERMANENT 
# rows        117 
# columns     117 
# north       8935384 
# south       8931775 
# west        794599.1 
# east        798208.6 
# nsres       30.85 
# ewres       30.85 
# projection  +proj=utm +south +no_defs +zone=17 +a=6378137 +rf=298.257223563 +towgs84=0,0,0,0,0,0,0 +to_meter=1 
rsbivand commented 5 years ago

Could you please try install.packages("rgrass7", repos="http://R-Forge.R-project.org")? https://r-forge.r-project.org/scm/viewvc.php/pkg/rgrass7/R/initGRASS.R?root=spgrass&r1=55&r2=67 shows changes affecting the junk file. They were needed for OSGEO4W directory choices IIRC.

raff-k commented 5 years ago

Thank you for the quick reply. The issue I mentioned is based on the changes in yellow from line 115-121. I do not know the reason why you had to change, but I assume a working example could be:

fn_gisrc <- "junk"
if (isTRUE(file.access(Sys.getenv("HOME"), 2) == 0)) { 
# instead of: if (isTRUE(file.access(".", 2) == 0)) {
      Sys.setenv(GISRC = paste(Sys.getenv("HOME"), "\\.grassrc7", sep = "")) 
# Instead of: Sys.setenv(GISRC = fn_gisrc)
    }
    else {
      warning("working directory not writable, using tempfile for GISRC")
      Sys.setenv(GISRC = paste0(tempfile(), "_", fn_gisrc))
    }

I am wondering, if it is really necessairy to use the current working directory for the GISRC-file? ('"."')

rsbivand commented 5 years ago

The specific difficulty was with OSGEO4W settings. On unix-type systems (all but Windows), it would be usual to put project files in the current directory, not $HOME. I cannot remember whether OSGEO4W didn't set HOME to a non-writable directory. I will not have access to a Windows system until the end of next week to try things out.

rsbivand commented 5 years ago

Could you please be more explicit about the parallellising issue? How many R or GRASS sessions do you intend to run and which is controlling what?

rsbivand commented 5 years ago

And we can carry on using this issue, but rgrass7 does live on R-Forge, not here.

rsbivand commented 5 years ago

@tim-salabim : Could we try to coordinate this, as link2GI is implicated? Re.: https://github.com/r-spatial/discuss/issues/18 ? I expect to be working on rgrass7 until mid August among other things. This is also https://github.com/r-spatial/link2GI/issues/20 @gisma

tim-salabim commented 5 years ago

Of course, are you thinking of migrating rgrass7 from R-Forge to github? Both you and @gisma are members of r-spatial already. Following each others updates to the repos should be easier that way

rsbivand commented 5 years ago

Yes, migration to github sooner, and r-spatial when sf/stars ready and backwards sp-compatible (that is the aim, anyway).

gisma commented 5 years ago

I have it on screen but no stable internet during the weekend...

raff-k commented 5 years ago

Could you please be more explicit about the parallellising issue? How many R or GRASS sessions do you intend to run and which is controlling what?

I plan to run for each worker (or core) a unique location to account for the peaceful coexistence. Since rgrass7::initGRASS() initiates the GISRC-environment (as junk-file) all the time in the current working directory, the GISRC's of the different locations overwrite each other. This causes errors initializing GRASS GIS in parallel-processing. Even if one set a path by the home-parameter, the junk-file is written to the current working directory. To set a proper and unique GISRC-file for each location, one has to switch the current working directory to a specified folder every time before executing rgrass7::initGRASS(). However, this behaviour is only the case for windows.

And we can carry on using this issue, but rgrass7 does live on R-Forge, not here.

That's great. Thank you :-)

rsbivand commented 5 years ago

OK, thanks, I'll think about how to disentangle this.