Détourage inversé (effacement) dans R?

14

Un clip inversé enregistre uniquement la partie de votre objet spatial qui se trouve en dehors des limites d'un autre objet, par opposition à un clip standard qui enregistre les parties qui se trouvent à l' intérieur de l'autre objet.

Vous effectuez un clip inversé dans ArcMap? montre comment le faire dans ArcMap.

Comment faire cela dans R?

Exemple reproductible (sur les machines Linux):

system("wget 'https://github.com/Robinlovelace/Creating-maps-in-R/archive/master.zip' -P /tmp/")
unzip("/tmp/master.zip", exdir = "/tmp/master")
uk <- readOGR("/tmp/master/Creating-maps-in-R-master/data/", "ukbord")
lnd <- readOGR("/tmp/master/Creating-maps-in-R-master/data/", "LondonBoroughs")
plot(uk)
plot(lnd, add = T, col = "black")

Ce que je veux faire ici, c'est sauver tout le Royaume-Uni, sauf Londres. Visuellement, je veux que la forme noire de l'image résultante soit un trou.

entrez la description de l'image ici

RobinLovelace
la source

Réponses:

4

Réponse pour des fonctionnalités simples:

Le paquet sf s'appuie sur Geometry Engine Open Source, et en tant que tel peut accéder à la liste des commandes telles que st_within, etc.

L'une de ces commandes, st_difference, fera le travail:

require(sf)

# make a square simple feature
s <- rbind(c(1,1), c(1,5), c(5,5), c(5,1), c(1,1))
s.sf <-st_sfc(st_polygon(list(s)))
s.pol = st_sf(ID = "sq", s.sf)

# make a smaller triangle simple feature
s2 <- rbind(c(2,2), c(3,4), c(4,2), c(2,2))
s2.sf <-st_sfc(st_polygon(list(s2)))
s2.pol = st_sf(ID = "tr", s2.sf)

# find the 'difference', i.e. reverse of st_intersection
t <- st_difference(s.pol,s2.pol)

plot(t)

# have a look at the new geometry, a well known text format with exterior followed by hole
st_geometry(t)[[1]]
POLYGON((1 1, 1 5, 5 5, 5 1, 1 1), (2 2, 4 2, 3 4, 2 2))

voir aussi vers le bas de cet article

peut également être fait en contraignant Sp à sf avec st_as_sf. Tenez compte des avertissements car les attributs peuvent être difficiles à gérer!

Sam
la source
12

Semble être une application simple gDifferencedu rgeospackage:

> require(rgeos)
> ukhole = gDifference(uk, lnd)
Warning message:
In RGEOSBinTopoFunc(spgeom1, spgeom2, byid, id, "rgeos_difference") :
  spgeom1 and spgeom2 have different proj4 strings
> plot(ukhole)

L'avertissement de projection est dû au fait que le LondonBoroughsfichier de formes n'a pas de .prjfichier.

Pour vous assurer qu'il s'agit bien d'un trou et non d'un contour ou d'un autre polygone solide:

> gArea(lnd) + gArea(ukhole) - gArea(uk)
[1] 0
Spacedman
la source
Sooo simple, merci pour la réponse rapide. Serait intéressé à regarder le code source de ces fonctions pour voir ce qui se passe sous le capot.
RobinLovelace
Au fond, ils appellent simplement GEOS qui est une bibliothèque de code C de fonctions géométriques trac.osgeo.org/geos
Spacedman
Intéressant - et aide à expliquer pourquoi il est raisonnablement rapide je suppose. Sur la base de cette page, il semble qu'elle ne soit pas activement développée. Quelqu'un peut-il confirmer / réfuter cela? svn.osgeo.org/geos/branches/3.4/ChangeLog
RobinLovelace
1
C'est sûr qu'il est développé. Voir la chronologie trac.osgeo.org/geos/timeline ou les archives de la liste de diffusion lists.osgeo.org/pipermail/geos-devel
user30184
5

Un peu tard pour la fête, mais il existe un moyen simple de le faire avec un masque en utilisant l'argument «inverse»;

ukhole <- mask(uk, lnd, inverse = TRUE)
Coding4Biology
la source
À partir du package raster. Et de SF des idées?
RobinLovelace