# Geographic Data Collection and Spatial data

`KoboToolbox` allows the collection of spatial data through three questions types: geopoint, geotrace and geoshape.

Geopoint:
The geopoint question type captures a single geographic coordinate (latitude and longitude) including altitude and accuracy. This is useful for marking locations, such as homes, schools, or water sources.

Geotrace:
The geotrace question type collects a series of connected geographic coordinates, forming a line. This can be used to map routes, paths, or boundaries.

Geoshape:
A geoshape question type captures a series of geographic coordinates that form a closed polygon. This is useful for defining areas, such as land parcels, agricultural fields, or protected zones.

To utilize these data types, we need to parse them into a GIS friendly format. `robotoolbox` uses Well-Known Text (WKT), a standard markup language for representing vector geometry, to represent points (`geopoint`), lines (`geotrace`) and polygons (`geoshape`).

## Spatial data

The following form provides a simple demonstration of how `robotoolbox` maps spatial field types.

### Survey questions

name | type | label
--- | --- | ---
point | geopoint | Record a location
point_description | text | Describe the recorded location
line | geotrace | Record a line
line_description | text | Describe the recorded line
polygon | geoshape | Record a polygon
polygon_description | text | Describe the recorded polygon

The form includes three spatial type columns: `point`, `line` and `polygon`.

### Loading the project

The aforementioned form, named `Spatial data`, was uploaded to the server. You can load it from the `asset_list` of assets.

    library(robotoolbox)
    library(dplyr)
    asset_list <- kobo_asset_list()
    uid <- filter(asset_list, name == "Spatial data") |>
      pull(uid)
    asset <- kobo_asset(uid)
    asset

    #> <robotoolbox asset>  a9NCKTJxBPKdy49gX57WL5
    #>   Asset name: Spatial data
    #>   Asset type: survey
    #>   Asset owner: dickoa
    #>   Created: 2023-04-22 11:57:54
    #>   Last modified: 2023-04-22 12:01:39
    #>   Submissions: 1

