This vignette shows how to generate artificial landscapes with different spatial patterns. These landscapes are designed for training and testing spatial pattern classifiers. For details on how to use the generated landscapes for training classifiers, see the [classify-metrics](classify-metrics.qmd) and [classify-pixels](classify-pixels.qmd) vignettes.

```{r}
#| label: setup

library(spatPatClassifyR)
# Set seed for reproducibility
set.seed(123456)
```

## Overview

You can:

- Generate batches of training landscapes with `create_training_landscapes()`
- Create individual landscapes with custom parameters using `create_landscape()`
- Visualize an individual landscape with `plot_landscape()
- Visualize multiple landscapes in a grid with `plot_landscape_list()`

### Available patterns

There are 11 different spatial patterns available:

#### Control patterns

- **random**: Randomly distributed vegetation
- **bare**: No/minimal vegetation (control)
- **dense**: Complete/maximal vegetation cover (control)

```{r}
#| label: control-patterns
#| echo: false
#| fig.width: 8
#| fig.height: 3
#| fig-alt: "Three landscapes showing control patterns: random, bare, and dense"

random <- create_landscape("random", name = "Random")
bare <- create_landscape("bare", name = "Bare")
dense <- create_landscape("dense", name = "Dense")

plot_landscape_list(list(random, bare, dense), show_legend = FALSE)
```

#### Ecotone patterns

- **sharp**: Sharp boundary
- **diffuse**: Gradual transition
- **fingers**: Curvy, finger-like extensions
- **clustered**: Vegetation clusters above a treeline
- **bands**: Sinusoidal vegetation bands

```{r}
#| label: ecotone-patterns
#| echo: false
#| fig-width: 8
#| fig-height: 6
#| fig-alt: "Five landscapes showing ecotone patterns: sharp, diffuse, fingers, clustered, and bands"

sharp <- create_landscape("sharp", name = "Sharp treeline")
diffuse <- create_landscape("diffuse", name = "Diffuse treeline")
fingers <- create_landscape("fingers", name = "Fingers")
clustered <- create_landscape("clustered", name = "Clustered")
bands <- create_landscape("bands", name = "Bands")
plot_landscape_list(
  list(sharp, diffuse, fingers, clustered, bands),
  show_legend = FALSE,
  ncol = 3
)
```

#### Patch patterns

- **spots**: Circular vegetation patches
- **gaps**: Circular vegetation gaps
- **labyrinth**: Maze-like vegetation patterns

```{r}
#| label: patch-patterns
#| echo: false
#| fig-width: 8
#| fig-height: 3
#| fig-alt: "Three landscapes showing patch patterns: spots, gaps, and labyrinth"

spots <- create_landscape("spots", name = "Spots")
gaps <- create_landscape("gaps", name = "Gaps")
labyrinth <- create_landscape("labyrinth", name = "Labyrinth")
plot_landscape_list(list(spots, gaps, labyrinth), show_legend = FALSE)
```

For detailed parameter descriptions and examples of each pattern type, see `?create_landscape`.


## Creating Multiple Training Landscapes

The quickest way to generate training data is with `create_training_landscapes()`.
It generates multiple landscapes balanced across all available patterns.

```{r}
#| label: create-training-landscapes
#| fig-width: 8
#| fig-height: 6
#| fig-alt: "Grid showing 20 randomly generated landscapes with different spatial patterns"

# Create 20 landscapes balanced across all pattern types
landscapes <- create_training_landscapes(n = 20)
```

The `landscapes` are returned as a list of `landscape` objects (see [below](landscape-generation.qmd#landscape-object-structure) for more info on the data structure).

They can be visualized using the `plot_landscape_list()` function:

```{r}
# Plot all landscapes
plot_landscape_list(landscapes)
```

By default, landscapes are created in a balanced way, so that each pattern type is represented equally in the generated set.

```{r}
#| label: check-pattern-distribution

# Check how many landscapes of each type were generated
table(purrr::map_chr(landscapes, ~ .x$pattern))
```

### Selecting Specific Patterns

Specific patterns can be selected to create only a subset of patterns using the `patterns` argument. For example, to create landscapes with only labyrinth, spots, and clustered patterns:

```{r}
#| label: specific-patterns
#| fig-width: 8
#| fig-height: 6
#| fig-alt: "Grid showing landscapes with only labyrinth, spots, and clustered patterns"

# Generate only specific patterns
landscapes <- create_training_landscapes(
  n = 12,
  patterns = c("labyrinth", "spots", "clustered")
)

plot_landscape_list(landscapes)
```

### Control landscape parameters

#### Landscape size

To modify the size (number of pixels in x- and y-direction) of all generated landscapes, use the `ncol` and `nrow` arguments. By default, landscapes are created with a size of 100x100 pixels.

```{r}
#| label: custom-size
#| fig-width: 8
#| fig-height: 3
#| fig-alt: "Three landscapes showing different sizes: 50x20 pixels"
non_square <- create_training_landscapes(
  n = 3,
  width = 50,
  height = 20
)
# Plot landscapes with custom size
plot_landscape_list(non_square)
```

#### Landscape rotation

By default, landscapes are rotated by angles randomly chosen between 0 and 360 degrees.
This ensures that classifiers trained on these landscapes are invariant to landscape orientation.

You can disable random rotation by setting the `add_rotation` parameter to `FALSE`.

You can also control used rotation angles directly using `rotation_angles`.

```{r}
#| label: rotation-example
#| message: false
#| fig-width: 8
#| fig-height: 3
#| fig-alt: "Landscapes showing the same pattern rotated at different angles"

