knitr::opts_chunk$set(echo = TRUE)
url <- "https://raw.githubusercontent.com/shawnbot/d3-cartogram/master/data/us-states.topojson" library(leaflet) leaflet() %>% addGeoJSONv2(readLines(url)) ## jsonlite does a weird simplify thing where a could-be-dimensioned array ## might be [1, 5] or [5, 1, 1] but for TopoJSON we can just treat all ## child-of-geometry arc arrays as 1D ## but then why is the coordinates also called "arcs" x <- jsonlite::fromJSON(url, simplifyVector = FALSE) names(x) x$type x$transform names(x$objects) lapply(x$objects, "[", "type") lapply(x$objects, function(x) unique(x$geometries$type)) lapply(x$objects, function(x) length(x$geometries$arcs)) unlist(range(lapply(x$arcs, nrow))) unique(range(lapply(x$arcs, ncol))) str(x)
So the x$arcs
are the coordinates, and must be qualified by transform.
coords_integer <- do.call(rbind, x$arcs) vec2mat <- function(x, n) matrix(rep(x, each = n), ncol = length(x)) coords <- vec2mat(x$transform$scale, nrow(coords_integer)) * coords_integer + vec2mat(x$transform$translate, nrow(coords_integer)) library(dplyr) arcs_obj1 <- bind_rows(lapply(x$objects[[1]]$geometries$arcs, function(x) { if (is.recursive(x)) x <- x[[1]] tibble(a = as.vector(x))}) , .id = "geometry") plot(coords) lapply(split(arcs_obj1, arcs_obj1$geometry), function(x) lines(coords[x$a + 1, ]))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.