การพิจารณาว่ามีจุดล้อมรอบโดยใช้การประมวลผลแบบแรสเตอร์หรือไม่


9

ฉันกำลังพยายามปรับปรุงกระบวนการเวกเตอร์ / หลามที่ยุ่งยากในขณะนี้สำหรับแบบจำลองความเป็นอันตรายตามธรรมชาติ ในขณะนี้เรามีสคริปต์ที่มีความยาวซึ่งสร้างเส้นระยะทาง / ทิศทางจากจุดที่กำหนดเพื่อพิจารณา:

  1. ประเภทของรูปหลายเหลี่ยมที่มันตัดกัน (เช่นป่าหญ้าป่าพรุ ฯลฯ )
  2. ระยะทางถึงรูปหลายเหลี่ยมนั้น
  3. จำนวนเส้นเหล่านี้ตัดกันรูปหลายเหลี่ยมเพื่อกำหนดว่า 'ล้อมรอบ' เป็นเท่าใด

มีส่วนร่วมมากขึ้น แต่นั่นคือส่วนสำคัญของมัน ฉันพยายามที่จะหาวิธีในการปรับปรุงและตอนนี้กำลังนิ่งงันในส่วนที่ 3 ความคิดคือการตรวจสอบว่าจุดที่ล้อมรอบด้วยรูปหลายเหลี่ยมอย่างสมบูรณ์ภายใน 200mPointA ถูกล้อมรอบในขณะที่ PointB นั้นล้อมรอบเพียง 50%

ดังนั้นในภาพที่แนบมาของฉันฉันต้องการให้จุด A ถูกทำเครื่องหมายว่ามีความเสี่ยงสูงกว่าจุด B เนื่องจากล้อมรอบด้วยรูปหลายเหลี่ยมของฉัน สิ่งนี้ซ้ำไปซ้ำมาประมาณ 13 ล้านจุดดังนั้นจึงไม่ใช่งานเล็ก ๆ และฉันอยากมีพื้นผิวที่จะได้รับค่ามากกว่าการใช้งานสคริปต์ของเรา ฉันคิดว่าจะต้องมีการเปลี่ยนแปลงของเครื่องมืออุทกวิทยาหรือเส้นทางต้นทุนในการทำเช่นนี้ แต่ฉันไม่สามารถไปรอบ ๆ มันได้

ฉันจะไปเกี่ยวกับเรื่องนี้ได้อย่างไร


1
Viewshedขึ้นอยู่กับภารกิจ แต่จะต้องการความช่วยเหลืออย่างมากเมื่อนำไปใช้กับ 13 ล้านคะแนน! คิดก่อนว่าจะกำจัดจุดที่มีสภาพแวดล้อมง่ายต่อการตรวจสอบอย่างไรเช่นจุดที่ตั้งอยู่ในพื้นที่ภายนอกรูปหลายเหลี่ยมที่มีเส้นผ่าศูนย์กลางน้อยกว่า (พูด) 200 ม.: ที่สามารถแยกแยะ "A" แต่อาจไม่ใช่ "B" "B" จะไม่ถูกตัดออกเพราะวิว (ใช้พื้นที่รูปหลายเหลี่ยมเป็นตำแหน่ง "สูง" ที่ปิดกั้นมุมมอง) ขยายออกไปกว่า 200m จากตำแหน่งของ B
whuber

เป็นจุดที่ดี @whuber แน่นอนว่าฉันสามารถลดจำนวนคะแนนทั้งหมดที่ประมวลผลโดยความใกล้ชิดและในความเป็นจริง lat-longs ที่ไม่ซ้ำกันเช่นกัน (ฉันกำลังพูดถึงที่อยู่ทางภูมิศาสตร์ geocoded ดังนั้นบล็อกพาร์ทเมนต์สามารถลดลงจาก 50 คะแนนเป็น 1) ที่หลายล้านแห่ง ฉันยังสามารถแบ่งทุกอย่างออกเป็นบล็อกที่ทับซ้อนกันได้หากจำเป็น จะตรวจสอบมุมมอง ขอบคุณ!
Loz

อีกหนึ่งหน้าจอที่รวดเร็วคือการคำนวณหาค่าโฟกัสของตารางตัวบ่งชี้ 0-1 ของรูปหลายเหลี่ยมของคุณโดยใช้ย่านวงแหวน: ที่เซลล์ใด ๆ ที่มีค่าเป็น 1 รูปหลายเหลี่ยมของคุณจะยึดพื้นที่รอบนอกทั้งหมดที่รัศมี นี่เป็นการคำนวณที่รวดเร็วและอาจกำจัดคะแนนส่วนใหญ่ของคุณได้ขึ้นอยู่กับว่าพวกเขาอยู่ที่ไหนและรูปหลายเหลี่ยมที่ซับซ้อนของคุณคืออะไร คุณสามารถเพิ่มความเร็วในการคัดกรองเบื้องต้นโดยการปรับตารางของคุณใหม่เป็นความละเอียดที่หยาบกว่าเดิมเช่น 25-50 ม. หรือราว ๆ นั้น
whuber

