Skip to content

Instantly share code, notes, and snippets.

@Nowosad
Created May 29, 2021 14:34
Show Gist options
  • Save Nowosad/3ca0b479ecfdd632283aaa89d68340e2 to your computer and use it in GitHub Desktop.
Save Nowosad/3ca0b479ecfdd632283aaa89d68340e2 to your computer and use it in GitHub Desktop.
Conversion from a SaTScan text file with ellipses to an sf R spatial object
st_from_ellipses = function(path, crs = "EPSG:25832", res = 30) {
e = read.csv(path)
pnt = sf::st_as_sf(e, coords = c("X", "Y"), crs = crs)
major = pnt$Major
minor = pnt$Minor
angle = pnt$Angle1
rotation = function(a){
r = a * pi / 180 #degrees to radians
matrix(c(cos(r), sin(r), -sin(r), cos(r)), nrow = 2, ncol = 2)
}
coords = sf::st_coordinates(pnt)
result = list()
for (i in 1:nrow(coords)) {
theta = seq(0, 2 * pi, length = res)
x = coords[i, 1] - minor[i]/2 * cos(theta)
y = coords[i, 2] - major[i]/2 * sin(theta)
elp = cbind(x[!is.na(x)], y[!is.na(y)])
npnt = sf::st_multipoint(elp)
pol = sf::st_cast(npnt, "LINESTRING")
pol = (sf::st_sfc(pol) - sf::st_geometry(pnt)[i]) *
rotation(angle[i]) + sf::st_geometry(pnt)[i]
result[[i]] = pol
}
result = do.call(c, result)
st_crs(result) = crs
result = cbind(sf::st_sf(geom = result), sf::st_drop_geometry(pnt))
result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment