Convert data to 'GeoJSON' or 'TopoJSON' from various R classes, including vectors, lists, data frames, shape files, and spatial classes. 'geojsonio' does not aim to replace packages like 'sp', 'rgdal', 'rgeos', but rather aims to be a high level client to simplify conversions of data from and to 'GeoJSON' and 'TopoJSON'.
Convert various data formats to GeoJSON or TopoJSON
This package is a utility to convert geographic data to GeoJSON and TopoJSON formats. Nothing else. We hope to do this one job very well, and handle all reasonable use cases.
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()
/topojson_list()
- convert to GeoJSON/TopoJSON as R list formatgeojson_json()
/topojson_json()
- convert to GeoJSON/TopoJSON as JSONgeojson_sp()
- convert output of geojson_list()
or geojson_json()
to sp
spatial objectsgeojson_sf()
- convert output of geojson_list()
or geojson_json()
to sf
objectsgeojson_read()
/topojson_read()
- read a GeoJSON/TopoJSON file from file path or URLgeojson_write()
/topojson_write()
- write a GeoJSON/TopoJSON file locallyEach of the above functions have methods for various objects/classes, including numeric
, data.frame
, list
, SpatialPolygons
, SpatialLines
, SpatialPoints
, etc.
Additional functions:
map_gist()
- push up a GeoJSON or topojson file as a GitHub gist (renders as an interactive map)
map_leaf()
- create a local interactive map using the leaflet
package
GeoJSON - spec
TopoJSON - spec
A note about installing rgdal
and rgeos
- these two packages are built on top of C libraries, and their installation often causes trouble for Mac and Linux users because no binaries are provided on CRAN for those platforms. Other dependencies in geojsonio
should install easily automatically when you install geojsonio
. Change to the version of rgdal
and GDAL
you have):
Mac
Install GDAL
on the command line first, e.g., using homebrew
brew install gdal
Then install rgdal
and rgeos
install.packages("rgdal", type = "source", configure.args = "--with-gdal-config=/Library/Frameworks/GDAL.framework/Versions/1.11/unix/bin/gdal-config --with-proj-include=/Library/Frameworks/PROJ.framework/unix/include --with-proj-lib=/Library/Frameworks/PROJ.framework/unix/lib")install.packages("rgeos", type = "source")
Linux
Get deps first
sudo apt-get install libgdal1-dev libgdal-dev libgeos-c1 libproj-dev
Then install rgdal
and rgeos
install.packages("rgdal", type = "source")install.packages("rgeos", type = "source")
Install geojsonio
Stable version from CRAN
install.packages("geojsonio")
Or development version from GitHub
install.packages("devtools")devtools::install_github("ropensci/geojsonio")
library("geojsonio")
From a numeric
vector of length 2, as json or list
geojson_json(c(32.45, -99.74))#> <FeatureCollection> #> type: FeatureCollection #> no. features: 1 #> features (1st 5): Point
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
library('maps')data(us.cities)geojson_json(us.cities[1:2, ], lat = 'lat', lon = 'long')#> <FeatureCollection> #> type: FeatureCollection #> no. features: 2 #> features (1st 5): Point, Point
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)
to json
geojson_json(sp_poly)#> <FeatureCollection> #> type: FeatureCollection #> no. features: 2 #> features (1st 5): Polygon, Polygon
to list
geojson_list(sp_poly)$features[[1]]#> $type#> [1] "Feature"#> #> $id#> [1] 1#> #> $properties#> $properties$dummy#> [1] 0#> ...
geo_list
+ geo_list
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":[]}]}
library('maps')data(us.cities)geojson_write(us.cities[1:2, ], lat = 'lat', lon = 'long')#> <geojson-file>#> Path: myfile.geojson#> From class: data.frame
file <- system.file("examples", "california.geojson", package = "geojsonio")out <- geojson_read(file)names(out)#> [1] "type" "crs" "features"names(out$features[[1]])#> [1] "type" "_id" "properties" "geometry"
topojson_json(c(-99.74,32.45))#> {"type":"Topology","objects":{"foo":{"type":"GeometryCollection","geometries":[{"type":"Point","coordinates":[-99.74,32.45]}]}},"arcs":[],"bbox":[-99.74,32.45,-99.74,32.45]}
library(sp)x <- c(1,2,3,4,5)y <- c(3,2,5,1,4)s <- SpatialPoints(cbind(x,y))topojson_list(s)#> $type#> [1] "Topology"#> #> $objects#> $objects$foo#> $objects$foo$type#> [1] "GeometryCollection"#> #> $objects$foo$geometries#> $objects$foo$geometries[[1]]#> $objects$foo$geometries[[1]]$type#> [1] "Point"#> #> $objects$foo$geometries[[1]]$coordinates#> [1] 1 3#> #> $objects$foo$geometries[[1]]$id#> [1] 1#> #> $objects$foo$geometries[[1]]$properties...
library('maps')data(us.cities)topojson_write(us.cities[1:2, ], lat = 'lat', lon = 'long')#> <topojson-file>#> Path: myfile.topojson#> From class: data.frame
library("sp")url <- "https://raw.githubusercontent.com/shawnbot/d3-cartogram/master/data/us-states.topojson"out <- topojson_read(url, verbose = FALSE)plot(out)
Using data from https://github.com/glynnbird/usstatesgeojson
Get some geojson
library('httr')res <- GET('https://api.github.com/repos/glynnbird/usstatesgeojson/contents')st_names <- Filter(function(x) grepl("\\.geojson", x), sapply(content(res), "[[", "name"))base <- 'https://raw.githubusercontent.com/glynnbird/usstatesgeojson/master/'st_files <- paste0(base, st_names)
Make a faceted plot
library('ggplot2')library('plyr')st_use <- st_files[7:13]geo <- lapply(st_use, geojson_read, method = "local", what = "sp")df <- ldply(setNames(lapply(geo, fortify), gsub("\\.geojson", "", st_names[7:13])))ggplot(df, aes(long, lat, group = group)) + geom_polygon() + facet_wrap(~.id, scales = "free")
Okay, so the maps are not quite right (stretched to fit each panel), but you get the idea.
geo2topo()
and topo2geo()
x <- '{"type": "LineString", "coordinates": [ [100.0, 0.0], [101.0, 1.0] ]}'(topo_json <- geo2topo(x))#> {"type":"Topology","objects":{"foo":{"type":"LineString","arcs":[0]}},"arcs":[[[100,0],[101,1]]],"bbox":[100,0,101,1]}topo2geo(topo_json)#> <FeatureCollection> #> type: FeatureCollection #> no. features: 1 #> features (1st 5): LineString
geojsonio
in R doing citation(package = 'geojsonio')
topojson_write()
gains a new parameter object_name
. With it you can set the name for the resulting TopoJSON object name created. As part of this geo2topo()
also gains a new parameter, similarly called object_name
, that does the same thing as for topojson_write()
. (#129) (thanks @josiekre) PR (#131)geojson_sf()
to convert output of geojson_list()
or geojson_json()
to sf
package classes - as an analog to geojson_sp()
geojson_json()
gains option with the type
parameter to skip a coercion to the geojson
package class geoclass
. Using type = "skip"
you can skip the geoclass
class coercion, which in some cases with large datasets should have performance improvements (#128) PR (#133)geojson_sp()
with the newest version of rgdal
. This was resolved by using the sf
package instead to read GeoJSON. This had a knock-on benefit of speeding up reading GeoJSON. In addition, sf
is now in Imports
instead of Suggests
(#130) PR (#132)geojson_atomize
to "atomize" a FeatureCollection
into its features, or a GeometryCollection into its geometries (#120)
via (#119) thx @SymbolixAUtopojson_list
and topojson_json
for converting
many input types with spatial data to TopoJSON, both as lists and
as JSON (#117)geojson_json
uses brief output provided by the geojson
package - this makes it less frustrating when you have an especially
large geojson string that prints to console - this instead prints a
brief summary of the GeoJSON object (#86) (#124)geojson_json
to make type
parameter more flexible (#125)topojson_write
- we were writing topojson file, but also
a geojson file - we now cleanup the geojson file (#127)topojson-server.js
from within the
package instead of from the web. This makes it so that the
package doesn’t make any web requests on load, which prevented package
from loading when no internet connection available. (#118)geo2topo
, topo2geo
, topojson_write
, and topojson_read
for working with TopoJSON data - associated with this, we
now import geojson
package (#24) (#100)geojson_write
and geojson_json
now pass ...
argument through to
rgdal::writeOGR
or jsonlite::toJSON
depending on the class/method. For
those methods that use the latter, this now allows setting of the na
argument to control how NA
values are represented in json, and the
pretty
argument to control whether or the resulting json is
pretty-formated or compact (#109) (#111)geojson_json
and geojson_write
now convert unsupported classes to
their basic class before conversion and/or writing to geojson. This was most
commonly occurring with fields in sf
objects calculated by sf::st_area
and sf::st_length
which were of class units
. (#107)GDAL
version >= 2.2.0 where the layer name in
a geojson file was not detected properly (#108)convert_wgs84
to do minimal test of
output, and to conditionally test only if sf
is available (#103)geojson_json
, geojson_list
, and geojson_write
gain new S3 methods:
sf
, sfc
, and sfg
- the three classes in the sf
package (#95)geojson_json
, geojson_list
, and geojson_write
gain two new
parameters each: convert_wgs84
(boolean) to convert to WGS84 or not (the
projection assumed for GeoJSON) and crs
to assign a CRS if known
(#101) (#102)geojson_json()
for non-sp classes now only keeps seven decimal places
in the coordinates. This follows the default that GDAL uses.methods
/stats
/utils
instead of importing themmethod
parameter in geojson_read
clarifying what the options are for (#93) thanks @bhaskarvkto_json
now defaults to 7 digits, which is used in
as.json
and geojson_json
(#96)geojson_read
to read correctly from a URL - in addition
to file paths (#91) (#92) thanks @lecygeojson_read
to read non-.geojson
extensions (#93)
thanks @bhaskarvkgeojson_json()
- moved to
reading in json with readr::read_file()
(#85) thanks @javrucebo !file_to_geojson()
to use httr::write_disk()
instead of
download.file()
(#83) thanks @patperulint()
and validate()
are now deprecated, and will be defunct in the next version of this
package. See the new package geojsonlint
on CRAN for linting
geojson functionality (#82)geojson_sp.json()
added to geojson_sp()
to handle json
class inputsencodin="UTF-8"
to httr::content()
callsgeojson_write()
didn't overwrite existing files despite saying so.
New parameter added to the function overwrite
to specify whether to
overwrite a function or not, which defaults to TRUE
(#81)
thanks @Robinlovelace !geojson_sp()
to convert output of geojson_list()
or
geojson_json()
to spatial classes (e.g., SpatialPointsDataFrame
) (#71)rgdal > v1.1-1
given fix to make writing multipolygon objects to geojson correct (#69)lint()
function, due to bug in passing data to the Javascript
layer (#73)as.json()
(#76)map_leaf()
uses the leaflet
package to make maps, with
S3 methods for most spatial classes as well as most R classes, including
data.frame's, lists, vectors, file inputs, and more (#48)geojson_read()
now optionally can give back a spatial class object,
just a convenience in case you want to not get back geojson, but a
spatial class (#60)leaflet
R package is on CRAN, put back in examples using
it to make maps (#49)geometry="polygon"
to
all geojson_*()
functions that have .list
methods. This checks to
make sure inputs have the same first and last coordinate pairs to
close the polygon (#34)methods
, stats
and utils
packages (#62)geojson_write()
in which geojson style names were altered
on accident (#56)