Skip to contents

Convert many input types with spatial data to geojson specified as a list

Usage

geojson_list(
  input,
  lat = NULL,
  lon = NULL,
  group = NULL,
  geometry = "point",
  type = "FeatureCollection",
  convert_wgs84 = FALSE,
  crs = NULL,
  precision = NULL,
  ...
)

Arguments

input

Input list, data.frame, spatial class, or sf class. Inputs can also be dplyr tbl_df class since it inherits from data.frame

lat

(character) Latitude name. The default is NULL, and we attempt to guess.

lon

(character) Longitude name. The default is NULL, and we attempt to guess.

group

(character) A grouping variable to perform grouping for polygons - doesn't apply for points

geometry

(character) One of point (Default) or polygon.

type

(character) The type of collection. One of FeatureCollection (default) or GeometryCollection.

convert_wgs84

Should the input be converted to the standard CRS for GeoJSON (https://tools.ietf.org/html/rfc7946) (geographic coordinate reference system, using the WGS84 datum, with longitude and latitude units of decimal degrees; EPSG: 4326). Default is FALSE though this may change in a future package version. This will only work for sf or Spatial objects with a CRS already defined. If one is not defined but you know what it is, you may define it in the crs argument below.

crs

The CRS of the input if it is not already defined. This can be an epsg code as a four or five digit integer or a valid proj4 string. This argument will be ignored if convert_wgs84 is FALSE or the object already has a CRS.

precision

(integer) desired number of decimal places for coordinates. Only used with classes from sp classes; ignored for other classes. Using fewer decimal places decreases object sizes (at the cost of precision). This changes the underlying precision stored in the data. options(digits = <some number>) changes the maximum number of digits displayed (to find out what yours is set at see getOption("digits")); the value of this parameter will change what's displayed in your console up to the value of getOption("digits")

...

Ignored

Details

This function creates a geojson structure as an R list; it does not write a file - see geojson_write() for that.

Note that all sp class objects will output as FeatureCollection objects, while other classes (numeric, list, data.frame) can be output as FeatureCollection or GeometryCollection objects. We're working on allowing GeometryCollection option for sp class objects.

Also note that with sp classes we do make a round-trip, using sf::st_write() to write GeoJSON to disk, then read it back in. This is fast and we don't have to think about it too much, but this disk round-trip is not ideal.

For sf classes (sf, sfc, sfg), the following conversions are made:

  • sfg: the appropriate geometry Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection

  • sfc: GeometryCollection, unless the sfc is length 1, then the geometry as above

  • sf: FeatureCollection

For list and data.frame objects, you don't have to pass in lat and lon parameters if they are named appropriately (e.g., lat/latitude, lon/long/longitude), as they will be auto-detected. If they can not be found, the function will stop and warn you to specify the parameters specifically.

Examples

if (FALSE) {
# From a numeric vector of length 2 to a point
vec <- c(-99.74, 32.45)
geojson_list(vec)

# Lists
## From a list
mylist <- list(
  list(latitude = 30, longitude = 120, marker = "red"),
  list(latitude = 30, longitude = 130, marker = "blue")
)
geojson_list(mylist)

## From a list of numeric vectors to a polygon
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)
)
geojson_list(vecs, geometry = "polygon")

# from data.frame to points
(res <- geojson_list(us_cities[1:2, ], lat = "lat", lon = "long"))
as.json(res)
## guess lat/long columns
geojson_list(us_cities[1:2, ])
geojson_list(states[1:3, ])
geojson_list(states[1:351, ], geometry = "polygon", group = "group")
geojson_list(canada_cities[1:30, ])
## a data.frame with columsn not named appropriately, but you can
## specify them
# dat <- data.frame(a = c(31, 41), b = c(-120, -110))
# geojson_list(dat)
# geojson_list(dat, lat="a", lon="b")

# from data.frame to polygons
head(states)
geojson_list(states[1:351, ],
  lat = "lat", lon = "long",
  geometry = "polygon", group = "group"
)

# 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)
geojson_list(sp_poly)

# From SpatialPolygons class with precision agreement
x_coord <- c(
  -114.345703125, -114.345703125, -106.61132812499999,
  -106.61132812499999, -114.345703125
)
y_coord <- c(
  39.436192999314095, 43.45291889355468, 43.45291889355468,
  39.436192999314095, 39.436192999314095
)
coords <- cbind(x_coord, y_coord)
poly <- Polygon(coords)
polys <- Polygons(list(poly), 1)
sp_poly2 <- SpatialPolygons(list(polys))
geojson_list(sp_poly2, geometry = "polygon", precision = 4)
geojson_list(sp_poly2, geometry = "polygon", precision = 3)
geojson_list(sp_poly2, geometry = "polygon", precision = 2)

