---
title: "Basic Usage of NLMR"
author: "Marco Sciaini & Craig E.Simpkins"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
bibliography: Citations.bib
vignette: >
  %\VignetteIndexEntry{Basic Usage of nlmR}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r global_options, include=FALSE}
library(raster)
library(NLMR)
```

`NLMR` is a `R` package designed to generate neutral landscape models (NLMs), 
simulated landscapes used to explore landscape scale ecological patterns and 
processes. The `NLMR` package was designed with a similar philosophy to the 
Python package `NLMpy` [see @EtheringtonNLMR2015], offering a general numeric 
framework allowing for a high degree of flexibility. Most of the common NLMs, 
as described by the relevant literature, can be produced using NLMR. 
Additionally, NLMR allows users to merge multiple landscapes, classify landscape
elements categorically and measure basic landscape level metrics. All NLMs 
produced take the form of two-dimensional raster arrays with specified row and 
column dimensions and cell values ranging between 0 and 1. By returning raster 
arrays, NLMs are easily integrated into the workflow of many useful spatial
analysis packages, notably the `raster` package.

## Basic landscape generation

`NLMR` supplies 16 NLM algorithms. The algorithms differ from each other in 
spatial auto-correlation, from no auto-correlation (random NLM) to a constant 
gradient (planar gradients) [see @Palmer1992].  

The 16 NLM algorithms are:

1. distance gradient
1. edge gradient  
1. hierarchical curdling
1. wheyed hierarchical curdling
1. midpoint displacement 
1. neighbourhood clustering
1. planar gradient  
1. random  
1. random cluster nearest-neighbour 
1. random curdling
1. random element 
1. random mosaic fields
1. random polygonal landscapes
1. random percolation  
1. random rectangular cluster 
1. spatially correlated random fields (Gaussian random fields)  
1. two-dimensional fractional Brownian motion

The basic syntax used to produce a NLM landscape is:
```
nlm_modeltype(ncol, nrow, resolution, ...)
```
    
For example, to produce a simple random neutral landscape one could use the 
following code:

```{r, fig.height=7, fig.width=7, fig.align='center'}
 x <- NLMR::nlm_random(20,20)
 NLMR::util_plot(x)
```



## Merging landscapes

Multiple NLM rasters can be merged or merged together to create new landscape 
patterns. A single primary or base raster can be merged with any number of 
additional secondary rasters, with optional scaling factors used to control the 
influence of the secondary rasters.  

The `util_merge` function is used to merge the rasters as in the example below:

```{r, fig.height=7, fig.width=7, fig.align='center'}
  #Create primary landscape raster
  pL <- NLMR::nlm_edgegradient(ncol = 100,
                               nrow = 100)

  NLMR::util_plot(pL)

  #Create secondary landscape rasters
  sL1 <- NLMR::nlm_distancegradient(ncol = 100,
                                    nrow = 100,
                                    origin = c(10, 10, 10, 10))
  sL2 <- NLMR::nlm_random(ncol = 100,
                          nrow = 100)

  mL1 <- NLMR::util_merge(pL,
                          c(sL1, sL2),
                          scalingfactor = 1)
  
  NLMR::util_plot(mL1)
```

## Classifying categories

Landscape rasters generated by `NLMR` contain continuous values between 0 and 1,
though these can be converted into categorical values using `util_classify`. The
number of classes and the proportion of the NLM raster assigned to each class is
determined using a `weighting` vector. If the weighting vector does not sum to 
1, the sum of the weightings is divided by the number of vector elements and 
these are used to define the class proportions. By default classes are numerical
starting from 1. If non-numerical levels are required, `level_names` can be 
specified. These classes can be plotted by selecting `discrete = TRUE` in 
`util_plot`. The number of cells contained by each class can be calculated using
`metric_area`.

```{r fig.height=7, fig.width=7, fig.align='center'}
nr <- NLMR::nlm_randomcluster(ncol = 50,
                              nrow = 50,
                              resolution = 1,
                              neighbourhood = 4,
                              p = 0.5)
                              
weighting <- c(0.5, 0.25, 0.25)

cr <- NLMR::util_classify(nr,
                          weighting = weighting,
                          level_names = c("L1", "L2", "L3"))

NLMR::util_plot(cr, discrete = TRUE)

