An R package to repair broken GIS polygons using the
prepair
C++ library.
The prepair
C++ library need these two libraries to compile:
The R package prepr
solves the CGAL dependencies by shipping with a
subset of the CGAL header. We also use
rwinlib
to provide GDAL
on Windows in
order to build this package from source. You will need the latest
version of rtools
in
order to build the source code on Windows.
prepair
can also use these optional libraries:
They are disabled by default on Windows but required if you want to
build the package in a Linux/OS X environment. After installing all
these libraries, you can now install the development version of the
prepr
R package from Gitlab using
the remotes
R package with:
# install.packages("remotes")
remotes::install_gitlab("dickoa/prepr")
remotes::install_github("dickoa/prepr") ## mirror
This is a simple tutorial which shows you how to solve common problems we can find with polygons:
library(prepr)
library(sf)
p1 <- st_as_sfc("POLYGON((0 0, 0 10, 10 0, 10 10, 0 0))")
st_is_valid(p1, reason = TRUE)
#> [1] "Self-intersection[5 5]"
p11 <- st_prepair(p1)
st_is_valid(p11)
#> [1] TRUE
st_as_text(p11)
#> [1] "MULTIPOLYGON (((0 0, 5 5, 0 10, 0 0)), ((5 5, 10 0, 10 10, 5 5)))"
par(mfrow = c(1, 2))
plot(p1, main = "RAW", col = "#D7722C")
plot(p11, main = "Repaired", col = "#D7722C")
p2 <- st_as_sfc("POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))")
st_is_valid(p2, reason = TRUE)
#> [1] "Valid Geometry"
plot(p2, main = "RAW", col = "#D7722C")
p3 <- st_as_sfc("POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(5 2, 5 7, 10 7, 10 2, 5 2))")
st_is_valid(p3, reason = TRUE)
#> [1] "Self-intersection[10 2]"
p33 <- st_prepair(p3)
st_is_valid(p33)
#> [1] TRUE
st_as_text(p33)
#> [1] "POLYGON ((0 0, 10 0, 10 2, 5 2, 5 7, 10 7, 10 10, 0 10, 0 0))"
par(mfrow = c(1, 2))
plot(p3, main = "RAW", col = "#D7722C")
plot(p33, main = "Repaired", col = "#D7722C")
p4 <- st_as_sfc("POLYGON((0 0, 10 0, 15 5, 10 0, 10 10, 0 10, 0 0))")
st_is_valid(p4, reason = TRUE)
#> [1] "Self-intersection[15 5]"
p44 <- st_prepair(p4)
st_is_valid(p44)
#> [1] TRUE
st_as_text(p44)
#> [1] "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))"
par(mfrow = c(1, 2))
plot(p4, main = "RAW", col = "#D7722C")
plot(p44, main = "Repaired", col = "#D7722C")
p6 <- st_as_sfc("POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 1 8, 3 8, 3 1, 1 1), (3 1, 3 8, 5 8, 5 1, 3 1))")
st_is_valid(p6, reason = TRUE)
#> [1] "Self-intersection[3 8]"
p66 <- st_prepair(p6)
st_is_valid(p66)
#> [1] TRUE
st_as_text(p66)
#> [1] "POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0), (1 1, 1 8, 3 8, 5 8, 5 1, 3 1, 1 1))"
par(mfrow = c(1, 2))
plot(p6, main = "RAW", col = "#D7722C")
plot(p66, main = "Repaired", col = "#D7722C")
p7 <- st_as_sfc("POLYGON((0 0, 10 0, 10 10, 0 10, 0 0), (2 8, 5 8, 5 2, 2 2, 2 8), (3 3, 4 3, 3 4, 3 3))")
st_is_valid(p7, reason = TRUE)
#> [1] "Holes are nested[3 3]"
p77 <- st_prepair(p7)
st_is_valid(p77)
#> [1] TRUE
st_as_text(p77)
#> [1] "MULTIPOLYGON (((0 0, 10 0, 10 10, 0 10, 0 0), (2 2, 2 8, 5 8, 5 2, 2 2)), ((3 3, 4 3, 3 4, 3 3)))"
par(mfrow = c(1, 2))
plot(p7, main = "RAW", col = "#D7722C")
plot(p77, main = "Repaired", col = "#D7722C")
Details of how we automatically repair broken polygons, and what results
you can expect, are available in this scientific article by the original
authors of prepair
:
Ledoux, H., Arroyo Ohori, K., and Meijers, M. (2014). A triangulation-based approach to automatically repair GIS polygons. Computers & Geosciences 66:121–131. [DOI] [PDF]
If you use the R package prepr
for a scientific project, please cite
their original work.
This package is released under the GPL-3 license.