The link2GI package tries to provide an easy entrance door for linking GRASS, SAGA GIS and QGIS as well as other awesome command line tools like the Orfeo Toolbox (OTB) for R users that are not operating system specialists or highly experienced GIS useres. It is a result of numerous graduate courseswith R-GIS beginners in the hostile world of university computer pools running under restricted Windows systems. It is is sometimes really cumbersome to get all necessary settings in a line. If have to do so on 20 ore so individual Windows Laptops you will get an idea why it could be comfortable to automize this procedure.
This vignette:
R has quite a lot of classes for storing and dealing with spatial data. For vector data the sp and recently the great sf packages are well known and the raster data world is widley covered by the raster package. Additionally external spatial data formats are interfaced by wrapping packages as rgdal or gdalUtils. For more specific links as needed for manipulating atmospheric modeling packages as ncdf4 are very helpful.
The spatial analysis itself is often supported by wrapper packages that integrate external libraries, command line tools or a mixture of both in an R-like syntax rgeos, geosphere, Distance, maptools, igraph or spatstat. It would be a never ending story to complete this list.
Despite all this capabilities of spatial analysis and data handling in the world of R, it can be stated (at least from a non-R point of view) that there is a enormous gap between R and the mature opensource Geographic Information System (GIS) and Remote Sensing (RS) software community. QGIS, GRASS GIS and SAGA GIS are providing a comprehensive, growing and mature collection of highly sophisticated algorithms. In most cases the algorithms are fast, stable and most of them are well proofed. Probavly most of the R users that are somehow related to the GI community know that there are some awesome good wrapper packages for bridging this gap. For GRASS GIS it is rgrass7 and for SAGA GIS the RSAGA package. The develoment of the RQGIS wrapper is the most recent outcome to get a simple access from the R side to the great QGIS command line interface.
Unfortunately most of these and other packages are not that easy to use. In case of RSAGA the main problem seems to be the fact that the SAGA GIS developers are not only changing the syntax and strategy of the command line interface (CLI) but also within a release the calls differ from OS to OS. So the maintenance of RSAGA is obviously laborious. Currently RSAGA supports the SAGA versions 2.0.4 - 2.2.3. On the other hand ias GRASS GIS well known for a sophisticated setup of the environment and the spatial properties of the database. It is not really simple to get an easy working temporary or permanent setup due to spatial and projection issues but even more caused by challenging system and environment settings. even more complicated these settings are pretty different for the major available Windows installer. To make it short it is a bit cumbersome to deal with all this stuff if one just want to start e.g. GRASS from the R commandline.
Linking means simply to provide all necessary environment settings as well as the full acess to the the command line APIs of the mentioned software tools. The strategy differs from software to software.
GRASS GIS has the most challenging requirements. It needs a bunch of envrionment and path variables as well as a correct setup of the geographical data parameters. The linkGRASS7() function tries to find all installations let you choose one and generate the necessary variables. As a result you can use both the rgrass7 package or the command line API of GRASS.
SAGA GIS is a bit easier to set up. The strategy is similar. The linkSAGA() function tries to find all SAGA installations, let you choose one and generate some global variables. You may use RSAGA if you run a SAGA version of 2.0.4 - 2.2.3. Nevertheless it is strongly recommended to use the R system() call to interface R with the saga_cmd API.
The Orfeo Toolbox (OTB) is a very powerful remote sensing toolbox. It is widely used for classifcation filtering and machine learning applications. You will find a lot of the implemented algorithm within different R packages but always much slower or restricted to small data chunks. The linkage is performed similar so that it is easy to use the command line API of the OTB. Currently there is no OTB wrapper available.
We will start with GRASS.
linkGRASS7() Initializes the session environment and the system pathes for an easy access to GRASS GIS 7.x. The correct setup of the spatial and projection parameters is automatically performed by using either an existing and valid raster, sp or sf object, or manually by providing a list containing the minimum parameters needed. These properties are used to initialize either a temporary or a permanent rgrass7 environment including the correct 'GRASS 7' data base structure.
The most time consuming part on 'Windows' Systems is the search process. This can easily take 10 or more minutes. To speed up this process you can also provide a correct parameter set. Best way to do so is to call manually searchGRASSW() for Windows or for 'Linux' searchGRASSX(). Then call linkGRASS7 with the version arguments of your choice.
The function linkGRASS7 tries to find all valid 'GRASS GIS' binaries by analyzing the startup script files of 'GRASS GIS'. After identifying the 'GRASS GIS' binaries all necessary system variables and settings will be generated and passed to a temporary R enviroment.
If you have more than one valid installation and run linkGRASS7() without arguments, you will be ask to select one.
require(link2GI)
require(sp)
data(meuse)
coordinates(meuse) <- ~x+y
proj4string(meuse) <-CRS("+init=epsg:28992")
require(sf)
meuse_sf = st_as_sf(meuse,
coords =
c("x", "y"),
crs = 28992,
agr = "constant")
Automatic search and find of GRASS binaries using the meuse sp data object for spatial referencing. This is the highly recommended linking procedure. NOTE: if more than one GRASS installation is found you have to choose.
linkGRASS7(meuse)
Assuming a typical standalone non-OSGeo4W installation and using the meuse sp data object for spatial referencing
linkGRASS7(meuse,c("C:/Program Files/GRASS GIS7.0.5","GRASS GIS 7.0.5","NSIS"))
Typical OSGeo4W64 installation using the meuse sp data object for spatial referencing
linkGRASS7(meuse,c("C:/OSGeo4W64","grass-7.0.5","osgeo4W"))
Choose manually the GRASS installation additionally using the meuse sf object for spatial referencing
linkGRASS7(meuse_sf, ver_select = TRUE)
Choose manually the GRASS installation and change the search location additionally using the meuse sf object for spatial referencing
linkGRASS7(meuse_sf, searchPath = "D:/")
Creating a permanent GRASS gisdbase (folder structure) at “~/temp3” with the standard mapset PERMANENT and the location named “project1”. For all spatial attributes use the the meuse sf object.
linkGRASS7(x = meuse_sf, gisdbase = "~/temp3",location = "project1")
Link to the permanent GRASS gisdbase (folder structure) at “~/temp3” with the standard mapset PERMANENT and the location named “project1”. For all spatial attributes use the the meuse sf object.
linkGRASS7(gisdbase = "~/temp3",location = "project1", gisdbase_exist = TRUE)
Setting up GRASS manually with spatial parameters of the meuse data
linkGRASS7(spatial_params = c(178605,329714,181390,333611,"+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +no_defs +a=6377397.155 +rf=299.1528128 +towgs84=565.4171,50.3319,465.5524,-0.398957,0.343988,-1.8774,4.0725 +to_meter=1"))
First of all we need some real data. In this this case the gridded 2011 micro zensus population data of Germany. It has some nice aspects. It is provided in a typical authority format, it is big enough and it is pretty instructicve for al lot of spatial analysis. We also have to download a meta data description file provided as an excel sheet for some informations about projection and data concepts.
# we need some packages
require(link2GI)
require(curl)
# first of all we create a project folder structure
link2GI::initProj(projRootDir = "~/link2GI_examples",
projFolders = c("data/","output/","run/"))
# set runtime directory
setwd(path_run)
# get some typical authority generated data
url<-"https://www.zensus2011.de/SharedDocs/Downloads/DE/Pressemitteilung/DemografischeGrunddaten/csv_Bevoelkerung_100m_Gitter.zip;jsessionid=294313DDBB57914D6636DE373897A3F2.2_cid389?__blob=publicationFile&v=3"
res <- curl::curl_download(url, "testdata.zip")
# unzip it
unzip(res,files = grep(".csv", unzip(res,list = TRUE)$Name,value = TRUE),junkpaths = TRUE,overwrite = TRUE)
fn <- list.files(pattern = "[.]csv$", path = getwd(), full.names = TRUE)
After downloading the data we will use it for some demonstration stuff. If you have a look the data is nothing than x,y,z with assumingly some projection information.
# get the filename
# fast read with data.table
xyz <- data.table::fread(paste0(getwd(),"/Zensus_Bevoelkerung_100m-Gitter.csv"))
head(xyz)
We can easy rasterize this data as it is intentionally gridded data.that means we have in at a grid size of 100 by 100 meters a value.
require(RColorBrewer)
require(raster)
require(mapview)
# clean dataframe
xyz <- xyz[,-1]
# rasterize it according to the projection
r <- raster::rasterFromXYZ(xyz,crs = sp::CRS("+init=epsg:3035"))
# map it
p <- colorRampPalette(brewer.pal(8, "Reds"))
# aet resolution to 1 sqkm
mapview::mapviewOptions(mapview.maxpixels = r@ncols*r@nrows/100)
mapview::mapview(r, col.regions = p, at = c(-1,10,25,50,100,500,1000,2500), legend = TRUE)
So far nothing new. Now we create a new but permanent GRASS gisbase using the spatial parameters from the raster object. The linkGRASS7 function performs a full search for one ore more valid GRASS installations. If a valid GRASS installation exists all parameter are setup und the package rgrass7 is linked.
Due to the fact that the gisdbase_exist is by default set to FALSE it will create a new structure according to the r object.
require(link2GI)
# initialize GRASS and set up a permanent structure
link2GI::linkGRASS7(x = r, gisdbase = "~/link2GI_examples",location = "microzensus2011")
Finally we can now import the data to the GRASS gisdbase using the rgass7 package functionality. First we must convert the raster object to GeoTIFF file. Any GDAL format is possible but GeoTIFF is very common and stable.
require(raster)
require(rgrass7)
# write it to geotiff
raster::writeRaster(r, paste0(getwd(),"/Zensus_Bevoelkerung_100m-Gitter.tif"), overwrite = TRUE)
# import raster to GRASS
rgrass7::execGRASS('r.external',
flags=c('o',"overwrite","quiet"),
input=paste0(getwd(),"/Zensus_Bevoelkerung_100m-Gitter.tif"),
output="Zensus_Bevoelkerung_100m_Gitter",
band=1
)
# check imported data set
rgrass7::execGRASS('r.info',
map = "Zensus_Bevoelkerung_100m_Gitter")
Let's do now the same import as a vector data set. First we create a sf object.
# xyz_sf = st_as_sf(xyz,
# coords = c("x_mp_100m", "y_mp_100m"),
# crs = 3035,
# agr = "constant")
#map points
# sf::plot_sf(xyz_sf)
The GRASS gisdbase already exists. So we tell it link2GRASS7 with setting gisdbase_exist=TRUE and import the xyz data as generic GRASS vector points.
require(sf)
require(sp)
require(link2GI)
data(meuse)
meuse_sf = st_as_sf(meuse,
coords = c("x", "y"),
crs = 28992,
agr = "constant")
w_gvec(x = meuse_sf,
obj_name = "meuse",
gisdbase = "~/link2GI_examples",
location = "meuse",
gisdbase_exist = FALSE
)
# check imported data set
rgrass7::execGRASS('v.info', map = "meuse")
A typical example is the usage of an already existing project data base in GRASS. GRASS organizes all data in an internal file structure that is known as gisdbase folder, a mapset and one ore more locations within this mapset. All raster and vector data is stored inside this structure and the organisation is performed by GRASS. So a typical task could be to work on data sets that are already stored in an existing GRASS structure