อีกขั้นตอนการประมวลผลที่เป็นไปได้หรือขั้นตอนการประมวลผลล่วงหน้าคือการส่งคะแนนของคุณผ่านชุดข้อมูลที่ผ่านการแรสเตอร์ของคุณเปรียบเทียบสถิติของพื้นที่ใกล้เคียงรอบ ๆ จุด คุณสามารถสรุปความต้องการ 'ที่ล้อมรอบ' ของคุณเป็นสถิติของพื้นที่ใกล้เคียงของคะแนนหรือหากจำเป็นต้อง 'ล้อมรอบ' คุณสามารถค้นหาคะแนน 'ง่าย' (เช่นจุดภายในพื้นที่เสี่ยง) โดยใช้พื้นที่ใกล้เคียงแบบแรสเตอร์ แยกวิเคราะห์คะแนน 'ง่าย' จากทุกจุดแล้วใช้การวิเคราะห์เวกเตอร์สำหรับจุดที่เหลือ
DPierce

ว้าวคำถามของฉันได้สร้างความสนใจอย่างมากอย่างแน่นอน! ขอบคุณทุกคนที่ให้คำแนะนำและความคิดเห็น ฉันจะไปตามทางของพวกเขาแม้ว่าพวกเขาทั้งหมดจะตอบกลับ แต่พวกเขาทั้งหมดจะต้องใช้เวลาพอสมควรในการทดสอบ ฉันสัญญาว่าจะตอบในที่สุด!
Loz

คำตอบ:


6

มีวิธีแก้ปัญหาเส้นทางราคา แต่คุณจะต้องรหัสด้วยตัวคุณเอง นี่คือลักษณะที่ปรากฏเมื่อนำไปใช้กับทุกจุดของภาพในคำถาม (หยาบเล็กน้อยเพื่อเพิ่มความเร็วในการคำนวณ):

รูปที่ 0

เซลล์สีดำเป็นส่วนหนึ่งของรูปหลายเหลี่ยมโดยรอบ สีต่าง ๆ ตั้งแต่สีส้มอ่อน (สั้น) ถึงสีน้ำเงิน (ยาว) แสดงระยะทางสูงสุด (ออกสูงสุด 50 เซลล์) ที่สามารถเข้าถึงได้โดยการสำรวจเส้นทางแนวสายตาโดยไม่ดักจับเซลล์รูปหลายเหลี่ยม (เซลล์ใดก็ตามที่อยู่นอกขอบเขตของภาพนี้ถือว่าเป็นส่วนหนึ่งของรูปหลายเหลี่ยม)

เรามาพูดถึงวิธีการที่มีประสิทธิภาพในการทำเช่นนี้โดยใช้การแทนค่า raster ของข้อมูล ในการเป็นตัวแทนนี้เซลล์รูปหลายเหลี่ยม "โดยรอบ" ทั้งหมดจะมีกล่าวว่าค่าที่ไม่ใช่ศูนย์และเซลล์ใด ๆ ที่สามารถ "เห็นผ่าน" จะมีค่าเป็นศูนย์

ขั้นตอนที่ 1: การคำนวณโครงสร้างข้อมูลพื้นที่ใกล้เคียงล่วงหน้า

