Таблица общих ребер для мозаики Вороного

Я пытаюсь создать таблицу соседей полигонов на основе мозаики Вороного (она же мозаика Дирихле или многоугольники Тиссена), созданной функцией dirichlet() библиотеки spatstat. Например, на рисунке ниже верхний правый и нижний правый тайлы будут иметь по 2 соседа, центральный правый тайл — 4 соседа, а остальные два тайла — по 3 соседа. Я хочу зафиксировать соседние пары в таблице и, в идеале, зафиксировать длину линии границы, которую они разделяют: например, «Плитка1», «Плитка2», «shared_edge_length».

Первоначально я пытался просмотреть и сравнить каждую пару полигонов в тесселяции, используя функции intersect.tess(), intersect.own(), а также polyclip, но я предполагаю, что они не работают, потому что плитки по определению не перекрываются по площади, несмотря на то, что они разделены. края. Есть ли простая функция для этого (альтернативой может быть цикл по $bdry точкам)? Вроде в пакете regeos есть gTouches, но для spatstat ничего похожего не нашел.

Это мой текущий нерабочий подход:

library(spatstat)
points <- ppp(x=c(-77.308703, -77.256582, -77.290600,  -77.135668, -77.097144),
         y=c(39.288603, 39.147019, 39.372818, 39.401898, 39.689203),
         window=owin(xrange=c(-77.7,-77), yrange=c(39.1, 39.7)))
vt <- dirichlet(points) # Dirichlet tesselation
plot(vt)

tilesA <- tiles(vt)
n_tiles <- length(tilesA)
boundary_calcs <- data.frame('area1_id'=numeric(), 'area2_id'=numeric(), 'neighbor'=logical()) # Store boundary pairs
for (i in 1:n_tiles) {
  for (j in 1:n_tiles) {
    intersection <- intersect.owin(tilesA[[i]], tilesA[[j]], fatal=FALSE) # does not work
    if (!is.empty(intersection)) {
      boundary_calcs[nrow(boundary_calcs)+1, ] <- c(i, j, TRUE) # add to data table as new row
} } }

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


person Bryan    schedule 19.06.2014    source источник


Ответы (2)


Следующая функция была предоставлена ​​авторами пакета. Он использует тот факт, что структура dirsgs функции deldir() выводит начальные и конечные координаты каждой строки в тесселяции вместе с индексами точек. Их можно преобразовать в шаблон сегмента линии psp, который может легко обеспечить длину каждого сегмента с помощью lengths.psp(). Приведенный ниже код создает таблицу с одной строкой для каждого из 7 ребер, которые можно увидеть на графике выше.

library(spatstat)
library(deldir)
points <- ppp(x=c(-77.308703, -77.256582, -77.290600,  -77.135668, -77.097144),
         y=c(39.288603, 39.147019, 39.372818, 39.401898, 39.689203),
         window=owin(xrange=c(-77.7,-77), yrange=c(39.1, 39.7)))

sharededge <- function(X) {
   verifyclass(X, "ppp")
   Y <- X[as.rectangle(X)]
   dX <- deldir(Y)
   DS <- dX$dirsgs
   xyxy <- DS[,1:4]
   names(xyxy) <- c("x0","y0","x1","y1")
   sX <- as.psp(xyxy,window=dX$rw)
   marks(sX) <- 1:nobjects(sX)
   sX <- sX[as.owin(X)]
   tX <- tapply(lengths.psp(sX), marks(sX), sum)
   jj <- as.integer(names(tX))
   ans <- data.frame(ind1=DS[jj,5], 
                     ind2=DS[jj,6], 
                     leng=as.numeric(tX))
   return(ans)
}

shared_edge_lengths <- sharededge(points)

Вывод хранится в shared_edge_lengths:

  ind1 ind2       leng
1    2    1 0.17387212
2    3    1 0.13444458
3    4    1 0.05791519
4    4    2 0.10039321
5    4    3 0.25842530
6    5    3 0.09818828
7    5    4 0.17162429
person Bryan    schedule 11.08.2014

Я только что спросил Рольфа Тернера, который является автором пакета deldir, и он предоставил приведенный ниже код для определения количества соседей для каждой плитки. Я еще не рассматривал ваше желание «идеально зафиксировать длину общей линии границы».

x <- c(-77.308703, -77.256582, -77.290600,  -77.135668, -77.097144)
y <- c(39.288603, 39.147019, 39.372818, 39.401898, 39.689203)
rw <- c(-77.7,-77,39.1,39.7)
require(deldir)
dxy <- deldir(x,y,rw=rw)

dxy$summary$n.tside
person Ege Rubak    schedule 20.06.2014
comment
После более подробного прочтения вопроса я вижу, что это вообще не дает ответа. Это просто количество соседей, а не указание, какие пары являются соседями. Надеюсь, у меня будет время вернуться к этому позже. (Вы можете попробовать delaunay для поиска соседних пар, но я абсолютно не уверен, что это полезно. Концептуально граф Делоне - это то, на что стоит обратить внимание.). - person Ege Rubak; 20.06.2014
comment
спасибо за заметки. Я изучал ваше предложение, но не нашел способа использовать график Делоне. Нет ли способа сделать это, используя пары плиток, уже созданных с помощью dirichlet? - person Bryan; 06.08.2014