Отримання TopologyException: Введення geom 1 недійсний, що пов'язано з самоперетином в R?


24

Широко обговорювалася помилка самоперетину "TopologyException: Input geom 1", що виникає внаслідок неправильної геометрії полігону. Однак я не знайшов зручного рішення в Інтернеті, яке покладається виключно на функціональність R.

Наприклад, мені вдалося створити об’єкт "SpatialPolygons" з результатів map("state", ...)наступних приємних відповідей Джоша О'Браєна тут .

library(maps)
library(maptools)

map_states = map("state", fill = TRUE, plot = FALSE)

IDs = sapply(strsplit(map_states$names, ":"), "[[", 1)
spydf_states = map2SpatialPolygons(map_states, IDs = IDs, proj4string = CRS("+init=epsg:4326"))

plot(spydf_states)

держав

Проблема з цим широко застосовуваним набором даних полягає в тому, що самоперетин відбувається в точці, наведеній нижче.

rgeos::gIsValid(spydf_states)
[1] FALSE
Warning message:
In RGEOSUnaryPredFunc(spgeom, byid, "rgeos_isvalid") :
  Self-intersection at or near point -122.22023214285259 38.060546477866055

На жаль, ця проблема перешкоджає подальшому використанню 'spydf_states', наприклад при дзвінку rgeos::gIntersection. Як я можу вирішити це питання зсередини R?


1
Якщо ви збільшите масштаб навколо цієї точки: plot(spydf_states, xlim=c(-122.1,-122.3),ylim=c(38,38.1))ви побачите, що в цьому немає "начебто" - є самоперетин.
Спайдермен

Відповіді:


39

Використання буфера нульової ширини очищує багато проблем з топологією в Р.

spydf_states <- gBuffer(spydf_states, byid=TRUE, width=0)

Однак робота з непроектованими координатами довгих довжин може спричинити rgeosзастереження.

Ось розширений приклад, який спочатку повторює проекцію Альберса:

library(sp)
library(rgeos)

load("~/Dropbox/spydf_states.RData")

# many geos functions require projections and you're probably going to end
# up plotting this eventually so we convert it to albers before cleaning up
# the polygons since you should use that if you are plotting the US
spydf_states <- spTransform(spydf_states, 
                            CRS("+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=37.5 +lon_0=-96"))

# simplify the polgons a tad (tweak 0.00001 to your liking)
spydf_states <- gSimplify(spydf_states, tol = 0.00001)

# this is a well known R / GEOS hack (usually combined with the above) to 
# deal with "bad" polygons
spydf_states <- gBuffer(spydf_states, byid=TRUE, width=0)

# any bad polys?
sum(gIsValid(spydf_states, byid=TRUE)==FALSE)

## [1] 0

plot(spydf_states)

введіть тут опис зображення


4
будь-який додатковий коментар / читання про те, чому gBuffer"хак" працює?
MichaelChirico

ви хочете використовувати gSimplify, оскільки він руйнує data.frame та перетворює SPDF в об'єкт просторового багатокутника?
wnursal

5
Якщо ви користуєтесь, sfви також можете скористатисяsf::st_buffer(x, dist = 0)
Філ

також працює в деяких випадках при використанніPostGIS
natsuapo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.