no_rotation <- create_training_landscapes(
  n = 3,
  patterns = c("clustered", "sharp", "bands"),
  add_rotation = FALSE
)

defined_angles <- create_training_landscapes(
  n = 3,
  patterns = "clustered",
  rotation_angles = c(45, 90)
)

plot_landscape_list(c(no_rotation, defined_angles))
```

#### Pattern-specific parameters

You can modify default parameters for all generated landscapes of a specific pattern by passing a list of parameter values to the `params_list ` argument. For example, to create landscapes with more spots of larger size:

```{r}
#| label: custom-parameters
#| message: false
#| fig-width: 8
#| fig-height: 6
#| fig-alt: "Grid showing landscapes with many large spots"

# Custom parameters for spot patterns
pattern_params <- list(
  spots = list(
    n_spots = 15,
    spot_radius = 10,
    spot_radius_sd = 3
  )
)
bigger_spots <- create_training_landscapes(
  n = 12,
  patterns = "spots",
  params_list = pattern_params
)

plot_landscape_list(bigger_spots)
```

To check parameter names and default values for each pattern type, see the function help `create_landscape()`.

## Creating Single Landscapes

To create single landscapes of all patterns with specific parameters, use the `create_landscape()` function. Check the help page `?create_landscape` for a full list of available parameters for each pattern type.

### Spot Patterns

```{r}
#| label: spot-patterns-examples
#| fig-width: 8
#| fig-height: 3
#| fig-alt: "Three landscapes showing spot patterns with different numbers and sizes of vegetation patches"

# Default spots
spots_default <- create_landscape("spots", name = "Default")

# More spots with size variation
spots_many <- create_landscape(
  "spots",
  name = "Many variable spots",
  n_spots = 15,
  spot_radius = 8,
  spot_radius_sd = 2
)

# Regular grid of spots
spots_regular <- create_landscape(
  "spots",
  name = "Regular grid",
  n_spots = 15,
  spot_radius = 20,
  spot_radius_sd = 0,
  regular_spots = TRUE
)

plot_landscape_list(
  list(spots_default, spots_many, spots_regular),
  titles = "name"
)
```

### Clustered Patterns

```{r}
#| label: clustered-patterns-examples
#| fig-width: 8
#| fig-height: 3
#| fig-alt: "Three landscapes showing clustered vegetation with different cluster sizes and numbers"

# Few large clusters
clustered_large <- create_landscape(
  "clustered",
  name = "Few large clusters",
  n_clusters = 5,
  cluster_radius = 12,
  scatter_zone_prop = 0.5
)

# Many small clusters
clustered_small <- create_landscape(
  "clustered",
  name = "Many small clusters",
  n_clusters = 30,
  cluster_radius = 2,
  scatter_zone_prop = 0.6
)

# Elongated clusters
clustered_horizontal <- create_landscape(
  "clustered",
  name = "Horizontal clusters",
  n_clusters = 15,
  cluster_radius = 5,
  elongation_x = 3,
  elongation_y = 1,
  scatter_zone_prop = 0.4
)

plot_landscape_list(
  list(
    clustered_large,
    clustered_small,
    clustered_horizontal
  ),
  titles = "name"
)
```

### Labyrinth Patterns

```{r}
#| label: labyrinth-patterns-examples
#| fig-width: 8
#| fig-height: 3
#| fig-alt: "Two landscapes showing labyrinth-like vegetation patterns with different frequencies"

# Default labyrinth
labyrinth_default <- create_landscape("labyrinth", name = "Default")

# Higher frequency with multiple octaves
labyrinth_complex <- create_landscape(
  "labyrinth",
  name = "Complex",
  frequency = 8,
  octaves = 3,
  band_fuzziness = 0.05
)

plot_landscape_list(list(labyrinth_default, labyrinth_complex), titles = "name")
```

## The landscape Object

In `spatPatClassifyR`,  landscapes are stored as lists containing the landscape data and metadata. All landscape generation functions return landscapes in this format and all other functions expect landscapes to be provided in this format. 

To learn how to transform your own raster data into this format, see [vignette on importing landscapes](importing-landscapes.qmd).

Each landscapes is stored as a list with the following components:

- data: The landscape object as a `SpatRaster` class
- pattern: Pattern type (e.g., "spots", "clustered")
- name: User-defined name
- params: List of parameters used to generate the landscape

```{r}
#| label: landscape-object-structure

landscape_example <- create_landscape("spots", name = "Example")
str(landscape_example)
```

#### Modifying Landscape Metadata

Users can modify landscape metadata using the helper functions `set_landscape_pattern()` and `set_landscape_name()`. For example, to change the pattern label or name of existing landscapes:

```{r}
#| label: modify-metadata

landscapes_example <- set_landscape_name(
  landscape_example,
  "New Landscape Name"
)
landscapes_example <- set_landscape_pattern(
  landscapes_example,
  "custom_pattern"
)
landscapes_example
```

## Next Steps

- See `vignette("landscape-metrics")` for extracting landscape features and finding the most informative metrics
- See `vignette("classify-metrics")` for training spatial pattern classifiers on the landscape metrics
- see `vignette("classify-pixels")` for training spatial pattern classifiers on the raw landscape data using keras

