รับ TopologyException: Input geom 1 ไม่ถูกต้องซึ่งเกิดจากการตัดกันด้วยตัวเองใน R?


24

ข้อผิดพลาด 'TopologyException: Input geom 1 ไม่ถูกต้อง' ซึ่งเกิดขึ้นจากรูปหลายเหลี่ยมที่ไม่ถูกต้องซึ่งมีการกล่าวถึงกันอย่างกว้างขวาง อย่างไรก็ตามฉันไม่พบวิธีแก้ไขปัญหาที่สะดวกบนเว็บที่อาศัยการทำงานของ R เพียงอย่างเดียว

ยกตัวอย่างเช่นฉันมีการจัดการเพื่อสร้างวัตถุ 'SpatialPolygons จากการส่งออกของmap("state", ...)ต่อไปนี้เป็นคำตอบที่ดี Josh โอไบรอันที่นี่

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))คุณจะเห็นว่าไม่มี "ที่ดูเหมือน" เกี่ยวกับมัน - มีจุดตัดด้วยตนเอง
Spacedman

คำตอบ:


39

การใช้บัฟเฟอร์ที่มีความกว้างเป็นศูนย์จะกำจัดปัญหาโทโพโลยีจำนวนมากใน R

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

อย่างไรก็ตามการทำงานกับพิกัดละติจูดยาวที่ไม่มีโครงการอาจทำให้เกิดrgeosคำเตือนได้

นี่คือตัวอย่างเพิ่มเติมที่นำมาฉายใน Albers ก่อน:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.