We have a single submission, where we recorded one location using a `geopoint` question, mapped a portion of a road using a `geotrace` question, and outlined a stadium using a `geoshape`` question.

### Extracting the data

From the assets, we can proceed to extract the submissions.

    df <- kobo_data(asset)
    glimpse(df)

    #> Rows: 1
    #> Columns: 23
    #> $ point                <chr> "14.719783 -17.459261 0 0"
    #> $ point_latitude       <dbl> 14.71978
    #> $ point_longitude      <dbl> -17.45926
    #> $ point_altitude       <dbl> 0
    #> $ point_precision      <dbl> 0
    #> $ point_wkt            <chr> "POINT (-17.459261 14.719783 0)"
    #> $ point_description    <chr> "Jardin Liberte"
    #> $ line                 <chr> "14.726129 -17.500409 0 0;14.726253 -17.498993 0 …
    #> $ line_wkt             <chr> "LINESTRING (-17.500409 14.726129 0, -17.498993 1…
    #> $ line_description     <chr> "Route de la Corniche"
    #> $ polygon              <chr> "14.747328 -17.452461 0 0;14.747743 -17.451869 0 …
    #> $ polygon_wkt          <chr> "POLYGON ((-17.452461 14.747328 0, -17.451869 14.…
    #> $ polygon_description  <chr> "Stade Leopold Sedar Senghor"
    #> $ `_id`                <int> 28557821
    #> $ uuid                 <chr> "01c7d7250bd84ac9b604199ca98daa84"
    #> $ `__version__`        <chr> "v7nQkzvEV64YLAfEQv5prV"
    #> $ instanceID           <chr> "uuid:26c66ec5-935a-4220-8902-6de928330122"
    #> $ `_xform_id_string`   <chr> "a9NCKTJxBPKdy49gX57WL5"
    #> $ `_uuid`              <chr> "26c66ec5-935a-4220-8902-6de928330122"
    #> $ `_status`            <chr> "submitted_via_web"
    #> $ `_submission_time`   <dttm> 2023-04-22 12:07:29
    #> $ `_validation_status` <chr> NA
    #> $ `_submitted_by`      <lgl> NA

We can see that we have all of our three columns `point`, `line` and `polygon`. For each of them, we have a corresponding WKT column.

    pull(df, point)
    #> [1] "14.719783 -17.459261 0 0"
    #> attr(,"label")
    #> [1] "Record a location"
    pull(df, point_wkt)
    #> [1] "POINT (-17.459261 14.719783 0)"
    #> attr(,"label")
    #> [1] "point_wkt"

For `geopoint` types, `robotoolbox` also offers columns for latitude, longitude, altitude, and precision.

    df |>
      select(starts_with("point_"))
    #> # A tibble: 1 × 6
    #>   point_latitude point_longitude point_altitude point_precision point_wkt
    #>            <dbl>           <dbl>          <dbl>           <dbl> <chr>
    #> 1           14.7           -17.5              0               0 POINT (-17.4592…
    #> # ℹ 1 more variable: point_description <chr>

The `line` column, derived from the `geotrace` question, has a corresponding `line_wkt` column.

    pull(df, line)
    #> [1] "14.726129 -17.500409 0 0;14.726253 -17.498993 0 0;14.725688 -17.498002 0 0;14.72527 -17.497068 0 0;14.724897 -17.496113 0 0;14.72438 -17.495383 0 0;14.723737 -17.494784 0 0"
    #> attr(,"label")
    #> [1] "Record a line"
    pull(df, line_wkt)
    #> [1] "LINESTRING (-17.500409 14.726129 0, -17.498993 14.726253 0, -17.498002 14.725688 0, -17.497068 14.72527 0, -17.496113 14.724897 0, -17.495383 14.72438 0, -17.494784 14.723737 0)"
    #> attr(,"label")
    #> [1] "line_wkt"

Lastly, `polygon_wkt` is the WKT column derived from the `geoshape` question labeled `polygon`.

    pull(df, polygon)
    #> [1] "14.747328 -17.452461 0 0;14.747743 -17.451869 0 0;14.747519 -17.451477 0 0;14.747244 -17.451332 0 0;14.746378 -17.451332 0 0;14.745989 -17.451563 0 0;14.745844 -17.451987 0 0;14.746062 -17.45232 0 0;14.74627 -17.452492 0 0;14.747328 -17.452461 0 0"
    #> attr(,"label")
    #> [1] "Record a polygon"
    pull(df, polygon_wkt)
    #> [1] "POLYGON ((-17.452461 14.747328 0, -17.451869 14.747743 0, -17.451477 14.747519 0, -17.451332 14.747244 0, -17.451332 14.746378 0, -17.451563 14.745989 0, -17.451987 14.745844 0, -17.45232 14.746062 0, -17.452492 14.74627 0, -17.452461 14.747328 0))"
    #> attr(,"label")
    #> [1] "polygon_wkt"

Now that we understand how `robotoolbox` stores spatial question types, we can convert these columns into spatial objects suitable for spatial data analysis.

## Geopoint

The standard approach to manipulate spatial vector data in `R` involves using the `sf` package. `sf` stands for Simple Features and it extends a `data.frame` by adding a geometry list-column. It’s a spatially enabled `data.frame`. It provides an interface to the popular GDAL, GEOS, PRØJ and S2 libraries. It can be used to efficiently manipulate and visualize spatial vector data.

Creating an `sf` object from a text column that contains `WKT` characters is straightforward. The `sf::st_as_sf` function can be used to turn the `data.frame` with a `WKT` column into an `sf` object.

    point_sf <- st_as_sf(data_spatial,
                         wkt = "point_wkt", crs = 4326)
    mapview(point_sf)

## Geotrace

We can also transform a `data.frame` with a column from a `geotrace` question to an `sf` object with a `LINESTRING` geometry. The `WKT` column is named `line_wkt`.

    line_sf <- st_as_sf(data_spatial,
                         wkt = "line_wkt", crs = 4326)
    mapview(line_sf)

## Geoshape

The column `polygon_wkt` can be used to create an `sf` polygon object. It’s a simple closed polygon.

    poly_sf <- st_as_sf(data_spatial,
                        wkt = "polygon_wkt", crs = 4326)
    mapview(poly_sf)

Not only does `robotoolbox` rely on the `sf` package, but it also leverages other packages from the same ecosystem to provide robust spatial data analysis for `KoboToolbox` users.

You can learn a lot about the `sf` packages and spatial data analysis with R from the excellent Geocomputation with R book and through the extensive `sf` package documentation.