geojsonio
converts geographic data to GeoJSON and TopoJSON formats - though the focus is mostly on GeoJSON
For those not familiar GeoJSON it is a format for encoding a variety of geographic data structures. GeoJSON supports the following geometry types: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, and GeometryCollection. These geometry types are also found in well known text (WKT), and have equivalents in R’s spatial classes. Read the spec for more detailed information.
Other great geojson resources:
- GeoJSON lint - lint your geojson - https://geojsonlint.com/
- GeoJSON.io - make maps with geojson input or draw maps and get geojson - https://geojson.io/
Functions in this package are organized first around what you’re working with or want to get, geojson or topojson, then convert to or read from various formats:
geojson_list()
- convert to GeoJSON as R list formatgeojson_json()
- convert to GeoJSON as jsongeojson_read()
/topojson_read()
- read a GeoJSON/TopoJSON file from file path or URLgeojson_write()
- write a GeoJSON file locally (no write TopoJSON yet)
Each of the above functions have methods for various objects/classes, including numeric
, data.frame
, list
, SpatialPolygons
, SpatialLines
, SpatialPoints
, etc. (including the classes in rgeos
)
Use cases for this package include (but not limited to, obs.) the following:
- Get data in GeoJSON json format, and you want to get it into a list in R.
- Get data into GeoJSON format to use downstream to make a interactive map
- in R (e.g., with leaflet)
- or in another context (e.g., using javascript with mapbox/leaflet)
- Data is in a data.frame/matrix/list and you want to make GeoJSON format data.
- Data is in one of the many spatial classes (e.g.,
SpatialPoints
) and you want GeoJSON - You need to add styling to your data - can do with this package for certain data types.
- You want to check that your GeoJSON data is valid - two ways to do it in geojsonio.
- Combine objects together (e.g., a point and a line), either from two
geo_list
objects, or twojson
objects. See?geojson-add
Install
See the github repo for notes about dependencies https://github.com/ropensci/geojsonio#install
CRAN version or the dev version from GitHub
install.packages("geojsonio")
devtools::install_github("sckott/geojsonio")
library("geojsonio")
GeoJSON
Convert various formats to geojson
From a numeric
vector of length 2
as json
geojson_json(c(32.45, -99.74))
#> {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[32.45,-99.74]},"properties":{}}]}
as a list
geojson_list(c(32.45, -99.74))
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> $features[[1]]
#> $features[[1]]$type
#> [1] "Feature"
#>
#> $features[[1]]$geometry
#> $features[[1]]$geometry$type
...
From a data.frame
as json
geojson_json(us_cities[1:2, ], lat = 'lat', lon = 'long')
#> {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-99.74,32.45]},"properties":{"name":"Abilene TX","country.etc":"TX","pop":"113888","capital":"0"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-81.52,41.08]},"properties":{"name":"Akron OH","country.etc":"OH","pop":"206634","capital":"0"}}]}
as a list
geojson_list(us_cities[1:2, ], lat = 'lat', lon = 'long')
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> $features[[1]]
#> $features[[1]]$type
#> [1] "Feature"
#>
#> $features[[1]]$geometry
#> $features[[1]]$geometry$type
...
From SpatialPolygons
class
library('sp')
poly1 <- Polygons(list(Polygon(cbind(c(-100, -90, -85, -100),
c(40, 50, 45, 40)))), "1")
poly2 <- Polygons(list(Polygon(cbind(c(-90, -80, -75, -90),
c(30, 40, 35, 30)))), "2")
(sp_poly <- SpatialPolygons(list(poly1, poly2), 1:2))
#> An object of class "SpatialPolygons"
#> Slot "polygons":
#> [[1]]
#> An object of class "Polygons"
#> Slot "Polygons":
#> [[1]]
#> An object of class "Polygon"
#> Slot "labpt":
#> [1] -91.66667 45.00000
#>
...
to json
geojson_json(sp_poly)
#> {"type":"FeatureCollection","features":[{"type":"Feature","id":1,"properties":{"dummy":0},"geometry":{"type":"Polygon","coordinates":[[[-100,40],[-90,50],[-85,45],[-100,40]]]}},{"type":"Feature","id":2,"properties":{"dummy":0},"geometry":{"type":"Polygon","coordinates":[[[-90,30],[-80,40],[-75,35],[-90,30]]]}}]}
to a list
geojson_list(sp_poly)
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> $features[[1]]
#> $features[[1]]$type
#> [1] "Feature"
#>
#> $features[[1]]$id
#> [1] 1
...
From SpatialPoints
class
x <- c(1, 2, 3, 4, 5)
y <- c(3, 2, 5, 1, 4)
(s <- SpatialPoints(cbind(x, y)))
#> SpatialPoints:
#> x y
#> [1,] 1 3
#> [2,] 2 2
#> [3,] 3 5
#> [4,] 4 1
#> [5,] 5 4
#> Coordinate Reference System (CRS) arguments: NA
to json
geojson_json(s)
#> {"type":"FeatureCollection","features":[{"type":"Feature","id":1,"properties":{"dat":1},"geometry":{"type":"Point","coordinates":[1,3]}},{"type":"Feature","id":2,"properties":{"dat":2},"geometry":{"type":"Point","coordinates":[2,2]}},{"type":"Feature","id":3,"properties":{"dat":3},"geometry":{"type":"Point","coordinates":[3,5]}},{"type":"Feature","id":4,"properties":{"dat":4},"geometry":{"type":"Point","coordinates":[4,1]}},{"type":"Feature","id":5,"properties":{"dat":5},"geometry":{"type":"Point","coordinates":[5,4]}}]}
to a list
geojson_list(s)
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> $features[[1]]
#> $features[[1]]$type
#> [1] "Feature"
#>
#> $features[[1]]$id
#> [1] 1
...
Combine objects
geo_list
+ geo_list
Note:
geo_list
is the output type fromgeojson_list()
, it’s just a list with a class attached so we know it’s geojson :)
vec <- c(-99.74, 32.45)
a <- geojson_list(vec)
vecs <- list(c(100.0, 0.0), c(101.0, 0.0), c(100.0, 0.0))
b <- geojson_list(vecs, geometry = "polygon")
a + b
#> $type
#> [1] "FeatureCollection"
#>
#> $features
#> $features[[1]]
#> $features[[1]]$type
#> [1] "Feature"
#>
#> $features[[1]]$geometry
#> $features[[1]]$geometry$type
...
json
+ json
c <- geojson_json(c(-99.74, 32.45))
vecs <- list(c(100.0, 0.0), c(101.0, 0.0), c(101.0, 1.0), c(100.0, 1.0), c(100.0, 0.0))
d <- geojson_json(vecs, geometry = "polygon")
c + d
#> {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-99.74,32.45]},"properties":{}},{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[100,0],[101,0],[101,1],[100,1],[100,0]]]},"properties":[]}]}
Write geojson
geojson_write(us_cities[1:2, ], lat = 'lat', lon = 'long')
#> <geojson>
#> Path: myfile.geojson
#> From class: data.frame
Topojson
In the current version of this package you can read topojson. Writing topojson was in this package, but is gone for now - will come back later as in interface to topojson via V8.
Read from a file
file <- system.file("examples", "us_states.topojson", package = "geojsonio")
out <- topojson_read(file)
Read from a URL
url <- "https://raw.githubusercontent.com/shawnbot/d3-cartogram/master/data/us-states.topojson"
out <- topojson_read(url)
Lint geojson
There are two ways to do this in this package.
lint, locally
Uses the javascript library geojsonhint from Mapbox. We’re running this locally via the V8 package.
Good
lint('{"type": "Point", "coordinates": [-100, 80]}')
#> [1] "valid"
Bad
lint('{"type": "Rhombus", "coordinates": [[1, 2], [3, 4], [5, 6]]}')
#> $message
#> [1] "The type Rhombus is unknown"
#>
#> $line
#> [1] 1
validate, with a web service
Uses the web service at https://geojsonlint.com/
Good
validate('{"type": "Point", "coordinates": [-100, 80]}')
#> $status
#> [1] "ok"
Bad
validate('{"type": "Rhombus", "coordinates": [[1, 2], [3, 4], [5, 6]]}')
#> $message
#> [1] "\"Rhombus\" is not a valid GeoJSON type."
#>
#> $status
#> [1] "error"
To do
- I’d like to replace
rgdal
with javascript libraries to read from various file types (kml, shp, etc.) and convert to geojson. This is in development, and will come in the next version of this package most likely. This should make installation a bit easier as we won’t have to depend onrgdal
andGDAL
- Performance improvements. Some operations already use the gdal or geos C libraries, so are quite fast, though the round trip to disk and back does take significant time. I’d like to speed this up.
- More input types. We already have operations (json, list, etc.) for lots of input types (data.frame, list, sp classes), but likely there will be more added.
- Most likely add functions
topojson_list()
,topojson_json()