thomasp85 / transformr

Smooth Polygon Transformations
Other
116 stars 12 forks source link

segfaults when tweening sf #2

Closed gergness closed 6 years ago

gergness commented 6 years ago

This is so cool, I'm so excited to see how it develops! I've been trying to animate cartograms (made with the getcartr package, but I've been getting a mixture of errors and segfaults (probably 30% error about subsetting a points object, 50% "R session aborted" and 20% success).

When I run the following code with valgrind, I get some kind of error almost every time (where my_shp.Rds and my_cart.Rds are included in the attached .zip file - let me know if you want to see how I made those, I don't think it's relevant though). I poked around a bit, and I think I tracked the problem down to the unpack_sf() function, but wasn't able to figure out what was wrong.

Let me know if there's anything else I can provide that would help!

shape_rds.zip

library(sf)
library(ggplot2)
library(transformr)
library(gganimate)

my_cart <- readRDS("my_cart.Rds")
my_shp <- readRDS("my_shp.Rds")

out <- tween_sf(
  my_shp,
  my_cart,
  "cubic-in-out",
  nframes = 30,
  id = "NHGISST"
)

Most recent error for me:

> source("test.R")
Linking to GEOS 3.5.1, GDAL 2.1.2, proj.4 4.9.3
==1114== Invalid read of size 8
==1114==    at 0x4ED5F59: getAttrib0 (attrib.c:149)
==1114==    by 0x4ED797F: R_data_class2 (attrib.c:809)
==1114==    by 0x4FAD5CE: Rf_usemethod (objects.c:428)
==1114==    by 0x4FADC19: do_usemethod (objects.c:524)
==1114==    by 0x4F5DBB7: bcEval (eval.c:6791)
==1114==    by 0x4F6E46F: Rf_eval (eval.c:624)
==1114==    by 0x4F6FDA8: R_execClosure (eval.c:1764)
==1114==    by 0x4F6582B: bcEval (eval.c:6739)
==1114==    by 0x4F6E46F: Rf_eval (eval.c:624)
==1114==    by 0x4F6FDA8: R_execClosure (eval.c:1764)
==1114==    by 0x4F6582B: bcEval (eval.c:6739)
==1114==    by 0x4F6E46F: Rf_eval (eval.c:624)
==1114==  Address 0x30 is not stack'd, malloc'd or (recently) free'd
==1114==

 *** caught segfault ***
address 0x30, cause 'memory not mapped'

Traceback:
 1: as.list(X)
 2: lapply(polygon, function(p) {    x <- c(p$x, p$x[1])    y <- c(p$y, p$y[1])    area <- (x[-1] - x[-length(x)]) * (y[-1] + y[-length(y)])    if (sum(area) < 0)         p <- p[rev(seq_len(nrow(p))), ]    p})
 3: as_clockwise(from)
 4: align_sf_polygon(from, to, 50)
 5: (function (from, to, type) {    switch(type, POINT = , MULTIPOINT = align_sf_point(from,         to), LINESTRING = , MULTILINESTRING = align_sf_path(from,         to, 50), POLYGON = , MULTIPOLYGON = align_sf_polygon(from,         to, 50))})(from = dots[[1L]][[1L]], to = dots[[2L]][[1L]], type = dots[[3L]][[1L]])
 6: mapply(FUN = f, ..., SIMPLIFY = FALSE)
 7: Map(function(from, to, type) {    switch(type, POINT = , MULTIPOINT = align_sf_point(from,         to), LINESTRING = , MULTILINESTRING = align_sf_path(from,         to, 50), POLYGON = , MULTIPOLYGON = align_sf_polygon(from,         to, 50))}, from = from, to = to, type = from_type)
 8: FUN(X[[i]], ...)
 9: lapply(seq_along(from), function(i) {    from_type <- as.character(unlist(lapply(from[[i]], st_geometry_type)))    if (!all(from_type %in% supp_types))         stop("Unsupported geometry type", call. = FALSE)    to_type <- as.character(unlist(lapply(to[[i]], st_geometry_type)))    if (!all(to_type %in% supp_types))         stop("Unsupported geometry type", call. = FALSE)    if (!all(sub("MULTI", "", from_type) == sub("MULTI", "",         to_type)))         stop("Incompatible geometry types", call. = FALSE)   from <- unpack_sf(from[[i]], from_type)    to <- unpack_sf(to[[i]], to_type)    aligned <- Map(function(from, to, type) {        switch(type, POINT = , MULTIPOINT = align_sf_point(from,             to), LINESTRING = , MULTILINESTRING = align_sf_path(from,             to, 50), POLYGON = , MULTIPOLYGON = align_sf_polygon(from,             to, 50))    }, from = from, to = to, type = from_type)    from <- lapply(aligned, `[[`,"from")    to <- lapply(aligned, `[[`, "to")    id <- rep(seq_along(from), vapply(from, nrow, integer(1)))    from <- do.call(rbind, from)    to <- do.call(rbind, to)    from$sf_id <- id    to$sf_id <- id    tweened <- tween_state(from, to, ease, nframes) st_sfc(repack_sf(tweened, from_type, nframes))})
10: tween_sf_col(sf_from, sf_to, rep(ease, length.out = ncol(from))[sf_columns],     nframes)
11: tween_sf(my_shp, my_cart, "cubic-in-out", nframes = 30, id = "NHGISST")
12: eval(ei, envir)
13: eval(ei, envir)
14: withVisible(eval(ei, envir))
15: source("test.R")

Possible actions:
1: abort (with core dump, if enabled)
2: normal R exit
3: exit R without saving workspace
4: exit R saving workspace
thomasp85 commented 6 years ago

Can I get you to check whether the errors persist? I’ve made some changes to the c++ code that should make it more well-behaved

gergness commented 6 years ago

Yep, fixed, thanks! The gganimate suite is looking amazing!