---
title: "BGM as Spatial objects"
author: "Michael D. Sumner"
date: "`r Sys.Date()`"
output:
  rmarkdown::html_vignette:
    fig_width: 7
    fig_height: 7
vignette: >
  %\VignetteIndexEntry{BGM and Spatial}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, echo = FALSE, message = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(raster)
library(dplyr)
library(sp)
```

Read in an example .bgm file with `bgmfile`, and plot it as box-polygons. 

```{r}
library(rbgm)
library(bgmfiles) ## example files
## example data set in package
fname <- bgmfiles(pattern = "Nordic")[1L]
bgm <- bgmfile(fname)
plot(boxSpatial(bgm), col = grey(seq(0, 1, length = nrow(bgm$boxes))))
```

The function `bgmfile` returns a generic list structure of tables, which currently includes the following. More on these later. 

```{r}
print(names(bgm))
```

There are functions for converting from the raw .bgm data structures to `Spatial` objects, as defined in the `sp` package. (Spatial objects are formal GIS-like data that store a table of attribute data against a set of matching polygons, lines or points.)

* `boxSpatial` converts to a `SpatialPolygonsDataFrame`, with a table of attributes relevant to the boxes
* `faceSpatial` converts to a `SpatialLinesDataFrame`, with attributes for the faces (straight line edges that define box boundaries)
* `nodeSpatial` converts to a `SpatialPointsDataFrame, with attributes for the unique vertices in the model 
* `pointSpatial` converts to a `SpatialPointsDataFrame`, with attributes for all instances of the vertices in the model (faces share vertices)
* `boundarySpatial` converts just the boundary path to `SpatialPolygonsDataFrame`

From these conversions we can export to GIS formats such as [GeoPackage](http://www.geopackage.org/). 

It's important to note that the Spatial objects cannot store the full topological and attribute information present in the .bgm, so these are convenience converters that are one-way. We can generate .bgm from these objects, but it cannot be stored in just one Spatial object. 

These converter functions provide fully-functional objects with complete coordinate system metadata, that we can subset, interrogate and plot. 

```{r}
(spdf <- boxSpatial(bgm))

(sldf <- faceSpatial(bgm))
```


Subset based on attribute

```{r}
subset(spdf, horizmix == 0, select = label)

plot(boxSpatial(bgm), col = grey(seq(0, 1, length = nrow(bgm$boxes)), alpha = 0.5))

text(coordinates(spdf), labels = spdf$label, col = grey(seq(1, 0, length = nrow(bgm$boxes))), cex = 0.8)
```

For illustration isolate boxes that are outside the boundary. 

```{r}
## subset the boundary boxes
plot(subset(spdf, boundary), border = "firebrick", lwd = 3)

## or just get a single boundary for the inner
plot(boundarySpatial(bgm), border =  "#1E90FF4C", lwd = 7, add = TRUE)
```

Plot the boxes and then label the faces. 

```{r}
plot(boxSpatial(bgm), col = grey(seq(0, 1, length = nrow(bgm$boxes)), alpha = 0.5))


plot(sldf, col = rainbow(nrow(sldf)), lwd = 2,  add = TRUE)
text(do.call(rbind, lapply(coordinates(sldf), function(x) apply(x[[1]], 2, mean))), 
     labels = gsub("ace", "", sldf$label), cex = 0.5, col = rainbow(nrow(sldf)), pos = 3)
```

Obtain the boundary polygon and plot. 

```{r}
plot(boundarySpatial(bgm), lwd = 4, col = "grey")
plot(boxSpatial(bgm), add = TRUE)
```

## More information

The BGM format and usage is described at the Atlantis site. https://research.csiro.au/atlantis/