ก่อนอื่นคุณต้องตัดสินใจว่ามันมีความหมายอย่างไรสำหรับเซลล์หนึ่งที่จะบล็อกอีกเซลล์หนึ่ง หนึ่งในกฎที่ยุติธรรมที่สุดที่ฉันสามารถหาได้คือ: โดยใช้พิกัดรวมสำหรับแถวและคอลัมน์ (และสมมติว่าเซลล์สี่เหลี่ยมจัตุรัส) ให้เราพิจารณาว่าเซลล์ใดอาจบล็อกเซลล์ (i, j) จากมุมมองที่จุดเริ่มต้น (0,0) ฉันเสนอชื่อเซลล์ (i ', j') ซึ่งใกล้เคียงกับส่วนของเส้นเชื่อมต่อ (i, j) ถึง (0,0) ในทุกเซลล์ที่พิกัดต่างจาก i และ j เป็นอย่างมาก 1 เนื่องจากสิ่งนี้ไม่ได้อยู่เสมอ ให้ผลลัพธ์ที่เป็นเอกลักษณ์ (ตัวอย่างเช่นด้วย (i, j) = (1,2) ทั้ง (0,1) และ (1,1) จะทำงานได้ดีพอ ๆ กัน) จำเป็นต้องใช้วิธีแก้ปัญหาความสัมพันธ์บางอย่าง มันจะดีสำหรับการแก้ปัญหาของความสัมพันธ์นี้เพื่อเคารพ symmetries ของละแวกวงกลมในกริด: negating พิกัดหรือสลับพิกัดรักษาย่านเหล่านี้ ดังนั้นเราสามารถตัดสินใจได้ว่าเซลล์ใดปิดกั้น (i,

Rแสดงกฎนี้เป็นรหัสต้นแบบต่อไปนี้เขียนใน รหัสนี้ส่งกลับโครงสร้างข้อมูลที่จะสะดวกในการพิจารณา "การล้อม" ของเซลล์ใด ๆ ในตาราง

screen <- function(k=1) {
  #
  # Returns a data structure:
  #   $offset is an array of offsets
  #   $screened is a parallel array of screened offset indexes.
  #   $distance is a parallel array of distances.
  # The first index always corresponds to (0,0).
  #
  screened.by <- function(xy) {
    uv <- abs(xy)
    if (reversed <- uv[2] > uv[1]) {
      uv <- rev(uv)
    }
    i <- which.min(c(uv[1], abs(uv[1]-uv[2]), uv[2]))
    ij <- uv + c(floor((1-i)/3), floor(i/3)-1)
    if (reversed) ij <- rev(ij)
    return(ij * sign(xy))
  }
  #
  # For each lattice point within the circular neighborhood,
  # find the unique lattice point that screens it from the origin.
  #
  xy <- subset(expand.grid(x=(-k:k), y=(-k:k)), 
               subset=(x^2+y^2 <= k^2) & (x != 0 | y != 0))
  g <- t(apply(xy, 1, function(z) c(screened.by(z), z)))
  #
  # Sort by distance from the origin.
  #
  colnames(g) <- c("x", "y", "x.to", "y.to")
  ij <- unique(rbind(g[, 1:2], g[, 3:4]))
  i <- order(abs(ij[,1]), abs(ij[,2])); ij <- ij[i, , drop=FALSE]
  rownames(ij) <- 1:length(i)
  #
  # Invert the "screened by" relation to produce the "screened" relation.
  #
  # (Row, column) offsets.
  ij.df <- data.frame(ij, i=1:length(i))
  #
  # Distances from the origin (in cells).
  distance <- apply(ij, 1, function(u) sqrt(sum(u*u)))
  #
  # "Screens" relation (represented by indexes into ij).
  g <- merge(merge(g, ij.df), ij.df, 
             by.x=c("x.to", "y.to"), by.y=c("x","y"))
  g <- subset(g, select=c(i.x, i.y))
  h <- by(g$i.y, g$i.x, identity)

  return( list(offset=ij, screened=h, distance=distance) )
}

ค่าของscreen(12)ใช้ในการสร้างภาพของความสัมพันธ์ในการคัดกรองนี้: ลูกศรชี้จากเซลล์ไปยังเซลล์ที่คัดกรองพวกมันทันที เฉดสีมีสัดส่วนตามระยะทางถึงจุดกำเนิดซึ่งอยู่ตรงกลางของย่านนี้:

รูปที่ 1

การคำนวณนี้รวดเร็วและจำเป็นต้องทำเพียงครั้งเดียวสำหรับพื้นที่ใกล้เคียงที่กำหนด ตัวอย่างเช่นเมื่อมองออกไป 200 ม. บนกริดที่มีเซลล์ 5 ม. ขนาดพื้นที่ใกล้เคียงจะเท่ากับ 200/5 = 40 หน่วย

ขั้นตอนที่ 2: ใช้การคำนวณกับคะแนนที่เลือก

ส่วนที่เหลือนั้นตรงไปตรงมา: เพื่อตรวจสอบว่าเซลล์ตั้งอยู่ที่ (x, y) (ในพิกัดแถวและคอลัมน์) เป็น "ล้อมรอบ" ด้วยความเคารพต่อโครงสร้างข้อมูลพื้นที่ใกล้เคียงนี้หรือไม่ทำการทดสอบซ้ำเริ่มต้นด้วยออฟเซ็ต (i, j) = (0,0) (ที่มาของพื้นที่ใกล้เคียง) หากค่าในตารางรูปหลายเหลี่ยมที่ (x, y) + (i, j) ไม่ใช่ศูนย์การมองเห็นจะถูกปิดกั้นที่นั่น มิฉะนั้นเราจะต้องพิจารณาถึงการชดเชยทั้งหมดที่อาจถูกบล็อกที่ออฟเซ็ต (i, j) (ซึ่งพบในเวลา O (1) โดยใช้โครงสร้างข้อมูลที่ส่งคืนโดยscreen) หากไม่มีสิ่งใดถูกปิดกั้นเราได้มาถึงขอบเขตแล้วและสรุปว่า (x, y) ไม่ถูกล้อมรอบดังนั้นเราจึงหยุดการคำนวณ (และไม่ต้องสนใจตรวจสอบจุดที่เหลืออยู่ในละแวกใกล้เคียง)

เราสามารถรวบรวมข้อมูลที่เป็นประโยชน์ได้มากขึ้นโดยการติดตามระยะห่างของแนวสายตาที่ไกลที่สุดในระหว่างอัลกอริทึม หากนี่น้อยกว่ารัศมีที่ต้องการเซลล์จะถูกล้อมรอบ มิฉะนั้นจะไม่

นี่คือRต้นแบบของอัลกอริทึมนี้ ยาวกว่าที่คิดเพราะRไม่สนับสนุนโครงสร้างสแต็ก (แบบง่าย) ที่จำเป็นต่อการใช้การเรียกซ้ำดังนั้นสแต็กจะต้องมีรหัสด้วย อัลกอริทึมที่แท้จริงเริ่มต้นประมาณสองในสามของการผ่านและต้องการเพียงหนึ่งโหลหรือมากกว่านั้น (และครึ่งหนึ่งของผู้ที่จัดการสถานการณ์รอบ ๆ ขอบกริดตรวจสอบหาดัชนีนอกขอบเขตภายในละแวกนี้อาจทำให้มีประสิทธิภาพมากขึ้นโดยการขยายตารางรูปหลายเหลี่ยมด้วยkแถวและคอลัมน์รอบปริมณฑล ต้องการการตรวจสอบช่วงดัชนีที่ค่าใช้จ่ายของ RAM เพิ่มอีกเล็กน้อยเพื่อเก็บตารางรูปหลายเหลี่ยม)

#
# Test a grid point `ij` for a line-of-sight connection to the perimeter
# of a circular neighborhood.  
#   `xy` is the grid.
#   `counting` determines whether to return max distance or count of stack ops.
#   `perimeter` is the assumed values beyond the extent of `xy`.
#
# Grid values of zero admit light; all others block visibility
# Returns maximum line-of-sight distance found within `nbr`.
#
panvisibility <- function(ij, xy, nbr=screen(), counting=FALSE, perimeter=1) {
  #
  # Implement a stack for the algorithm.
  #
  count <- 0 # Stack count
  stack <- list(ptr=0, s=rep(NA, dim(nbr$offset)[1]))
  push <- function(x) {
    n <- length(x)
    count <<- count+n         # For timing
    stack$s[1:n + stack$ptr] <<- x
    stack$ptr <<- stack$ptr+n
  }
  pop <- function() {
    count <<- count+1         # For timing
    if (stack$ptr <= 0) return(NULL)
    y <- stack$s[stack$ptr]
    #stack$s[stack$ptr] <<- NA # For debugging
    stack$ptr <<- stack$ptr - 1
    return(y)
  }
  #
  # Initialization.
  #
  m <- dim(xy)[1]; n <- dim(xy)[2]
  push(1) # Stack the *indexes* of nbr$offset and nbr$screened.
  dist.max <- -1
  #
  # The algorithm.
  #
  while (!is.null(i <- pop())) {
    cell <- nbr$offset[i, ] + ij
    if (cell[1] <= 0 || cell[1] > m || cell[2] <= 0 || cell[2] > n) {
      value <- perimeter
    } else {  
      value <- xy[cell[1], cell[2]]
    }
    if (value==0) {
      if (nbr$distance[i] > dist.max) dist.max <- nbr$distance[i]
      s <- nbr$screened[[paste(i)]]
      if (is.null(s)) {
        #exited = TRUE
        break
      }
      push(s)
    }
  }
  if (counting) return ( count )
  return(dist.max)
}

รูปที่ 2: ตัวอย่าง

ในตัวอย่างนี้เซลล์รูปเหลี่ยมมีสีดำ สีให้ระยะห่างระหว่างเส้นสายตาสูงสุด (ไม่เกิน 50 เซลล์) สำหรับเซลล์ที่ไม่ใช่รูปหลายเหลี่ยมตั้งแต่สีส้มอ่อนสำหรับระยะทางสั้นถึงสีน้ำเงินเข้มสำหรับระยะทางไกลที่สุด (เซลล์มีความกว้างหนึ่งหน่วยและสูง) ริ้วที่เห็นได้ชัดนั้นถูกสร้างขึ้นโดย "เกาะ" รูปหลายเหลี่ยมขนาดเล็กที่อยู่ตรงกลางของ "แม่น้ำ": แต่ละเซลล์จะบล็อกเซลล์อื่น ๆ เป็นแนวยาว

การวิเคราะห์อัลกอริทึม

โครงสร้างสแต็กจะทำการค้นหากราฟความลึกของพื้นที่ใกล้เคียงก่อนเพื่อหาหลักฐานว่าเซลล์ไม่ได้ล้อมรอบ ในกรณีที่เซลล์อยู่ไกลจากรูปหลายเหลี่ยมใด ๆ การค้นหานี้จะต้องมีการตรวจสอบเซลล์ O (k) เท่านั้นเพื่อหารัศมีวงกลม k กรณีที่เลวร้ายที่สุดเกิดขึ้นเมื่อมีจำนวนของเซลล์รูปหลายเหลี่ยมที่กระจัดกระจายอยู่ในละแวกใกล้เคียง แต่ถึงแม้ว่าจะไม่สามารถเข้าถึงขอบเขตของละแวกเพื่อนบ้านได้: สิ่งเหล่านี้ต้องการการตรวจสอบเกือบทุกเซลล์ในแต่ละพื้นที่ใกล้เคียงซึ่งเป็น O (k ^ 2) การทำงาน

พฤติกรรมต่อไปนี้เป็นสิ่งปกติที่จะเกิดขึ้น สำหรับค่าขนาดเล็กของ k ยกเว้นว่ารูปหลายเหลี่ยมเติมส่วนใหญ่ของกริดเซลล์ที่ไม่ใช่รูปหลายเหลี่ยมส่วนใหญ่จะไม่ถูกล้อมรอบอย่างชัดเจนและอัลกอริทึมจะปรับขนาดเช่น O (k) สำหรับค่าระดับกลางการปรับสเกลจะเริ่มดูเหมือน O (k ^ 2) เมื่อ k มีขนาดใหญ่จริง ๆ เซลล์ส่วนใหญ่จะถูกล้อมรอบและสามารถระบุความจริงได้ดีก่อนที่จะตรวจสอบพื้นที่ใกล้เคียงทั้งหมด: ความพยายามในการคำนวณของอัลกอริทึมจึงมาถึงขีด จำกัด ในทางปฏิบัติ ข้อ จำกัด นี้จะบรรลุได้เมื่อรัศมีพื้นที่ใกล้เคียงเข้าสู่เส้นผ่านศูนย์กลางของพื้นที่ที่ไม่ใช่รูปหลายเหลี่ยมที่เชื่อมต่อที่ใหญ่ที่สุดในตาราง

ตัวอย่างเช่นฉันใช้countingตัวเลือกที่เข้ารหัสในต้นแบบของscreenเพื่อส่งคืนจำนวนการดำเนินการสแต็กที่ใช้ในการโทรแต่ละครั้ง สิ่งนี้วัดความพยายามในการคำนวณ กราฟต่อไปนี้แสดงจำนวนเฉลี่ยของสแต็ก ops เป็นฟังก์ชันของรัศมีพื้นที่ใกล้เคียง มันแสดงพฤติกรรมที่ทำนายไว้

รูปที่ 3

เราสามารถใช้สิ่งนี้เพื่อประเมินการคำนวณที่จำเป็นในการประเมิน 13 ล้านคะแนนในตาราง สมมติว่ามีการใช้ย่าน k = 200/5 = 40 โดยเฉลี่ยแล้วการปฏิบัติการกองซ้อนสองสามร้อยครั้ง (ขึ้นอยู่กับความซับซ้อนของรูปหลายเหลี่ยมกริดและตำแหน่งที่ 13 ล้านจุดนั้นสัมพันธ์กับรูปหลายเหลี่ยม) ซึ่งหมายความว่าในภาษาที่รวบรวมได้อย่างมีประสิทธิภาพ จะต้อง (เพิ่มคูณอ่านเขียนชดเชย ฯลฯ ) พีซีส่วนใหญ่จะสามารถประเมินความสามารถรอบตัวได้ประมาณล้านจุดในอัตรานั้น (ในRการใช้งานช้ากว่านั้นมากเพราะมันแย่ในอัลกอริธึมชนิดนี้ซึ่งเป็นเหตุผลว่าทำไมมันจึงถูกพิจารณาเป็นเพียงต้นแบบเท่านั้น) ดังนั้นเราอาจหวังว่าการใช้งานที่มีประสิทธิภาพในภาษาที่มีประสิทธิภาพและเหมาะสม - C ++ และ Python มาถึงใจ - สามารถประเมินผลได้ 13 ล้านคะแนนในหนึ่งนาทีหรือน้อยกว่าโดยสมมติว่าตารางรูปหลายเหลี่ยมทั้งหมดอยู่ใน RAM

เมื่อกริดมีขนาดใหญ่เกินกว่าจะใส่ลงใน RAM ได้ขั้นตอนนี้สามารถใช้กับส่วนเรียงต่อกันของตาราง พวกเขาจะต้องทับซ้อนกันโดยkแถวและคอลัมน์ ใช้เวลาสูงสุดที่ทับซ้อนกันเมื่อทำการโมเสคผลลัพธ์

แอพพลิเคชั่นอื่น ๆ

"ดึง" ของร่างกายของน้ำมีความสัมพันธ์อย่างใกล้ชิดกับ "surroundedness" ของจุดของมัน ในความเป็นจริงถ้าเราใช้รัศมีพื้นที่ใกล้เคียงเท่ากับหรือมากกว่าเส้นผ่าศูนย์กลางของ waterbody เราจะสร้างตารางของการดึง (ไม่ใช่ทิศทาง) ที่ทุกจุดใน waterbody โดยการใช้รัศมีพื้นที่ใกล้เคียงที่มีขนาดเล็กเราจะได้รับขอบเขตที่ต่ำกว่าสำหรับการดึงที่จุดดึงสูงสุดทั้งหมดซึ่งในบางแอปพลิเคชันอาจดีพอ (และสามารถลดความพยายามในการคำนวณได้อย่างมาก) ตัวแปรของอัลกอริธึมที่ จำกัด "การคัดเลือกโดย" ความสัมพันธ์กับทิศทางที่เฉพาะเจาะจงจะเป็นวิธีหนึ่งในการคำนวณการดึงข้อมูลอย่างมีประสิทธิภาพในทิศทางเหล่านั้น โปรดทราบว่าตัวแปรดังกล่าวต้องการการแก้ไขโค้ดสำหรับscreen; รหัสสำหรับpanvisibilityจะไม่เปลี่ยนแปลงเลย


2

ฉันสามารถเห็นได้อย่างแน่นอนว่าคน ๆ หนึ่งอาจต้องการทำสิ่งนี้ด้วยวิธีแก้ปัญหาแรสเตอร์ แต่ด้วยคะแนนที่ลดลงฉันคาดว่าจะมีขนาดใหญ่ / ความละเอียดสูงและยากที่จะประมวลผลกริดหรือกริด ระบุว่าฉันสงสัยว่าการหาประโยชน์ทอพอโลยีใน gdb อาจมีประสิทธิภาพมากกว่านี้หรือไม่ คุณสามารถค้นหาช่องว่างภายในทั้งหมดด้วยสิ่งต่อไปนี้:

arcpy.env.workspace = 'myGDB'
arcpy.CreateTopology_management('myGDB', 'myTopology', '')    
arcpy.AddFeatureClassToTopology_management('myTopology', 'myFeatures', '1','1')    
arcpy.AddRuleToTopology_management ('myToplogy', 'Must Not Have Gaps (Area)', 'myFeatures', '', '', '')    
arcpy.ValidateTopology_management('myTopology', 'Full_Extent')
arcpy.ExportTopologyErrors_management('myTopology', 'myGDB', 'topoErrors')
arcpy.FeatureToPolygon_management('topoErrors_line','topoErrorsVoidPolys', '0.1')`

จากนั้นคุณสามารถทำงานtopoErrorsVoidPolysในรูปแบบปกติIntersect_analysis()หรืออะไรก็ได้ คุณอาจต้องยุ่งกับการดึงโพลีน่าสนใจออกtopoErrorsVoidPolysมา @whuber มีโพสต์ที่ยอดเยี่ยมจำนวนมากในเนื้อหาประเภทนี้ที่อื่นที่นี่ใน gis.stackexchange.com


นั่นเป็นแนวคิดก่อนการประมวลผลที่น่าสนใจ ฉันคิดว่ามันสามารถปรับได้อย่างง่ายดายเพื่อรวมขีด จำกัด 200 ม. (โดยการบัฟเฟอร์และจุดตัดเป็นต้น) จุดของคุณเกี่ยวกับกริดที่ใหญ่ขึ้นเป็นสิ่งที่น่ากังวลอย่างแท้จริง ไม่มีกฎใน GIS ที่บอกว่าการแก้ปัญหาจะต้องอาศัย raster-based หรือแบบเวกเตอร์ล้วนๆ (แม้ว่าจะมีหลักการที่บอกว่าคุณควรมีเหตุผลที่ดีในการแปลงจากการเป็นตัวแทนหนึ่งไปอีกอันหนึ่งที่อยู่ตรงกลาง ของการวิเคราะห์ที่นี่ตามที่คุณแนะนำอาจมีประโยชน์มากมายจากการทำเช่นนั้น)
whuber

0

ถ้าคุณอยากจะแรสเตอร์จริง ๆ ... ฉันจะทำบางสิ่งตามบรรทัดของรหัสหลอกนี้ (อย่าประจบประแจงเพียงเพราะมันชัดเจนว่าฉันเป็นนักเลง AML!: p)

  1. rasterize คะแนน ("pts_g") และ polys ("polys_g" (
  2. voids = regiongroup (แย้ง (isnull (polys_g), 1))
  3. อาจจำเป็นต้องทำบางสิ่งเพื่อปรับแต่งช่องว่างเพื่อกำจัดรูปหลายเหลี่ยมภายนอก / พื้นที่จักรวาลเปิดที่ไม่ต้องการ
  4. pts_surrounded = con (voids, pts_g)

เพียงแค่สร้างมันขึ้นมาดังนั้นอาจต้องมีการปรับแต่ง


โซลูชันของคุณไม่มีการอ้างอิงถึงระยะทางที่ จำกัด (ของ, พูด, 200 ม.) ดังนั้นจึงดูเหมือนไม่ตอบคำถามได้อย่างถูกต้อง
whuber

คุณถูก. สิ่งนี้ใช้ได้กับคำตอบอื่น ๆ ของฉันเช่นกัน ฉันคิดว่าใครสามารถใช้Expand()แต่ ณ จุดนั้นฉันคิดว่าคำตอบจาก @radouxju จะเทียบเท่ากับการทำงานและอาจเร็วกว่า (ไม่มีอะไรเทียบกับ viewshed เพียงไม่ได้ใช้มันมาก)
Roland

พยายามแก้ไขเมื่อเวลาหมด ต้องการที่จะขยายในExpand()ที่จะบอกว่าทำอย่างนั้นบนpts_gและใช้เพียงเพื่อตัดกับCon() polys_g
Roland

0

หากคุณใช้ค่าระยะทางขีด จำกัด (ที่นี่คุณจะพูดคุยประมาณ 200 ม.) ทางออกที่ดีที่สุดคือใช้การวิเคราะห์เวกเตอร์:

1) สร้างบัฟเฟอร์ 200 ม. รอบแต่ละจุด (เป็นสีดำบนภาพประกอบ)

2) ใช้เครื่องมือตัด (การวิเคราะห์) ระหว่างบัฟเฟอร์และรูปหลายเหลี่ยม (เป็นสีน้ำเงินในภาพประกอบ) มันจะดูดีกว่าถ้าคุณทำสิ่งนี้ระหว่างขอบเขตของรูปหลายเหลี่ยมโดยรอบและบัฟเฟอร์ แต่ผลลัพธ์สุดท้ายจะเหมือนกัน

3) ใช้คุณสมบัติเพื่อสร้างรูปหลายเหลี่ยม (การจัดการ) เพื่อสร้างรูปหลายเหลี่ยมที่จุดของคุณล้อมรอบสมบูรณ์ (สีแดงบนภาพประกอบ)

4) เลือกเลเยอร์ตามตำแหน่ง (การจัดการ) หรือการรวมเชิงพื้นที่ (การวิเคราะห์) เพื่อระบุจุดที่ล้อมรอบ การใช้การรวมเชิงพื้นที่ช่วยให้คุณมีข้อมูลเกี่ยวกับการฝังรูปหลายเหลี่ยม (พื้นที่ของรูปหลายเหลี่ยม, สถิติเชิงพื้นที่ ... ) ซึ่งอาจเป็นประโยชน์สำหรับการประมวลผลเพิ่มเติม

ทางเลือก 2b) ขึ้นอยู่กับความต้องการของคุณคุณสามารถเลือกรูปหลายเหลี่ยมโดยรอบในระยะ 200 เมตรจากนั้นคุณสามารถระบุ "สิ่งที่แนบมา" ได้ แต่ไม่เข้มงวดเท่าใน 2)

ป้อนคำอธิบายรูปภาพที่นี่

เมื่อพิจารณาถึง "เขาวงกต" สิ่งนี้อาจช่วยได้: ประเมินว่าจะ "หนี" นานแค่ไหนจากตำแหน่ง

  • คุณสามารถแยกออกจากการวิเคราะห์คะแนนที่รวมหรือฟรีทั้งหมด

  • จากนั้นคุณแปลงสิ่งกีดขวางของคุณเป็นแรสเตอร์และตั้งค่าเป็น NoData ที่คุณมีรูปหลายเหลี่ยมและขนาดเซลล์เป็นหน่วยเมตรซึ่งคุณไม่ต้องทำ

  • สามคุณสามารถคำนวณระยะทางต้นทุนโดยใช้แรสเตอร์ต้นทุนที่สร้างขึ้นใหม่

  • ในที่สุดคุณใช้สถิติโซนเป็นตารางตามขอบเขตบัฟเฟอร์ที่แปลงเป็นแรสเตอร์ หากคุณสามารถหลบหนีไปได้ทุกทิศทางค่าต่ำสุดควรประมาณ 200 (ขึ้นอยู่กับขนาดของเซลล์ในการวิเคราะห์ของคุณ) แต่ถ้าคุณอยู่ในเขาวงกตค่าสูงสุดจะมากกว่า 200 ดังนั้นสถิติสูงสุดของเขตพื้นที่ลบ 200 จะเป็นค่าต่อเนื่องที่บ่งบอกว่ายากแค่ไหนที่จะ "หลบหนี"


โปรดอธิบายความหมายของคุณว่า "ล้อม" คำอธิบายในคำถามแสดงให้เห็นว่าควรพิจารณาจุดที่ "ล้อมรอบ" เมื่อบางส่วนของรูปหลายเหลี่ยมสามารถมองเห็นได้ในทุกทิศทางรอบจุดนั้น (ออกไปเป็นระยะทาง 200 ม.) คุณทดสอบในขั้นตอนที่ (3) ได้อย่างไร (การวิเคราะห์เวกเตอร์ไม่ใช่เรื่องง่าย!)
whuber

ฉันได้เพิ่มภาพประกอบเล็ก ๆ น้อย ๆ มันจะอธิบายได้ง่ายกว่านั้น หากบัฟเฟอร์ไม่ตัดรูปหลายเหลี่ยมในทุกทิศทางดังนั้นจะไม่ปิดลูป และถ้าลูปไม่ปิดนี่จะไม่สร้างรูปหลายเหลี่ยม
radouxju

ฉันไม่แน่ใจว่าคุณหมายถึงอะไรโดย "วน" หรือ "ปิด" โปรดทราบว่าจุดหนึ่งสามารถ "ล้อมรอบ" แม้ว่าจะไม่มีวงกลมรัศมี r (น้อยกว่า 200 เมตร) รอบ ๆ มันจะอยู่ในรูปหลายเหลี่ยม คิดถึงเขาวงกต: รูปหลายเหลี่ยมนั้นเป็นทุกอย่างยกเว้นทางเดินในเขาวงกต หนึ่งสามารถหนีจากเขาวงกตเริ่มต้นที่จุดใด ๆ ภายใน แต่จุดส่วนใหญ่จะ "ล้อมรอบ" ในแง่ที่ว่าด้านนอกของเขาวงกตจะมองไม่เห็นจากพวกเขา
whuber

จากความเข้าใจของฉันสิ่งที่ประหลาดใจหมายความว่าคุณไม่สามารถหลบหนีได้ คุณสามารถหลบหนีจาก B แต่ไม่ใช่จาก A ในทางกลับกัน B ดูเหมือนจะถูกล้อมรอบหากคุณใช้ viewshed (ดีอาจจะไม่อยู่ที่ 200 ม. เนื่องจากไม่มีสเกลบาร์ในภาพ แต่คุณจะ ดูขอบเขตรูปหลายเหลี่ยมเมื่อมองทุกทิศทาง) ฉันคิดว่าเราต้องการรายละเอียดเพิ่มเติมจาก @Loz
radouxju

นี่จะไม่ใช่คำถามที่ยากเลยถ้า "ไม่สามารถหลบหนี" เป็นเกณฑ์ในการตรวจสอบ: เพียงแค่จัดกลุ่มส่วนประกอบของรูปหลายเหลี่ยมให้จัดกลุ่มส่วนประกอบภายนอกที่ไม่ซ้ำกันและตรวจสอบการรวมอยู่ภายใน ฉันคิดว่าการอ่านคำถามอย่างถี่ถ้วน - โดยเฉพาะอย่างยิ่งการอ้างอิงถึงการมองหาตลับลูกปืนที่เป็นไปได้ทั้งหมด - ให้ความกระจ่างถึงความตั้งใจที่จะ "ล้อมรอบ" ไว้แม้ว่าฉันจะเห็นด้วยว่ามันค่อนข้างคลุมเครือ
whuber
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.