---
title: "Using OSM Building Data"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Using OSM Building Data}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
set.seed(19750604)
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

In areas where good OpenStreetMap building surveys are available, this data makes a 
good proxy for a population density when no census is available.
The `osmdata` package lets a user query the OSM database for particular features.
This vignette illustrates how to get OSM building data and use it for a sampling
design.

## Input Polygon

First we need to define a polygon for our study region. Here we construct it from 
a WKT string, but typically this might be read in from a data source such as a 
geopackage or a shapefile, or even drawn on a map using R's
interactove `locator` function.

```{r setup}
library(sidclosepairs)
library(sf)
study_area = "POLYGON (
 (-2.794796 54.02322, -2.801250 54.02686, -2.802311 54.02867, -2.802351 54.02891, -2.802334 54.03084,
  -2.802218 54.03190, -2.801649 54.03199, -2.801142 54.03202, -2.784621 54.03237, -2.780087 54.03196,
  -2.778327 54.03087, -2.777984 54.03048, -2.775405 54.02391, -2.775982 54.02327, -2.794796 54.02322))"

## remove newline markers
study_area = gsub("\n","", study_area)

# convert WKT to spatial polygon data frame
study_area = st_as_sf(data.frame(wkt=study_area), wkt="wkt", crs=4326)
```

## Get the Buildings

Now with our study area defined, we construct a query using `osmdata` package functions and
get back the points in the bounding box of our study area. Taking the centroid of the 
buildings makes sure we reduce polygons down to points. Finally we take only the points
that are within the polygon itself, not just the bounding box. We'll wrap these calls
into a function for re-use and call it to get buildings in our study area.

```{r getem}
library(osmdata)
## or use another overpass server
set_overpass_url("https://overpass-api.de/api/interpreter")
get_buildings <- function(area){
    osmd <- opq(bbox = st_bbox(area))
    osmd <- add_osm_feature(osmd, key = "building")
    osmd <- osmdata_sf(osmd)
    centroids_in_area <- st_intersection(st_centroid(osmd$osm_polygons), area)
    return(centroids_in_area)
}
buildings = get_buildings(study_area)
```

If you want to do this for several study areas you should consider wrapping
the `osmdata` calls into a single function for convenience.

## Inhibitory Close Pair Sampling

Now we'll sample fifty points in total, with ten sets of close pairs, keeping our 
inhibitory points 100 metres apart, and our close pairs in a 20 metre radius.

First we have to convert our data to a local Cartesian coordinate system,
so we use EPSG code 27700, for the Ordnance Survey GB system which is appropriate
for this region in Lancaster.

```{r convo}
crs = 27700
study_gb = st_transform(study_area, crs)
buildings = st_transform(buildings, crs)
```

Now we can sample our 50 points with 10 close pairs using the "census" proposal method
for the inhibitory points, and a 20 metre radius for the close pairs.

```{r samplez, fig.width=6}
pts_buildings = icpSample(50, 10, 100, 20, censusxy=buildings, poly=study_gb, proposal="census")
pts_buildings
```

## Plotting

To show these points we can first plot the building locations in grey, then overlay the
first 40 points in red to show the inhibitory points, and then add the close pairs in blue.

```{r plots, fig.width=6}
plot(study_gb)
plot(st_geometry(buildings), add=TRUE, col="grey", cex=.5)
plot(st_geometry(pts_buildings[1:40,]), add=TRUE, col="red")
plot(st_geometry(pts_buildings[41:50,]), add=TRUE, col="blue")
```

Note that the blue close pair points are not guaranteed to be on a building, but some
other method will need to be used to select the second building for a survey related
to that point. Often the nearest building to the point will be sampled, or the nearest in 
the direction indicated by the two points.
