ลดความซับซ้อนของรูปหลายเหลี่ยมของวัตถุ sf


14

ฉันจะลดความซับซ้อนของsfรูปหลายเหลี่ยมได้อย่างไรโดยไม่แนะนำช่องว่างและตัวเอียง

ด้วย Shapefile เช่นฉันจะใช้rmapshaper::ms_simplify():

library("pryr")
library("rgdal")
library("rmapshaper")

download.file("https://borders.ukdataservice.ac.uk/ukborders/easy_download/prebuilt/shape/England_gor_2011.zip",
              destfile = "regions.zip")
unzip("regions.zip")
regions <- readOGR(".", "england_gor_2011")
object_size(regions)
# ~13MB

regions <- ms_simplify(regions)
object_size(regions)
# < 1MB

ฉันได้ลองแล้วsf::st_cast()ซึ่งจากหน้าคน, รัฐ:

ส่งเรขาคณิตไปยังประเภทอื่น: ลดความซับซ้อนหรือโยนอย่างชัดเจน

และ:

เพื่อโต้แย้ง: ตัวละคร; ประเภทเป้าหมายหากขาดหายไปจะพยายามลดความซับซ้อน เมื่อ x เป็นชนิด sfg (เช่นเรขาคณิตเดียว) จากนั้นจำเป็นต้องระบุ

เมื่อฉันจากtoไปเพราะขาดสิ่งนี้มันก็ไม่ได้ผลตามที่คาดหวังไว้ (ฉันรู้ว่ามันดีเกินกว่าจะเป็นจริงได้!):

library("sf")
regions <- sf::read_sf("england_gor_2011.shp")
object_size(regions)
# ~13MB

regions <- sf::st_cast(regions)
object_size(regions)
# Still 13MB

ขณะนี้ฉันกำลังเปิดไฟล์ที่มีการลดความซับซ้อนของมันประหยัดนี้แล้วโหลดนี้อีกครั้งกับrgdal::readOGR()sf

มีวิธีที่ดีกว่า?


rgeos::gSimplify()

คำแนะนำของ @sk ของrgeos::gSimplify()สามารถทำการลดความซับซ้อนของtopologically (เช่นลดความซับซ้อนโดยไม่ต้องสร้าง slivers) เมื่อระบุด้วยอาร์กิวเมนต์ต่อไปนี้:

library("rgeos")
regions_gSimplify <- gSimplify(regions, tol = 0.05, topologyPreserve = TRUE)

gSimplifyไม่รักษา@dataเฟรมไว้ดังนั้นเราควรสร้างใหม่อีกครั้ง:

regions_df <- regions@data
regions_gSimplify <- sp::SpatialPolygonsDataFrame(regions_gSimplify, regions_df)

และนี่จะส่งผลให้ไฟล์มีขนาดเล็กลง (สามารถปรับtolอาร์กิวเมนต์ให้เล็กลงได้) และฉันยืนยันว่านี่ไม่ได้สร้าง slivers ใด ๆ โดยตรวจสอบใน QGIS

object_size(regions_gSimplify)
# ~8MB

ดังนั้นแม้ว่านี่จะเป็นทางเลือกที่ถูกต้องสำหรับrmapshaper::ms_simplify()ฉันยังคงมีปัญหาเดียวกันนั่นคือมันใช้ไม่ได้กับsf:

regions_sf <- sf::read_sf("england_gor_2011.shp")
object_size(regions_sf)

regions_gSimplify <- gSimplify(regions_sf, topologyPreserve = TRUE, tol = 0.05)
# Error in gSimplify(regions_sf, topologyPreserve = TRUE, tol = 0.05) : 
# no slot of name "proj4string" for this object of class "sf"

@obrl_soil 'คำตอบ sนอกจากนี้ยังสามารถนำไปใช้เพียงแค่ใช้มันในสถานที่ของgSimplify()ms_simplify()


