lawn
is an R wrapper for the Javascript library turf.js for advanced geospatial analysis. In addition, we have a few functions to interface with the geojson-random Javascript library.
lawn
includes traditional spatial operations, helper functions for creating GeoJSON data, and data classification and statistics tools.
There is an additional helper function (see view()
) in this package to help visualize data with interactive maps via the leaflet
package (https://github.com/rstudio/leaflet). Note that leaflet
is not required to install lawn
- it's in Suggests, not Imports or Depends.
If installing leaflet
devtools::install_github("rstudio/leaflet")
Stable lawn
version from CRAN
install.packages("lawn")
Or, the development version from Github
devtools::install_github("ropensci/lawn")
library("lawn")
Point
lawn_point(c(-74.5, 40))
#> $type
#> [1] "Feature"
#>
#> $geometry
#> $geometry$type
#> [1] "Point"
#>
#> $geometry$coordinates
#> [1] -74.5 40.0
#>
#>
#> $properties
#> named list()
#>
#> attr(,"class")
#> [1] "point"
Polygon
rings <- list(list(
c(-2.275543, 53.464547),
c(-2.275543, 53.489271),
c(-2.215118, 53.489271),
c(-2.215118, 53.464547),
c(-2.275543, 53.464547)
))
lawn_polygon(rings)
#> $type
#> [1] "Feature"
#>
#> $geometry
#> $geometry$type
#> [1] "Polygon"
#>
#> $geometry$coordinates
#> , , 1
#>
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] -2.275543 -2.275543 -2.215118 -2.215118 -2.275543
#>
#> , , 2
#>
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 53.46455 53.48927 53.48927 53.46455 53.46455
#>
#>
#>
#> $properties
#> named list()
#>
#> attr(,"class")
#> [1] "polygon"
Count number of points within polygons
lawn_count(polygons = lawn_data$polygons_count, points = lawn_data$points_count)
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> type pt_count geometry.type
#> 1 Feature 2 Polygon
#> 2 Feature 0 Polygon
#> geometry.coordinates
#> 1 -112.07239, -112.07239, -112.02810, -112.02810, -112.07239, 46.58659, 46.61761, 46.61761, 46.58659, 46.58659
#> 2 -112.02398, -112.02398, -111.96613, -111.96613, -112.02398, 46.57043, 46.61502, 46.61502, 46.57043, 46.57043
#>
#> attr(,"class")
#> [1] "featurecollection"
Average value of a field for a set of points within a set of polygons
lawn_average(polygons = lawn_data$polygons_average,
points = lawn_data$points_average,
field = 'population')
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> type average geometry.type
#> 1 Feature 300 Polygon
#> 2 Feature 250 Polygon
#> geometry.coordinates
#> 1 10.66635, 10.66635, 10.76248, 10.76248, 10.66635, 59.89066, 59.93678, 59.93678, 59.89066, 59.89066
#> 2 10.76454, 10.76454, 10.86617, 10.86617, 10.76454, 59.88928, 59.93713, 59.93713, 59.88928, 59.88928
#>
#> attr(,"class")
#> [1] "featurecollection"
Define two points
from <- '{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [-75.343, 39.984]
}
}'
to <- '{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [-75.534, 39.123]
}
}'
Calculate distance, default units is kilometers (default output: km
)
lawn_distance(from, to)
#> [1] 97.15958
lawn_random(n = 2)
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> type geometry.type geometry.coordinates
#> 1 Feature Point -57.59454, 19.33782
#> 2 Feature Point 9.649159, -24.151190
#>
#> attr(,"class")
#> [1] "featurecollection"
lawn_random(n = 5)
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> type geometry.type geometry.coordinates
#> 1 Feature Point -129.19505, -45.57817
#> 2 Feature Point 118.87442, 28.94969
#> 3 Feature Point -133.65880, 26.14595
#> 4 Feature Point -63.48161, -78.71907
#> 5 Feature Point 8.208663, 31.347472
#>
#> attr(,"class")
#> [1] "featurecollection"
Positions
gr_position()
#> [1] -13.98266 16.81496
Points
gr_point(2)
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> type geometry.type geometry.coordinates
#> 1 Feature Point -89.365314, -6.577021
#> 2 Feature Point 147.51072, -36.05571
#>
#> attr(,"class")
#> [1] "featurecollection"
Polygons
gr_polygon(n = 1, vertices = 5, max_radial_length = 5)
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> type geometry.type
#> 1 Feature Polygon
#> geometry.coordinates
#> 1 -64.14027, -65.06539, -63.49399, -66.47064, -67.25660, -64.14027, -15.60968, -16.67584, -20.31435, -21.93198, -15.58848, -15.60968
#>
#> attr(,"class")
#> [1] "featurecollection"
dat <- lawn_data$points_average
lawn_sample(dat, 1)
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> type population geometry.type geometry.coordinates
#> 1 Feature 200 Point 10.80643, 59.90891
#>
#> attr(,"class")
#> [1] "featurecollection"
lawn_sample(dat, 2)
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> type population geometry.type geometry.coordinates
#> 1 Feature 300 Point 10.79544, 59.93162
#> 2 Feature 200 Point 10.80643, 59.90891
#>
#> attr(,"class")
#> [1] "featurecollection"
lawn_sample(dat, 3)
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> type population geometry.type geometry.coordinates
#> 1 Feature 200 Point 10.72403, 59.92681
#> 2 Feature 100 Point 10.74600, 59.90857
#> 3 Feature 600 Point 10.71579, 59.90478
#>
#> attr(,"class")
#> [1] "featurecollection"
lawn_extent(lawn_data$points_average)
#> [1] 10.71579 59.90478 10.80643 59.93162
lawn_within(lawn_data$points_within, lawn_data$polygons_within)
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> type geometry.type geometry.coordinates
#> 1 Feature Point -46.6318, -23.5523
#> 2 Feature Point -46.643, -23.557
#>
#> attr(,"class")
#> [1] "featurecollection"
dat <- '{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Polygon",
"coordinates": [[
[-112.072391,46.586591],
[-112.072391,46.61761],
[-112.028102,46.61761],
[-112.028102,46.586591],
[-112.072391,46.586591]
]]
}
}'
lawn_buffer(dat, 1, "miles")
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> type geometry.type
#> 1 Feature Polygon
#> geometry.coordinates
#> 1 -112.07239, -112.07522, -112.07793, -112.08044, -112.08263, -112.08443, -112.08577, -112.08660, -112.08687, -112.08687, -112.08660, -112.08577, -112.08443, -112.08263, -112.08044, -112.07793, -112.07522, -112.07239, -112.02810, -112.02528, -112.02256, -112.02006, -112.01786, -112.01606, -112.01472, -112.01390, -112.01362, -112.01362, -112.01390, -112.01472, -112.01606, -112.01786, -112.02006, -112.02256, -112.02528, -112.02810, -112.07239, 46.57211, 46.57239, 46.57321, 46.57455, 46.57635, 46.57854, 46.58105, 46.58377, 46.58659, 46.61761, 46.62044, 46.62315, 46.62566, 46.62785, 46.62965, 46.63099, 46.63181, 46.63209, 46.63209, 46.63181, 46.63099, 46.62965, 46.62785, 46.62566, 46.62315, 46.62044, 46.61761, 46.58659, 46.58377, 46.58105, 46.57854, 46.57635, 46.57455, 46.57321, 46.57239, 46.57211, 46.57211
#>
#> attr(,"class")
#> [1] "featurecollection"
For most functions, you can lint your input geojson data to make sure it is proper geojson. We use
the javascript library geojsonhint. See the lint
parameter where available.
Good GeoJSON
dat <- '{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"population": 200
},
"geometry": {
"type": "Point",
"coordinates": [10.724029, 59.926807]
}
},
{
"type": "Feature",
"properties": {
"population": 600
},
"geometry": {
"type": "Point",
"coordinates": [10.715789, 59.904778]
}
}
]
}'
lawn_extent(dat)
#> [1] 10.71579 59.90478 10.72403 59.92681
Bad GeoJSON
dat <- '{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"population": 200
},
"geometry": {
"type": "Point"
}
},
{
"type": "Feature",
"properties": {
"population": 600
},
"geometry": {
"type": "Point",
"coordinates": [10.715789, 59.904778]
}
}
]
}'
lawn_extent(dat, lint = TRUE)
#> Error: Line 1 - "coordinates" property required
lawn
includes a tiny helper function for visualizing geojson.
view(lawn_data$points_average)
Here, we sample at random two points from the same dataset just viewed.
lawn_sample(lawn_data$points_average, 2) %>% view()