NLMR::metric_area(cr)
```

## Handling Raster* Objects in R

### Basics
The `raster` package, the major framework for `NLMR`,  is built around a 
number of classes, most importantly the `RasterLayer`, `RasterBrick`, and `RasterStack` classes. The latter two basically comprising collections of multiple `RasterLayers` with the same spatial extent and resolution.

A `RasterLayer` is defined by its spatial dimensions (number of rows, number of 
columns and resulting number of cells) and its spatial extent. These two
parameters define the spatial resolution of the layer.

A `RasterLayer` can be manually created as follows:

```{r raster-example, message=FALSE, warning=FALSE, cache=TRUE}
library(raster)
r <- raster(ncol=10, nrow=10, xmn=0, xmx=100, ymn=0, ymx=100)
r
```

However, the raster created is empty, the cells containing no values. We can add values using the following code:

```{r raster-example2, dependson='raster-example', message=FALSE, warning=FALSE, cache=TRUE}
library(raster)
values(r) <- runif(ncell(r))
r
```

By running the above code we have just created one of the most simple NLMs - a completely
random landscape.

To visually examine the created `RasterLayer`, we can use `raster`'s built-in plotting function (
<small> but recommend to the use of NLMR::util_plot, for aesthetic and viridis reasons
</small>):

```{r dependson='raster-example2', message=FALSE, warning=FALSE, fig.height=7, fig.width=7, fig.align='center'}
raster::plot(r)
```

In landscape ecology it is quite usual to try and infer ecological dynamics using multiple environmental datasets derived from the same geographical area.
The `raster` packages uses `RasterStack` and `RasterBrick` for this kind of multi-layer data.

`RasterStack` is basically a list of `RasterLayer` with the same spatial extent 
and resolution. `RasterBrick`, however, is a truly multi-layered object. This 
means that all layer share a single reference for dimensions and extent (which often results in it being more efficient to process a `RasterBrick` than a `RasterStack`).

```{r dependson='raster-example2', message=FALSE, warning=FALSE, fig.height=7, fig.width=7, fig.align='center'}
r2 <- r * (abs(0.5 - r) * -2) + 1
r3  <- NLMR::util_classify(r, c(0.5, 0.5))
s <- raster::stack(r, r2, r3)
s
raster::plot(s)
```

### Manipulation

#### Dimensions, resolution and extent

The dimensions, resolution and extent of a `Raster*` object can be changed:

```{r dependson='raster-example', message=FALSE, warning=FALSE}
r <- raster(ncol=10, nrow=10, xmn=0, xmx=100, ymn=0, ymx=100)
dim(r)
ncol(r) <- 42
dim(r)
```

```{r dependson='raster-example', message=FALSE, warning=FALSE}
r <- raster::raster(ncol=10, nrow=10, xmn=0, xmx=100, ymn=0, ymx=100)
res(r)
res(r) <- 42
res(r)
```
```{r dependson='raster-example', message=FALSE, warning=FALSE}
r <- raster(ncol=10, nrow=10, xmn=0, xmx=100, ymn=0, ymx=100)
extent(r)
extent(r) <- c(0, 42, 0, 42)
extent(r)
```

#### Raster algebra
As long as the first argument of your algebra operation is a `Raster*` object,
you can use most of the `R` functions to transform your raster.

```{r dependson='raster-example', message=FALSE, warning=FALSE}
r <- raster(ncol=10, nrow=10)
values(r) <- 1:ncell(r)

# do some math
s <- sqrt(r)
s <- s * r + 5
```
... or replace values in a raster:
```{r dependson='raster-example', message=FALSE, warning=FALSE}
r <- raster(ncol=5, nrow=5)
values(r) <- 1:ncell(r)

r[s == c(1,3,5,9,13)] <- 45
r
```


#### ‘High-level’ raster functions
The `raster` package provides all the functions that would expected from a typical GIS 
software.

Some examples are:

```{r dependson='raster-example', message=FALSE, warning=FALSE, fig.height=7, fig.width=7, fig.align='center'}
r <- raster(ncol=100, nrow=100)
values(r) <- 1:ncell(r)

# aggregate/disaggregate raster
ra <- aggregate(r, 20)
rd <- disaggregate(ra, 20)
par(mfrow=c(1,2))
plot(ra)
plot(rd)
```
```{r dependson='raster-example', message=FALSE, warning=FALSE, fig.height=7, fig.width=7, fig.align='center'}
r <- raster(ncol=100, nrow=100)
values(r) <- 1:ncell(r)

# crop and merge
r1 <- crop(r, extent(-50,0,0,30))
r2 <- crop(r, extent(-10,50,-20, 10))
m <- merge(r1, r2)
plot(m)
```
### Assessing raster object slots

All `Raster*` objects share common slots to store information.
Perhaps the most interesting (the values) can be accessed via:

```{r dependson='raster-example', message=FALSE, warning=FALSE}
r <- raster(ncol=10, nrow=10)
values(r) <- 1:ncell(r)

# access the values via @
r@data@values

# ... or by treating the raster like a vector
r[]


# this vector can then be coerced to a matrix:
matrix(r[], nrow(r), ncol(r))
```


### More raster information

* [http://www.rspatial.org](http://www.rspatial.org)


##References