# From SpatialPoints class with precision
points <- SpatialPoints(cbind(x_coord, y_coord))
geojson_list(points)

# From SpatialPolygonsDataFrame class
sp_polydf <- as(sp_poly, "SpatialPolygonsDataFrame")
geojson_list(input = sp_polydf)

# From SpatialPoints class
x <- c(1, 2, 3, 4, 5)
y <- c(3, 2, 5, 1, 4)
s <- SpatialPoints(cbind(x, y))
geojson_list(s)

# From SpatialPointsDataFrame class
s <- SpatialPointsDataFrame(cbind(x, y), mtcars[1:5, ])
geojson_list(s)

# From SpatialLines class
library("sp")
c1 <- cbind(c(1, 2, 3), c(3, 2, 2))
c2 <- cbind(c1[, 1] + .05, c1[, 2] + .05)
c3 <- cbind(c(1, 2, 3), c(1, 1.5, 1))
L1 <- Line(c1)
L2 <- Line(c2)
L3 <- Line(c3)
Ls1 <- Lines(list(L1), ID = "a")
Ls2 <- Lines(list(L2, L3), ID = "b")
sl1 <- SpatialLines(list(Ls1))
sl12 <- SpatialLines(list(Ls1, Ls2))
geojson_list(sl1)
geojson_list(sl12)
as.json(geojson_list(sl12))
as.json(geojson_list(sl12), pretty = TRUE)

# From SpatialLinesDataFrame class
dat <- data.frame(
  X = c("Blue", "Green"),
  Y = c("Train", "Plane"),
  Z = c("Road", "River"), row.names = c("a", "b")
)
sldf <- SpatialLinesDataFrame(sl12, dat)
geojson_list(sldf)
as.json(geojson_list(sldf))
as.json(geojson_list(sldf), pretty = TRUE)

# From SpatialGrid
x <- GridTopology(c(0, 0), c(1, 1), c(5, 5))
y <- SpatialGrid(x)
geojson_list(y)

# From SpatialGridDataFrame
sgdim <- c(3, 4)
sg <- SpatialGrid(GridTopology(rep(0, 2), rep(10, 2), sgdim))
sgdf <- SpatialGridDataFrame(sg, data.frame(val = 1:12))
geojson_list(sgdf)

# From SpatialPixels
library("sp")
pixels <- suppressWarnings(
  SpatialPixels(SpatialPoints(us_cities[c("long", "lat")]))
)
summary(pixels)
geojson_list(pixels)

# From SpatialPixelsDataFrame
library("sp")
pixelsdf <- suppressWarnings(
  SpatialPixelsDataFrame(
    points = canada_cities[c("long", "lat")],
    data = canada_cities
  )
)
geojson_list(pixelsdf)

# From sf classes:
if (require(sf)) {
  ## sfg (a single simple features geometry)
  p1 <- rbind(c(0, 0), c(1, 0), c(3, 2), c(2, 4), c(1, 4), c(0, 0))
  poly <- rbind(c(1, 1), c(1, 2), c(2, 2), c(1, 1))
  poly_sfg <- st_polygon(list(p1))
  geojson_list(poly_sfg)

  ## sfc (a collection of geometries)
  p1 <- rbind(c(0, 0), c(1, 0), c(3, 2), c(2, 4), c(1, 4), c(0, 0))
  p2 <- rbind(c(5, 5), c(5, 6), c(4, 5), c(5, 5))
  poly_sfc <- st_sfc(st_polygon(list(p1)), st_polygon(list(p2)))
  geojson_list(poly_sfc)

  ## sf (collection of geometries with attributes)
  p1 <- rbind(c(0, 0), c(1, 0), c(3, 2), c(2, 4), c(1, 4), c(0, 0))
  p2 <- rbind(c(5, 5), c(5, 6), c(4, 5), c(5, 5))
  poly_sfc <- st_sfc(st_polygon(list(p1)), st_polygon(list(p2)))
  poly_sf <- st_sf(foo = c("a", "b"), bar = 1:2, poly_sfc)
  geojson_list(poly_sf)
}
}