I need to find which lines are closed lines and which aren't inside a SpatialLines object in R. A closed line mean that the first point is the same as the last point. Is there any tool or function in R to find/check this? I give a reproducible example below.

How can I query the SpatialLines object called spLines to know that the first line (blue) is closed and the second line (green) opened?

# Libraries

# Points
points.x1 <- c(-54.00000, -54.43489, -54.78560, -54.00000, -53.57810, -53.22097, -54.00000)
points.y1 <- c(-40.74859, -40.00000, -38.00000, -37.49485, -38.00000, -40.00000, -40.74859)

points.x2 <- c(-52.53557, -52.00000, -50.00000, -48.00000, -46.40190)
points.y2 <- c(-41.00000, -40.60742, -40.08149, -40.82503, -39.00000)

# Lines
line1 <- Line(coords = cbind(points.x1, points.y1))
line2 <- Line(coords = cbind(points.x2, points.y2))

# SpatialLines
spLines <- SpatialLines(LinesList = list(Lines(slinelist = list(line1, line2), ID = "A")))

# Plot
plot(spLines, cex = 0, xlab = "Longitude", ylab = "Latitude", main = "Plot")
lines(spLines@lines[[1]]@Lines[[1]], col = "#3465A4", lwd = 4)
lines(spLines@lines[[1]]@Lines[[2]], col = "#73D216", lwd = 4)

plot example

Note: this is only a simple example with two lines, the answer should work with a SpatialLines object with many lines.

  • Is it sufficient to check if the first point is the same as the last point? – Spacedman Feb 23 '17 at 18:26
  • @Spacedman Yes, it would be ok! – Guzmán Feb 23 '17 at 18:32
  • 1
    Use rgeos::gPolygonize per object as a kind of raw filter – mdsumner Feb 23 '17 at 20:39

A simplistic index to each part with a TRUE or FALSE if it's polygonable.

unlist(lapply(seq_along(dsa), function(x) is.null(rgeos::gPolygonize(dsa[x]))))

This won't generalize well since we are lapplying across a single feature, the answer you are after is n:1 but there's no structure in the original object to store that grouping. Obviously brute force calling to the geometry library is pretty hefty going, but it'll be reliable by its definition.

It's similar to the discussion here: https://twitter.com/obrl_soil/status/832818604131307520

Another option with sf, though you might not be able to cast and keep the feature attributes (I need to check). Cast is a kind of explode, for some reason.

x <- st_as_sf(spLines, feature = seq_len(length(spLines))) ## record the feature ID

## cast to LINESTRING (a form of explode, but we maybe lose our data, I need to check)

## built-in polygonize will return an empty GEOMETRYCOLLECTION for the line
st_polygonize(st_cast(x, "LINESTRING")) %>% st_sf() %>% filter(st_area(geometry) > 0)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.