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

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!


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

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)

À partir du package raster. Et de SF des idées?
RobinLovelace
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.