---
title: "Choosing a *clifro* Station"
author: "Blake Seers"
date: "`r Sys.Date()`"
output: 
  rmarkdown::html_vignette:
    fig_width: 5
    fig_height: 5
vignette: >
  %\VignetteIndexEntry{Choosing a clifro station}
  %\VignetteEngine{knitr::rmarkdown}
  \usepackage[utf8]{inputenc}
---

```{r, echo=FALSE}
library(clifro)
```

# Introduction

Choosing `clifro` stations is made easy with the single `cf_find_station`
function. This function is all that is required to find clifro stations. This
function is equivalent to conducting the same search on the 
[find stations](http://cliflo.niwa.co.nz/pls/niwp/wstn.get_stn_html) page when 
conducting a query online at CliFlo, except without some of the errors and bugs. 
This means that the searches and the types of searches possible are exactly the 
same however, `clifro` extends functionality to exploring the spatial nature of 
stations via KML files that can be opened by Google Earth(TM), or plotting 
directly in R. This is the main advantage in searching for stations using 
`clifro` as locating suitable stations on a map is generally the preferred 
search tool.

There are four possible types of searches:

* A search based on pattern matching the station name
* A search based on pattern matching the network ID
* A search based on region
* A search based on the vicinity of a given location

For each of these searches either all, open or closed stations may be returned
and these searches also may only return stations where given datatypes are
available. The primary goal in searching for stations is to find the 
unique station agent number required to create a `cfStation` object. This 
vignette details the various search options in `clifro` and ways to find these
requisite agent numbers, primarily by way of example.

# Ignoring datatypes
The following examples detail how to use the `cf_find_station` search function
ignoring any datatypes.

## Station name search
Both of these searches use pattern matching to find the appropriate stations. 
The station name search is useful for searching stations in certain towns or
suburbs or maybe even streets and parks. The network ID is a number that is 
assigned to the stations which makes this search useful to look up stations 
where these are known.

These searches are used when part or all of the station name or network ID is 
known. For example, consider we are looking for open stations located in Takaka, 
at the southeastern end of Golden Bay at the northern end of the South Island, 
New Zealand. The default for the `cf_find_station` function is to search *open* 
station names matching the string.

At the time of writing this, CliFlo ignores the status argument in the name and 
network ID search whereas `clifro` does not. Searching open stations with the
station name matching "takaka" on CliFlo will return these stations.

```{r, eval = FALSE}
# Equivalent to searching for status = "open" on CliFro
# Note the search string is not case sensitive
cf_find_station("takaka", status = "all")
```

```{r, echo = FALSE}
takaka.df = structure(list(name = structure(c(9L, 11L, 13L, 5L, 3L, 8L, 12L, 
10L, 7L, 2L, 6L, 4L, 1L), .Label = c("Takaka", "Takaka Aero", 
"Takaka Aero Raws", "Takaka,Bu Bu", "Takaka Ews", "Takaka Hill", 
"Takaka,Kotinga 1", "Takaka, Kotinga 2", "Takaka, Kotinga Road", 
"Takaka,Patons Rock", "Takaka Pohara", "Upper Takaka", "Upper Takaka 2"
), class = "factor"), network = structure(c(5L, 7L, 12L, 8L, 
13L, 6L, 11L, 1L, 9L, 2L, 10L, 3L, 4L), .Label = c("F02772", 
"F02871", "F02872", "F02881", "F02882", "F02883", "F02884", "F02885", 
"F02971", "F12081", "F12082", "F12083", "O00957"), class = "factor"), 
    agent = c(3788, 3790, 11519, 23849, 41196, 3789, 7316, 3779, 
    3794, 3785, 3833, 3786, 3787), start = structure(c(18273600, 
    520516800, 805464000, 1020081600, 1439294400, 502110000, 
    688820400, -7992000, -255182400, -1046692800, -704894400, 
    -1159875000, -2082886200), class = c("POSIXct", "POSIXt"), tzone = "Pacific/Auckland"), 
    end = structure(c(1532433600, 1532433600, 1532433600, 1532433600, 
    1532433600, 1341057600, 720442800, 157719600, 49809600, 7732800, 
    -320932800, -760190400, -1333452600), class = c("POSIXct", 
    "POSIXt"), tzone = "Pacific/Auckland"), open = c(TRUE, TRUE, 
    TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
    FALSE, FALSE), distance = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0), lat = c(-40.872, -40.845, -41.01516, -40.86364, 
    -40.81531, -40.882, -41.051, -40.789, -40.9, -40.816, -41.017, 
    -40.85, -40.817), lon = c(172.809, 172.867, 172.82582, 172.80568, 
    172.7765, 172.801, 172.833, 172.757, 172.775, 172.772, 172.867, 
    172.733, 172.8)), class = "data.frame", row.names = c(NA, 
-13L))

new("cfStation", takaka.df)
```

This shows that 8 of these 13 stations are closed. The search in `clifro` does 
not ignore the station status.

```{r, eval = FALSE}
cf_find_station("takaka", status = "open")
```

```{r, echo = FALSE}
takaka.df = structure(list(name = structure(c(3L, 4L, 5L, 2L, 1L), .Label = c("Takaka Aero Raws", 
"Takaka Ews", "Takaka, Kotinga Road", "Takaka Pohara", "Upper Takaka 2"
), class = "factor"), network = structure(c(1L, 2L, 4L, 3L, 5L
), .Label = c("F02882", "F02884", "F02885", "F12083", "O00957"
), class = "factor"), agent = c(3788, 3790, 11519, 23849, 41196
), start = structure(c(18273600, 520516800, 805464000, 1020081600, 
1439294400), class = c("POSIXct", "POSIXt"), tzone = "Pacific/Auckland"), 
    end = structure(c(1532433600, 1532433600, 1532433600, 1532433600, 
    1532433600), class = c("POSIXct", "POSIXt"), tzone = "Pacific/Auckland"), 
    open = c(TRUE, TRUE, TRUE, TRUE, TRUE), distance = c(0, 0, 
    0, 0, 0), lat = c(-40.872, -40.845, -41.01516, -40.86364, 
    -40.81531), lon = c(172.809, 172.867, 172.82582, 172.80568, 
    172.7765)), class = "data.frame", row.names = c(NA, -5L))

new("cfStation", takaka.df)
```

Stations are considered open in `clifro` if the final date returned from the
search is within four weeks of the current date. This gives the user a better
idea on the stations that are currently collecting data. 

## Station network ID search
The same can be done for searching stations using network ID although 
`search = "network"` needs to be added to the function call. Assume we knew
that the only stations we were interested in were the open stations whose 
network ID's match `F028`.

```{r, eval = FALSE}
cf_find_station("f028", search = "network", status = "all")
```

```{r, echo = FALSE}
xx.df = structure(list(name = structure(c(11L, 12L, 9L, 10L, 4L, 3L, 
2L, 1L, 13L, 7L, 14L, 8L, 6L, 5L), .Label = c("Golden Bay,Table Hl 2", 
"Golden Bay,Table Hl I", "Gouland Downs", "Nelson,Mckay Hut", 
"Quartz Ranges", "Takaka", "Takaka Aero", "Takaka,Bu Bu", "Takaka Ews", 
"Takaka, Kotinga 2", "Takaka, Kotinga Road", "Takaka Pohara", 
"Tarakohe", "Totaranui"), class = "factor"), network = structure(c(9L, 
11L, 12L, 10L, 1L, 2L, 4L, 5L, 13L, 6L, 14L, 7L, 8L, 3L), .Label = c("F02821", 
"F02831", "F02851", "F02852", "F02853", "F02871", "F02872", "F02881", 
"F02882", "F02883", "F02884", "F02885", "F02891", "F02892"), class = "factor"), 
    agent = c(3788, 3790, 23849, 3789, 3780, 3781, 3783, 3784, 
    3791, 3785, 3792, 3786, 3787, 3782), start = structure(c(18273600, 
    520516800, 1020081600, 502110000, 417960000, 467982000, 233928000, 
    233928000, -1188819000, -1046692800, -410270400, -1159875000, 
    -2082886200, -2177494200), class = c("POSIXct", "POSIXt"), tzone = "Pacific/Auckland"), 
    end = structure(c(1532433600, 1532433600, 1532433600, 1341057600, 
    745416000, 745416000, 690807600, 690807600, 599569200, 7732800, 
    -294667200, -760190400, -1333452600, -2125049400), class = c("POSIXct", 
    "POSIXt"), tzone = "Pacific/Auckland"), open = c(TRUE, TRUE, 
    TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
    FALSE, FALSE, FALSE), distance = c(0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0), lat = c(-40.872, -40.845, -40.86364, -40.882, 
    -40.89, -40.892, -40.807, -40.807, -40.825, -40.816, -40.823, 
    -40.85, -40.817, -40.867), lon = c(172.809, 172.867, 172.80568, 
    172.801, 172.213, 172.351, 172.556, 172.556, 172.898, 172.772, 
    173.002, 172.733, 172.8, 172.517)), class = "data.frame", row.names = c(NA, 
-14L))

new("cfStation", xx.df)
```

Notice that the resulting dataframes in all of these searches are first ordered
by the date they last received data then by the date they opened to give the
longest-running open stations first and the most historic, closed stations last.

## Return all stations within a region
This broad search returns all, open or closed stations within one of the 29 
preselected New Zealand regions (note that stations can belong to more than
one region). The `search = "region"` argument must be 
added to the `cf_find_station` function to conduct these searches. If the region 
is unknown then the search argument may be missing which brings up an 
interactive menu of the 29 regions for the user to select 
(`cf_find_station(search = "region")`), otherwise partial matching is used.

```{r, echo = FALSE}
open.queenstown.stations.df = dget(system.file("extdata", "queenStations", package = "clifro"))
open.queenstown.stations = new("cfStation", open.queenstown.stations.df)
```

```{r, eval = FALSE}
# Partial match for the Queenstown region
open.queenstown.stations = cf_find_station("queen", search = "region")
```

Typing `open.queenstown.stations` into R will then return all the 
`r nrow(open.queenstown.stations)` open Queenstown stations. This 
is clearly a burden to choose stations based on a large list of numbers hence 
plotting them on a map (covered below) to assess their spatial extent will make 
this task much easier.

## Return all stations within the vicinity of a given location

This location based search is conducted by including the 
`search = "latlong"` argument to the `cf_find_station` function. There are 
three parameters needed for this search; latitude, longitude and radius 
(kilometres). Just like any other function in R, if these arguments aren't 
named then the order matters and should be written in the order specified above.
The latitude and longitude must be given in decimal degrees.

We are (still) interested in finding all open stations around the small town of
Takaka. From 
[GeoHack](http://tools.wmflabs.org/geohack/geohack.php?pagename=Takaka%2C_New_Zealand&params=40_51_S_172_48_E_type:city%281149%29_region:NZ)
we can see that the latitude is -40.85 and the longitude is 172.8. We are 
interested in all open stations within a 10km radius of the main township.

```{r, echo = FALSE}
takaka.town.df = structure(list(name = structure(c(3L, 4L, 2L, 1L), .Label = c("Takaka Aero Raws", 
"Takaka Ews", "Takaka, Kotinga Road", "Takaka Pohara"), class = "factor"), 
    network = structure(1:4, .Label = c("F02882", "F02884", "F02885", 
    "O00957"), class = "factor"), agent = c(3788, 3790, 23849, 
    41196), start = structure(c(18273600, 520516800, 1020081600, 
    1439294400), class = c("POSIXct", "POSIXt"), tzone = "Pacific/Auckland"), 
    end = structure(c(1532520000, 1532520000, 1532520000, 1532520000
    ), class = c("POSIXct", "POSIXt"), tzone = "Pacific/Auckland"), 
    open = c(TRUE, TRUE, TRUE, TRUE), distance = c(2.6, 5.7, 
    1.6, 4.3), lat = c(-40.872, -40.845, -40.86364, -40.81531
    ), lon = c(172.809, 172.867, 172.80568, 172.7765)), class = "data.frame", row.names = c(NA, 
-4L))
takaka.town.st = new("cfStation", takaka.town.df)
```

```{r, eval = FALSE}
takaka.town.st = cf_find_station(lat = -40.85, long = 172.8, rad = 10, search = "latlong")
takaka.town.st[, -c(8, 9)]
```

```{r, echo = -1}
takaka.town.st[, -c(8, 9)]

# We may rather order the stations by distance from the township
takaka.town.st[order(takaka.town.st$distance), -c(8, 9)]
```

# Searches based on datatypes

All the above searches did not include a datatype therefore they ignore the 
datatypes available at these stations. Imagine we are looking for 
hourly rain data at an open station in Takaka (using any of the aforementioned
searches), we would need to include the hourly rain datatype in the search for 
it to return a suitable station.

### Note
Unless the Reefton EWS station is the only CliFlo station of interest, the user 
will need a [CliFlo account](https://cliflo.niwa.co.nz/pls/niwp/wsubform.intro)
to get data from other stations.

```{r, echo = FALSE}
hourly.rain.dt = new("cfDatatype"
    , dt_name = "Precipitation"
    , dt_type = "Rain (fixed periods)"
    , dt_sel_option_names = list("Hourly")
    , dt_sel_combo_name = NA_character_
    , dt_param = structure("ls_ra,1,2,3,4", .Names = "dt1")
    , dt_sel_option_params = list(structure("182", .Names = "prm2"))
    , dt_selected_options = list(2)
    , dt_option_length = 4
)
```

```{r, eval = FALSE}
# Create a clifro datatype for hourly rain
hourly.rain.dt = cf_datatype(3, 1, 2)
hourly.rain.dt
```

```{r, echo = FALSE}
hourly.rain.dt
```

```{r, eval = FALSE}
# Conduct the search
cf_find_station("takaka", datatype = hourly.rain.dt)
```

```
##          name network agent      start        end open distance
## 1) Takaka Ews  F02885 23849 2002-06-02 2018-07-19 TRUE        0
```

This tells us that the only *open* station in Takaka where hourly rain data 
is available is at the Takaka Ews station. 

# More than one search at a time

Since the `cf_find_station` function returns `cfStation` objects, any of these 
methods work on objects created from the `cf_station` function (see the 
[working with clifro stations vignette][clifrostation] for more details). We can 
conduct two or more searches at a time using the addition sign, just like we did 
for `cfDatatype`s (see the [choose datatypes vignette][chooseDatatype]).

We would like to return all open stations within a 10km radius of the Takaka 
township in the South Island, and the open stations in Kaitaia, in the North 
Island that collect hourly rain data.

```{r, echo = FALSE}
kaitaia.df = structure(list(name = structure(c(4L, 10L, 9L, 3L, 8L, 1L, 6L, 
7L, 2L, 5L), .Label = c("Cape Reinga Aws", "Dargaville 2 Ews", 
"Kaikohe Aws", "Kaitaia Aero Ews", "Kaitaia Ews", "Kerikeri Aerodrome Aws", 
"Kerikeri Ews", "Purerua Aws", "Russell Cws", "Trounson Cws"), class = "factor"), 
    network = structure(c(2L, 7L, 10L, 6L, 9L, 1L, 5L, 4L, 8L, 
    3L), .Label = c("A42462", "A53026", "A53127", "A53191", "A53295", 
    "A53487", "A53762", "A53987", "A54101", "A54212"), class = "factor"), 
    agent = c(18183, 37131, 41262, 1134, 1196, 1002, 37258, 1056, 
    25119, 17067), start = structure(c(960984000, 1244030400, 
    1459771200, 500727600, 788871600, 788871600, 1214395200, 
    1025179200, 1067425200, 913806000), class = c("POSIXct", 
    "POSIXt"), tzone = "Pacific/Auckland"), end = structure(c(1532347200, 
    1532347200, 1532347200, 1532260800, 1532260800, 1532260800, 
    1532260800, 1531915200, 1531915200, 1531310400), class = c("POSIXct", 
    "POSIXt"), tzone = "Pacific/Auckland"), open = c(TRUE, TRUE, 
    TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE), distance = c(0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0), lat = c(-35.0677, -35.72035, 
    -35.26835, -35.4172, -35.129, -34.42963, -35.262, -35.183, 
    -35.93145, -35.135), lon = c(173.2874, 173.65153, 174.136, 
    173.8229, 174.015, 172.68186, 173.911, 173.926, 173.85317, 
    173.262)), class = "data.frame", row.names = c(NA, -10L))
kaitaia.st = new("cfStation", kaitaia.df)
my.composite.search = takaka.town.st + kaitaia.st
```

```{r, eval = FALSE}
my.composite.search = takaka.town.st + cf_find_station("kaitaia", 
                                                       search = "region", 
                                                       datatype = hourly.rain.dt)
my.composite.search
```

```{r, echo = -1}
my.composite.search

# How long have these stations been open for?
transform(my.composite.search, ndays = round(end - start))[, c(1, 10)]
```

# So where are these stations?

Up until now there probably hasn't been any good reason to choose clifro to 
search for stations instead of the 
['Choose Stations' form on CliFlo](https://cliflo.niwa.co.nz/pls/niwp/wstn.get_stn_html). 
However, the real advantage of using clifro is to visualise the station 
locations on a map by returning a KML file, particularly when there are lots of 
stations returned by the search. This Keyhole Markup Language 
([KML](http://resources.arcgis.com/en/help/main/10.1/index.html#//00s20000000m000000)) 
is an XML-based language provided by Google(TM) for defining the graphic display 
of spatial data in applications such as Google Earth(TM) and Google Maps(TM).

To return the stations as a KML file simply use the `cf_save_kml` function on 
any `cfStation` object. The `cf_find_station` function returns `cfStation` 
objects therefore it's very easy to plot these on a map. To assess the 
geographic extent of the Auckland stations we can return a KML file from the 
search and open it using our preferred KML-friendly software.

```{r, echo = FALSE}
all.auckland.df = dget(system.file("extdata", "auckStations", package = "clifro"))
all.auckland.st = new("cfStation", all.auckland.df)
```

```{r,eval = FALSE}
# First, search for the stations
all.auckland.st = cf_find_station("auckland", search = "region", status = "all")
```

Now `all.auckland.st` contains all the `r nrow(all.auckland.st)` 
Auckland stations where data have been recorded on CliFlo. 

```{r,eval=FALSE}
# Then save these as a KML
cf_save_kml(all.auckland.st, file_name = "all_auckland_stations")
```

The green markers represent the open stations and the red markers indicate 
closed stations. The resulting KML file is saved to the current R session's 
working directory by default. Have a look at the 
[clifro station vignette][clifrostation] for more methods and plotting of 
`cfStation` objects.

![auckland stations][allAucklandStations]

[chooseDatatype]: choose-datatype.html
[clifrostation]: cfStation.html
[allAucklandStations]: figures/map.png "All Auckland Stations"