1
คุณมีการเข้าถึงอัลกอริทึม Douglas – Peucker หรือไม่? มันเป็นที่รู้จักกันอย่างกว้างขวางสำหรับคุณสมบัติการทำให้เข้าใจง่ายในโลก GIS stackoverflow.com/questions/17217413/ … & r-bloggers.com/simplifying-spatial-polygons-in-r
sk

1
ไม่st_simplifyควรที่จะทำอย่างนั้น? (ยังไม่ได้ใช้มัน)
lbusett

2
โอ้ฉันไม่ได้สังเกตเห็นst_simplifyขอบคุณที่ชี้ให้เห็น ฉันชอบอัลกอริทึมที่เป็นrmapshaper::ms_simplifyค่าเริ่มต้นสำหรับคนอื่น ๆ ทั้งหมดที่ฉันได้ลองมาแล้ว แต่ฉันจะเล่นกับตัวเลือกใหม่ (อัปเดต: ผู้ใช้งานด้วยความระมัดระวังpreserveTopology = TRUEไม่ทำงานอย่างถูกต้อง)
obrl_soil

1
ดีแล้วที่รู้. สิ่งที่เกี่ยวกับการเปิดรายงานข้อผิดพลาดเกี่ยวกับเรื่องนี้?
lbusett

1
@obrl_soil มันใช้งานได้กับความคลาดเคลื่อนมากถึง 1,000 บนรูปหลายเหลี่ยมที่ฉันเคยใช้ในคำถาม ( regions) แต่นอกเหนือจากนั้นมันไม่ได้เก็บโทโพโลยีอีกต่อไป เมื่อถึงจุดหนึ่งฉันจะบอกว่านั่นไม่ใช่พฤติกรรมที่ตั้งใจ
Phil

คำตอบ:


16

คุณสามารถส่งวัตถุ sf ไปที่ sp, สำหรับแพ็คเกจที่ยังไม่รองรับ sf - ฉันทำสิ่งนี้ได้ดีสำหรับการโต้ตอบ raster / polygon ดังนั้นคุณสามารถทำได้:

simplepolys <- rmapshaper::ms_simplify(input = as(sfobj, 'Spatial')) %>%
  st_as_sf()

1
เทคนิคนี้ - หล่อเป็นวัตถุอวกาศง่ายแล้ว re-หล่อเป็นsfวัตถุ - ทำงานอย่างสมบูรณ์และสามารถนำมาใช้กับหรือrmapshaper::ms_simplify() rgeos::gSimplify()ขอบคุณสำหรับคำแนะนำ!
Phil

เด็ดสุด ๆ เพิ่งทราบว่าทอพอโลยีของรูปหลายเหลี่ยมที่เชื่อมต่อกันได้รับการเก็บรักษาไว้อย่างแท้จริงด้วยวิธีการของ rmapshaper หากข้อมูลอินพุตของคุณเป็นรูปหลายเหลี่ยมที่แยกกันและไม่ประสานคุณสามารถใช้ algs การทำให้เข้าใจง่ายที่มีอยู่ได้อย่างปลอดภัย
obrl_soil

ฉันยอมรับสิ่งนี้เป็นคำตอบเพราะยิ่งบัญญัติมากขึ้นsf::st_simplify()ไม่ทนทานที่ความอดทนสูงในขณะที่เขียนแม้ว่าจะเห็นได้ชัดว่าสิ่งนี้อาจเปลี่ยนแปลงได้
Phil

8
ฉันกำลังทำงานเพื่อสนับสนุนsfวัตถุในrmapshaper rmapshaperms_simplifyพร้อมใช้งานสำหรับsfวัตถุในรุ่นที่กำลังพัฒนา ฉันชอบผู้ทดสอบเร็ว - หากคุณต้องการลองคุณสามารถติดตั้งด้วยdevtools::install_github("ateucher/rmapshaper", ref = "sf")
andyteucher

6
ตั้งแต่rmapshaperเวอร์ชัน 0.3.0 as( , "Spatial")ไม่จำเป็นต้องโทรไปที่อีกต่อไป
Luke1018
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.