-
Notifications
You must be signed in to change notification settings - Fork 2
/
README.Rmd
125 lines (70 loc) · 4.09 KB
/
README.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
---
output: github_document
---
<!-- README.md is generated from README.Rmd. Please edit that file -->
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "# ",
fig.path = "man/figures/README-",
out.width = "100%"
)
```
# spatialwidget
### What's a 'spatialwidget'
Well, what do these packages have in common?
- leaflet
- googleway
- mapdeck
- mapview
- tmap
1. They are all [htmlwidgets](https://www.htmlwidgets.org/)
2. They all plot interactive maps
3. They all take data from R and display it on the maps.
And on 22nd August 2017 on the [r-spatial github page](https://github.com/r-spatial/discuss/issues/15#issue-251762127) it was requested if there could be a common package which could be shared by all the interactive web-plotting libraries
> Currently there is code in the leaflet package that extracts data from sp and sf objects and converts it into a dataframe that is then passed to the Javascript side (by converting it into a JSON).
This code is fairly generic and not really dependent on anything leaflet specific. It makes a lot of sense to take out this code and make it a package of its own. That way we can build other web plotting R packages to wrap say d3.geo or mapboxGL or cesium and reuse a major chunk of the code that takes data from spatial objects and passes it to Javascript.
so **spatialwidget** is my attempt at this library.
### What does it do?
It takes a simple feature object (`sf`), plus some user-supplied arguments, and converts the data into JSON, ready for plotting/ parsing in whatever javascript library you chose.
### Can you show me?
Sure. In this example I'm using the `capitals` data, which is an `sf` object of all the capital cities.
```{r}
library(spatialwidget)
library(sf)
sf <- spatialwidget::widget_capitals
sf
```
As each capital is a POINT, you can use `widget_point()` to conver it to JSON.
```{r}
l <- widget_point( data = sf[1:2, ], fill_colour = "country" , legend = F)
```
Each row of `capitals` has been converted into a JSON object. And all these objects are within an array.
Look, here are the first two rows of `capitals` as JSON
```{r}
sf[1:2, ]
jsonify::pretty_json( l$data )
```
You can see that the coordinates are inside a `geometry` object, and the user-defined `fill_colour` is within the `properties` object.
### That looks a lot like GeoJSON
Well spotted. But it's not quite GeoJSON for a very good reason.
Some plotting libraries can use more than one geometry, such as [mapdeck::add_arc()](https://github.com/SymbolixAU/mapdeck#basic-use), which uses an origin and destination. So spatialwidget needs to handle multiple geometries.
Typical GeoJSON will take the form
```js
[{"type":"Feature", "properties":{"stroke_colour":"#440154FF"},"geometry":{"type":"Point","coordinates":[0,0]}}]
```
Whereas I've nested the geometries one-level deeper, so the pseudo-GeoJSON i'm using takes the form
```js
[{"type":"Feature", "properties":{"stroke_colour":"#440154FF"},"geometry":{"myGeometry":{"type":"Point","coordinates":[0,0]}}}]
```
Where the `myGeometry` object is defined on a per-application bases. You are free to call this whatever you want inside your library.
### That sort of makes sense, but can you show me an example with multiple geometries?
Yep.
The `arcs` data is an `sf` object with two POINT geometry columns. So say we want to generate an arc-map showing an arc between Sydney and all the other capitals cities. Just call `widget_od`, supplying the origin and destination columns.
```{r}
l <- widget_od( widget_arcs[1:2, ], origin = "origin", destination = "destination")
jsonify::pretty_json( l$data )
```
Notice now the `geometry` object has within it an `origin` and a `destination`. This is why I've nested the geometries one level deeper within the GeoJSON
### How do I use it in my package?
You can use these R functions, but they have limited scope. This package has been designed so you use the C++ functions directly. I've gone into more detail in the [vignette](https://symbolixau.github.io/spatialwidget/), so it's probably best you read that to understand how to call the C++ functions.